60 lines
2.1 KiB
TypeScript
60 lines
2.1 KiB
TypeScript
import { FunctionalComponent, h } from "preact";
|
|
import { Project } from "../../models/project";
|
|
import { Task } from "../../models/task";
|
|
import { useState, useEffect } from "preact/hooks";
|
|
import { getProjectWeightedMean, getProjectStandardDeviation } from "../../util/stat";
|
|
|
|
export interface TimePreviewProps {
|
|
project: Project
|
|
}
|
|
|
|
const TimePreview: FunctionalComponent<TimePreviewProps> = ({ project }) => {
|
|
const [ estimations, setEstimations ] = useState({
|
|
p99: { e: '0', sd: '0' },
|
|
p90: { e: '0', sd: '0' },
|
|
p68: { e: '0', sd: '0' },
|
|
});
|
|
|
|
useEffect(() => {
|
|
const projectWeightedMean = getProjectWeightedMean(project).toFixed(2);
|
|
const projectStandardDeviation = getProjectStandardDeviation(project);
|
|
setEstimations({
|
|
p99: { e: projectWeightedMean, sd: (projectStandardDeviation * 3).toFixed(2) },
|
|
p90: { e: projectWeightedMean, sd: (projectStandardDeviation * 1.645).toFixed(2) },
|
|
p68: { e: projectWeightedMean, sd: (projectStandardDeviation).toFixed(2) },
|
|
})
|
|
}, [project.tasks]);
|
|
|
|
return (
|
|
<div class="table-container">
|
|
<table class="table is-bordered is-striped is-fullwidth">
|
|
<thead>
|
|
<tr>
|
|
<th colSpan={2}>Prévisionnel temps</th>
|
|
</tr>
|
|
<tr>
|
|
<th>Niveau de confiance</th>
|
|
<th>Estimation</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>>= 99.7%</td>
|
|
<td>{`${estimations.p99.e} ± ${estimations.p99.sd} j/h`}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>>= 90%</td>
|
|
<td>{`${estimations.p90.e} ± ${estimations.p90.sd} j/h`}</td>
|
|
</tr>
|
|
<tr>
|
|
<td>>= 68%</td>
|
|
<td>{`${estimations.p68.e} ± ${estimations.p68.sd} j/h`}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default TimePreview;
|