From 94580cd3adfae5cc52f9601776bc1357ca1ed2d2 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Wed, 27 Mar 2024 06:46:21 +0100 Subject: [PATCH] Implement evt of clusterEventsMonitor usecase --- web/src/core/usecases/clusterEvents/evt.ts | 29 ----- .../core/usecases/clusterEvents/selectors.ts | 100 ------------------ .../core/usecases/clusterEventsMonitor/evt.ts | 31 ++++++ .../index.ts | 0 .../clusterEventsMonitor/selectors.ts | 45 ++++++++ .../state.ts | 2 +- .../thunks.ts | 0 web/src/core/usecases/index.ts | 2 + 8 files changed, 79 insertions(+), 130 deletions(-) delete mode 100644 web/src/core/usecases/clusterEvents/evt.ts delete mode 100644 web/src/core/usecases/clusterEvents/selectors.ts create mode 100644 web/src/core/usecases/clusterEventsMonitor/evt.ts rename web/src/core/usecases/{clusterEvents => clusterEventsMonitor}/index.ts (100%) create mode 100644 web/src/core/usecases/clusterEventsMonitor/selectors.ts rename web/src/core/usecases/{clusterEvents => clusterEventsMonitor}/state.ts (98%) rename web/src/core/usecases/{clusterEvents => clusterEventsMonitor}/thunks.ts (100%) diff --git a/web/src/core/usecases/clusterEvents/evt.ts b/web/src/core/usecases/clusterEvents/evt.ts deleted file mode 100644 index 4a4f1a2a0..000000000 --- a/web/src/core/usecases/clusterEvents/evt.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { CreateEvt } from "core/bootstrap"; -import { name } from "./state"; -import { Evt } from "evt"; - -export const createEvt = (({ evtAction }) => { - const evtOut = Evt.create<{ - actionName: "redirect away"; - }>(); - - evtAction.attach( - action => - action.usecaseName === "projectManagement" && - action.actionName === "projectChanged", - () => { - evtOut.post({ "actionName": "redirect away" }); - } - ); - - evtAction.attach( - action => - action.usecaseName === name && - action.actionName === "notifyHelmReleaseNoLongerExists", - () => { - evtOut.post({ "actionName": "redirect away" }); - } - ); - - return evtOut; -}) satisfies CreateEvt; diff --git a/web/src/core/usecases/clusterEvents/selectors.ts b/web/src/core/usecases/clusterEvents/selectors.ts deleted file mode 100644 index bcf197083..000000000 --- a/web/src/core/usecases/clusterEvents/selectors.ts +++ /dev/null @@ -1,100 +0,0 @@ -import type { State as RootState } from "core/bootstrap"; -import { createSelector } from "clean-architecture"; -import { assert } from "tsafe/assert"; -import { name } from "./state"; - -const state = (rootState: RootState) => rootState[name]; - -const readyState = createSelector(state, state => { - if (state.stateDescription !== "ready") { - return undefined; - } - - return state; -}); - -const isReady = createSelector(state, state => state.stateDescription === "ready"); - -const helmReleaseName = createSelector(state, state => { - if (state.stateDescription === "not initialized" && !state.isFetching) { - return undefined; - } - - const { helmReleaseName } = state; - - return helmReleaseName; -}); - -const helmReleaseFriendlyName = createSelector(readyState, state => { - if (state === undefined) { - return undefined; - } - - const { helmReleaseFriendlyName } = state; - - return helmReleaseFriendlyName; -}); - -const tasks = createSelector(readyState, state => { - if (state === undefined) { - return []; - } - - return state.tasks; -}); - -const events = createSelector(readyState, state => { - if (state === undefined) { - return undefined; - } - - const { events } = state; - - return events; -}); - -const env = createSelector(readyState, state => { - if (state === undefined) { - return undefined; - } - - const { env } = state; - - return env; -}); - -const main = createSelector( - isReady, - helmReleaseName, - helmReleaseFriendlyName, - tasks, - events, - env, - (isReady, helmReleaseName, helmReleaseFriendlyName, tasks, events, env) => { - if (!isReady) { - return { - "isReady": false as const, - helmReleaseName - }; - } - - assert(helmReleaseName !== undefined); - assert(helmReleaseFriendlyName !== undefined); - assert(tasks !== undefined); - assert(events !== undefined); - assert(env !== undefined); - - return { - "isReady": true, - helmReleaseName, - helmReleaseFriendlyName, - tasks, - events, - env - }; - } -); - -export const selectors = { - main -}; diff --git a/web/src/core/usecases/clusterEventsMonitor/evt.ts b/web/src/core/usecases/clusterEventsMonitor/evt.ts new file mode 100644 index 000000000..107b07b1e --- /dev/null +++ b/web/src/core/usecases/clusterEventsMonitor/evt.ts @@ -0,0 +1,31 @@ +import type { CreateEvt } from "core/bootstrap"; +import { Evt } from "evt"; + +export const createEvt = (({ evtAction }) => { + const evtOut = Evt.create<{ + actionName: "display notification"; + severity: "warning" | "error"; + message: string; + }>(); + + evtAction.$attach( + action => + action.usecaseName === "clusterEventsMonitor" && + action.actionName === "clusterEventReceived" + ? [action.payload] + : null, + ({ clusterEvent }) => { + if (clusterEvent.severity === "info") { + return; + } + + evtOut.post({ + "actionName": "display notification", + "message": clusterEvent.message, + "severity": clusterEvent.severity + }); + } + ); + + return evtOut; +}) satisfies CreateEvt; diff --git a/web/src/core/usecases/clusterEvents/index.ts b/web/src/core/usecases/clusterEventsMonitor/index.ts similarity index 100% rename from web/src/core/usecases/clusterEvents/index.ts rename to web/src/core/usecases/clusterEventsMonitor/index.ts diff --git a/web/src/core/usecases/clusterEventsMonitor/selectors.ts b/web/src/core/usecases/clusterEventsMonitor/selectors.ts new file mode 100644 index 000000000..b5e07c976 --- /dev/null +++ b/web/src/core/usecases/clusterEventsMonitor/selectors.ts @@ -0,0 +1,45 @@ +import type { State as RootState } from "core/bootstrap"; +import * as projectManagement from "core/usecases/projectManagement"; +import { createSelector } from "clean-architecture"; +import { name } from "./state"; + +const state = (rootState: RootState) => rootState[name]; + +const scopedState = createSelector( + state, + projectManagement.selectors.currentProject, + (state, currentProject) => { + const scopedState = state.clusterEventsByProjectId[currentProject.id]; + + if (scopedState === undefined) { + return { + "clusterEvents": [], + "notificationCheckoutTime": 0 + }; + } + + return scopedState; + } +); + +const clusterEvents = createSelector(scopedState, scopedState => { + const { clusterEvents, notificationCheckoutTime } = scopedState; + + return clusterEvents.map(clusterEvent => ({ + ...clusterEvent, + "isHighlighted": + clusterEvent.severity !== "info" && + clusterEvent.timestamp > notificationCheckoutTime + })); +}); + +const notificationsCount = createSelector( + clusterEvents, + clusterEvents => + clusterEvents.filter(clusterEvent => clusterEvent.isHighlighted).length +); + +export const selectors = { + clusterEvents, + notificationsCount +}; diff --git a/web/src/core/usecases/clusterEvents/state.ts b/web/src/core/usecases/clusterEventsMonitor/state.ts similarity index 98% rename from web/src/core/usecases/clusterEvents/state.ts rename to web/src/core/usecases/clusterEventsMonitor/state.ts index d4843c64e..2136f311e 100644 --- a/web/src/core/usecases/clusterEvents/state.ts +++ b/web/src/core/usecases/clusterEventsMonitor/state.ts @@ -17,7 +17,7 @@ export type State = { >; }; -export const name = "custerEvents"; +export const name = "clusterEventsMonitor"; export const { reducer, actions } = createUsecaseActions({ name, diff --git a/web/src/core/usecases/clusterEvents/thunks.ts b/web/src/core/usecases/clusterEventsMonitor/thunks.ts similarity index 100% rename from web/src/core/usecases/clusterEvents/thunks.ts rename to web/src/core/usecases/clusterEventsMonitor/thunks.ts diff --git a/web/src/core/usecases/index.ts b/web/src/core/usecases/index.ts index 031a44c41..f53d1f098 100644 --- a/web/src/core/usecases/index.ts +++ b/web/src/core/usecases/index.ts @@ -1,5 +1,6 @@ import * as autoLogoutCountdown from "./autoLogoutCountdown"; import * as catalog from "./catalog"; +import * as clusterEventsMonitor from "./clusterEventsMonitor"; import * as deploymentRegionManagement from "./deploymentRegionManagement"; import * as fileExplorer from "./fileExplorer"; import * as secretExplorer from "./secretExplorer"; @@ -23,6 +24,7 @@ import * as viewQuotas from "./viewQuotas"; export const usecases = { autoLogoutCountdown, catalog, + clusterEventsMonitor, deploymentRegionManagement, fileExplorer, secretExplorer,