@orchestrator-ui/orchestrator-ui-components 7.7.0 → 8.1.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 (34) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test.log +7 -7
  4. package/CHANGELOG.md +17 -0
  5. package/dist/index.d.ts +384 -9
  6. package/dist/index.js +2589 -2445
  7. package/dist/index.js.map +1 -1
  8. package/package.json +2 -2
  9. package/src/components/WfoBadges/WfoProductStatusBadge/WfoProductStatusBadge.tsx +7 -4
  10. package/src/components/WfoBadges/WfoVersionIncompatibleBadge/WfoVersionIncompatibleBadge.tsx +4 -3
  11. package/src/components/WfoInlineNoteEdit/WfoProcessListNoteEdit.tsx +31 -0
  12. package/src/components/WfoInlineNoteEdit/index.ts +1 -0
  13. package/src/components/WfoInlineNoteEdit/styles.ts +11 -0
  14. package/src/components/WfoMetadata/WfoMetadataStatusField.tsx +48 -0
  15. package/src/components/WfoMetadata/index.ts +2 -0
  16. package/src/components/WfoProcessList/WfoProcessesList.tsx +8 -0
  17. package/src/components/WfoProcessList/processListObjectMappers.ts +4 -0
  18. package/src/components/WfoPydanticForm/fields/WfoArrayField/WfoArrayField.tsx +1 -1
  19. package/src/components/WfoPydanticForm/fields/WfoInteger.tsx +8 -6
  20. package/src/components/WfoPydanticForm/fields/WfoObjectField/WfoObjectField.tsx +1 -1
  21. package/src/components/WfoSubscription/WfoProcessesTimeline.tsx +7 -0
  22. package/src/components/WfoSubscription/utils/utils.spec.ts +1 -0
  23. package/src/configuration/version.ts +1 -1
  24. package/src/messages/en-GB.json +4 -2
  25. package/src/messages/nl-NL.json +4 -2
  26. package/src/pages/metadata/WfoProductsPage.tsx +23 -7
  27. package/src/pages/processes/WfoProcessDetail.tsx +8 -1
  28. package/src/rtk/api.ts +1 -0
  29. package/src/rtk/endpoints/metadata/products.ts +23 -2
  30. package/src/rtk/endpoints/processDetail.ts +25 -1
  31. package/src/rtk/endpoints/processList.ts +1 -0
  32. package/src/rtk/endpoints/subscriptionDetail.ts +1 -0
  33. package/src/types/types.ts +13 -5
  34. package/src/utils/getProductNamesFromProcess.spec.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchestrator-ui/orchestrator-ui-components",
3
- "version": "7.7.0",
3
+ "version": "8.1.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Library of UI Components used to display the workflow orchestrator frontend",
6
6
  "author": {
@@ -54,7 +54,7 @@
54
54
  "next-query-params": "^5.0.0",
55
55
  "object-hash": "^3.0.0",
56
56
  "prism-themes": "^1.9.0",
57
- "pydantic-forms": "^1.0.7",
57
+ "pydantic-forms": "^2.0.0",
58
58
  "react-diff-view": "^3.2.0",
59
59
  "react-draggable": "^4.4.6",
60
60
  "react-redux": "^9.1.2",
@@ -8,13 +8,16 @@ export type WfoProductStatusBadgeProps = {
8
8
  status: ProductLifecycleStatus;
9
9
  };
10
10
 
11
+ const normalizedStatus = (status: ProductLifecycleStatus): string => status.toLowerCase().replace(/_/g, ' ');
12
+
11
13
  export const WfoProductStatusBadge: FC<WfoProductStatusBadgeProps> = ({ status }) => {
12
14
  const { theme, toSecondaryColor } = useOrchestratorTheme();
13
15
 
14
- const getBadgeColorFromStatus = (status: string) => {
16
+ const productLifeCycleStatus = normalizedStatus(status);
17
+ const getBadgeColorFromStatus = () => {
15
18
  const { primary, borderBaseSubdued, textPrimary, textParagraph, success, textSuccess } = theme.colors;
16
19
 
17
- switch (status.toLowerCase()) {
20
+ switch (productLifeCycleStatus) {
18
21
  case ProductLifecycleStatus.ACTIVE:
19
22
  return {
20
23
  badgeColor: toSecondaryColor(success),
@@ -34,11 +37,11 @@ export const WfoProductStatusBadge: FC<WfoProductStatusBadgeProps> = ({ status }
34
37
  }
35
38
  };
36
39
 
37
- const { badgeColor, textColor } = getBadgeColorFromStatus(status);
40
+ const { badgeColor, textColor } = getBadgeColorFromStatus();
38
41
 
39
42
  return (
40
43
  <WfoBadge textColor={textColor} color={badgeColor}>
41
- {status.toLowerCase()}
44
+ {productLifeCycleStatus}
42
45
  </WfoBadge>
43
46
  );
44
47
  };
@@ -21,7 +21,7 @@ export const WfoVersionIncompatibleBadge: FC<WfoVersionIncompatibleBadgeProps> =
21
21
  orchestratorCoreVersion,
22
22
  }) => {
23
23
  const t = useTranslations('main');
24
- const { theme } = useOrchestratorTheme();
24
+ const { theme, isDarkModeActive } = useOrchestratorTheme();
25
25
  const mappedVersions: MappedVersion[] = versionCompatibility;
26
26
  const isReady = orchestratorCoreVersion && orchestratorUiVersion;
27
27
 
@@ -50,10 +50,11 @@ export const WfoVersionIncompatibleBadge: FC<WfoVersionIncompatibleBadgeProps> =
50
50
  >
51
51
  <WfoHeaderBadge
52
52
  color="danger"
53
- textColor={theme.colors.textGhost}
53
+ textColor={isDarkModeActive ? theme.colors.textGhost : theme.colors.textInk}
54
54
  css={{
55
55
  marginLeft: theme.size.s,
56
- display: minimumOrchestratorCoreVersion ? 'block' : 'none',
56
+ display: minimumOrchestratorCoreVersion ? 'flex' : 'none',
57
+ cursor: 'default',
57
58
  }}
58
59
  >
59
60
  {t('incompatibleVersion')}
@@ -0,0 +1,31 @@
1
+ import type { FC } from 'react';
2
+ import React, { useEffect, useState } from 'react';
3
+
4
+ import { usePatchProcessMutation } from '@/rtk';
5
+ import { ProcessDetail } from '@/types';
6
+
7
+ import { WfoInlineEdit } from '../WfoInlineEdit';
8
+
9
+ interface WfoProcessDetailNoteEditProps {
10
+ processId: ProcessDetail['processId'];
11
+ note: ProcessDetail['note'];
12
+ }
13
+
14
+ export const WfoProcessListNoteEdit: FC<WfoProcessDetailNoteEditProps> = ({ processId, note }) => {
15
+ const [patchProcess] = usePatchProcessMutation();
16
+ const [noteValue, setNoteValue] = useState(note);
17
+
18
+ useEffect(() => {
19
+ if (note !== noteValue) {
20
+ setNoteValue(note);
21
+ }
22
+ }, [note, noteValue]);
23
+
24
+ const onSaveNote = async (note: string) => {
25
+ const noteModifyPayload = { id: processId, note: note };
26
+ patchProcess(noteModifyPayload);
27
+ return note;
28
+ };
29
+
30
+ return <WfoInlineEdit value={noteValue?.trim() || ''} onSave={onSaveNote} />;
31
+ };
@@ -1,2 +1,3 @@
1
1
  export * from './WfoSubscriptionNoteEdit';
2
2
  export * from './WfoSubscriptionDetailNoteEdit';
3
+ export * from './WfoProcessListNoteEdit';
@@ -0,0 +1,11 @@
1
+ import { css } from '@emotion/react';
2
+
3
+ export const getStyles = () => {
4
+ const getProcessDetailPageNoteStyle = css({
5
+ paddingBottom: '10px',
6
+ });
7
+
8
+ return {
9
+ getProcessDetailPageNoteStyle,
10
+ };
11
+ };
@@ -0,0 +1,48 @@
1
+ import React, { FC, useState } from 'react';
2
+
3
+ import { EuiButtonEmpty } from '@elastic/eui';
4
+
5
+ import { ProductLifecycleStatus } from '@/types';
6
+
7
+ import { WfoProductStatusBadge } from '../WfoBadges';
8
+ import { WfoPopover } from '../WfoPopover';
9
+
10
+ interface WfoMetadataStatusFieldProps {
11
+ onSave: (updatedStatus: ProductLifecycleStatus) => void;
12
+ currentStatus: ProductLifecycleStatus;
13
+ }
14
+
15
+ export const WfoMetadataStatusField: FC<WfoMetadataStatusFieldProps> = ({ onSave, currentStatus }) => {
16
+ const [isPopoverOpen, setPopover] = useState<boolean>(false);
17
+ const onButtonClick = () => setPopover(!isPopoverOpen);
18
+ const button = (
19
+ <EuiButtonEmpty iconType="arrowDown" iconSide="right" onClick={onButtonClick} color={'text'}>
20
+ <WfoProductStatusBadge status={currentStatus} />
21
+ </EuiButtonEmpty>
22
+ );
23
+
24
+ const handleOnSelectOption = (updatedStatus: ProductLifecycleStatus) => {
25
+ setPopover(false);
26
+ onSave(updatedStatus);
27
+ };
28
+
29
+ const setNewStatusBadges = () =>
30
+ Object.values(ProductLifecycleStatus).map((productStatus) => (
31
+ <EuiButtonEmpty onClick={() => handleOnSelectOption(productStatus)}>
32
+ <WfoProductStatusBadge status={productStatus} />
33
+ </EuiButtonEmpty>
34
+ ));
35
+
36
+ return (
37
+ <WfoPopover
38
+ id={'productStatusPopover'}
39
+ isLoading={false}
40
+ button={button}
41
+ isPopoverOpen={isPopoverOpen}
42
+ closePopover={() => setPopover(false)}
43
+ PopoverContent={setNewStatusBadges}
44
+ />
45
+ );
46
+ };
47
+
48
+ export default WfoMetadataStatusField;
@@ -0,0 +1,2 @@
1
+ export * from './WfoMetadataDescriptionField';
2
+ export * from './WfoMetadataStatusField';
@@ -8,6 +8,7 @@ import {
8
8
  FilterQuery,
9
9
  PATH_WORKFLOWS,
10
10
  WfoDateTime,
11
+ WfoProcessListNoteEdit,
11
12
  WfoProcessStatusBadge,
12
13
  WfoWorkflowTargetBadge,
13
14
  getPageIndexChangeHandler,
@@ -53,6 +54,7 @@ export type ProcessListItem = Pick<
53
54
  | 'assignee'
54
55
  | 'processId'
55
56
  | 'subscriptions'
57
+ | 'note'
56
58
  > & {
57
59
  startedAt: Date;
58
60
  lastModifiedAt: Date;
@@ -138,6 +140,12 @@ export const WfoProcessesList = ({
138
140
  label: t('customerAbbreviation'),
139
141
  width: '125px',
140
142
  },
143
+ note: {
144
+ columnType: ColumnType.DATA,
145
+ label: t('note'),
146
+ width: '250px',
147
+ renderData: (note, { processId }) => <WfoProcessListNoteEdit processId={processId} note={note} />,
148
+ },
141
149
  subscriptions: {
142
150
  columnType: ColumnType.DATA,
143
151
  label: t('subscriptions'),
@@ -23,6 +23,7 @@ export const mapGraphQlProcessListResultToProcessListItems = (processes: Process
23
23
  product,
24
24
  customer,
25
25
  isTask,
26
+ note,
26
27
  } = process;
27
28
 
28
29
  return {
@@ -41,6 +42,7 @@ export const mapGraphQlProcessListResultToProcessListItems = (processes: Process
41
42
  tag: product?.tag,
42
43
  customer: customer.fullname,
43
44
  customerAbbreviation: customer.shortcode,
45
+ note,
44
46
  };
45
47
  });
46
48
 
@@ -62,6 +64,7 @@ export const mapGraphQlProcessListExportResultToProcessListItems = (
62
64
  product,
63
65
  customer,
64
66
  isTask,
67
+ note,
65
68
  } = process;
66
69
 
67
70
  return {
@@ -83,6 +86,7 @@ export const mapGraphQlProcessListExportResultToProcessListItems = (
83
86
  productTag: product?.tag,
84
87
  customer: customer.fullname,
85
88
  customerAbbreviation: customer.shortcode,
89
+ note,
86
90
  };
87
91
  });
88
92
 
@@ -81,7 +81,7 @@ export const WfoArrayField = ({ pydanticFormField }: PydanticFormElementProps) =
81
81
 
82
82
  if (!arrayItem) return null;
83
83
 
84
- const component = fieldToComponentMatcher(arrayItem, config?.componentMatcherExtender);
84
+ const component = fieldToComponentMatcher(arrayItem, config?.componentMatcher);
85
85
 
86
86
  const renderField = (field: Record<'id', string>, index: number) => {
87
87
  const itemizedField = itemizeArrayItem(index, arrayItem, arrayName);
@@ -31,20 +31,22 @@ export const WfoInteger: PydanticFormControlledElement = ({ pydanticFormField, o
31
31
  // this is imposed by react-hook-form. We try to detect this and extract the actual value
32
32
  const fieldName = getFormFieldIdWithPath(pydanticFormField.id);
33
33
  const fieldValue = _.isObject(value) && _.has(value, fieldName) ? _.get(value, fieldName) : value;
34
- const [userInput, setUserInput] = React.useState<string>();
34
+ const [userInput, setUserInput] = React.useState<string>('');
35
35
 
36
36
  useEffect(() => {
37
37
  if (fieldValue !== undefined && fieldValue !== null) {
38
38
  setUserInput(fieldValue);
39
- } else {
40
- setUserInput('');
41
39
  }
42
40
  }, [fieldValue, value]);
43
41
 
44
42
  const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {
45
- const newValue = event.target.value;
46
- if (value === null && newValue !== value) {
47
- onChange(parseInt(newValue));
43
+ const newValue = event.target.value || '';
44
+ if (value === null || newValue !== value) {
45
+ if (!isNaN(parseInt(newValue))) {
46
+ onChange(parseInt(newValue));
47
+ } else {
48
+ onChange('');
49
+ }
48
50
  }
49
51
  setUserInput(newValue);
50
52
  };
@@ -16,7 +16,7 @@ export const WfoObjectField = ({ pydanticFormField }: PydanticFormElementProps)
16
16
  const config = useGetConfig();
17
17
  const disabled = pydanticFormField.attributes?.disabled || false;
18
18
  const { wfoObjectFieldStyles } = getWfoObjectFieldStyles();
19
- const components = getPydanticFormComponents(pydanticFormField.properties || {}, config?.componentMatcherExtender);
19
+ const components = getPydanticFormComponents(pydanticFormField.properties || {}, config?.componentMatcher);
20
20
 
21
21
  // We have decided - for now - on the convention that all descendants of disabled fields will be disabled as well
22
22
  // so we will not displaying any interactive elements inside a disabled element
@@ -9,6 +9,7 @@ import {
9
9
  PATH_TASKS,
10
10
  PATH_WORKFLOWS,
11
11
  WfoLoading,
12
+ WfoProcessListNoteEdit,
12
13
  WfoRadioDropdown,
13
14
  WfoRadioDropdownOption,
14
15
  sortProcessesByDate,
@@ -54,6 +55,12 @@ const WfoProcessCard = ({ subscriptionDetailProcess }: WfoProcessCardProps) => {
54
55
  label: t('startedBy'),
55
56
  content: subscriptionDetailProcess.createdBy,
56
57
  },
58
+ {
59
+ label: t('note'),
60
+ content: (
61
+ <WfoProcessListNoteEdit processId={subscriptionDetailProcess.processId} note={subscriptionDetailProcess.note} />
62
+ ),
63
+ },
57
64
  ];
58
65
 
59
66
  return (
@@ -171,6 +171,7 @@ const testProcess: SubscriptionDetailProcess = {
171
171
  processId: 'testProcessId 1',
172
172
  startedAt: '2021-01-01T00:00:00Z',
173
173
  isTask: false,
174
+ note: 'testNote',
174
175
  };
175
176
 
176
177
  describe('getLastUncompletedProcess', () => {
@@ -1 +1 @@
1
- export const ORCHESTRATOR_UI_LIBRARY_VERSION = '7.7.0';
1
+ export const ORCHESTRATOR_UI_LIBRARY_VERSION = '8.1.0';
@@ -249,7 +249,8 @@
249
249
  "lastModified": "Last modified",
250
250
  "workflowTarget": "Target",
251
251
  "productTag": "Product tag",
252
- "showAllRelatedSubscriptions": "Show all related subscriptions"
252
+ "showAllRelatedSubscriptions": "Show all related subscriptions",
253
+ "note": "Note"
253
254
  },
254
255
  "detail": {
255
256
  "retry": "Retry",
@@ -409,7 +410,8 @@
409
410
  "id": "ID",
410
411
  "status": "Status",
411
412
  "startedAt": "Started at",
412
- "startedBy": "Started by"
413
+ "startedBy": "Started by",
414
+ "note": "Note"
413
415
  },
414
416
  "showAll": "Show all",
415
417
  "hideAll": "Hide all",
@@ -248,7 +248,8 @@
248
248
  "lastModified": "Aangepast op",
249
249
  "workflowTarget": "Target",
250
250
  "productTag": "Product tag",
251
- "showAllRelatedSubscriptions": "Toon alle gerelateerde subscriptions"
251
+ "showAllRelatedSubscriptions": "Toon alle gerelateerde subscriptions",
252
+ "note": "Note"
252
253
  },
253
254
  "detail": {
254
255
  "retry": "Probeer opnieuw",
@@ -408,7 +409,8 @@
408
409
  "id": "ID",
409
410
  "status": "Status",
410
411
  "startedAt": "Started at",
411
- "startedBy": "Started by"
412
+ "startedBy": "Started by",
413
+ "note": "Note"
412
414
  },
413
415
  "showAll": "Toon alles",
414
416
  "hideAll": "Verberg alles",
@@ -15,10 +15,10 @@ import {
15
15
  StoredTableConfig,
16
16
  WfoDateTime,
17
17
  WfoProductBlockBadge,
18
- WfoProductStatusBadge,
19
18
  getDataSortHandler,
20
19
  getQueryStringHandler,
21
20
  } from '@/components';
21
+ import { WfoMetadataStatusField } from '@/components/WfoMetadata';
22
22
  import { WfoMetadataDescriptionField } from '@/components/WfoMetadata/WfoMetadataDescriptionField';
23
23
  import { WfoAdvancedTable } from '@/components/WfoTable/WfoAdvancedTable';
24
24
  import { WfoAdvancedTableColumnConfig } from '@/components/WfoTable/WfoAdvancedTable/types';
@@ -26,10 +26,15 @@ import { WfoFirstPartUUID } from '@/components/WfoTable/WfoFirstPartUUID';
26
26
  import { ColumnType, Pagination } from '@/components/WfoTable/WfoTable';
27
27
  import { mapSortableAndFilterableValuesToTableColumnConfig } from '@/components/WfoTable/WfoTable/utils';
28
28
  import { useDataDisplayParams, useShowToastMessage, useStoredTableConfig } from '@/hooks';
29
- import { useGetProductsQuery, useLazyGetProductsQuery, useUpdateProductMutation } from '@/rtk';
29
+ import {
30
+ useGetProductsQuery,
31
+ useLazyGetProductsQuery,
32
+ useUpdateProductDescriptionMutation,
33
+ useUpdateProductStatusMutation,
34
+ } from '@/rtk';
30
35
  import { ProductsResponse } from '@/rtk';
31
36
  import { mapRtkErrorToWfoError } from '@/rtk/utils';
32
- import type { GraphqlQueryVariables, ProductDefinition } from '@/types';
37
+ import type { GraphqlQueryVariables, ProductDefinition, ProductLifecycleStatus } from '@/types';
33
38
  import { BadgeType, SortOrder } from '@/types';
34
39
  import {
35
40
  getConcatenatedResult,
@@ -56,7 +61,8 @@ export const WfoProductsPage = () => {
56
61
  const [tableDefaults, setTableDefaults] = useState<StoredTableConfig<ProductDefinition>>();
57
62
 
58
63
  const getStoredTableConfig = useStoredTableConfig<ProductDefinition>(METADATA_PRODUCT_TABLE_LOCAL_STORAGE_KEY);
59
- const [updateProduct] = useUpdateProductMutation();
64
+ const [updateProductDescription] = useUpdateProductDescriptionMutation();
65
+ const [updateProductStatus] = useUpdateProductStatusMutation();
60
66
 
61
67
  useEffect(() => {
62
68
  const storedConfig = getStoredTableConfig();
@@ -106,7 +112,7 @@ export const WfoProductsPage = () => {
106
112
  renderData: (value, row) => (
107
113
  <WfoMetadataDescriptionField
108
114
  onSave={(updatedNote) =>
109
- updateProduct({
115
+ updateProductDescription({
110
116
  id: row.productId,
111
117
  description: updatedNote,
112
118
  })
@@ -123,8 +129,18 @@ export const WfoProductsPage = () => {
123
129
  status: {
124
130
  columnType: ColumnType.DATA,
125
131
  label: t('status'),
126
- width: '90px',
127
- renderData: (value) => <WfoProductStatusBadge status={value} />,
132
+ width: '150px',
133
+ renderData: (value, row) => (
134
+ <WfoMetadataStatusField
135
+ onSave={(updatedStatus: ProductLifecycleStatus) =>
136
+ updateProductStatus({
137
+ id: row.productId,
138
+ status: updatedStatus,
139
+ })
140
+ }
141
+ currentStatus={value}
142
+ />
143
+ ),
128
144
  },
129
145
  fixedInputs: {
130
146
  columnType: ColumnType.DATA,
@@ -11,6 +11,7 @@ import {
11
11
  TimelineItem,
12
12
  WfoIsAllowedToRender,
13
13
  WfoLoading,
14
+ WfoProcessListNoteEdit,
14
15
  WfoTimeline,
15
16
  WfoTitleWithWebsocketBadge,
16
17
  } from '@/components';
@@ -182,7 +183,13 @@ export const WfoProcessDetail = ({
182
183
  <WfoContentHeader
183
184
  title={<WfoTitleWithWebsocketBadge title={pageTitle} />}
184
185
  subtitle={
185
- <WfoProductInformationWithLink productNames={productNames} workflowName={processDetail?.workflowName ?? ''} />
186
+ <>
187
+ <WfoProcessListNoteEdit processId={processDetail?.processId || ''} note={processDetail?.note || ''} />
188
+ <WfoProductInformationWithLink
189
+ productNames={productNames}
190
+ workflowName={processDetail?.workflowName ?? ''}
191
+ />
192
+ </>
186
193
  }
187
194
  >
188
195
  <WfoIsAllowedToRender resource={PolicyResource.PROCESS_RETRY}>
package/src/rtk/api.ts CHANGED
@@ -165,6 +165,7 @@ export const orchestratorApi = createApi({
165
165
  CacheTagType.processStatusCounts,
166
166
  CacheTagType.subscriptions,
167
167
  CacheTagType.scheduledTasks,
168
+ CacheTagType.metadataProducts,
168
169
  ],
169
170
  keepUnusedDataFor: process.env.NEXT_PUBLIC_DISABLE_CACHE === 'true' ? 0 : 60 * 60 * 1000,
170
171
  });
@@ -2,11 +2,14 @@ import { METADATA_PRODUCT_ENDPOINT } from '@/configuration/constants';
2
2
  import { BaseQueryTypes, orchestratorApi } from '@/rtk';
3
3
  import {
4
4
  BaseGraphQlResult,
5
+ CacheTagType,
5
6
  GraphqlQueryVariables,
6
7
  MetadataDescriptionParams,
8
+ MetadataStatusParams,
7
9
  ProductDefinition,
8
10
  ProductDefinitionsResult,
9
11
  } from '@/types';
12
+ import { getCacheTag } from '@/utils';
10
13
 
11
14
  export const products = `
12
15
  query MetadataProducts(
@@ -66,6 +69,7 @@ const productsApi = orchestratorApi.injectEndpoints({
66
69
  pageInfo,
67
70
  };
68
71
  },
72
+ providesTags: getCacheTag(CacheTagType.metadataProducts),
69
73
  }),
70
74
  }),
71
75
  });
@@ -74,7 +78,7 @@ export const { useGetProductsQuery, useLazyGetProductsQuery } = productsApi;
74
78
 
75
79
  const productRestApi = orchestratorApi.injectEndpoints({
76
80
  endpoints: (build) => ({
77
- updateProduct: build.mutation<null, MetadataDescriptionParams>({
81
+ updateProductDescription: build.mutation<null, MetadataDescriptionParams>({
78
82
  query: (product) => ({
79
83
  url: `${METADATA_PRODUCT_ENDPOINT}/${product.id}`,
80
84
  method: 'PATCH',
@@ -88,8 +92,25 @@ const productRestApi = orchestratorApi.injectEndpoints({
88
92
  extraOptions: {
89
93
  baseQueryType: BaseQueryTypes.fetch,
90
94
  },
95
+ invalidatesTags: getCacheTag(CacheTagType.metadataProducts),
96
+ }),
97
+ updateProductStatus: build.mutation<null, MetadataStatusParams>({
98
+ query: (product) => ({
99
+ url: `${METADATA_PRODUCT_ENDPOINT}/${product.id}`,
100
+ method: 'PATCH',
101
+ headers: {
102
+ 'Content-Type': 'application/json',
103
+ },
104
+ body: {
105
+ status: product.status,
106
+ },
107
+ }),
108
+ extraOptions: {
109
+ baseQueryType: BaseQueryTypes.fetch,
110
+ },
111
+ invalidatesTags: getCacheTag(CacheTagType.metadataProducts),
91
112
  }),
92
113
  }),
93
114
  });
94
115
 
95
- export const { useUpdateProductMutation } = productRestApi;
116
+ export const { useUpdateProductDescriptionMutation, useUpdateProductStatusMutation } = productRestApi;
@@ -5,7 +5,13 @@ import {
5
5
  PROCESS_RESUME_ENDPOINT,
6
6
  } from '@/configuration';
7
7
  import { BaseQueryTypes, orchestratorApi } from '@/rtk';
8
- import { CacheTagType, ProcessDetail, ProcessDetailResultRaw, ProcessesDetailResult } from '@/types';
8
+ import {
9
+ CacheTagType,
10
+ ProcessDetail,
11
+ ProcessDetailResultRaw,
12
+ ProcessPatchParams,
13
+ ProcessesDetailResult,
14
+ } from '@/types';
9
15
  import { getCacheTag } from '@/utils/cacheTag';
10
16
 
11
17
  export const processDetailQuery = `query ProcessDetail($processId: String!) {
@@ -21,6 +27,7 @@ export const processDetailQuery = `query ProcessDetail($processId: String!) {
21
27
  isTask
22
28
  form
23
29
  traceback
30
+ note
24
31
  userPermissions {
25
32
  retryAllowed
26
33
  resumeAllowed
@@ -130,6 +137,22 @@ const processDetailApi = orchestratorApi.injectEndpoints({
130
137
  },
131
138
  invalidatesTags: getCacheTag(CacheTagType.processes),
132
139
  }),
140
+ patchProcess: builder.mutation<void, ProcessPatchParams>({
141
+ query: (process) => ({
142
+ url: `${PROCESSES_ENDPOINT}/${process.id}`,
143
+ method: 'PATCH',
144
+ headers: {
145
+ 'Content-Type': 'application/json',
146
+ },
147
+ body: {
148
+ note: process.note,
149
+ },
150
+ }),
151
+ extraOptions: {
152
+ baseQueryType: BaseQueryTypes.fetch,
153
+ },
154
+ invalidatesTags: [CacheTagType.processes, CacheTagType.subscriptions],
155
+ }),
133
156
  }),
134
157
  });
135
158
 
@@ -140,4 +163,5 @@ export const {
140
163
  useRetryProcessMutation,
141
164
  useDeleteProcessMutation,
142
165
  useAbortProcessMutation,
166
+ usePatchProcessMutation,
143
167
  } = processDetailApi;
@@ -50,6 +50,7 @@ export const processListQuery = `
50
50
  description
51
51
  }
52
52
  }
53
+ note
53
54
  }
54
55
  pageInfo {
55
56
  hasNextPage
@@ -57,6 +57,7 @@ fragment SubscriptionDetail on SubscriptionInterface {
57
57
  workflowTarget
58
58
  workflowName
59
59
  isTask
60
+ note
60
61
  }
61
62
  }
62
63
  }
@@ -164,6 +164,7 @@ export type Process = {
164
164
  subscriptions: {
165
165
  page: Pick<Subscription, 'subscriptionId' | 'description'>[];
166
166
  };
167
+ note: string | null;
167
168
  };
168
169
 
169
170
  // These step statusses match the ones in the backend
@@ -204,6 +205,7 @@ export interface ProcessDetail {
204
205
  customer: {
205
206
  fullname: string;
206
207
  };
208
+ note: string | null;
207
209
  }
208
210
 
209
211
  // From backend
@@ -501,10 +503,15 @@ export type MetadataDescriptionParams = {
501
503
  description: string;
502
504
  };
503
505
 
504
- // export type Workflow = {
505
- // workflow_id: string;
506
- // description: string;
507
- // };
506
+ export type ProcessPatchParams = {
507
+ id: string;
508
+ note: string | null;
509
+ };
510
+
511
+ export type MetadataStatusParams = {
512
+ id: string;
513
+ status: ProductLifecycleStatus;
514
+ };
508
515
 
509
516
  export type SubscriptionDetail = {
510
517
  subscriptionId: string;
@@ -535,7 +542,7 @@ export type SubscriptionDetail = {
535
542
 
536
543
  export type SubscriptionDetailProcess = Pick<
537
544
  Process,
538
- 'processId' | 'lastStatus' | 'startedAt' | 'createdBy' | 'workflowTarget' | 'workflowName' | 'isTask'
545
+ 'processId' | 'lastStatus' | 'startedAt' | 'createdBy' | 'workflowTarget' | 'workflowName' | 'isTask' | 'note'
539
546
  >;
540
547
 
541
548
  export type RelatedSubscription = Pick<
@@ -622,6 +629,7 @@ export enum CacheTagType {
622
629
  processStatusCounts = 'processStatusCounts',
623
630
  subscriptions = 'subscriptions',
624
631
  scheduledTasks = 'scheduledTags',
632
+ metadataProducts = 'metadataProducts',
625
633
  }
626
634
 
627
635
  export interface MappedVersion {
@@ -12,6 +12,7 @@ const getProcessDetail = (data: Partial<ProcessDetail> = {}): ProcessDetail => {
12
12
  workflowName: 'workflowName',
13
13
  isTask: false,
14
14
  traceback: null,
15
+ note: 'note',
15
16
  userPermissions: {
16
17
  retryAllowed: true,
17
18
  resumeAllowed: true,