@orchestrator-ui/orchestrator-ui-components 8.3.0 → 8.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.
- package/.turbo/turbo-build.log +8 -8
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +6 -6
- package/CHANGELOG.md +15 -0
- package/dist/index.d.ts +72 -1034
- package/dist/index.js +341 -1505
- package/dist/index.js.map +1 -1
- package/package.json +10 -14
- package/src/components/WfoAvailabilityCheck/WfoAvailabilityCheck.tsx +1 -1
- package/src/components/WfoBackendUnavailable/WfoBackendUnavailable.tsx +2 -31
- package/src/components/WfoMetadata/WfoMetadataStatusField.tsx +18 -1
- package/src/components/WfoProcessList/WfoProcessListDeltaPopover.tsx +1 -1
- package/src/components/WfoTable/WfoAdvancedTable/WfoAdvancedTable.tsx +8 -4
- package/src/components/WfoWorkflowSteps/WfoStep/WfoStep.tsx +35 -24
- package/src/components/index.ts +0 -1
- package/src/configuration/version.ts +1 -1
- package/src/hooks/useBackendAvailability.ts +1 -24
- package/src/messages/en-GB.json +2 -63
- package/src/messages/nl-NL.json +1 -0
- package/src/pages/metadata/WfoScheduleTaskFormPage.tsx +1 -424
- package/src/rtk/endpoints/availability.ts +1 -17
- package/src/rtk/endpoints/index.ts +0 -1
- package/src/utils/getDefaultTableConfig.ts +1 -1
- package/src/components/WfoAgent/ExportButton/ExportButton.tsx +0 -86
- package/src/components/WfoAgent/ExportButton/index.ts +0 -1
- package/src/components/WfoAgent/ExportButton/styles.ts +0 -69
- package/src/components/WfoAgent/WfoAgent/WfoAgent.tsx +0 -147
- package/src/components/WfoAgent/WfoAgent/index.ts +0 -1
- package/src/components/WfoAgent/WfoAgentChart/WfoAgentLineChart.tsx +0 -52
- package/src/components/WfoAgent/WfoAgentChart/WfoAgentPieChart.tsx +0 -55
- package/src/components/WfoAgent/WfoAgentChart/index.ts +0 -2
- package/src/components/WfoAgent/WfoAgentChart/styles.ts +0 -6
- package/src/components/WfoAgent/WfoAgentTable/WfoAgentTable.tsx +0 -66
- package/src/components/WfoAgent/WfoAgentTable/index.ts +0 -1
- package/src/components/WfoAgent/WfoAgentVisualization/WfoAgentVisualization.tsx +0 -54
- package/src/components/WfoAgent/WfoAgentVisualization/index.ts +0 -1
- package/src/components/WfoAgent/WfoPlanProgress/WfoPlanProgress.tsx +0 -107
- package/src/components/WfoAgent/WfoPlanProgress/index.ts +0 -1
- package/src/components/WfoAgent/WfoPlanProgress/styles.ts +0 -62
- package/src/components/WfoAgent/WfoQueryArtifact/WfoQueryArtifact.tsx +0 -40
- package/src/components/WfoAgent/WfoQueryArtifact/index.ts +0 -1
- package/src/components/WfoAgent/index.ts +0 -7
- package/src/hooks/useAgentPlanEvents.ts +0 -187
- package/src/rtk/endpoints/agentExport.ts +0 -23
- package/src/rtk/endpoints/agentQueryResults.ts +0 -19
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import React, { useCallback, useMemo } from 'react';
|
|
2
2
|
|
|
3
3
|
import _ from 'lodash';
|
|
4
|
-
import { useTranslations } from 'next-intl';
|
|
5
4
|
import { useRouter } from 'next/router';
|
|
6
5
|
import { PydanticForm } from 'pydantic-forms';
|
|
7
6
|
import type { PydanticFormApiProvider } from 'pydantic-forms';
|
|
8
|
-
import { PydanticFormApiResponseType, PydanticFormFieldFormat, PydanticFormFieldType } from 'pydantic-forms';
|
|
9
|
-
import type { PydanticFormDefinitionResponse, PydanticFormSuccessResponse, RawJsonProperties } from 'pydantic-forms';
|
|
10
7
|
|
|
11
8
|
import { PATH_METADATA_SCHEDULED_TASKS } from '@/components';
|
|
12
|
-
import { WfoContentHeader, WfoLoading } from '@/components';
|
|
13
9
|
import { Footer } from '@/components/WfoPydanticForm/Footer';
|
|
14
|
-
import { NUMBER_OF_ITEMS_REPRESENTING_ALL_ITEMS } from '@/configuration';
|
|
15
10
|
import { useShowToastMessage } from '@/hooks';
|
|
16
11
|
import { useGetPydanticFormsConfig } from '@/hooks/useGetPydanticFormsConfig';
|
|
17
12
|
import {
|
|
@@ -21,422 +16,12 @@ import {
|
|
|
21
16
|
isRecord,
|
|
22
17
|
useCreateScheduledTaskMutation,
|
|
23
18
|
} from '@/rtk';
|
|
24
|
-
import type { CronKwargs } from '@/rtk';
|
|
25
|
-
import { useGetTasksQuery } from '@/rtk';
|
|
26
19
|
import { useStartFormMutation } from '@/rtk/endpoints/forms';
|
|
27
|
-
import { useGetVersionsQuery } from '@/rtk/endpoints/versions';
|
|
28
20
|
import { ToastTypes } from '@/types';
|
|
29
|
-
import { Intervals, TaskDefinition, TaskType } from '@/types';
|
|
30
|
-
import { compareVersions } from '@/utils/compareVersions';
|
|
31
|
-
|
|
32
|
-
type CreateScheduleFormStep1 = {
|
|
33
|
-
workflowId: TaskDefinition['workflowId'];
|
|
34
|
-
taskType: TaskType;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
type CreateScheduleFormStep2Once = {
|
|
38
|
-
taskType: TaskType.DATE;
|
|
39
|
-
startDate: string;
|
|
40
|
-
};
|
|
41
|
-
type CreateScheduleFormStep2Cron = {
|
|
42
|
-
taskType: TaskType.CRON;
|
|
43
|
-
startDate: string;
|
|
44
|
-
cron: string;
|
|
45
|
-
};
|
|
46
|
-
type CreateScheduleFormStep2Interval = {
|
|
47
|
-
taskType: TaskType.INTERVAL;
|
|
48
|
-
startDate: string;
|
|
49
|
-
interval: Intervals;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
type CreateScheduleFormStep2 =
|
|
53
|
-
| CreateScheduleFormStep2Once
|
|
54
|
-
| CreateScheduleFormStep2Cron
|
|
55
|
-
| CreateScheduleFormStep2Interval;
|
|
56
|
-
|
|
57
|
-
type CreateScheduleFormInput = [CreateScheduleFormStep1, CreateScheduleFormStep2];
|
|
58
|
-
|
|
59
|
-
// TODO: remove after 5.0.0 releases and rename WfoScheduleTaskFormPageBackend to WfoScheduleTaskFormPage
|
|
60
|
-
export const WfoScheduleTaskFormPageHardCoded = () => {
|
|
61
|
-
const t = useTranslations('metadata.scheduleTaskForm');
|
|
62
|
-
const { showToastMessage } = useShowToastMessage();
|
|
63
|
-
|
|
64
|
-
const [createScheduledTask, mutationState] = useCreateScheduledTaskMutation();
|
|
65
|
-
const { data, isLoading } = useGetTasksQuery({
|
|
66
|
-
first: NUMBER_OF_ITEMS_REPRESENTING_ALL_ITEMS,
|
|
67
|
-
after: 0,
|
|
68
|
-
});
|
|
69
|
-
const router = useRouter();
|
|
70
|
-
const { workflowId } = router.query;
|
|
71
|
-
const getFormStep2 = (userInput: CreateScheduleFormInput): PydanticFormDefinitionResponse => {
|
|
72
|
-
const getStep2Defs = () => ({
|
|
73
|
-
IntervalEnum: {
|
|
74
|
-
enum: [
|
|
75
|
-
Intervals.ONE_HOUR,
|
|
76
|
-
Intervals.TWO_HOURS,
|
|
77
|
-
Intervals.FOUR_HOURS,
|
|
78
|
-
Intervals.TWELVE_HOURS,
|
|
79
|
-
Intervals.TWENTY4_HOURS,
|
|
80
|
-
Intervals.ONE_WEEK,
|
|
81
|
-
Intervals.TWO_WEEKS,
|
|
82
|
-
Intervals.ONE_MONTH,
|
|
83
|
-
],
|
|
84
|
-
options: {
|
|
85
|
-
[Intervals.ONE_HOUR]: t('1hour'),
|
|
86
|
-
[Intervals.TWO_HOURS]: t('2hours'),
|
|
87
|
-
[Intervals.FOUR_HOURS]: t('4hours'),
|
|
88
|
-
[Intervals.TWELVE_HOURS]: t('12hours'),
|
|
89
|
-
[Intervals.TWENTY4_HOURS]: t('24hours'),
|
|
90
|
-
[Intervals.ONE_WEEK]: t('1week'),
|
|
91
|
-
[Intervals.TWO_WEEKS]: t('2weeks'),
|
|
92
|
-
[Intervals.ONE_MONTH]: t('1month'),
|
|
93
|
-
},
|
|
94
|
-
title: t('selectTaskType'),
|
|
95
|
-
type: PydanticFormFieldType.STRING,
|
|
96
|
-
},
|
|
97
|
-
ButtonColor: {
|
|
98
|
-
enum: ['primary', 'accent', 'success', 'warning', 'danger', 'ghost', 'text'],
|
|
99
|
-
options: {},
|
|
100
|
-
title: 'ButtonColor',
|
|
101
|
-
type: PydanticFormFieldType.STRING,
|
|
102
|
-
},
|
|
103
|
-
ButtonConfig: {
|
|
104
|
-
additionalProperties: false,
|
|
105
|
-
properties: {
|
|
106
|
-
text: {
|
|
107
|
-
title: 'Text',
|
|
108
|
-
type: PydanticFormFieldType.STRING,
|
|
109
|
-
},
|
|
110
|
-
dialog: {
|
|
111
|
-
title: 'Dialog',
|
|
112
|
-
type: PydanticFormFieldType.STRING,
|
|
113
|
-
},
|
|
114
|
-
color: {
|
|
115
|
-
$ref: '#/$defs/ButtonColor',
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
enum: [],
|
|
119
|
-
title: 'ButtonConfig',
|
|
120
|
-
options: {},
|
|
121
|
-
type: PydanticFormFieldType.OBJECT,
|
|
122
|
-
},
|
|
123
|
-
Buttons: {
|
|
124
|
-
additionalProperties: false,
|
|
125
|
-
title: 'Buttons',
|
|
126
|
-
type: PydanticFormFieldType.OBJECT,
|
|
127
|
-
properties: {
|
|
128
|
-
previous: {
|
|
129
|
-
$ref: '#/$defs/ButtonConfig',
|
|
130
|
-
},
|
|
131
|
-
next: {
|
|
132
|
-
$ref: '#/$defs/ButtonConfig',
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
required: ['previous', 'next'],
|
|
136
|
-
enum: [],
|
|
137
|
-
options: {},
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
const getStep2Properties = (userInput: CreateScheduleFormInput): RawJsonProperties => {
|
|
142
|
-
const step1UserInput = userInput[0];
|
|
143
|
-
|
|
144
|
-
const step2Properties: RawJsonProperties = {
|
|
145
|
-
startDate: {
|
|
146
|
-
type: PydanticFormFieldType.NUMBER,
|
|
147
|
-
format: PydanticFormFieldFormat.DATETIME,
|
|
148
|
-
title: t('firstRunDate'),
|
|
149
|
-
$ref: '',
|
|
150
|
-
uniforms: {
|
|
151
|
-
showTimeSelect: true,
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
if (step1UserInput.taskType === TaskType.INTERVAL) {
|
|
157
|
-
step2Properties.interval = {
|
|
158
|
-
type: PydanticFormFieldType.STRING,
|
|
159
|
-
format: PydanticFormFieldFormat.DROPDOWN,
|
|
160
|
-
title: t('selectInterval'),
|
|
161
|
-
$ref: '#/$defs/IntervalEnum',
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
if (step1UserInput.taskType === TaskType.CRON) {
|
|
165
|
-
const cronRegex =
|
|
166
|
-
'^(?:(\\*|([0-5]?\\d))(?:\\/(\\d+))?\\s+){4}(?:(\\*|([0-5]?\\d))(?:\\/(\\d+))?\\s+)?(?:([0-9,/*\\-?LW#]+)(?:\\s+([0-9,/*\\-?LW#]+))?(?:\\s+([0-9,/*\\-?LW#]+))?)$';
|
|
167
|
-
|
|
168
|
-
step2Properties.cron = {
|
|
169
|
-
type: PydanticFormFieldType.STRING,
|
|
170
|
-
format: PydanticFormFieldFormat.DEFAULT,
|
|
171
|
-
pattern: cronRegex,
|
|
172
|
-
$ref: '',
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return step2Properties;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
const step2Properties = getStep2Properties(userInput);
|
|
180
|
-
const form2Defs = getStep2Defs();
|
|
181
|
-
const formStep2: PydanticFormDefinitionResponse = {
|
|
182
|
-
type: PydanticFormApiResponseType.FORM_DEFINITION,
|
|
183
|
-
form: {
|
|
184
|
-
type: PydanticFormFieldType.OBJECT,
|
|
185
|
-
properties: {
|
|
186
|
-
buttons: {
|
|
187
|
-
$ref: '#/$defs/Buttons',
|
|
188
|
-
default: {
|
|
189
|
-
previous: {},
|
|
190
|
-
next: { text: t('createScheduleButton') },
|
|
191
|
-
},
|
|
192
|
-
type: PydanticFormFieldType.OBJECT,
|
|
193
|
-
format: PydanticFormFieldFormat.HIDDEN,
|
|
194
|
-
},
|
|
195
|
-
...step2Properties,
|
|
196
|
-
},
|
|
197
|
-
$defs: { ...form2Defs },
|
|
198
|
-
},
|
|
199
|
-
meta: {
|
|
200
|
-
hasNext: false,
|
|
201
|
-
},
|
|
202
|
-
status: 510,
|
|
203
|
-
};
|
|
204
|
-
return formStep2;
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const onSuccess = () => {
|
|
208
|
-
router.replace(PATH_METADATA_SCHEDULED_TASKS);
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
const onCancel = () => {
|
|
212
|
-
router.replace(PATH_METADATA_SCHEDULED_TASKS);
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
const getTaskByWorkflowId = (workflowId: TaskDefinition['workflowId']) => {
|
|
216
|
-
return data?.tasks.find((task) => task.workflowId === workflowId);
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
const createTask = (userInput: CreateScheduleFormInput): PydanticFormSuccessResponse => {
|
|
220
|
-
const getIntervalArg = (interval: Intervals) => {
|
|
221
|
-
const intervalMap = new Map([
|
|
222
|
-
[Intervals.ONE_HOUR, { hours: 1 }],
|
|
223
|
-
[Intervals.TWO_HOURS, { hours: 2 }],
|
|
224
|
-
[Intervals.FOUR_HOURS, { hours: 4 }],
|
|
225
|
-
[Intervals.TWELVE_HOURS, { hours: 12 }],
|
|
226
|
-
[Intervals.TWENTY4_HOURS, { hours: 24 }],
|
|
227
|
-
[Intervals.ONE_WEEK, { weeks: 1 }],
|
|
228
|
-
[Intervals.TWO_WEEKS, { weeks: 2 }],
|
|
229
|
-
[Intervals.ONE_MONTH, { weeks: 4 }],
|
|
230
|
-
]);
|
|
231
|
-
return intervalMap.has(interval) ? intervalMap.get(interval) : undefined;
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
const getCronKwargs = (cron: string, startDate: string): CronKwargs => {
|
|
235
|
-
const [minute, hour, day, month, day_of_week] = cron.split(' ');
|
|
236
|
-
|
|
237
|
-
return {
|
|
238
|
-
start_date: startDate,
|
|
239
|
-
minute: parseInt(minute, 10),
|
|
240
|
-
hour: parseInt(hour, 10),
|
|
241
|
-
day: parseInt(day, 10),
|
|
242
|
-
month: parseInt(month, 10),
|
|
243
|
-
day_of_week: parseInt(day_of_week, 10),
|
|
244
|
-
};
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
const getCreateTaskPayload = (userInput: CreateScheduleFormInput): ScheduledTaskPostPayload => {
|
|
248
|
-
const userInputStep1 = userInput[0];
|
|
249
|
-
const userInputStep2 = userInput[1];
|
|
250
|
-
|
|
251
|
-
if (!userInputStep1 || !userInputStep2) {
|
|
252
|
-
throw new Error('Unknown or missing form input');
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
const startTimestampMilliseconds = parseInt(userInputStep2.startDate, 10);
|
|
256
|
-
const startDate = new Date(startTimestampMilliseconds * 1000).toISOString();
|
|
257
|
-
|
|
258
|
-
const task = getTaskByWorkflowId(userInputStep1.workflowId);
|
|
259
|
-
|
|
260
|
-
if (!task) {
|
|
261
|
-
throw Error('No task found with id');
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (userInputStep1.taskType === TaskType.DATE) {
|
|
265
|
-
return {
|
|
266
|
-
scheduled_type: 'create',
|
|
267
|
-
workflow_id: task.workflowId,
|
|
268
|
-
workflow_name: task.name,
|
|
269
|
-
name: task.description,
|
|
270
|
-
trigger: userInputStep1.taskType,
|
|
271
|
-
trigger_kwargs: {
|
|
272
|
-
run_date: startDate,
|
|
273
|
-
},
|
|
274
|
-
user_inputs: [],
|
|
275
|
-
};
|
|
276
|
-
} else if (userInputStep1.taskType === TaskType.INTERVAL) {
|
|
277
|
-
const step2Input = userInputStep2 as CreateScheduleFormStep2Interval;
|
|
278
|
-
const intervalArg = getIntervalArg(step2Input.interval);
|
|
279
|
-
|
|
280
|
-
if (!intervalArg) {
|
|
281
|
-
throw new Error('Unknown or missing task interval');
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
return {
|
|
285
|
-
scheduled_type: 'create',
|
|
286
|
-
workflow_id: task.workflowId,
|
|
287
|
-
workflow_name: task.name,
|
|
288
|
-
name: task.description,
|
|
289
|
-
trigger: userInputStep1.taskType,
|
|
290
|
-
trigger_kwargs: {
|
|
291
|
-
start_date: startDate,
|
|
292
|
-
...intervalArg,
|
|
293
|
-
},
|
|
294
|
-
user_inputs: [],
|
|
295
|
-
};
|
|
296
|
-
} else if (userInputStep1.taskType === TaskType.CRON) {
|
|
297
|
-
const step2Input = userInputStep2 as CreateScheduleFormStep2Cron;
|
|
298
|
-
// minute hour day month weekday
|
|
299
|
-
return {
|
|
300
|
-
scheduled_type: 'create',
|
|
301
|
-
workflow_id: task.workflowId,
|
|
302
|
-
workflow_name: task.name,
|
|
303
|
-
name: task.description,
|
|
304
|
-
trigger: userInputStep1.taskType,
|
|
305
|
-
trigger_kwargs: getCronKwargs(step2Input.cron, startDate),
|
|
306
|
-
user_inputs: [],
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
throw new Error('Unknown or missing task type');
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
const createSchedulePayload = getCreateTaskPayload(userInput);
|
|
313
|
-
createScheduledTask(createSchedulePayload);
|
|
314
|
-
|
|
315
|
-
return {
|
|
316
|
-
type: PydanticFormApiResponseType.SUCCESS,
|
|
317
|
-
data: userInput,
|
|
318
|
-
status: 201,
|
|
319
|
-
};
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
const validateForm = (formInput: unknown): boolean => {
|
|
323
|
-
if (!_.isEmpty(formInput) && _.isArray(formInput) && formInput.length === 2) {
|
|
324
|
-
return true;
|
|
325
|
-
}
|
|
326
|
-
return false;
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
const validateStep1 = (formInput: unknown): boolean => {
|
|
330
|
-
return !_.isEmpty(formInput);
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
const taskOptions =
|
|
334
|
-
data?.tasks.reduce((options, taskOption) => {
|
|
335
|
-
if (taskOption.isTask) {
|
|
336
|
-
return {
|
|
337
|
-
[taskOption.workflowId]: taskOption.description,
|
|
338
|
-
...options,
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
return options;
|
|
342
|
-
}, {}) || {};
|
|
343
|
-
|
|
344
|
-
const formStep1: PydanticFormDefinitionResponse = {
|
|
345
|
-
type: PydanticFormApiResponseType.FORM_DEFINITION,
|
|
346
|
-
form: {
|
|
347
|
-
$defs: {
|
|
348
|
-
TaskTypeChoice: {
|
|
349
|
-
enum: ['once', 'recurring'],
|
|
350
|
-
options: {
|
|
351
|
-
[TaskType.DATE]: t('taskTypeDate'),
|
|
352
|
-
[TaskType.INTERVAL]: t('taskTypeInterval'),
|
|
353
|
-
[TaskType.CRON]: t('taskTypeCron'),
|
|
354
|
-
},
|
|
355
|
-
title: t('selectTaskType'),
|
|
356
|
-
type: PydanticFormFieldType.STRING,
|
|
357
|
-
},
|
|
358
|
-
TasksEnum: {
|
|
359
|
-
enum: Object.keys(taskOptions),
|
|
360
|
-
options: taskOptions,
|
|
361
|
-
title: t('selectTask'),
|
|
362
|
-
type: PydanticFormFieldType.STRING,
|
|
363
|
-
},
|
|
364
|
-
},
|
|
365
|
-
type: PydanticFormFieldType.OBJECT,
|
|
366
|
-
properties: {
|
|
367
|
-
workflowId: {
|
|
368
|
-
type: PydanticFormFieldType.STRING,
|
|
369
|
-
format: PydanticFormFieldFormat.DROPDOWN,
|
|
370
|
-
$ref: '#/$defs/TasksEnum',
|
|
371
|
-
default: workflowId as string,
|
|
372
|
-
},
|
|
373
|
-
taskType: {
|
|
374
|
-
type: PydanticFormFieldType.STRING,
|
|
375
|
-
format: PydanticFormFieldFormat.RADIO,
|
|
376
|
-
$ref: '#/$defs/TaskTypeChoice',
|
|
377
|
-
},
|
|
378
|
-
},
|
|
379
|
-
required: ['task', 'taskOption'],
|
|
380
|
-
},
|
|
381
|
-
meta: {
|
|
382
|
-
hasNext: true,
|
|
383
|
-
},
|
|
384
|
-
status: 510,
|
|
385
|
-
};
|
|
386
|
-
|
|
387
|
-
const getApiProvider = (): PydanticFormApiProvider => {
|
|
388
|
-
return ({
|
|
389
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
390
|
-
formKey,
|
|
391
|
-
requestBody,
|
|
392
|
-
}: {
|
|
393
|
-
formKey: string;
|
|
394
|
-
requestBody: CreateScheduleFormInput;
|
|
395
|
-
}) => {
|
|
396
|
-
const userInput = requestBody;
|
|
397
|
-
return new Promise<Record<string, unknown>>((resolve) => {
|
|
398
|
-
if (validateForm(userInput)) {
|
|
399
|
-
const successResponse = createTask(userInput);
|
|
400
|
-
return resolve(successResponse);
|
|
401
|
-
} else if (validateStep1(userInput[0])) {
|
|
402
|
-
const formStep2 = getFormStep2(userInput);
|
|
403
|
-
resolve(formStep2);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
resolve(formStep1);
|
|
407
|
-
}).then((formDefinition) => {
|
|
408
|
-
return formDefinition;
|
|
409
|
-
});
|
|
410
|
-
};
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
const config = useGetPydanticFormsConfig(getApiProvider, Footer);
|
|
414
|
-
|
|
415
|
-
if (mutationState.isError) {
|
|
416
|
-
showToastMessage(ToastTypes.ERROR, '', 'Error while saving scheduled task');
|
|
417
|
-
console.error('Error saving scheduled task', mutationState);
|
|
418
|
-
return undefined;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
return (
|
|
422
|
-
<>
|
|
423
|
-
<WfoContentHeader title={t('newSchedule')} />
|
|
424
|
-
{(isLoading && <WfoLoading />) || (
|
|
425
|
-
<PydanticForm
|
|
426
|
-
formKey="add-schedule-key"
|
|
427
|
-
formId="add-schedule-id"
|
|
428
|
-
onSuccess={onSuccess}
|
|
429
|
-
onCancel={onCancel}
|
|
430
|
-
config={config}
|
|
431
|
-
/>
|
|
432
|
-
)}
|
|
433
|
-
</>
|
|
434
|
-
);
|
|
435
|
-
};
|
|
436
21
|
|
|
437
22
|
const START_SCHEDULE_PAYLOAD = {};
|
|
438
23
|
|
|
439
|
-
export const
|
|
24
|
+
export const WfoScheduleTaskFormPage = () => {
|
|
440
25
|
const { showToastMessage } = useShowToastMessage();
|
|
441
26
|
|
|
442
27
|
const generateFormId = useMemo(() => {
|
|
@@ -530,11 +115,3 @@ export const WfoScheduleTaskFormPageBackend = () => {
|
|
|
530
115
|
/>
|
|
531
116
|
);
|
|
532
117
|
};
|
|
533
|
-
|
|
534
|
-
export const WfoScheduleTaskFormPage = () => {
|
|
535
|
-
const { data } = useGetVersionsQuery();
|
|
536
|
-
const coreVersion = data?.version.applicationVersions[0].split(' ')[1] ?? '';
|
|
537
|
-
|
|
538
|
-
const isCompatible = compareVersions(coreVersion, '5.0.0a7') !== -1;
|
|
539
|
-
return isCompatible ? <WfoScheduleTaskFormPageBackend /> : <WfoScheduleTaskFormPageHardCoded />;
|
|
540
|
-
};
|
|
@@ -16,23 +16,7 @@ const availabilityApi = orchestratorApi.injectEndpoints({
|
|
|
16
16
|
baseQueryType: BaseQueryTypes.fetch,
|
|
17
17
|
},
|
|
18
18
|
}),
|
|
19
|
-
checkAgentAvailability: build.query<AvailabilityCheckResponse, void>({
|
|
20
|
-
query: () => ({
|
|
21
|
-
url: '/agent/',
|
|
22
|
-
method: 'POST',
|
|
23
|
-
headers: {
|
|
24
|
-
'Content-Type': 'application/json',
|
|
25
|
-
},
|
|
26
|
-
body: JSON.stringify({
|
|
27
|
-
messages: [],
|
|
28
|
-
}),
|
|
29
|
-
}),
|
|
30
|
-
extraOptions: {
|
|
31
|
-
baseQueryType: BaseQueryTypes.fetch,
|
|
32
|
-
apiName: 'agent',
|
|
33
|
-
},
|
|
34
|
-
}),
|
|
35
19
|
}),
|
|
36
20
|
});
|
|
37
21
|
|
|
38
|
-
export const { useCheckSearchAvailabilityQuery
|
|
22
|
+
export const { useCheckSearchAvailabilityQuery } = availabilityApi;
|
|
@@ -42,7 +42,7 @@ export const getDefaultTableConfig = <T>(storageKey: string) => {
|
|
|
42
42
|
return getTableConfig<T>(resourceTypeColumns as (keyof T)[]);
|
|
43
43
|
}
|
|
44
44
|
case METADATA_PRODUCT_TABLE_LOCAL_STORAGE_KEY: {
|
|
45
|
-
const productColumns: (keyof ProductDefinition)[] = ['productId', '
|
|
45
|
+
const productColumns: (keyof ProductDefinition)[] = ['productId', 'createdAt'];
|
|
46
46
|
return getTableConfig<T>(productColumns as (keyof T)[]);
|
|
47
47
|
}
|
|
48
48
|
case METADATA_WORKFLOWS_TABLE_LOCAL_STORAGE_KEY: {
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
import { useTranslations } from 'next-intl';
|
|
4
|
-
|
|
5
|
-
import { EuiIcon, EuiLoadingSpinner } from '@elastic/eui';
|
|
6
|
-
|
|
7
|
-
import { useShowToastMessage, useWithOrchestratorTheme } from '@/hooks';
|
|
8
|
-
import { useLazyGetAgentExportQuery } from '@/rtk/endpoints/agentExport';
|
|
9
|
-
import { ExportArtifact, GraphQLPageInfo } from '@/types';
|
|
10
|
-
import { getCsvFileNameWithDate } from '@/utils';
|
|
11
|
-
import { csvDownloadHandler } from '@/utils/csvDownload';
|
|
12
|
-
|
|
13
|
-
import { getExportButtonStyles } from './styles';
|
|
14
|
-
|
|
15
|
-
export type ExportButtonProps = {
|
|
16
|
-
artifact: ExportArtifact;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
type ExportApiResponse = {
|
|
20
|
-
page: object[];
|
|
21
|
-
pageInfo?: GraphQLPageInfo;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export function ExportButton({ artifact }: ExportButtonProps) {
|
|
25
|
-
const { showToastMessage } = useShowToastMessage();
|
|
26
|
-
const tError = useTranslations('errors');
|
|
27
|
-
const [triggerExport, { isFetching }] = useLazyGetAgentExportQuery();
|
|
28
|
-
|
|
29
|
-
const {
|
|
30
|
-
containerStyle,
|
|
31
|
-
buttonWrapperStyle,
|
|
32
|
-
titleStyle,
|
|
33
|
-
fileRowStyle,
|
|
34
|
-
fileInfoStyle,
|
|
35
|
-
filenameStyle,
|
|
36
|
-
downloadButtonStyle,
|
|
37
|
-
} = useWithOrchestratorTheme(getExportButtonStyles);
|
|
38
|
-
|
|
39
|
-
const filename = getCsvFileNameWithDate('export');
|
|
40
|
-
|
|
41
|
-
const onDownloadClick = async () => {
|
|
42
|
-
const data = await triggerExport(artifact.download_url).unwrap();
|
|
43
|
-
|
|
44
|
-
const keyOrder = data.page.length > 0 ? Object.keys(data.page[0]) : [];
|
|
45
|
-
|
|
46
|
-
const handleExport = csvDownloadHandler(
|
|
47
|
-
async () => data,
|
|
48
|
-
(data: ExportApiResponse) => data.page,
|
|
49
|
-
(data: ExportApiResponse) =>
|
|
50
|
-
data.pageInfo ?? {
|
|
51
|
-
totalItems: data.page.length,
|
|
52
|
-
startCursor: 0,
|
|
53
|
-
endCursor: data.page.length - 1,
|
|
54
|
-
hasNextPage: false,
|
|
55
|
-
hasPreviousPage: false,
|
|
56
|
-
sortFields: [],
|
|
57
|
-
filterFields: [],
|
|
58
|
-
},
|
|
59
|
-
keyOrder,
|
|
60
|
-
filename,
|
|
61
|
-
showToastMessage,
|
|
62
|
-
tError,
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
await handleExport();
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
return (
|
|
69
|
-
<div css={containerStyle}>
|
|
70
|
-
<div css={buttonWrapperStyle}>
|
|
71
|
-
{artifact.description && <div css={titleStyle}>{artifact.description}</div>}
|
|
72
|
-
<div css={fileRowStyle} onClick={onDownloadClick}>
|
|
73
|
-
<div css={fileInfoStyle}>
|
|
74
|
-
<EuiIcon type="document" size="m" />
|
|
75
|
-
<span css={filenameStyle}>{filename}</span>
|
|
76
|
-
</div>
|
|
77
|
-
<div css={downloadButtonStyle}>
|
|
78
|
-
{isFetching ?
|
|
79
|
-
<EuiLoadingSpinner size="m" />
|
|
80
|
-
: <EuiIcon type="download" size="m" />}
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
</div>
|
|
85
|
-
);
|
|
86
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './ExportButton';
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { css } from '@emotion/react';
|
|
2
|
-
|
|
3
|
-
import { WfoThemeHelpers } from '@/hooks';
|
|
4
|
-
|
|
5
|
-
export const getExportButtonStyles = ({ theme }: WfoThemeHelpers) => {
|
|
6
|
-
const containerStyle = css({
|
|
7
|
-
marginTop: theme.size.xl,
|
|
8
|
-
marginBottom: theme.size.xl,
|
|
9
|
-
width: '50%',
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
const buttonWrapperStyle = css({
|
|
13
|
-
backgroundColor: theme.colors.backgroundBaseNeutral,
|
|
14
|
-
padding: `${theme.size.xl} ${theme.size.xl}`,
|
|
15
|
-
border: `${theme.border.width.thin} solid transparent`,
|
|
16
|
-
display: 'flex',
|
|
17
|
-
flexDirection: 'column',
|
|
18
|
-
gap: theme.size.l,
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
const titleStyle = css({
|
|
22
|
-
fontSize: theme.size.m,
|
|
23
|
-
fontWeight: theme.font.weight.semiBold,
|
|
24
|
-
color: theme.colors.textParagraph,
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
const fileRowStyle = css({
|
|
28
|
-
display: 'flex',
|
|
29
|
-
alignItems: 'center',
|
|
30
|
-
justifyContent: 'space-between',
|
|
31
|
-
gap: theme.size.m,
|
|
32
|
-
border: `${theme.border.width.thin} solid ${theme.colors.borderBaseSubdued}`,
|
|
33
|
-
borderRadius: theme.border.radius.medium,
|
|
34
|
-
padding: `${theme.size.m} ${theme.size.l}`,
|
|
35
|
-
backgroundColor: theme.colors.backgroundBaseNeutral,
|
|
36
|
-
cursor: 'pointer',
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
const fileInfoStyle = css({
|
|
40
|
-
display: 'flex',
|
|
41
|
-
alignItems: 'center',
|
|
42
|
-
gap: theme.size.m,
|
|
43
|
-
flex: 1,
|
|
44
|
-
color: theme.colors.textParagraph,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const filenameStyle = css({
|
|
48
|
-
fontSize: theme.size.m,
|
|
49
|
-
fontWeight: theme.font.weight.medium,
|
|
50
|
-
color: theme.colors.textParagraph,
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
const downloadButtonStyle = css({
|
|
54
|
-
display: 'flex',
|
|
55
|
-
alignItems: 'center',
|
|
56
|
-
justifyContent: 'center',
|
|
57
|
-
color: theme.colors.textParagraph,
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
containerStyle,
|
|
62
|
-
buttonWrapperStyle,
|
|
63
|
-
titleStyle,
|
|
64
|
-
fileRowStyle,
|
|
65
|
-
fileInfoStyle,
|
|
66
|
-
filenameStyle,
|
|
67
|
-
downloadButtonStyle,
|
|
68
|
-
};
|
|
69
|
-
};
|