From 47965a859bd0c6470569cb90c29f2bc21f71b403 Mon Sep 17 00:00:00 2001 From: Piotr Rudnicki Date: Fri, 13 Dec 2024 16:19:45 +0100 Subject: [PATCH] [Nu-7330] Use activities endpoint to compute ranges in counts window --- designer/client/cypress/e2e/counts.cy.ts | 2 +- .../modals/CalculateCounts/CountsRanges.tsx | 8 +-- .../CalculateCounts/useActivityHistory.ts | 54 +++++++++++++++++++ .../components/toolbars/activities/types.ts | 7 +++ designer/client/src/http/HttpService.ts | 24 ++++++++- 5 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 designer/client/src/components/modals/CalculateCounts/useActivityHistory.ts diff --git a/designer/client/cypress/e2e/counts.cy.ts b/designer/client/cypress/e2e/counts.cy.ts index 6a3042c53ed..7da9ff3a86c 100644 --- a/designer/client/cypress/e2e/counts.cy.ts +++ b/designer/client/cypress/e2e/counts.cy.ts @@ -44,7 +44,7 @@ describe("Counts", () => { cy.get("@button").click(); cy.get("[data-testid=window]").contains("Quick ranges").should("be.visible"); - cy.contains(/^previous deployments...$/i) + cy.contains(/^previous activities...$/i) .should("be.visible") .click(); cy.get("[data-testid=window]").matchImage({ maxDiffThreshold }); diff --git a/designer/client/src/components/modals/CalculateCounts/CountsRanges.tsx b/designer/client/src/components/modals/CalculateCounts/CountsRanges.tsx index ea53dc1c1c5..0d03b9aa697 100644 --- a/designer/client/src/components/modals/CalculateCounts/CountsRanges.tsx +++ b/designer/client/src/components/modals/CalculateCounts/CountsRanges.tsx @@ -4,9 +4,9 @@ import { useTranslation } from "react-i18next"; import { useSelector } from "react-redux"; import { getProcessName } from "../../../reducers/selectors/graph"; import { CountsRangesButtons } from "./CountsRangesButtons"; -import { useDeployHistory } from "./useDeployHistory"; import { predefinedRanges } from "./utils"; import { StyledRangesWrapper } from "./CountsStyled"; +import { useActivityHistory } from "./useActivityHistory"; interface RangesProps { label: string; @@ -16,7 +16,7 @@ interface RangesProps { export function CountsRanges({ label, onChange }: RangesProps): JSX.Element { const { t } = useTranslation(); const processName = useSelector(getProcessName); - const deploys = useDeployHistory(processName); + const activities = useActivityHistory(processName); const dates = useMemo(() => predefinedRanges(t), [t]); return ( @@ -24,8 +24,8 @@ export function CountsRanges({ label, onChange }: RangesProps): JSX.Element {

{label}

- - {t("calculateCounts.deployments", "Previous deployments...")} + + {t("calculateCounts.activities", "Previous activities...")} diff --git a/designer/client/src/components/modals/CalculateCounts/useActivityHistory.ts b/designer/client/src/components/modals/CalculateCounts/useActivityHistory.ts new file mode 100644 index 00000000000..b2e813a4e33 --- /dev/null +++ b/designer/client/src/components/modals/CalculateCounts/useActivityHistory.ts @@ -0,0 +1,54 @@ +import { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import HttpService from "../../../http/HttpService"; +import { DATE_FORMAT } from "../../../config"; +import { Range } from "./CountsRangesButtons"; +import moment from "moment"; +import { PredefinedActivityType } from "../../toolbars/activities/types"; + +function displayableNameOfPredefinedActivityType(predefinedActivityType: PredefinedActivityType) { + switch (predefinedActivityType) { + case PredefinedActivityType.ScenarioCanceled: + return "Cancel"; + case PredefinedActivityType.ScenarioDeployed: + return "Deployment"; + case PredefinedActivityType.PerformedScheduledExecution: + return "Scheduled deployment"; + case PredefinedActivityType.PerformedSingleExecution: + return "Run now"; + default: + return "Unknown activity type"; + } +} + +export function useActivityHistory(processName: string): Range[] { + const { t } = useTranslation(); + const [activities, setActivities] = useState([]); + + useEffect(() => { + HttpService.fetchProcessesActivities(processName) + .then((activities) => + activities.map((current, i, all) => { + const from = moment(current.date); + const to = all[i - 1]?.date; + const isOmitted = current.type === PredefinedActivityType.ScenarioCanceled; + return { + from: () => from, + to: () => (to ? moment(to) : moment().add(1, "day").startOf("day")), + name: i + ? t("calculateCounts.range.prevAction", "Previous {{activity}} #{{i}} {{date}}", { + activity: displayableNameOfPredefinedActivityType(current.type), + i: all.length - i, + date: from.format(DATE_FORMAT), + }) + : t("calculateCounts.range.lastDeploy", "Latest deploy"), + isOmitted, + }; + }), + ) + .then((res) => res.filter((activity) => !activity.isOmitted)) + .then(setActivities); + }, [t, processName]); + + return activities; +} diff --git a/designer/client/src/components/toolbars/activities/types.ts b/designer/client/src/components/toolbars/activities/types.ts index 2c7712826ae..2dc1f7ff542 100644 --- a/designer/client/src/components/toolbars/activities/types.ts +++ b/designer/client/src/components/toolbars/activities/types.ts @@ -17,6 +17,13 @@ export type ActivityType = | "AUTOMATIC_UPDATE" | "CUSTOM_ACTION"; +export enum PredefinedActivityType { + ScenarioDeployed = "SCENARIO_DEPLOYED", + ScenarioCanceled = "SCENARIO_CANCELED", + PerformedSingleExecution = "PERFORMED_SINGLE_EXECUTION", + PerformedScheduledExecution = "PERFORMED_SCHEDULED_EXECUTION", +} + export interface ActivityMetadata { type: ActivityType; displayableName: string; diff --git a/designer/client/src/http/HttpService.ts b/designer/client/src/http/HttpService.ts index 375d2ec3c9b..abd9f30b4e5 100644 --- a/designer/client/src/http/HttpService.ts +++ b/designer/client/src/http/HttpService.ts @@ -22,7 +22,12 @@ import { Scenario, StatusDefinitionType, } from "../components/Process/types"; -import { ActivitiesResponse, ActivityMetadataResponse } from "../components/toolbars/activities/types"; +import { + ActivitiesResponse, + ActivityMetadataResponse, + ActivityType, + PredefinedActivityType, +} from "../components/toolbars/activities/types"; import { ToolbarsConfig } from "../components/toolbarSettings/types"; import { EventTrackingSelectorType, EventTrackingType } from "../containers/event-tracking"; import { BackendNotification } from "../containers/Notifications"; @@ -321,6 +326,23 @@ class HttpService { return promise; } + fetchProcessesActivities(processName: string) { + return api + .get<{ activities: { date: string; type: ActivityType }[] }>( + `/processes/${encodeURIComponent(processName)}/activity/activities`, + ) + .then((res) => { + return res.data.activities.filter( + ({ date, type }) => + type === PredefinedActivityType.ScenarioDeployed || + type === PredefinedActivityType.ScenarioCanceled || + type === PredefinedActivityType.PerformedSingleExecution || + type === PredefinedActivityType.PerformedScheduledExecution, + ); + }) + .then((res) => res.reverse().map((item) => ({ ...item, type: item.type as PredefinedActivityType }))); + } + fetchProcessesDeployments(processName: string) { return api .get<