@openmrs/esm-stock-management-app 3.1.1-pre.1177 → 3.1.1-pre.1184
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 +0 -5
- package/.husky/pre-push +0 -3
- package/dist/130.js +1 -1
- package/dist/130.js.map +1 -1
- package/dist/2177.js +1 -1
- package/dist/2177.js.map +1 -1
- package/dist/3220.js +1 -1
- package/dist/3220.js.map +1 -1
- package/dist/4300.js +1 -1
- package/dist/4732.js +1 -1
- package/dist/4732.js.map +1 -1
- package/dist/5125.js +1 -1
- package/dist/5125.js.map +1 -1
- package/dist/5333.js +1 -1
- package/dist/5333.js.map +1 -1
- package/dist/5609.js +1 -1
- package/dist/5609.js.map +1 -1
- package/dist/6184.js +1 -1
- package/dist/6184.js.map +1 -1
- package/dist/6757.js +1 -1
- package/dist/6757.js.map +1 -1
- package/dist/8161.js +1 -1
- package/dist/8161.js.map +1 -1
- package/dist/9186.js +1 -1
- package/dist/9186.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 +1 -1
- package/dist/openmrs-esm-stock-management-app.js.buildmanifest.json +42 -42
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/constants.ts +2 -3
- package/src/core/components/carbon/controlled-combo-box.component.tsx +12 -9
- package/src/core/components/carbon/controlled-radio-button-group.component.tsx +21 -16
- package/src/core/components/table/table.component.tsx +26 -17
- package/src/core/components/table/table.scss +4 -0
- package/src/core/components/table/types.ts +12 -0
- package/src/core/components/tabs/vertical-tabs.component.tsx +2 -6
- package/src/declarations.d.ts +0 -3
- package/src/stock-home/stock-home-inventory-card.component.tsx +2 -2
- package/src/stock-items/add-stock-item/add-stock-item.component.tsx +1 -1
- package/src/stock-items/add-stock-item/batch-information/batch-information-locations/batch-information-locations-filter.component.tsx +0 -3
- package/src/stock-items/add-stock-item/batch-information/batch-information.component.tsx +4 -4
- package/src/stock-items/add-stock-item/dispensing-package-measurement/dispensing-package-measurement.component.tsx +2 -5
- package/src/stock-items/add-stock-item/drug-selector/drug-selector.component.tsx +4 -8
- package/src/stock-items/add-stock-item/packaging-units/packaging-units-delete.modal.tsx +2 -2
- package/src/stock-items/add-stock-item/packaging-units/packaging-units.component.tsx +32 -18
- package/src/stock-items/add-stock-item/packaging-units-concept-selector/packaging-units-concept-selector.component.tsx +2 -5
- package/src/stock-items/add-stock-item/preferred-vendor-selector/preferred-vendor-selector.component.tsx +0 -3
- package/src/stock-items/add-stock-item/stock-item-category-selector/stock-item-category-selector.component.tsx +2 -5
- package/src/stock-items/add-stock-item/stock-item-details/stock-item-details.component.tsx +10 -10
- package/src/stock-items/add-stock-item/stock-item-references/stock-item-references.component.tsx +36 -27
- package/src/stock-items/add-stock-item/stock-item-references/stock-references-selector.component.tsx +2 -5
- package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rules.component.tsx +16 -16
- package/src/stock-items/add-stock-item/stock-item-rules/stock-item-rules.component.tsx +10 -9
- package/src/stock-items/add-stock-item/stock-item-rules/stock-rules-filter.component.tsx +8 -3
- package/src/stock-items/add-stock-item/stock-item-units-edit/stock-item-units-edit.component.tsx +2 -2
- package/src/stock-items/add-stock-item/transactions/printout/printable-bincard-transaction-header.component.tsx +5 -5
- package/src/stock-items/add-stock-item/transactions/printout/printable-stockcard-transaction-header.component.tsx +3 -3
- package/src/stock-items/add-stock-item/transactions/printout/transactions-print-action.component.tsx +2 -5
- package/src/stock-items/add-stock-item/transactions/printout/transactions-print-bincard-preview.modal.tsx +1 -1
- package/src/stock-items/add-stock-item/transactions/transaction-filters/transaction-locations-filter.component.tsx +0 -3
- package/src/stock-items/components/filter-stock-items/filter-stock-items.component.tsx +6 -4
- package/src/stock-items/edit-stock-item/edit-stock-item-action-menu.component.tsx +1 -1
- package/src/stock-items/stock-items-table.component.tsx +21 -15
- package/src/stock-items/stock-items-table.resource.ts +1 -1
- package/src/stock-items/stock-items.resource.ts +1 -2
- package/src/stock-locations/add-locations-form.workspace.tsx +9 -11
- package/src/stock-locations/location-admin-form.component.tsx +9 -4
- package/src/stock-locations/stock-locations-table.component.tsx +3 -3
- package/src/stock-lookups/stock-lookups.resource.ts +2 -2
- package/src/stock-management-admin-card-link.component.tsx +1 -1
- package/src/stock-operations/add-stock-operation/stock-operations-expanded-row/stock-items-table.tsx +12 -8
- package/src/stock-operations/add-stock-operation/stock-operations-expanded-row/stock-operation-expanded-row.component.tsx +4 -4
- package/src/stock-operations/edit-stock-operation/edit-stock-operation-action-menu.component.tsx +6 -7
- package/src/stock-operations/stock-operation-operations-filter/stock-operation-operations-filter.component.tsx +7 -3
- package/src/stock-operations/stock-operation-sources-filter/stock-operation-sources-filter.component.tsx +8 -4
- package/src/stock-operations/stock-operation-statuses-filter/stock-operation-statuses-filter.component.tsx +16 -14
- package/src/stock-operations/stock-operation-types-selector/stock-operation-types-selector.component.tsx +4 -4
- package/src/stock-operations/stock-operations-filters.component.tsx +4 -2
- package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.component.tsx +2 -2
- package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.test.tsx +1 -1
- package/src/stock-operations/stock-operations-forms/input-components/qty-uim-selector.test.tsx +1 -1
- package/src/stock-operations/stock-operations-forms/input-components/quantity-uom-selector.component.tsx +3 -3
- package/src/stock-operations/stock-operations-forms/input-components/stock-item-search.component.tsx +3 -4
- package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.component.tsx +3 -3
- package/src/stock-operations/stock-operations-forms/input-components/users-selector.component.tsx +6 -6
- package/src/stock-operations/stock-operations-forms/step2.test.tsx +1 -5
- package/src/stock-operations/stock-operations-forms/steps/base-operation-details-form-step.tsx +15 -16
- package/src/stock-operations/stock-operations-forms/steps/quantity-uom-cell.component.tsx +1 -1
- package/src/stock-operations/stock-operations-forms/steps/received-items.component.tsx +2 -2
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.component.tsx +24 -21
- package/src/stock-operations/stock-operations-forms/steps/stock-operation-submission-form-step.component.tsx +4 -4
- package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.workspace.tsx +60 -53
- package/src/stock-operations/stock-operations-forms/stock-operation-form.component.tsx +17 -12
- package/src/stock-operations/stock-operations-modal/stock-operations-completed-dispatch-button.component.tsx +1 -1
- package/src/stock-operations/stock-operations-modal/stock-operations-issue-stock-button.component.tsx +1 -1
- package/src/stock-operations/stock-operations-modal/stock-operations-print-button.component.tsx +6 -2
- package/src/stock-operations/stock-operations-modal/stock-operations-reject-button.component.tsx +4 -5
- package/src/stock-operations/stock-operations-modal/stock-operations.modal.tsx +4 -2
- package/src/stock-operations/stock-operations-table.component.tsx +16 -12
- package/src/stock-operations/stock-operations-table.resource.ts +1 -0
- package/src/stock-reports/generate-report/create-stock-report.workspace.tsx +31 -35
- package/src/stock-reports/report-list/stock-reports.component.tsx +5 -9
- package/src/stock-reports/stock-reports.resource.ts +1 -1
- package/src/stock-sources/add-stock-sources/add-stock-sources.workspace.tsx +6 -6
- package/src/stock-sources/stock-sources-items-table.component.tsx +14 -10
- package/src/stock-user-role-scopes/add-stock-user-scope/add-stock-user-role-scope.workspace.tsx +52 -53
- package/src/stock-user-role-scopes/delete-stock-user-scope/delete-stock-user-scope.component.tsx +1 -1
- package/src/stock-user-role-scopes/delete-stock-user-scope.modal.tsx +4 -1
- package/src/stock-user-role-scopes/stock-user-role-scopes-items-table.component.tsx +8 -12
- package/translations/en.json +105 -71
- package/src/core/components/carbon/controlled-dropdown.component.tsx +0 -37
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import styles from './stock-operation-operations-filter.scss';
|
|
2
|
-
import { Dropdown, DropdownSkeleton } from '@carbon/react';
|
|
3
1
|
import React from 'react';
|
|
2
|
+
import { Dropdown, DropdownSkeleton } from '@carbon/react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { useStockOperationTypes } from '../../stock-lookups/stock-lookups.resource';
|
|
5
|
+
import styles from './stock-operation-operations-filter.scss';
|
|
5
6
|
|
|
6
7
|
const StockOperationOperationsFilter: React.FC = () => {
|
|
8
|
+
const { t } = useTranslation();
|
|
7
9
|
// get stock sources
|
|
8
10
|
const { types, isLoading, error } = useStockOperationTypes();
|
|
9
11
|
if (isLoading || error) {
|
|
@@ -15,9 +17,11 @@ const StockOperationOperationsFilter: React.FC = () => {
|
|
|
15
17
|
<Dropdown
|
|
16
18
|
id="stockOperationOperationsFiter"
|
|
17
19
|
items={types.results}
|
|
18
|
-
itemToString={(item) => (item ? item.name : 'Not Set')}
|
|
20
|
+
itemToString={(item) => (item ? item.name : t('notSet', 'Not Set'))}
|
|
19
21
|
type="inline"
|
|
20
22
|
size="sm"
|
|
23
|
+
label={t('filterByOperationType', 'Filter by operation type')}
|
|
24
|
+
titleText={t('operationType', 'Operation Type')}
|
|
21
25
|
/>
|
|
22
26
|
</div>
|
|
23
27
|
</>
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import styles from './stock-operation-sources-filter.scss';
|
|
2
|
-
import { Dropdown, DropdownSkeleton } from '@carbon/react';
|
|
3
1
|
import React from 'react';
|
|
4
|
-
import {
|
|
2
|
+
import { Dropdown, DropdownSkeleton } from '@carbon/react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
5
4
|
import { type ConfigObject } from '../../config-schema';
|
|
5
|
+
import { useConcept } from '../../stock-lookups/stock-lookups.resource';
|
|
6
6
|
import { useConfig } from '@openmrs/esm-framework';
|
|
7
|
+
import styles from './stock-operation-sources-filter.scss';
|
|
7
8
|
|
|
8
9
|
const StockOperationSourcesFilter: React.FC = () => {
|
|
10
|
+
const { t } = useTranslation();
|
|
9
11
|
const { stockSourceTypeUUID } = useConfig<ConfigObject>();
|
|
10
12
|
|
|
11
13
|
// get stock sources
|
|
@@ -19,9 +21,11 @@ const StockOperationSourcesFilter: React.FC = () => {
|
|
|
19
21
|
<Dropdown
|
|
20
22
|
id="stockOperationSourcesFiter"
|
|
21
23
|
items={[...items.answers]}
|
|
22
|
-
itemToString={(item) => (item ? item.display : 'Not Set')}
|
|
24
|
+
itemToString={(item) => (item ? item.display : t('notSet', 'Not Set'))}
|
|
23
25
|
type="inline"
|
|
24
26
|
size="sm"
|
|
27
|
+
label={t('filterBySource', 'Filter by source')}
|
|
28
|
+
titleText={t('source', 'Source')}
|
|
25
29
|
/>
|
|
26
30
|
</div>
|
|
27
31
|
</>
|
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
import styles from './stock-operation-statuses-filter.scss';
|
|
2
|
-
import { Dropdown } from '@carbon/react';
|
|
3
1
|
import React from 'react';
|
|
2
|
+
import { Dropdown } from '@carbon/react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import styles from './stock-operation-statuses-filter.scss';
|
|
5
|
+
|
|
4
6
|
const StockOperationStatusesFilter: React.FC = () => {
|
|
7
|
+
const { t } = useTranslation();
|
|
5
8
|
// get stock sources
|
|
6
|
-
|
|
7
9
|
const items = ['SUBMITTED', 'NEW', 'RETURNED', 'CANCELLED', 'DISPATCHED', 'COMPLETED', 'REJECTED'];
|
|
8
10
|
|
|
9
11
|
return (
|
|
10
|
-
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
<div className={styles.filterContainer}>
|
|
13
|
+
<Dropdown
|
|
14
|
+
id="stockOperationStatusesFiter"
|
|
15
|
+
items={items}
|
|
16
|
+
itemToString={(item) => (item ? item : t('notSet', 'Not Set'))}
|
|
17
|
+
type="inline"
|
|
18
|
+
size="sm"
|
|
19
|
+
label={t('filterByStatus', 'Filter by status')}
|
|
20
|
+
titleText={t('status', 'Status')}
|
|
21
|
+
/>
|
|
22
|
+
</div>
|
|
21
23
|
);
|
|
22
24
|
};
|
|
23
25
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import React, { useCallback, useEffect } from 'react';
|
|
1
2
|
import { ButtonSkeleton, OverflowMenu, OverflowMenuItem } from '@carbon/react';
|
|
2
3
|
import { OverflowMenuVertical } from '@carbon/react/icons';
|
|
3
|
-
import { showSnackbar } from '@openmrs/esm-framework';
|
|
4
|
-
import React, { useCallback, useEffect } from 'react';
|
|
5
4
|
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import { showSnackbar } from '@openmrs/esm-framework';
|
|
6
6
|
import { OperationType, type StockOperationType } from '../../core/api/types/stockOperation/StockOperationType';
|
|
7
7
|
import { launchStockoperationAddOrEditWorkSpace } from '../stock-operation.utils';
|
|
8
8
|
import useFilteredOperationTypesByRoles from '../stock-operations-forms/hooks/useFilteredOperationTypesByRoles';
|
|
@@ -24,7 +24,7 @@ const StockOperationTypesSelector = () => {
|
|
|
24
24
|
if (error) {
|
|
25
25
|
showSnackbar({
|
|
26
26
|
kind: 'error',
|
|
27
|
-
title: t('
|
|
27
|
+
title: t('stockOperationTypesError', 'Error loading stock operation types'),
|
|
28
28
|
subtitle: error?.message,
|
|
29
29
|
});
|
|
30
30
|
}
|
|
@@ -42,7 +42,7 @@ const StockOperationTypesSelector = () => {
|
|
|
42
42
|
<OverflowMenuVertical size={16} />
|
|
43
43
|
</>
|
|
44
44
|
)}
|
|
45
|
-
menuOffset={{
|
|
45
|
+
menuOffset={{ top: 0, left: -100 }}
|
|
46
46
|
style={{
|
|
47
47
|
backgroundColor: '#007d79',
|
|
48
48
|
backgroundImage: 'none',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
2
3
|
import { DropdownSkeleton, MultiSelect } from '@carbon/react';
|
|
3
4
|
import { getStockOperationTypes, useConcept } from '../stock-lookups/stock-lookups.resource';
|
|
4
5
|
import { StockFilters } from '../constants';
|
|
@@ -12,6 +13,7 @@ interface StockOperationFiltersProps {
|
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
const StockOperationsFilters: React.FC<StockOperationFiltersProps> = ({ conceptUuid, onFilterChange, filterName }) => {
|
|
16
|
+
const { t } = useTranslation();
|
|
15
17
|
const { items, isLoading } = useConcept(conceptUuid);
|
|
16
18
|
const [isDataLoading, setIsDataLoading] = useState(false);
|
|
17
19
|
const [dataItems, setDataItems] = useState([]);
|
|
@@ -65,7 +67,7 @@ const StockOperationsFilters: React.FC<StockOperationFiltersProps> = ({ conceptU
|
|
|
65
67
|
label={filterName}
|
|
66
68
|
labelInline
|
|
67
69
|
items={dataItems}
|
|
68
|
-
itemToString={(item) => (item ? item.display : 'Not Set')}
|
|
70
|
+
itemToString={(item) => (item ? item.display : t('notSet', 'Not Set'))}
|
|
69
71
|
onChange={({ selectedItems }) => {
|
|
70
72
|
if (selectedItems) {
|
|
71
73
|
onFilterChange(
|
|
@@ -74,7 +76,7 @@ const StockOperationsFilters: React.FC<StockOperationFiltersProps> = ({ conceptU
|
|
|
74
76
|
);
|
|
75
77
|
}
|
|
76
78
|
}}
|
|
77
|
-
placeholder={
|
|
79
|
+
placeholder={t('filterBy', 'Filter by {{filterName}}', { filterName })}
|
|
78
80
|
/>
|
|
79
81
|
);
|
|
80
82
|
};
|
package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.component.tsx
CHANGED
|
@@ -107,10 +107,10 @@ const BatchNoSelector: React.FC<BatchNoSelectorProps> = ({ stockItemUuid, error,
|
|
|
107
107
|
itemToString={itemToString}
|
|
108
108
|
name="stockBatchUuid"
|
|
109
109
|
onChange={handleChange}
|
|
110
|
-
placeholder={
|
|
110
|
+
placeholder={t('filterPlaceholder', 'Filter...')}
|
|
111
111
|
selectedItem={initialSelectedItem}
|
|
112
112
|
style={{ flexGrow: 1 }}
|
|
113
|
-
titleText={t('batchNo', 'Batch
|
|
113
|
+
titleText={t('batchNo', 'Batch number')}
|
|
114
114
|
/>
|
|
115
115
|
);
|
|
116
116
|
};
|
package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.test.tsx
CHANGED
|
@@ -106,7 +106,7 @@ describe('BatchNoSelector', () => {
|
|
|
106
106
|
render(<BatchNoSelector stockItemUuid={mockStockItemUuid} onValueChange={mockOnValueChange} />);
|
|
107
107
|
|
|
108
108
|
expect(screen.getByRole('combobox')).toBeInTheDocument();
|
|
109
|
-
expect(screen.getByText(/batch
|
|
109
|
+
expect(screen.getByText(/batch number/i)).toBeInTheDocument();
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
it('should handle batch selection', async () => {
|
package/src/stock-operations/stock-operations-forms/input-components/qty-uim-selector.test.tsx
CHANGED
|
@@ -131,7 +131,7 @@ describe('QtyUOMSelector', () => {
|
|
|
131
131
|
|
|
132
132
|
render(<QtyUomSelector stockItemUuid={mockStockItemUuid} onValueChange={mockOnValueChange} />);
|
|
133
133
|
|
|
134
|
-
expect(screen.
|
|
134
|
+
expect(screen.queryByRole('combobox')).not.toBeInTheDocument();
|
|
135
135
|
});
|
|
136
136
|
|
|
137
137
|
it('should render Inline notification error when error ocuured while fetching item', () => {
|
|
@@ -24,7 +24,7 @@ const QtyUomSelector: React.FC<QtyUomSelectorProps> = ({ stockItemUuid, error, i
|
|
|
24
24
|
}
|
|
25
25
|
}, [initialSelectedItem, onValueChange]);
|
|
26
26
|
|
|
27
|
-
if (isLoading) return <SkeletonText
|
|
27
|
+
if (isLoading) return <SkeletonText />;
|
|
28
28
|
|
|
29
29
|
if (stockItemError)
|
|
30
30
|
return (
|
|
@@ -49,8 +49,8 @@ const QtyUomSelector: React.FC<QtyUomSelectorProps> = ({ stockItemUuid, error, i
|
|
|
49
49
|
onChange={(data: { selectedItem?: StockItemPackagingUOMDTO }) => {
|
|
50
50
|
onValueChange?.(data.selectedItem?.uuid);
|
|
51
51
|
}}
|
|
52
|
-
placeholder={t('
|
|
53
|
-
titleText={t('quantityUom', '
|
|
52
|
+
placeholder={t('filterPlaceholder', 'Filter...')}
|
|
53
|
+
titleText={t('quantityUom', 'Quantity unit of measurement')}
|
|
54
54
|
/>
|
|
55
55
|
);
|
|
56
56
|
};
|
package/src/stock-operations/stock-operations-forms/input-components/stock-item-search.component.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { ClickableTile, Search } from '@carbon/react';
|
|
2
|
-
import { useConfig, useDebounce } from '@openmrs/esm-framework';
|
|
3
1
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { ClickableTile, Search } from '@carbon/react';
|
|
4
3
|
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import { useConfig, useDebounce } from '@openmrs/esm-framework';
|
|
5
5
|
import { type StockItemDTO } from '../../../core/api/types/stockItem/StockItem';
|
|
6
6
|
import { useFilterableStockItems } from '../hooks/useFilterableStockItems';
|
|
7
|
-
import styles from './input-components-styles.scss';
|
|
8
7
|
import { type ConfigObject } from '../../../config-schema';
|
|
8
|
+
import styles from './input-components-styles.scss';
|
|
9
9
|
|
|
10
10
|
type StockItemSearchProps = {
|
|
11
11
|
onSelectedItem?: (stockItem: StockItemDTO) => void;
|
|
@@ -55,7 +55,6 @@ const StockItemSearch: React.FC<StockItemSearchProps> = ({ onSelectedItem }) =>
|
|
|
55
55
|
closeButtonLabelText={t('clearSearch', 'Clear search input')}
|
|
56
56
|
value={searchTerm}
|
|
57
57
|
id="search-stock-operation-item"
|
|
58
|
-
name="search-stock-operation-item"
|
|
59
58
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
60
59
|
/>
|
|
61
60
|
</div>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ComboBox, InlineNotification, SelectSkeleton } from '@carbon/react';
|
|
2
|
-
import { useConfig } from '@openmrs/esm-framework';
|
|
3
1
|
import React from 'react';
|
|
2
|
+
import { ComboBox, InlineNotification, SelectSkeleton } from '@carbon/react';
|
|
4
3
|
import { Controller, useFormContext } from 'react-hook-form';
|
|
5
4
|
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import { useConfig } from '@openmrs/esm-framework';
|
|
6
6
|
import { type ConfigObject } from '../../../config-schema';
|
|
7
7
|
import { type Concept } from '../../../core/api/types/concept/Concept';
|
|
8
8
|
import { useConcept } from '../../../stock-lookups/stock-lookups.resource';
|
|
@@ -56,7 +56,7 @@ const StockOperationReasonSelector: React.FC<StockOperationReasonSelectorProps>
|
|
|
56
56
|
field.onChange(data?.selectedItem?.uuid);
|
|
57
57
|
}}
|
|
58
58
|
ref={field.ref}
|
|
59
|
-
invalid={error?.message}
|
|
59
|
+
invalid={!!error?.message}
|
|
60
60
|
invalidText={error?.message}
|
|
61
61
|
/>
|
|
62
62
|
)}
|
package/src/stock-operations/stock-operations-forms/input-components/users-selector.component.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ComboBox, InlineNotification, SelectSkeleton, Column, TextInput } from '@carbon/react';
|
|
2
1
|
import React, { useEffect } from 'react';
|
|
2
|
+
import { ComboBox, InlineNotification, SelectSkeleton, Column, TextInput } from '@carbon/react';
|
|
3
3
|
import { Controller, useFormContext } from 'react-hook-form';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { type User } from '../../../core/api/types/identity/User';
|
|
@@ -68,10 +68,10 @@ const UsersSelector = () => {
|
|
|
68
68
|
? otherUser
|
|
69
69
|
: ''
|
|
70
70
|
}
|
|
71
|
-
itemToString={(item) => item?.person?.display || ''}
|
|
71
|
+
itemToString={(item) => (typeof item === 'string' ? item : item?.person?.display || '')}
|
|
72
72
|
onInputChange={debouncedSearch}
|
|
73
|
-
placeholder={t('filter', 'Filter
|
|
74
|
-
invalid={error?.message}
|
|
73
|
+
placeholder={t('filter', 'Filter...')}
|
|
74
|
+
invalid={!!error?.message}
|
|
75
75
|
invalidText={error?.message}
|
|
76
76
|
ref={field.ref}
|
|
77
77
|
/>
|
|
@@ -93,8 +93,8 @@ const UsersSelector = () => {
|
|
|
93
93
|
name="responsiblePersonOther"
|
|
94
94
|
size="lg"
|
|
95
95
|
labelText={t('responsiblePerson', 'Responsible Person')}
|
|
96
|
-
placeholder={t('pleaseSpecify', 'Please
|
|
97
|
-
invalid={error?.message}
|
|
96
|
+
placeholder={t('pleaseSpecify', 'Please specify')}
|
|
97
|
+
invalid={!!error?.message}
|
|
98
98
|
invalidText={error?.message}
|
|
99
99
|
/>
|
|
100
100
|
)}
|
|
@@ -239,11 +239,7 @@ describe('Stock Operation step 2 (stock operation items details)', () => {
|
|
|
239
239
|
expect(
|
|
240
240
|
screen.getByRole('searchbox', {
|
|
241
241
|
name(accessibleName, element) {
|
|
242
|
-
return (
|
|
243
|
-
element.getAttribute('id') === 'search-stock-operation-item' &&
|
|
244
|
-
element.getAttribute('placeholder') === 'Find your items' &&
|
|
245
|
-
element.getAttribute('name') === 'search-stock-operation-item'
|
|
246
|
-
);
|
|
242
|
+
return element.getAttribute('id') === 'search-stock-operation-item';
|
|
247
243
|
},
|
|
248
244
|
}),
|
|
249
245
|
).toBeInTheDocument();
|
package/src/stock-operations/stock-operations-forms/steps/base-operation-details-form-step.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React, { type ChangeEvent, type FC, useEffect, useMemo } from 'react';
|
|
1
2
|
import {
|
|
2
3
|
Button,
|
|
3
4
|
Column,
|
|
@@ -10,10 +11,9 @@ import {
|
|
|
10
11
|
TextInput,
|
|
11
12
|
} from '@carbon/react';
|
|
12
13
|
import { ArrowRight } from '@carbon/react/icons';
|
|
13
|
-
import { ErrorState } from '@openmrs/esm-framework';
|
|
14
|
-
import React, { type ChangeEvent, type FC, useEffect, useMemo } from 'react';
|
|
15
14
|
import { Controller, useFormContext } from 'react-hook-form';
|
|
16
15
|
import { useTranslation } from 'react-i18next';
|
|
16
|
+
import { ErrorState } from '@openmrs/esm-framework';
|
|
17
17
|
import { DATE_PICKER_CONTROL_FORMAT, DATE_PICKER_FORMAT, MAIN_STORE_LOCATION_TAG } from '../../../constants';
|
|
18
18
|
import { type Party } from '../../../core/api/types/Party';
|
|
19
19
|
import { type StockOperationDTO } from '../../../core/api/types/stockOperation/StockOperationDTO';
|
|
@@ -42,7 +42,7 @@ const BaseOperationDetailsFormStep: FC<BaseOperationDetailsFormStepProps> = ({
|
|
|
42
42
|
destinationParties,
|
|
43
43
|
sourceParties,
|
|
44
44
|
isLoading: isPartiesLoading,
|
|
45
|
-
error:
|
|
45
|
+
error: partiesError,
|
|
46
46
|
sourceTags,
|
|
47
47
|
destinationTags,
|
|
48
48
|
} = useParties(stockOperationType);
|
|
@@ -61,7 +61,9 @@ const BaseOperationDetailsFormStep: FC<BaseOperationDetailsFormStepProps> = ({
|
|
|
61
61
|
'reasonUuid',
|
|
62
62
|
'responsiblePersonOther',
|
|
63
63
|
]);
|
|
64
|
-
if (valid)
|
|
64
|
+
if (valid) {
|
|
65
|
+
onNext();
|
|
66
|
+
}
|
|
65
67
|
};
|
|
66
68
|
|
|
67
69
|
// initialize location fields
|
|
@@ -96,9 +98,9 @@ const BaseOperationDetailsFormStep: FC<BaseOperationDetailsFormStepProps> = ({
|
|
|
96
98
|
/>
|
|
97
99
|
);
|
|
98
100
|
|
|
99
|
-
if (
|
|
101
|
+
if (partiesError)
|
|
100
102
|
return (
|
|
101
|
-
<ErrorState error={
|
|
103
|
+
<ErrorState error={partiesError} headerTitle={t('partiesError', 'Error launching base operation details form')} />
|
|
102
104
|
);
|
|
103
105
|
|
|
104
106
|
return (
|
|
@@ -113,7 +115,6 @@ const BaseOperationDetailsFormStep: FC<BaseOperationDetailsFormStepProps> = ({
|
|
|
113
115
|
render={({ field, fieldState: { error } }) => (
|
|
114
116
|
<DatePicker
|
|
115
117
|
readOnly={field.disabled}
|
|
116
|
-
id={`operationDate`}
|
|
117
118
|
datePickerType="single"
|
|
118
119
|
locale="en"
|
|
119
120
|
className={styles.datePickerInput}
|
|
@@ -125,12 +126,10 @@ const BaseOperationDetailsFormStep: FC<BaseOperationDetailsFormStepProps> = ({
|
|
|
125
126
|
}}
|
|
126
127
|
>
|
|
127
128
|
<DatePickerInput
|
|
128
|
-
autoComplete="off"
|
|
129
129
|
id={`operationDate-input`}
|
|
130
|
-
name="operationDate-input"
|
|
131
130
|
placeholder={DATE_PICKER_FORMAT}
|
|
132
131
|
labelText={t('operationDate', 'Operation Date')}
|
|
133
|
-
invalid={error?.message}
|
|
132
|
+
invalid={!!error?.message}
|
|
134
133
|
invalidText={error?.message}
|
|
135
134
|
size="lg"
|
|
136
135
|
/>
|
|
@@ -176,7 +175,7 @@ const BaseOperationDetailsFormStep: FC<BaseOperationDetailsFormStepProps> = ({
|
|
|
176
175
|
: t('chooseALocation', 'Choose a location')
|
|
177
176
|
}
|
|
178
177
|
ref={field.ref}
|
|
179
|
-
invalid={error?.message}
|
|
178
|
+
invalid={!!error?.message}
|
|
180
179
|
invalidText={error?.message}
|
|
181
180
|
/>
|
|
182
181
|
)}
|
|
@@ -192,7 +191,7 @@ const BaseOperationDetailsFormStep: FC<BaseOperationDetailsFormStepProps> = ({
|
|
|
192
191
|
readOnly={field.disabled}
|
|
193
192
|
titleText={
|
|
194
193
|
isStockIssueOperation
|
|
195
|
-
? t('destination', '
|
|
194
|
+
? t('destination', 'Destination')
|
|
196
195
|
: stockOperationType?.hasSource || stockOperation?.atLocationUuid
|
|
197
196
|
? t('to', 'To')
|
|
198
197
|
: t('location', 'Location')
|
|
@@ -213,7 +212,7 @@ const BaseOperationDetailsFormStep: FC<BaseOperationDetailsFormStepProps> = ({
|
|
|
213
212
|
: t('location', 'Location')
|
|
214
213
|
}
|
|
215
214
|
ref={field.ref}
|
|
216
|
-
invalid={error?.message}
|
|
215
|
+
invalid={!!error?.message}
|
|
217
216
|
invalidText={error?.message}
|
|
218
217
|
/>
|
|
219
218
|
)}
|
|
@@ -239,10 +238,10 @@ const BaseOperationDetailsFormStep: FC<BaseOperationDetailsFormStepProps> = ({
|
|
|
239
238
|
onChange={(e: ChangeEvent<HTMLTextAreaElement>) => {
|
|
240
239
|
field.onChange(e.target.value);
|
|
241
240
|
}}
|
|
242
|
-
placeholder={t('
|
|
241
|
+
placeholder={t('enterRemarksPlaceholder', 'Enter remarks...')}
|
|
243
242
|
id={'remarks'}
|
|
244
243
|
labelText={t('remarks', 'Remarks')}
|
|
245
|
-
invalid={error?.message}
|
|
244
|
+
invalid={!!error?.message}
|
|
246
245
|
invalidText={error?.message}
|
|
247
246
|
/>
|
|
248
247
|
)}
|
|
@@ -251,7 +250,7 @@ const BaseOperationDetailsFormStep: FC<BaseOperationDetailsFormStepProps> = ({
|
|
|
251
250
|
<div className={styles.btnSet}>
|
|
252
251
|
{typeof onNext === 'function' && (
|
|
253
252
|
<Button kind="primary" onClick={handleNext} role="button" renderIcon={ArrowRight}>
|
|
254
|
-
{t('
|
|
253
|
+
{t('nextButton', 'Next')}
|
|
255
254
|
</Button>
|
|
256
255
|
)}
|
|
257
256
|
</div>
|
|
@@ -20,7 +20,7 @@ const QuantityUomCell: React.FC<QuantityUomCellProps> = ({ stockItemPackagingUOM
|
|
|
20
20
|
if (error) {
|
|
21
21
|
showSnackbar({
|
|
22
22
|
kind: 'error',
|
|
23
|
-
title: t('packagingUomError', 'Error loading
|
|
23
|
+
title: t('packagingUomError', 'Error loading Stock item'),
|
|
24
24
|
subtitle: error?.message,
|
|
25
25
|
});
|
|
26
26
|
}
|
|
@@ -37,7 +37,7 @@ const ReceivedItems: React.FC<ReceivedItemsProps> = ({ stockOperation, onPreviou
|
|
|
37
37
|
{ key: 'item', header: t('item', 'Item') },
|
|
38
38
|
{ key: 'requested', header: t('requested', 'Requested') },
|
|
39
39
|
{ key: 'batch', header: t('batch', 'Batch No') },
|
|
40
|
-
{ key: 'expiry', header: t('expiry', 'Expiry
|
|
40
|
+
{ key: 'expiry', header: t('expiry', 'Expiry') },
|
|
41
41
|
{ key: 'qtySent', header: t('quantitySent', 'Quantity Sent') },
|
|
42
42
|
{ key: 'qtyReceived', header: t('quantityReceived', 'Quantity Received') },
|
|
43
43
|
{
|
|
@@ -101,7 +101,7 @@ const ReceivedItems: React.FC<ReceivedItemsProps> = ({ stockOperation, onPreviou
|
|
|
101
101
|
<Button
|
|
102
102
|
data-testid="previous-btn"
|
|
103
103
|
hasIconOnly
|
|
104
|
-
iconDescription={t('
|
|
104
|
+
iconDescription={t('previousButton', 'Previous')}
|
|
105
105
|
kind="secondary"
|
|
106
106
|
onClick={onPrevious}
|
|
107
107
|
renderIcon={ArrowLeft}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useId, useMemo } from 'react';
|
|
2
2
|
import { ArrowLeft, ArrowRight, Edit, TrashCan } from '@carbon/react/icons';
|
|
3
3
|
import {
|
|
4
4
|
Button,
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from '@carbon/react';
|
|
14
14
|
import { useFormContext } from 'react-hook-form';
|
|
15
15
|
import { useTranslation } from 'react-i18next';
|
|
16
|
+
import { showSnackbar } from '@openmrs/esm-framework';
|
|
16
17
|
import { type StockOperationDTO } from '../../../core/api/types/stockOperation/StockOperationDTO';
|
|
17
18
|
import { type StockOperationType } from '../../../core/api/types/stockOperation/StockOperationType';
|
|
18
19
|
import { getStockOperationUniqueId } from '../../stock-operation.utils';
|
|
@@ -24,8 +25,8 @@ import StockAvailability from './stock-availability-cell.component';
|
|
|
24
25
|
import StockOperationItemBatchNoCell from './stock-operation-item-batch-no-cell.component';
|
|
25
26
|
import StockOperationItemCell from './stock-operation-item-cell.component';
|
|
26
27
|
import StockoperationItemExpiryCell from './stock-operation-item-expiry-cell.component';
|
|
28
|
+
import { type CustomTableHeader } from '../../../core/components/table/types';
|
|
27
29
|
import styles from './stock-operation-items-form-step.scc.scss';
|
|
28
|
-
import { showSnackbar } from '@openmrs/esm-framework';
|
|
29
30
|
|
|
30
31
|
type StockOperationItemsFormStepProps = {
|
|
31
32
|
stockOperation?: StockOperationDTO;
|
|
@@ -63,7 +64,7 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
|
63
64
|
? [
|
|
64
65
|
{
|
|
65
66
|
key: 'batch',
|
|
66
|
-
header: t('batchNo', 'Batch
|
|
67
|
+
header: t('batchNo', 'Batch number'),
|
|
67
68
|
styles: { width: '15% !important' },
|
|
68
69
|
},
|
|
69
70
|
]
|
|
@@ -87,11 +88,11 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
|
87
88
|
|
|
88
89
|
{
|
|
89
90
|
key: 'quantity',
|
|
90
|
-
header: t('
|
|
91
|
+
header: t('quantity', 'Quantity'),
|
|
91
92
|
},
|
|
92
93
|
{
|
|
93
94
|
key: 'quantityuom',
|
|
94
|
-
header: t('quantityUom', '
|
|
95
|
+
header: t('quantityUom', 'Quantity unit of measurement'),
|
|
95
96
|
},
|
|
96
97
|
...(operationTypePermision.canCaptureQuantityPrice
|
|
97
98
|
? [
|
|
@@ -151,7 +152,7 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
|
151
152
|
type="button"
|
|
152
153
|
size="sm"
|
|
153
154
|
className="submitButton clear-padding-margin"
|
|
154
|
-
iconDescription={'Edit'}
|
|
155
|
+
iconDescription={t('edit', 'Edit')}
|
|
155
156
|
kind="ghost"
|
|
156
157
|
renderIcon={Edit}
|
|
157
158
|
onClick={() => {
|
|
@@ -162,7 +163,7 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
|
162
163
|
type="button"
|
|
163
164
|
size="sm"
|
|
164
165
|
className="submitButton clear-padding-margin"
|
|
165
|
-
iconDescription={'Delete'}
|
|
166
|
+
iconDescription={t('delete', 'Delete')}
|
|
166
167
|
kind="ghost"
|
|
167
168
|
renderIcon={TrashCan}
|
|
168
169
|
onClick={() => {
|
|
@@ -173,7 +174,7 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
|
173
174
|
),
|
|
174
175
|
};
|
|
175
176
|
});
|
|
176
|
-
}, [observableOperationItems, onLaunchItemsForm, stockOperationType, uniqueId]);
|
|
177
|
+
}, [observableOperationItems, onLaunchItemsForm, stockOperationType, t, uniqueId]);
|
|
177
178
|
|
|
178
179
|
const handleNext = async () => {
|
|
179
180
|
const valid = await form.trigger(['stockOperationItems']);
|
|
@@ -191,7 +192,7 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
|
191
192
|
}
|
|
192
193
|
};
|
|
193
194
|
|
|
194
|
-
const headerTitle = t('
|
|
195
|
+
const headerTitle = t('stockOperationItems', 'Stock operation items');
|
|
195
196
|
|
|
196
197
|
return (
|
|
197
198
|
<div style={{ margin: '10px' }}>
|
|
@@ -209,13 +210,8 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
|
209
210
|
})
|
|
210
211
|
}
|
|
211
212
|
/>
|
|
212
|
-
<DataTable
|
|
213
|
-
|
|
214
|
-
headers={headers}
|
|
215
|
-
isSortable={false}
|
|
216
|
-
useZebraStyles={true}
|
|
217
|
-
className={styles.dataTable}
|
|
218
|
-
render={({ rows, headers, getTableProps, getHeaderProps, getRowProps }) => (
|
|
213
|
+
<DataTable rows={tableRows ?? []} headers={headers} isSortable={false} useZebraStyles>
|
|
214
|
+
{({ rows, headers, getTableProps, getHeaderProps, getRowProps }) => (
|
|
219
215
|
<TableContainer>
|
|
220
216
|
<Table {...getTableProps()}>
|
|
221
217
|
<TableHead>
|
|
@@ -226,10 +222,17 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
|
226
222
|
header,
|
|
227
223
|
isSortable: false,
|
|
228
224
|
})}
|
|
229
|
-
style={header?.styles}
|
|
225
|
+
style={(header as CustomTableHeader)?.styles}
|
|
230
226
|
key={header.key}
|
|
231
227
|
>
|
|
232
|
-
{
|
|
228
|
+
{(() => {
|
|
229
|
+
const customHeader = header as CustomTableHeader;
|
|
230
|
+
return typeof customHeader.header === 'object' &&
|
|
231
|
+
customHeader.header !== null &&
|
|
232
|
+
'content' in customHeader.header
|
|
233
|
+
? (customHeader.header.content as React.ReactNode)
|
|
234
|
+
: (customHeader.header as React.ReactNode);
|
|
235
|
+
})()}
|
|
233
236
|
</TableHeader>
|
|
234
237
|
))}
|
|
235
238
|
</TableRow>
|
|
@@ -246,11 +249,11 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
|
246
249
|
</Table>
|
|
247
250
|
</TableContainer>
|
|
248
251
|
)}
|
|
249
|
-
|
|
252
|
+
</DataTable>
|
|
250
253
|
<div className={styles.btnSet}>
|
|
251
254
|
{typeof onNext === 'function' && (
|
|
252
255
|
<Button kind="primary" onClick={handleNext} renderIcon={ArrowRight}>
|
|
253
|
-
{t('
|
|
256
|
+
{t('nextButton', 'Next')}
|
|
254
257
|
</Button>
|
|
255
258
|
)}
|
|
256
259
|
{typeof onPrevious === 'function' && (
|
|
@@ -260,7 +263,7 @@ const StockOperationItemsFormStep: React.FC<StockOperationItemsFormStepProps> =
|
|
|
260
263
|
renderIcon={ArrowLeft}
|
|
261
264
|
hasIconOnly
|
|
262
265
|
data-testid="previous-btn"
|
|
263
|
-
iconDescription={t('
|
|
266
|
+
iconDescription={t('previousButton', 'Previous')}
|
|
264
267
|
/>
|
|
265
268
|
)}
|
|
266
269
|
</div>
|
|
@@ -66,14 +66,14 @@ const StockOperationSubmissionFormStep: React.FC<StockOperationSubmissionFormSte
|
|
|
66
66
|
kind: del.status === 'rejected' ? 'error' : 'success',
|
|
67
67
|
title:
|
|
68
68
|
del.status === 'rejected'
|
|
69
|
-
? t('
|
|
69
|
+
? t('stockOperationItemDeleteError', 'Error deleting stock operation item {{item}}', {
|
|
70
70
|
item: itemsToDelete[index].commonName,
|
|
71
71
|
})
|
|
72
72
|
: t('success', 'Success'),
|
|
73
73
|
subtitle:
|
|
74
74
|
del.status === 'rejected'
|
|
75
75
|
? del.reason?.message
|
|
76
|
-
: t('
|
|
76
|
+
: t('stockOperationItemDeleteSuccess', 'Stock operation item {{item}} deleted successfully', {
|
|
77
77
|
item: itemsToDelete[index].commonName,
|
|
78
78
|
}),
|
|
79
79
|
});
|
|
@@ -233,7 +233,7 @@ const StockOperationSubmissionFormStep: React.FC<StockOperationSubmissionFormSte
|
|
|
233
233
|
<div className={styles.btnSet}>
|
|
234
234
|
{typeof onNext === 'function' && (
|
|
235
235
|
<Button kind="tertiary" onClick={onNext} renderIcon={ArrowRight}>
|
|
236
|
-
{t('
|
|
236
|
+
{t('nextButton', 'Next')}
|
|
237
237
|
</Button>
|
|
238
238
|
)}
|
|
239
239
|
{typeof onPrevious === 'function' && (
|
|
@@ -243,7 +243,7 @@ const StockOperationSubmissionFormStep: React.FC<StockOperationSubmissionFormSte
|
|
|
243
243
|
renderIcon={ArrowLeft}
|
|
244
244
|
hasIconOnly
|
|
245
245
|
data-testid="previous-btn"
|
|
246
|
-
iconDescription={t('
|
|
246
|
+
iconDescription={t('previousButton', 'Previous')}
|
|
247
247
|
/>
|
|
248
248
|
)}
|
|
249
249
|
</div>
|