@openmrs/esm-stock-management-app 3.1.1-pre.1179 → 3.1.1-pre.1186
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/3066.js +2 -0
- package/dist/3066.js.map +1 -0
- 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 +64 -64
- 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/dist/2474.js +0 -2
- package/dist/2474.js.map +0 -1
- package/src/core/components/carbon/controlled-dropdown.component.tsx +0 -37
- /package/dist/{2474.js.LICENSE.txt → 3066.js.LICENSE.txt} +0 -0
|
@@ -74,21 +74,24 @@ const DataList: React.FC<ListProps> = ({ columns, data, children, totalItems, go
|
|
|
74
74
|
}),
|
|
75
75
|
);
|
|
76
76
|
};
|
|
77
|
-
const
|
|
77
|
+
const handleExportCSV = () => {
|
|
78
78
|
const csvString = convertToCSV(list, columns);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
saveAs(blob, 'data.csv');
|
|
82
|
-
} else if (object.currentTarget.innerText === 'Download As Json') {
|
|
83
|
-
const jsonBlob = new Blob([csvString], { type: 'application/json' });
|
|
84
|
-
saveAs(jsonBlob, 'data.json');
|
|
85
|
-
}
|
|
79
|
+
const blob = new Blob([csvString], { type: 'text/csv;charset=utf-8' });
|
|
80
|
+
saveAs(blob, 'data.csv');
|
|
86
81
|
};
|
|
82
|
+
|
|
83
|
+
const handleExportJSON = () => {
|
|
84
|
+
const jsonString = JSON.stringify(list, null, 2);
|
|
85
|
+
const jsonBlob = new Blob([jsonString], { type: 'application/json' });
|
|
86
|
+
saveAs(jsonBlob, 'data.json');
|
|
87
|
+
};
|
|
88
|
+
|
|
87
89
|
const convertToCSV = (data, columns) => {
|
|
88
90
|
const header = columns.map((col) => col.header).join(',');
|
|
89
91
|
const rows = data.map((row) => columns.map((col) => JSON.stringify(row[col.key])).join(','));
|
|
90
92
|
return [header, ...rows].join('\n');
|
|
91
93
|
};
|
|
94
|
+
|
|
92
95
|
return (
|
|
93
96
|
<>
|
|
94
97
|
<DataTable
|
|
@@ -119,15 +122,21 @@ const DataList: React.FC<ListProps> = ({ columns, data, children, totalItems, go
|
|
|
119
122
|
) : (
|
|
120
123
|
<>
|
|
121
124
|
<OverflowMenu
|
|
122
|
-
size="sm"
|
|
123
|
-
kind="tertiary"
|
|
124
|
-
renderIcon={DocumentDownload}
|
|
125
|
-
iconDescription="Download As"
|
|
126
125
|
focusTrap={false}
|
|
126
|
+
iconDescription={t('downloadOptions', 'Download options')}
|
|
127
|
+
renderIcon={DocumentDownload}
|
|
128
|
+
size="sm"
|
|
127
129
|
>
|
|
128
|
-
<OverflowMenuItem
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
<OverflowMenuItem
|
|
131
|
+
className={styles.menuItem}
|
|
132
|
+
itemText={t('downloadAsCSV', 'Download As CSV')}
|
|
133
|
+
onClick={handleExportCSV}
|
|
134
|
+
/>
|
|
135
|
+
<OverflowMenuItem
|
|
136
|
+
className={styles.menuItem}
|
|
137
|
+
itemText={t('downloadAsJson', 'Download As JSON')}
|
|
138
|
+
onClick={handleExportJSON}
|
|
139
|
+
/>
|
|
131
140
|
</OverflowMenu>
|
|
132
141
|
<TableToolbarSearch
|
|
133
142
|
className={styles.itemListSearch}
|
|
@@ -172,8 +181,8 @@ const DataList: React.FC<ListProps> = ({ columns, data, children, totalItems, go
|
|
|
172
181
|
</div>
|
|
173
182
|
) : null}
|
|
174
183
|
<Pagination
|
|
175
|
-
forwardText=
|
|
176
|
-
backwardText=
|
|
184
|
+
forwardText={t('nextPage', 'Next page')}
|
|
185
|
+
backwardText={t('previousPage', 'Previous page')}
|
|
177
186
|
page={currentPage}
|
|
178
187
|
pageSize={currentPageSize}
|
|
179
188
|
pageSizes={pageSizes}
|
|
@@ -3,3 +3,15 @@ import type React from 'react';
|
|
|
3
3
|
export interface DataTableRenderProps {
|
|
4
4
|
onInputChange: (e: React.ChangeEvent<HTMLInputElement>, defaultValue?: string) => void;
|
|
5
5
|
}
|
|
6
|
+
|
|
7
|
+
export interface CustomTableHeader {
|
|
8
|
+
key: string;
|
|
9
|
+
header: string | { content: React.ReactNode };
|
|
10
|
+
styles?: React.CSSProperties;
|
|
11
|
+
isSortable?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CustomTableRow {
|
|
15
|
+
id: string;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
@@ -20,12 +20,8 @@ const VerticalTabs: React.FC<VerticalTabsProps> = ({ tabs, title, hasContainer,
|
|
|
20
20
|
`}
|
|
21
21
|
>
|
|
22
22
|
{title && <p className={styles.heading}>{title}</p>}
|
|
23
|
-
<div className={styles.tab}>
|
|
24
|
-
<Tabs
|
|
25
|
-
className={`${styles.verticalTabs}`}
|
|
26
|
-
selectedIndex={selectedIndex}
|
|
27
|
-
onChange={({ selectedIndex }) => onChange?.(selectedIndex)}
|
|
28
|
-
>
|
|
23
|
+
<div className={`${styles.tab} ${styles.verticalTabs}`}>
|
|
24
|
+
<Tabs selectedIndex={selectedIndex} onChange={({ selectedIndex }) => onChange?.(selectedIndex)}>
|
|
29
25
|
<TabList aria-label="navigation">
|
|
30
26
|
{tabs.map((tab: TabItem, index: number) => (
|
|
31
27
|
<Tab key={index} disabled={tab.disabled}>
|
package/src/declarations.d.ts
CHANGED
|
@@ -55,8 +55,8 @@ const StockHomeInventoryCard = () => {
|
|
|
55
55
|
<div className={styles.cardText}>
|
|
56
56
|
<p>{t('expiringStock', 'Expiring stock')}</p>
|
|
57
57
|
<p>
|
|
58
|
-
<strong>{item?.drugName}</strong> {t('
|
|
59
|
-
{item?.quantity} {item?.dispensingUnitName}
|
|
58
|
+
<strong>{item?.drugName}</strong> {t('batchNumberLabel', 'Batch number:')} {item?.batchNo}{' '}
|
|
59
|
+
{t('quantityLabel', 'Quantity:')} {item?.quantity} {item?.dispensingUnitName}
|
|
60
60
|
</p>
|
|
61
61
|
</div>
|
|
62
62
|
</div>
|
|
@@ -53,7 +53,7 @@ const AddEditStockItem: React.FC<AddStockItemProps> = ({ stockItem, closeWorkspa
|
|
|
53
53
|
disabled: !isEditing,
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
|
-
name: t('
|
|
56
|
+
name: t('rules', 'Rules'),
|
|
57
57
|
component: <StockItemRules stockItemUuid={stockItem?.uuid} />,
|
|
58
58
|
disabled: !isEditing,
|
|
59
59
|
},
|
|
@@ -29,9 +29,6 @@ const BatchInformationLocationsFilter = <T,>(props: BatchInformationLocationsFil
|
|
|
29
29
|
render={({ field: { onChange, value, ref } }) => (
|
|
30
30
|
<ComboBox
|
|
31
31
|
titleText={props.title}
|
|
32
|
-
name={props.name}
|
|
33
|
-
control={props.control}
|
|
34
|
-
controllerName={props.controllerName}
|
|
35
32
|
id={props.name}
|
|
36
33
|
size={'md'}
|
|
37
34
|
items={stockLocations ?? []}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { useForm } from 'react-hook-form';
|
|
3
4
|
import { formatDisplayDate } from '../../../core/utils/datetimeUtils';
|
|
4
5
|
import { DataTableSkeleton } from '@carbon/react';
|
|
5
|
-
import
|
|
6
|
+
import { type StockItemInventoryFilter } from '../../stock-items.resource';
|
|
6
7
|
import { useStockItemBatchInformationHook } from './batch-information.resource';
|
|
7
8
|
import BatchInformationLocationsFilter from './batch-information-locations/batch-information-locations-filter.component';
|
|
8
|
-
import
|
|
9
|
-
import { type StockItemInventoryFilter } from '../../stock-items.resource';
|
|
9
|
+
import DataList from '../../../core/components/table/table.component';
|
|
10
10
|
|
|
11
11
|
interface BatchInformationProps {
|
|
12
12
|
onSubmit?: () => void;
|
|
@@ -32,7 +32,7 @@ const BatchInformation: React.FC<BatchInformationProps> = ({ stockItemUuid }) =>
|
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
key: 'batch',
|
|
35
|
-
header: t('batchNumber', 'Batch
|
|
35
|
+
header: t('batchNumber', 'Batch number'),
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
key: 'quantity',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React, { type ReactNode, useMemo
|
|
1
|
+
import React, { type ReactNode, useMemo } from 'react';
|
|
2
|
+
import { ComboBox, SelectSkeleton } from '@carbon/react';
|
|
2
3
|
import { type Control, Controller, type FieldValues } from 'react-hook-form';
|
|
3
4
|
import { type StockItemPackagingUOMDTO } from '../../../core/api/types/stockItem/StockItemPackagingUOM';
|
|
4
|
-
import { ComboBox, SelectSkeleton } from '@carbon/react';
|
|
5
5
|
|
|
6
6
|
interface DispensingPackageMeasurementProps<T> {
|
|
7
7
|
dispensingUnitPackagingUoMUuid?: string;
|
|
@@ -40,9 +40,6 @@ const DispensingPackageMeasurement = <T,>(props: DispensingPackageMeasurementPro
|
|
|
40
40
|
render={({ field: { onChange, ref } }) => (
|
|
41
41
|
<ComboBox
|
|
42
42
|
titleText={props.title}
|
|
43
|
-
name={props.name}
|
|
44
|
-
control={props.control}
|
|
45
|
-
controllerName={props.controllerName}
|
|
46
43
|
id={props.name}
|
|
47
44
|
size={'sm'}
|
|
48
45
|
items={props.packagingUnits ?? []}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React, { type ReactNode, useState } from 'react';
|
|
2
|
-
import { useTranslation } from 'react-i18next';
|
|
3
2
|
import { ComboBox, InlineLoading } from '@carbon/react';
|
|
4
|
-
import {
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
5
4
|
import { type Control, Controller, type FieldValues } from 'react-hook-form';
|
|
6
|
-
import {
|
|
5
|
+
import { type Drug } from '../../../core/api/types/concept/Drug';
|
|
7
6
|
import { fetchStockItem } from '../../stock-items.resource';
|
|
7
|
+
import { useDrugsHook } from './drug-selector.resource';
|
|
8
8
|
|
|
9
9
|
interface DrugSelectorProps<T> {
|
|
10
10
|
placeholder?: string;
|
|
@@ -47,9 +47,6 @@ const DrugSelector = <T,>(props: DrugSelectorProps<T>) => {
|
|
|
47
47
|
render={({ field: { onChange, ref } }) => (
|
|
48
48
|
<ComboBox
|
|
49
49
|
titleText={props.title}
|
|
50
|
-
name={props.name}
|
|
51
|
-
control={props.control}
|
|
52
|
-
controllerName={props.controllerName}
|
|
53
50
|
id={props.name}
|
|
54
51
|
size={'md'}
|
|
55
52
|
items={drugList || []}
|
|
@@ -64,7 +61,6 @@ const DrugSelector = <T,>(props: DrugSelectorProps<T>) => {
|
|
|
64
61
|
}
|
|
65
62
|
}}
|
|
66
63
|
onInputChange={(event) => handleInputChange(event)}
|
|
67
|
-
inputValue={inputValue}
|
|
68
64
|
placeholder={props.placeholder}
|
|
69
65
|
invalid={props.invalid}
|
|
70
66
|
invalidText={props.invalidText}
|
|
@@ -73,7 +69,7 @@ const DrugSelector = <T,>(props: DrugSelectorProps<T>) => {
|
|
|
73
69
|
)}
|
|
74
70
|
/>
|
|
75
71
|
{isLoading && <InlineLoading status="active" iconDescription="Searching" description="Searching..." />}
|
|
76
|
-
{showExistenceError && <div style={{ color: '#da1e28' }}>{t('itemAlreadyExists', 'Item already
|
|
72
|
+
{showExistenceError && <div style={{ color: '#da1e28' }}>{t('itemAlreadyExists', 'Item already exists')}</div>}
|
|
77
73
|
</div>
|
|
78
74
|
);
|
|
79
75
|
};
|
|
@@ -34,9 +34,9 @@ const DeletePackagingUnitModal: React.FC<DeletePackagingUnitModalProps> = ({ row
|
|
|
34
34
|
closeModal();
|
|
35
35
|
showSnackbar({
|
|
36
36
|
isLowContrast: true,
|
|
37
|
-
title: t('
|
|
37
|
+
title: t('deletePackingItem', 'Delete packing item'),
|
|
38
38
|
kind: 'success',
|
|
39
|
-
subtitle: t('
|
|
39
|
+
subtitle: t('deletePackagingUnitMessage', 'Stock item packing unit deleted successfully'),
|
|
40
40
|
});
|
|
41
41
|
},
|
|
42
42
|
(error) => {
|
|
@@ -24,6 +24,7 @@ import { useStockItemPackageUnitsHook } from './packaging-units.resource';
|
|
|
24
24
|
import ControlledNumberInput from '../../../core/components/carbon/controlled-number-input.component';
|
|
25
25
|
import DeletePackagingUnitActionButton from './delete-packaging-unit-action-button.component';
|
|
26
26
|
import PackagingUnitsConceptSelector from '../packaging-units-concept-selector/packaging-units-concept-selector.component';
|
|
27
|
+
import { type CustomTableHeader, type CustomTableRow } from '../../../core/components/table/types';
|
|
27
28
|
import styles from './packaging-units.scss';
|
|
28
29
|
|
|
29
30
|
interface PackagingUnitsProps {
|
|
@@ -57,7 +58,7 @@ const PackagingUnits: React.FC<PackagingUnitsProps> = ({ stockItemUuid, handleTa
|
|
|
57
58
|
}, [items]);
|
|
58
59
|
|
|
59
60
|
const { t } = useTranslation();
|
|
60
|
-
const tableHeaders = useMemo(
|
|
61
|
+
const tableHeaders = useMemo<CustomTableHeader[]>(
|
|
61
62
|
() => [
|
|
62
63
|
{
|
|
63
64
|
key: 'packaging',
|
|
@@ -189,27 +190,40 @@ const PackagingUnits: React.FC<PackagingUnitsProps> = ({ stockItemUuid, handleTa
|
|
|
189
190
|
return (
|
|
190
191
|
<FormProvider {...packageUnitForm}>
|
|
191
192
|
<DataTable
|
|
192
|
-
rows={
|
|
193
|
-
|
|
193
|
+
rows={
|
|
194
|
+
[
|
|
195
|
+
...items.map((item, idx) => ({ ...item, id: item.uuid || `item-${idx}` })),
|
|
196
|
+
{ id: 'new-row' },
|
|
197
|
+
] as CustomTableRow[]
|
|
198
|
+
}
|
|
199
|
+
headers={tableHeaders as any}
|
|
194
200
|
isSortable={false}
|
|
195
|
-
useZebraStyles
|
|
196
|
-
|
|
201
|
+
useZebraStyles
|
|
202
|
+
>
|
|
203
|
+
{({ headers, getHeaderProps, getTableProps }) => (
|
|
197
204
|
<TableContainer className={styles.packagingTableContainer}>
|
|
198
205
|
<Table {...getTableProps()} className={styles.packingTable}>
|
|
199
206
|
<TableHead>
|
|
200
207
|
<TableRow>
|
|
201
|
-
{headers.map((header) =>
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
208
|
+
{headers.map((header) => {
|
|
209
|
+
const customHeader = header as CustomTableHeader;
|
|
210
|
+
return (
|
|
211
|
+
<TableHeader
|
|
212
|
+
{...getHeaderProps({
|
|
213
|
+
header,
|
|
214
|
+
isSortable: false,
|
|
215
|
+
})}
|
|
216
|
+
style={customHeader.styles}
|
|
217
|
+
key={header.key}
|
|
218
|
+
>
|
|
219
|
+
{typeof customHeader.header === 'object' &&
|
|
220
|
+
customHeader.header !== null &&
|
|
221
|
+
'content' in customHeader.header
|
|
222
|
+
? (customHeader.header.content as React.ReactNode)
|
|
223
|
+
: (customHeader.header as React.ReactNode)}
|
|
224
|
+
</TableHeader>
|
|
225
|
+
);
|
|
226
|
+
})}
|
|
213
227
|
<TableHeader style={{ width: '70%' }} />
|
|
214
228
|
</TableRow>
|
|
215
229
|
</TableHead>
|
|
@@ -232,7 +246,7 @@ const PackagingUnits: React.FC<PackagingUnitsProps> = ({ stockItemUuid, handleTa
|
|
|
232
246
|
</Table>
|
|
233
247
|
</TableContainer>
|
|
234
248
|
)}
|
|
235
|
-
|
|
249
|
+
</DataTable>
|
|
236
250
|
<div className={styles.packageUnitsBtn}>
|
|
237
251
|
<Button kind="secondary" onClick={handleCancelPackagingUnits}>
|
|
238
252
|
{getCoreTranslation('cancel')}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React, { type ReactNode } from 'react';
|
|
2
|
+
import { ComboBox, TextInputSkeleton } from '@carbon/react';
|
|
2
3
|
import { type Concept } from '../../../core/api/types/concept/Concept';
|
|
3
4
|
import { type Control, Controller, type FieldValues } from 'react-hook-form';
|
|
4
5
|
import { useConcept } from '../../../stock-lookups/stock-lookups.resource';
|
|
5
|
-
import {
|
|
6
|
+
import { type ConfigObject } from '../../../config-schema';
|
|
6
7
|
import { type StockItemPackagingUOMDTO } from '../../../core/api/types/stockItem/StockItemPackagingUOM';
|
|
7
8
|
import { useConfig } from '@openmrs/esm-framework';
|
|
8
|
-
import { type ConfigObject } from '../../../config-schema';
|
|
9
9
|
|
|
10
10
|
interface PackagingUnitsConceptSelectorProps<T> {
|
|
11
11
|
row?: StockItemPackagingUOMDTO;
|
|
@@ -38,9 +38,6 @@ const PackagingUnitsConceptSelector = <T,>(props: PackagingUnitsConceptSelectorP
|
|
|
38
38
|
render={({ field: { onChange } }) => (
|
|
39
39
|
<ComboBox
|
|
40
40
|
titleText={props.title}
|
|
41
|
-
name={props.name}
|
|
42
|
-
control={props.control}
|
|
43
|
-
controllerName={props.controllerName}
|
|
44
41
|
id={`${props.name}-${props.row.id}-${props.row.uuid}`}
|
|
45
42
|
size="md"
|
|
46
43
|
items={
|
|
@@ -37,9 +37,6 @@ const PreferredVendorSelector = <T,>(props: PreferredVendorSelectorProps<T>) =>
|
|
|
37
37
|
render={({ field: { onChange, value, ref } }) => (
|
|
38
38
|
<ComboBox
|
|
39
39
|
titleText={props.title}
|
|
40
|
-
name={props.name}
|
|
41
|
-
control={props.control}
|
|
42
|
-
controllerName={props.controllerName}
|
|
43
40
|
id={props.name}
|
|
44
41
|
size={'md'}
|
|
45
42
|
items={sourcesList || []}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React, { type ReactNode } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
2
3
|
import { type Control, Controller, type FieldValues } from 'react-hook-form';
|
|
3
4
|
import { type Concept } from '../../../core/api/types/concept/Concept';
|
|
4
5
|
import { ComboBox, TextInputSkeleton } from '@carbon/react';
|
|
6
|
+
import { useConfig } from '@openmrs/esm-framework';
|
|
5
7
|
import { useConcept } from '../../../stock-lookups/stock-lookups.resource';
|
|
6
8
|
import { type ConfigObject } from '../../../config-schema';
|
|
7
|
-
import { useConfig } from '@openmrs/esm-framework';
|
|
8
|
-
import { useTranslation } from 'react-i18next';
|
|
9
9
|
|
|
10
10
|
interface StockItemCategorySelectorProps<T> {
|
|
11
11
|
categoryUuid?: string;
|
|
@@ -42,9 +42,6 @@ const StockItemCategorySelector = <T,>(props: StockItemCategorySelectorProps<T>)
|
|
|
42
42
|
render={({ field: { onChange, value, ref } }) => (
|
|
43
43
|
<ComboBox
|
|
44
44
|
titleText={props.title}
|
|
45
|
-
name={props.name}
|
|
46
|
-
control={props.control}
|
|
47
|
-
controllerName={props.controllerName}
|
|
48
45
|
id={props.name}
|
|
49
46
|
size={'md'}
|
|
50
47
|
items={filteredCategories || []}
|
|
@@ -49,11 +49,11 @@ const StockItemDetails = forwardRef<never, StockItemDetailsProps>(
|
|
|
49
49
|
if (response?.data) {
|
|
50
50
|
showSnackbar({
|
|
51
51
|
isLowContrast: true,
|
|
52
|
-
title: stockItem ? `${t('editStockItem', 'Edit
|
|
52
|
+
title: stockItem ? `${t('editStockItem', 'Edit stock item')}` : `${t('addStockItem', 'Add stock item')}`,
|
|
53
53
|
kind: 'success',
|
|
54
54
|
subtitle: stockItem
|
|
55
|
-
? `${t('stockItemEdited', 'Stock
|
|
56
|
-
: `${t('stockItemAdded', 'Stock
|
|
55
|
+
? `${t('stockItemEdited', 'Stock item edited successfully')}`
|
|
56
|
+
: `${t('stockItemAdded', 'Stock item added successfully')}`,
|
|
57
57
|
});
|
|
58
58
|
if (!stockItem) {
|
|
59
59
|
onCloseWorkspace?.();
|
|
@@ -91,8 +91,8 @@ const StockItemDetails = forwardRef<never, StockItemDetailsProps>(
|
|
|
91
91
|
{!stockItem && (
|
|
92
92
|
<FormGroup
|
|
93
93
|
className="clear-margin-bottom"
|
|
94
|
-
legendText={t('itemType', 'Item
|
|
95
|
-
title={t('itemType', 'Item
|
|
94
|
+
legendText={t('itemType', 'Item type')}
|
|
95
|
+
title={t('itemType', 'Item type')}
|
|
96
96
|
>
|
|
97
97
|
<ControlledRadioButtonGroup
|
|
98
98
|
control={control}
|
|
@@ -110,8 +110,8 @@ const StockItemDetails = forwardRef<never, StockItemDetailsProps>(
|
|
|
110
110
|
name="drugUuid"
|
|
111
111
|
controllerName="drugUuid"
|
|
112
112
|
control={control}
|
|
113
|
-
title={t('pleaseSpecify', 'Please specify
|
|
114
|
-
placeholder=
|
|
113
|
+
title={t('pleaseSpecify', 'Please specify')}
|
|
114
|
+
placeholder={t('chooseADrug', 'Choose a drug')}
|
|
115
115
|
drugUuid={stockItem?.drugUuid}
|
|
116
116
|
invalid={!!errors.drugUuid}
|
|
117
117
|
invalidText={errors.drugUuid && errors?.drugUuid?.message}
|
|
@@ -121,7 +121,7 @@ const StockItemDetails = forwardRef<never, StockItemDetailsProps>(
|
|
|
121
121
|
name="conceptUuid"
|
|
122
122
|
controllerName="conceptUuid"
|
|
123
123
|
control={control}
|
|
124
|
-
title={t('pleaseSpecify', 'Please specify')
|
|
124
|
+
title={t('pleaseSpecify', 'Please specify')}
|
|
125
125
|
placeholder={t('chooseAnItem', 'Choose an item')}
|
|
126
126
|
invalid={!!errors.drugUuid}
|
|
127
127
|
invalidText={errors.drugUuid && errors?.drugUuid?.message}
|
|
@@ -174,7 +174,7 @@ const StockItemDetails = forwardRef<never, StockItemDetailsProps>(
|
|
|
174
174
|
</FormGroup>
|
|
175
175
|
|
|
176
176
|
{observableHasExpiration && (
|
|
177
|
-
<FormGroup className="clear-margin-bottom"
|
|
177
|
+
<FormGroup className="clear-margin-bottom" legendText={t('expirationNotice', 'Expiration Notice (days)')}>
|
|
178
178
|
<ControlledNumberInput
|
|
179
179
|
id="expiryNotice"
|
|
180
180
|
name="expiryNotice"
|
|
@@ -221,7 +221,7 @@ const StockItemDetails = forwardRef<never, StockItemDetailsProps>(
|
|
|
221
221
|
name="dispensingUnitUuid"
|
|
222
222
|
controllerName="dispensingUnitUuid"
|
|
223
223
|
control={control}
|
|
224
|
-
title={t('dispensingUnit', 'Dispensing
|
|
224
|
+
title={t('dispensingUnit', 'Dispensing unit') + ':'}
|
|
225
225
|
placeholder={t('dispensingUnitHolder', 'Choose a dispensing unit')}
|
|
226
226
|
invalid={!!errors.dispensingUnitUuid}
|
|
227
227
|
invalidText={errors.dispensingUnitUuid && errors?.dispensingUnitUuid?.message}
|
package/src/stock-items/add-stock-item/stock-item-references/stock-item-references.component.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
3
3
|
import {
|
|
4
4
|
Button,
|
|
5
5
|
DataTable,
|
|
6
|
+
DataTableSkeleton,
|
|
6
7
|
Table,
|
|
7
8
|
TableBody,
|
|
8
9
|
TableCell,
|
|
@@ -10,22 +11,22 @@ import {
|
|
|
10
11
|
TableHead,
|
|
11
12
|
TableHeader,
|
|
12
13
|
TableRow,
|
|
13
|
-
DataTableSkeleton,
|
|
14
14
|
} from '@carbon/react';
|
|
15
|
-
import styles from './stock-item-references.scss';
|
|
16
15
|
import { TrashCan, Save } from '@carbon/react/icons';
|
|
17
16
|
import { FormProvider, useForm, useFormContext } from 'react-hook-form';
|
|
18
|
-
import StockSourceSelector from './stock-references-selector.component';
|
|
19
17
|
import { useStockItemReferencesHook } from './stock-item-references.resource';
|
|
20
18
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
21
19
|
import { type StockItemReferenceData } from './validation-schema';
|
|
22
20
|
import { stockItemDetailsSchema } from '../../validationSchema';
|
|
23
21
|
import { type StockItemReferenceDTO } from '../../../core/api/types/stockItem/StockItemReference';
|
|
24
|
-
import ControlledTextInput from '../../../core/components/carbon/controlled-text-input.component';
|
|
25
22
|
import { createStockItemReference, deleteStockItemReference } from '../../stock-items.resource';
|
|
26
23
|
import { restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
|
|
27
24
|
import { extractErrorMessagesFromResponse } from '../../../constants';
|
|
28
25
|
import { handleMutate } from '../../../utils';
|
|
26
|
+
import ControlledTextInput from '../../../core/components/carbon/controlled-text-input.component';
|
|
27
|
+
import StockSourceSelector from './stock-references-selector.component';
|
|
28
|
+
import { type CustomTableHeader, type CustomTableRow } from '../../../core/components/table/types';
|
|
29
|
+
import styles from './stock-item-references.scss';
|
|
29
30
|
|
|
30
31
|
interface StockReferencesProps {
|
|
31
32
|
isEditing?: boolean;
|
|
@@ -42,7 +43,7 @@ const StockReferences: React.FC<StockReferencesProps> = ({ stockItemUuid }) => {
|
|
|
42
43
|
setStockItemUuid(stockItemUuid);
|
|
43
44
|
}, [stockItemUuid, setStockItemUuid]);
|
|
44
45
|
|
|
45
|
-
const tableHeaders = useMemo(
|
|
46
|
+
const tableHeaders = useMemo<CustomTableHeader[]>(
|
|
46
47
|
() => [
|
|
47
48
|
{
|
|
48
49
|
key: 'source',
|
|
@@ -84,7 +85,7 @@ const StockReferences: React.FC<StockReferencesProps> = ({ stockItemUuid }) => {
|
|
|
84
85
|
handleMutate(`${restBaseUrl}/stockmanagement/stockitemreference`);
|
|
85
86
|
|
|
86
87
|
showSnackbar({
|
|
87
|
-
title: t('saveReferenceTitle', '
|
|
88
|
+
title: t('saveReferenceTitle', 'Stock Item Reference'),
|
|
88
89
|
subtitle: t('saveStockItemReferenceMessage', 'Stock Item Reference saved successfully'),
|
|
89
90
|
kind: 'success',
|
|
90
91
|
});
|
|
@@ -94,7 +95,7 @@ const StockReferences: React.FC<StockReferencesProps> = ({ stockItemUuid }) => {
|
|
|
94
95
|
|
|
95
96
|
const err = extractErrorMessagesFromResponse(error);
|
|
96
97
|
showSnackbar({
|
|
97
|
-
title: t('saveStockItemReferenceErrorTitle', '
|
|
98
|
+
title: t('saveStockItemReferenceErrorTitle', 'Stock Item Reference'),
|
|
98
99
|
subtitle: t('saveStockItemReferenceErrorMessage', 'Error saving stock item reference' + err.join(',')),
|
|
99
100
|
kind: 'error',
|
|
100
101
|
});
|
|
@@ -107,27 +108,35 @@ const StockReferences: React.FC<StockReferencesProps> = ({ stockItemUuid }) => {
|
|
|
107
108
|
return (
|
|
108
109
|
<FormProvider {...stockReferenceForm}>
|
|
109
110
|
<DataTable
|
|
110
|
-
rows={items ?? []}
|
|
111
|
-
headers={tableHeaders}
|
|
111
|
+
rows={(items ?? []).map((item, idx) => ({ ...item, id: item.uuid || `ref-${idx}` })) as CustomTableRow[]}
|
|
112
|
+
headers={tableHeaders as any}
|
|
112
113
|
isSortable={false}
|
|
113
|
-
useZebraStyles
|
|
114
|
-
|
|
114
|
+
useZebraStyles
|
|
115
|
+
>
|
|
116
|
+
{({ headers, getHeaderProps, getTableProps }) => (
|
|
115
117
|
<TableContainer className={styles.referencesTableContainer}>
|
|
116
118
|
<Table {...getTableProps()} className={styles.referencesTable}>
|
|
117
119
|
<TableHead>
|
|
118
120
|
<TableRow>
|
|
119
|
-
{headers.map((header) =>
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
121
|
+
{headers.map((header) => {
|
|
122
|
+
const customHeader = header as CustomTableHeader;
|
|
123
|
+
return (
|
|
124
|
+
<TableHeader
|
|
125
|
+
{...getHeaderProps({
|
|
126
|
+
header,
|
|
127
|
+
isSortable: false,
|
|
128
|
+
})}
|
|
129
|
+
style={customHeader.styles}
|
|
130
|
+
key={header.key}
|
|
131
|
+
>
|
|
132
|
+
{typeof customHeader.header === 'object' &&
|
|
133
|
+
customHeader.header !== null &&
|
|
134
|
+
'content' in customHeader.header
|
|
135
|
+
? (customHeader.header.content as React.ReactNode)
|
|
136
|
+
: (customHeader.header as React.ReactNode)}
|
|
137
|
+
</TableHeader>
|
|
138
|
+
);
|
|
139
|
+
})}
|
|
131
140
|
<TableHeader style={{ width: '70%' }} />
|
|
132
141
|
</TableRow>
|
|
133
142
|
</TableHead>
|
|
@@ -140,7 +149,7 @@ const StockReferences: React.FC<StockReferencesProps> = ({ stockItemUuid }) => {
|
|
|
140
149
|
</Table>
|
|
141
150
|
</TableContainer>
|
|
142
151
|
)}
|
|
143
|
-
|
|
152
|
+
</DataTable>
|
|
144
153
|
|
|
145
154
|
<Button
|
|
146
155
|
name="save"
|
|
@@ -171,9 +180,9 @@ const StockReferencesRow: React.FC<{
|
|
|
171
180
|
deleteStockItemReference(row.uuid).then(
|
|
172
181
|
() => {
|
|
173
182
|
showSnackbar({
|
|
174
|
-
title: t('
|
|
183
|
+
title: t('deleteStockItemReference', 'Delete stock item reference'),
|
|
175
184
|
kind: 'success',
|
|
176
|
-
subtitle: t('
|
|
185
|
+
subtitle: t('deleteStockItemReferenceMessage', 'Stock item reference deleted successfully'),
|
|
177
186
|
});
|
|
178
187
|
},
|
|
179
188
|
(error) => {
|
|
@@ -217,7 +226,7 @@ const StockReferencesRow: React.FC<{
|
|
|
217
226
|
type="button"
|
|
218
227
|
size="sm"
|
|
219
228
|
className="submitButton clear-padding-margin"
|
|
220
|
-
iconDescription={'Delete'}
|
|
229
|
+
iconDescription={t('delete', 'Delete')}
|
|
221
230
|
kind="ghost"
|
|
222
231
|
renderIcon={TrashCan}
|
|
223
232
|
onClick={(e) => handleDelete(e)}
|
package/src/stock-items/add-stock-item/stock-item-references/stock-references-selector.component.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ComboBox, TextInputSkeleton } from '@carbon/react';
|
|
3
3
|
import { type Control, Controller, type FieldValues } from 'react-hook-form';
|
|
4
4
|
import { type StockSource } from '../../../core/api/types/stockOperation/StockSource';
|
|
5
|
-
import { ResourceRepresentation } from '../../../core/api/api';
|
|
6
5
|
import { useStockSources } from '../../../stock-sources/stock-sources.resource';
|
|
7
6
|
import { type Concept } from '../../../core/api/types/concept/Concept';
|
|
8
7
|
import { type StockItemReferenceDTO } from '../../../core/api/types/stockItem/StockItemReference';
|
|
8
|
+
import { ResourceRepresentation } from '../../../core/api/api';
|
|
9
9
|
|
|
10
10
|
interface StockSourceSelectorProps<T> {
|
|
11
11
|
row?: StockItemReferenceDTO;
|
|
@@ -36,9 +36,6 @@ const StockSourceSelector = <T,>(props: StockSourceSelectorProps<T>) => {
|
|
|
36
36
|
render={({ field: { onChange, value, ref } }) => (
|
|
37
37
|
<ComboBox
|
|
38
38
|
titleText={props.title}
|
|
39
|
-
name={props.name}
|
|
40
|
-
control={props.control}
|
|
41
|
-
controllerName={props.controllerName}
|
|
42
39
|
id={props.name}
|
|
43
40
|
size={'md'}
|
|
44
41
|
items={sourcesList || []}
|