From 80b5d609f4f458dec8f8814277c6c1946e399424 Mon Sep 17 00:00:00 2001 From: Adrien Delannoy Date: Sun, 30 Jun 2024 13:48:52 +0200 Subject: [PATCH 1/4] feat: add start/end workflows ISO display switch Signed-off-by: Adrien Delannoy --- .../cluster-workflow-template-list.tsx | 3 +- .../app/cron-workflows/cron-workflow-list.tsx | 11 ++++- .../cron-workflow-status-viewer.tsx | 3 +- .../app/event-sources/event-source-list.tsx | 3 +- ui/src/app/sensors/sensor-list.tsx | 3 +- ui/src/app/shared/components/timestamp.tsx | 46 ++++++++++++++----- ui/src/app/shared/use-timestamp.ts | 40 ++++++++++++++++ .../workflow-template-list.tsx | 3 +- .../app/workflows/components/events-panel.tsx | 3 +- .../components/workflow-artifacts.tsx | 3 +- .../workflow-node-info/workflow-node-info.tsx | 25 +++++----- .../components/workflow-summary-panel.tsx | 5 +- .../workflows-row/workflows-row.tsx | 5 +- 13 files changed, 115 insertions(+), 38 deletions(-) create mode 100644 ui/src/app/shared/use-timestamp.ts diff --git a/ui/src/app/cluster-workflow-templates/cluster-workflow-template-list.tsx b/ui/src/app/cluster-workflow-templates/cluster-workflow-template-list.tsx index 2e52d4591658..0434bf667aed 100644 --- a/ui/src/app/cluster-workflow-templates/cluster-workflow-template-list.tsx +++ b/ui/src/app/cluster-workflow-templates/cluster-workflow-template-list.tsx @@ -20,6 +20,7 @@ import {services} from '../shared/services'; import {ClusterWorkflowTemplateCreator} from './cluster-workflow-template-creator'; import './cluster-workflow-template-list.scss'; +import {TIMESTAMP_KEYS} from '../shared/use-timestamp'; export function ClusterWorkflowTemplateList({history, location}: RouteComponentProps) { const {navigation} = useContext(Context); @@ -84,7 +85,7 @@ export function ClusterWorkflowTemplateList({history, location}: RouteComponentP
{t.metadata.name}
- +
))} diff --git a/ui/src/app/cron-workflows/cron-workflow-list.tsx b/ui/src/app/cron-workflows/cron-workflow-list.tsx index 48809f7d5871..2d7e1d4f79ef 100644 --- a/ui/src/app/cron-workflows/cron-workflow-list.tsx +++ b/ui/src/app/cron-workflows/cron-workflow-list.tsx @@ -27,6 +27,7 @@ import {CronWorkflowFilters} from './cron-workflow-filters'; import {PrettySchedule} from './pretty-schedule'; import './cron-workflow-list.scss'; +import {TIMESTAMP_KEYS} from '../shared/use-timestamp'; const learnMore = Learn more; @@ -180,10 +181,16 @@ export function CronWorkflowList({match, location, history}: RouteComponentProps )}
- +
- {w.spec.suspend ? '' : {() => }} + {w.spec.suspend ? ( + '' + ) : ( + + {() => } + + )}
))} diff --git a/ui/src/app/cron-workflows/cron-workflow-status-viewer.tsx b/ui/src/app/cron-workflows/cron-workflow-status-viewer.tsx index e3a72e9a6242..6a82045871d4 100644 --- a/ui/src/app/cron-workflows/cron-workflow-status-viewer.tsx +++ b/ui/src/app/cron-workflows/cron-workflow-status-viewer.tsx @@ -6,6 +6,7 @@ import {Timestamp} from '../shared/components/timestamp'; import {ConditionsPanel} from '../shared/conditions-panel'; import {WorkflowLink} from '../workflows/components/workflow-link'; import {PrettySchedule} from './pretty-schedule'; +import {TIMESTAMP_KEYS} from '../shared/use-timestamp'; export function CronWorkflowStatusViewer({spec, status}: {spec: CronWorkflowSpec; status: CronWorkflowStatus}) { if (status === null) { @@ -35,7 +36,7 @@ export function CronWorkflowStatusViewer({spec, status}: {spec: CronWorkflowSpec ) }, - {title: 'Last Scheduled Time', value: }, + {title: 'Last Scheduled Time', value: }, {title: 'Conditions', value: } ].map(attr => (
diff --git a/ui/src/app/event-sources/event-source-list.tsx b/ui/src/app/event-sources/event-source-list.tsx index a2796cfb7769..5dcaae79e976 100644 --- a/ui/src/app/event-sources/event-source-list.tsx +++ b/ui/src/app/event-sources/event-source-list.tsx @@ -26,6 +26,7 @@ import {Utils} from '../shared/utils'; import {EventsPanel} from '../workflows/components/events-panel'; import {EventSourceCreator} from './event-source-creator'; import {EventSourceLogsViewer} from './event-source-log-viewer'; +import {TIMESTAMP_KEYS} from '../shared/use-timestamp'; const learnMore = Learn more; @@ -140,7 +141,7 @@ export function EventSourceList({match, location, history}: RouteComponentProps<
{es.metadata.name}
{es.metadata.namespace}
- +
Learn more; @@ -138,7 +139,7 @@ export function SensorList({match, location, history}: RouteComponentProps)
{s.metadata.name}
{s.metadata.namespace}
- +
-; -export function Timestamp({date}: {date: Date | string | number}) { - const tooltip = (utc: Date | string | number) => { - return utc.toString() + '\n' + new Date(utc.toString()).toLocaleString(); - }; return ( - {date === null || date === undefined ? ( - '-' - ) : ( - - {() => ago(new Date(date))} - - )} + + {displayISOFormat ? ( + new Date(date.toString()).toISOString() + ) : ( + <> + {displayLocalDateTime ? ( + <> + {new Date(date.toString()).toLocaleString()} ({() => ago(new Date(date))}) + + ) : ( + {() => ago(new Date(date))} + )} + + )} + + + + { + e.stopPropagation(); + e.preventDefault(); + setDisplayISOFormat(!displayISOFormat); + }} + /> + + ); } diff --git a/ui/src/app/shared/use-timestamp.ts b/ui/src/app/shared/use-timestamp.ts new file mode 100644 index 000000000000..7e6f5397d1eb --- /dev/null +++ b/ui/src/app/shared/use-timestamp.ts @@ -0,0 +1,40 @@ +import React from 'react'; +import {ScopedLocalStorage} from './scoped-local-storage'; + +export enum TIMESTAMP_KEYS { + WORKFLOW_NODE_STARTED = 'workflowNodeStarted', + WORKFLOW_NODE_FINISHED = 'workflowNodeFinished', + CLUSTER_WORKFLOW_TEMPLATE_LIST = 'clusterWorkflowTemplateList', + CRON_WORKFLOW_LIST_CREATION = 'cronWorkflowListCreation', + CRON_WORKFLOW_LIST_NEXT_SCHEDULED = 'cronWorkflowListNextScheduled', + CRON_WORKFLOW_STATUS_LAST_SCHEDULED = 'cronWorkflowStatusLastScheduled', + EVENT_SOURCE_LIST_CREATION = 'eventSourceListCreation', + SENSOR_LIST_CREATION = 'sensorListCreation', + EVENTS_PANEL_LAST = 'eventsPanelLast', + WORKFLOW_ARTIFACTS_CREATED = 'workflowArtifactsCreated', + WORKFLOW_SUMMARY_PANEL_START = 'workflowSummaryPanelStart', + WORKFLOW_SUMMARY_PANEL_END = 'workflowSummaryPanelEnd', + WORKFLOW_NODE_ARTIFACT_CREATED = 'workflowNodeArtifactCreated', + WORKFLOW_TEMPLATE_LIST_CREATION = 'workflowTemplateListCreation', + WORKFLOWS_ROW_STARTED = 'workflowsRowStarted', + WORKFLOWS_ROW_FINISHED = 'workflowsRowFinished' +} + +const storage = new ScopedLocalStorage('Timestamp'); + +// key is used to store the preference in local storage +const useTimestamp = (timestampKey: TIMESTAMP_KEYS) => { + const [displayISOFormat, setDisplayISOFormat] = React.useState(storage.getItem(`displayISOFormat-${timestampKey}`, false)); + + const handleDisplayISOFormatChange = (value: boolean) => { + setDisplayISOFormat(value); + storage.setItem(`displayISOFormat-${timestampKey}`, value, false); + }; + + return { + displayISOFormat, + setDisplayISOFormat: handleDisplayISOFormatChange + }; +}; + +export default useTimestamp; diff --git a/ui/src/app/workflow-templates/workflow-template-list.tsx b/ui/src/app/workflow-templates/workflow-template-list.tsx index 7f40a15db439..8eee872e64dd 100644 --- a/ui/src/app/workflow-templates/workflow-template-list.tsx +++ b/ui/src/app/workflow-templates/workflow-template-list.tsx @@ -27,6 +27,7 @@ import {WorkflowTemplateCreator} from './workflow-template-creator'; import {WorkflowTemplateFilters} from './workflow-template-filters'; import './workflow-template-list.scss'; +import {TIMESTAMP_KEYS} from '../shared/use-timestamp'; const learnMore = Learn more; @@ -154,7 +155,7 @@ export function WorkflowTemplateList({match, location, history}: RouteComponentP
{t.metadata.namespace}
- +
))} diff --git a/ui/src/app/workflows/components/events-panel.tsx b/ui/src/app/workflows/components/events-panel.tsx index 3e1fd61bd67c..db427de49816 100644 --- a/ui/src/app/workflows/components/events-panel.tsx +++ b/ui/src/app/workflows/components/events-panel.tsx @@ -9,6 +9,7 @@ import {ToggleButton} from '../../shared/components/toggle-button'; import debounce from '../../shared/debounce'; import {ListWatch} from '../../shared/list-watch'; import {services} from '../../shared/services'; +import {TIMESTAMP_KEYS} from '../../shared/use-timestamp'; export function EventsPanel({namespace, name, kind}: {namespace: string; name: string; kind: string}) { const [showAll, setShowAll] = useState(false); @@ -120,7 +121,7 @@ export function EventsPanel({namespace, name, kind}: {namespace: string; name: s {e.type === 'Normal' ? : }
- +
{e.reason}
diff --git a/ui/src/app/workflows/components/workflow-artifacts.tsx b/ui/src/app/workflows/components/workflow-artifacts.tsx index 9b700ec8998b..1f9c820822c1 100644 --- a/ui/src/app/workflows/components/workflow-artifacts.tsx +++ b/ui/src/app/workflows/components/workflow-artifacts.tsx @@ -3,6 +3,7 @@ import * as React from 'react'; import * as models from '../../../models'; import {Timestamp} from '../../shared/components/timestamp'; import {services} from '../../shared/services'; +import {TIMESTAMP_KEYS} from '../../shared/use-timestamp'; interface Props { workflow: models.Workflow; @@ -53,7 +54,7 @@ export function WorkflowArtifacts(props: Props) {
{artifact.stepName}
{artifact.path}
- +
))} diff --git a/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx b/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx index 8d5c70a4ec34..7c4dc96f0a19 100644 --- a/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx +++ b/ui/src/app/workflows/components/workflow-node-info/workflow-node-info.tsx @@ -21,6 +21,7 @@ import {services} from '../../../shared/services'; import {getResolvedTemplates} from '../../../shared/template-resolution'; import './workflow-node-info.scss'; +import {TIMESTAMP_KEYS} from '../../../shared/use-timestamp'; function nodeDuration(node: models.NodeStatus, now: moment.Moment) { const endTime = node.finishedAt ? moment(node.finishedAt) : now; @@ -82,20 +83,16 @@ const AttributeRows = (props: {attributes: {title: string; value: any}[]}) => (
); -function DisplayWorkflowTime(props: {date: Date | string | number}) { +function DisplayWorkflowTime(props: {date: Date | string | number; timestampKey: TIMESTAMP_KEYS}) { const {date} = props; - const getLocalDateTime = (utc: Date | string | number) => { - return new Date(utc.toString()).toLocaleString(); - }; + + if (date === null || date === undefined) return
-
; + return (
- {date === null || date === undefined ? ( - '-' - ) : ( - - {getLocalDateTime(date)} () - - )} + + +
); } @@ -120,8 +117,8 @@ function WorkflowNodeSummary(props: Props) { } ] : []), - {title: 'START TIME', value: }, - {title: 'END TIME', value: }, + {title: 'START TIME', value: }, + {title: 'END TIME', value: }, { title: 'DURATION', value: {now => } @@ -450,7 +447,7 @@ function WorkflowNodeArtifacts(props: {workflow: Workflow; node: NodeStatus; arc {artifact.path} - +
diff --git a/ui/src/app/workflows/components/workflow-summary-panel.tsx b/ui/src/app/workflows/components/workflow-summary-panel.tsx index 36cade2327e8..85d66735b7b7 100644 --- a/ui/src/app/workflows/components/workflow-summary-panel.tsx +++ b/ui/src/app/workflows/components/workflow-summary-panel.tsx @@ -13,6 +13,7 @@ import {ResourcesDuration} from '../../shared/resources-duration'; import {WorkflowCreatorInfo} from './workflow-creator-info/workflow-creator-info'; import {WorkflowFrom} from './workflow-from'; import {WorkflowLabels} from './workflow-labels/workflow-labels'; +import {TIMESTAMP_KEYS} from '../../shared/use-timestamp'; export const WorkflowSummaryPanel = (props: {workflow: Workflow}) => ( @@ -36,8 +37,8 @@ export const WorkflowSummaryPanel = (props: {workflow: Workflow}) => ( ) }, - {title: 'Started', value: }, - {title: 'Finished ', value: }, + {title: 'Started', value: }, + {title: 'Finished ', value: }, { title: 'Duration', value: ( diff --git a/ui/src/app/workflows/components/workflows-row/workflows-row.tsx b/ui/src/app/workflows/components/workflows-row/workflows-row.tsx index b7aba72bf9cb..303d25754d72 100644 --- a/ui/src/app/workflows/components/workflows-row/workflows-row.tsx +++ b/ui/src/app/workflows/components/workflows-row/workflows-row.tsx @@ -13,6 +13,7 @@ import {PhaseIcon} from '../../../shared/components/phase-icon'; import {Timestamp} from '../../../shared/components/timestamp'; import {wfDuration} from '../../../shared/duration'; import {WorkflowDrawer} from '../workflow-drawer/workflow-drawer'; +import {TIMESTAMP_KEYS} from '../../../shared/use-timestamp'; require('./workflows-row.scss'); @@ -61,10 +62,10 @@ export function WorkflowsRow(props: WorkflowsRowProps) {
{wf.metadata.namespace}
- +
- +
{() => } From 40f0258078010904dc3552fa1387e59e1ded3aed Mon Sep 17 00:00:00 2001 From: Adrien Delannoy Date: Mon, 15 Jul 2024 19:08:33 +0200 Subject: [PATCH 2/4] feat: improve timestamp switch management Signed-off-by: Adrien Delannoy --- .../cluster-workflow-template-list.tsx | 12 +++-- .../app/event-sources/event-source-list.tsx | 12 +++-- ui/src/app/sensors/sensor-list.tsx | 12 +++-- ui/src/app/shared/components/timestamp.tsx | 47 ++++++++++++------- ui/src/app/shared/use-timestamp.ts | 19 ++++---- .../workflow-template-list.tsx | 12 +++-- .../app/workflows/components/events-panel.tsx | 12 +++-- .../workflow-details-list.tsx | 25 ++++++++-- .../workflows-list/workflows-list.tsx | 20 +++++++- .../workflows-row/workflows-row.tsx | 7 +-- 10 files changed, 124 insertions(+), 54 deletions(-) diff --git a/ui/src/app/cluster-workflow-templates/cluster-workflow-template-list.tsx b/ui/src/app/cluster-workflow-templates/cluster-workflow-template-list.tsx index 0434bf667aed..c5cffe6c2f96 100644 --- a/ui/src/app/cluster-workflow-templates/cluster-workflow-template-list.tsx +++ b/ui/src/app/cluster-workflow-templates/cluster-workflow-template-list.tsx @@ -10,7 +10,7 @@ import {ErrorNotice} from '../shared/components/error-notice'; import {ExampleManifests} from '../shared/components/example-manifests'; import {InfoIcon} from '../shared/components/fa-icons'; import {Loading} from '../shared/components/loading'; -import {Timestamp} from '../shared/components/timestamp'; +import {Timestamp, TimestampSwitch} from '../shared/components/timestamp'; import {useCollectEvent} from '../shared/use-collect-event'; import {ZeroState} from '../shared/components/zero-state'; import {Context} from '../shared/context'; @@ -20,7 +20,7 @@ import {services} from '../shared/services'; import {ClusterWorkflowTemplateCreator} from './cluster-workflow-template-creator'; import './cluster-workflow-template-list.scss'; -import {TIMESTAMP_KEYS} from '../shared/use-timestamp'; +import useTimestamp, {TIMESTAMP_KEYS} from '../shared/use-timestamp'; export function ClusterWorkflowTemplateList({history, location}: RouteComponentProps) { const {navigation} = useContext(Context); @@ -52,6 +52,8 @@ export function ClusterWorkflowTemplateList({history, location}: RouteComponentP useCollectEvent('openedClusterWorkflowTemplateList'); + const [storedDisplayISOFormat, setStoredDisplayISOFormat] = useTimestamp(TIMESTAMP_KEYS.CLUSTER_WORKFLOW_TEMPLATE_LIST); + function renderTemplates() { if (error) { return ; @@ -76,7 +78,9 @@ export function ClusterWorkflowTemplateList({history, location}: RouteComponentP
NAME
-
CREATED
+
+ CREATED +
{templates.map(t => ( @@ -85,7 +89,7 @@ export function ClusterWorkflowTemplateList({history, location}: RouteComponentP
{t.metadata.name}
- +
))} diff --git a/ui/src/app/event-sources/event-source-list.tsx b/ui/src/app/event-sources/event-source-list.tsx index 5dcaae79e976..f6824cfc66a6 100644 --- a/ui/src/app/event-sources/event-source-list.tsx +++ b/ui/src/app/event-sources/event-source-list.tsx @@ -14,7 +14,7 @@ import {ErrorNotice} from '../shared/components/error-notice'; import {Node} from '../shared/components/graph/types'; import {Loading} from '../shared/components/loading'; import {NamespaceFilter} from '../shared/components/namespace-filter'; -import {Timestamp} from '../shared/components/timestamp'; +import {Timestamp, TimestampSwitch} from '../shared/components/timestamp'; import {useCollectEvent} from '../shared/use-collect-event'; import {ZeroState} from '../shared/components/zero-state'; import {Context} from '../shared/context'; @@ -26,7 +26,7 @@ import {Utils} from '../shared/utils'; import {EventsPanel} from '../workflows/components/events-panel'; import {EventSourceCreator} from './event-source-creator'; import {EventSourceLogsViewer} from './event-source-log-viewer'; -import {TIMESTAMP_KEYS} from '../shared/use-timestamp'; +import useTimestamp, {TIMESTAMP_KEYS} from '../shared/use-timestamp'; const learnMore = Learn more; @@ -89,6 +89,8 @@ export function EventSourceList({match, location, history}: RouteComponentProps< useCollectEvent('openedEventSourceList'); + const [storedDisplayISOFormat, setStoredDisplayISOFormat] = useTimestamp(TIMESTAMP_KEYS.EVENT_SOURCE_LIST_CREATION); + return (
NAME
NAMESPACE
-
CREATED
+
+ CREATED +
LOGS
{eventSources.map(es => ( @@ -141,7 +145,7 @@ export function EventSourceList({match, location, history}: RouteComponentProps<
{es.metadata.name}
{es.metadata.namespace}
- +
Learn more; @@ -84,6 +84,8 @@ export function SensorList({match, location, history}: RouteComponentProps) const loading = !error && !sensors; const zeroState = (sensors || []).length === 0; + const [storedDisplayISOFormat, setStoredDisplayISOFormat] = useTimestamp(TIMESTAMP_KEYS.SENSOR_LIST_CREATION); + return ( )
NAME
NAMESPACE
-
CREATED
+
+ CREATED +
LOGS
{sensors.map(s => ( @@ -139,7 +143,7 @@ export function SensorList({match, location, history}: RouteComponentProps)
{s.metadata.name}
{s.metadata.namespace}
- +
-; return ( - {displayISOFormat ? ( + {displayISOFormatValue ? ( new Date(date.toString()).toISOString() ) : ( <> @@ -27,19 +36,25 @@ export function Timestamp({date, timestampKey, displayLocalDateTime}: {date: Dat )} - - - { - e.stopPropagation(); - e.preventDefault(); - setDisplayISOFormat(!displayISOFormat); - }} - /> - - + {timestampKey ? : null} ); } + +export function TimestampSwitch({storedDisplayISOFormat, setStoredDisplayISOFormat}: {storedDisplayISOFormat: boolean; setStoredDisplayISOFormat: (value: boolean) => void}) { + return ( + + + { + e.stopPropagation(); + e.preventDefault(); + setStoredDisplayISOFormat(!storedDisplayISOFormat); + }} + /> + + + ); +} diff --git a/ui/src/app/shared/use-timestamp.ts b/ui/src/app/shared/use-timestamp.ts index 7e6f5397d1eb..53085de8a8c0 100644 --- a/ui/src/app/shared/use-timestamp.ts +++ b/ui/src/app/shared/use-timestamp.ts @@ -1,4 +1,4 @@ -import React from 'react'; +import {useState} from 'react'; import {ScopedLocalStorage} from './scoped-local-storage'; export enum TIMESTAMP_KEYS { @@ -17,24 +17,23 @@ export enum TIMESTAMP_KEYS { WORKFLOW_NODE_ARTIFACT_CREATED = 'workflowNodeArtifactCreated', WORKFLOW_TEMPLATE_LIST_CREATION = 'workflowTemplateListCreation', WORKFLOWS_ROW_STARTED = 'workflowsRowStarted', - WORKFLOWS_ROW_FINISHED = 'workflowsRowFinished' + WORKFLOWS_ROW_FINISHED = 'workflowsRowFinished', + CRON_ROW_STARTED = 'cronRowStarted', + CRON_ROW_FINISHED = 'cronRowFinished' } const storage = new ScopedLocalStorage('Timestamp'); // key is used to store the preference in local storage -const useTimestamp = (timestampKey: TIMESTAMP_KEYS) => { - const [displayISOFormat, setDisplayISOFormat] = React.useState(storage.getItem(`displayISOFormat-${timestampKey}`, false)); +const useTimestamp = (timestampKey: TIMESTAMP_KEYS): [boolean, (value: boolean) => void] => { + const [storedDisplayISOFormat, setStoredDisplayISOFormat] = useState(storage.getItem(`displayISOFormat-${timestampKey}`, false)); - const handleDisplayISOFormatChange = (value: boolean) => { - setDisplayISOFormat(value); + const handleStoredDisplayISOFormatChange = (value: boolean) => { + setStoredDisplayISOFormat(value); storage.setItem(`displayISOFormat-${timestampKey}`, value, false); }; - return { - displayISOFormat, - setDisplayISOFormat: handleDisplayISOFormatChange - }; + return [storedDisplayISOFormat, handleStoredDisplayISOFormatChange]; }; export default useTimestamp; diff --git a/ui/src/app/workflow-templates/workflow-template-list.tsx b/ui/src/app/workflow-templates/workflow-template-list.tsx index 8eee872e64dd..8e11dc92c348 100644 --- a/ui/src/app/workflow-templates/workflow-template-list.tsx +++ b/ui/src/app/workflow-templates/workflow-template-list.tsx @@ -12,7 +12,7 @@ import {ExampleManifests} from '../shared/components/example-manifests'; import {InfoIcon} from '../shared/components/fa-icons'; import {Loading} from '../shared/components/loading'; import {PaginationPanel} from '../shared/components/pagination-panel'; -import {Timestamp} from '../shared/components/timestamp'; +import {Timestamp, TimestampSwitch} from '../shared/components/timestamp'; import {useCollectEvent} from '../shared/use-collect-event'; import {ZeroState} from '../shared/components/zero-state'; import {Context} from '../shared/context'; @@ -27,7 +27,7 @@ import {WorkflowTemplateCreator} from './workflow-template-creator'; import {WorkflowTemplateFilters} from './workflow-template-filters'; import './workflow-template-list.scss'; -import {TIMESTAMP_KEYS} from '../shared/use-timestamp'; +import useTimestamp, {TIMESTAMP_KEYS} from '../shared/use-timestamp'; const learnMore = Learn more; @@ -86,6 +86,8 @@ export function WorkflowTemplateList({match, location, history}: RouteComponentP useCollectEvent('openedWorkflowTemplateList'); + const [storedDisplayISOFormat, setStoredDisplayISOFormat] = useTimestamp(TIMESTAMP_KEYS.WORKFLOW_TEMPLATE_LIST_CREATION); + return (
NAME
NAMESPACE
-
CREATED
+
+ CREATED +
{templates.map(t => (
{t.metadata.namespace}
- +
))} diff --git a/ui/src/app/workflows/components/events-panel.tsx b/ui/src/app/workflows/components/events-panel.tsx index db427de49816..dae92540688b 100644 --- a/ui/src/app/workflows/components/events-panel.tsx +++ b/ui/src/app/workflows/components/events-panel.tsx @@ -4,12 +4,12 @@ import {map} from 'rxjs/operators'; import {Event} from '../../../models'; import {ErrorNotice} from '../../shared/components/error-notice'; import {Notice} from '../../shared/components/notice'; -import {Timestamp} from '../../shared/components/timestamp'; +import {Timestamp, TimestampSwitch} from '../../shared/components/timestamp'; import {ToggleButton} from '../../shared/components/toggle-button'; import debounce from '../../shared/debounce'; import {ListWatch} from '../../shared/list-watch'; import {services} from '../../shared/services'; -import {TIMESTAMP_KEYS} from '../../shared/use-timestamp'; +import useTimestamp, {TIMESTAMP_KEYS} from '../../shared/use-timestamp'; export function EventsPanel({namespace, name, kind}: {namespace: string; name: string; kind: string}) { const [showAll, setShowAll] = useState(false); @@ -88,6 +88,8 @@ export function EventsPanel({namespace, name, kind}: {namespace: string; name: s }; }); + const [storedDisplayISOFormat, setStoredDisplayISOFormat] = useTimestamp(TIMESTAMP_KEYS.EVENTS_PANEL_LAST); + return ( <>
@@ -107,7 +109,9 @@ export function EventsPanel({namespace, name, kind}: {namespace: string; name: s
Type
-
Last Seen
+
+ Last Seen +
Reason
Object
Message
@@ -121,7 +125,7 @@ export function EventsPanel({namespace, name, kind}: {namespace: string; name: s {e.type === 'Normal' ? : }
- +
{e.reason}
diff --git a/ui/src/app/workflows/components/workflow-details-list/workflow-details-list.tsx b/ui/src/app/workflows/components/workflow-details-list/workflow-details-list.tsx index 40dbb9e427b4..68f8bef5e90b 100644 --- a/ui/src/app/workflows/components/workflow-details-list/workflow-details-list.tsx +++ b/ui/src/app/workflows/components/workflow-details-list/workflow-details-list.tsx @@ -4,6 +4,8 @@ import * as models from '../../../../models'; import {WorkflowsRow} from '../../../workflows/components/workflows-row/workflows-row'; import './workflow-details-list.scss'; +import useTimestamp, {TIMESTAMP_KEYS} from '../../../shared/use-timestamp'; +import {TimestampSwitch} from '../../../shared/components/timestamp'; interface WorkflowDetailsList { workflows: models.Workflow[]; @@ -11,6 +13,8 @@ interface WorkflowDetailsList { } export function WorkflowDetailsList(props: WorkflowDetailsList) { + const [storedDisplayISOFormatStart, setStoredDisplayISOFormatStart] = useTimestamp(TIMESTAMP_KEYS.CRON_ROW_STARTED); + const [storedDisplayISOFormatFinished, setStoredDisplayISOFormatFinished] = useTimestamp(TIMESTAMP_KEYS.CRON_ROW_FINISHED); return (
@@ -18,8 +22,12 @@ export function WorkflowDetailsList(props: WorkflowDetailsList) {
NAME
NAMESPACE
-
STARTED
-
FINISHED
+
+ STARTED +
+
+ FINISHED +
DURATION
PROGRESS
MESSAGE
@@ -36,7 +44,18 @@ export function WorkflowDetailsList(props: WorkflowDetailsList) {
{/* checkboxes are not visible and are unused in details pages */} {props.workflows.map(wf => { - return ; + return ( + + ); })}
); diff --git a/ui/src/app/workflows/components/workflows-list/workflows-list.tsx b/ui/src/app/workflows/components/workflows-list/workflows-list.tsx index d1c9b3ab6630..e994cef30955 100644 --- a/ui/src/app/workflows/components/workflows-list/workflows-list.tsx +++ b/ui/src/app/workflows/components/workflows-list/workflows-list.tsx @@ -29,6 +29,8 @@ import {WorkflowsSummaryContainer} from '../workflows-summary-container/workflow import {WorkflowsToolbar} from '../workflows-toolbar/workflows-toolbar'; import './workflows-list.scss'; +import useTimestamp, {TIMESTAMP_KEYS} from '../../../shared/use-timestamp'; +import {TimestampSwitch} from '../../../shared/components/timestamp'; interface WorkflowListRenderOptions { paginationLimit: number; @@ -160,6 +162,9 @@ export function WorkflowsList({match, location, history}: RouteComponentProps
NAME
NAMESPACE
-
STARTED
-
FINISHED
+
+ STARTED{' '} + +
+
+ FINISHED{' '} + +
DURATION
PROGRESS
MESSAGE
@@ -305,6 +319,8 @@ export function WorkflowsList({match, location, history}: RouteComponentProps ); })} diff --git a/ui/src/app/workflows/components/workflows-row/workflows-row.tsx b/ui/src/app/workflows/components/workflows-row/workflows-row.tsx index 303d25754d72..af2ac3309b50 100644 --- a/ui/src/app/workflows/components/workflows-row/workflows-row.tsx +++ b/ui/src/app/workflows/components/workflows-row/workflows-row.tsx @@ -13,7 +13,6 @@ import {PhaseIcon} from '../../../shared/components/phase-icon'; import {Timestamp} from '../../../shared/components/timestamp'; import {wfDuration} from '../../../shared/duration'; import {WorkflowDrawer} from '../workflow-drawer/workflow-drawer'; -import {TIMESTAMP_KEYS} from '../../../shared/use-timestamp'; require('./workflows-row.scss'); @@ -23,6 +22,8 @@ interface WorkflowsRowProps { select: (wf: Workflow) => void; checked: boolean; columns: models.Column[]; + displayISOFormatStart: boolean; + displayISOFormatFinished: boolean; } export function WorkflowsRow(props: WorkflowsRowProps) { @@ -62,10 +63,10 @@ export function WorkflowsRow(props: WorkflowsRowProps) {
{wf.metadata.namespace}
- +
- +
{() => } From d3cea28bc0ae43f97ccad90944c6d3031e9e03d4 Mon Sep 17 00:00:00 2001 From: Adrien Delannoy Date: Mon, 29 Jul 2024 15:50:06 +0200 Subject: [PATCH 3/4] fix: timestamp display on cron workflow list Signed-off-by: Adrien Delannoy --- .../app/cron-workflows/cron-workflow-list.tsx | 36 ++++++++++++------- ui/src/app/shared/components/timestamp.tsx | 2 +- .../workflows-list/workflows-list.scss | 8 +++++ .../workflows-row/workflows-row.tsx | 4 +-- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/ui/src/app/cron-workflows/cron-workflow-list.tsx b/ui/src/app/cron-workflows/cron-workflow-list.tsx index 2d7e1d4f79ef..cbcf08627e84 100644 --- a/ui/src/app/cron-workflows/cron-workflow-list.tsx +++ b/ui/src/app/cron-workflows/cron-workflow-list.tsx @@ -12,7 +12,7 @@ import {ErrorNotice} from '../shared/components/error-notice'; import {ExampleManifests} from '../shared/components/example-manifests'; import {InfoIcon} from '../shared/components/fa-icons'; import {Loading} from '../shared/components/loading'; -import {Timestamp} from '../shared/components/timestamp'; +import {Timestamp, TimestampSwitch} from '../shared/components/timestamp'; import {useCollectEvent} from '../shared/use-collect-event'; import {ZeroState} from '../shared/components/zero-state'; import {Context} from '../shared/context'; @@ -27,7 +27,7 @@ import {CronWorkflowFilters} from './cron-workflow-filters'; import {PrettySchedule} from './pretty-schedule'; import './cron-workflow-list.scss'; -import {TIMESTAMP_KEYS} from '../shared/use-timestamp'; +import useTimestamp, {TIMESTAMP_KEYS} from '../shared/use-timestamp'; const learnMore = Learn more; @@ -41,6 +41,9 @@ export function CronWorkflowList({match, location, history}: RouteComponentProps const [labels, setLabels] = useState([]); const [states, setStates] = useState(['Running', 'Suspended']); // check all by default + const [storedDisplayISOFormatCreation, setStoredDisplayISOFormatCreation] = useTimestamp(TIMESTAMP_KEYS.CRON_WORKFLOW_LIST_CREATION); + const [storedDisplayISOFormatNextScheduled, setStoredDisplayISOFormatNextScheduled] = useTimestamp(TIMESTAMP_KEYS.CRON_WORKFLOW_LIST_NEXT_SCHEDULED); + useEffect( useQueryParams(history, p => { setSidePanel(p.get('sidePanel') === 'true'); @@ -136,13 +139,22 @@ export function CronWorkflowList({match, location, history}: RouteComponentProps
-
NAME
+
NAME
NAMESPACE
TimeZone
SCHEDULE
-
-
CREATED
-
NEXT RUN
+
+
+ CREATED{' '} + +
+
+ NEXT RUN{' '} + +
{cronWorkflows.map(w => (
{w.spec.suspend ? : }
-
+
{w.metadata.annotations?.[ANNOTATION_TITLE] ?? w.metadata.name} {w.metadata.annotations?.[ANNOTATION_DESCRIPTION] ?

{w.metadata.annotations[ANNOTATION_DESCRIPTION]}

: null}
-
{w.metadata.namespace}
+
{w.metadata.namespace}
{w.spec.timezone}
{w.spec.schedule != '' @@ -180,15 +192,15 @@ export function CronWorkflowList({match, location, history}: RouteComponentProps )}
-
- +
+
-
+
{w.spec.suspend ? ( '' ) : ( - {() => } + {() => } )}
diff --git a/ui/src/app/shared/components/timestamp.tsx b/ui/src/app/shared/components/timestamp.tsx index 9e054f450803..47497931f56e 100644 --- a/ui/src/app/shared/components/timestamp.tsx +++ b/ui/src/app/shared/components/timestamp.tsx @@ -21,7 +21,7 @@ export function Timestamp({date, timestampKey, displayLocalDateTime, displayISOF return ( - + {displayISOFormatValue ? ( new Date(date.toString()).toISOString() ) : ( diff --git a/ui/src/app/workflows/components/workflows-list/workflows-list.scss b/ui/src/app/workflows/components/workflows-list/workflows-list.scss index 01b94241d786..85ec8f2cb346 100644 --- a/ui/src/app/workflows/components/workflows-list/workflows-list.scss +++ b/ui/src/app/workflows/components/workflows-list/workflows-list.scss @@ -32,6 +32,14 @@ height: 100%; } + &__timestamp { + white-space: break-spaces !important; + line-height: normal; + align-items: center; + display: flex; + word-break: break-word; + } + &__title { font-weight: bolder; font-size: 15px; diff --git a/ui/src/app/workflows/components/workflows-row/workflows-row.tsx b/ui/src/app/workflows/components/workflows-row/workflows-row.tsx index af2ac3309b50..8e29fd2bc56f 100644 --- a/ui/src/app/workflows/components/workflows-row/workflows-row.tsx +++ b/ui/src/app/workflows/components/workflows-row/workflows-row.tsx @@ -62,10 +62,10 @@ export function WorkflowsRow(props: WorkflowsRowProps) {
{hasAnnotation ? : markdown}
{wf.metadata.namespace}
-
+
-
+
From f02c44b5398ca00b9864bc3ba60dfaa1062456a4 Mon Sep 17 00:00:00 2001 From: Adrien Delannoy Date: Wed, 21 Aug 2024 15:56:16 +0200 Subject: [PATCH 4/4] feat: update title depending on ISO/relative Signed-off-by: Adrien Delannoy --- ui/src/app/shared/components/timestamp.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/shared/components/timestamp.tsx b/ui/src/app/shared/components/timestamp.tsx index 47497931f56e..ad8c2e17e63c 100644 --- a/ui/src/app/shared/components/timestamp.tsx +++ b/ui/src/app/shared/components/timestamp.tsx @@ -43,7 +43,7 @@ export function Timestamp({date, timestampKey, displayLocalDateTime, displayISOF export function TimestampSwitch({storedDisplayISOFormat, setStoredDisplayISOFormat}: {storedDisplayISOFormat: boolean; setStoredDisplayISOFormat: (value: boolean) => void}) { return ( - +