@orchestrator-ui/orchestrator-ui-components 5.3.4 → 5.4.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 (44) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test.log +4 -4
  4. package/CHANGELOG.md +12 -0
  5. package/dist/index.d.ts +47 -19
  6. package/dist/index.js +806 -694
  7. package/dist/index.js.map +1 -1
  8. package/package.json +2 -2
  9. package/src/components/WfoForms/UserInputForm.tsx +6 -0
  10. package/src/components/WfoForms/UserInputFormWizard.tsx +3 -0
  11. package/src/components/WfoPydanticForm/Footer.tsx +7 -1
  12. package/src/components/WfoPydanticForm/Header.tsx +3 -1
  13. package/src/components/WfoPydanticForm/RenderFormErrors.tsx +33 -0
  14. package/src/components/WfoPydanticForm/Row.tsx +1 -0
  15. package/src/components/WfoPydanticForm/WfoPydanticForm.tsx +194 -178
  16. package/src/components/WfoPydanticForm/fields/WfoArrayField/WfoArrayField.tsx +25 -4
  17. package/src/components/WfoPydanticForm/fields/{Checkbox.tsx → WfoCheckbox.tsx} +2 -1
  18. package/src/components/WfoPydanticForm/fields/{Divider.tsx → WfoDivider.tsx} +2 -1
  19. package/src/components/WfoPydanticForm/fields/{Integer.tsx → WfoInteger.tsx} +2 -1
  20. package/src/components/WfoPydanticForm/fields/{Label.tsx → WfoLabel.tsx} +2 -2
  21. package/src/components/WfoPydanticForm/fields/WfoObjectField/WfoObjectField.tsx +8 -2
  22. package/src/components/WfoPydanticForm/fields/{Radio.tsx → WfoRadio.tsx} +2 -1
  23. package/src/components/WfoPydanticForm/fields/{Summary.tsx → WfoSummary.tsx} +2 -2
  24. package/src/components/WfoPydanticForm/fields/{Text.tsx → WfoText.tsx} +3 -1
  25. package/src/components/WfoPydanticForm/fields/{TextArea.tsx → WfoTextArea.tsx} +2 -1
  26. package/src/components/WfoPydanticForm/fields/index.ts +8 -8
  27. package/src/components/WfoPydanticForm/index.ts +1 -0
  28. package/src/components/WfoStartButton/WfoStartTaskComboBox.tsx +1 -0
  29. package/src/components/WfoStartButton/WfoStartWorkflowComboBox.tsx +1 -0
  30. package/src/components/WfoWorkflowSteps/WfoStep/WfoStep.tsx +10 -4
  31. package/src/components/WfoWorkflowSteps/WfoStep/WfoStepForm.tsx +4 -1
  32. package/src/components/WfoWorkflowSteps/WfoStepList/WfoStepList.tsx +24 -30
  33. package/src/components/WfoWorkflowSteps/WfoWorkflowStepList/WfoWorkflowStepList.tsx +4 -3
  34. package/src/configuration/version.ts +1 -1
  35. package/src/messages/en-GB.json +2 -1
  36. package/src/messages/nl-NL.json +2 -1
  37. package/src/pages/processes/WfoProcessDetail.tsx +1 -0
  38. package/src/pages/processes/WfoProcessDetailPage.tsx +1 -0
  39. package/src/pages/processes/timelineUtils.spec.ts +2 -1
  40. package/src/rtk/endpoints/processDetail.ts +6 -1
  41. package/src/rtk/endpoints/startOptions.ts +10 -1
  42. package/src/types/forms.ts +5 -0
  43. package/src/types/types.ts +6 -2
  44. package/src/utils/getProductNamesFromProcess.spec.ts +6 -1
@@ -6,10 +6,11 @@ import { EuiHorizontalRule } from '@elastic/eui';
6
6
 
7
7
  import { useOrchestratorTheme } from '@/hooks';
8
8
 
9
- export const Divider: PydanticFormElement = ({ pydanticFormField }) => {
9
+ export const WfoDivider: PydanticFormElement = ({ pydanticFormField }) => {
10
10
  const { theme } = useOrchestratorTheme();
11
11
  return (
12
12
  <EuiHorizontalRule
13
+ data-testid={pydanticFormField.id}
13
14
  style={{ marginTop: theme.base }}
14
15
  id={pydanticFormField.id}
15
16
  />
@@ -22,7 +22,7 @@ const getFormFieldsBaseStyle = ({ theme }: WfoTheme) => {
22
22
  };
23
23
  };
24
24
 
25
- export const Integer: PydanticFormControlledElement = ({
25
+ export const WfoInteger: PydanticFormControlledElement = ({
26
26
  pydanticFormField,
27
27
  onChange,
28
28
  value,
@@ -34,6 +34,7 @@ export const Integer: PydanticFormControlledElement = ({
34
34
 
35
35
  return (
36
36
  <EuiFieldNumber
37
+ data-testid={pydanticFormField.id}
37
38
  css={formFieldBaseStyle}
38
39
  name={pydanticFormField.id}
39
40
  onChange={(event) => onChange(parseInt(event.target.value))}
@@ -4,11 +4,11 @@ import { PydanticFormElement } from 'pydantic-forms';
4
4
 
5
5
  import { useOrchestratorTheme } from '@/hooks';
6
6
 
7
- export const Label: PydanticFormElement = ({ pydanticFormField }) => {
7
+ export const WfoLabel: PydanticFormElement = ({ pydanticFormField }) => {
8
8
  const { theme } = useOrchestratorTheme();
9
9
 
10
10
  return (
11
- <div>
11
+ <div data-testid={pydanticFormField.id}>
12
12
  <label
13
13
  css={{
14
14
  color: theme.colors.text,
@@ -22,8 +22,14 @@ export const WfoObjectField = ({
22
22
  );
23
23
 
24
24
  return (
25
- <EuiFlexGroup css={wfoObjectFieldStyles}>
26
- <RenderFields pydanticFormComponents={components} />
25
+ <EuiFlexGroup
26
+ data-testid={pydanticFormField.id}
27
+ css={wfoObjectFieldStyles}
28
+ >
29
+ <RenderFields
30
+ pydanticFormComponents={components}
31
+ idPrefix={pydanticFormField.id}
32
+ />
27
33
  </EuiFlexGroup>
28
34
  );
29
35
  };
@@ -4,7 +4,7 @@ import type { PydanticFormControlledElement } from 'pydantic-forms';
4
4
 
5
5
  import { EuiRadioGroup } from '@elastic/eui';
6
6
 
7
- export const Radio: PydanticFormControlledElement = ({
7
+ export const WfoRadio: PydanticFormControlledElement = ({
8
8
  pydanticFormField,
9
9
  onChange,
10
10
  value,
@@ -17,6 +17,7 @@ export const Radio: PydanticFormControlledElement = ({
17
17
 
18
18
  return (
19
19
  <EuiRadioGroup
20
+ data-testid={pydanticFormField.id}
20
21
  options={radioOptions}
21
22
  idSelected={value}
22
23
  onChange={(id) => onChange(id)}
@@ -52,7 +52,7 @@ export const getStyles = ({ theme }: WfoTheme) => {
52
52
  };
53
53
  };
54
54
 
55
- export const Summary: PydanticFormElement = ({ pydanticFormField }) => {
55
+ export const WfoSummary: PydanticFormElement = ({ pydanticFormField }) => {
56
56
  const { summaryFieldStyle } = useWithOrchestratorTheme(getStyles);
57
57
  const { formRowStyle } = useWithOrchestratorTheme(getCommonFormFieldStyles);
58
58
 
@@ -103,7 +103,7 @@ export const Summary: PydanticFormElement = ({ pydanticFormField }) => {
103
103
  );
104
104
 
105
105
  return (
106
- <EuiFlexItem css={[summaryFieldStyle, formRowStyle]}>
106
+ <EuiFlexItem data-testid={id} css={[summaryFieldStyle, formRowStyle]}>
107
107
  <section>
108
108
  <EuiFormRow
109
109
  label={description}
@@ -7,10 +7,11 @@ import { EuiFieldText } from '@elastic/eui';
7
7
  import { useWithOrchestratorTheme } from '@/hooks';
8
8
  import { getFormFieldsBaseStyle } from '@/theme';
9
9
 
10
- export const Text: PydanticFormControlledElement = ({
10
+ export const WfoText: PydanticFormControlledElement = ({
11
11
  onChange,
12
12
  value,
13
13
  disabled,
14
+ pydanticFormField,
14
15
  }) => {
15
16
  const { formFieldBaseStyle } = useWithOrchestratorTheme(
16
17
  getFormFieldsBaseStyle,
@@ -18,6 +19,7 @@ export const Text: PydanticFormControlledElement = ({
18
19
 
19
20
  return (
20
21
  <EuiFieldText
22
+ data-testid={pydanticFormField.id}
21
23
  css={formFieldBaseStyle}
22
24
  disabled={disabled}
23
25
  onChange={(event) => onChange(event.target.value)}
@@ -4,7 +4,7 @@ import type { PydanticFormControlledElement } from 'pydantic-forms';
4
4
 
5
5
  import { EuiTextArea } from '@elastic/eui';
6
6
 
7
- export const TextArea: PydanticFormControlledElement = ({
7
+ export const WfoTextArea: PydanticFormControlledElement = ({
8
8
  pydanticFormField,
9
9
  onChange,
10
10
  value,
@@ -12,6 +12,7 @@ export const TextArea: PydanticFormControlledElement = ({
12
12
  }) => {
13
13
  return (
14
14
  <EuiTextArea
15
+ data-testid={pydanticFormField.id}
15
16
  disabled={disabled}
16
17
  name={pydanticFormField.id}
17
18
  onChange={(event) => onChange(event.target.value)}
@@ -1,10 +1,10 @@
1
- export * from './TextArea';
2
- export * from './Text';
3
- export * from './Label';
4
- export * from './Divider';
5
- export * from './Checkbox';
6
- export * from './Summary';
1
+ export * from './WfoTextArea';
2
+ export * from './WfoText';
3
+ export * from './WfoLabel';
4
+ export * from './WfoDivider';
5
+ export * from './WfoCheckbox';
6
+ export * from './WfoSummary';
7
7
  export * from './WfoObjectField';
8
8
  export * from './WfoArrayField';
9
- export * from './Radio';
10
- export * from './Integer';
9
+ export * from './WfoRadio';
10
+ export * from './WfoInteger';
@@ -2,3 +2,4 @@ export * from './WfoPydanticForm';
2
2
  export * from './fields';
3
3
  export * from './Row';
4
4
  export * from './Footer';
5
+ export * from './Header';
@@ -24,6 +24,7 @@ export const WfoStartTaskButtonComboBox = () => {
24
24
  workflowName: option.name,
25
25
  },
26
26
  label: option.description ?? option.name,
27
+ disabled: option.isAllowed === false,
27
28
  }))
28
29
  .sort((taskA, taskB) => taskA.label.localeCompare(taskB.label));
29
30
 
@@ -28,6 +28,7 @@ export const WfoStartWorkflowButtonComboBox = () => {
28
28
  productId: option.productId,
29
29
  },
30
30
  label: option.productName || '',
31
+ disabled: option.isAllowed === false,
31
32
  }));
32
33
 
33
34
  const handleOptionChange = async (selectedProduct: StartComboBoxOption) => {
@@ -15,6 +15,7 @@ import { useOrchestratorTheme, useWithOrchestratorTheme } from '@/hooks';
15
15
  import { WfoChevronDown, WfoChevronUp } from '@/icons';
16
16
  import type { EmailState } from '@/types';
17
17
  import { StepStatus } from '@/types';
18
+ import { FormUserPermissions } from '@/types/forms';
18
19
  import { calculateTimeDifference, formatDate } from '@/utils';
19
20
 
20
21
  import { WfoStepStatusIcon } from '../WfoStepStatusIcon';
@@ -26,11 +27,13 @@ import { WfoStepForm } from './WfoStepForm';
26
27
  export interface WfoStepProps {
27
28
  stepListItem: StepListItem;
28
29
  startedAt: string;
30
+ completedAt: string;
29
31
  showHiddenKeys: boolean;
30
32
  onToggleStepDetail: () => void;
31
33
  isTask: boolean;
32
34
  isStartStep?: boolean;
33
35
  processId?: string;
36
+ userPermissions: FormUserPermissions;
34
37
  }
35
38
 
36
39
  export const WfoStep = React.forwardRef(
@@ -39,10 +42,12 @@ export const WfoStep = React.forwardRef(
39
42
  stepListItem,
40
43
  onToggleStepDetail,
41
44
  startedAt,
45
+ completedAt,
42
46
  showHiddenKeys,
43
47
  isStartStep = false,
44
48
  isTask,
45
49
  processId,
50
+ userPermissions,
46
51
  }: WfoStepProps,
47
52
  ref: LegacyRef<HTMLDivElement>,
48
53
  ) => {
@@ -130,13 +135,13 @@ export const WfoStep = React.forwardRef(
130
135
  </EuiText>
131
136
  <EuiText>
132
137
  {step.status}{' '}
133
- {step.executed &&
134
- `- ${formatDate(step.executed)}`}
138
+ {step.completed &&
139
+ `- ${formatDate(step.completed)}`}
135
140
  </EuiText>
136
141
  </EuiFlexItem>
137
142
 
138
143
  <EuiFlexGroup css={stepRowStyle}>
139
- {step.executed && (
144
+ {step.completed && (
140
145
  <>
141
146
  {isExpanded && (
142
147
  <EuiButton
@@ -165,7 +170,7 @@ export const WfoStep = React.forwardRef(
165
170
  <EuiText size="m">
166
171
  {calculateTimeDifference(
167
172
  startedAt,
168
- step.executed,
173
+ completedAt,
169
174
  )}
170
175
  </EuiText>
171
176
  </EuiFlexItem>
@@ -209,6 +214,7 @@ export const WfoStep = React.forwardRef(
209
214
  userInputForm={userInputForm}
210
215
  isTask={isTask}
211
216
  processId={processId}
217
+ userPermissions={userPermissions}
212
218
  />
213
219
  )}
214
220
  </EuiPanel>
@@ -6,18 +6,20 @@ import { UserInputFormWizard, WfoError, WfoLoading } from '@/components';
6
6
  import { useOrchestratorTheme } from '@/hooks';
7
7
  import { HttpStatus } from '@/rtk';
8
8
  import { useResumeProcessMutation } from '@/rtk/endpoints/forms';
9
- import { InputForm } from '@/types/forms';
9
+ import { FormUserPermissions, InputForm } from '@/types/forms';
10
10
 
11
11
  interface WfoStepFormProps {
12
12
  userInputForm: InputForm;
13
13
  isTask: boolean;
14
14
  processId?: string;
15
+ userPermissions: FormUserPermissions;
15
16
  }
16
17
 
17
18
  export const WfoStepForm = ({
18
19
  userInputForm,
19
20
  isTask,
20
21
  processId,
22
+ userPermissions,
21
23
  }: WfoStepFormProps) => {
22
24
  const [isProcessing, setIsProcessing] = useState<boolean>(false);
23
25
  const [hasError, setHasError] = useState<boolean>(false);
@@ -57,6 +59,7 @@ export const WfoStepForm = ({
57
59
  hasNext={false}
58
60
  isTask={isTask}
59
61
  isResuming={true}
62
+ allowSubmit={userPermissions.resumeAllowed}
60
63
  />
61
64
  )}
62
65
  </EuiFlexItem>
@@ -3,6 +3,7 @@ import React, { Ref, useImperativeHandle, useRef } from 'react';
3
3
  import { getPageTemplateStyles } from '@/components/WfoPageTemplate/WfoPageTemplate/styles';
4
4
  import { getTimelineStyles } from '@/components/WfoTimeline/styles';
5
5
  import { useContentRef, useWithOrchestratorTheme } from '@/hooks';
6
+ import { FormUserPermissions } from '@/types/forms';
6
7
 
7
8
  import { WfoStep } from '../WfoStep';
8
9
  import { getWorkflowStepsStyles } from '../styles';
@@ -15,11 +16,11 @@ export type WfoStepListRef = {
15
16
  export type WfoStepListProps = {
16
17
  stepListItems: StepListItem[];
17
18
  showHiddenKeys: boolean;
18
- startedAt: string;
19
19
  onToggleExpandStepListItem: (stepListItem: StepListItem) => void;
20
20
  onTriggerExpandStepListItem: (stepListItem: StepListItem) => void;
21
21
  isTask: boolean;
22
22
  processId: string;
23
+ userPermissions: FormUserPermissions;
23
24
  };
24
25
 
25
26
  export const WfoStepList = React.forwardRef(
@@ -27,11 +28,11 @@ export const WfoStepList = React.forwardRef(
27
28
  {
28
29
  stepListItems,
29
30
  showHiddenKeys,
30
- startedAt,
31
31
  onToggleExpandStepListItem,
32
32
  onTriggerExpandStepListItem,
33
33
  isTask,
34
34
  processId,
35
+ userPermissions,
35
36
  }: WfoStepListProps,
36
37
  reference: Ref<WfoStepListRef>,
37
38
  ) => {
@@ -52,8 +53,6 @@ export const WfoStepList = React.forwardRef(
52
53
 
53
54
  const { contentRef } = useContentRef();
54
55
 
55
- let stepStartTime = startedAt;
56
-
57
56
  useImperativeHandle(reference, () => ({
58
57
  scrollToStep: async (stepId: string) => {
59
58
  // Applied a promise construction to wait for the browser to expand the step before scrolling
@@ -103,32 +102,27 @@ export const WfoStepList = React.forwardRef(
103
102
 
104
103
  return (
105
104
  <>
106
- {stepListItems.map((stepListItem, index) => {
107
- const stepComponent = (
108
- <div key={`step-${index}`}>
109
- {index !== 0 && <div css={stepSpacerStyle} />}
110
- <WfoStep
111
- ref={getReferenceCallbackForStepId(
112
- stepListItem.step.stepId,
113
- )}
114
- onToggleStepDetail={() =>
115
- onToggleExpandStepListItem(stepListItem)
116
- }
117
- stepListItem={stepListItem}
118
- startedAt={stepStartTime}
119
- showHiddenKeys={showHiddenKeys}
120
- isStartStep={index === 0}
121
- isTask={isTask}
122
- processId={processId}
123
- />
124
- </div>
125
- );
126
-
127
- if (index > 0) {
128
- stepStartTime = stepListItem.step.executed;
129
- }
130
- return stepComponent;
131
- })}
105
+ {stepListItems.map((stepListItem, index) => (
106
+ <div key={`step-${index}`}>
107
+ {index !== 0 && <div css={stepSpacerStyle} />}
108
+ <WfoStep
109
+ ref={getReferenceCallbackForStepId(
110
+ stepListItem.step.stepId,
111
+ )}
112
+ onToggleStepDetail={() =>
113
+ onToggleExpandStepListItem(stepListItem)
114
+ }
115
+ stepListItem={stepListItem}
116
+ startedAt={stepListItem.step.started}
117
+ completedAt={stepListItem.step.completed}
118
+ showHiddenKeys={showHiddenKeys}
119
+ isStartStep={index === 0}
120
+ isTask={isTask}
121
+ processId={processId}
122
+ userPermissions={userPermissions}
123
+ />
124
+ </div>
125
+ ))}
132
126
  </>
133
127
  );
134
128
  },
@@ -13,7 +13,7 @@ import WfoDiff from '@/components/WfoDiff/WfoDiff';
13
13
  import { WfoTraceback } from '@/components/WfoWorkflowSteps/WfoTraceback/WfoTraceback';
14
14
  import { useGetRawProcessDetailQuery } from '@/rtk/endpoints/processDetail';
15
15
  import { ProcessStatus, Step, StepStatus } from '@/types';
16
- import { InputForm } from '@/types/forms';
16
+ import { FormUserPermissions, InputForm } from '@/types/forms';
17
17
 
18
18
  export type StepListItem = {
19
19
  step: Step;
@@ -29,6 +29,7 @@ export interface WfoWorkflowStepListProps {
29
29
  processId: string;
30
30
  isTask: boolean;
31
31
  userInputForm?: InputForm;
32
+ userPermissions: FormUserPermissions;
32
33
  }
33
34
 
34
35
  export const WfoProcessRawData = ({ processId }: { processId: string }) => {
@@ -70,10 +71,10 @@ export const WfoWorkflowStepList = React.forwardRef(
70
71
  steps = [],
71
72
  lastStatus,
72
73
  traceBack,
73
- startedAt,
74
74
  processId,
75
75
  isTask,
76
76
  userInputForm,
77
+ userPermissions,
77
78
  }: WfoWorkflowStepListProps,
78
79
  reference: Ref<WfoStepListRef>,
79
80
  ) => {
@@ -206,7 +207,6 @@ export const WfoWorkflowStepList = React.forwardRef(
206
207
  <WfoStepList
207
208
  ref={reference}
208
209
  stepListItems={stepListItems}
209
- startedAt={startedAt}
210
210
  showHiddenKeys={showHiddenKeys}
211
211
  isTask={isTask}
212
212
  onToggleExpandStepListItem={
@@ -214,6 +214,7 @@ export const WfoWorkflowStepList = React.forwardRef(
214
214
  }
215
215
  processId={processId}
216
216
  onTriggerExpandStepListItem={handleExpandStepListItem}
217
+ userPermissions={userPermissions}
217
218
  />
218
219
  )}
219
220
  </>
@@ -1 +1 @@
1
- export const ORCHESTRATOR_UI_LIBRARY_VERSION = '5.3.4';
1
+ export const ORCHESTRATOR_UI_LIBRARY_VERSION = '5.4.0';
@@ -317,7 +317,8 @@
317
317
  "no_validate_workflow": "This subscription can not be validated as the product has no validate workflows.",
318
318
  "not_in_sync": "This subscription can not be modified because it is not in-sync. This means there is some error in the registration of the subscription or that it is being modified by another workflow.",
319
319
  "relations_not_in_sync": "This subscription can not be modified because some related subscriptions are not in-sync. Locked subscriptions: {locked_relations}",
320
- "no_modify_subscription_in_use_by_others": "This subscription can not be modified because it is in use by one or more other subscriptions: {unterminated_parents}"
320
+ "no_modify_subscription_in_use_by_others": "This subscription can not be modified because it is in use by one or more other subscriptions: {unterminated_parents}",
321
+ "insufficient_workflow_permissions": "Insufficient user permissions to run this workflow"
321
322
  }
322
323
  },
323
324
  "subscriptionInstanceId": "Instance ID",
@@ -314,7 +314,8 @@
314
314
  "no_validate_workflow": "Deze subscription kan niet worden gevalideerd omdat het product geen validate workflows heeft.",
315
315
  "not_in_sync": "Deze subscription kan niet worden gewijzigd omdat het niet in-sync is. Dit betekent dat er een fout zit in de registratie van de subscription of dat het wordt gewijzigd door een andere workflow.",
316
316
  "relations_not_in_sync": "Deze subscription kan niet worden gewijzigd omdat sommige gerelateerde subscriptions niet in-sync zijn. Geblokkeerde subscriptions: {locked_relations}",
317
- "no_modify_subscription_in_use_by_others": "Deze subscription kan niet worden gewijzigd omdat het in gebruik is door een of meer andere subscriptions: {unterminated_parents}"
317
+ "no_modify_subscription_in_use_by_others": "Deze subscription kan niet worden gewijzigd omdat het in gebruik is door een of meer andere subscriptions: {unterminated_parents}",
318
+ "insufficient_workflow_permissions": "Onvoldoende rechten om deze actie uit te kunnen voeren"
318
319
  }
319
320
  },
320
321
  "subscriptionInstanceId": "Instance ID",
@@ -122,6 +122,7 @@ export const WfoProcessDetail = ({
122
122
 
123
123
  const retryButtonIsDisabled =
124
124
  buttonsAreDisabled ||
125
+ processDetail?.userPermissions!.retryAllowed === false ||
125
126
  !listIncludesStatus(
126
127
  [
127
128
  ProcessStatus.FAILED,
@@ -87,6 +87,7 @@ export const WfoProcessDetailPage = ({
87
87
  userInputForm={processDetail.form}
88
88
  startedAt={processDetail.startedAt}
89
89
  isTask={isTask}
90
+ userPermissions={processDetail.userPermissions}
90
91
  />
91
92
  )) || <h1>Invalid processId</h1>}
92
93
  </WfoProcessDetail>
@@ -7,7 +7,8 @@ import {
7
7
  } from './timelineUtils';
8
8
 
9
9
  const baseStep: Step = {
10
- executed: 'testExecuted',
10
+ started: 'testStarted',
11
+ completed: 'testCompleted',
11
12
  name: 'tesName',
12
13
  state: {
13
14
  testKey: 'testValue',
@@ -26,12 +26,17 @@ export const processDetailQuery = `query ProcessDetail($processId: String!) {
26
26
  isTask
27
27
  form
28
28
  traceback
29
+ userPermissions {
30
+ retryAllowed
31
+ resumeAllowed
32
+ }
29
33
  steps {
30
34
  name
31
35
  status
32
36
  stepId
33
- executed
34
37
  stateDelta
38
+ started
39
+ completed
35
40
  }
36
41
  customer {
37
42
  fullname
@@ -12,6 +12,7 @@ const workflowOptionsQuery = `
12
12
  workflows(first: 1000000, after: 0, filterBy: [{ field: "target", value: "${WorkflowTarget.CREATE}"}]) {
13
13
  page {
14
14
  name
15
+ isAllowed
15
16
  products {
16
17
  productType
17
18
  productId
@@ -28,6 +29,7 @@ const taskOptionsQuery = `
28
29
  workflows(first: 1000000, after: 0, filterBy: [{ field: "isTask", value: "true"}]) {
29
30
  page {
30
31
  name
32
+ isAllowed
31
33
  description
32
34
  }
33
35
  }
@@ -36,6 +38,7 @@ const taskOptionsQuery = `
36
38
 
37
39
  type WorkflowOption = {
38
40
  workflowName: WorkflowDefinition['name'];
41
+ isAllowed: WorkflowDefinition['isAllowed'];
39
42
  productName: ProductDefinition['name'];
40
43
  productId: ProductDefinition['productId'];
41
44
  productType: ProductDefinition['productType'];
@@ -44,6 +47,7 @@ type WorkflowOption = {
44
47
 
45
48
  type WorkflowOptionsResult = StartOptionsResult<{
46
49
  name: WorkflowDefinition['name'];
50
+ isAllowed: WorkflowDefinition['isAllowed'];
47
51
  products: {
48
52
  name: ProductDefinition['name'];
49
53
  productId: ProductDefinition['productId'];
@@ -56,7 +60,10 @@ export type StartOptionsResponse<StartOption> = {
56
60
  startOptions: StartOption[];
57
61
  };
58
62
 
59
- type TaskOption = Pick<WorkflowDefinition, 'name' | 'description'>;
63
+ type TaskOption = Pick<
64
+ WorkflowDefinition,
65
+ 'name' | 'isAllowed' | 'description'
66
+ >;
60
67
  type TaskOptionsResult = StartOptionsResult<TaskOption>;
61
68
 
62
69
  const startButtonOptionsApi = orchestratorApi.injectEndpoints({
@@ -78,6 +85,7 @@ const startButtonOptionsApi = orchestratorApi.injectEndpoints({
78
85
  workflow.products.forEach((product) => {
79
86
  startOptions.push({
80
87
  workflowName,
88
+ isAllowed: workflow.isAllowed,
81
89
  productName: product.name,
82
90
  productId: product.productId,
83
91
  productType: product.productType,
@@ -97,6 +105,7 @@ const startButtonOptionsApi = orchestratorApi.injectEndpoints({
97
105
  return {
98
106
  startOptions: response.workflows.page.map((option) => ({
99
107
  name: option.name,
108
+ isAllowed: option.isAllowed,
100
109
  description: option.description,
101
110
  })),
102
111
  };
@@ -37,3 +37,8 @@ export type FormValidationError = {
37
37
  data: ValidationErrorData;
38
38
  status: HttpStatus;
39
39
  };
40
+
41
+ export interface FormUserPermissions {
42
+ retryAllowed: boolean;
43
+ resumeAllowed: boolean;
44
+ }
@@ -2,7 +2,7 @@ import { ReactNode } from 'react';
2
2
 
3
3
  import { Toast } from '@elastic/eui/src/components/toast/global_toast_list';
4
4
 
5
- import { InputForm } from './forms';
5
+ import { FormUserPermissions, InputForm } from './forms';
6
6
 
7
7
  export type Nullable<T> = T | null;
8
8
 
@@ -198,6 +198,7 @@ export interface ProcessDetail {
198
198
  isTask: boolean;
199
199
  steps: Step[];
200
200
  traceback: string | null;
201
+ userPermissions: FormUserPermissions;
201
202
  subscriptions: {
202
203
  page: {
203
204
  product: Pick<ProductDefinition, 'name'>;
@@ -251,9 +252,10 @@ export interface Step {
251
252
  name: string;
252
253
  status: StepStatus;
253
254
  stepId: string; // sic backend
254
- executed: string;
255
255
  state: StepState | undefined;
256
256
  stateDelta: StepState;
257
+ started: string;
258
+ completed: string;
257
259
  }
258
260
 
259
261
  export interface WorkflowDefinition {
@@ -262,6 +264,7 @@ export interface WorkflowDefinition {
262
264
  description: string;
263
265
  target: WorkflowTarget;
264
266
  isTask: boolean;
267
+ isAllowed: boolean;
265
268
  products: Pick<ProductDefinition, 'tag' | 'productId' | 'name'>[];
266
269
  createdAt: string;
267
270
  }
@@ -405,6 +408,7 @@ export type StartComboBoxOption = {
405
408
  productId?: string;
406
409
  };
407
410
  label: string;
411
+ disabled?: boolean;
408
412
  };
409
413
 
410
414
  export interface GraphQlResultPage<T> {
@@ -12,12 +12,17 @@ const getProcessDetail = (data: Partial<ProcessDetail> = {}): ProcessDetail => {
12
12
  workflowName: 'workflowName',
13
13
  isTask: false,
14
14
  traceback: null,
15
+ userPermissions: {
16
+ retryAllowed: true,
17
+ resumeAllowed: true,
18
+ },
15
19
  steps: [
16
20
  {
17
21
  name: 'step name',
18
22
  status: StepStatus.RUNNING,
19
23
  stepId: 'step id',
20
- executed: 'executed',
24
+ started: 'started',
25
+ completed: 'completed',
21
26
  state: {},
22
27
  stateDelta: {},
23
28
  },