@orchestrator-ui/orchestrator-ui-components 0.3.0 → 0.3.1

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 (143) hide show
  1. package/.turbo/turbo-build.log +9 -8
  2. package/.turbo/turbo-lint.log +4 -1
  3. package/.turbo/turbo-test.log +13 -9
  4. package/CHANGELOG.md +11 -0
  5. package/dist/index.d.ts +484 -239
  6. package/dist/index.js +4255 -2987
  7. package/package.json +31 -26
  8. package/src/api/axios.ts +2 -8
  9. package/src/api/index.ts +4 -4
  10. package/src/components/WfoBadges/WfoBadge/WfoBadge.tsx +4 -1
  11. package/src/components/WfoBadges/index.ts +1 -0
  12. package/src/components/WfoError/WfoError.stories.tsx +26 -0
  13. package/src/components/WfoError/WfoError.tsx +19 -0
  14. package/src/components/WfoError/index.ts +1 -0
  15. package/src/components/WfoFilterTabs/WfoFilterTabs.tsx +4 -2
  16. package/src/components/WfoForms/UserInputForm.tsx +14 -2
  17. package/src/components/WfoForms/formFields/SplitPrefix.tsx +2 -1
  18. package/src/components/WfoForms/formFields/SubscriptionField.tsx +8 -3
  19. package/src/components/WfoForms/formFields/utils.spec.ts +88 -9
  20. package/src/components/WfoKeyValueTable/WfoValueCell.tsx +2 -2
  21. package/src/components/WfoOptionalLink/WfoOptionalLink.tsx +20 -0
  22. package/src/components/WfoOptionalLink/index.ts +1 -0
  23. package/src/components/WfoPageTemplate/WfoBreadcrumbs/WfoBreadcrumbs.tsx +5 -2
  24. package/src/components/WfoPageTemplate/WfoPageHeader/WfoAppLogo.tsx +28 -0
  25. package/src/components/WfoPageTemplate/WfoPageHeader/WfoPageHeader.tsx +19 -16
  26. package/src/components/WfoPageTemplate/WfoPageHeader/styles.ts +29 -0
  27. package/src/components/WfoPageTemplate/WfoPageHeader/utils/toHexColorWithOpacity.spec.ts +12 -0
  28. package/src/components/WfoPageTemplate/WfoPageHeader/utils/toHexColorWithOpacity.ts +5 -0
  29. package/src/components/WfoPageTemplate/WfoSidebar/WfoStartCreateWorkflowButtonComboBox.tsx +0 -3
  30. package/src/components/WfoProcessList/{WfoProcessList.tsx → WfoProcessesList.tsx} +32 -28
  31. package/src/components/WfoProcessList/index.ts +1 -1
  32. package/src/components/WfoProcessList/processListObjectMappers.ts +1 -1
  33. package/src/components/WfoSettings/WfoFlushSettings.tsx +16 -6
  34. package/src/components/WfoSettings/WfoModifySettings.tsx +1 -1
  35. package/src/components/WfoSettingsModal/WfoSubmitModal.tsx +61 -0
  36. package/src/components/WfoSettingsModal/index.tsx +1 -0
  37. package/src/components/WfoStartTaskButtonComboBox/WfoStartTaskButtonComboBox.tsx +0 -3
  38. package/src/components/WfoSubscription/WfoRelatedSubscriptions.tsx +4 -1
  39. package/src/components/WfoSubscription/WfoSubscription.tsx +38 -66
  40. package/src/components/WfoSubscription/WfoSubscriptionDetailTree.tsx +2 -6
  41. package/src/components/WfoSubscription/WfoSubscriptionProductBlock.tsx +2 -1
  42. package/src/components/WfoSubscription/subscriptionDetailTabs.tsx +29 -0
  43. package/src/components/WfoSubscription/utils/utils.ts +5 -5
  44. package/src/components/WfoSubscriptionsList/WfoSubscriptionsList.tsx +28 -14
  45. package/src/components/WfoSubscriptionsList/index.ts +1 -1
  46. package/src/components/WfoSubscriptionsList/{mapGrapghQlSubscriptionsResultToSubscriptionListItems.ts → mapGraphQlSubscriptionsResultToSubscriptionListItems.ts} +8 -1
  47. package/src/components/WfoSubscriptionsList/subscriptionListTabs.ts +8 -30
  48. package/src/components/WfoSummary/WfoSummaryCardHeader/WfoSummaryCardHeader.tsx +55 -0
  49. package/src/components/WfoSummary/WfoSummaryCardHeader/index.ts +1 -0
  50. package/src/components/WfoSummary/WfoSummaryCardHeader/styles.ts +26 -0
  51. package/src/components/WfoSummary/WfoSummaryCardList/WfoSummaryCardList.tsx +86 -0
  52. package/src/components/WfoSummary/WfoSummaryCardList/WfoSummaryCardListItem.tsx +59 -0
  53. package/src/components/WfoSummary/WfoSummaryCardList/index.ts +2 -0
  54. package/src/components/WfoSummary/WfoSummaryCardList/styles.ts +52 -0
  55. package/src/components/WfoSummary/WfoSummaryCards.tsx +111 -0
  56. package/src/components/WfoSummary/getNumberOfColumns.ts +14 -0
  57. package/src/components/WfoSummary/index.ts +4 -0
  58. package/src/components/WfoSummary/styles.ts +13 -0
  59. package/src/components/WfoTable/WfoBasicTable/WfoBasicTable.tsx +18 -16
  60. package/src/components/WfoTable/WfoBasicTable/WfoTableHeaderCell.tsx +2 -2
  61. package/src/components/WfoTable/WfoBasicTable/index.ts +1 -0
  62. package/src/components/WfoTable/WfoBasicTable/styles.ts +28 -2
  63. package/src/components/WfoTable/WfoFirstPartUUID/WfoFirstPartUUID.tsx +12 -3
  64. package/src/components/WfoTable/WfoFirstPartUUID/styles.ts +12 -0
  65. package/src/components/WfoTable/WfoTableWithFilter/WfoTableWithFilter.tsx +12 -4
  66. package/src/components/WfoTable/index.ts +2 -0
  67. package/src/components/WfoTable/utils/columns.ts +21 -15
  68. package/src/components/WfoTable/utils/constants.ts +4 -2
  69. package/src/components/WfoTable/utils/mapSortableAndFilterableValuesToTableColumnConfig.ts +5 -3
  70. package/src/components/WfoTree/WfoTreeNode.tsx +1 -4
  71. package/src/components/WfoWorkflowSteps/WfoStep/WfoStep.tsx +4 -3
  72. package/src/components/WfoWorkflowSteps/index.ts +1 -0
  73. package/src/components/index.ts +3 -1
  74. package/src/contexts/ApiClientContext.tsx +5 -1
  75. package/src/contexts/OrchestratorConfigContext.tsx +0 -3
  76. package/src/contexts/ToastContext.tsx +1 -1
  77. package/src/contexts/TreeContext.tsx +1 -1
  78. package/src/graphqlQueries/customersQuery.ts +2 -1
  79. package/src/graphqlQueries/processListQuery.ts +46 -6
  80. package/src/graphqlQueries/productBlocksQuery.ts +3 -1
  81. package/src/graphqlQueries/productsQuery.ts +40 -9
  82. package/src/graphqlQueries/resourceTypesQuery.ts +3 -1
  83. package/src/graphqlQueries/subscriptionDetailQuery.ts +4 -1
  84. package/src/graphqlQueries/subscriptionsDropdownOptionsQuery.ts +2 -1
  85. package/src/graphqlQueries/subscriptionsListQuery.ts +41 -4
  86. package/src/graphqlQueries/workflows/workflowsQuery.ts +3 -1
  87. package/src/graphqlQueries/workflows/workflowsQueryForDropdownList.ts +3 -6
  88. package/src/hooks/DataFetchHooks.ts +17 -63
  89. package/src/hooks/surf/useGetSubscriptionDropdownOptions.ts +1 -0
  90. package/src/hooks/surf/useIsTaggedPort.ts +1 -2
  91. package/src/hooks/useOrchestratorConfig.ts +0 -3
  92. package/src/hooks/useQueryWithGraphql.ts +25 -13
  93. package/src/hooks/useSessionWithToken.ts +3 -5
  94. package/src/hooks/useSubscriptionActions.ts +8 -2
  95. package/src/icons/WfoBell.tsx +34 -0
  96. package/src/icons/WfoContactEnvelopeFill.tsx +29 -0
  97. package/src/icons/WfoPencil.tsx +21 -0
  98. package/src/icons/WfoSideMenu.stories.tsx +13 -0
  99. package/src/icons/WfoSideMenu.tsx +39 -0
  100. package/src/icons/WfoStatistic.tsx +3 -3
  101. package/src/icons/WfoViewList.tsx +24 -0
  102. package/src/icons/index.ts +6 -0
  103. package/src/messages/en-GB.json +32 -2
  104. package/src/messages/nl-NL.json +34 -4
  105. package/src/pages/index.ts +2 -1
  106. package/src/pages/metadata/WfoProductBlocksPage.tsx +6 -10
  107. package/src/pages/metadata/WfoProductsPage.tsx +7 -10
  108. package/src/pages/metadata/WfoResourceTypesPage.tsx +5 -9
  109. package/src/pages/metadata/WfoWorkflowsPage.tsx +7 -10
  110. package/src/pages/processes/WfoProcessDetail.tsx +5 -1
  111. package/src/pages/processes/WfoProcessDetailPage.tsx +31 -15
  112. package/src/pages/processes/WfoStartProcessPage.tsx +41 -17
  113. package/src/pages/startPage/WfoStartPage.tsx +239 -0
  114. package/src/pages/startPage/index.ts +1 -0
  115. package/src/pages/subscriptions/WfoSubscriptionsListPage.tsx +22 -26
  116. package/src/pages/tasks/{WfoTaskListPage.tsx → WfoTasksListPage.tsx} +67 -44
  117. package/src/pages/tasks/getTasksListTabTypeFromString.ts +19 -0
  118. package/src/pages/tasks/index.ts +3 -1
  119. package/src/pages/tasks/tabConfig.ts +51 -0
  120. package/src/pages/{workflow/WfoWorkflowListPage.tsx → workflows/WfoWorkflowsListPage.tsx} +18 -19
  121. package/src/pages/workflows/getWorkflowsListTabTypeFromString.ts +19 -0
  122. package/src/pages/workflows/index.ts +1 -0
  123. package/src/pages/{workflow → workflows}/tabConfig.ts +9 -9
  124. package/src/theme/defaultOrchestratorTheme.ts +8 -0
  125. package/src/types/types.ts +8 -53
  126. package/src/utils/date.ts +39 -0
  127. package/src/utils/getDefaultTableConfig.ts +19 -9
  128. package/tsconfig.json +4 -4
  129. package/src/components/WfoStartPage/WfoFrequentlyUsed.stories.tsx +0 -16
  130. package/src/components/WfoStartPage/WfoFrequentlyUsed.tsx +0 -21
  131. package/src/components/WfoStartPage/WfoListItemStartPage.stories.tsx +0 -40
  132. package/src/components/WfoStartPage/WfoListItemStartPage.tsx +0 -95
  133. package/src/components/WfoStartPage/WfoListStartPage.stories.tsx +0 -98
  134. package/src/components/WfoStartPage/WfoListStartPage.tsx +0 -45
  135. package/src/components/WfoStartPage/WfoMultiListSection.stories.tsx +0 -90
  136. package/src/components/WfoStartPage/WfoMultiListSection.tsx +0 -25
  137. package/src/components/WfoStartPage/WfoNewProcessPanel.stories.tsx +0 -13
  138. package/src/components/WfoStartPage/WfoNewProcessPanel.tsx +0 -45
  139. package/src/components/WfoStartPage/WfoStatCards.stories.tsx +0 -13
  140. package/src/components/WfoStartPage/WfoStatCards.tsx +0 -75
  141. package/src/components/WfoStartPage/index.ts +0 -6
  142. package/src/pages/workflow/getWorkflowListTabTypeFromString.ts +0 -19
  143. package/src/pages/workflow/index.ts +0 -1
@@ -9,7 +9,6 @@ import {
9
9
  DEFAULT_PAGE_SIZE,
10
10
  DEFAULT_PAGE_SIZES,
11
11
  METADATA_PRODUCT_BLOCKS_TABLE_LOCAL_STORAGE_KEY,
12
- WfoLoading,
13
12
  } from '../../components';
14
13
  import {
15
14
  WfoProductBlockBadge,
@@ -179,28 +178,24 @@ export const WfoProductBlocksPage = () => {
179
178
  };
180
179
 
181
180
  const { pageSize, pageIndex, sortBy, queryString } = dataDisplayParams;
182
- const { data, isFetching } = useQueryWithGraphql(
181
+ const { data, isLoading, isError } = useQueryWithGraphql(
183
182
  GET_PRODUCTS_BLOCKS_GRAPHQL_QUERY,
184
183
  {
185
184
  first: pageSize,
186
185
  after: pageIndex * pageSize,
187
186
  sortBy: sortBy,
188
- query: queryString,
187
+ query: queryString || undefined,
189
188
  },
190
189
  'productBlocks',
191
190
  );
192
191
 
193
- if (!data) {
194
- return <WfoLoading />;
195
- }
196
-
197
192
  const dataSorting: WfoDataSorting<ProductBlockDefinition> = {
198
193
  field: sortBy?.field ?? PRODUCT_BLOCK_FIELD_NAME,
199
194
  sortOrder: sortBy?.order ?? SortOrder.ASC,
200
195
  };
201
196
 
202
197
  const { totalItems, sortFields, filterFields } =
203
- data.productBlocks.pageInfo;
198
+ data?.productBlocks?.pageInfo ?? {};
204
199
 
205
200
  const pagination: Pagination = {
206
201
  pageSize: pageSize,
@@ -212,7 +207,7 @@ export const WfoProductBlocksPage = () => {
212
207
  return (
213
208
  <WfoMetadataPageLayout>
214
209
  <WfoTableWithFilter<ProductBlockDefinition>
215
- data={data.productBlocks.page}
210
+ data={data?.productBlocks.page || []}
216
211
  tableColumns={mapSortableAndFilterableValuesToTableColumnConfig(
217
212
  tableColumns,
218
213
  sortFields,
@@ -230,7 +225,8 @@ export const WfoProductBlocksPage = () => {
230
225
  setDataDisplayParam,
231
226
  )}
232
227
  pagination={pagination}
233
- isLoading={isFetching}
228
+ isLoading={isLoading}
229
+ hasError={isError}
234
230
  queryString={queryString}
235
231
  localStorageKey={
236
232
  METADATA_PRODUCT_BLOCKS_TABLE_LOCAL_STORAGE_KEY
@@ -11,7 +11,6 @@ import {
11
11
  METADATA_PRODUCT_TABLE_LOCAL_STORAGE_KEY,
12
12
  StoredTableConfig,
13
13
  WfoDateTime,
14
- WfoLoading,
15
14
  WfoProductBlockBadge,
16
15
  WfoProductStatusBadge,
17
16
  WfoTableWithFilter,
@@ -21,7 +20,7 @@ import {
21
20
  } from '@/components';
22
21
  import { WfoFirstPartUUID } from '@/components/WfoTable/WfoFirstPartUUID';
23
22
  import { mapSortableAndFilterableValuesToTableColumnConfig } from '@/components/WfoTable/utils/mapSortableAndFilterableValuesToTableColumnConfig';
24
- import { GET_PRODUCTS_GRAPHQL_QUERY } from '@/graphqlQueries';
23
+ import { getProductsQuery } from '@/graphqlQueries';
25
24
  import {
26
25
  useDataDisplayParams,
27
26
  useQueryWithGraphql,
@@ -153,8 +152,8 @@ export const WfoProductsPage = () => {
153
152
  };
154
153
 
155
154
  const { pageSize, pageIndex, sortBy, queryString } = dataDisplayParams;
156
- const { data, isFetching } = useQueryWithGraphql(
157
- GET_PRODUCTS_GRAPHQL_QUERY,
155
+ const { data, isLoading, isError } = useQueryWithGraphql(
156
+ getProductsQuery(),
158
157
  {
159
158
  first: pageSize,
160
159
  after: pageIndex * pageSize,
@@ -164,11 +163,8 @@ export const WfoProductsPage = () => {
164
163
  'products',
165
164
  );
166
165
 
167
- if (!data) {
168
- return <WfoLoading />;
169
- }
170
-
171
- const { totalItems, sortFields, filterFields } = data.products.pageInfo;
166
+ const { totalItems, sortFields, filterFields } =
167
+ data?.products?.pageInfo ?? {};
172
168
 
173
169
  const pagination: Pagination = {
174
170
  pageSize: pageSize,
@@ -203,7 +199,8 @@ export const WfoProductsPage = () => {
203
199
  setDataDisplayParam,
204
200
  )}
205
201
  pagination={pagination}
206
- isLoading={isFetching}
202
+ isLoading={isLoading}
203
+ hasError={isError}
207
204
  queryString={queryString}
208
205
  localStorageKey={METADATA_PRODUCT_TABLE_LOCAL_STORAGE_KEY}
209
206
  />
@@ -9,7 +9,6 @@ import {
9
9
  DEFAULT_PAGE_SIZE,
10
10
  DEFAULT_PAGE_SIZES,
11
11
  METADATA_RESOURCE_TYPES_TABLE_LOCAL_STORAGE_KEY,
12
- WfoLoading,
13
12
  WfoProductBlockBadge,
14
13
  } from '../../components';
15
14
  import type { WfoDataSorting, WfoTableColumns } from '../../components';
@@ -125,28 +124,24 @@ export const WfoResourceTypesPage = () => {
125
124
  };
126
125
 
127
126
  const { pageSize, pageIndex, sortBy, queryString } = dataDisplayParams;
128
- const { data, isFetching } = useQueryWithGraphql(
127
+ const { data, isLoading, isError } = useQueryWithGraphql(
129
128
  GET_RESOURCE_TYPES_GRAPHQL_QUERY,
130
129
  {
131
130
  first: pageSize,
132
131
  after: pageIndex * pageSize,
133
132
  sortBy: sortBy,
134
- query: queryString,
133
+ query: queryString || undefined,
135
134
  },
136
135
  'resourceTypes',
137
136
  );
138
137
 
139
- if (!data) {
140
- return <WfoLoading />;
141
- }
142
-
143
138
  const dataSorting: WfoDataSorting<ResourceTypeDefinition> = {
144
139
  field: sortBy?.field ?? RESOURCE_TYPE_FIELD_TYPE,
145
140
  sortOrder: sortBy?.order ?? SortOrder.ASC,
146
141
  };
147
142
 
148
143
  const { totalItems, sortFields, filterFields } =
149
- data.resourceTypes.pageInfo;
144
+ data?.resourceTypes?.pageInfo || {};
150
145
 
151
146
  const pagination: Pagination = {
152
147
  pageSize: pageSize,
@@ -176,7 +171,8 @@ export const WfoResourceTypesPage = () => {
176
171
  setDataDisplayParam,
177
172
  )}
178
173
  pagination={pagination}
179
- isLoading={isFetching}
174
+ isLoading={isLoading}
175
+ hasError={isError}
180
176
  queryString={queryString}
181
177
  localStorageKey={
182
178
  METADATA_RESOURCE_TYPES_TABLE_LOCAL_STORAGE_KEY
@@ -9,7 +9,6 @@ import {
9
9
  DEFAULT_PAGE_SIZE,
10
10
  DEFAULT_PAGE_SIZES,
11
11
  METADATA_WORKFLOWS_TABLE_LOCAL_STORAGE_KEY,
12
- WfoLoading,
13
12
  WfoProductBlockBadge,
14
13
  } from '../../components';
15
14
  import { WfoTableWithFilter } from '../../components';
@@ -137,27 +136,24 @@ export const WfoWorkflowsPage = () => {
137
136
  };
138
137
 
139
138
  const { pageSize, pageIndex, sortBy, queryString } = dataDisplayParams;
140
- const { data, isFetching } = useQueryWithGraphql(
139
+ const { data, isLoading, isError } = useQueryWithGraphql(
141
140
  GET_WORKFLOWS_GRAPHQL_QUERY,
142
141
  {
143
142
  first: pageSize,
144
143
  after: pageIndex * pageSize,
145
144
  sortBy: graphQlWorkflowListMapper(sortBy),
146
- query: queryString,
145
+ query: queryString || undefined,
147
146
  },
148
147
  'workflows',
149
148
  );
150
149
 
151
- if (!data) {
152
- return <WfoLoading />;
153
- }
154
-
155
150
  const dataSorting: WfoDataSorting<WorkflowListItem> = {
156
151
  field: sortBy?.field ?? 'name',
157
152
  sortOrder: sortBy?.order ?? SortOrder.ASC,
158
153
  };
159
154
 
160
- const { totalItems, sortFields, filterFields } = data.workflows.pageInfo;
155
+ const { totalItems, sortFields, filterFields } =
156
+ data?.workflows?.pageInfo || {};
161
157
 
162
158
  const pagination: Pagination = {
163
159
  pageSize: pageSize,
@@ -169,7 +165,7 @@ export const WfoWorkflowsPage = () => {
169
165
  return (
170
166
  <WfoMetadataPageLayout>
171
167
  <WfoTableWithFilter<WorkflowListItem>
172
- data={mapWorkflowDefinitionToWorkflowListItem(data)}
168
+ data={data ? mapWorkflowDefinitionToWorkflowListItem(data) : []}
173
169
  tableColumns={mapSortableAndFilterableValuesToTableColumnConfig(
174
170
  tableColumns,
175
171
  sortFields,
@@ -187,7 +183,8 @@ export const WfoWorkflowsPage = () => {
187
183
  setDataDisplayParam,
188
184
  )}
189
185
  pagination={pagination}
190
- isLoading={isFetching}
186
+ isLoading={isLoading}
187
+ hasError={isError}
191
188
  queryString={queryString}
192
189
  localStorageKey={METADATA_WORKFLOWS_TABLE_LOCAL_STORAGE_KEY}
193
190
  />
@@ -80,6 +80,8 @@ interface ProcessDetailProps {
80
80
  processDetail: Partial<ProcessDetail> | undefined;
81
81
  timelineItems: TimelineItem[];
82
82
  onTimelineItemClick?: (id: string) => void;
83
+ isLoading?: boolean;
84
+ hasError?: boolean;
83
85
  }
84
86
 
85
87
  export const WfoProcessDetail = ({
@@ -90,6 +92,8 @@ export const WfoProcessDetail = ({
90
92
  buttonsAreDisabled,
91
93
  timelineItems,
92
94
  onTimelineItemClick,
95
+ isLoading = false,
96
+ hasError = false,
93
97
  }: ProcessDetailProps) => {
94
98
  const t = useTranslations('processes.detail');
95
99
  const { theme } = useOrchestratorTheme();
@@ -243,7 +247,7 @@ export const WfoProcessDetail = ({
243
247
  color="subdued"
244
248
  element="div"
245
249
  >
246
- {(processDetail === undefined && <WfoLoading />) ||
250
+ {(isLoading && !hasError && <WfoLoading />) ||
247
251
  (processDetail !== undefined && (
248
252
  <EuiFlexGroup direction="row" gutterSize="m">
249
253
  <ProcessHeaderValue
@@ -1,14 +1,14 @@
1
- import React, { useContext, useEffect, useRef, useState } from 'react';
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+
3
+ import { TimelineItem, WfoError, WfoLoading } from '@/components';
2
4
 
3
- import { TimelineItem, WfoLoading } from '../../components';
4
5
  import {
5
6
  WfoStepListRef,
6
7
  WfoWorkflowStepList,
7
8
  } from '../../components/WfoWorkflowSteps';
8
- import { OrchestratorConfigContext } from '../../contexts';
9
9
  import { GET_PROCESS_DETAIL_GRAPHQL_QUERY } from '../../graphqlQueries';
10
10
  import { useQueryWithGraphql } from '../../hooks';
11
- import { ProcessDoneStatuses, Step } from '../../types';
11
+ import { ProcessDoneStatuses, ProcessStatus, Step } from '../../types';
12
12
  import { getProductNamesFromProcess } from '../../utils';
13
13
  import { WfoProcessDetail } from './WfoProcessDetail';
14
14
  import {
@@ -20,36 +20,49 @@ export type GroupedStep = {
20
20
  steps: Step[];
21
21
  };
22
22
 
23
+ const PROCESS_DETAIL_DEFAULT_REFETCH_INTERVAL = 3000;
24
+
23
25
  interface WfoProcessDetailPageProps {
24
26
  processId: string;
27
+ processDetailRefetchInterval?: number;
25
28
  }
26
29
 
27
30
  export const WfoProcessDetailPage = ({
28
31
  processId,
32
+ processDetailRefetchInterval = PROCESS_DETAIL_DEFAULT_REFETCH_INTERVAL,
29
33
  }: WfoProcessDetailPageProps) => {
30
- const { dataRefetchInterval } = useContext(OrchestratorConfigContext);
31
34
  const stepListRef = useRef<WfoStepListRef>(null);
32
- const [fetchInterval, setFetchInterval] = useState<number | undefined>(
33
- dataRefetchInterval.processDetail,
34
- );
35
- const { data, isFetching } = useQueryWithGraphql(
35
+ const [fetchInterval, setFetchInterval] = useState<number | undefined>();
36
+ const { data, isLoading, isError } = useQueryWithGraphql(
36
37
  GET_PROCESS_DETAIL_GRAPHQL_QUERY,
37
38
  {
38
39
  processId,
39
40
  },
40
41
  'processDetail',
41
- fetchInterval,
42
+ { refetchInterval: fetchInterval, refetchOnWindowFocus: false },
42
43
  );
43
44
 
45
+ if (isError) {
46
+ if (fetchInterval) {
47
+ setFetchInterval(undefined);
48
+ }
49
+ }
50
+
44
51
  useEffect(() => {
45
- const lastStatus = data?.processes?.page[0]?.lastStatus;
52
+ const process = data?.processes.page[0];
53
+ // We need to cast here because the backend might return the string in upperCase and
54
+ // toLowerCase() will converts the value type to string
55
+ const lastStatus =
56
+ process?.lastStatus.toLocaleLowerCase() as ProcessStatus;
57
+
46
58
  const isInProgress = !(
47
59
  lastStatus && ProcessDoneStatuses.includes(lastStatus)
48
60
  );
61
+
49
62
  setFetchInterval(
50
- isInProgress ? dataRefetchInterval.processDetail : undefined,
63
+ isInProgress ? processDetailRefetchInterval : undefined,
51
64
  );
52
- }, [data, dataRefetchInterval.processDetail]);
65
+ }, [data, processDetailRefetchInterval]);
53
66
 
54
67
  const process = data?.processes.page[0];
55
68
  const steps = process?.steps ?? [];
@@ -65,14 +78,17 @@ export const WfoProcessDetailPage = ({
65
78
  <WfoProcessDetail
66
79
  pageTitle={pageTitle}
67
80
  productNames={productNames}
68
- buttonsAreDisabled={isFetching && !process}
81
+ buttonsAreDisabled={isLoading || isError}
69
82
  processDetail={process}
70
83
  timelineItems={timelineItems}
71
84
  onTimelineItemClick={(id: string) =>
72
85
  stepListRef.current?.scrollToStep(id)
73
86
  }
87
+ isLoading={isLoading}
88
+ hasError={isError}
74
89
  >
75
- {(isFetching && !process && <WfoLoading />) ||
90
+ {(isError && <WfoError />) ||
91
+ (isLoading && <WfoLoading />) ||
76
92
  (process !== undefined && (
77
93
  <WfoWorkflowStepList
78
94
  ref={stepListRef}
@@ -1,9 +1,9 @@
1
1
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
2
 
3
+ import { AxiosError } from 'axios';
3
4
  import { JSONSchema6 } from 'json-schema';
4
5
  import { useTranslations } from 'next-intl';
5
6
  import { useRouter } from 'next/router';
6
- import { ParsedUrlQuery } from 'querystring';
7
7
 
8
8
  import {
9
9
  EuiFlexGroup,
@@ -13,7 +13,7 @@ import {
13
13
  EuiText,
14
14
  } from '@elastic/eui';
15
15
 
16
- import { PATH_TASKS, TimelineItem, WfoLoading } from '@/components';
16
+ import { PATH_TASKS, TimelineItem, WfoError, WfoLoading } from '@/components';
17
17
  import { PATH_WORKFLOWS } from '@/components';
18
18
  import { useAxiosApiClient } from '@/components/WfoForms/useAxiosApiClient';
19
19
  import { WfoStepStatusIcon } from '@/components/WfoWorkflowSteps';
@@ -43,7 +43,7 @@ type StartWorkflowPayload =
43
43
  | StartCreateWorkflowPayload
44
44
  | StartModifyWorkflowPayload;
45
45
 
46
- interface StartProcessPageQuery extends ParsedUrlQuery {
46
+ interface StartProcessPageQuery {
47
47
  productId?: string;
48
48
  subscriptionId?: string;
49
49
  }
@@ -82,6 +82,7 @@ export const WfoStartProcessPage = ({
82
82
  const apiClient = useAxiosApiClient();
83
83
  const t = useTranslations('processes.steps');
84
84
  const router = useRouter();
85
+ const [hasError, setHasError] = useState<boolean>(false);
85
86
  const { theme } = useOrchestratorTheme();
86
87
  const [form, setForm] = useState<UserInputForm>({});
87
88
  const { productId, subscriptionId } = router.query as StartProcessPageQuery;
@@ -92,10 +93,11 @@ export const WfoStartProcessPage = ({
92
93
  );
93
94
 
94
95
  const { stepUserInput, hasNext } = form;
96
+
95
97
  const { getStepHeaderStyle, stepListContentBoldTextStyle } =
96
98
  getStyles(theme);
97
99
 
98
- const { data, isFetched } = useQueryWithGraphql(
100
+ const { data, isLoading, isError } = useQueryWithGraphql(
99
101
  GET_PROCESS_STEPS_GRAPHQL_QUERY,
100
102
  {
101
103
  processName,
@@ -103,8 +105,14 @@ export const WfoStartProcessPage = ({
103
105
  `processSteps={processName}`,
104
106
  );
105
107
 
108
+ if (isError) {
109
+ if (!hasError) {
110
+ setHasError(true);
111
+ }
112
+ }
113
+
106
114
  const timeLineItems: TimelineItem[] =
107
- data?.workflows?.page[0]?.steps && isFetched
115
+ data?.workflows?.page[0]?.steps && !isLoading
108
116
  ? data.workflows.page[0].steps.map(({ name }: StartProcessStep) => {
109
117
  return {
110
118
  processStepStatus: StepStatus.PENDING,
@@ -143,7 +151,20 @@ export const WfoStartProcessPage = ({
143
151
  (e) => {
144
152
  throw e;
145
153
  },
146
- );
154
+ )
155
+ .catch((error: AxiosError) => {
156
+ if (error?.response?.status !== 510) {
157
+ if (error?.response?.status === 400) {
158
+ // Rethrow the error so userInputForm can catch it and display validation errors
159
+ throw error;
160
+ }
161
+
162
+ console.error(error);
163
+ setHasError(true);
164
+ } else {
165
+ throw error;
166
+ }
167
+ });
147
168
 
148
169
  // Catch a 503: Service unavailable error indicating the engine is down. This rethrows other errors
149
170
  // if it's not 503 so we can catch the special 510 error in the catchErrorStatus call in the useEffect hook
@@ -210,17 +231,20 @@ export const WfoStartProcessPage = ({
210
231
  </EuiFlexItem>
211
232
  </EuiFlexGroup>
212
233
  <EuiHorizontalRule />
213
- {(stepUserInput && (
214
- <UserInputFormWizard
215
- stepUserInput={stepUserInput}
216
- validSubmit={submit}
217
- cancel={() =>
218
- router.push(isTask ? PATH_TASKS : PATH_WORKFLOWS)
219
- }
220
- hasNext={hasNext}
221
- isTask={isTask}
222
- />
223
- )) || <WfoLoading />}
234
+ {(hasError && <WfoError />) ||
235
+ (stepUserInput && (
236
+ <UserInputFormWizard
237
+ stepUserInput={stepUserInput}
238
+ validSubmit={submit}
239
+ cancel={() =>
240
+ router.push(
241
+ isTask ? PATH_TASKS : PATH_WORKFLOWS,
242
+ )
243
+ }
244
+ hasNext={hasNext}
245
+ isTask={isTask}
246
+ />
247
+ )) || <WfoLoading />}
224
248
  </EuiPanel>
225
249
  </WfoProcessDetail>
226
250
  );