@orchestrator-ui/orchestrator-ui-components 5.0.0 → 5.2.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.
- package/.turbo/turbo-build.log +8 -8
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +4 -4
- package/CHANGELOG.md +21 -0
- package/dist/index.d.ts +2858 -345
- package/dist/index.js +1967 -1714
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/WfoForms/formFields/SubscriptionSummaryField.tsx +1 -1
- package/src/components/WfoForms/formFields/commonStyles.ts +6 -0
- package/src/components/WfoForms/formFields/{SubscriptionField.tsx → deprecated/SubscriptionField.tsx} +53 -157
- package/src/components/WfoForms/formFields/deprecated/index.ts +1 -0
- package/src/components/WfoForms/formFields/index.ts +1 -1
- package/src/components/WfoPydanticForm/Footer.tsx +75 -34
- package/src/components/WfoPydanticForm/Header.tsx +18 -0
- package/src/components/WfoPydanticForm/Row.tsx +17 -5
- package/src/components/WfoPydanticForm/WfoPydanticForm.tsx +101 -9
- package/src/components/WfoPydanticForm/fields/Checkbox.tsx +22 -0
- package/src/components/WfoPydanticForm/fields/Divider.tsx +17 -0
- package/src/components/WfoPydanticForm/fields/Label.tsx +23 -0
- package/src/components/WfoPydanticForm/fields/Summary.tsx +125 -0
- package/src/components/WfoPydanticForm/fields/Text.tsx +28 -0
- package/src/components/WfoPydanticForm/fields/index.ts +5 -0
- package/src/configuration/constants.ts +2 -0
- package/src/configuration/version.ts +1 -1
- package/src/hooks/deprecated/useGetSurfSubcriptionDropdownOptions.ts +37 -0
- package/src/icons/WfoExclamationTriangle.tsx +29 -0
- package/src/icons/index.ts +1 -0
- package/src/pages/metadata/WfoTasksPage.tsx +11 -26
- package/src/pages/metadata/WfoWorkflowsPage.tsx +11 -12
- package/src/rtk/api.ts +3 -1
- package/src/rtk/endpoints/deprecated/index.ts +1 -0
- package/src/rtk/endpoints/deprecated/surfSubscriptionDropdownOptions.ts +53 -0
- package/src/rtk/endpoints/index.ts +2 -1
- package/src/types/deprecated/SurfSubscriptionDropdownOptionsFilterParams.ts +10 -0
- package/src/types/deprecated/index.ts +1 -0
- package/src/types/index.ts +1 -0
- package/src/types/types.ts +2 -2
- package/src/hooks/deprecated/useGetSubscriptionDropdownOptions.ts +0 -39
- package/src/rtk/endpoints/subscriptionsDropdownOptions.ts +0 -71
- /package/src/components/WfoForms/formFields/{SubscriptionFieldStyling.ts → deprecated/SubscriptionFieldStyling.ts} +0 -0
|
@@ -2,17 +2,18 @@ import React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { AbstractIntlMessages, useMessages, useTranslations } from 'next-intl';
|
|
4
4
|
import { useRouter } from 'next/router';
|
|
5
|
-
import {
|
|
6
|
-
PydanticForm,
|
|
7
|
-
PydanticFormFieldFormat,
|
|
8
|
-
PydanticFormFieldType,
|
|
9
|
-
} from 'pydantic-forms';
|
|
10
5
|
import type {
|
|
11
6
|
ComponentMatcher,
|
|
12
7
|
PydanticComponentMatcher,
|
|
13
8
|
PydanticFormApiProvider,
|
|
14
9
|
PydanticFormLabelProvider,
|
|
15
10
|
} from 'pydantic-forms';
|
|
11
|
+
import {
|
|
12
|
+
PydanticForm,
|
|
13
|
+
PydanticFormFieldFormat,
|
|
14
|
+
PydanticFormFieldType,
|
|
15
|
+
zodValidationPresets,
|
|
16
|
+
} from 'pydantic-forms';
|
|
16
17
|
|
|
17
18
|
import { FetchBaseQueryError } from '@reduxjs/toolkit/query';
|
|
18
19
|
|
|
@@ -21,10 +22,12 @@ import { StartWorkflowPayload } from '@/pages/processes/WfoStartProcessPage';
|
|
|
21
22
|
import { HttpStatus } from '@/rtk';
|
|
22
23
|
import { useStartProcessMutation } from '@/rtk/endpoints/forms';
|
|
23
24
|
import { useAppSelector } from '@/rtk/hooks';
|
|
25
|
+
import { FormValidationError } from '@/types';
|
|
24
26
|
|
|
25
27
|
import { Footer } from './Footer';
|
|
28
|
+
import { Header } from './Header';
|
|
26
29
|
import { Row } from './Row';
|
|
27
|
-
import { TextArea } from './fields
|
|
30
|
+
import { Checkbox, Divider, Label, Summary, Text, TextArea } from './fields';
|
|
28
31
|
|
|
29
32
|
interface WfoPydanticFormProps {
|
|
30
33
|
processName: string;
|
|
@@ -54,6 +57,11 @@ export const WfoPydanticForm = ({
|
|
|
54
57
|
typeof translationMessages?.pydanticForms !== 'string'
|
|
55
58
|
? translationMessages.pydanticForms.backendTranslations
|
|
56
59
|
: {};
|
|
60
|
+
const widgetsTranslations =
|
|
61
|
+
translationMessages?.pydanticForms &&
|
|
62
|
+
typeof translationMessages?.pydanticForms !== 'string'
|
|
63
|
+
? translationMessages.pydanticForms.widgets
|
|
64
|
+
: {};
|
|
57
65
|
|
|
58
66
|
const onSuccess = (_fieldValues: object, req: object) => {
|
|
59
67
|
const request = req as { response: StartProcessResponse };
|
|
@@ -88,6 +96,18 @@ export const WfoPydanticForm = ({
|
|
|
88
96
|
object | string
|
|
89
97
|
>;
|
|
90
98
|
resolve(data);
|
|
99
|
+
} else if (
|
|
100
|
+
typeof error === 'object' &&
|
|
101
|
+
error !== null
|
|
102
|
+
) {
|
|
103
|
+
const validationError =
|
|
104
|
+
error as FormValidationError;
|
|
105
|
+
if (validationError?.status === 400) {
|
|
106
|
+
resolve({
|
|
107
|
+
...validationError.data,
|
|
108
|
+
status: validationError.status.toString(),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
91
111
|
}
|
|
92
112
|
} else if (result.data) {
|
|
93
113
|
resolve(result.data);
|
|
@@ -112,11 +132,13 @@ export const WfoPydanticForm = ({
|
|
|
112
132
|
return pydanticFormProvider;
|
|
113
133
|
};
|
|
114
134
|
|
|
135
|
+
const orchestratorTranslations = formTranslations as unknown;
|
|
136
|
+
|
|
115
137
|
const pydanticLabelProvider: PydanticFormLabelProvider = async () => {
|
|
116
138
|
return new Promise((resolve) => {
|
|
117
139
|
resolve({
|
|
118
140
|
labels: {
|
|
119
|
-
...(
|
|
141
|
+
...(orchestratorTranslations as object),
|
|
120
142
|
},
|
|
121
143
|
data: {},
|
|
122
144
|
});
|
|
@@ -138,22 +160,88 @@ export const WfoPydanticForm = ({
|
|
|
138
160
|
);
|
|
139
161
|
},
|
|
140
162
|
},
|
|
141
|
-
|
|
163
|
+
{
|
|
164
|
+
id: 'summary',
|
|
165
|
+
ElementMatch: {
|
|
166
|
+
Element: Summary,
|
|
167
|
+
isControlledElement: false,
|
|
168
|
+
},
|
|
169
|
+
matcher(field) {
|
|
170
|
+
return (
|
|
171
|
+
field.type === PydanticFormFieldType.STRING &&
|
|
172
|
+
(field.format as string) === 'summary'
|
|
173
|
+
);
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
id: 'label',
|
|
178
|
+
ElementMatch: {
|
|
179
|
+
Element: Label,
|
|
180
|
+
isControlledElement: false,
|
|
181
|
+
},
|
|
182
|
+
matcher(field) {
|
|
183
|
+
return (
|
|
184
|
+
field.type === PydanticFormFieldType.STRING &&
|
|
185
|
+
field.format === PydanticFormFieldFormat.LABEL
|
|
186
|
+
);
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
id: 'divider',
|
|
191
|
+
ElementMatch: {
|
|
192
|
+
Element: Divider,
|
|
193
|
+
isControlledElement: false,
|
|
194
|
+
},
|
|
195
|
+
matcher(field) {
|
|
196
|
+
return (
|
|
197
|
+
field.type === PydanticFormFieldType.STRING &&
|
|
198
|
+
field.format === PydanticFormFieldFormat.DIVIDER
|
|
199
|
+
);
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
id: 'checkbox',
|
|
204
|
+
ElementMatch: {
|
|
205
|
+
Element: Checkbox,
|
|
206
|
+
isControlledElement: true,
|
|
207
|
+
},
|
|
208
|
+
matcher(field) {
|
|
209
|
+
return field.type === PydanticFormFieldType.BOOLEAN;
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
...currentMatchers.filter((matcher) => matcher.id !== 'text'),
|
|
213
|
+
{
|
|
214
|
+
id: 'text',
|
|
215
|
+
ElementMatch: {
|
|
216
|
+
Element: Text,
|
|
217
|
+
isControlledElement: true,
|
|
218
|
+
},
|
|
219
|
+
matcher(field) {
|
|
220
|
+
return field.type === PydanticFormFieldType.STRING;
|
|
221
|
+
},
|
|
222
|
+
validator: zodValidationPresets.string,
|
|
223
|
+
},
|
|
142
224
|
];
|
|
143
225
|
|
|
144
226
|
return componentMatcher ? componentMatcher(wfoMatchers) : wfoMatchers;
|
|
145
227
|
};
|
|
146
228
|
|
|
229
|
+
const handleCancel = () => {
|
|
230
|
+
const pfBasePath = isTask ? PATH_TASKS : PATH_WORKFLOWS;
|
|
231
|
+
router.replace(pfBasePath);
|
|
232
|
+
};
|
|
233
|
+
|
|
147
234
|
return (
|
|
148
235
|
<PydanticForm
|
|
149
|
-
title={''}
|
|
150
236
|
id={processName}
|
|
151
237
|
onSuccess={onSuccess}
|
|
238
|
+
onCancel={handleCancel}
|
|
152
239
|
loadingComponent={<WfoLoading />}
|
|
153
240
|
config={{
|
|
154
241
|
apiProvider: getPydanticFormProvider(),
|
|
155
242
|
allowUntouchedSubmit: true,
|
|
156
243
|
footerRenderer: Footer,
|
|
244
|
+
headerRenderer: Header,
|
|
157
245
|
skipSuccessNotice: true,
|
|
158
246
|
componentMatcher: wfoComponentMatcher,
|
|
159
247
|
labelProvider: pydanticLabelProvider,
|
|
@@ -161,6 +249,10 @@ export const WfoPydanticForm = ({
|
|
|
161
249
|
customTranslations: {
|
|
162
250
|
cancel: t('cancel'),
|
|
163
251
|
startWorkflow: t('startWorkflow'),
|
|
252
|
+
widgets: {
|
|
253
|
+
...(widgetsTranslations as object),
|
|
254
|
+
},
|
|
255
|
+
...translationMessages,
|
|
164
256
|
},
|
|
165
257
|
}}
|
|
166
258
|
/>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { PydanticFormControlledElement } from 'pydantic-forms';
|
|
4
|
+
|
|
5
|
+
import { EuiCheckbox } from '@elastic/eui';
|
|
6
|
+
|
|
7
|
+
export const Checkbox: PydanticFormControlledElement = ({
|
|
8
|
+
pydanticFormField,
|
|
9
|
+
onChange,
|
|
10
|
+
value,
|
|
11
|
+
disabled,
|
|
12
|
+
}) => {
|
|
13
|
+
return (
|
|
14
|
+
<EuiCheckbox
|
|
15
|
+
checked={value || false}
|
|
16
|
+
disabled={disabled}
|
|
17
|
+
id={pydanticFormField.id}
|
|
18
|
+
label={pydanticFormField.title || <div> </div>}
|
|
19
|
+
onChange={() => !disabled && onChange(!value)}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { PydanticFormElement } from 'pydantic-forms';
|
|
4
|
+
|
|
5
|
+
import { EuiHorizontalRule } from '@elastic/eui';
|
|
6
|
+
|
|
7
|
+
import { useOrchestratorTheme } from '@/hooks';
|
|
8
|
+
|
|
9
|
+
export const Divider: PydanticFormElement = ({ pydanticFormField }) => {
|
|
10
|
+
const { theme } = useOrchestratorTheme();
|
|
11
|
+
return (
|
|
12
|
+
<EuiHorizontalRule
|
|
13
|
+
style={{ marginTop: theme.base }}
|
|
14
|
+
id={pydanticFormField.id}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { PydanticFormElement } from 'pydantic-forms';
|
|
4
|
+
|
|
5
|
+
import { useOrchestratorTheme } from '@/hooks';
|
|
6
|
+
|
|
7
|
+
export const Label: PydanticFormElement = ({ pydanticFormField }) => {
|
|
8
|
+
const { theme } = useOrchestratorTheme();
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<div>
|
|
12
|
+
<label
|
|
13
|
+
css={{
|
|
14
|
+
color: theme.colors.text,
|
|
15
|
+
display: 'block',
|
|
16
|
+
}}
|
|
17
|
+
id={pydanticFormField.id}
|
|
18
|
+
>
|
|
19
|
+
{pydanticFormField.title}
|
|
20
|
+
</label>
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { PydanticFormElement } from 'pydantic-forms';
|
|
4
|
+
|
|
5
|
+
import { EuiFlexItem, EuiFormRow, EuiText } from '@elastic/eui';
|
|
6
|
+
import { tint } from '@elastic/eui';
|
|
7
|
+
import { css } from '@emotion/react';
|
|
8
|
+
import type { WfoTheme } from '@orchestrator-ui/orchestrator-ui-components';
|
|
9
|
+
|
|
10
|
+
import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles';
|
|
11
|
+
import { useWithOrchestratorTheme } from '@/hooks';
|
|
12
|
+
|
|
13
|
+
export const getStyles = ({ theme }: WfoTheme) => {
|
|
14
|
+
const toShadeColor = (color: string) => tint(color, 0.9);
|
|
15
|
+
|
|
16
|
+
const summaryFieldStyle = css({
|
|
17
|
+
'div.emailMessage': {
|
|
18
|
+
td: {
|
|
19
|
+
color: theme.colors.text,
|
|
20
|
+
},
|
|
21
|
+
p: {
|
|
22
|
+
color: theme.colors.text,
|
|
23
|
+
},
|
|
24
|
+
html: {
|
|
25
|
+
marginLeft: '-10px',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
'section.table-summary': {
|
|
29
|
+
marginTop: '20px',
|
|
30
|
+
width: '100%',
|
|
31
|
+
td: {
|
|
32
|
+
padding: '10px',
|
|
33
|
+
verticalAlign: 'top',
|
|
34
|
+
},
|
|
35
|
+
'td:not(:first-child):not(:last-child)': {
|
|
36
|
+
borderRight: `1px solid ${theme.colors.lightestShade}`,
|
|
37
|
+
},
|
|
38
|
+
'.label': {
|
|
39
|
+
fontWeight: 'bold',
|
|
40
|
+
color: theme.colors.lightestShade,
|
|
41
|
+
backgroundColor: theme.colors.primary,
|
|
42
|
+
borderRight: `2px solid ${theme.colors.lightestShade}`,
|
|
43
|
+
borderBottom: `1px solid ${theme.colors.lightestShade}`,
|
|
44
|
+
},
|
|
45
|
+
'.value': {
|
|
46
|
+
backgroundColor: toShadeColor(theme.colors.primary),
|
|
47
|
+
borderBottom: `1px solid ${theme.colors.lightestShade}`,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
return {
|
|
52
|
+
summaryFieldStyle: summaryFieldStyle,
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const Summary: PydanticFormElement = ({ pydanticFormField }) => {
|
|
57
|
+
const { summaryFieldStyle } = useWithOrchestratorTheme(getStyles);
|
|
58
|
+
const { formRowStyle } = useWithOrchestratorTheme(getCommonFormFieldStyles);
|
|
59
|
+
|
|
60
|
+
const { id, title, description } = pydanticFormField;
|
|
61
|
+
const uniforms = pydanticFormField.schema.uniforms;
|
|
62
|
+
const summaryData = uniforms?.data as unknown as {
|
|
63
|
+
headers: string[][];
|
|
64
|
+
labels: string[];
|
|
65
|
+
columns: string[][];
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const headers = summaryData?.headers as string[][];
|
|
69
|
+
const labels = summaryData?.labels as string[];
|
|
70
|
+
const columns = summaryData?.columns || [];
|
|
71
|
+
|
|
72
|
+
const extraColumnsData = columns.filter((_, index) => index !== 0);
|
|
73
|
+
|
|
74
|
+
const rows = columns[0].map((row, index) => (
|
|
75
|
+
<tr key={index}>
|
|
76
|
+
{labels && <td className={`label`}>{labels[index]}</td>}
|
|
77
|
+
<td className={`value`}>
|
|
78
|
+
{typeof row === 'string' && row.includes('<!doctype html>') ? (
|
|
79
|
+
<div
|
|
80
|
+
className="emailMessage"
|
|
81
|
+
dangerouslySetInnerHTML={{ __html: row }}
|
|
82
|
+
></div>
|
|
83
|
+
) : (
|
|
84
|
+
row
|
|
85
|
+
)}
|
|
86
|
+
</td>
|
|
87
|
+
{extraColumnsData &&
|
|
88
|
+
extraColumnsData.map((_, idx) => (
|
|
89
|
+
<td className={`value`} key={idx}>
|
|
90
|
+
{extraColumnsData[idx][index]}
|
|
91
|
+
</td>
|
|
92
|
+
))}
|
|
93
|
+
</tr>
|
|
94
|
+
));
|
|
95
|
+
|
|
96
|
+
const tableHeader =
|
|
97
|
+
!headers || headers.length === 0 ? null : (
|
|
98
|
+
<tr>
|
|
99
|
+
{labels && <th />}
|
|
100
|
+
{headers.map((header, idx) => (
|
|
101
|
+
<th key={idx}>{header}</th>
|
|
102
|
+
))}
|
|
103
|
+
</tr>
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<EuiFlexItem css={[summaryFieldStyle, formRowStyle]}>
|
|
108
|
+
<section>
|
|
109
|
+
<EuiFormRow
|
|
110
|
+
label={description}
|
|
111
|
+
labelAppend={<EuiText size="m">{title}</EuiText>}
|
|
112
|
+
id={id}
|
|
113
|
+
fullWidth
|
|
114
|
+
>
|
|
115
|
+
<section className="table-summary">
|
|
116
|
+
<table id={`${id}-table`}>
|
|
117
|
+
<thead>{tableHeader}</thead>
|
|
118
|
+
<tbody>{rows}</tbody>
|
|
119
|
+
</table>
|
|
120
|
+
</section>
|
|
121
|
+
</EuiFormRow>
|
|
122
|
+
</section>
|
|
123
|
+
</EuiFlexItem>
|
|
124
|
+
);
|
|
125
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { PydanticFormControlledElement } from 'pydantic-forms';
|
|
4
|
+
|
|
5
|
+
import { EuiFieldText } from '@elastic/eui';
|
|
6
|
+
|
|
7
|
+
import { useWithOrchestratorTheme } from '@/hooks';
|
|
8
|
+
import { getFormFieldsBaseStyle } from '@/theme';
|
|
9
|
+
|
|
10
|
+
export const Text: PydanticFormControlledElement = ({
|
|
11
|
+
onChange,
|
|
12
|
+
value,
|
|
13
|
+
disabled,
|
|
14
|
+
}) => {
|
|
15
|
+
const { formFieldBaseStyle } = useWithOrchestratorTheme(
|
|
16
|
+
getFormFieldsBaseStyle,
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<EuiFieldText
|
|
21
|
+
css={formFieldBaseStyle}
|
|
22
|
+
disabled={disabled}
|
|
23
|
+
onChange={(event) => onChange(event.target.value)}
|
|
24
|
+
value={value ?? ''}
|
|
25
|
+
fullWidth
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
@@ -25,6 +25,8 @@ export const IPAM_FREE_SUBNETS_ENDPOINT = `${IPAM_ENDPOINT}/free_subnets`;
|
|
|
25
25
|
|
|
26
26
|
//subscriptions
|
|
27
27
|
export const SUBSCRIPTION_ACTIONS_ENDPOINT = 'subscriptions/workflows';
|
|
28
|
+
export const SUBSCRIPTION_DROPDOWN_OPTIONS_ENDPOINT =
|
|
29
|
+
'surf/subscriptions/dropdown-options';
|
|
28
30
|
export const CUSTOMER_DESCRIPTION_ENDPOINT =
|
|
29
31
|
'/subscription_customer_descriptions';
|
|
30
32
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const ORCHESTRATOR_UI_LIBRARY_VERSION = '5.
|
|
1
|
+
export const ORCHESTRATOR_UI_LIBRARY_VERSION = '5.2.0';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useGetSurfSubscriptionDropdownOptionsQuery } from '@/rtk/endpoints/deprecated/surfSubscriptionDropdownOptions';
|
|
2
|
+
import { SurfSubscriptionDropdownOptionsFilterParams } from '@/types';
|
|
3
|
+
|
|
4
|
+
export const useGetSurfSubscriptionDropdownOptions = (
|
|
5
|
+
tags: string[] = [],
|
|
6
|
+
statuses: string[] = ['active'],
|
|
7
|
+
productIds: string[] = [],
|
|
8
|
+
excludeSubscriptionIds: string[] = [],
|
|
9
|
+
customerId?: string,
|
|
10
|
+
portModes: string[] = [],
|
|
11
|
+
bandwidth?: number,
|
|
12
|
+
) => {
|
|
13
|
+
const filter_params: SurfSubscriptionDropdownOptionsFilterParams = {
|
|
14
|
+
product_tags: tags,
|
|
15
|
+
statuses,
|
|
16
|
+
product_ids: productIds,
|
|
17
|
+
exclude_subscription_ids: excludeSubscriptionIds,
|
|
18
|
+
port_modes: portModes,
|
|
19
|
+
bandwidth,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
if (customerId) {
|
|
23
|
+
filter_params.customer_ids = [customerId];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const { data, isFetching, refetch, isError } =
|
|
27
|
+
useGetSurfSubscriptionDropdownOptionsQuery({ params: filter_params });
|
|
28
|
+
|
|
29
|
+
const options = (() => {
|
|
30
|
+
if (!isFetching && !isError && data) {
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
33
|
+
return [];
|
|
34
|
+
})();
|
|
35
|
+
|
|
36
|
+
return { isFetching, refetch, options };
|
|
37
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
|
+
|
|
3
|
+
import { WfoIconProps } from './WfoIconProps';
|
|
4
|
+
|
|
5
|
+
export const WfoExclamationTriangle: FC<WfoIconProps> = ({
|
|
6
|
+
width = 24,
|
|
7
|
+
height = 24,
|
|
8
|
+
color = '#000000',
|
|
9
|
+
}) => (
|
|
10
|
+
<svg
|
|
11
|
+
width={width}
|
|
12
|
+
height={height}
|
|
13
|
+
viewBox="0 0 24 24"
|
|
14
|
+
version="1.1"
|
|
15
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
16
|
+
color={color}
|
|
17
|
+
>
|
|
18
|
+
<title>icon/exclamation-circle</title>
|
|
19
|
+
<g id="Symbols" strokeWidth="1.5" fill="currentColor">
|
|
20
|
+
<g id="icon/exclamation-triangle" fill="currentColor">
|
|
21
|
+
<path
|
|
22
|
+
fillRule="evenodd"
|
|
23
|
+
d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495ZM10 5a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 10 5Zm0 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"
|
|
24
|
+
clipRule="evenodd"
|
|
25
|
+
/>
|
|
26
|
+
</g>
|
|
27
|
+
</g>
|
|
28
|
+
</svg>
|
|
29
|
+
);
|
package/src/icons/index.ts
CHANGED
|
@@ -128,33 +128,18 @@ export const WfoTasksPage = () => {
|
|
|
128
128
|
columnType: ColumnType.DATA,
|
|
129
129
|
label: t('description'),
|
|
130
130
|
width: '700px',
|
|
131
|
-
renderData: (value, row) =>
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
) : null,
|
|
131
|
+
renderData: (value, row) => (
|
|
132
|
+
<WfoMetadataDescriptionField
|
|
133
|
+
onSave={(updatedNote) =>
|
|
134
|
+
updateWorkflow({
|
|
135
|
+
id: row.workflowId,
|
|
136
|
+
description: updatedNote,
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
description={value}
|
|
140
|
+
/>
|
|
141
|
+
),
|
|
143
142
|
},
|
|
144
|
-
|
|
145
|
-
// description: {
|
|
146
|
-
// columnType: ColumnType.DATA,
|
|
147
|
-
// label: t('description'),
|
|
148
|
-
// width: '450px',
|
|
149
|
-
// renderData: (value, row) =>
|
|
150
|
-
// value ? (
|
|
151
|
-
// <WfoWorkflowDescriptionField
|
|
152
|
-
// workflow_id={row.workflowId}
|
|
153
|
-
// description={value}
|
|
154
|
-
// />
|
|
155
|
-
// ) : null,
|
|
156
|
-
// },
|
|
157
|
-
|
|
158
143
|
target: {
|
|
159
144
|
columnType: ColumnType.DATA,
|
|
160
145
|
label: t('target'),
|
|
@@ -131,18 +131,17 @@ export const WfoWorkflowsPage = () => {
|
|
|
131
131
|
columnType: ColumnType.DATA,
|
|
132
132
|
label: t('description'),
|
|
133
133
|
width: '700px',
|
|
134
|
-
renderData: (value, row) =>
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
) : null,
|
|
134
|
+
renderData: (value, row) => (
|
|
135
|
+
<WfoMetadataDescriptionField
|
|
136
|
+
onSave={(updatedNote) =>
|
|
137
|
+
updateWorkflow({
|
|
138
|
+
id: row.workflowId,
|
|
139
|
+
description: updatedNote,
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
description={value}
|
|
143
|
+
/>
|
|
144
|
+
),
|
|
146
145
|
},
|
|
147
146
|
target: {
|
|
148
147
|
columnType: ColumnType.DATA,
|
package/src/rtk/api.ts
CHANGED
|
@@ -61,6 +61,7 @@ export type UseQuery<T, U> = (
|
|
|
61
61
|
type ExtraOptions = {
|
|
62
62
|
baseQueryType?: BaseQueryTypes;
|
|
63
63
|
apiName?: string;
|
|
64
|
+
paramsSerializer?: (params: Record<string, unknown>) => string;
|
|
64
65
|
};
|
|
65
66
|
|
|
66
67
|
export type WfoGraphqlError = {
|
|
@@ -131,7 +132,7 @@ export const catchErrorResponse = async (
|
|
|
131
132
|
export const orchestratorApi = createApi({
|
|
132
133
|
reducerPath: 'orchestratorApi',
|
|
133
134
|
baseQuery: (args, api, extraOptions: ExtraOptions) => {
|
|
134
|
-
const { baseQueryType, apiName } = extraOptions || {};
|
|
135
|
+
const { baseQueryType, apiName, paramsSerializer } = extraOptions || {};
|
|
135
136
|
|
|
136
137
|
const state = api.getState() as RootState;
|
|
137
138
|
const { orchestratorApiBaseUrl, graphqlEndpointCore, authActive } =
|
|
@@ -148,6 +149,7 @@ export const orchestratorApi = createApi({
|
|
|
148
149
|
? customApi.apiBaseUrl
|
|
149
150
|
: orchestratorApiBaseUrl,
|
|
150
151
|
prepareHeaders,
|
|
152
|
+
paramsSerializer,
|
|
151
153
|
responseHandler: (response) =>
|
|
152
154
|
catchErrorResponse(response, authActive),
|
|
153
155
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './surfSubscriptionDropdownOptions';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Option } from '@/components/WfoForms/formFields/types';
|
|
2
|
+
import { SUBSCRIPTION_DROPDOWN_OPTIONS_ENDPOINT } from '@/configuration';
|
|
3
|
+
import { BaseQueryTypes, orchestratorApi } from '@/rtk';
|
|
4
|
+
import { SurfSubscriptionDropdownOptionsFilterParams } from '@/types';
|
|
5
|
+
|
|
6
|
+
// Custom endpoint used by the deprecated SubscriptionField formfield.
|
|
7
|
+
// Has to be present in the library for now.
|
|
8
|
+
// In the future, pydantic-forms will make it possible to add/override custom endpoints in the app implementation.
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Serialize URL parameters object to a string.
|
|
12
|
+
*
|
|
13
|
+
* @param params Object with url parameters, values can be scalar or array, i.e. {a: [1, 2], b: [3], c: 4}
|
|
14
|
+
* @returns the url parameter string, i.e. ?a=1&a=2&b=3&c=4
|
|
15
|
+
*/
|
|
16
|
+
export function toUrlParams(params: Record<string, unknown>): string {
|
|
17
|
+
const urlParams = new URLSearchParams();
|
|
18
|
+
|
|
19
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
20
|
+
if (Array.isArray(value)) {
|
|
21
|
+
value.forEach((v) => {
|
|
22
|
+
urlParams.append(key, String(v));
|
|
23
|
+
});
|
|
24
|
+
} else if (value !== undefined) {
|
|
25
|
+
urlParams.append(key, String(value));
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return urlParams.toString();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const surfSubscriptionDropdownOptionsApi = orchestratorApi.injectEndpoints({
|
|
33
|
+
endpoints: (build) => ({
|
|
34
|
+
getSurfSubscriptionDropdownOptions: build.query<
|
|
35
|
+
Option<string>[],
|
|
36
|
+
{ params: SurfSubscriptionDropdownOptionsFilterParams }
|
|
37
|
+
>({
|
|
38
|
+
query: ({ params }) => ({
|
|
39
|
+
url: SUBSCRIPTION_DROPDOWN_OPTIONS_ENDPOINT,
|
|
40
|
+
params: params,
|
|
41
|
+
}),
|
|
42
|
+
extraOptions: {
|
|
43
|
+
baseQueryType: BaseQueryTypes.fetch,
|
|
44
|
+
paramsSerializer: toUrlParams,
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const {
|
|
51
|
+
useGetSurfSubscriptionDropdownOptionsQuery,
|
|
52
|
+
useLazyGetSurfSubscriptionDropdownOptionsQuery,
|
|
53
|
+
} = surfSubscriptionDropdownOptionsApi;
|
|
@@ -16,5 +16,6 @@ export * from './subscriptionDetail';
|
|
|
16
16
|
export * from './subscriptionInUseByRelationsList';
|
|
17
17
|
export * from './subscriptionList';
|
|
18
18
|
export * from './subscriptionListSummary';
|
|
19
|
-
export * from './subscriptionsDropdownOptions';
|
|
20
19
|
export * from './forms';
|
|
20
|
+
export * from './deprecated';
|
|
21
|
+
export * from './formFields';
|