@openmrs/esm-stock-management-app 3.0.1-pre.853 → 3.0.1-pre.855
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/.husky/pre-commit +1 -4
- package/__mocks__/react-i18next.js +9 -8
- package/dist/10.js +1 -1
- package/dist/10.js.map +1 -1
- package/dist/119.js +1 -1
- package/dist/119.js.map +1 -1
- package/dist/14.js +1 -1
- package/dist/14.js.map +1 -1
- package/dist/172.js +1 -1
- package/dist/172.js.map +1 -1
- package/dist/20.js +1 -1
- package/dist/20.js.map +1 -1
- package/dist/290.js +1 -1
- package/dist/290.js.map +1 -1
- package/dist/467.js +1 -1
- package/dist/467.js.map +1 -1
- package/dist/574.js +1 -1
- package/dist/606.js +1 -1
- package/dist/606.js.map +1 -1
- package/dist/627.js +1 -0
- package/dist/627.js.map +1 -0
- package/dist/642.js +1 -1
- package/dist/642.js.map +1 -1
- package/dist/675.js +1 -1
- package/dist/675.js.map +1 -1
- package/dist/727.js +1 -1
- package/dist/727.js.map +1 -1
- package/dist/842.js +1 -1
- package/dist/842.js.map +1 -1
- package/dist/93.js +1 -1
- package/dist/93.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-stock-management-app.js.buildmanifest.json +70 -70
- package/dist/routes.json +1 -1
- package/jest.config.js +3 -6
- package/package.json +1 -1
- package/src/core/components/table/table.component.tsx +2 -2
- package/src/index.ts +5 -5
- package/src/stock-items/add-bulk-stock-item/add-stock-items-bulk-import-action-button.component.tsx +3 -3
- package/src/stock-items/add-bulk-stock-item/{stock-items-bulk-import.modal.tsx → stock-items-bulk-import.component.tsx} +19 -20
- package/src/stock-items/add-bulk-stock-item/stock-items-bulk-import.resource.ts +1 -1
- package/src/stock-items/add-bulk-stock-item/stock-items-bulk-import.test.tsx +59 -59
- package/src/stock-items/add-stock-item/add-stock-action-button.component.tsx +6 -6
- package/src/stock-items/add-stock-item/add-stock-item.component.tsx +4 -6
- package/src/stock-items/add-stock-item/add-stock-item.scss +0 -5
- package/src/stock-items/add-stock-item/add-stock-item.test.tsx +43 -28
- package/src/stock-items/add-stock-item/packaging-units/packaging-units-delete-modal.component.tsx +4 -3
- package/src/stock-items/add-stock-item/packaging-units/packaging-units.component.tsx +10 -9
- package/src/stock-items/add-stock-item/packaging-units/packaging-units.scss +4 -4
- package/src/stock-items/add-stock-item/stock-item-details/stock-item-details.component.tsx +19 -27
- package/src/stock-items/add-stock-item/stock-item-references/stock-item-references.scss +4 -4
- package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rules.component.tsx +9 -15
- package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rules.scss +0 -1
- package/src/stock-items/add-stock-item/stock-item-rules/delete-stock-rule-modal.component.tsx +1 -2
- package/src/stock-items/add-stock-item/stock-item-rules/stock-item-rules.component.tsx +16 -14
- package/src/stock-items/add-stock-item/stock-item-rules/stock-item-rules.scss +3 -7
- package/src/stock-items/add-stock-item/transactions/printout/transactions-print-bincard-preview.modal.tsx +6 -14
- package/src/stock-items/add-stock-item/transactions/printout/transactions-print-stockcard-preview.modal.tsx +8 -14
- package/src/stock-items/edit-stock-item/edit-stock-item-action-menu.component.tsx +2 -2
- package/src/stock-items/stock-item.utils.tsx +5 -3
- package/src/stock-items/stock-items-table.component.tsx +45 -47
- package/src/stock-items/stock-items-table.resource.ts +2 -2
- package/src/stock-items/stock-items-table.scss +1 -5
- package/src/stock-items/stock-items-table.test.tsx +65 -106
- package/src/stock-locations/location-admin-form.component.tsx +4 -5
- package/src/stock-locations/stock-locations-table.component.tsx +8 -10
- package/src/stock-lookups/stock-lookups.resource.ts +2 -3
- package/src/stock-operations/stock-operations-dialog/stock-operations-dialog.component.tsx +2 -2
- package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.component.tsx +11 -11
- package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.test.tsx +25 -115
- package/src/stock-operations/stock-operations-forms/input-components/qty-uim-selector.test.tsx +65 -107
- package/src/stock-operations/stock-operations-forms/input-components/quantity-uom-selector.component.tsx +9 -9
- package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.test.tsx +153 -35
- package/src/stock-operations/stock-operations-forms/input-components/user-selector.test.tsx +29 -82
- package/src/stock-operations/stock-operations-forms/step1.test.tsx +69 -204
- package/src/stock-operations/stock-operations-forms/step2.test.tsx +63 -140
- package/src/stock-operations/stock-operations-forms/step3.test.tsx +60 -79
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.component.tsx +5 -6
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-submission-form-step.component.tsx +11 -12
- package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.scss +0 -1
- package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.workspace.tsx +12 -20
- package/src/stock-operations/stock-operations-forms/stock-operation-form.scss +0 -1
- package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stepper.scss +3 -1
- package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stock-operation-stepper.component.tsx +1 -2
- package/src/stock-reports/generate-report/create-stock-report.scss +2 -3
- package/src/stock-reports/generate-report/create-stock-report.workspace.tsx +25 -32
- package/src/stock-reports/report-list/stock-report-parameters.component.tsx +1 -1
- package/src/stock-reports/report-list/stock-report-status.component.tsx +1 -1
- package/src/stock-reports/report-list/stock-reports.component.tsx +25 -24
- package/src/stock-reports/report-list/stock-reports.scss +2 -10
- package/src/stock-sources/add-stock-sources/add-stock-sources.scss +4 -11
- package/src/stock-sources/add-stock-sources/add-stock-sources.test.tsx +36 -38
- package/src/stock-sources/add-stock-sources/add-stock-sources.workspace.tsx +30 -35
- package/src/stock-sources/delete-stock-modal.component.tsx +1 -2
- package/src/stock-sources/stock-sources-delete/stock-sources-delete.test.tsx +36 -27
- package/src/stock-sources/stock-sources-filter/stock-sources-filter.component.tsx +21 -33
- package/src/stock-sources/stock-sources-items-table.component.tsx +17 -16
- package/src/stock-sources/stock-sources-items-table.resource.ts +6 -8
- package/src/stock-sources/stock-sources-items-table.test.tsx +37 -60
- package/src/stock-sources/stock-sources.scss +2 -6
- package/src/stock-user-role-scopes/add-stock-user-scope/add-stock-user-role-scope.scss +13 -5
- package/src/stock-user-role-scopes/add-stock-user-scope/add-stock-user-role-scope.workspace.tsx +2 -2
- package/src/stock-user-role-scopes/delete-stock-user-scope-modal.component.tsx +1 -2
- package/translations/en.json +6 -5
- package/tsconfig.json +0 -4
- package/dist/33.js +0 -1
- package/dist/33.js.map +0 -1
@@ -1,105 +1,105 @@
|
|
1
1
|
import React from 'react';
|
2
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
2
3
|
import userEvent from '@testing-library/user-event';
|
3
|
-
import
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
import ImportBulkStockItemsModal from './stock-items-bulk-import.modal';
|
4
|
+
import ImportDialogPopup from './stock-items-bulk-import.component';
|
5
|
+
import { showSnackbar } from '@openmrs/esm-framework';
|
6
|
+
import { UploadStockItems } from './stock-items-bulk-import.resource';
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
jest.mock('@openmrs/esm-framework', () => ({
|
9
|
+
showSnackbar: jest.fn(),
|
10
|
+
}));
|
10
11
|
|
11
12
|
jest.mock('./stock-items-bulk-import.resource', () => ({
|
12
|
-
|
13
|
+
UploadStockItems: jest.fn(),
|
13
14
|
}));
|
14
15
|
|
15
|
-
describe('
|
16
|
+
describe('ImportDialogPopup', () => {
|
16
17
|
const mockCloseModal = jest.fn();
|
17
18
|
|
19
|
+
beforeEach(() => {
|
20
|
+
jest.clearAllMocks();
|
21
|
+
});
|
22
|
+
|
18
23
|
it('renders with initial state and UI elements', () => {
|
19
|
-
render(<
|
24
|
+
render(<ImportDialogPopup closeModal={mockCloseModal} />);
|
20
25
|
|
21
|
-
expect(screen.getByText(
|
22
|
-
expect(screen.getByRole('button', { name:
|
23
|
-
expect(screen.getByText(
|
24
|
-
expect(screen.getByRole('button', { name:
|
25
|
-
expect(screen.getByRole('button', { name:
|
26
|
+
expect(screen.getByText('Import Stock Items')).toBeInTheDocument();
|
27
|
+
expect(screen.getByRole('button', { name: 'Select file' })).toBeInTheDocument();
|
28
|
+
expect(screen.getByText('Only .csv files at 2mb or less')).toBeInTheDocument();
|
29
|
+
expect(screen.getByRole('button', { name: 'Cancel' })).toBeInTheDocument();
|
30
|
+
expect(screen.getByRole('button', { name: 'Upload StockItems' })).toBeInTheDocument();
|
26
31
|
});
|
27
32
|
|
28
33
|
it('allows only CSV files', async () => {
|
29
|
-
render(<
|
34
|
+
render(<ImportDialogPopup closeModal={mockCloseModal} />);
|
30
35
|
|
31
|
-
const fileInput = screen.getByLabelText(
|
36
|
+
const fileInput = screen.getByLabelText('Select file') as HTMLInputElement;
|
32
37
|
expect(fileInput.accept).toBe('.csv');
|
33
38
|
});
|
34
39
|
|
35
40
|
it('closes modal when cancel button is clicked', async () => {
|
36
|
-
|
37
|
-
|
41
|
+
render(<ImportDialogPopup closeModal={mockCloseModal} />);
|
42
|
+
|
43
|
+
const cancelButton = screen.getByRole('button', { name: 'Cancel' });
|
44
|
+
await userEvent.click(cancelButton);
|
38
45
|
|
39
|
-
const cancelButton = screen.getByRole('button', { name: /cancel/i });
|
40
|
-
await user.click(cancelButton);
|
41
46
|
expect(mockCloseModal).toHaveBeenCalledTimes(1);
|
42
47
|
});
|
43
48
|
|
44
49
|
it('does nothing when upload is clicked without a file', async () => {
|
45
|
-
|
46
|
-
render(<ImportBulkStockItemsModal closeModal={mockCloseModal} />);
|
50
|
+
render(<ImportDialogPopup closeModal={mockCloseModal} />);
|
47
51
|
|
48
|
-
const uploadButton = screen.getByRole('button', { name:
|
49
|
-
await
|
52
|
+
const uploadButton = screen.getByRole('button', { name: 'Upload StockItems' });
|
53
|
+
await userEvent.click(uploadButton);
|
50
54
|
|
51
|
-
expect(
|
52
|
-
expect(
|
55
|
+
expect(UploadStockItems).not.toHaveBeenCalled();
|
56
|
+
expect(showSnackbar).not.toHaveBeenCalled();
|
53
57
|
expect(mockCloseModal).not.toHaveBeenCalled();
|
54
58
|
});
|
55
59
|
|
56
60
|
it('uploads file successfully and shows success snackbar', async () => {
|
57
|
-
|
58
|
-
|
59
|
-
mockUploadStockItems.mockResolvedValue({
|
60
|
-
data: {},
|
61
|
-
status: 200,
|
62
|
-
ok: true,
|
63
|
-
} as FetchResponse<unknown>);
|
64
|
-
render(<ImportBulkStockItemsModal closeModal={mockCloseModal} />);
|
61
|
+
(UploadStockItems as jest.Mock).mockResolvedValue({});
|
62
|
+
render(<ImportDialogPopup closeModal={mockCloseModal} />);
|
65
63
|
|
66
64
|
const validFile = new File(['test content'], 'valid.csv', { type: 'text/csv' });
|
67
65
|
const fileInput = screen.getByLabelText('Select file') as HTMLInputElement;
|
68
66
|
await userEvent.upload(fileInput, validFile);
|
69
67
|
|
70
|
-
const uploadButton = screen.getByRole('button', { name:
|
71
|
-
await
|
72
|
-
|
73
|
-
expect(
|
74
|
-
|
75
|
-
expect.
|
76
|
-
|
77
|
-
|
78
|
-
|
68
|
+
const uploadButton = screen.getByRole('button', { name: 'Upload StockItems' });
|
69
|
+
await userEvent.click(uploadButton);
|
70
|
+
|
71
|
+
await waitFor(() => expect(UploadStockItems).toHaveBeenCalled());
|
72
|
+
await waitFor(() =>
|
73
|
+
expect(showSnackbar).toHaveBeenCalledWith(
|
74
|
+
expect.objectContaining({
|
75
|
+
kind: 'success',
|
76
|
+
title: 'Uploaded Order',
|
77
|
+
}),
|
78
|
+
),
|
79
79
|
);
|
80
|
-
expect(mockCloseModal).toHaveBeenCalledTimes(1);
|
80
|
+
await waitFor(() => expect(mockCloseModal).toHaveBeenCalledTimes(1));
|
81
81
|
});
|
82
82
|
|
83
83
|
it('shows error snackbar on upload failure', async () => {
|
84
|
-
|
85
|
-
|
86
|
-
mockUploadStockItems.mockRejectedValue(new Error('Upload failed'));
|
87
|
-
render(<ImportBulkStockItemsModal closeModal={mockCloseModal} />);
|
84
|
+
(UploadStockItems as jest.Mock).mockRejectedValue(new Error('Upload failed'));
|
85
|
+
render(<ImportDialogPopup closeModal={mockCloseModal} />);
|
88
86
|
|
89
87
|
const validFile = new File(['test content'], 'valid.csv', { type: 'text/csv' });
|
90
|
-
const fileInput = screen.getByLabelText(
|
88
|
+
const fileInput = screen.getByLabelText('Select file') as HTMLInputElement;
|
91
89
|
await userEvent.upload(fileInput, validFile);
|
92
90
|
|
93
|
-
const uploadButton = screen.getByRole('button', { name:
|
94
|
-
await
|
95
|
-
|
96
|
-
expect(
|
97
|
-
|
98
|
-
expect.
|
99
|
-
|
100
|
-
|
101
|
-
|
91
|
+
const uploadButton = screen.getByRole('button', { name: 'Upload StockItems' });
|
92
|
+
await userEvent.click(uploadButton);
|
93
|
+
|
94
|
+
await waitFor(() => expect(UploadStockItems).toHaveBeenCalled());
|
95
|
+
await waitFor(() =>
|
96
|
+
expect(showSnackbar).toHaveBeenCalledWith(
|
97
|
+
expect.objectContaining({
|
98
|
+
kind: 'error',
|
99
|
+
title: 'An error occurred uploading stock items',
|
100
|
+
}),
|
101
|
+
),
|
102
102
|
);
|
103
|
-
expect(mockCloseModal).not.toHaveBeenCalled();
|
103
|
+
await waitFor(() => expect(mockCloseModal).not.toHaveBeenCalled());
|
104
104
|
});
|
105
105
|
});
|
@@ -1,18 +1,18 @@
|
|
1
|
+
import { Button } from '@carbon/react';
|
1
2
|
import React, { useCallback } from 'react';
|
2
3
|
import { useTranslation } from 'react-i18next';
|
3
|
-
import {
|
4
|
-
import { launchAddOrEditStockItemWorkspace } from '../stock-item.utils';
|
4
|
+
import { launchAddOrStockItemWorkspace } from '../stock-item.utils';
|
5
5
|
|
6
6
|
const AddStockItemActionButton: React.FC = () => {
|
7
7
|
const { t } = useTranslation();
|
8
8
|
|
9
|
-
const
|
10
|
-
|
9
|
+
const handleClick = useCallback(() => {
|
10
|
+
launchAddOrStockItemWorkspace(t);
|
11
11
|
}, [t]);
|
12
12
|
|
13
13
|
return (
|
14
|
-
<Button onClick={
|
15
|
-
{t('
|
14
|
+
<Button onClick={handleClick} size="md" kind="primary">
|
15
|
+
{t('addNewStock', 'Add New')}
|
16
16
|
</Button>
|
17
17
|
);
|
18
18
|
};
|
@@ -1,15 +1,15 @@
|
|
1
|
+
import { type DefaultWorkspaceProps } from '@openmrs/esm-framework';
|
1
2
|
import React, { useState } from 'react';
|
2
3
|
import { useTranslation } from 'react-i18next';
|
3
|
-
import { type DefaultWorkspaceProps } from '@openmrs/esm-framework';
|
4
4
|
import { type StockItemDTO } from '../../core/api/types/stockItem/StockItem';
|
5
5
|
import { type TabItem } from '../../core/components/tabs/types';
|
6
|
+
import StockOperationStepper from '../../stock-operations/stock-operations-forms/stock-operation-stepper/stock-operation-stepper.component';
|
6
7
|
import BatchInformation from './batch-information/batch-information.component';
|
7
8
|
import PackagingUnits from './packaging-units/packaging-units.component';
|
8
|
-
import StockItemDetails from './stock-item-details/stock-item-details.component';
|
9
|
-
import StockItemRules from './stock-item-rules/stock-item-rules.component';
|
10
|
-
import StockOperationStepper from '../../stock-operations/stock-operations-forms/stock-operation-stepper/stock-operation-stepper.component';
|
11
9
|
import StockQuantities from './quantities/quantities.component';
|
10
|
+
import StockItemDetails from './stock-item-details/stock-item-details.component';
|
12
11
|
import StockReferences from './stock-item-references/stock-item-references.component';
|
12
|
+
import StockItemRules from './stock-item-rules/stock-item-rules.component';
|
13
13
|
import Transactions from './transactions/transactions.component';
|
14
14
|
|
15
15
|
interface AddStockItemProps extends Partial<DefaultWorkspaceProps> {
|
@@ -20,11 +20,9 @@ const AddEditStockItem: React.FC<AddStockItemProps> = ({ stockItem, closeWorkspa
|
|
20
20
|
const { t } = useTranslation();
|
21
21
|
const [selectedTab, setSelectedTab] = useState(0);
|
22
22
|
const isEditing = Boolean(stockItem);
|
23
|
-
|
24
23
|
const handleTabChange = (index: number) => {
|
25
24
|
setSelectedTab(index);
|
26
25
|
};
|
27
|
-
|
28
26
|
const tabs: TabItem[] = [
|
29
27
|
{
|
30
28
|
name: t('stockItemDetails', 'Stock Item Details'),
|
@@ -11,7 +11,6 @@
|
|
11
11
|
}
|
12
12
|
|
13
13
|
.button {
|
14
|
-
height: layout.$spacing-10;
|
15
14
|
display: flex;
|
16
15
|
align-content: flex-start;
|
17
16
|
align-items: baseline;
|
@@ -23,7 +22,3 @@
|
|
23
22
|
justify-content: space-between;
|
24
23
|
width: 100%;
|
25
24
|
}
|
26
|
-
|
27
|
-
.stack {
|
28
|
-
margin: layout.$spacing-05;
|
29
|
-
}
|
@@ -1,8 +1,22 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import userEvent from '@testing-library/user-event';
|
3
2
|
import { render, screen } from '@testing-library/react';
|
4
|
-
import
|
3
|
+
import userEvent from '@testing-library/user-event';
|
5
4
|
import AddEditStockItem from './add-stock-item.component';
|
5
|
+
import { type StockItemDTO } from '../../core/api/types/stockItem/StockItem';
|
6
|
+
|
7
|
+
// Mock components
|
8
|
+
jest.mock('react-i18next', () => ({
|
9
|
+
useTranslation: () => ({
|
10
|
+
t: (key) => key,
|
11
|
+
}),
|
12
|
+
}));
|
13
|
+
jest.mock('@carbon/react', () => {
|
14
|
+
const originalModule = jest.requireActual('@carbon/react');
|
15
|
+
return {
|
16
|
+
...originalModule,
|
17
|
+
useMatchMedia: jest.fn().mockReturnValue(false),
|
18
|
+
};
|
19
|
+
});
|
6
20
|
|
7
21
|
jest.mock('@carbon/react/icons', () => ({
|
8
22
|
Save: () => <div>Save Icon</div>,
|
@@ -115,11 +129,11 @@ describe('AddEditStockItem', () => {
|
|
115
129
|
const user = userEvent.setup();
|
116
130
|
render(<AddEditStockItem stockItem={mockModel} />);
|
117
131
|
|
118
|
-
await user.click(screen.getByText(
|
132
|
+
await user.click(screen.getByText('packagingUnits'));
|
119
133
|
expect(screen.getByTestId('packaging-units')).toBeInTheDocument();
|
120
134
|
expect(screen.getByText('Packaging Units: test-uuid-123')).toBeInTheDocument();
|
121
135
|
|
122
|
-
await user.click(screen.getByText(
|
136
|
+
await user.click(screen.getByText('transactions'));
|
123
137
|
expect(screen.getByTestId('transactions')).toBeInTheDocument();
|
124
138
|
expect(screen.getByText('Transactions: test-uuid-123')).toBeInTheDocument();
|
125
139
|
});
|
@@ -128,12 +142,12 @@ describe('AddEditStockItem', () => {
|
|
128
142
|
render(<AddEditStockItem />);
|
129
143
|
|
130
144
|
const disabledTabs = [
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
145
|
+
'packagingUnits',
|
146
|
+
'transactions',
|
147
|
+
'batchInformation',
|
148
|
+
'quantities',
|
149
|
+
'stockRules',
|
150
|
+
'references',
|
137
151
|
];
|
138
152
|
disabledTabs.forEach((tabName) => {
|
139
153
|
const tab = screen.getByRole('button', { name: tabName });
|
@@ -145,12 +159,12 @@ describe('AddEditStockItem', () => {
|
|
145
159
|
render(<AddEditStockItem stockItem={mockModel} />);
|
146
160
|
|
147
161
|
const enabledTabs = [
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
162
|
+
'packagingUnits',
|
163
|
+
'transactions',
|
164
|
+
'batchInformation',
|
165
|
+
'quantities',
|
166
|
+
'stockRules',
|
167
|
+
'references',
|
154
168
|
];
|
155
169
|
enabledTabs.forEach((tabName) => {
|
156
170
|
const tab = screen.getByRole('button', { name: tabName });
|
@@ -164,22 +178,22 @@ describe('AddEditStockItem', () => {
|
|
164
178
|
|
165
179
|
expect(screen.getByText('Stock Item Details: test-uuid-123')).toBeInTheDocument();
|
166
180
|
|
167
|
-
await user.click(screen.getByText(
|
181
|
+
await user.click(screen.getByText('packagingUnits'));
|
168
182
|
expect(screen.getByText('Packaging Units: test-uuid-123')).toBeInTheDocument();
|
169
183
|
|
170
|
-
await user.click(screen.getByText(
|
184
|
+
await user.click(screen.getByText('transactions'));
|
171
185
|
expect(screen.getByText('Transactions: test-uuid-123')).toBeInTheDocument();
|
172
186
|
|
173
|
-
await user.click(screen.getByText(
|
187
|
+
await user.click(screen.getByText('batchInformation'));
|
174
188
|
expect(screen.getByText('Batch Information: test-uuid-123')).toBeInTheDocument();
|
175
189
|
|
176
|
-
await user.click(screen.getByText(
|
190
|
+
await user.click(screen.getByText('quantities'));
|
177
191
|
expect(screen.getByText('Quantities: test-uuid-123')).toBeInTheDocument();
|
178
192
|
|
179
|
-
await user.click(screen.getByText(
|
193
|
+
await user.click(screen.getByText('stockRules'));
|
180
194
|
expect(screen.getByText('Rules: test-uuid-123')).toBeInTheDocument();
|
181
195
|
|
182
|
-
await user.click(screen.getByText(
|
196
|
+
await user.click(screen.getByText('references'));
|
183
197
|
expect(screen.getByText('References: test-uuid-123')).toBeInTheDocument();
|
184
198
|
});
|
185
199
|
|
@@ -187,12 +201,13 @@ describe('AddEditStockItem', () => {
|
|
187
201
|
render(<AddEditStockItem stockItem={mockModel} />);
|
188
202
|
|
189
203
|
const tabNames = [
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
204
|
+
'stockItemDetails',
|
205
|
+
'packagingUnits',
|
206
|
+
'transactions',
|
207
|
+
'batchInformation',
|
208
|
+
'quantities',
|
209
|
+
'stockRules',
|
210
|
+
'references',
|
196
211
|
];
|
197
212
|
tabNames.forEach((tabName) => {
|
198
213
|
expect(screen.getByText(tabName)).toBeInTheDocument();
|
package/src/stock-items/add-stock-item/packaging-units/packaging-units-delete-modal.component.tsx
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
import React, { useState, useEffect } from 'react';
|
2
|
-
import {
|
2
|
+
import { showSnackbar } from '@openmrs/esm-framework';
|
3
3
|
import { Button, ModalHeader, ModalBody, ModalFooter, TextArea } from '@carbon/react';
|
4
|
-
import { showSnackbar, getCoreTranslation } from '@openmrs/esm-framework';
|
5
|
-
import { type StockItemPackagingUOMDTO } from '../../../core/api/types/stockItem/StockItemPackagingUOM';
|
6
4
|
import { deleteStockItemPackagingUnit } from '../../stock-items.resource';
|
7
5
|
import { useStockItemPackageUnitsHook } from './packaging-units.resource';
|
6
|
+
import { useTranslation } from 'react-i18next';
|
7
|
+
import { type StockItemPackagingUOMDTO } from '../../../core/api/types/stockItem/StockItemPackagingUOM';
|
8
|
+
|
8
9
|
import styles from '../packaging-units/packaging-units.scss';
|
9
10
|
|
10
11
|
interface DeletePackagingUnitProps {
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import React, { useEffect, useMemo, useState } from 'react';
|
2
1
|
import {
|
3
2
|
Button,
|
4
3
|
DataTable,
|
@@ -13,17 +12,19 @@ import {
|
|
13
12
|
} from '@carbon/react';
|
14
13
|
import { Save } from '@carbon/react/icons';
|
15
14
|
import { zodResolver } from '@hookform/resolvers/zod';
|
15
|
+
import { restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
|
16
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
16
17
|
import { FormProvider, useForm, useFormContext } from 'react-hook-form';
|
17
18
|
import { useTranslation } from 'react-i18next';
|
18
|
-
import { getCoreTranslation, restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
|
19
|
-
import { createStockItemPackagingUnit, updateStockItemPackagingUnit } from '../../stock-items.resource';
|
20
|
-
import { handleMutate } from '../../../utils';
|
21
|
-
import { type PackageUnitFormData, packageUnitSchema } from './validationSchema';
|
22
19
|
import { type StockItemPackagingUOMDTO } from '../../../core/api/types/stockItem/StockItemPackagingUOM';
|
23
|
-
import { useStockItemPackageUnitsHook } from './packaging-units.resource';
|
24
20
|
import ControlledNumberInput from '../../../core/components/carbon/controlled-number-input/controlled-number-input.component';
|
25
|
-
import
|
21
|
+
import { handleMutate } from '../../../utils';
|
22
|
+
import { createStockItemPackagingUnit, updateStockItemPackagingUnit } from '../../stock-items.resource';
|
26
23
|
import PackagingUnitsConceptSelector from '../packaging-units-concept-selector/packaging-units-concept-selector.component';
|
24
|
+
import DeleteModalButton from './packaging-units-delete-modal-button.component';
|
25
|
+
import { useStockItemPackageUnitsHook } from './packaging-units.resource';
|
26
|
+
import { type PackageUnitFormData, packageUnitSchema } from './validationSchema';
|
27
|
+
|
27
28
|
import styles from './packaging-units.scss';
|
28
29
|
|
29
30
|
interface PackagingUnitsProps {
|
@@ -235,7 +236,7 @@ const PackagingUnits: React.FC<PackagingUnitsProps> = ({ stockItemUuid, handleTa
|
|
235
236
|
/>
|
236
237
|
<div className={styles.packageUnitsBtn}>
|
237
238
|
<Button kind="secondary" onClick={handleCancelPackagingUnits}>
|
238
|
-
{
|
239
|
+
{t('cancel', 'Cancel')}
|
239
240
|
</Button>
|
240
241
|
<Button
|
241
242
|
name="save"
|
@@ -245,7 +246,7 @@ const PackagingUnits: React.FC<PackagingUnitsProps> = ({ stockItemUuid, handleTa
|
|
245
246
|
kind="primary"
|
246
247
|
renderIcon={Save}
|
247
248
|
>
|
248
|
-
{
|
249
|
+
{t('save', 'Save')}
|
249
250
|
</Button>
|
250
251
|
</div>
|
251
252
|
</FormProvider>
|
@@ -1,6 +1,6 @@
|
|
1
|
-
@use '@carbon/colors';
|
2
|
-
@use '@carbon/
|
3
|
-
@use '@carbon/type';
|
1
|
+
@use '@carbon/styles/scss/colors';
|
2
|
+
@use '@carbon/styles/scss/spacing';
|
3
|
+
@use '@carbon/styles/scss/type';
|
4
4
|
|
5
5
|
.packingTable {
|
6
6
|
min-height: 15rem;
|
@@ -13,7 +13,7 @@
|
|
13
13
|
}
|
14
14
|
|
15
15
|
.packagingTableBody {
|
16
|
-
min-height:
|
16
|
+
min-height: spacing.$spacing-13;
|
17
17
|
}
|
18
18
|
|
19
19
|
.packagingTableContainer {
|
@@ -1,27 +1,26 @@
|
|
1
|
-
import
|
2
|
-
import classNames from 'classnames';
|
3
|
-
import { Button, ButtonSet, FormGroup, InlineLoading, Stack } from '@carbon/react';
|
1
|
+
import { Button, ButtonSet, FormGroup, InlineLoading } from '@carbon/react';
|
4
2
|
import { Save } from '@carbon/react/icons';
|
5
3
|
import { zodResolver } from '@hookform/resolvers/zod';
|
4
|
+
import { restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
|
5
|
+
import React, { forwardRef, useMemo } from 'react';
|
6
6
|
import { type SubmitHandler, useForm } from 'react-hook-form';
|
7
7
|
import { useTranslation } from 'react-i18next';
|
8
|
-
import { getCoreTranslation, restBaseUrl, showSnackbar, useLayoutType } from '@openmrs/esm-framework';
|
9
|
-
import { createStockItem, updateStockItem } from '../../stock-items.resource';
|
10
|
-
import { expirationOptions, radioOptions, StockItemType } from './stock-item-details.resource';
|
11
|
-
import { handleMutate } from '../../../utils';
|
12
|
-
import { launchAddOrEditStockItemWorkspace } from '../../stock-item.utils';
|
13
|
-
import { stockItemDetailsSchema, type StockItemFormData } from '../../validationSchema';
|
14
8
|
import { type StockItemDTO } from '../../../core/api/types/stockItem/StockItem';
|
15
|
-
import ConceptsSelector from '../concepts-selector/concepts-selector.component';
|
16
9
|
import ControlledNumberInput from '../../../core/components/carbon/controlled-number-input/controlled-number-input.component';
|
17
10
|
import ControlledRadioButtonGroup from '../../../core/components/carbon/controlled-radio-button-group/controlled-radio-button-group.component';
|
18
11
|
import ControlledTextInput from '../../../core/components/carbon/controlled-text-input/controlled-text-input.component';
|
12
|
+
import { handleMutate } from '../../../utils';
|
13
|
+
import styles from '../../add-stock-item/add-stock-item.scss';
|
14
|
+
import { launchAddOrStockItemWorkspace } from '../../stock-item.utils';
|
15
|
+
import { createStockItem, updateStockItem } from '../../stock-items.resource';
|
16
|
+
import { stockItemDetailsSchema, type StockItemFormData } from '../../validationSchema';
|
17
|
+
import ConceptsSelector from '../concepts-selector/concepts-selector.component';
|
19
18
|
import DispensingUnitSelector from '../dispensing-unit-selector/dispensing-unit-selector.component';
|
20
19
|
import DrugSelector from '../drug-selector/drug-selector.component';
|
21
20
|
import PreferredVendorSelector from '../preferred-vendor-selector/preferred-vendor-selector.component';
|
22
21
|
import StockItemCategorySelector from '../stock-item-category-selector/stock-item-category-selector.component';
|
23
22
|
import StockItemUnitsEdit from '../stock-item-units-edit/stock-item-units-edit.component';
|
24
|
-
import
|
23
|
+
import { expirationOptions, radioOptions, StockItemType } from './stock-item-details.resource';
|
25
24
|
|
26
25
|
interface StockItemDetailsProps {
|
27
26
|
stockItem?: StockItemDTO;
|
@@ -32,8 +31,6 @@ interface StockItemDetailsProps {
|
|
32
31
|
const StockItemDetails = forwardRef<never, StockItemDetailsProps>(
|
33
32
|
({ stockItem, handleTabChange, onCloseWorkspace }) => {
|
34
33
|
const { t } = useTranslation();
|
35
|
-
const isTablet = useLayoutType() === 'tablet';
|
36
|
-
|
37
34
|
const { handleSubmit, control, formState, watch } = useForm<StockItemFormData>({
|
38
35
|
defaultValues: stockItem ?? {},
|
39
36
|
mode: 'all',
|
@@ -60,7 +57,7 @@ const StockItemDetails = forwardRef<never, StockItemDetailsProps>(
|
|
60
57
|
// launch edit dialog
|
61
58
|
const item = response.data;
|
62
59
|
item.isDrug = !!item.drugUuid;
|
63
|
-
|
60
|
+
launchAddOrStockItemWorkspace(t, item);
|
64
61
|
}
|
65
62
|
}
|
66
63
|
|
@@ -87,7 +84,7 @@ const StockItemDetails = forwardRef<never, StockItemDetailsProps>(
|
|
87
84
|
|
88
85
|
return (
|
89
86
|
<form className={styles.formContainer}>
|
90
|
-
<
|
87
|
+
<div>
|
91
88
|
{!stockItem && (
|
92
89
|
<FormGroup
|
93
90
|
className="clear-margin-bottom"
|
@@ -230,25 +227,20 @@ const StockItemDetails = forwardRef<never, StockItemDetailsProps>(
|
|
230
227
|
{observableIsDrug && stockItem && (
|
231
228
|
<StockItemUnitsEdit control={control} formState={formState} stockItemUuid={stockItem?.uuid} />
|
232
229
|
)}
|
233
|
-
</
|
234
|
-
<ButtonSet
|
235
|
-
className={classNames(styles.buttonSet, {
|
236
|
-
[styles.tablet]: isTablet,
|
237
|
-
[styles.desktop]: !isTablet,
|
238
|
-
})}
|
239
|
-
>
|
230
|
+
</div>
|
231
|
+
<ButtonSet className={styles.buttonSet}>
|
240
232
|
<Button kind="secondary" onClick={onCloseWorkspace} className={styles.button}>
|
241
|
-
{
|
233
|
+
{t('cancel', 'Cancel')}
|
242
234
|
</Button>
|
243
235
|
<Button
|
244
|
-
className={styles.button}
|
245
|
-
kind="primary"
|
246
236
|
name="save"
|
237
|
+
type="button"
|
238
|
+
className={styles.button}
|
247
239
|
onClick={handleSubmit(handleSave)}
|
240
|
+
kind="primary"
|
248
241
|
renderIcon={Save}
|
249
|
-
type="button"
|
250
242
|
>
|
251
|
-
{formState.isSubmitting ? <InlineLoading /> :
|
243
|
+
{formState.isSubmitting ? <InlineLoading /> : t('save', 'Save')}
|
252
244
|
</Button>
|
253
245
|
</ButtonSet>
|
254
246
|
</form>
|
@@ -1,6 +1,6 @@
|
|
1
|
-
@use '@carbon/colors';
|
2
|
-
@use '@carbon/
|
3
|
-
@use '@carbon/type';
|
1
|
+
@use '@carbon/styles/scss/colors';
|
2
|
+
@use '@carbon/styles/scss/spacing';
|
3
|
+
@use '@carbon/styles/scss/type';
|
4
4
|
|
5
5
|
.referencesTable {
|
6
6
|
min-height: 15rem;
|
@@ -13,7 +13,7 @@
|
|
13
13
|
}
|
14
14
|
|
15
15
|
.referencesTableBody {
|
16
|
-
min-height:
|
16
|
+
min-height: spacing.$spacing-13;
|
17
17
|
}
|
18
18
|
|
19
19
|
.referencesTableContainer {
|
@@ -1,6 +1,3 @@
|
|
1
|
-
import React, { type ChangeEvent, useCallback, useEffect, useState } from 'react';
|
2
|
-
import classNames from 'classnames';
|
3
|
-
import { useTranslation } from 'react-i18next';
|
4
1
|
import {
|
5
2
|
Button,
|
6
3
|
ButtonSet,
|
@@ -12,13 +9,15 @@ import {
|
|
12
9
|
SelectItem,
|
13
10
|
TextInput,
|
14
11
|
} from '@carbon/react';
|
15
|
-
import { type DefaultWorkspaceProps,
|
16
|
-
import {
|
12
|
+
import { type DefaultWorkspaceProps, showSnackbar } from '@openmrs/esm-framework';
|
13
|
+
import React, { type ChangeEvent, useCallback, useEffect, useState } from 'react';
|
14
|
+
import { useTranslation } from 'react-i18next';
|
17
15
|
import { ResourceRepresentation } from '../../../core/api/api';
|
18
|
-
import { type StockItemInventoryFilter, useStockItemPackagingUOMs } from '../../stock-items.resource';
|
19
16
|
import { type StockRule } from '../../../core/api/types/stockItem/StockRule';
|
20
17
|
import { useRoles, useStockTagLocations } from '../../../stock-lookups/stock-lookups.resource';
|
18
|
+
import { type StockItemInventoryFilter, useStockItemPackagingUOMs } from '../../stock-items.resource';
|
21
19
|
import styles from './add-stock-rules.scss';
|
20
|
+
import { createOrUpdateStockRule } from './stock-rules.resource';
|
22
21
|
|
23
22
|
interface AddStockRuleProps extends Partial<DefaultWorkspaceProps> {
|
24
23
|
model?: StockRule;
|
@@ -27,7 +26,7 @@ interface AddStockRuleProps extends Partial<DefaultWorkspaceProps> {
|
|
27
26
|
|
28
27
|
const StockRulesAddOrUpdate: React.FC<AddStockRuleProps> = ({ model, stockItemUuid, closeWorkspace }) => {
|
29
28
|
const { t } = useTranslation();
|
30
|
-
|
29
|
+
|
31
30
|
const [stockItemFilter, setStockItemFilter] = useState<StockItemInventoryFilter>({
|
32
31
|
startIndex: 0,
|
33
32
|
v: ResourceRepresentation.Default,
|
@@ -316,17 +315,12 @@ const StockRulesAddOrUpdate: React.FC<AddStockRuleProps> = ({ model, stockItemUu
|
|
316
315
|
notification will only be sent once per specified notification frequency.
|
317
316
|
</div>
|
318
317
|
</div>
|
319
|
-
<ButtonSet
|
320
|
-
className={classNames(styles.buttonSet, {
|
321
|
-
[styles.tablet]: isTablet,
|
322
|
-
[styles.desktop]: !isTablet,
|
323
|
-
})}
|
324
|
-
>
|
318
|
+
<ButtonSet className={styles.buttonSet}>
|
325
319
|
<Button kind="secondary" onClick={closeWorkspace} className={styles.button}>
|
326
|
-
{
|
320
|
+
{t('cancel', 'Cancel')}
|
327
321
|
</Button>
|
328
322
|
<Button type="submit" className={styles.button}>
|
329
|
-
{
|
323
|
+
{t('save', 'Save')}
|
330
324
|
</Button>
|
331
325
|
</ButtonSet>
|
332
326
|
</Form>
|
package/src/stock-items/add-stock-item/stock-item-rules/delete-stock-rule-modal.component.tsx
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { useTranslation } from 'react-i18next';
|
3
3
|
import { Button, ModalHeader, ModalBody, ModalFooter } from '@carbon/react';
|
4
|
-
import { getCoreTranslation } from '@openmrs/esm-framework';
|
5
4
|
import styles from '../../../root.scss';
|
6
5
|
|
7
6
|
interface DeleteConfirmationProps {
|
@@ -31,7 +30,7 @@ const DeleteConfirmation: React.FC<DeleteConfirmationProps> = ({ close, onConfir
|
|
31
30
|
</ModalBody>
|
32
31
|
<ModalFooter>
|
33
32
|
<Button size="lg" kind="secondary" onClick={handleCancel}>
|
34
|
-
{
|
33
|
+
{t('cancel', 'Cancel')}
|
35
34
|
</Button>
|
36
35
|
<Button autoFocus kind="danger" onClick={handleDelete} size="lg">
|
37
36
|
{t('delete', 'Delete')}
|