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