@orchestrator-ui/orchestrator-ui-components 1.13.0 → 1.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchestrator-ui/orchestrator-ui-components",
3
- "version": "1.13.0",
3
+ "version": "1.13.2",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Library of UI Components used to display the workflow orchestrator frontend",
6
6
  "author": {
@@ -0,0 +1,27 @@
1
+ import React, { FC } from 'react';
2
+
3
+ import { useTranslations } from 'next-intl';
4
+
5
+ import { EuiCodeBlock, EuiText } from '@elastic/eui';
6
+
7
+ import { useWithOrchestratorTheme } from '@/hooks';
8
+
9
+ import { getStyles } from './styles';
10
+
11
+ export type WfoTracebackProps = {
12
+ children: string | null;
13
+ };
14
+
15
+ export const WfoTraceback: FC<WfoTracebackProps> = ({ children }) => {
16
+ const { codeBlockStyle } = useWithOrchestratorTheme(getStyles);
17
+ const t = useTranslations('processes.steps');
18
+
19
+ return (
20
+ <>
21
+ <EuiText>
22
+ <h3>{t('traceback')}</h3>
23
+ </EuiText>
24
+ <EuiCodeBlock css={codeBlockStyle}>{children}</EuiCodeBlock>
25
+ </>
26
+ );
27
+ };
@@ -0,0 +1 @@
1
+ export * from './WfoTraceback';
@@ -3,6 +3,7 @@ import { css } from '@emotion/react';
3
3
 
4
4
  export const getStyles = (theme: EuiThemeComputed) => {
5
5
  const codeBlockStyle = css({
6
+ marginTop: theme.size.m,
6
7
  marginBottom: theme.size.l,
7
8
  borderRadius: theme.border.radius.medium,
8
9
  });
@@ -2,17 +2,15 @@ import React, { Ref, useEffect, useState } from 'react';
2
2
 
3
3
  import { useTranslations } from 'next-intl';
4
4
 
5
- import { EuiCodeBlock } from '@elastic/eui';
6
-
7
5
  import { WfoJsonCodeBlock, WfoLoading } from '@/components';
8
6
  import WfoDiff from '@/components/WfoDiff/WfoDiff';
9
- import { useRawProcessDetails, useWithOrchestratorTheme } from '@/hooks';
7
+ import { WfoTraceback } from '@/components/WfoWorkflowSteps/WfoTraceback/WfoTraceback';
8
+ import { useRawProcessDetails } from '@/hooks';
10
9
  import { Step, StepStatus } from '@/types';
11
10
  import { InputForm } from '@/types/forms';
12
11
 
13
12
  import { WfoStepList, WfoStepListRef } from '../WfoStepList';
14
13
  import { WfoStepListHeader } from './WfoStepListHeader';
15
- import { getStyles } from './styles';
16
14
 
17
15
  export type StepListItem = {
18
16
  step: Step;
@@ -73,8 +71,6 @@ export const WfoWorkflowStepList = React.forwardRef(
73
71
  }: WfoWorkflowStepListProps,
74
72
  reference: Ref<WfoStepListRef>,
75
73
  ) => {
76
- const { codeBlockStyle } = useWithOrchestratorTheme(getStyles);
77
-
78
74
  const [showHiddenKeys, setShowHiddenKeys] = useState(false);
79
75
  const [showRaw, setShowRaw] = useState(false);
80
76
  const [showDelta, setShowDelta] = useState(false);
@@ -185,11 +181,7 @@ export const WfoWorkflowStepList = React.forwardRef(
185
181
  onShowTraceback={setShowTraceback}
186
182
  isTask={isTask}
187
183
  />
188
- {showTraceback && (
189
- <EuiCodeBlock css={codeBlockStyle}>
190
- {traceBack}
191
- </EuiCodeBlock>
192
- )}
184
+ {showTraceback && <WfoTraceback>{traceBack}</WfoTraceback>}
193
185
  {showRaw && <WfoProcessRawData processId={processId} />}
194
186
  {showDelta && (
195
187
  <WfoProcessSubscriptionDelta processId={processId} />
@@ -225,7 +225,8 @@
225
225
  "duration": "Duration",
226
226
  "userInput": "User input",
227
227
  "submitTaskFormLabel": "Please submit the form to start this task",
228
- "submitWorkflowFormLabel": "Please submit the form to start this workflow"
228
+ "submitWorkflowFormLabel": "Please submit the form to start this workflow",
229
+ "traceback": "Traceback"
229
230
  },
230
231
  "delta": {
231
232
  "title": "Subscription delta"
@@ -371,6 +372,11 @@
371
372
  }
372
373
  },
373
374
  "startPage": {
375
+ "myWorkflows": {
376
+ "buttonText": "Show my completed workflows",
377
+ "headerTitle": "My completed workflows",
378
+ "listTitle": "My most recent workflows"
379
+ },
374
380
  "activeSubscriptions": {
375
381
  "buttonText": "Show all active subscriptions",
376
382
  "headerTitle": "Total active subscriptions",
@@ -223,7 +223,8 @@
223
223
  "duration": "Looptijd",
224
224
  "userInput": "Invoer gebruiker",
225
225
  "submitTaskFormLabel": "Verstuur het formulier om deze taak te starten",
226
- "submitWorkflowFormLabel": "Verstuur het formulier om deze workflow te starten"
226
+ "submitWorkflowFormLabel": "Verstuur het formulier om deze workflow te starten",
227
+ "traceback": "Traceback"
227
228
  },
228
229
  "delta": {
229
230
  "title": "Subscription delta"
@@ -369,6 +370,11 @@
369
370
  }
370
371
  },
371
372
  "startPage": {
373
+ "myWorkflows": {
374
+ "buttonText": "Toon mijn afgeronde workflows",
375
+ "headerTitle": "Mijn afgeronde workflows",
376
+ "listTitle": "Mijn recente afgeronde workflows"
377
+ },
372
378
  "activeSubscriptions": {
373
379
  "buttonText": "Toon alle actieve subscriptions",
374
380
  "headerTitle": "Totaal aantal actieve subscriptions",
@@ -11,24 +11,35 @@ import {
11
11
  WfoSummaryCards,
12
12
  } from '@/components/WfoSummary/WfoSummaryCards';
13
13
  import { PolicyResource } from '@/configuration';
14
- import { usePolicy } from '@/hooks';
14
+ import { usePolicy, useWfoSession } from '@/hooks';
15
15
  import {
16
16
  useGetProcessListSummaryQuery,
17
17
  useGetProductsSummaryQuery,
18
18
  } from '@/rtk';
19
19
  import { useGetSubscriptionSummaryListQuery } from '@/rtk/endpoints/subscriptionListSummary';
20
+ import { optionalArrayMapper, toOptionalArrayEntry } from '@/utils';
21
+
22
+ import {
23
+ mapProcessSummaryToSummaryCardListItem,
24
+ mapSubscriptionSummaryToSummaryCardListItem,
25
+ } from './mappers';
20
26
  import {
21
- GraphqlQueryVariables,
22
- Process,
23
- ProductsSummary,
24
- SortOrder,
25
- Subscription,
26
- } from '@/types';
27
- import { formatDate } from '@/utils';
27
+ activeWorkflowsListSummaryQueryVariables,
28
+ getMyWorkflowListSummaryQueryVariables,
29
+ outOfSyncSubscriptionsListSummaryQueryVariables,
30
+ productsSummaryQueryVariables,
31
+ subscriptionsListSummaryQueryVariables,
32
+ taskListSummaryQueryVariables,
33
+ } from './queryVariables';
34
+ import { useStartPageSummaryCardConfigurationOverride } from './useStartPageSummaryCardConfigurationOverride';
28
35
 
29
36
  export const WfoStartPage = () => {
30
37
  const t = useTranslations('startPage');
38
+ const { overrideSummaryCards } =
39
+ useStartPageSummaryCardConfigurationOverride();
31
40
  const { isAllowed } = usePolicy();
41
+ const { session } = useWfoSession();
42
+ const username = session?.user?.name ?? '';
32
43
 
33
44
  const {
34
45
  data: subscriptionsSummaryResult,
@@ -43,9 +54,16 @@ export const WfoStartPage = () => {
43
54
  outOfSyncSubscriptionsListSummaryQueryVariables,
44
55
  );
45
56
  const {
46
- data: processesSummaryResponse,
47
- isFetching: processesSummaryIsFetching,
48
- } = useGetProcessListSummaryQuery(processListSummaryQueryVariables);
57
+ data: activeWorkflowsSummaryResponse,
58
+ isFetching: activeWorkflowsSummaryIsFetching,
59
+ } = useGetProcessListSummaryQuery(activeWorkflowsListSummaryQueryVariables);
60
+
61
+ const {
62
+ data: myWorkflowsSummaryResponse,
63
+ isFetching: myWorkflowsSummaryIsFetching,
64
+ } = useGetProcessListSummaryQuery(
65
+ getMyWorkflowListSummaryQueryVariables(username),
66
+ );
49
67
 
50
68
  const {
51
69
  data: failedTasksSummaryResponse,
@@ -62,12 +80,10 @@ export const WfoStartPage = () => {
62
80
  headerValue: subscriptionsSummaryResult?.pageInfo.totalItems ?? 0,
63
81
  headerStatus: SummaryCardStatus.Neutral,
64
82
  listTitle: t('activeSubscriptions.listTitle'),
65
- listItems:
66
- subscriptionsSummaryResult?.subscriptions.map((subscription) => ({
67
- title: subscription.description,
68
- value: formatDate(subscription.startDate),
69
- url: `${PATH_SUBSCRIPTIONS}/${subscription.subscriptionId}`,
70
- })) ?? [],
83
+ listItems: optionalArrayMapper(
84
+ subscriptionsSummaryResult?.subscriptions,
85
+ mapSubscriptionSummaryToSummaryCardListItem,
86
+ ),
71
87
  button: {
72
88
  name: t('activeSubscriptions.buttonText'),
73
89
  url: PATH_SUBSCRIPTIONS,
@@ -81,14 +97,10 @@ export const WfoStartPage = () => {
81
97
  outOfSyncSubscriptionsSummaryResult?.pageInfo.totalItems ?? 0,
82
98
  headerStatus: SummaryCardStatus.Error,
83
99
  listTitle: t('outOfSyncSubscriptions.listTitle'),
84
- listItems:
85
- outOfSyncSubscriptionsSummaryResult?.subscriptions.map(
86
- (subscription) => ({
87
- title: subscription.description,
88
- value: formatDate(subscription.startDate),
89
- url: `${PATH_SUBSCRIPTIONS}/${subscription.subscriptionId}`,
90
- }),
91
- ) ?? [],
100
+ listItems: optionalArrayMapper(
101
+ outOfSyncSubscriptionsSummaryResult?.subscriptions,
102
+ mapSubscriptionSummaryToSummaryCardListItem,
103
+ ),
92
104
  button: {
93
105
  name: t('outOfSyncSubscriptions.buttonText'),
94
106
  url: `${PATH_SUBSCRIPTIONS}?activeTab=ALL&sortBy=field-startDate_order-ASC&queryString=status%3A%28provisioning%7Cactive%29+insync%3Afalse`,
@@ -96,22 +108,38 @@ export const WfoStartPage = () => {
96
108
  isLoading: outOfSyncsubscriptionsSummaryIsFetching,
97
109
  };
98
110
 
99
- const latestWorkflowsSummaryCard: SummaryCard = {
111
+ const activeWorkflowsSummaryCard: SummaryCard = {
100
112
  headerTitle: t('activeWorkflows.headerTitle'),
101
- headerValue: processesSummaryResponse?.pageInfo.totalItems ?? 0,
113
+ headerValue: activeWorkflowsSummaryResponse?.pageInfo.totalItems ?? 0,
102
114
  headerStatus: SummaryCardStatus.Success,
103
115
  listTitle: t('activeWorkflows.listTitle'),
104
- listItems:
105
- processesSummaryResponse?.processes.map((workflow) => ({
106
- title: workflow.workflowName,
107
- value: formatDate(workflow?.startedAt),
108
- url: `${PATH_WORKFLOWS}/${workflow.processId}`,
109
- })) ?? [],
116
+ listItems: optionalArrayMapper(
117
+ activeWorkflowsSummaryResponse?.processes,
118
+ mapProcessSummaryToSummaryCardListItem,
119
+ ),
110
120
  button: {
111
121
  name: t('activeWorkflows.buttonText'),
112
122
  url: PATH_WORKFLOWS,
113
123
  },
114
- isLoading: processesSummaryIsFetching,
124
+ isLoading: activeWorkflowsSummaryIsFetching,
125
+ };
126
+
127
+ const myWorkflowsSummaryCard: SummaryCard = {
128
+ headerTitle: t('myWorkflows.headerTitle'),
129
+ headerValue: myWorkflowsSummaryResponse?.pageInfo.totalItems ?? 0,
130
+ headerStatus: SummaryCardStatus.Success,
131
+ listTitle: t('myWorkflows.listTitle'),
132
+ listItems: optionalArrayMapper(
133
+ myWorkflowsSummaryResponse?.processes,
134
+ mapProcessSummaryToSummaryCardListItem,
135
+ ),
136
+ button: username
137
+ ? {
138
+ name: t('myWorkflows.buttonText'),
139
+ url: `${PATH_WORKFLOWS}?activeTab=COMPLETED&sortBy=field-lastModifiedAt_order-DESC&queryString=createdBy%3A${username}`,
140
+ }
141
+ : undefined,
142
+ isLoading: myWorkflowsSummaryIsFetching,
115
143
  };
116
144
 
117
145
  const failedTasksSummaryCard: SummaryCard = {
@@ -119,12 +147,10 @@ export const WfoStartPage = () => {
119
147
  headerValue: failedTasksSummaryResponse?.pageInfo.totalItems ?? 0,
120
148
  headerStatus: SummaryCardStatus.Error,
121
149
  listTitle: t('failedTasks.listTitle'),
122
- listItems:
123
- failedTasksSummaryResponse?.processes.map((task) => ({
124
- title: task.workflowName,
125
- value: formatDate(task?.startedAt),
126
- url: `${PATH_TASKS}/${task.processId}`,
127
- })) ?? [],
150
+ listItems: optionalArrayMapper(
151
+ failedTasksSummaryResponse?.processes,
152
+ mapProcessSummaryToSummaryCardListItem,
153
+ ),
128
154
  button: {
129
155
  name: t('failedTasks.buttonText'),
130
156
  url: PATH_TASKS,
@@ -163,113 +189,24 @@ export const WfoStartPage = () => {
163
189
  isLoading: productsSummaryIsFetching,
164
190
  };
165
191
 
166
- function getFailedTasksSummarycard() {
167
- return isAllowed(PolicyResource.NAVIGATION_TASKS)
168
- ? [failedTasksSummaryCard]
169
- : [];
170
- }
171
-
172
192
  const allowedSummaryCards = [
173
- latestWorkflowsSummaryCard,
174
- ...getFailedTasksSummarycard(),
193
+ ...toOptionalArrayEntry(myWorkflowsSummaryCard, !!username),
194
+ activeWorkflowsSummaryCard,
195
+ ...toOptionalArrayEntry(
196
+ failedTasksSummaryCard,
197
+ isAllowed(PolicyResource.NAVIGATION_TASKS),
198
+ ),
175
199
  latestOutOfSyncSubscriptionsSummaryCard,
176
200
  latestActiveSubscriptionsSummaryCard,
177
201
  productsSummaryCard,
178
202
  ];
179
203
 
204
+ const summaryCards =
205
+ overrideSummaryCards?.(allowedSummaryCards) || allowedSummaryCards;
206
+
180
207
  return (
181
208
  <EuiFlexItem>
182
- <WfoSummaryCards summaryCards={allowedSummaryCards} />
209
+ <WfoSummaryCards summaryCards={summaryCards} />
183
210
  </EuiFlexItem>
184
211
  );
185
212
  };
186
-
187
- const subscriptionsListSummaryQueryVariables: GraphqlQueryVariables<Subscription> =
188
- {
189
- first: 5,
190
- after: 0,
191
- sortBy: {
192
- field: 'startDate',
193
- order: SortOrder.DESC,
194
- },
195
- filterBy: [
196
- {
197
- field: 'status',
198
- value: 'Active',
199
- },
200
- ],
201
- };
202
-
203
- const outOfSyncSubscriptionsListSummaryQueryVariables: GraphqlQueryVariables<Subscription> =
204
- {
205
- first: 5,
206
- after: 0,
207
- sortBy: {
208
- field: 'startDate',
209
- order: SortOrder.ASC,
210
- },
211
- query: 'insync:false',
212
- filterBy: [
213
- {
214
- field: 'status',
215
- value: 'Active-Provisioning',
216
- },
217
- ],
218
- };
219
-
220
- const processListSummaryQueryVariables: GraphqlQueryVariables<Process> = {
221
- first: 5,
222
- after: 0,
223
- sortBy: {
224
- field: 'startedAt',
225
- order: SortOrder.DESC,
226
- },
227
- filterBy: [
228
- {
229
- // Todo: isTask is not a key of Process
230
- // However, backend still supports it. Field should not be a keyof ProcessListItem (or process)
231
- // https://github.com/workfloworchestrator/orchestrator-ui/issues/290
232
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
233
- // @ts-ignore waiting for fix in backend
234
- field: 'isTask',
235
- value: 'false',
236
- },
237
- {
238
- field: 'lastStatus',
239
- value: 'created-running-suspended-waiting-failed-resumed-inconsistent_data-api_unavailable-awaiting_callback',
240
- },
241
- ],
242
- };
243
-
244
- const taskListSummaryQueryVariables: GraphqlQueryVariables<Process> = {
245
- first: 5,
246
- after: 0,
247
- sortBy: {
248
- field: 'startedAt',
249
- order: SortOrder.DESC,
250
- },
251
- filterBy: [
252
- {
253
- // Todo: isTask is not a key of Process
254
- // However, backend still supports it. Field should not be a keyof ProcessListItem (or process)
255
- // https://github.com/workfloworchestrator/orchestrator-ui/issues/290
256
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
257
- // @ts-ignore waiting for fix in backend
258
- field: 'isTask',
259
- value: 'true',
260
- },
261
- {
262
- field: 'lastStatus',
263
- value: 'failed-inconsistent_data-api_unavailable',
264
- },
265
- ],
266
- };
267
-
268
- const productsSummaryQueryVariables: GraphqlQueryVariables<ProductsSummary> = {
269
- first: 1000,
270
- after: 0,
271
- sortBy: {
272
- field: 'name',
273
- order: SortOrder.ASC,
274
- },
275
- };
@@ -0,0 +1,21 @@
1
+ import { PATH_SUBSCRIPTIONS, PATH_WORKFLOWS } from '@/components';
2
+ import { SummaryCardListItem } from '@/components/WfoSummary';
3
+ import { ProcessSummary } from '@/rtk';
4
+ import { SubscriptionSummary } from '@/types';
5
+ import { formatDate } from '@/utils';
6
+
7
+ export const mapProcessSummaryToSummaryCardListItem = (
8
+ processSummary: ProcessSummary,
9
+ ): SummaryCardListItem => ({
10
+ title: processSummary.workflowName,
11
+ value: formatDate(processSummary?.startedAt),
12
+ url: `${PATH_WORKFLOWS}/${processSummary.processId}`,
13
+ });
14
+
15
+ export const mapSubscriptionSummaryToSummaryCardListItem = (
16
+ subscription: SubscriptionSummary,
17
+ ): SummaryCardListItem => ({
18
+ title: subscription.description,
19
+ value: formatDate(subscription.startDate),
20
+ url: `${PATH_SUBSCRIPTIONS}/${subscription.subscriptionId}`,
21
+ });
@@ -0,0 +1,111 @@
1
+ import {
2
+ GraphqlFilter,
3
+ GraphqlQueryVariables,
4
+ Process,
5
+ ProductsSummary,
6
+ SortOrder,
7
+ Subscription,
8
+ } from '@/types';
9
+
10
+ const baseQueryVariables: Partial<GraphqlQueryVariables<unknown>> = {
11
+ first: 5,
12
+ after: 0,
13
+ };
14
+ const baseQueryVariablesForSubscription: Partial<
15
+ GraphqlQueryVariables<Subscription>
16
+ > = {
17
+ ...baseQueryVariables,
18
+ sortBy: {
19
+ field: 'startDate',
20
+ order: SortOrder.DESC,
21
+ },
22
+ };
23
+
24
+ const baseQueryVariablesForProcess: Partial<GraphqlQueryVariables<Process>> = {
25
+ ...baseQueryVariables,
26
+ sortBy: {
27
+ field: 'startedAt',
28
+ order: SortOrder.DESC,
29
+ },
30
+ };
31
+
32
+ const getTaskFilter = (isTask: boolean): GraphqlFilter<Process> => {
33
+ return {
34
+ // Todo: isTask is not a key of Process
35
+ // However, backend still supports it. Field should not be a keyof ProcessListItem (or process)
36
+ // https://github.com/workfloworchestrator/orchestrator-ui/issues/290
37
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
38
+ // @ts-ignore waiting for fix in backend
39
+ field: 'isTask',
40
+ value: isTask ? 'true' : 'false',
41
+ };
42
+ };
43
+
44
+ export const subscriptionsListSummaryQueryVariables: GraphqlQueryVariables<Subscription> =
45
+ {
46
+ ...baseQueryVariablesForSubscription,
47
+ filterBy: [
48
+ {
49
+ field: 'status',
50
+ value: 'Active',
51
+ },
52
+ ],
53
+ };
54
+
55
+ export const outOfSyncSubscriptionsListSummaryQueryVariables: GraphqlQueryVariables<Subscription> =
56
+ {
57
+ ...baseQueryVariablesForSubscription,
58
+ query: 'insync:false',
59
+ filterBy: [
60
+ {
61
+ field: 'status',
62
+ value: 'Active-Provisioning',
63
+ },
64
+ ],
65
+ };
66
+
67
+ export const getMyWorkflowListSummaryQueryVariables = (
68
+ username: string,
69
+ ): GraphqlQueryVariables<Process> => ({
70
+ ...baseQueryVariablesForProcess,
71
+ filterBy: [
72
+ getTaskFilter(false),
73
+ {
74
+ field: 'createdBy',
75
+ value: username,
76
+ },
77
+ ],
78
+ });
79
+
80
+ export const activeWorkflowsListSummaryQueryVariables: GraphqlQueryVariables<Process> =
81
+ {
82
+ ...baseQueryVariablesForProcess,
83
+ filterBy: [
84
+ getTaskFilter(false),
85
+ {
86
+ field: 'lastStatus',
87
+ value: 'created-running-suspended-waiting-failed-resumed-inconsistent_data-api_unavailable-awaiting_callback',
88
+ },
89
+ ],
90
+ };
91
+
92
+ export const taskListSummaryQueryVariables: GraphqlQueryVariables<Process> = {
93
+ ...baseQueryVariablesForProcess,
94
+ filterBy: [
95
+ getTaskFilter(true),
96
+ {
97
+ field: 'lastStatus',
98
+ value: 'failed-inconsistent_data-api_unavailable',
99
+ },
100
+ ],
101
+ };
102
+
103
+ export const productsSummaryQueryVariables: GraphqlQueryVariables<ProductsSummary> =
104
+ {
105
+ first: 1000,
106
+ after: 0,
107
+ sortBy: {
108
+ field: 'name',
109
+ order: SortOrder.ASC,
110
+ },
111
+ };
@@ -0,0 +1,13 @@
1
+ import { useAppSelector } from '@/rtk/hooks';
2
+
3
+ export const useStartPageSummaryCardConfigurationOverride = () => {
4
+ const overrideSummaryCards = useAppSelector(
5
+ (state) =>
6
+ state.orchestratorComponentOverride?.startPage
7
+ ?.summaryCardConfigurationOverride,
8
+ );
9
+
10
+ return {
11
+ overrideSummaryCards,
12
+ };
13
+ };
@@ -36,7 +36,10 @@ export const processListSummaryQuery = `
36
36
  }
37
37
  `;
38
38
 
39
- type ProcessSummary = Pick<Process, 'processId' | 'workflowName' | 'startedAt'>;
39
+ export type ProcessSummary = Pick<
40
+ Process,
41
+ 'processId' | 'workflowName' | 'startedAt'
42
+ >;
40
43
 
41
44
  export type ProcessListSummaryResponse = {
42
45
  processes: ProcessSummary[];
@@ -2,6 +2,7 @@ import { ReactNode } from 'react';
2
2
 
3
3
  import { Slice, createSlice } from '@reduxjs/toolkit';
4
4
 
5
+ import { SummaryCard } from '@/components/WfoSummary';
5
6
  import { FieldValue, SubscriptionDetail } from '@/types';
6
7
 
7
8
  export type ValueOverrideFunction = (fieldValue: FieldValue) => ReactNode;
@@ -13,6 +14,11 @@ export type WfoSubscriptionDetailGeneralConfiguration = {
13
14
  };
14
15
 
15
16
  export type OrchestratorComponentOverride = {
17
+ startPage?: {
18
+ summaryCardConfigurationOverride?: (
19
+ defaultItems: SummaryCard[],
20
+ ) => SummaryCard[];
21
+ };
16
22
  subscriptionDetail?: {
17
23
  valueOverrides?: ValueOverrideConfiguration;
18
24
  generalSectionConfigurationOverride?: (
@@ -9,4 +9,4 @@ export * from './onlyUnique';
9
9
  export * from './uuid';
10
10
  export * from './resultFlattener';
11
11
  export * from './strings';
12
- export * from './toOptionalArrayEntry';
12
+ export * from './optionalArray';
@@ -0,0 +1,32 @@
1
+ import { optionalArrayMapper, toOptionalArrayEntry } from './optionalArray';
2
+
3
+ describe('toOptionalArrayEntry', () => {
4
+ const testInput = { testField: 'testValue' };
5
+
6
+ it('returns an array with the data if the condition is true', () => {
7
+ const result = toOptionalArrayEntry(testInput, true);
8
+
9
+ expect(result).toEqual([testInput]);
10
+ });
11
+
12
+ it('returns an empty array if the condition is false', () => {
13
+ const result = toOptionalArrayEntry(testInput, false);
14
+
15
+ expect(result).toEqual([]);
16
+ });
17
+ });
18
+
19
+ describe('optionalArrayMapper', () => {
20
+ it('applies the mapper when data is defined', () => {
21
+ const testData = [{ testField: 'testValue' }];
22
+
23
+ const result = optionalArrayMapper(testData, () => 'mappedValue');
24
+
25
+ expect(result).toEqual(['mappedValue']);
26
+ });
27
+ it('returns an empty array when data is undefined', () => {
28
+ const result = optionalArrayMapper(undefined, () => 'test');
29
+
30
+ expect(result).toEqual([]);
31
+ });
32
+ });
@@ -0,0 +1,9 @@
1
+ export const toOptionalArrayEntry = <T>(
2
+ data: T,
3
+ condition: boolean,
4
+ ): [T] | [] => (condition ? [data] : []);
5
+
6
+ export const optionalArrayMapper = <T, U>(
7
+ data: T[] | undefined = [],
8
+ mapper: (input: T) => U,
9
+ ): U[] => data.map(mapper);
@@ -1,17 +0,0 @@
1
- import { toOptionalArrayEntry } from './toOptionalArrayEntry';
2
-
3
- describe('toOptionalArrayEntry', () => {
4
- const testInput = { testField: 'testValue' };
5
-
6
- it('returns an array with the data if ', () => {
7
- const result = toOptionalArrayEntry(testInput, true);
8
-
9
- expect(result).toEqual([testInput]);
10
- });
11
-
12
- it('returns an empty array if the condition is false', () => {
13
- const result = toOptionalArrayEntry(testInput, false);
14
-
15
- expect(result).toEqual([]);
16
- });
17
- });