@openmrs/esm-openconceptlab-app 3.0.1-pre.10 → 3.0.1-pre.5
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 +19 -19
- package/dist/15.js +1 -0
- package/dist/538.js +2 -0
- package/dist/{645.js.LICENSE.txt → 538.js.LICENSE.txt} +0 -0
- package/dist/574.js +1 -1
- package/dist/862.js +1 -1
- package/dist/main.js +1 -1
- package/dist/openmrs-esm-openconceptlab-app.js +1 -1
- package/dist/openmrs-esm-openconceptlab-app.js.buildmanifest.json +42 -42
- package/dist/openmrs-esm-openconceptlab-app.old +1 -1
- package/locales/en/translation.json +35 -0
- package/locales/fr/translation.json +35 -0
- package/package.json +2 -2
- package/src/import/import.component.tsx +16 -23
- package/src/import/import.test.tsx +15 -13
- package/src/root.component.tsx +5 -8
- package/src/root.test.tsx +4 -4
- package/src/subscription/subscription.component.tsx +17 -28
- package/src/subscription/subscription.test.tsx +20 -22
- package/src/types.ts +0 -10
- package/translations/en.json +26 -40
- package/dist/452.js +0 -1
- package/dist/645.js +0 -2
- package/src/previous-imports/import-overview/import-items.component.scss +0 -24
- package/src/previous-imports/import-overview/import-items.component.tsx +0 -124
- package/src/previous-imports/import-overview/import-items.resource.ts +0 -10
- package/src/previous-imports/import-overview/import-items.test.tsx +0 -93
- package/src/previous-imports/import-overview/import-overview.component.scss +0 -11
- package/src/previous-imports/import-overview/import-overview.component.tsx +0 -65
- package/src/previous-imports/import-overview/import-overview.test.tsx +0 -83
- package/src/previous-imports/previous-imports.component.scss +0 -39
- package/src/previous-imports/previous-imports.component.tsx +0 -136
- package/src/previous-imports/previous-imports.resource.ts +0 -17
- package/src/previous-imports/previous-imports.test.tsx +0 -77
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
@use "@carbon/styles/scss/spacing";
|
|
2
|
-
@use "@carbon/styles/scss/type";
|
|
3
|
-
@import "~@openmrs/esm-styleguide/src/vars";
|
|
4
|
-
|
|
5
|
-
.pagination {
|
|
6
|
-
@include type.type-style('body-short-01');
|
|
7
|
-
background-color: $ui-02;
|
|
8
|
-
color: $text-02;
|
|
9
|
-
border: 1px solid $ui-03;
|
|
10
|
-
display: flex;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.tableBordered {
|
|
14
|
-
border: 1px solid $ui-03;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.tableDataRow > td {
|
|
18
|
-
padding-left: 1rem !important;
|
|
19
|
-
background-color: $ui-02 !important;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.tableHeaderRow > th {
|
|
23
|
-
background-color: $ui-03 !important;
|
|
24
|
-
}
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { showNotification, usePagination } from '@openmrs/esm-framework';
|
|
2
|
-
import {
|
|
3
|
-
DataTableSkeleton,
|
|
4
|
-
Link,
|
|
5
|
-
Pagination,
|
|
6
|
-
PaginationSkeleton,
|
|
7
|
-
Table,
|
|
8
|
-
TableBody,
|
|
9
|
-
TableCell,
|
|
10
|
-
TableHead,
|
|
11
|
-
TableHeader,
|
|
12
|
-
TableRow,
|
|
13
|
-
} from '@carbon/react';
|
|
14
|
-
import React, { Fragment, useCallback, useEffect, useState } from 'react';
|
|
15
|
-
import { useTranslation } from 'react-i18next';
|
|
16
|
-
import { getImportDetails } from './import-items.resource';
|
|
17
|
-
import styles from './import-items.component.scss';
|
|
18
|
-
import { ImportItem } from '../../types';
|
|
19
|
-
|
|
20
|
-
interface ImportItemsProps {
|
|
21
|
-
importUuid: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const ImportItems: React.FC<ImportItemsProps> = ({ importUuid }) => {
|
|
25
|
-
const { t } = useTranslation();
|
|
26
|
-
const [isLoading, setIsLoading] = useState<Boolean>();
|
|
27
|
-
const [pageSize, setPageSize] = useState(5);
|
|
28
|
-
|
|
29
|
-
const [selectedImportItems, setSelectedImportItems] = useState<ImportItem[]>([]);
|
|
30
|
-
const { results, currentPage, goTo } = usePagination(selectedImportItems, pageSize);
|
|
31
|
-
|
|
32
|
-
const handleImportDetails = useCallback(
|
|
33
|
-
async (uuid: string) => {
|
|
34
|
-
setIsLoading(true);
|
|
35
|
-
const abortController = new AbortController();
|
|
36
|
-
|
|
37
|
-
const response = await getImportDetails(uuid, abortController);
|
|
38
|
-
|
|
39
|
-
if (response.ok) {
|
|
40
|
-
setSelectedImportItems(response.data.results);
|
|
41
|
-
} else {
|
|
42
|
-
showNotification({
|
|
43
|
-
title: t('importItemsFetchError', 'Error occured while fetching the import items'),
|
|
44
|
-
kind: 'error',
|
|
45
|
-
critical: true,
|
|
46
|
-
description: JSON.stringify(response.data),
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
setIsLoading(false);
|
|
50
|
-
return () => abortController.abort();
|
|
51
|
-
},
|
|
52
|
-
[t],
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
handleImportDetails(importUuid);
|
|
57
|
-
}, [handleImportDetails, importUuid]);
|
|
58
|
-
|
|
59
|
-
if (isLoading) {
|
|
60
|
-
return (
|
|
61
|
-
<div>
|
|
62
|
-
<DataTableSkeleton showHeader={false} showToolbar={false} columnCount={2} />
|
|
63
|
-
<PaginationSkeleton />
|
|
64
|
-
</div>
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const headerData = [
|
|
69
|
-
{
|
|
70
|
-
header: t('conceptOrMapping', 'Concept/Mapping'),
|
|
71
|
-
key: 'uuid',
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
header: t('message', 'Message'),
|
|
75
|
-
key: 'errorMessage',
|
|
76
|
-
},
|
|
77
|
-
];
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
!isLoading && (
|
|
81
|
-
<div>
|
|
82
|
-
<Table size="sm" className={styles.tableBordered}>
|
|
83
|
-
<TableHead>
|
|
84
|
-
<TableRow className={styles.tableHeaderRow}>
|
|
85
|
-
{headerData.map((header, i) => (
|
|
86
|
-
<TableHeader key={i} isSortable={true}>
|
|
87
|
-
{header.header}
|
|
88
|
-
</TableHeader>
|
|
89
|
-
))}
|
|
90
|
-
</TableRow>
|
|
91
|
-
</TableHead>
|
|
92
|
-
<TableBody>
|
|
93
|
-
{results?.map((row) => (
|
|
94
|
-
<Fragment key={row.uuid}>
|
|
95
|
-
<TableRow className={styles.tableDataRow}>
|
|
96
|
-
<TableCell>
|
|
97
|
-
<Link href={row.versionUrl}>
|
|
98
|
-
{row.type} {row.uuid}
|
|
99
|
-
</Link>
|
|
100
|
-
</TableCell>
|
|
101
|
-
<TableCell>{row.errorMessage}</TableCell>
|
|
102
|
-
</TableRow>
|
|
103
|
-
</Fragment>
|
|
104
|
-
))}
|
|
105
|
-
</TableBody>
|
|
106
|
-
</Table>
|
|
107
|
-
<Pagination
|
|
108
|
-
className={styles.pagination}
|
|
109
|
-
size="sm"
|
|
110
|
-
page={currentPage}
|
|
111
|
-
pageSize={pageSize}
|
|
112
|
-
pageSizes={[5, 10, 20, 50, 100]}
|
|
113
|
-
totalItems={selectedImportItems?.length}
|
|
114
|
-
onChange={({ page, pageSize }) => {
|
|
115
|
-
goTo(page);
|
|
116
|
-
setPageSize(pageSize);
|
|
117
|
-
}}
|
|
118
|
-
/>
|
|
119
|
-
</div>
|
|
120
|
-
)
|
|
121
|
-
);
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
export default ImportItems;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
2
|
-
import { ImportItem } from '../../types';
|
|
3
|
-
|
|
4
|
-
export async function getImportDetails(importUuid: string, abortController?: AbortController) {
|
|
5
|
-
const url = `/ws/rest/v1/openconceptlab/import/${importUuid}/item?state=ERROR&v=full`;
|
|
6
|
-
return openmrsFetch<{ results: ImportItem[] }>(url, {
|
|
7
|
-
method: 'GET',
|
|
8
|
-
signal: abortController?.signal,
|
|
9
|
-
});
|
|
10
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { screen, waitFor } from '@testing-library/react';
|
|
3
|
-
import { usePagination } from '@openmrs/esm-framework';
|
|
4
|
-
import { renderWithSwr } from '../../../../../tools/test-helpers';
|
|
5
|
-
import { mockImportItems, mockPreviousImports } from '../../../../../__mocks__/openconceptlab.mock';
|
|
6
|
-
import { ImportItem } from '../../types';
|
|
7
|
-
import ImportItems from './import-items.component';
|
|
8
|
-
import { getImportDetails } from './import-items.resource';
|
|
9
|
-
|
|
10
|
-
const testProps = {
|
|
11
|
-
importUuid: mockPreviousImports[1].uuid,
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const mockGetImportDetails = getImportDetails as jest.Mock;
|
|
15
|
-
const mockUsePagination = usePagination as jest.Mock;
|
|
16
|
-
|
|
17
|
-
jest.mock('./import-items.resource', () => {
|
|
18
|
-
const originalModule = jest.requireActual('./import-items.resource');
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
...originalModule,
|
|
22
|
-
getImportDetails: jest.fn(),
|
|
23
|
-
};
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
jest.mock('@openmrs/esm-framework', () => {
|
|
27
|
-
const originalModule = jest.requireActual('@openmrs/esm-framework');
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
...originalModule,
|
|
31
|
-
usePagination: jest.fn(),
|
|
32
|
-
};
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe(`Import Items component`, () => {
|
|
36
|
-
afterEach(() => {
|
|
37
|
-
mockGetImportDetails.mockReset();
|
|
38
|
-
mockUsePagination.mockReset();
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it(`renders without dying`, () => {
|
|
42
|
-
mockGetImportDetails.mockReturnValue({ status: 200, ok: true, data: [] });
|
|
43
|
-
mockUsePagination.mockReturnValue({
|
|
44
|
-
currentPage: 1,
|
|
45
|
-
goTo: () => {},
|
|
46
|
-
results: [],
|
|
47
|
-
});
|
|
48
|
-
renderImportItemsComponent();
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it(`renders the table`, async () => {
|
|
52
|
-
mockGetImportDetails.mockReturnValue({ status: 200, ok: true, data: mockImportItems });
|
|
53
|
-
mockUsePagination.mockReturnValue({
|
|
54
|
-
currentPage: 1,
|
|
55
|
-
goTo: () => {},
|
|
56
|
-
results: mockImportItems,
|
|
57
|
-
});
|
|
58
|
-
renderImportItemsComponent();
|
|
59
|
-
await waitForLoadingToFinish();
|
|
60
|
-
|
|
61
|
-
expect(screen.getByText('Concept/Mapping')).toBeVisible();
|
|
62
|
-
expect(screen.getByText('Message')).toBeVisible();
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it(`renders the import items correctly`, async () => {
|
|
66
|
-
mockGetImportDetails.mockReturnValue({ status: 200, ok: true, data: mockImportItems });
|
|
67
|
-
mockUsePagination.mockReturnValue({
|
|
68
|
-
currentPage: 1,
|
|
69
|
-
goTo: () => {},
|
|
70
|
-
results: mockImportItems,
|
|
71
|
-
});
|
|
72
|
-
renderImportItemsComponent();
|
|
73
|
-
await waitForLoadingToFinish();
|
|
74
|
-
|
|
75
|
-
expect(screen.getByText('Concept/Mapping')).toBeVisible();
|
|
76
|
-
expect(screen.getByText('Message')).toBeVisible();
|
|
77
|
-
|
|
78
|
-
mockImportItems.slice(5).forEach((importItem: ImportItem) => {
|
|
79
|
-
expect(screen.getByText(importItem.type + ' ' + importItem.uuid)).toBeVisible();
|
|
80
|
-
expect(screen.getByText(importItem.errorMessage)).toBeVisible();
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
function renderImportItemsComponent() {
|
|
86
|
-
renderWithSwr(<ImportItems {...testProps} />);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function waitForLoadingToFinish() {
|
|
90
|
-
return waitFor(() => {
|
|
91
|
-
expect(screen.getByText('Concept/Mapping')).toBeVisible(), { timeout: 2000 };
|
|
92
|
-
});
|
|
93
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { formatDatetime } from '@openmrs/esm-framework';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { useTranslation } from 'react-i18next';
|
|
4
|
-
import styles from './import-overview.component.scss';
|
|
5
|
-
import { Import } from '../../types';
|
|
6
|
-
import ImportItems from './import-items.component';
|
|
7
|
-
|
|
8
|
-
interface ImportOverviewProps {
|
|
9
|
-
selectedImportObject: Import;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const ImportOverview: React.FC<ImportOverviewProps> = ({ selectedImportObject }) => {
|
|
13
|
-
const { t } = useTranslation();
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<div>
|
|
17
|
-
<span className={styles.heading01}>{t('startedOn', 'Started on')} </span>
|
|
18
|
-
<span className="body">{formatDatetime(new Date(selectedImportObject.localDateStarted))}</span>
|
|
19
|
-
<br />
|
|
20
|
-
|
|
21
|
-
<span className={styles.heading01}>{t('completedOn', 'Completed on')} </span>
|
|
22
|
-
<span className="body">{formatDatetime(new Date(selectedImportObject.localDateStopped))}</span>
|
|
23
|
-
<br />
|
|
24
|
-
|
|
25
|
-
<span className={styles.heading01}>{t('duration', 'Duration')} </span>
|
|
26
|
-
<span className="body">{selectedImportObject.importTime}</span>
|
|
27
|
-
<br />
|
|
28
|
-
<br />
|
|
29
|
-
|
|
30
|
-
<span className={styles.heading01}>{t('result', 'Result:')} </span>
|
|
31
|
-
<br />
|
|
32
|
-
|
|
33
|
-
<div className={`body ${styles.indentedContent}`}>
|
|
34
|
-
<span>
|
|
35
|
-
{selectedImportObject.upToDateItemsCount} {t('conceptsUpToDate', 'concepts up to date')}
|
|
36
|
-
</span>
|
|
37
|
-
<br />
|
|
38
|
-
<span>
|
|
39
|
-
{selectedImportObject.addedItemsCount} {t('conceptsAdded', 'concepts added')}
|
|
40
|
-
</span>
|
|
41
|
-
<br />
|
|
42
|
-
<span>
|
|
43
|
-
{selectedImportObject.updatedItemsCount} {t('conceptsUpdated', 'concepts updated')}
|
|
44
|
-
</span>
|
|
45
|
-
<br />
|
|
46
|
-
<span>
|
|
47
|
-
{selectedImportObject.retiredItemsCount} {t('conceptsRetired', 'concepts retired')}
|
|
48
|
-
</span>
|
|
49
|
-
<br />
|
|
50
|
-
<span>
|
|
51
|
-
{selectedImportObject.errorItemsCount} {t('errorsFound', 'errors found')}
|
|
52
|
-
</span>
|
|
53
|
-
<br />
|
|
54
|
-
<span>
|
|
55
|
-
{selectedImportObject.ignoredErrorsCount} {t('errorsIgnored', 'errors ignored')}
|
|
56
|
-
</span>
|
|
57
|
-
<br />
|
|
58
|
-
</div>
|
|
59
|
-
<br />
|
|
60
|
-
{selectedImportObject.errorItemsCount != 0 && <ImportItems importUuid={selectedImportObject.uuid} />}
|
|
61
|
-
</div>
|
|
62
|
-
);
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export default ImportOverview;
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { screen, waitFor } from '@testing-library/react';
|
|
3
|
-
import { formatDatetime } from '@openmrs/esm-framework';
|
|
4
|
-
import { renderWithSwr } from '../../../../../tools/test-helpers';
|
|
5
|
-
import { mockPreviousImports } from '../../../../../__mocks__/openconceptlab.mock';
|
|
6
|
-
import { Import } from '../../types';
|
|
7
|
-
import ImportOverview from './import-overview.component';
|
|
8
|
-
|
|
9
|
-
describe(`Import Overview component`, () => {
|
|
10
|
-
it(`renders without dying`, () => {
|
|
11
|
-
renderImportOverviewComponent(mockPreviousImports[0]);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it(`renders the fields`, async () => {
|
|
15
|
-
renderImportOverviewComponent(mockPreviousImports[0]);
|
|
16
|
-
await waitForLoadingToFinish();
|
|
17
|
-
|
|
18
|
-
expect(screen.getByText('Started on')).toBeVisible();
|
|
19
|
-
expect(screen.getByText('Completed on')).toBeVisible();
|
|
20
|
-
expect(screen.getByText('Duration')).toBeVisible();
|
|
21
|
-
expect(screen.getByText('Result:')).toBeVisible();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it(`renders the import details when no errored items`, async () => {
|
|
25
|
-
const selectedImport = mockPreviousImports[0];
|
|
26
|
-
|
|
27
|
-
renderImportOverviewComponent(selectedImport);
|
|
28
|
-
await waitForLoadingToFinish();
|
|
29
|
-
|
|
30
|
-
const startedTimeText = formatDatetime(selectedImport.localDateStarted);
|
|
31
|
-
const stoppedTimeText = formatDatetime(selectedImport.localDateStopped);
|
|
32
|
-
const upToDateItemsText = selectedImport.upToDateItemsCount + ' concepts up to date';
|
|
33
|
-
const addedItemsText = selectedImport.addedItemsCount + ' concepts added';
|
|
34
|
-
const updatedItemsText = selectedImport.updatedItemsCount + ' concepts updated';
|
|
35
|
-
const retiredItemsText = selectedImport.retiredItemsCount + ' concepts retired';
|
|
36
|
-
const errorItemsText = selectedImport.errorItemsCount + ' errors found';
|
|
37
|
-
const ignoredErrorsText = selectedImport.ignoredErrorsCount + ' errors ignored';
|
|
38
|
-
|
|
39
|
-
expect(screen.getByText(startedTimeText)).toBeVisible();
|
|
40
|
-
expect(screen.getByText(stoppedTimeText)).toBeVisible();
|
|
41
|
-
expect(screen.getByText(upToDateItemsText)).toBeVisible();
|
|
42
|
-
expect(screen.getByText(addedItemsText)).toBeVisible();
|
|
43
|
-
expect(screen.getByText(updatedItemsText)).toBeVisible();
|
|
44
|
-
expect(screen.getByText(retiredItemsText)).toBeVisible();
|
|
45
|
-
expect(screen.getByText(errorItemsText)).toBeVisible();
|
|
46
|
-
expect(screen.getByText(ignoredErrorsText)).toBeVisible();
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it(`renders the import details when there are errored items`, async () => {
|
|
50
|
-
const selectedImport = mockPreviousImports[1];
|
|
51
|
-
|
|
52
|
-
renderImportOverviewComponent(selectedImport);
|
|
53
|
-
await waitForLoadingToFinish();
|
|
54
|
-
|
|
55
|
-
const startedTimeText = formatDatetime(selectedImport.localDateStarted);
|
|
56
|
-
const stoppedTimeText = formatDatetime(selectedImport.localDateStopped);
|
|
57
|
-
const upToDateItemsText = selectedImport.upToDateItemsCount + ' concepts up to date';
|
|
58
|
-
const addedItemsText = selectedImport.addedItemsCount + ' concepts added';
|
|
59
|
-
const updatedItemsText = selectedImport.updatedItemsCount + ' concepts updated';
|
|
60
|
-
const retiredItemsText = selectedImport.retiredItemsCount + ' concepts retired';
|
|
61
|
-
const errorItemsText = selectedImport.errorItemsCount + ' errors found';
|
|
62
|
-
const ignoredErrorsText = selectedImport.ignoredErrorsCount + ' errors ignored';
|
|
63
|
-
|
|
64
|
-
expect(screen.getByText(startedTimeText)).toBeVisible();
|
|
65
|
-
expect(screen.getByText(stoppedTimeText)).toBeVisible();
|
|
66
|
-
expect(screen.getByText(upToDateItemsText)).toBeVisible();
|
|
67
|
-
expect(screen.getByText(addedItemsText)).toBeVisible();
|
|
68
|
-
expect(screen.getByText(updatedItemsText)).toBeVisible();
|
|
69
|
-
expect(screen.getByText(retiredItemsText)).toBeVisible();
|
|
70
|
-
expect(screen.getByText(errorItemsText)).toBeVisible();
|
|
71
|
-
expect(screen.getByText(ignoredErrorsText)).toBeVisible();
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
function renderImportOverviewComponent(importObject: Import) {
|
|
76
|
-
renderWithSwr(<ImportOverview selectedImportObject={importObject} />);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function waitForLoadingToFinish() {
|
|
80
|
-
return waitFor(() => {
|
|
81
|
-
expect(screen.getByText('Started on')).toBeVisible(), { timeout: 2000 };
|
|
82
|
-
});
|
|
83
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
@use "@carbon/styles/scss/spacing";
|
|
2
|
-
@use "@carbon/styles/scss/type";
|
|
3
|
-
@import "~@openmrs/esm-styleguide/src/vars";
|
|
4
|
-
|
|
5
|
-
.grid {
|
|
6
|
-
margin-left: 0;
|
|
7
|
-
margin-right: 0;
|
|
8
|
-
padding-left: 0;
|
|
9
|
-
padding-right: 0;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.productiveHeading03 {
|
|
13
|
-
@include type.type-style('productive-heading-03');
|
|
14
|
-
margin-bottom: spacing.$spacing-03;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.pagination {
|
|
18
|
-
@include type.type-style('body-short-01');
|
|
19
|
-
background-color: $ui-02;
|
|
20
|
-
color: $text-02;
|
|
21
|
-
border: 1px solid $ui-03;
|
|
22
|
-
display: flex;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.tableBordered {
|
|
26
|
-
border: 1px solid $ui-03;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.tableRow > td {
|
|
30
|
-
background-color: $ui-02;
|
|
31
|
-
border-bottom: 1px solid $ui-03 !important;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.tableExpandedRow > td {
|
|
35
|
-
padding-left: spacing.$spacing-09 !important;
|
|
36
|
-
padding-right: spacing.$spacing-09;
|
|
37
|
-
padding-top: spacing.$spacing-05;
|
|
38
|
-
padding-bottom: spacing.$spacing-05;
|
|
39
|
-
}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { formatDatetime, showNotification, usePagination } from '@openmrs/esm-framework';
|
|
2
|
-
import {
|
|
3
|
-
Column,
|
|
4
|
-
DataTable,
|
|
5
|
-
DataTableSkeleton,
|
|
6
|
-
Pagination,
|
|
7
|
-
PaginationSkeleton,
|
|
8
|
-
Grid,
|
|
9
|
-
SkeletonText,
|
|
10
|
-
Table,
|
|
11
|
-
TableBody,
|
|
12
|
-
TableCell,
|
|
13
|
-
TableExpandedRow,
|
|
14
|
-
TableExpandHeader,
|
|
15
|
-
TableExpandRow,
|
|
16
|
-
TableHead,
|
|
17
|
-
TableHeader,
|
|
18
|
-
TableRow,
|
|
19
|
-
} from '@carbon/react';
|
|
20
|
-
import React, { Fragment, useState } from 'react';
|
|
21
|
-
import { useTranslation } from 'react-i18next';
|
|
22
|
-
import { usePreviousImports } from './previous-imports.resource';
|
|
23
|
-
import styles from './previous-imports.component.scss';
|
|
24
|
-
import { Import } from '../types';
|
|
25
|
-
import ImportOverview from './import-overview/import-overview.component';
|
|
26
|
-
|
|
27
|
-
const PreviousImports: React.FC = () => {
|
|
28
|
-
const { t } = useTranslation();
|
|
29
|
-
const [pageSize, setPageSize] = useState(10);
|
|
30
|
-
|
|
31
|
-
const { data: prevImports, isLoading, isError } = usePreviousImports();
|
|
32
|
-
const { results, currentPage, goTo } = usePagination(prevImports, pageSize);
|
|
33
|
-
|
|
34
|
-
if (isLoading) {
|
|
35
|
-
return (
|
|
36
|
-
<Grid className={styles.grid}>
|
|
37
|
-
<Column sm={4} md={8} lg={10}>
|
|
38
|
-
<SkeletonText className={styles.productiveHeading03} />
|
|
39
|
-
<DataTableSkeleton showHeader={false} showToolbar={false} rowCount={10} columnCount={3} />
|
|
40
|
-
<PaginationSkeleton />
|
|
41
|
-
</Column>
|
|
42
|
-
</Grid>
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (isError) {
|
|
47
|
-
showNotification({
|
|
48
|
-
kind: 'error',
|
|
49
|
-
description: t('previousImportsFetchError', 'Error occured while fetching the imports'),
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const headerData = [
|
|
54
|
-
{
|
|
55
|
-
header: t('dateAndTime', 'Date and Time'),
|
|
56
|
-
key: 'localDateStarted',
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
header: t('duration', 'Duration'),
|
|
60
|
-
key: 'importTime',
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
header: t('status', 'Status'),
|
|
64
|
-
key: 'status',
|
|
65
|
-
},
|
|
66
|
-
];
|
|
67
|
-
|
|
68
|
-
const rowData = results?.map((prevImport) => {
|
|
69
|
-
return {
|
|
70
|
-
id: prevImport.uuid,
|
|
71
|
-
localDateStarted: formatDatetime(new Date(prevImport.localDateStarted)),
|
|
72
|
-
importTime: prevImport.importTime,
|
|
73
|
-
status: prevImport.status,
|
|
74
|
-
};
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
return (
|
|
78
|
-
!isLoading &&
|
|
79
|
-
!isError && (
|
|
80
|
-
<Grid className={styles.grid}>
|
|
81
|
-
<Column sm={4} md={8} lg={10}>
|
|
82
|
-
<h3 className={styles.productiveHeading03}>{t('previousImports', 'Previous Imports')}</h3>
|
|
83
|
-
|
|
84
|
-
<DataTable rows={rowData} headers={headerData} size="sm">
|
|
85
|
-
{({ rows, headers, getHeaderProps, getRowProps, getTableProps }) => (
|
|
86
|
-
<Table {...getTableProps()} className={styles.tableBordered}>
|
|
87
|
-
<TableHead>
|
|
88
|
-
<TableRow>
|
|
89
|
-
<TableExpandHeader />
|
|
90
|
-
{headers.map((header, i) => (
|
|
91
|
-
<TableHeader key={i} {...getHeaderProps({ header })}>
|
|
92
|
-
{header.header}
|
|
93
|
-
</TableHeader>
|
|
94
|
-
))}
|
|
95
|
-
</TableRow>
|
|
96
|
-
</TableHead>
|
|
97
|
-
<TableBody>
|
|
98
|
-
{rows.map((row) => (
|
|
99
|
-
<Fragment key={row.id}>
|
|
100
|
-
<TableExpandRow {...getRowProps({ row })} className={styles.tableRow}>
|
|
101
|
-
{row.cells.map((cell) => (
|
|
102
|
-
<TableCell key={cell.id}>{cell.value}</TableCell>
|
|
103
|
-
))}
|
|
104
|
-
</TableExpandRow>
|
|
105
|
-
{row.isExpanded && (
|
|
106
|
-
<TableExpandedRow colSpan={headers.length + 1} className={styles.tableExpandedRow}>
|
|
107
|
-
<ImportOverview
|
|
108
|
-
selectedImportObject={prevImports.find((importItem: Import) => importItem.uuid === row.id)}
|
|
109
|
-
/>
|
|
110
|
-
</TableExpandedRow>
|
|
111
|
-
)}
|
|
112
|
-
</Fragment>
|
|
113
|
-
))}
|
|
114
|
-
</TableBody>
|
|
115
|
-
</Table>
|
|
116
|
-
)}
|
|
117
|
-
</DataTable>
|
|
118
|
-
<Pagination
|
|
119
|
-
className={styles.pagination}
|
|
120
|
-
size="sm"
|
|
121
|
-
page={currentPage}
|
|
122
|
-
pageSize={pageSize}
|
|
123
|
-
pageSizes={[10, 20, 50, 100]}
|
|
124
|
-
totalItems={prevImports.length}
|
|
125
|
-
onChange={({ page, pageSize }) => {
|
|
126
|
-
goTo(page);
|
|
127
|
-
setPageSize(pageSize);
|
|
128
|
-
}}
|
|
129
|
-
/>
|
|
130
|
-
</Column>
|
|
131
|
-
</Grid>
|
|
132
|
-
)
|
|
133
|
-
);
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
export default PreviousImports;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
2
|
-
import useSWR from 'swr';
|
|
3
|
-
import { Import } from '../types';
|
|
4
|
-
|
|
5
|
-
export function usePreviousImports() {
|
|
6
|
-
const { data, error, isValidating } = useSWR<{ data: { results: Import[] } }, Error>(
|
|
7
|
-
'/ws/rest/v1/openconceptlab/import?v=full',
|
|
8
|
-
openmrsFetch,
|
|
9
|
-
);
|
|
10
|
-
|
|
11
|
-
return {
|
|
12
|
-
data: data?.data?.results,
|
|
13
|
-
isLoading: !data && !error,
|
|
14
|
-
isError: error,
|
|
15
|
-
isValidating,
|
|
16
|
-
};
|
|
17
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { screen, waitFor } from '@testing-library/react';
|
|
3
|
-
import { formatDatetime, openmrsFetch, usePagination } from '@openmrs/esm-framework';
|
|
4
|
-
import { renderWithSwr } from '../../../../tools/test-helpers';
|
|
5
|
-
import { mockPreviousImports } from '../../../../__mocks__/openconceptlab.mock';
|
|
6
|
-
import { Import } from '../types';
|
|
7
|
-
import PreviousImports from './previous-imports.component';
|
|
8
|
-
|
|
9
|
-
const mockOpenmrsFetch = openmrsFetch as jest.Mock;
|
|
10
|
-
const mockUsePagination = usePagination as jest.Mock;
|
|
11
|
-
|
|
12
|
-
jest.mock('@openmrs/esm-framework', () => {
|
|
13
|
-
const originalModule = jest.requireActual('@openmrs/esm-framework');
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
...originalModule,
|
|
17
|
-
usePagination: jest.fn(),
|
|
18
|
-
};
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
describe(`Previous Imports component`, () => {
|
|
22
|
-
afterEach(() => {
|
|
23
|
-
mockUsePagination.mockReset();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it(`renders without dying`, () => {
|
|
27
|
-
mockUsePagination.mockReturnValue({
|
|
28
|
-
currentPage: 1,
|
|
29
|
-
goTo: () => {},
|
|
30
|
-
results: [],
|
|
31
|
-
});
|
|
32
|
-
renderPreviousImportsComponent();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it(`renders the table`, async () => {
|
|
36
|
-
mockOpenmrsFetch.mockReturnValueOnce({ data: { results: [] } });
|
|
37
|
-
mockUsePagination.mockReturnValue({
|
|
38
|
-
currentPage: 1,
|
|
39
|
-
goTo: () => {},
|
|
40
|
-
results: [],
|
|
41
|
-
});
|
|
42
|
-
renderPreviousImportsComponent();
|
|
43
|
-
await waitForLoadingToFinish();
|
|
44
|
-
|
|
45
|
-
expect(screen.getByText('Previous Imports')).toBeVisible();
|
|
46
|
-
expect(screen.getByText('Date and Time')).toBeVisible();
|
|
47
|
-
expect(screen.getByText('Duration')).toBeVisible();
|
|
48
|
-
expect(screen.getByText('Status')).toBeVisible();
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it(`renders the previous imports correctly`, async () => {
|
|
52
|
-
mockOpenmrsFetch.mockReturnValueOnce({ data: { results: mockPreviousImports } });
|
|
53
|
-
mockUsePagination.mockReturnValue({
|
|
54
|
-
currentPage: 1,
|
|
55
|
-
goTo: () => {},
|
|
56
|
-
results: mockPreviousImports,
|
|
57
|
-
});
|
|
58
|
-
renderPreviousImportsComponent();
|
|
59
|
-
await waitForLoadingToFinish();
|
|
60
|
-
|
|
61
|
-
mockPreviousImports.forEach((item: Import) => {
|
|
62
|
-
expect(screen.getByText(formatDatetime(item.localDateStarted))).toBeVisible();
|
|
63
|
-
expect(screen.getByText(item.importTime)).toBeVisible();
|
|
64
|
-
expect(screen.getByText(item.status)).toBeVisible();
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
function renderPreviousImportsComponent() {
|
|
70
|
-
renderWithSwr(<PreviousImports />);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function waitForLoadingToFinish() {
|
|
74
|
-
return waitFor(() => {
|
|
75
|
-
expect(screen.getByText('Previous Imports')).toBeVisible(), { timeout: 2000 };
|
|
76
|
-
});
|
|
77
|
-
}
|