@openmrs/esm-form-builder-app 3.4.2-pre.3421 → 3.4.2-pre.3423
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/dist/1379.js +1 -1
- package/dist/1379.js.map +1 -1
- package/dist/1637.js +1 -1
- package/dist/1719.js +1 -1
- package/dist/2324.js +1 -1
- package/dist/2324.js.map +1 -1
- package/dist/3074.js +1 -1
- package/dist/3896.js +1 -1
- package/dist/4192.js +1 -1
- package/dist/4300.js +1 -1
- package/dist/5328.js +1 -1
- package/dist/7140.js +1 -1
- package/dist/7146.js +1 -1
- package/dist/7252.js +1 -1
- package/dist/7252.js.map +1 -1
- package/dist/8091.js +1 -1
- package/dist/8295.js +1 -1
- package/dist/8776.js +1 -1
- package/dist/{9441.js → 8935.js} +2 -2
- package/dist/8935.js.map +1 -0
- package/dist/9544.js +1 -1
- package/dist/9672.js +1 -1
- package/dist/9852.js +1 -1
- package/dist/main.js +1 -1
- package/dist/openmrs-esm-form-builder-app.js +1 -1
- package/dist/openmrs-esm-form-builder-app.js.buildmanifest.json +47 -47
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/components/action-buttons/action-buttons.component.tsx +1 -1
- package/src/components/audit-details/audit-details.component.tsx +41 -7
- package/src/components/dashboard/dashboard.component.tsx +60 -27
- package/src/components/dashboard/dashboard.scss +6 -0
- package/src/components/form-editor/form-editor.component.tsx +39 -8
- package/src/components/form-editor/form-editor.scss +15 -1
- package/src/components/interactive-builder/interactive-builder.component.tsx +6 -4
- package/src/components/interactive-builder/modals/add-form-reference/add-form-reference.modal.tsx +2 -2
- package/src/components/interactive-builder/modals/question/question-form/common/concept-search/concept-search.component.tsx +1 -1
- package/src/components/translation-builder/translation-builder.component.tsx +2 -2
- package/dist/9441.js.map +0 -1
- /package/dist/{9441.js.LICENSE.txt → 8935.js.LICENSE.txt} +0 -0
|
@@ -66,19 +66,20 @@ interface FormsListProps {
|
|
|
66
66
|
t: TFunction;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function CustomTag({ condition }: { condition?: boolean }) {
|
|
69
|
+
function CustomTag({ condition, invertTone = false }: { condition?: boolean; invertTone?: boolean }) {
|
|
70
70
|
const { t } = useTranslation();
|
|
71
|
+
const positiveTrueType = invertTone ? 'red' : 'green';
|
|
71
72
|
|
|
72
73
|
if (condition) {
|
|
73
74
|
return (
|
|
74
|
-
<Tag type=
|
|
75
|
+
<Tag type={positiveTrueType} size="md" title="Clear Filter" data-testid="yes-tag">
|
|
75
76
|
{t('yes', 'Yes')}
|
|
76
77
|
</Tag>
|
|
77
78
|
);
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
return (
|
|
81
|
-
<Tag type="
|
|
82
|
+
<Tag type="cool-gray" size="md" title="Clear Filter" data-testid="no-tag">
|
|
82
83
|
{t('no', 'No')}
|
|
83
84
|
</Tag>
|
|
84
85
|
);
|
|
@@ -237,7 +238,7 @@ function ActionButtons({ form, mutate, responsiveSize, t }: ActionButtonsProps)
|
|
|
237
238
|
};
|
|
238
239
|
|
|
239
240
|
return (
|
|
240
|
-
|
|
241
|
+
<div className={styles.actionButtons}>
|
|
241
242
|
{formResources.length == 0 || !form?.resources[0] ? (
|
|
242
243
|
<ImportButton />
|
|
243
244
|
) : (
|
|
@@ -247,7 +248,7 @@ function ActionButtons({ form, mutate, responsiveSize, t }: ActionButtonsProps)
|
|
|
247
248
|
</>
|
|
248
249
|
)}
|
|
249
250
|
{form.retired ? <RestoreButton /> : <DeleteButton />}
|
|
250
|
-
|
|
251
|
+
</div>
|
|
251
252
|
);
|
|
252
253
|
}
|
|
253
254
|
|
|
@@ -286,22 +287,27 @@ function FormsList({ forms, isValidating, mutate, t }: FormsListProps) {
|
|
|
286
287
|
{
|
|
287
288
|
header: t('name', 'Name'),
|
|
288
289
|
key: 'name',
|
|
290
|
+
isSortable: true,
|
|
289
291
|
},
|
|
290
292
|
{
|
|
291
293
|
header: t('version', 'Version'),
|
|
292
294
|
key: 'version',
|
|
295
|
+
isSortable: true,
|
|
293
296
|
},
|
|
294
297
|
{
|
|
295
298
|
header: t('published', 'Published'),
|
|
296
299
|
key: 'published',
|
|
300
|
+
isSortable: true,
|
|
297
301
|
},
|
|
298
302
|
{
|
|
299
303
|
header: t('retired', 'Retired'),
|
|
300
304
|
key: 'retired',
|
|
305
|
+
isSortable: true,
|
|
301
306
|
},
|
|
302
307
|
{
|
|
303
308
|
header: t('schemaActions', 'Schema actions'),
|
|
304
309
|
key: 'actions',
|
|
310
|
+
isSortable: false,
|
|
305
311
|
},
|
|
306
312
|
];
|
|
307
313
|
|
|
@@ -318,23 +324,47 @@ function FormsList({ forms, isValidating, mutate, t }: FormsListProps) {
|
|
|
318
324
|
const { paginated, goTo, results, currentPage } = usePagination(searchResults, pageSize);
|
|
319
325
|
|
|
320
326
|
const tableRows = results?.map((form: TypedForm) => ({
|
|
321
|
-
...form,
|
|
322
327
|
id: form?.uuid,
|
|
323
|
-
name:
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
onMouseEnter={() => void preload(`${restBaseUrl}/form/${form?.uuid}?v=full`, openmrsFetch)}
|
|
329
|
-
>
|
|
330
|
-
{form.name}
|
|
331
|
-
</ConfigurableLink>
|
|
332
|
-
),
|
|
333
|
-
published: <CustomTag condition={form.published} />,
|
|
334
|
-
retired: <CustomTag condition={form.retired} />,
|
|
335
|
-
actions: <ActionButtons form={form} mutate={mutate} responsiveSize={responsiveSize} t={t} />,
|
|
328
|
+
name: form.name,
|
|
329
|
+
version: form.version,
|
|
330
|
+
published: form.published,
|
|
331
|
+
retired: form.retired,
|
|
332
|
+
actions: form.uuid,
|
|
336
333
|
}));
|
|
337
334
|
|
|
335
|
+
const formsByUuid = useMemo(() => new Map(results?.map((form: TypedForm) => [form.uuid, form]) ?? []), [results]);
|
|
336
|
+
|
|
337
|
+
const renderCell = (cell: { id: string; value: unknown; info: { header: string } }) => {
|
|
338
|
+
const form = formsByUuid.get(String(cell.value)) ?? formsByUuid.get(cell.id.split(':')[0]);
|
|
339
|
+
switch (cell.info.header) {
|
|
340
|
+
case 'name': {
|
|
341
|
+
const rowForm = formsByUuid.get(cell.id.split(':')[0]);
|
|
342
|
+
return (
|
|
343
|
+
<ConfigurableLink
|
|
344
|
+
className={styles.link}
|
|
345
|
+
to={editSchemaUrl}
|
|
346
|
+
templateParams={{ formUuid: rowForm?.uuid }}
|
|
347
|
+
onMouseEnter={() => rowForm && void preload(`${restBaseUrl}/form/${rowForm.uuid}?v=full`, openmrsFetch)}
|
|
348
|
+
>
|
|
349
|
+
{String(cell.value)}
|
|
350
|
+
</ConfigurableLink>
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
case 'published':
|
|
354
|
+
return <CustomTag condition={Boolean(cell.value)} />;
|
|
355
|
+
case 'retired':
|
|
356
|
+
return <CustomTag condition={Boolean(cell.value)} invertTone />;
|
|
357
|
+
case 'actions': {
|
|
358
|
+
const actionForm = formsByUuid.get(String(cell.value));
|
|
359
|
+
return actionForm ? (
|
|
360
|
+
<ActionButtons form={actionForm} mutate={mutate} responsiveSize={responsiveSize} t={t} />
|
|
361
|
+
) : null;
|
|
362
|
+
}
|
|
363
|
+
default:
|
|
364
|
+
return String(cell.value);
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
338
368
|
const handleFilter = ({ selectedItem }: { selectedItem: string }) => setFilter(selectedItem);
|
|
339
369
|
|
|
340
370
|
const handleSearch = useCallback(
|
|
@@ -365,7 +395,7 @@ function FormsList({ forms, isValidating, mutate, t }: FormsListProps) {
|
|
|
365
395
|
<span>{isValidating ? <InlineLoading /> : null}</span>
|
|
366
396
|
</div>
|
|
367
397
|
</div>
|
|
368
|
-
<DataTable rows={tableRows} headers={tableHeaders} size={isTablet ? 'lg' : 'sm'} useZebraStyles>
|
|
398
|
+
<DataTable rows={tableRows} headers={tableHeaders} size={isTablet ? 'lg' : 'sm'} useZebraStyles isSortable>
|
|
369
399
|
{({ rows, headers, getTableProps, getHeaderProps, getRowProps }) => (
|
|
370
400
|
<>
|
|
371
401
|
<TableContainer className={styles.tableContainer} data-testid="forms-table">
|
|
@@ -381,7 +411,6 @@ function FormsList({ forms, isValidating, mutate, t }: FormsListProps) {
|
|
|
381
411
|
<Button
|
|
382
412
|
kind="primary"
|
|
383
413
|
iconDescription={t('createNewForm', 'Create a new form')}
|
|
384
|
-
renderIcon={() => <Add size={16} />}
|
|
385
414
|
size={responsiveSize}
|
|
386
415
|
onClick={() =>
|
|
387
416
|
navigate({
|
|
@@ -389,6 +418,7 @@ function FormsList({ forms, isValidating, mutate, t }: FormsListProps) {
|
|
|
389
418
|
})
|
|
390
419
|
}
|
|
391
420
|
>
|
|
421
|
+
<Add size={16} style={{ marginRight: '0.5rem' }} aria-hidden />
|
|
392
422
|
{t('createNewForm', 'Create a new form')}
|
|
393
423
|
</Button>
|
|
394
424
|
</TableToolbarContent>
|
|
@@ -397,16 +427,19 @@ function FormsList({ forms, isValidating, mutate, t }: FormsListProps) {
|
|
|
397
427
|
<Table {...getTableProps()} className={styles.table}>
|
|
398
428
|
<TableHead>
|
|
399
429
|
<TableRow>
|
|
400
|
-
{headers.map((header) =>
|
|
401
|
-
|
|
402
|
-
|
|
430
|
+
{headers.map((header) => {
|
|
431
|
+
const sortable = (header as { isSortable?: boolean }).isSortable;
|
|
432
|
+
return (
|
|
433
|
+
<TableHeader {...getHeaderProps({ header, isSortable: sortable })}>{header.header}</TableHeader>
|
|
434
|
+
);
|
|
435
|
+
})}
|
|
403
436
|
</TableRow>
|
|
404
437
|
</TableHead>
|
|
405
438
|
<TableBody>
|
|
406
439
|
{rows.map((row) => (
|
|
407
|
-
<TableRow key=
|
|
440
|
+
<TableRow key={row.id} {...getRowProps({ row })} data-testid={`form-row-${row.id}`}>
|
|
408
441
|
{row.cells.map((cell) => (
|
|
409
|
-
<TableCell key={cell.id}>{cell
|
|
442
|
+
<TableCell key={cell.id}>{renderCell(cell)}</TableCell>
|
|
410
443
|
))}
|
|
411
444
|
</TableRow>
|
|
412
445
|
))}
|
|
@@ -472,7 +505,7 @@ const Dashboard: React.FC = () => {
|
|
|
472
505
|
lowContrast
|
|
473
506
|
title={t(
|
|
474
507
|
'schemaSaveWarningMessage',
|
|
475
|
-
"
|
|
508
|
+
"This is a demo server and can't be relied upon to save your schemas permanently. To avoid losing your work, please save your schemas to your local machine. Alternatively, upload your schema to the distro repo to have it persisted across server resets.",
|
|
476
509
|
)}
|
|
477
510
|
/>
|
|
478
511
|
)}
|
|
@@ -16,8 +16,9 @@ import {
|
|
|
16
16
|
TabPanel,
|
|
17
17
|
TabPanels,
|
|
18
18
|
Tabs,
|
|
19
|
+
Tag,
|
|
19
20
|
} from '@carbon/react';
|
|
20
|
-
import { ArrowLeft, Maximize, Minimize, Download } from '@carbon/react/icons';
|
|
21
|
+
import { ArrowLeft, Maximize, Minimize, Download, Renew } from '@carbon/react/icons';
|
|
21
22
|
import { useParams } from 'react-router-dom';
|
|
22
23
|
import { useTranslation } from 'react-i18next';
|
|
23
24
|
import { type TFunction } from 'i18next';
|
|
@@ -95,6 +96,21 @@ const FormEditorContent: React.FC<TranslationFnProps> = ({ t }) => {
|
|
|
95
96
|
|
|
96
97
|
const isLoadingFormOrSchema = Boolean(formUuid) && (isLoadingClobdata || isLoadingForm);
|
|
97
98
|
|
|
99
|
+
const savedSchemaString = useMemo(() => (clobdata ? JSON.stringify(clobdata, null, 2) : ''), [clobdata]);
|
|
100
|
+
const hasSchemaContent =
|
|
101
|
+
Boolean(stringifiedSchema) && stringifiedSchema !== 'undefined' && stringifiedSchema !== 'null';
|
|
102
|
+
const isDirty = hasSchemaContent && stringifiedSchema !== savedSchemaString;
|
|
103
|
+
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
if (!isDirty) return;
|
|
106
|
+
const handler = (event: BeforeUnloadEvent) => {
|
|
107
|
+
event.preventDefault();
|
|
108
|
+
event.returnValue = '';
|
|
109
|
+
};
|
|
110
|
+
window.addEventListener('beforeunload', handler);
|
|
111
|
+
return () => window.removeEventListener('beforeunload', handler);
|
|
112
|
+
}, [isDirty]);
|
|
113
|
+
|
|
98
114
|
const langCodeForPreview = useMemo(
|
|
99
115
|
() => (shouldMergeTranslation ? renderLangCode : null),
|
|
100
116
|
[shouldMergeTranslation, renderLangCode],
|
|
@@ -353,7 +369,14 @@ const FormEditorContent: React.FC<TranslationFnProps> = ({ t }) => {
|
|
|
353
369
|
{isLoadingFormOrSchema ? (
|
|
354
370
|
<InlineLoading description={t('loadingSchema', 'Loading schema') + '...'} />
|
|
355
371
|
) : (
|
|
356
|
-
<h1 className={styles.formName}>
|
|
372
|
+
<h1 className={styles.formName}>
|
|
373
|
+
{form?.name}
|
|
374
|
+
{isDirty && (
|
|
375
|
+
<Tag className={styles.dirtyIndicator} type="warm-gray" size="sm">
|
|
376
|
+
{t('unsavedChanges', 'Unsaved changes')}
|
|
377
|
+
</Tag>
|
|
378
|
+
)}
|
|
379
|
+
</h1>
|
|
357
380
|
)}
|
|
358
381
|
</div>
|
|
359
382
|
<div>
|
|
@@ -378,7 +401,7 @@ const FormEditorContent: React.FC<TranslationFnProps> = ({ t }) => {
|
|
|
378
401
|
) : null}
|
|
379
402
|
{isNewSchema && !schema ? (
|
|
380
403
|
<Button kind="ghost" onClick={inputDummySchema}>
|
|
381
|
-
{t('inputDummySchema', '
|
|
404
|
+
{t('inputDummySchema', 'Load sample schema')}
|
|
382
405
|
</Button>
|
|
383
406
|
) : null}
|
|
384
407
|
<Dropdown
|
|
@@ -395,12 +418,18 @@ const FormEditorContent: React.FC<TranslationFnProps> = ({ t }) => {
|
|
|
395
418
|
className={styles.dropdown}
|
|
396
419
|
/>
|
|
397
420
|
|
|
398
|
-
<Button
|
|
399
|
-
|
|
421
|
+
<Button
|
|
422
|
+
kind="tertiary"
|
|
423
|
+
size="sm"
|
|
424
|
+
renderIcon={Renew}
|
|
425
|
+
onClick={handleRenderSchemaChanges}
|
|
426
|
+
disabled={!!invalidJsonErrorMessage}
|
|
427
|
+
>
|
|
428
|
+
{t('renderChanges', 'Render changes')}
|
|
400
429
|
</Button>
|
|
401
430
|
</div>
|
|
402
431
|
{schema ? (
|
|
403
|
-
|
|
432
|
+
<div className={styles.schemaIconActions}>
|
|
404
433
|
<IconButton
|
|
405
434
|
enterDelayMs={defaultEnterDelayInMs}
|
|
406
435
|
kind="ghost"
|
|
@@ -429,7 +458,7 @@ const FormEditorContent: React.FC<TranslationFnProps> = ({ t }) => {
|
|
|
429
458
|
<Download />
|
|
430
459
|
</IconButton>
|
|
431
460
|
</a>
|
|
432
|
-
|
|
461
|
+
</div>
|
|
433
462
|
) : null}
|
|
434
463
|
</div>
|
|
435
464
|
{formError ? (
|
|
@@ -518,10 +547,12 @@ function BackButton({ t }: TranslationFnProps) {
|
|
|
518
547
|
|
|
519
548
|
function FormEditor() {
|
|
520
549
|
const { t } = useTranslation();
|
|
550
|
+
const { formUuid } = useParams<{ formUuid: string }>();
|
|
551
|
+
const isNewForm = !formUuid;
|
|
521
552
|
|
|
522
553
|
return (
|
|
523
554
|
<>
|
|
524
|
-
<Header title={t('
|
|
555
|
+
<Header title={isNewForm ? t('createNewForm', 'Create a new form') : t('editForm', 'Edit form')} />
|
|
525
556
|
<BackButton t={t} />
|
|
526
557
|
<FormEditorContent t={t} />
|
|
527
558
|
</>
|
|
@@ -56,6 +56,11 @@
|
|
|
56
56
|
@include type.type-style('heading-03');
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
.dirtyIndicator {
|
|
60
|
+
margin-left: layout.$spacing-03;
|
|
61
|
+
vertical-align: middle;
|
|
62
|
+
}
|
|
63
|
+
|
|
59
64
|
.editorContainer {
|
|
60
65
|
padding: 1rem;
|
|
61
66
|
|
|
@@ -70,6 +75,7 @@
|
|
|
70
75
|
display: flex;
|
|
71
76
|
margin-right: 1rem;
|
|
72
77
|
align-items: center;
|
|
78
|
+
gap: layout.$spacing-05;
|
|
73
79
|
}
|
|
74
80
|
|
|
75
81
|
.tabHeading {
|
|
@@ -112,10 +118,18 @@ button {
|
|
|
112
118
|
.topBtns {
|
|
113
119
|
display: flex;
|
|
114
120
|
align-items: center;
|
|
121
|
+
gap: layout.$spacing-05;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.schemaIconActions {
|
|
125
|
+
display: flex;
|
|
126
|
+
align-items: center;
|
|
127
|
+
gap: layout.$spacing-02;
|
|
115
128
|
}
|
|
116
129
|
|
|
117
130
|
.dropdown {
|
|
118
|
-
|
|
131
|
+
gap: layout.$spacing-03 !important;
|
|
132
|
+
column-gap: layout.$spacing-03 !important;
|
|
119
133
|
|
|
120
134
|
:global(.cds--label) {
|
|
121
135
|
white-space: nowrap;
|
|
@@ -392,7 +392,8 @@ const InteractiveBuilder: React.FC<InteractiveBuilderProps> = ({
|
|
|
392
392
|
</p>
|
|
393
393
|
</div>
|
|
394
394
|
<Button
|
|
395
|
-
kind="
|
|
395
|
+
kind="tertiary"
|
|
396
|
+
size="sm"
|
|
396
397
|
renderIcon={Add}
|
|
397
398
|
onClick={launchAddPageModal}
|
|
398
399
|
iconDescription={t('addPage', 'Add Page')}
|
|
@@ -420,7 +421,7 @@ const InteractiveBuilder: React.FC<InteractiveBuilderProps> = ({
|
|
|
420
421
|
)}
|
|
421
422
|
</p>
|
|
422
423
|
|
|
423
|
-
<Button onClick={launchNewFormModal} className={styles.startButton} kind="
|
|
424
|
+
<Button onClick={launchNewFormModal} className={styles.startButton} kind="primary">
|
|
424
425
|
{t('startBuilding', 'Start building')}
|
|
425
426
|
</Button>
|
|
426
427
|
</div>
|
|
@@ -481,7 +482,7 @@ const InteractiveBuilder: React.FC<InteractiveBuilderProps> = ({
|
|
|
481
482
|
<IconButton
|
|
482
483
|
enterDelayMs={300}
|
|
483
484
|
kind="ghost"
|
|
484
|
-
label={t('editSection', 'Edit
|
|
485
|
+
label={t('editSection', 'Edit section')}
|
|
485
486
|
onClick={() =>
|
|
486
487
|
section.reference
|
|
487
488
|
? launchAddFormReferenceModal(pageIndex, 'edit', sectionIndex)
|
|
@@ -565,7 +566,8 @@ const InteractiveBuilder: React.FC<InteractiveBuilderProps> = ({
|
|
|
565
566
|
|
|
566
567
|
<Button
|
|
567
568
|
className={styles.addQuestionButton}
|
|
568
|
-
kind="
|
|
569
|
+
kind="tertiary"
|
|
570
|
+
size="sm"
|
|
569
571
|
renderIcon={Add}
|
|
570
572
|
onClick={() => {
|
|
571
573
|
launchAddQuestionModal(pageIndex, sectionIndex);
|
package/src/components/interactive-builder/modals/add-form-reference/add-form-reference.modal.tsx
CHANGED
|
@@ -178,7 +178,7 @@ const AddFormReferenceModal: React.FC<AddFormReferenceModalProps> = ({
|
|
|
178
178
|
<ModalBody className={styles.modalBody}>
|
|
179
179
|
<Stack gap={4}>
|
|
180
180
|
{isLoading ? (
|
|
181
|
-
<InlineLoading description={t('loading', 'Loading...'
|
|
181
|
+
<InlineLoading description={t('loading', 'Loading') + '...'} />
|
|
182
182
|
) : error ? (
|
|
183
183
|
<InlineNotification>{t('errorLoadingForms', 'Error loading forms')}</InlineNotification>
|
|
184
184
|
) : forms.length === 0 ? (
|
|
@@ -200,7 +200,7 @@ const AddFormReferenceModal: React.FC<AddFormReferenceModalProps> = ({
|
|
|
200
200
|
</FormGroup>
|
|
201
201
|
) : null}
|
|
202
202
|
{isLoadingClobdata ? (
|
|
203
|
-
<InlineLoading description={t('loading', 'Loading...'
|
|
203
|
+
<InlineLoading description={t('loading', 'Loading') + '...'} />
|
|
204
204
|
) : clobdataError ? (
|
|
205
205
|
<InlineNotification>{t('errorLoadingForm', 'Error loading form')}</InlineNotification>
|
|
206
206
|
) : pages && pages.length > 0 && !mode ? (
|
|
@@ -102,7 +102,7 @@ const ConceptSearch: React.FC<ConceptSearchProps> = ({
|
|
|
102
102
|
)}
|
|
103
103
|
<div className={styles.searchContainer}>
|
|
104
104
|
{isLoadingConcept ? (
|
|
105
|
-
<InlineLoading className={styles.loader} description={t('loading', 'Loading...'
|
|
105
|
+
<InlineLoading className={styles.loader} description={t('loading', 'Loading') + '...'} />
|
|
106
106
|
) : (
|
|
107
107
|
<Search
|
|
108
108
|
id="conceptLookup"
|
|
@@ -195,11 +195,11 @@ const TranslationBuilder: React.FC<TranslationBuilderProps> = ({ formSchema, onU
|
|
|
195
195
|
subtitle: t('translationsUploadedSuccessfully', `Translation file uploaded successfully.`),
|
|
196
196
|
});
|
|
197
197
|
} catch (err: any) {
|
|
198
|
-
setError(t('translationFileUploadFail', 'Failed to upload translation file
|
|
198
|
+
setError(t('translationFileUploadFail', 'Failed to upload translation file'));
|
|
199
199
|
showSnackbar({
|
|
200
200
|
title: t('uploadFailed', 'Upload Failed'),
|
|
201
201
|
kind: 'error',
|
|
202
|
-
subtitle: t('translationFileUploadFail',
|
|
202
|
+
subtitle: t('translationFileUploadFail', 'Failed to upload translation file'),
|
|
203
203
|
});
|
|
204
204
|
console.error(err);
|
|
205
205
|
} finally {
|