@orchestrator-ui/orchestrator-ui-components 1.6.0 → 1.7.0

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.
Files changed (35) hide show
  1. package/.turbo/turbo-build.log +5 -5
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test.log +9 -8
  4. package/CHANGELOG.md +19 -0
  5. package/dist/index.d.ts +1282 -1143
  6. package/dist/index.js +686 -333
  7. package/package.json +1 -1
  8. package/src/components/WfoBadges/WfoProductBlockBadge/WfoProductBlockBadge.tsx +1 -0
  9. package/src/components/WfoPageTemplate/WfoSidebar/WfoSidebar.tsx +10 -0
  10. package/src/components/WfoPageTemplate/paths.ts +1 -0
  11. package/src/components/WfoProcessList/WfoProcessesList.tsx +5 -1
  12. package/src/components/WfoProcessList/processListObjectMappers.ts +7 -4
  13. package/src/components/WfoSubscription/WfoSubscriptionGeneral.tsx +10 -6
  14. package/src/components/WfoTable/utils/constants.ts +1 -0
  15. package/src/components/index.ts +1 -0
  16. package/src/messages/en-GB.json +11 -1
  17. package/src/messages/nl-NL.json +10 -1
  18. package/src/pages/metadata/WfoMetadataPageLayout.tsx +10 -5
  19. package/src/pages/metadata/WfoProductBlocksPage.tsx +25 -1
  20. package/src/pages/metadata/WfoProductsPage.tsx +27 -1
  21. package/src/pages/metadata/WfoResourceTypesPage.tsx +23 -4
  22. package/src/pages/metadata/WfoTasksPage.tsx +226 -0
  23. package/src/pages/metadata/WfoWorkflowsPage.tsx +29 -6
  24. package/src/pages/metadata/index.ts +3 -0
  25. package/src/pages/metadata/taskListObjectMapper.ts +40 -0
  26. package/src/pages/subscriptions/WfoSubscriptionDetailPage.tsx +2 -2
  27. package/src/pages/subscriptions/WfoSubscriptionsListPage.tsx +1 -1
  28. package/src/pages/workflows/index.ts +2 -0
  29. package/src/rtk/endpoints/metadata/index.ts +1 -0
  30. package/src/rtk/endpoints/metadata/tasks.ts +74 -0
  31. package/src/types/types.ts +15 -2
  32. package/src/utils/getDefaultTableConfig.ts +2 -0
  33. package/src/utils/index.ts +1 -0
  34. package/src/utils/resultFlattener.spec.ts +51 -0
  35. package/src/utils/resultFlattener.ts +25 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchestrator-ui/orchestrator-ui-components",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Library of UI Components used to display the workflow orchestrator frontend",
6
6
  "author": {
@@ -42,6 +42,7 @@ export function WfoProductBlockBadge({
42
42
  textColor: primaryText,
43
43
  };
44
44
  case BadgeType.WORKFLOW:
45
+ case BadgeType.TASK:
45
46
  case BadgeType.PRODUCT:
46
47
  return {
47
48
  badgeColor: toSecondaryColor(danger),
@@ -16,6 +16,7 @@ import {
16
16
  PATH_METADATA_PRODUCTS,
17
17
  PATH_METADATA_PRODUCT_BLOCKS,
18
18
  PATH_METADATA_RESOURCE_TYPES,
19
+ PATH_METADATA_TASKS,
19
20
  PATH_METADATA_WORKFLOWS,
20
21
  PATH_SETTINGS,
21
22
  PATH_START,
@@ -128,6 +129,15 @@ export const WfoSidebar: FC<WfoSidebarProps> = ({ overrideMenuItems }) => {
128
129
  router.push(PATH_METADATA_WORKFLOWS);
129
130
  },
130
131
  },
132
+ {
133
+ name: t('metadataTasks'),
134
+ id: '5.5',
135
+ isSelected: router.pathname === PATH_METADATA_TASKS,
136
+ onClick: (e) => {
137
+ e.preventDefault();
138
+ router.push(PATH_METADATA_TASKS);
139
+ },
140
+ },
131
141
  ],
132
142
  },
133
143
  {
@@ -8,5 +8,6 @@ export const PATH_METADATA_PRODUCTS = '/metadata/products';
8
8
  export const PATH_METADATA_PRODUCT_BLOCKS = '/metadata/productblocks';
9
9
  export const PATH_METADATA_RESOURCE_TYPES = '/metadata/resource-types';
10
10
  export const PATH_METADATA_WORKFLOWS = '/metadata/workflows';
11
+ export const PATH_METADATA_TASKS = '/metadata/tasks';
11
12
  export const PATH_TASKS = '/tasks';
12
13
  export const PATH_SETTINGS = '/settings';
@@ -67,6 +67,10 @@ export type ProcessListItem = Pick<
67
67
  customerAbbreviation: string;
68
68
  };
69
69
 
70
+ export type ProcessListExportItem = Omit<ProcessListItem, 'subscriptions'> & {
71
+ subscriptions: string;
72
+ };
73
+
70
74
  export type WfoProcessesListProps = {
71
75
  alwaysOnFilters?: FilterQuery<ProcessListItem>[];
72
76
  defaultHiddenColumns: TableColumnKeys<ProcessListItem> | undefined;
@@ -264,7 +268,7 @@ export const WfoProcessesList = ({
264
268
  onUpdateDataSort={getDataSortHandler(setDataDisplayParam)}
265
269
  onExportData={csvDownloadHandler<
266
270
  ProcessListResponse,
267
- ProcessListItem
271
+ ProcessListExportItem
268
272
  >(
269
273
  getProcessListForExport,
270
274
  mapGraphQlProcessListExportResultToProcessListItems,
@@ -1,7 +1,8 @@
1
1
  import { ProcessListResponse } from '@/rtk';
2
- import { GraphQLSort, GraphqlFilter, Process } from '@/types';
2
+ import { GraphQLSort, GraphqlFilter, Process, Subscription } from '@/types';
3
+ import { getConcatenatedPagedResult } from '@/utils';
3
4
 
4
- import { ProcessListItem } from './WfoProcessesList';
5
+ import { ProcessListExportItem, ProcessListItem } from './WfoProcessesList';
5
6
 
6
7
  export const mapGraphQlProcessListResultToPageInfo = (
7
8
  processesResponse: ProcessListResponse,
@@ -48,7 +49,7 @@ export const mapGraphQlProcessListResultToProcessListItems = (
48
49
 
49
50
  export const mapGraphQlProcessListExportResultToProcessListItems = (
50
51
  processesResponse: ProcessListResponse,
51
- ): ProcessListItem[] =>
52
+ ): ProcessListExportItem[] =>
52
53
  processesResponse.processes.map((process) => {
53
54
  const {
54
55
  workflowName,
@@ -77,7 +78,9 @@ export const mapGraphQlProcessListExportResultToProcessListItems = (
77
78
  isTask,
78
79
  startedAt: new Date(startedAt),
79
80
  lastModifiedAt: new Date(lastModifiedAt),
80
- subscriptions,
81
+ subscriptions: getConcatenatedPagedResult<
82
+ Pick<Subscription, 'subscriptionId' | 'description'>
83
+ >(subscriptions, ['subscriptionId', 'description']),
81
84
  productName: product?.name,
82
85
  productTag: product?.tag,
83
86
  customer: customer.fullname,
@@ -126,6 +126,8 @@ export const WfoSubscriptionGeneral = ({
126
126
  ];
127
127
  };
128
128
 
129
+ const hasMetadata = Object.entries(subscriptionDetail.metadata).length > 0;
130
+
129
131
  return (
130
132
  <EuiFlexGrid direction={'row'}>
131
133
  <>
@@ -135,12 +137,14 @@ export const WfoSubscriptionGeneral = ({
135
137
  keyValues={getSubscriptionDetailBlockData()}
136
138
  />
137
139
  </EuiFlexItem>
138
- <EuiFlexItem>
139
- <SubscriptionKeyValueBlock
140
- title={t('metadata')}
141
- keyValues={getMetadataBlockData()}
142
- />
143
- </EuiFlexItem>
140
+ {hasMetadata && (
141
+ <EuiFlexItem>
142
+ <SubscriptionKeyValueBlock
143
+ title={t('metadata')}
144
+ keyValues={getMetadataBlockData()}
145
+ />
146
+ </EuiFlexItem>
147
+ )}
144
148
  <EuiFlexItem>
145
149
  <SubscriptionKeyValueBlock
146
150
  title={t('blockTitleFixedInputs')}
@@ -17,5 +17,6 @@ export const METADATA_PRODUCT_BLOCKS_TABLE_LOCAL_STORAGE_KEY =
17
17
  export const METADATA_PRODUCT_TABLE_LOCAL_STORAGE_KEY = 'metadataProductTable';
18
18
  export const METADATA_WORKFLOWS_TABLE_LOCAL_STORAGE_KEY =
19
19
  'metadataWorkflowsTable';
20
+ export const METADATA_TASKS_TABLE_LOCAL_STORAGE_KEY = 'metadataTasksTable';
20
21
 
21
22
  export const SUBSCRIPTIONS_TABLE_LOCAL_STORAGE_KEY = 'subscriptionsTable';
@@ -26,3 +26,4 @@ export * from './WfoErrorBoundary';
26
26
  export * from './WfoWorkflowSteps';
27
27
  export * from './WfoNoResults';
28
28
  export * from './WfoStartButton';
29
+ export * from './WfoSubscriptionsList';
@@ -5,6 +5,7 @@
5
5
  "metadataProductblocks": "Product blocks",
6
6
  "metadataResourceTypes": "Resource types",
7
7
  "metadataWorkflows": "Workflows",
8
+ "metadataTasks": "Tasks",
8
9
  "mobileTitle": "Main menu",
9
10
  "settings": "Settings",
10
11
  "start": "Start",
@@ -121,11 +122,13 @@
121
122
  }
122
123
  },
123
124
  "metadata": {
125
+ "title": "Metadata",
124
126
  "tabs": {
125
127
  "products": "Products",
126
128
  "productBlocks": "Product blocks",
127
129
  "resourceTypes": "Resource types",
128
- "workflows": "Workflows"
130
+ "workflows": "Workflows",
131
+ "tasks": "Tasks"
129
132
  },
130
133
  "products": {
131
134
  "id": "ID",
@@ -162,6 +165,13 @@
162
165
  "target": "Target",
163
166
  "productTags": "Product tags",
164
167
  "createdAt": "Created"
168
+ },
169
+ "tasks": {
170
+ "name": "Task",
171
+ "description": "Task description",
172
+ "target": "Target",
173
+ "productTags": "Product tags",
174
+ "createdAt": "Created"
165
175
  }
166
176
  },
167
177
  "processes": {
@@ -5,6 +5,7 @@
5
5
  "metadataProductblocks": "Product blocks",
6
6
  "metadataResourceTypes": "Resource types",
7
7
  "metadataWorkflows": "Workflows",
8
+ "metadataTasks": "Taken",
8
9
  "mobileTitle": "Hoofdmenu",
9
10
  "settings": "Settings",
10
11
  "start": "Start",
@@ -125,7 +126,8 @@
125
126
  "products": "Producten",
126
127
  "productBlocks": "Product blocks",
127
128
  "resourceTypes": "Resource types",
128
- "workflows": "Workflows"
129
+ "workflows": "Workflows",
130
+ "tasks": "Taken"
129
131
  },
130
132
  "products": {
131
133
  "id": "ID",
@@ -162,6 +164,13 @@
162
164
  "target": "Target",
163
165
  "productTags": "Product tags",
164
166
  "createdAt": "Aangemaakt"
167
+ },
168
+ "tasks": {
169
+ "name": "Taak",
170
+ "description": "Taak beschrijving",
171
+ "target": "Target",
172
+ "productTags": "Product tags",
173
+ "createdAt": "Aangemaakt"
165
174
  }
166
175
  },
167
176
  "processes": {
@@ -17,7 +17,7 @@ export interface MetaDataTab {
17
17
  path: string;
18
18
  }
19
19
 
20
- const metaDataTabs: MetaDataTab[] = [
20
+ export const metaDataTabs: MetaDataTab[] = [
21
21
  {
22
22
  id: 1,
23
23
  translationKey: 'products',
@@ -34,10 +34,15 @@ const metaDataTabs: MetaDataTab[] = [
34
34
  path: '/metadata/resource-types',
35
35
  },
36
36
  {
37
- id: 5,
37
+ id: 4,
38
38
  translationKey: 'workflows',
39
39
  path: '/metadata/workflows',
40
40
  },
41
+ {
42
+ id: 5,
43
+ translationKey: 'tasks',
44
+ path: '/metadata/tasks',
45
+ },
41
46
  ];
42
47
 
43
48
  export const WfoMetadataPageLayout = ({
@@ -45,14 +50,14 @@ export const WfoMetadataPageLayout = ({
45
50
  tabs = metaDataTabs,
46
51
  }: MetadataLayoutProps) => {
47
52
  const router = useRouter();
48
- const t = useTranslations('metadata.tabs');
53
+ const t = useTranslations('metadata');
49
54
  const currentPath = router.pathname;
50
55
 
51
56
  return (
52
57
  <>
53
58
  <EuiSpacer />
54
59
 
55
- <EuiPageHeader pageTitle="Metadata" />
60
+ <EuiPageHeader pageTitle={t('title')} />
56
61
  <EuiSpacer size="m" />
57
62
  <EuiTabs>
58
63
  {tabs.map(({ id, translationKey: name, path }) => (
@@ -61,7 +66,7 @@ export const WfoMetadataPageLayout = ({
61
66
  isSelected={path === currentPath}
62
67
  onClick={() => router.push(path)}
63
68
  >
64
- {t(name)}
69
+ {t(`tabs.${name}`)}
65
70
  </EuiTab>
66
71
  ))}
67
72
  </EuiTabs>
@@ -28,6 +28,7 @@ import {
28
28
  useStoredTableConfig,
29
29
  } from '@/hooks';
30
30
  import { useGetProductBlocksQuery, useLazyGetProductBlocksQuery } from '@/rtk';
31
+ import type { ProductBlocksResponse } from '@/rtk';
31
32
  import {
32
33
  BadgeType,
33
34
  GraphqlQueryVariables,
@@ -36,6 +37,7 @@ import {
36
37
  } from '@/types';
37
38
  import {
38
39
  csvDownloadHandler,
40
+ getConcatenatedResult,
39
41
  getCsvFileNameWithDate,
40
42
  getQueryVariablesForExport,
41
43
  parseDateToLocaleDateTimeString,
@@ -59,6 +61,14 @@ const PRODUCT_BLOCK_FIELD_RESOURCE_TYPES: keyof ProductBlockDefinition =
59
61
  const PRODUCT_BLOCK_FIELD_PRODUCT_BLOCKS: keyof ProductBlockDefinition =
60
62
  'dependsOn';
61
63
 
64
+ type ProductBlockDefinitionExportItem = Omit<
65
+ ProductBlockDefinition,
66
+ 'resourceTypes' | 'dependsOn'
67
+ > & {
68
+ resourceTypes: string;
69
+ dependsOn: string;
70
+ };
71
+
62
72
  export const WfoProductBlocksPage = () => {
63
73
  const t = useTranslations('metadata.productBlocks');
64
74
  const tError = useTranslations('errors');
@@ -218,6 +228,20 @@ export const WfoProductBlocksPage = () => {
218
228
  totalItemCount: totalItems ? totalItems : 0,
219
229
  };
220
230
 
231
+ const mapToExportItems = (
232
+ productBlocksResponse: ProductBlocksResponse,
233
+ ): ProductBlockDefinitionExportItem[] => {
234
+ const { productBlocks } = productBlocksResponse;
235
+ return productBlocks.map((productBlock) => ({
236
+ ...productBlock,
237
+ resourceTypes: getConcatenatedResult(productBlock.resourceTypes, [
238
+ 'resourceType',
239
+ 'description',
240
+ ]),
241
+ dependsOn: getConcatenatedResult(productBlock.dependsOn, ['name']),
242
+ }));
243
+ };
244
+
221
245
  return (
222
246
  <WfoMetadataPageLayout>
223
247
  <WfoTableWithFilter<ProductBlockDefinition>
@@ -247,7 +271,7 @@ export const WfoProductBlocksPage = () => {
247
271
  }
248
272
  onExportData={csvDownloadHandler(
249
273
  getProductBlocksForExport,
250
- (data) => data.productBlocks,
274
+ mapToExportItems,
251
275
  (data) => data.pageInfo,
252
276
  Object.keys(tableColumns),
253
277
  getCsvFileNameWithDate('ProductBlocks'),
@@ -26,9 +26,11 @@ import {
26
26
  useStoredTableConfig,
27
27
  } from '@/hooks';
28
28
  import { useGetProductsQuery, useLazyGetProductsQuery } from '@/rtk';
29
+ import { ProductsResponse } from '@/rtk';
29
30
  import type { GraphqlQueryVariables, ProductDefinition } from '@/types';
30
31
  import { BadgeType, SortOrder } from '@/types';
31
32
  import {
33
+ getConcatenatedResult,
32
34
  getQueryVariablesForExport,
33
35
  parseDateToLocaleDateTimeString,
34
36
  parseIsoString,
@@ -50,6 +52,14 @@ const PRODUCT_FIELD_PRODUCT_BLOCKS: keyof ProductDefinition = 'productBlocks';
50
52
  const PRODUCT_FIELD_FIXED_INPUTS: keyof ProductDefinition = 'fixedInputs';
51
53
  const PRODUCT_FIELD_CREATED_AT: keyof ProductDefinition = 'createdAt';
52
54
 
55
+ type ProductDefinitionExportItem = Omit<
56
+ ProductDefinition,
57
+ 'fixedInputs' | 'productBlocks'
58
+ > & {
59
+ fixedInputs: string;
60
+ productBlocks: string;
61
+ };
62
+
53
63
  export const WfoProductsPage = () => {
54
64
  const t = useTranslations('metadata.products');
55
65
  const tError = useTranslations('errors');
@@ -197,6 +207,22 @@ export const WfoProductsPage = () => {
197
207
  sortOrder: sortBy?.order ?? SortOrder.ASC,
198
208
  };
199
209
 
210
+ const mapToExportItems = (
211
+ productsResponse: ProductsResponse,
212
+ ): ProductDefinitionExportItem[] => {
213
+ const { products } = productsResponse;
214
+ return products.map((product) => ({
215
+ ...product,
216
+ fixedInputs: getConcatenatedResult(product.fixedInputs, [
217
+ 'name',
218
+ 'value',
219
+ ]),
220
+ productBlocks: getConcatenatedResult(product.productBlocks, [
221
+ 'name',
222
+ ]),
223
+ }));
224
+ };
225
+
200
226
  return (
201
227
  <WfoMetadataPageLayout>
202
228
  <WfoTableWithFilter<ProductDefinition>
@@ -224,7 +250,7 @@ export const WfoProductsPage = () => {
224
250
  localStorageKey={METADATA_PRODUCT_TABLE_LOCAL_STORAGE_KEY}
225
251
  onExportData={csvDownloadHandler(
226
252
  getProductsForExport,
227
- (data) => data?.products ?? [],
253
+ mapToExportItems,
228
254
  (data) => data?.pageInfo || {},
229
255
  Object.keys(tableColumns),
230
256
  getCsvFileNameWithDate('Products'),
@@ -25,14 +25,18 @@ import {
25
25
  useShowToastMessage,
26
26
  useStoredTableConfig,
27
27
  } from '@/hooks';
28
- import { useGetResourceTypesQuery, useLazyGetResourceTypesQuery } from '@/rtk';
28
+ import {
29
+ ResourceTypesResponse,
30
+ useGetResourceTypesQuery,
31
+ useLazyGetResourceTypesQuery,
32
+ } from '@/rtk';
29
33
  import {
30
34
  BadgeType,
31
35
  GraphqlQueryVariables,
32
36
  ResourceTypeDefinition,
33
37
  SortOrder,
34
38
  } from '@/types';
35
- import { getQueryVariablesForExport } from '@/utils';
39
+ import { getConcatenatedResult, getQueryVariablesForExport } from '@/utils';
36
40
  import {
37
41
  csvDownloadHandler,
38
42
  getCsvFileNameWithDate,
@@ -51,6 +55,10 @@ export const RESOURCE_TYPE_FIELD_DESCRIPTION: keyof ResourceTypeDefinition =
51
55
  export const RESOURCE_TYPE_FIELD_PRODUCT_BLOCKS: keyof ResourceTypeDefinition =
52
56
  'productBlocks';
53
57
 
58
+ type ResourceTypeExportItem = Omit<ResourceTypeDefinition, 'productBlocks'> & {
59
+ productBlocks: string;
60
+ };
61
+
54
62
  export const WfoResourceTypesPage = () => {
55
63
  const t = useTranslations('metadata.resourceTypes');
56
64
  const tError = useTranslations('errors');
@@ -168,7 +176,18 @@ export const WfoResourceTypesPage = () => {
168
176
  pageSizeOptions: DEFAULT_PAGE_SIZES,
169
177
  totalItemCount: totalItems ? totalItems : 0,
170
178
  };
171
-
179
+ const mapToExportItems = (
180
+ resourceTypesResponse: ResourceTypesResponse,
181
+ ): ResourceTypeExportItem[] => {
182
+ const { resourceTypes } = resourceTypesResponse;
183
+ return resourceTypes.map((resourceType) => ({
184
+ ...resourceType,
185
+ productBlocks: getConcatenatedResult(resourceType.productBlocks, [
186
+ 'productBlockId',
187
+ 'name',
188
+ ]),
189
+ }));
190
+ };
172
191
  return (
173
192
  <WfoMetadataPageLayout>
174
193
  <WfoTableWithFilter<ResourceTypeDefinition>
@@ -198,7 +217,7 @@ export const WfoResourceTypesPage = () => {
198
217
  }
199
218
  onExportData={csvDownloadHandler(
200
219
  getResourceTypesForExport,
201
- (data) => data.resourceTypes,
220
+ mapToExportItems,
202
221
  (data) => data.pageInfo,
203
222
  Object.keys(tableColumns),
204
223
  getCsvFileNameWithDate('ResourceTypes'),
@@ -0,0 +1,226 @@
1
+ import React, { useEffect, useState } from 'react';
2
+
3
+ import { useTranslations } from 'next-intl';
4
+
5
+ import { EuiBadgeGroup } from '@elastic/eui';
6
+ import type { Pagination } from '@elastic/eui/src/components';
7
+
8
+ import { WfoTableWithFilter, WfoWorkflowTargetBadge } from '@/components';
9
+ import type { WfoDataSorting, WfoTableColumns } from '@/components';
10
+ import { StoredTableConfig } from '@/components';
11
+ import {
12
+ DEFAULT_PAGE_SIZE,
13
+ DEFAULT_PAGE_SIZES,
14
+ METADATA_TASKS_TABLE_LOCAL_STORAGE_KEY,
15
+ WfoProductBlockBadge,
16
+ } from '@/components';
17
+ import {
18
+ getDataSortHandler,
19
+ getPageChangeHandler,
20
+ getQueryStringHandler,
21
+ } from '@/components';
22
+ import { WfoDateTime } from '@/components/WfoDateTime/WfoDateTime';
23
+ import { mapSortableAndFilterableValuesToTableColumnConfig } from '@/components/WfoTable/utils/mapSortableAndFilterableValuesToTableColumnConfig';
24
+ import {
25
+ useDataDisplayParams,
26
+ useShowToastMessage,
27
+ useStoredTableConfig,
28
+ } from '@/hooks';
29
+ import { useGetTasksQuery, useLazyGetTasksQuery } from '@/rtk';
30
+ import type { GraphqlQueryVariables, TaskDefinition } from '@/types';
31
+ import { BadgeType, SortOrder } from '@/types';
32
+ import {
33
+ getQueryVariablesForExport,
34
+ onlyUnique,
35
+ parseDateToLocaleDateTimeString,
36
+ parseIsoString,
37
+ } from '@/utils';
38
+ import {
39
+ csvDownloadHandler,
40
+ getCsvFileNameWithDate,
41
+ } from '@/utils/csvDownload';
42
+
43
+ import { WfoMetadataPageLayout } from './WfoMetadataPageLayout';
44
+ import {
45
+ graphQlTaskListMapper,
46
+ mapTaskDefinitionToTaskListItem,
47
+ } from './taskListObjectMapper';
48
+
49
+ export type TaskListItem = Pick<
50
+ TaskDefinition,
51
+ 'name' | 'description' | 'target' | 'createdAt'
52
+ > & {
53
+ productTags: string[];
54
+ };
55
+
56
+ export const WfoTasksPage = () => {
57
+ const t = useTranslations('metadata.tasks');
58
+ const tError = useTranslations('errors');
59
+ const { showToastMessage } = useShowToastMessage();
60
+
61
+ const [tableDefaults, setTableDefaults] =
62
+ useState<StoredTableConfig<TaskListItem>>();
63
+
64
+ const getStoredTableConfig = useStoredTableConfig<TaskListItem>(
65
+ METADATA_TASKS_TABLE_LOCAL_STORAGE_KEY,
66
+ );
67
+
68
+ useEffect(() => {
69
+ const storedConfig = getStoredTableConfig();
70
+
71
+ if (storedConfig) {
72
+ setTableDefaults(storedConfig);
73
+ }
74
+ }, [getStoredTableConfig]);
75
+
76
+ const { dataDisplayParams, setDataDisplayParam } =
77
+ useDataDisplayParams<TaskListItem>({
78
+ // TODO: Improvement: A default pageSize value is set to avoid a graphql error when the query is executed
79
+ // the fist time before the useEffect has populated the tableDefaults. Better is to create a way for
80
+ // the query to wait for the values to be available
81
+ // https://github.com/workfloworchestrator/orchestrator-ui/issues/261
82
+ pageSize: tableDefaults?.selectedPageSize || DEFAULT_PAGE_SIZE,
83
+ sortBy: {
84
+ field: 'name',
85
+ order: SortOrder.ASC,
86
+ },
87
+ });
88
+
89
+ const tableColumns: WfoTableColumns<TaskListItem> = {
90
+ name: {
91
+ field: 'name',
92
+ name: t('name'),
93
+ width: '20%',
94
+ render: (name) => (
95
+ <WfoProductBlockBadge badgeType={BadgeType.TASK}>
96
+ {name}
97
+ </WfoProductBlockBadge>
98
+ ),
99
+ },
100
+ description: {
101
+ field: 'description',
102
+ name: t('description'),
103
+ width: '40%',
104
+ },
105
+ target: {
106
+ field: 'target',
107
+ name: t('target'),
108
+ width: '15%',
109
+ render: (target) => <WfoWorkflowTargetBadge target={target} />,
110
+ },
111
+ productTags: {
112
+ field: 'productTags',
113
+ name: t('productTags'),
114
+ width: '20%',
115
+ render: (productTags) => (
116
+ <>
117
+ {productTags
118
+ ?.filter(onlyUnique)
119
+ .map((productTag, index) => (
120
+ <WfoProductBlockBadge
121
+ key={index}
122
+ badgeType={BadgeType.PRODUCT_TAG}
123
+ >
124
+ {productTag}
125
+ </WfoProductBlockBadge>
126
+ ))}
127
+ </>
128
+ ),
129
+ renderDetails: (productTags) => (
130
+ <EuiBadgeGroup gutterSize="s">
131
+ {productTags
132
+ ?.filter(onlyUnique)
133
+ .map((productTag, index) => (
134
+ <WfoProductBlockBadge
135
+ key={index}
136
+ badgeType={BadgeType.PRODUCT_TAG}
137
+ >
138
+ {productTag}
139
+ </WfoProductBlockBadge>
140
+ ))}
141
+ </EuiBadgeGroup>
142
+ ),
143
+ },
144
+ createdAt: {
145
+ field: 'createdAt',
146
+ name: t('createdAt'),
147
+ width: '15%',
148
+ render: (date) => <WfoDateTime dateOrIsoString={date} />,
149
+ renderDetails: parseIsoString(parseDateToLocaleDateTimeString),
150
+ clipboardText: parseIsoString(parseDateToLocaleDateTimeString),
151
+ },
152
+ };
153
+
154
+ const { pageSize, pageIndex, sortBy, queryString } = dataDisplayParams;
155
+
156
+ const taskListQueryVariables: GraphqlQueryVariables<TaskDefinition> = {
157
+ first: pageSize,
158
+ after: pageIndex * pageSize,
159
+ sortBy: graphQlTaskListMapper(sortBy),
160
+ query: queryString || undefined,
161
+ };
162
+ const { data, isFetching, isError } = useGetTasksQuery(
163
+ taskListQueryVariables,
164
+ );
165
+
166
+ const [getTasksTrigger, { isFetching: isFetchingCsv }] =
167
+ useLazyGetTasksQuery();
168
+
169
+ const getTasksForExport = () =>
170
+ getTasksTrigger(
171
+ getQueryVariablesForExport(taskListQueryVariables),
172
+ ).unwrap();
173
+
174
+ const dataSorting: WfoDataSorting<TaskListItem> = {
175
+ field: sortBy?.field ?? 'name',
176
+ sortOrder: sortBy?.order ?? SortOrder.ASC,
177
+ };
178
+
179
+ const { totalItems, sortFields, filterFields } = data?.pageInfo || {};
180
+
181
+ const pagination: Pagination = {
182
+ pageSize: pageSize,
183
+ pageIndex: pageIndex,
184
+ pageSizeOptions: DEFAULT_PAGE_SIZES,
185
+ totalItemCount: totalItems ? totalItems : 0,
186
+ };
187
+
188
+ return (
189
+ <WfoMetadataPageLayout>
190
+ <WfoTableWithFilter<TaskListItem>
191
+ data={data ? mapTaskDefinitionToTaskListItem(data.tasks) : []}
192
+ tableColumns={mapSortableAndFilterableValuesToTableColumnConfig(
193
+ tableColumns,
194
+ sortFields,
195
+ filterFields,
196
+ )}
197
+ dataSorting={dataSorting}
198
+ defaultHiddenColumns={tableDefaults?.hiddenColumns}
199
+ onUpdateDataSort={getDataSortHandler<TaskListItem>(
200
+ setDataDisplayParam,
201
+ )}
202
+ onUpdatePage={getPageChangeHandler<TaskListItem>(
203
+ setDataDisplayParam,
204
+ )}
205
+ onUpdateQueryString={getQueryStringHandler<TaskListItem>(
206
+ setDataDisplayParam,
207
+ )}
208
+ pagination={pagination}
209
+ isLoading={isFetching}
210
+ hasError={isError}
211
+ queryString={queryString}
212
+ localStorageKey={METADATA_TASKS_TABLE_LOCAL_STORAGE_KEY}
213
+ onExportData={csvDownloadHandler(
214
+ getTasksForExport,
215
+ (data) => data.tasks,
216
+ (data) => data.pageInfo,
217
+ Object.keys(tableColumns),
218
+ getCsvFileNameWithDate('Tasks'),
219
+ showToastMessage,
220
+ tError,
221
+ )}
222
+ exportDataIsLoading={isFetchingCsv}
223
+ />
224
+ </WfoMetadataPageLayout>
225
+ );
226
+ };