Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TRACK-6: Issue Accordion Staleness #2487

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions epictrack-web/src/apiManager/http-request-handler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,11 @@ const PatchRequest = <T>(url: string, data = {}) => {
},
})
.then((response) => {
// console.warn("PatchRequest - Response:", response); // Log the response
return response;
})
.catch((error) => {
console.error("PatchRequest - Error:", error); // Log the error
throw error; // Ensure the error propagates
console.error("PatchRequest - Error:", error);
throw error;
});
};

Expand Down
12 changes: 2 additions & 10 deletions epictrack-web/src/components/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -330,19 +330,12 @@ const GoToIcon = (props: IconProps) => {
);
};

const ExclamationSmallIcon = (props: IconProps) => {
const ExclamationSmallIcon = ({ fill, ...rest }: IconProps) => {
return (
<svg
{...commonProps}
{...props}
width="18"
height="16"
viewBox="0 0 18 16"
>
<svg {...rest} width="18" height="16" viewBox="0 0 18 16">
<path
opacity="0.8"
d="M16.8125 13.0293C17.3125 13.9043 16.6875 14.998 15.6562 14.998H2.3125C1.28125 14.998 0.65625 13.9043 1.15625 13.0293L7.84375 1.6543C8.34375 0.779297 9.625 0.779297 10.1562 1.6543L16.8125 13.0293ZM8.25 5.24805V9.24805C8.25 9.68555 8.625 9.99805 9 9.99805C9.40625 9.99805 9.75 9.68555 9.75 9.24805V5.24805C9.75 4.8418 9.40625 4.49805 9 4.49805C8.5625 4.49805 8.25 4.8418 8.25 5.24805ZM9 12.998C9.53125 12.998 9.96875 12.5605 9.96875 12.0293C9.96875 11.498 9.53125 11.0605 9 11.0605C8.4375 11.0605 8 11.498 8 12.0293C8 12.5605 8.4375 12.998 9 12.998Z"
fill={Palette.secondary.dark}
/>
</svg>
);
Expand All @@ -353,7 +346,6 @@ const ExclamationMediumIcon = (props: IconProps) => {
<path
opacity="0.8"
d="M24.7188 19.5469C25.4688 20.8594 24.5312 22.5 22.9844 22.5H2.96875C1.42188 22.5 0.484375 20.8594 1.23438 19.5469L11.2656 2.48438C12.0156 1.17188 13.9375 1.17188 14.7344 2.48438L24.7188 19.5469ZM11.875 7.875V13.875C11.875 14.5312 12.4375 15 13 15C13.6094 15 14.125 14.5312 14.125 13.875V7.875C14.125 7.26562 13.6094 6.75 13 6.75C12.3438 6.75 11.875 7.26562 11.875 7.875ZM13 19.5C13.7969 19.5 14.4531 18.8438 14.4531 18.0469C14.4531 17.25 13.7969 16.5938 13 16.5938C12.1562 16.5938 11.5 17.25 11.5 18.0469C11.5 18.8438 12.1562 19.5 13 19.5Z"
fill={Palette.secondary.dark}
/>
</svg>
);
Expand Down
272 changes: 169 additions & 103 deletions epictrack-web/src/components/workPlan/WorkPlanContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ import Status from "./status";
import Icons from "../icons";
import { IconProps } from "../icons/type";
import Issues from "./issues";
import { WorkIssue } from "../../models/Issue";
import WorkState from "./WorkState";
import { isStatusOutOfDate } from "./status/shared";
import About from "./about";
import { useLocation } from "react-router-dom";
import { WORKPLAN_TAB } from "./constants";
import { StalenessEnum } from "constants/application-constant";
import useRouterLocationStateForHelpPage from "hooks/useRouterLocationStateForHelpPage";
import { calculateStaleness } from "./utils";

const IndicatorIcon: React.FC<IconProps> = Icons["IndicatorIcon"];

const ExclamationSmallIcon: React.FC<IconProps> = Icons["ExclamationSmallIcon"];
const tabPanel: SxProps = {
paddingTop: "2rem",
};
Expand All @@ -35,6 +38,10 @@ const WorkPlanContainer = () => {

const ctx = useContext(WorkplanContext);

const { issues } = useContext(WorkplanContext) as {
issues: WorkIssue[];
};

const activeStaff = ctx.team.filter(
(staffWorkRole) => staffWorkRole.is_active
);
Expand All @@ -43,118 +50,177 @@ const WorkPlanContainer = () => {
setSelectedTabIndex(index);
};

if (ctx.loading) {
return <WorkPlanSkeleton />;
}

const statusOutOfDate =
ctx.statuses.length === 0 ||
isStatusOutOfDate(ctx.statuses.find((status) => status.is_approved));

const mapIssues = (issues: WorkIssue[]): StalenessEnum | null => {
const stalenessPriority = [
StalenessEnum.GOOD,
StalenessEnum.WARN,
StalenessEnum.CRITICAL,
];

// Helper function to get the "highest" staleness
const getHigherStaleness = (
a: StalenessEnum,
b: StalenessEnum
): StalenessEnum => {
return stalenessPriority.indexOf(a) > stalenessPriority.indexOf(b)
? a
: b;
};

if (issues.length === 0) return StalenessEnum.GOOD; // No issues to check

const topStaleness = issues.reduce((currentHighest, issue) => {
const staleness = calculateStaleness(issue);
console.info("stalenessTab:", staleness);
return getHigherStaleness(currentHighest, staleness);
}, StalenessEnum.GOOD); // Start with GOOD as the "lowest" level

return topStaleness;
};

const highestStaleness = mapIssues(issues) ?? StalenessEnum.GOOD; // Fallback to GOOD

console.info("highestStaleness:", highestStaleness);

const iconStyles = React.useMemo(() => {
if (highestStaleness === "CRITICAL") {
return {
fill: Palette.error.light,
};
}
if (highestStaleness === "WARN") {
return {
fill: Palette.secondary.light,
};
}
return {
fill: Palette.white,
};
}, [highestStaleness]);

return (
<ETPageContainer
sx={{
paddingBottom: "0rem !important",
}}
>
<Box sx={{ display: "flex", gap: "16px" }}>
<ETHeading2 bold color={Palette.primary.main}>
{ctx.work?.title}
</ETHeading2>
<ETCaption3 bold>
<WorkState work_state={ctx.work?.work_state} />
</ETCaption3>
</Box>
<Box
sx={{
marginTop: "1rem",
}}
>
<ETTabs
<>
{ctx.loading ? (
<WorkPlanSkeleton />
) : (
<ETPageContainer
sx={{
gap: "2rem",
paddingBottom: "0rem !important",
}}
onChange={handleTabSelected}
value={selectedTabIndex}
>
<ETTab
<Box sx={{ display: "flex", gap: "16px" }}>
<ETHeading2 bold color={Palette.primary.main}>
{ctx.work?.title}
</ETHeading2>
<ETCaption3 bold>
<WorkState work_state={ctx.work?.work_state} />
</ETCaption3>
</Box>
<Box
sx={{
marginTop: "1rem",
}}
>
<ETTabs
sx={{
gap: "2rem",
}}
onChange={handleTabSelected}
value={selectedTabIndex}
>
<ETTab
sx={{
paddingLeft: 0,
}}
label={WORKPLAN_TAB.WORKPLAN.label}
/>
<ETTab
label={WORKPLAN_TAB.STATUS.label}
icon={statusOutOfDate && <IndicatorIcon />}
/>
<ETTab
label={WORKPLAN_TAB.ISSUES.label}
icon={
<ExclamationSmallIcon
style={{
...iconStyles,
}}
/>
}
/>
<ETTab label={WORKPLAN_TAB.ABOUT.label} />
<ETTab
label={WORKPLAN_TAB.TEAM.label}
identifier={activeStaff.length.toString()}
data-title="dddd"
/>
<ETTab
label={WORKPLAN_TAB.FIRST_NATIONS.label}
identifier={ctx.firstNations.length.toString()}
/>
</ETTabs>
</Box>
<TabPanel
index={WORKPLAN_TAB.WORKPLAN.index}
value={selectedTabIndex}
sx={{
...tabPanel,
}}
>
<PhaseContainer />
</TabPanel>
<TabPanel
index={WORKPLAN_TAB.STATUS.index}
value={selectedTabIndex}
sx={{
...tabPanel,
}}
>
<Status />
</TabPanel>
<TabPanel
index={WORKPLAN_TAB.ISSUES.index}
value={selectedTabIndex}
sx={{
...tabPanel,
}}
>
<Issues />
</TabPanel>
<TabPanel
index={WORKPLAN_TAB.ABOUT.index}
value={selectedTabIndex}
sx={{
...tabPanel,
}}
>
<About />
</TabPanel>
<TabPanel
index={WORKPLAN_TAB.TEAM.index}
value={selectedTabIndex}
sx={{
...tabPanel,
}}
>
<TeamContainer />
</TabPanel>
<TabPanel
index={WORKPLAN_TAB.FIRST_NATIONS.index}
value={selectedTabIndex}
sx={{
paddingLeft: 0,
...tabPanel,
}}
label={WORKPLAN_TAB.WORKPLAN.label}
/>
<ETTab
label={WORKPLAN_TAB.STATUS.label}
icon={statusOutOfDate && <IndicatorIcon />}
/>
<ETTab label={WORKPLAN_TAB.ISSUES.label} />
<ETTab label={WORKPLAN_TAB.ABOUT.label} />
<ETTab
label={WORKPLAN_TAB.TEAM.label}
identifier={activeStaff.length.toString()}
data-title="dddd"
/>
<ETTab
label={WORKPLAN_TAB.FIRST_NATIONS.label}
identifier={ctx.firstNations.length.toString()}
/>
</ETTabs>
</Box>
<TabPanel
index={WORKPLAN_TAB.WORKPLAN.index}
value={selectedTabIndex}
sx={{
...tabPanel,
}}
>
<PhaseContainer />
</TabPanel>
<TabPanel
index={WORKPLAN_TAB.STATUS.index}
value={selectedTabIndex}
sx={{
...tabPanel,
}}
>
<Status />
</TabPanel>
<TabPanel
index={WORKPLAN_TAB.ISSUES.index}
value={selectedTabIndex}
sx={{
...tabPanel,
}}
>
<Issues />
</TabPanel>
<TabPanel
index={WORKPLAN_TAB.ABOUT.index}
value={selectedTabIndex}
sx={{
...tabPanel,
}}
>
<About />
</TabPanel>
<TabPanel
index={WORKPLAN_TAB.TEAM.index}
value={selectedTabIndex}
sx={{
...tabPanel,
}}
>
<TeamContainer />
</TabPanel>
<TabPanel
index={WORKPLAN_TAB.FIRST_NATIONS.index}
value={selectedTabIndex}
sx={{
...tabPanel,
}}
>
<FirstNationContainer />
</TabPanel>
</ETPageContainer>
>
<FirstNationContainer />
</TabPanel>
</ETPageContainer>
)}
</>
);
};

Expand Down
Loading