@orchestrator-ui/orchestrator-ui-components 8.3.0 → 8.4.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 (45) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test.log +8 -8
  4. package/CHANGELOG.md +21 -0
  5. package/dist/index.d.ts +72 -1034
  6. package/dist/index.js +341 -1505
  7. package/dist/index.js.map +1 -1
  8. package/package.json +11 -15
  9. package/src/components/WfoAvailabilityCheck/WfoAvailabilityCheck.tsx +1 -1
  10. package/src/components/WfoBackendUnavailable/WfoBackendUnavailable.tsx +2 -31
  11. package/src/components/WfoMetadata/WfoMetadataStatusField.tsx +18 -1
  12. package/src/components/WfoProcessList/WfoProcessListDeltaPopover.tsx +1 -1
  13. package/src/components/WfoTable/WfoAdvancedTable/WfoAdvancedTable.tsx +8 -4
  14. package/src/components/WfoWorkflowSteps/WfoStep/WfoStep.tsx +36 -25
  15. package/src/components/index.ts +0 -1
  16. package/src/configuration/version.ts +1 -1
  17. package/src/hooks/useBackendAvailability.ts +1 -24
  18. package/src/messages/en-GB.json +2 -63
  19. package/src/messages/nl-NL.json +1 -0
  20. package/src/pages/metadata/WfoScheduleTaskFormPage.tsx +1 -424
  21. package/src/rtk/endpoints/availability.ts +1 -17
  22. package/src/rtk/endpoints/index.ts +0 -1
  23. package/src/utils/getDefaultTableConfig.ts +1 -1
  24. package/src/components/WfoAgent/ExportButton/ExportButton.tsx +0 -86
  25. package/src/components/WfoAgent/ExportButton/index.ts +0 -1
  26. package/src/components/WfoAgent/ExportButton/styles.ts +0 -69
  27. package/src/components/WfoAgent/WfoAgent/WfoAgent.tsx +0 -147
  28. package/src/components/WfoAgent/WfoAgent/index.ts +0 -1
  29. package/src/components/WfoAgent/WfoAgentChart/WfoAgentLineChart.tsx +0 -52
  30. package/src/components/WfoAgent/WfoAgentChart/WfoAgentPieChart.tsx +0 -55
  31. package/src/components/WfoAgent/WfoAgentChart/index.ts +0 -2
  32. package/src/components/WfoAgent/WfoAgentChart/styles.ts +0 -6
  33. package/src/components/WfoAgent/WfoAgentTable/WfoAgentTable.tsx +0 -66
  34. package/src/components/WfoAgent/WfoAgentTable/index.ts +0 -1
  35. package/src/components/WfoAgent/WfoAgentVisualization/WfoAgentVisualization.tsx +0 -54
  36. package/src/components/WfoAgent/WfoAgentVisualization/index.ts +0 -1
  37. package/src/components/WfoAgent/WfoPlanProgress/WfoPlanProgress.tsx +0 -107
  38. package/src/components/WfoAgent/WfoPlanProgress/index.ts +0 -1
  39. package/src/components/WfoAgent/WfoPlanProgress/styles.ts +0 -62
  40. package/src/components/WfoAgent/WfoQueryArtifact/WfoQueryArtifact.tsx +0 -40
  41. package/src/components/WfoAgent/WfoQueryArtifact/index.ts +0 -1
  42. package/src/components/WfoAgent/index.ts +0 -7
  43. package/src/hooks/useAgentPlanEvents.ts +0 -187
  44. package/src/rtk/endpoints/agentExport.ts +0 -23
  45. 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 WfoScheduleTaskFormPageBackend = () => {
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, useCheckAgentAvailabilityQuery } = availabilityApi;
22
+ export const { useCheckSearchAvailabilityQuery } = availabilityApi;
@@ -20,4 +20,3 @@ export * from './forms';
20
20
  export * from './fileUpload';
21
21
  export * from './search';
22
22
  export * from './availability';
23
- export * from './agentQueryResults';
@@ -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', 'productType', 'status', 'createdAt'];
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
- };