@openmrs/esm-stock-management-app 3.0.1-pre.805 → 3.0.1-pre.826

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.
Files changed (196) hide show
  1. package/.eslintrc +10 -1
  2. package/dist/10.js +1 -0
  3. package/dist/10.js.map +1 -0
  4. package/dist/165.js +1 -1
  5. package/dist/165.js.map +1 -1
  6. package/dist/20.js +1 -1
  7. package/dist/20.js.map +1 -1
  8. package/dist/606.js.map +1 -1
  9. package/dist/642.js +1 -0
  10. package/dist/642.js.map +1 -0
  11. package/dist/675.js +1 -0
  12. package/dist/675.js.map +1 -0
  13. package/dist/{880.js → 727.js} +1 -1
  14. package/dist/727.js.map +1 -0
  15. package/dist/780.js +1 -0
  16. package/dist/780.js.map +1 -0
  17. package/dist/793.js +1 -1
  18. package/dist/793.js.map +1 -1
  19. package/dist/main.js +1 -1
  20. package/dist/main.js.map +1 -1
  21. package/dist/openmrs-esm-stock-management-app.js +1 -1
  22. package/dist/openmrs-esm-stock-management-app.js.buildmanifest.json +132 -59
  23. package/dist/openmrs-esm-stock-management-app.js.map +1 -1
  24. package/dist/routes.json +1 -1
  25. package/package.json +3 -2
  26. package/src/core/api/api.ts +1 -1
  27. package/src/core/api/types/Auditable.ts +2 -2
  28. package/src/core/api/types/BaseOpenmrsData.ts +2 -2
  29. package/src/core/api/types/BaseOpenmrsMetadata.ts +2 -2
  30. package/src/core/api/types/BaseOpenmrsObject.ts +1 -1
  31. package/src/core/api/types/BatchJob.ts +1 -1
  32. package/src/core/api/types/LocationTree.ts +1 -1
  33. package/src/core/api/types/OpenmrsData.ts +3 -3
  34. package/src/core/api/types/OpenmrsMetadata.ts +3 -3
  35. package/src/core/api/types/Retireable.ts +2 -2
  36. package/src/core/api/types/Voidable.ts +2 -2
  37. package/src/core/api/types/concept/Concept.ts +4 -4
  38. package/src/core/api/types/concept/ConceptName.ts +2 -2
  39. package/src/core/api/types/concept/Drug.ts +2 -2
  40. package/src/core/api/types/identity/Patient.ts +1 -1
  41. package/src/core/api/types/identity/Privilege.ts +1 -1
  42. package/src/core/api/types/identity/Session.ts +3 -3
  43. package/src/core/api/types/identity/User.ts +2 -2
  44. package/src/core/api/types/identity/UserRoleScope.ts +3 -3
  45. package/src/core/api/types/identity/UserRoleScopeLocation.ts +1 -1
  46. package/src/core/api/types/identity/UserRoleScopeOperationType.ts +1 -1
  47. package/src/core/api/types/stockItem/StockBatch.ts +2 -2
  48. package/src/core/api/types/stockItem/StockItem.ts +6 -6
  49. package/src/core/api/types/stockItem/StockItemPackagingUOM.ts +3 -3
  50. package/src/core/api/types/stockItem/StockItemReference.ts +3 -3
  51. package/src/core/api/types/stockItem/StockItemTransaction.ts +1 -1
  52. package/src/core/api/types/stockItem/StockRule.ts +1 -1
  53. package/src/core/api/types/stockOperation/StockOperation.ts +8 -8
  54. package/src/core/api/types/stockOperation/StockOperationDTO.ts +3 -3
  55. package/src/core/api/types/stockOperation/StockOperationItem.ts +5 -5
  56. package/src/core/api/types/stockOperation/StockOperationItemDTO.ts +2 -2
  57. package/src/core/api/types/stockOperation/StockOperationType.ts +2 -2
  58. package/src/core/api/types/stockOperation/StockSource.ts +2 -2
  59. package/src/core/components/carbon/controlled-combo-box/controlled-combo-box.component.tsx +1 -1
  60. package/src/core/components/carbon/controlled-dropdown/controlled-dropdown.component.tsx +2 -2
  61. package/src/core/components/carbon/controlled-number-input/controlled-number-input.component.tsx +3 -3
  62. package/src/core/components/carbon/controlled-radio-button-group/controlled-radio-button-group.component.tsx +3 -3
  63. package/src/core/components/carbon/controlled-text-area/controlled-text-area.component.tsx +3 -3
  64. package/src/core/components/carbon/controlled-text-input/controlled-text-input.component.tsx +3 -3
  65. package/src/core/components/carbon/types.ts +1 -1
  66. package/src/core/components/side-nav/side-nav.component.tsx +1 -1
  67. package/src/core/components/table/table.component.tsx +1 -1
  68. package/src/core/components/table/types.ts +1 -1
  69. package/src/core/components/tabs/types.ts +1 -1
  70. package/src/core/components/tabs/vertical-tabs.component.tsx +1 -1
  71. package/src/core/print/PrintTemplate.ts +1 -1
  72. package/src/core/utils/utils.ts +1 -1
  73. package/src/index.ts +8 -0
  74. package/src/routes.json +14 -0
  75. package/src/stock-batch/stock-batch.resource.ts +4 -4
  76. package/src/stock-home/stock-home-inventory-expiry.resource.tsx +1 -1
  77. package/src/stock-home/stock-home-inventory-items.resource.tsx +1 -1
  78. package/src/stock-home/stock-home-issuing.resource.tsx +1 -1
  79. package/src/stock-home/stock-home-metrics.tsx +1 -1
  80. package/src/stock-home/stock-home-receiving.resource.tsx +1 -1
  81. package/src/stock-home/useDisposalList.tsx +1 -1
  82. package/src/stock-items/add-stock-item/add-stock-action-button.component.tsx +2 -3
  83. package/src/stock-items/add-stock-item/add-stock-item.component.tsx +30 -21
  84. package/src/stock-items/add-stock-item/add-stock-item.resource.tsx +1 -1
  85. package/src/stock-items/add-stock-item/add-stock-item.scss +22 -3
  86. package/src/stock-items/add-stock-item/add-stock-item.test.tsx +12 -12
  87. package/src/stock-items/add-stock-item/batch-information/batch-information-locations/batch-information-locations-filter.component.tsx +2 -2
  88. package/src/stock-items/add-stock-item/batch-information/batch-information.component.tsx +1 -1
  89. package/src/stock-items/add-stock-item/batch-information/batch-information.resource.tsx +1 -1
  90. package/src/stock-items/add-stock-item/concepts-selector/concepts-selector.component.tsx +3 -3
  91. package/src/stock-items/add-stock-item/dispensing-package-measurement/dispensing-package-measurement.component.tsx +3 -3
  92. package/src/stock-items/add-stock-item/dispensing-unit-selector/dispensing-unit-selector.component.tsx +3 -3
  93. package/src/stock-items/add-stock-item/drug-selector/drug-selector.component.tsx +3 -3
  94. package/src/stock-items/add-stock-item/drug-selector/drug-selector.resource.tsx +1 -1
  95. package/src/stock-items/add-stock-item/packaging-units/packaging-units-delete-modal-button.component.tsx +1 -1
  96. package/src/stock-items/add-stock-item/packaging-units/packaging-units-delete-modal.component.tsx +1 -1
  97. package/src/stock-items/add-stock-item/packaging-units/packaging-units.component.tsx +10 -11
  98. package/src/stock-items/add-stock-item/packaging-units/packaging-units.resource.tsx +2 -2
  99. package/src/stock-items/add-stock-item/packaging-units-concept-selector/packaging-units-concept-selector.component.tsx +4 -4
  100. package/src/stock-items/add-stock-item/preferred-vendor-selector/preferred-vendor-selector.component.tsx +4 -4
  101. package/src/stock-items/add-stock-item/quantities/quantities.resource.tsx +1 -1
  102. package/src/stock-items/add-stock-item/stock-item-category-selector/stock-item-category-selector.component.tsx +3 -3
  103. package/src/stock-items/add-stock-item/stock-item-details/stock-item-details.component.tsx +226 -214
  104. package/src/stock-items/add-stock-item/stock-item-details/stock-item-details.resource.tsx +7 -2
  105. package/src/stock-items/add-stock-item/stock-item-references/stock-item-references.component.tsx +2 -2
  106. package/src/stock-items/add-stock-item/stock-item-references/stock-item-references.resource.ts +1 -1
  107. package/src/stock-items/add-stock-item/stock-item-references/stock-references-selector.component.tsx +4 -4
  108. package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rule-button.component.tsx +6 -4
  109. package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rules.component.tsx +163 -167
  110. package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rules.scss +19 -11
  111. package/src/stock-items/add-stock-item/stock-item-rules/edit-stock-rule.component.tsx +9 -6
  112. package/src/stock-items/add-stock-item/stock-item-rules/stock-item-rules.component.tsx +1 -1
  113. package/src/stock-items/add-stock-item/stock-item-rules/stock-item-rules.resource.tsx +1 -1
  114. package/src/stock-items/add-stock-item/stock-item-rules/stock-rules.resource.ts +3 -3
  115. package/src/stock-items/add-stock-item/stock-item-units-edit/stock-item-units-edit.component.tsx +2 -2
  116. package/src/stock-items/add-stock-item/transactions/printout/transactions-print-action.component.tsx +2 -3
  117. package/src/stock-items/add-stock-item/transactions/transaction-filters/transaction-locations-filter.component.tsx +2 -2
  118. package/src/stock-items/add-stock-item/transactions/transactions.component.tsx +1 -1
  119. package/src/stock-items/add-stock-item/transactions/transactions.resource.tsx +1 -1
  120. package/src/stock-items/edit-stock-item/edit-stock-item-action-menu.component.tsx +3 -3
  121. package/src/stock-items/stock-item.utils.tsx +7 -50
  122. package/src/stock-items/stock-items-table.component.tsx +2 -2
  123. package/src/stock-items/stock-items-table.resource.ts +1 -1
  124. package/src/stock-items/stock-items-table.test.tsx +28 -23
  125. package/src/stock-items/stock-items.resource.ts +17 -15
  126. package/src/stock-items/types.ts +3 -3
  127. package/src/stock-locations/add-locations-form.component.tsx +1 -1
  128. package/src/stock-locations/location-admin-form.component.tsx +1 -1
  129. package/src/stock-locations/stock-locations-table.resource.tsx +2 -2
  130. package/src/stock-lookups/stock-lookups.resource.ts +13 -13
  131. package/src/stock-operations/add-stock-operation/stock-operations-expanded-row/stock-items-table.tsx +1 -1
  132. package/src/stock-operations/add-stock-operation/stock-operations-expanded-row/stock-operation-expanded-row.component.tsx +1 -1
  133. package/src/stock-operations/edit-stock-operation/edit-stock-operation-action-menu.component.tsx +1 -1
  134. package/src/stock-operations/stock-operation-actions.component.tsx +2 -2
  135. package/src/stock-operations/stock-operation-links.component.tsx +2 -2
  136. package/src/stock-operations/stock-operation-status/stock-operation-status-row.tsx +1 -1
  137. package/src/stock-operations/stock-operation-types-selector/stock-operation-types-selector.component.tsx +1 -1
  138. package/src/stock-operations/stock-operation.utils.tsx +3 -3
  139. package/src/stock-operations/stock-operations-dialog/stock-operations-approve-button.component.tsx +1 -1
  140. package/src/stock-operations/stock-operations-dialog/stock-operations-approve-dispatch-button.component.tsx +1 -1
  141. package/src/stock-operations/stock-operations-dialog/stock-operations-cancel-button.component.tsx +1 -1
  142. package/src/stock-operations/stock-operations-dialog/stock-operations-complete-button.component.tsx +1 -1
  143. package/src/stock-operations/stock-operations-dialog/stock-operations-completed-dispatch-button.component.tsx +1 -1
  144. package/src/stock-operations/stock-operations-dialog/stock-operations-dialog.component.tsx +5 -2
  145. package/src/stock-operations/stock-operations-dialog/stock-operations-issue-stock-button.component.tsx +1 -1
  146. package/src/stock-operations/stock-operations-dialog/stock-operations-print-button.component.tsx +5 -6
  147. package/src/stock-operations/stock-operations-dialog/stock-operations-reject-button.component.tsx +1 -1
  148. package/src/stock-operations/stock-operations-dialog/stock-operations-return-button.component.tsx +1 -1
  149. package/src/stock-operations/stock-operations-forms/hooks/useFilterableStockItems.ts +2 -2
  150. package/src/stock-operations/stock-operations-forms/hooks/useOperationTypePermisions.ts +1 -1
  151. package/src/stock-operations/stock-operations-forms/hooks/useParties.ts +3 -3
  152. package/src/stock-operations/stock-operations-forms/hooks/useSearchUser.ts +5 -1
  153. package/src/stock-operations/stock-operations-forms/hooks/useStockItemBatchNumbers.ts +1 -1
  154. package/src/stock-operations/stock-operations-forms/hooks/useStockOperationLinks.ts +2 -2
  155. package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.component.tsx +1 -1
  156. package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.test.tsx +1 -1
  157. package/src/stock-operations/stock-operations-forms/input-components/quantity-uom-selector.component.tsx +1 -1
  158. package/src/stock-operations/stock-operations-forms/input-components/stock-item-search.component.tsx +2 -2
  159. package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.component.tsx +2 -2
  160. package/src/stock-operations/stock-operations-forms/input-components/unique-batch-no-entry-input.component.tsx +2 -3
  161. package/src/stock-operations/stock-operations-forms/input-components/users-selector.component.tsx +2 -4
  162. package/src/stock-operations/stock-operations-forms/step2.test.tsx +3 -4
  163. package/src/stock-operations/stock-operations-forms/step3.test.tsx +1 -2
  164. package/src/stock-operations/stock-operations-forms/steps/base-operation-details-form-step.tsx +16 -7
  165. package/src/stock-operations/stock-operations-forms/steps/received-items.component.tsx +1 -1
  166. package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-batch-no-cell.component.tsx +1 -1
  167. package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-cell.component.tsx +1 -1
  168. package/src/stock-operations/stock-operations-forms/steps/stock-operation-item-expiry-cell.component.tsx +1 -1
  169. package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.component.tsx +3 -3
  170. package/src/stock-operations/stock-operations-forms/steps/stock-operation-submission-form-step.component.tsx +4 -4
  171. package/src/stock-operations/stock-operations-forms/stock-issue-form-initializer-with-related-requisition-operation.component.tsx +2 -2
  172. package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.workspace.tsx +7 -4
  173. package/src/stock-operations/stock-operations-forms/stock-operation-form.component.tsx +9 -9
  174. package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stock-operation-stepper.component.tsx +1 -0
  175. package/src/stock-operations/stock-operations-forms/stock-operations-form-utils.ts +1 -1
  176. package/src/stock-operations/stock-operations-table.component.tsx +1 -1
  177. package/src/stock-operations/stock-operations-table.resource.tsx +1 -1
  178. package/src/stock-operations/stock-operations.resource.ts +9 -9
  179. package/src/stock-operations/stock-print-reports/GoodsReceivedNote.tsx +1 -1
  180. package/src/stock-operations/stock-print-reports/RequisitionDocument.tsx +1 -1
  181. package/src/stock-operations/stock-print-reports/StockOperationReport.tsx +4 -4
  182. package/src/stock-operations/stock-print-reports/StockTransferDocument.tsx +1 -1
  183. package/src/stock-reports/generate-report/create-stock-report.component.tsx +3 -3
  184. package/src/stock-reports/stock-reports.resource.ts +1 -1
  185. package/src/stock-sources/add-stock-sources/add-stock-sources.component.tsx +2 -2
  186. package/src/stock-sources/add-stock-sources/add-stock-sources.test.tsx +2 -2
  187. package/src/stock-sources/edit-stock-source/edit-stock-source.component.tsx +1 -1
  188. package/src/stock-sources/stock-sources-items-table.resource.ts +1 -1
  189. package/src/stock-sources/stock-sources.resource.ts +3 -3
  190. package/src/stock-user-role-scopes/add-stock-user-scope/add-stock-user-role-scope.component.tsx +7 -7
  191. package/src/stock-user-role-scopes/edit-stock-user-scope/edit-stock-user-scope-action-menu.component.tsx +1 -1
  192. package/src/stock-user-role-scopes/stock-user-role-scopes-items-table.resource.ts +1 -1
  193. package/src/stock-user-role-scopes/stock-user-role-scopes.resource.ts +3 -3
  194. package/dist/600.js +0 -1
  195. package/dist/600.js.map +0 -1
  196. package/dist/880.js.map +0 -1
@@ -1,239 +1,251 @@
1
- import React, { forwardRef, useEffect, useState } from 'react';
2
- import { useTranslation } from 'react-i18next';
1
+ import { Button, ButtonSet, FormGroup, InlineLoading } from '@carbon/react';
3
2
  import { Save } from '@carbon/react/icons';
4
-
5
- import { Button, FormGroup, InlineLoading } from '@carbon/react';
6
- import { StockItemDTO } from '../../../core/api/types/stockItem/StockItem';
7
- import DrugSelector from '../drug-selector/drug-selector.component';
8
- import { useForm } from 'react-hook-form';
9
3
  import { zodResolver } from '@hookform/resolvers/zod';
10
- import { stockItemDetailsSchema, StockItemFormData } from '../../validationSchema';
11
- import ControlledRadioButtonGroup from '../../../core/components/carbon/controlled-radio-button-group/controlled-radio-button-group.component';
4
+ import { restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
5
+ import React, { forwardRef, useMemo } from 'react';
6
+ import { type SubmitHandler, useForm } from 'react-hook-form';
7
+ import { useTranslation } from 'react-i18next';
8
+ import { type StockItemDTO } from '../../../core/api/types/stockItem/StockItem';
12
9
  import ControlledNumberInput from '../../../core/components/carbon/controlled-number-input/controlled-number-input.component';
10
+ import ControlledRadioButtonGroup from '../../../core/components/carbon/controlled-radio-button-group/controlled-radio-button-group.component';
13
11
  import ControlledTextInput from '../../../core/components/carbon/controlled-text-input/controlled-text-input.component';
12
+ import { handleMutate } from '../../../utils';
13
+ import styles from '../../add-stock-item/add-stock-item.scss';
14
+ import { launchAddOrStockItemWorkspace } from '../../stock-item.utils';
15
+ import { createStockItem, updateStockItem } from '../../stock-items.resource';
16
+ import { stockItemDetailsSchema, type StockItemFormData } from '../../validationSchema';
17
+ import ConceptsSelector from '../concepts-selector/concepts-selector.component';
14
18
  import DispensingUnitSelector from '../dispensing-unit-selector/dispensing-unit-selector.component';
19
+ import DrugSelector from '../drug-selector/drug-selector.component';
15
20
  import PreferredVendorSelector from '../preferred-vendor-selector/preferred-vendor-selector.component';
16
21
  import StockItemCategorySelector from '../stock-item-category-selector/stock-item-category-selector.component';
17
22
  import StockItemUnitsEdit from '../stock-item-units-edit/stock-item-units-edit.component';
18
- import { SaveStockItem } from '../../types';
19
- import ConceptsSelector from '../concepts-selector/concepts-selector.component';
20
- import styles from '../../add-stock-item/add-stock-item.scss';
21
- import { closeOverlay } from '../../../core/components/overlay/hook';
22
- import { expirationOptions, radioOptions } from './stock-item-details.resource';
23
- import { restBaseUrl } from '@openmrs/esm-framework';
24
- import { handleMutate } from '../../../utils';
23
+ import { expirationOptions, radioOptions, StockItemType } from './stock-item-details.resource';
25
24
 
26
25
  interface StockItemDetailsProps {
27
- model: StockItemDTO;
28
- onSave: SaveStockItem;
29
- isEditing?: boolean;
26
+ stockItem?: StockItemDTO;
30
27
  handleTabChange: (index) => void;
28
+ onCloseWorkspace?: () => void;
31
29
  }
32
30
 
33
- const StockItemDetails = forwardRef<never, StockItemDetailsProps>(({ model, onSave, isEditing, handleTabChange }) => {
34
- const { t } = useTranslation();
35
- const { handleSubmit, control, formState } = useForm<StockItemFormData>({
36
- defaultValues: model,
37
- mode: 'all',
38
- resolver: zodResolver(stockItemDetailsSchema),
39
- });
40
-
41
- const { errors } = formState;
42
- const handleSave = async (item: StockItemDTO) => {
43
- try {
44
- setIsSaving(true);
45
-
46
- // Restore uuid
47
- item.uuid = model.uuid;
48
- await onSave(item);
49
- handleTabChange(1);
50
- handleMutate(`${restBaseUrl}/stockmanagement/stockitem`);
51
- } catch (e) {
52
- // Show notification
53
- } finally {
54
- setIsSaving(false);
55
- }
56
- };
31
+ const StockItemDetails = forwardRef<never, StockItemDetailsProps>(
32
+ ({ stockItem, handleTabChange, onCloseWorkspace }) => {
33
+ const { t } = useTranslation();
34
+ const { handleSubmit, control, formState, watch } = useForm<StockItemFormData>({
35
+ defaultValues: stockItem ?? {},
36
+ mode: 'all',
37
+ resolver: zodResolver(stockItemDetailsSchema),
38
+ });
57
39
 
58
- const [isSaving, setIsSaving] = useState(false);
59
- const [isDrug, setIsDrug] = useState(false);
60
- const [selectedItemType, setSelectedItemType] = useState('');
61
- const [hasExpiration, setHasExpiration] = useState(false);
40
+ const { errors } = formState;
41
+ const handleSave: SubmitHandler<StockItemFormData> = async (formValues) => {
42
+ try {
43
+ const response = stockItem
44
+ ? await updateStockItem(stockItem?.uuid, formValues)
45
+ : await createStockItem(formValues);
46
+ if (response?.data) {
47
+ showSnackbar({
48
+ isLowContrast: true,
49
+ title: stockItem ? `${t('editStockItem', 'Edit Stock Item')}` : `${t('addStockItem', 'Add Stock Item')}`,
50
+ kind: 'success',
51
+ subtitle: stockItem
52
+ ? `${t('stockItemEdited', 'Stock Item Edited Successfully')}`
53
+ : `${t('stockItemAdded', 'Stock Item Added Successfully')}`,
54
+ });
55
+ if (!stockItem) {
56
+ onCloseWorkspace?.();
57
+ // launch edit dialog
58
+ const item = response.data;
59
+ item.isDrug = !!item.drugUuid;
60
+ launchAddOrStockItemWorkspace(t, item);
61
+ }
62
+ }
62
63
 
63
- useEffect(() => {
64
- setIsDrug(model.isDrug ?? false);
65
- setHasExpiration(model.hasExpiration ?? false);
66
- }, [model.hasExpiration, model.isDrug]);
64
+ handleTabChange(1);
65
+ handleMutate(`${restBaseUrl}/stockmanagement/stockitem`);
66
+ } catch (e) {
67
+ // Show notification
68
+ showSnackbar({
69
+ title: stockItem
70
+ ? t('errorEditingStockItem', 'Error editing a stock Item')
71
+ : t('errorAddingStockItem', 'Error adding a stock Item'),
72
+ kind: 'error',
73
+ isLowContrast: true,
74
+ subtitle: e?.responseBody?.error?.message,
75
+ });
76
+ }
77
+ };
78
+ const [observableIsDrug, observableHasExpiration] = watch(['isDrug', 'hasExpiration']);
79
+ const selectedItemType = useMemo<StockItemType | null>(() => {
80
+ if (observableIsDrug === true) return StockItemType.PHARMACEUTICALS;
81
+ else if (observableIsDrug === false) return StockItemType.NONE_PHARMACEUTICALS;
82
+ return null;
83
+ }, [observableIsDrug]);
67
84
 
68
- return (
69
- <form className={`${styles.formContainer} ${styles.verticalForm}`}>
70
- {!isEditing && (
71
- <FormGroup
72
- className="clear-margin-bottom"
73
- legendText={t('itemType', 'Item Type')}
74
- title={t('itemType', 'Item Type')}
75
- >
76
- <ControlledRadioButtonGroup
85
+ return (
86
+ <form className={styles.formContainer}>
87
+ <div>
88
+ {!stockItem && (
89
+ <FormGroup
90
+ className="clear-margin-bottom"
91
+ legendText={t('itemType', 'Item Type')}
92
+ title={t('itemType', 'Item Type')}
93
+ >
94
+ <ControlledRadioButtonGroup
95
+ control={control}
96
+ name="isDrug"
97
+ controllerName="isDrug"
98
+ legendText=""
99
+ invalid={!!errors.isDrug}
100
+ invalidText={errors.isDrug && errors?.isDrug?.message}
101
+ options={radioOptions} // Pass radioOptions directly
102
+ />
103
+ </FormGroup>
104
+ )}
105
+ {selectedItemType === StockItemType.PHARMACEUTICALS ? (
106
+ <DrugSelector
107
+ name="drugUuid"
108
+ controllerName="drugUuid"
109
+ control={control}
110
+ title={t('pleaseSpecify', 'Please specify:')}
111
+ placeholder="Choose a drug"
112
+ drugUuid={stockItem?.drugUuid}
113
+ invalid={!!errors.drugUuid}
114
+ invalidText={errors.drugUuid && errors?.drugUuid?.message}
115
+ />
116
+ ) : selectedItemType === StockItemType.NONE_PHARMACEUTICALS ? (
117
+ <ConceptsSelector
118
+ name="conceptUuid"
119
+ controllerName="conceptUuid"
120
+ control={control}
121
+ title={t('pleaseSpecify', 'Please specify') + ':'}
122
+ placeholder={t('chooseAnItem', 'Choose an item')}
123
+ invalid={!!errors.drugUuid}
124
+ invalidText={errors.drugUuid && errors?.drugUuid?.message}
125
+ />
126
+ ) : null}
127
+ <ControlledTextInput
128
+ id="commonName"
129
+ name="commonName"
77
130
  control={control}
78
- name="isDrug"
79
- controllerName="isDrug"
80
- legendText=""
81
- invalid={!!errors.isDrug}
82
- invalidText={errors.isDrug && errors?.isDrug?.message}
83
- onChange={(selectedValue: string) => {
84
- const selectedOption = radioOptions.find((option) => String(option.value) === selectedValue);
85
- const selectedLabel = selectedOption ? selectedOption.label : '';
86
- setIsDrug(selectedValue === 'true');
87
- setSelectedItemType(selectedLabel);
88
- }}
89
- options={radioOptions} // Pass radioOptions directly
131
+ controllerName="commonName"
132
+ maxLength={255}
133
+ size={'md'}
134
+ value={`${stockItem?.commonName ?? ''}`}
135
+ labelText={t('commonName', 'Common name') + ':'}
136
+ invalid={!!errors.commonName}
137
+ invalidText={errors.commonName && errors?.commonName?.message}
90
138
  />
91
- </FormGroup>
92
- )}
93
- {selectedItemType === 'Pharmaceuticals' ? (
94
- <DrugSelector
95
- name="drugUuid"
96
- controllerName="drugUuid"
97
- control={control}
98
- title={t('pleaseSpecify', 'Please specify:')}
99
- placeholder="Choose a drug"
100
- drugUuid={model.drugUuid}
101
- invalid={!!errors.drugUuid}
102
- invalidText={errors.drugUuid && errors?.drugUuid?.message}
103
- />
104
- ) : selectedItemType === 'Non Pharmaceuticals' ? (
105
- <ConceptsSelector
106
- name="conceptUuid"
107
- controllerName="conceptUuid"
108
- control={control}
109
- title={t('pleaseSpecify', 'Please specify') + ':'}
110
- placeholder={t('chooseAnItem', 'Choose an item')}
111
- invalid={!!errors.drugUuid}
112
- invalidText={errors.drugUuid && errors?.drugUuid?.message}
113
- />
114
- ) : null}
115
- <ControlledTextInput
116
- id="commonName"
117
- name="commonName"
118
- control={control}
119
- controllerName="commonName"
120
- maxLength={255}
121
- size={'md'}
122
- value={`${model?.commonName ?? ''}`}
123
- labelText={t('commonName', 'Common name') + ':'}
124
- invalid={!!errors.commonName}
125
- invalidText={errors.commonName && errors?.commonName?.message}
126
- />
127
- <ControlledTextInput
128
- id="acronym"
129
- maxLength={255}
130
- name="acronym"
131
- control={control}
132
- controllerName="acronym"
133
- size={'md'}
134
- labelText={t('abbreviation', 'Abbreviation') + ':'}
135
- invalid={!!errors.acronym}
136
- invalidText={errors.acronym && errors?.acronym?.message}
137
- />
138
- <div
139
- style={{
140
- display: 'grid',
141
- gridTemplateColumns: '1fr 1fr',
142
- justifyContent: 'center',
143
- }}
144
- >
145
- <FormGroup
146
- className="clear-margin-bottom"
147
- legendText={t('hasExpiration', 'Does the item expire?')}
148
- title={t('hasExpiration', 'Does the item expire?')}
149
- >
150
- <ControlledRadioButtonGroup
151
- name="hasExpiration"
152
- controllerName="hasExpiration"
139
+ <ControlledTextInput
140
+ id="acronym"
141
+ maxLength={255}
142
+ name="acronym"
153
143
  control={control}
154
- legendText=""
155
- invalid={!!errors.hasExpiration}
156
- invalidText={errors.hasExpiration && errors?.hasExpiration?.message}
157
- onChange={(selectedValue: string) => {
158
- setHasExpiration(selectedValue === 'true');
159
- }}
160
- options={expirationOptions} // Pass expirationOptions directly
144
+ controllerName="acronym"
145
+ size={'md'}
146
+ labelText={t('abbreviation', 'Abbreviation') + ':'}
147
+ invalid={!!errors.acronym}
148
+ invalidText={errors.acronym && errors?.acronym?.message}
161
149
  />
162
- </FormGroup>
150
+ <div
151
+ style={{
152
+ display: 'grid',
153
+ gridTemplateColumns: '1fr 1fr',
154
+ justifyContent: 'center',
155
+ }}
156
+ >
157
+ <FormGroup
158
+ className="clear-margin-bottom"
159
+ legendText={t('hasExpiration', 'Does the item expire?')}
160
+ title={t('hasExpiration', 'Does the item expire?')}
161
+ >
162
+ <ControlledRadioButtonGroup
163
+ name="hasExpiration"
164
+ controllerName="hasExpiration"
165
+ control={control}
166
+ legendText=""
167
+ invalid={!!errors.hasExpiration}
168
+ invalidText={errors.hasExpiration && errors?.hasExpiration?.message}
169
+ options={expirationOptions} // Pass expirationOptions directly
170
+ />
171
+ </FormGroup>
163
172
 
164
- {hasExpiration && (
165
- <FormGroup className="clear-margin-bottom" title={t('expirationNotice', 'Expiration Notice (days)')}>
166
- <ControlledNumberInput
167
- id="expiryNotice"
168
- name="expiryNotice"
173
+ {observableHasExpiration && (
174
+ <FormGroup className="clear-margin-bottom" title={t('expirationNotice', 'Expiration Notice (days)')}>
175
+ <ControlledNumberInput
176
+ id="expiryNotice"
177
+ name="expiryNotice"
178
+ control={control}
179
+ controllerName="expiryNotice"
180
+ min={0}
181
+ hideSteppers={true}
182
+ size={'md'}
183
+ allowEmpty={true}
184
+ label={t('expiryNoticeDays', 'Expiration Notice (days)')}
185
+ invalid={!!errors.expiryNotice}
186
+ invalidText={errors.expiryNotice && errors?.expiryNotice?.message}
187
+ />
188
+ </FormGroup>
189
+ )}
190
+ </div>
191
+ <PreferredVendorSelector
192
+ name="preferredVendorUuid"
193
+ controllerName="preferredVendorUuid"
194
+ control={control}
195
+ title={t('whoIsThePreferredVendor', 'Who is the preferred vendor?')}
196
+ placeholder={t('chooseVendor', 'Choose vendor')}
197
+ invalid={!!errors.preferredVendorUuid}
198
+ invalidText={errors.preferredVendorUuid && errors?.preferredVendorUuid?.message}
199
+ />
200
+ <StockItemCategorySelector
201
+ name="categoryUuid"
202
+ controllerName="categoryUuid"
203
+ control={control}
204
+ itemType={
205
+ selectedItemType === StockItemType.PHARMACEUTICALS
206
+ ? 'Drugs'
207
+ : selectedItemType === StockItemType.NONE_PHARMACEUTICALS
208
+ ? 'Non Drugs'
209
+ : undefined
210
+ }
211
+ title={t('category', 'Category') + ':'}
212
+ placeholder={t('chooseACategory', 'Choose a category')}
213
+ invalid={!!errors.categoryUuid}
214
+ invalidText={errors.categoryUuid && errors?.categoryUuid?.message}
215
+ />
216
+ {observableIsDrug && (
217
+ <DispensingUnitSelector
218
+ name="dispensingUnitUuid"
219
+ controllerName="dispensingUnitUuid"
169
220
  control={control}
170
- controllerName="expiryNotice"
171
- min={0}
172
- hideSteppers={true}
173
- size={'md'}
174
- allowEmpty={true}
175
- label={t('expiryNoticeDays', 'Expiration Notice (days)')}
176
- invalid={!!errors.expiryNotice}
177
- invalidText={errors.expiryNotice && errors?.expiryNotice?.message}
221
+ title={t('dispensingUnit', 'Dispensing Unit') + ':'}
222
+ placeholder={t('dispensingUnitHolder', 'Choose a dispensing unit')}
223
+ invalid={!!errors.dispensingUnitUuid}
224
+ invalidText={errors.dispensingUnitUuid && errors?.dispensingUnitUuid?.message}
178
225
  />
179
- </FormGroup>
180
- )}
181
- </div>
182
- <PreferredVendorSelector
183
- name="preferredVendorUuid"
184
- controllerName="preferredVendorUuid"
185
- control={control}
186
- title={t('whoIsThePreferredVendor', 'Who is the preferred vendor?')}
187
- placeholder={t('chooseVendor', 'Choose vendor')}
188
- invalid={!!errors.preferredVendorUuid}
189
- invalidText={errors.preferredVendorUuid && errors?.preferredVendorUuid?.message}
190
- />
191
- <StockItemCategorySelector
192
- name="categoryUuid"
193
- controllerName="categoryUuid"
194
- control={control}
195
- itemType={
196
- selectedItemType === 'Pharmaceuticals'
197
- ? 'Drugs'
198
- : selectedItemType === 'Non Pharmaceuticals'
199
- ? 'Non Drugs'
200
- : undefined
201
- }
202
- title={t('category', 'Category') + ':'}
203
- placeholder={t('chooseACategory', 'Choose a category')}
204
- invalid={!!errors.categoryUuid}
205
- invalidText={errors.categoryUuid && errors?.categoryUuid?.message}
206
- />
207
- {isDrug && (
208
- <DispensingUnitSelector
209
- name="dispensingUnitUuid"
210
- controllerName="dispensingUnitUuid"
211
- control={control}
212
- title={t('dispensingUnit', 'Dispensing Unit') + ':'}
213
- placeholder={t('dispensingUnitHolder', 'Choose a dispensing unit')}
214
- invalid={!!errors.dispensingUnitUuid}
215
- invalidText={errors.dispensingUnitUuid && errors?.dispensingUnitUuid?.message}
216
- />
217
- )}
218
- {isDrug && isEditing && <StockItemUnitsEdit control={control} formState={formState} stockItemUuid={model.uuid} />}
219
-
220
- <div style={{ display: 'flex', flexDirection: 'row-reverse' }}>
221
- <Button
222
- name="save"
223
- type="button"
224
- className="submitButton"
225
- onClick={handleSubmit(handleSave)}
226
- kind="primary"
227
- renderIcon={Save}
228
- >
229
- {isSaving ? <InlineLoading /> : t('save', 'Save')}
230
- </Button>
231
- <Button kind="secondary" onClick={closeOverlay}>
232
- {t('cancel', 'Cancel')}
233
- </Button>
234
- </div>
235
- </form>
236
- );
237
- });
226
+ )}
227
+ {observableIsDrug && stockItem && (
228
+ <StockItemUnitsEdit control={control} formState={formState} stockItemUuid={stockItem?.uuid} />
229
+ )}
230
+ </div>
231
+ <ButtonSet className={styles.buttonSet}>
232
+ <Button kind="secondary" onClick={onCloseWorkspace} className={styles.button}>
233
+ {t('cancel', 'Cancel')}
234
+ </Button>
235
+ <Button
236
+ name="save"
237
+ type="button"
238
+ className={styles.button}
239
+ onClick={handleSubmit(handleSave)}
240
+ kind="primary"
241
+ renderIcon={Save}
242
+ >
243
+ {formState.isSubmitting ? <InlineLoading /> : t('save', 'Save')}
244
+ </Button>
245
+ </ButtonSet>
246
+ </form>
247
+ );
248
+ },
249
+ );
238
250
 
239
251
  export default StockItemDetails;
@@ -3,9 +3,14 @@ export interface RadioOption {
3
3
  value: boolean;
4
4
  }
5
5
 
6
+ export enum StockItemType {
7
+ PHARMACEUTICALS = 'Pharmaceuticals',
8
+ NONE_PHARMACEUTICALS = 'Non Pharmaceuticals',
9
+ }
10
+
6
11
  export const radioOptions: RadioOption[] = [
7
- { label: 'Pharmaceuticals', value: true },
8
- { label: 'Non Pharmaceuticals', value: false },
12
+ { label: StockItemType.PHARMACEUTICALS, value: true },
13
+ { label: StockItemType.NONE_PHARMACEUTICALS, value: false },
9
14
  ];
10
15
 
11
16
  export const expirationOptions: RadioOption[] = [
@@ -18,9 +18,9 @@ import { FormProvider, useForm, useFormContext } from 'react-hook-form';
18
18
  import StockSourceSelector from './stock-references-selector.component';
19
19
  import { useStockItemReferencesHook } from './stock-item-references.resource';
20
20
  import { zodResolver } from '@hookform/resolvers/zod';
21
- import { StockItemReferenceData } from './validation-schema';
21
+ import { type StockItemReferenceData } from './validation-schema';
22
22
  import { stockItemDetailsSchema } from '../../validationSchema';
23
- import { StockItemReferenceDTO } from '../../../core/api/types/stockItem/StockItemReference';
23
+ import { type StockItemReferenceDTO } from '../../../core/api/types/stockItem/StockItemReference';
24
24
  import ControlledTextInput from '../../../core/components/carbon/controlled-text-input/controlled-text-input.component';
25
25
  import { createStockItemReference, deleteStockItemReference } from '../../stock-items.resource';
26
26
  import { restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
@@ -1,5 +1,5 @@
1
1
  import { ResourceRepresentation } from '../../../core/api/api';
2
- import { StockItemReferenceFilter, useStockItemReferences } from '../../stock-items.resource';
2
+ import { type StockItemReferenceFilter, useStockItemReferences } from '../../stock-items.resource';
3
3
  import { useEffect, useState } from 'react';
4
4
 
5
5
  export function useStockItemReferencesHook(v?: ResourceRepresentation) {
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
2
  import { TextInputSkeleton, ComboBox } from '@carbon/react';
3
- import { Control, Controller, FieldValues } from 'react-hook-form';
4
- import { StockSource } from '../../../core/api/types/stockOperation/StockSource';
3
+ import { type Control, Controller, type FieldValues } from 'react-hook-form';
4
+ import { type StockSource } from '../../../core/api/types/stockOperation/StockSource';
5
5
  import { ResourceRepresentation } from '../../../core/api/api';
6
6
  import { useStockSources } from '../../../stock-sources/stock-sources.resource';
7
- import { Concept } from '../../../core/api/types/concept/Concept';
8
- import { StockItemReferenceDTO } from '../../../core/api/types/stockItem/StockItemReference';
7
+ import { type Concept } from '../../../core/api/types/concept/Concept';
8
+ import { type StockItemReferenceDTO } from '../../../core/api/types/stockItem/StockItemReference';
9
9
 
10
10
  interface StockSourceSelectorProps<T> {
11
11
  row?: StockItemReferenceDTO;
@@ -1,8 +1,7 @@
1
1
  import { Button } from '@carbon/react';
2
+ import { launchWorkspace } from '@openmrs/esm-framework';
2
3
  import React, { useCallback } from 'react';
3
4
  import { useTranslation } from 'react-i18next';
4
- import { launchOverlay } from '../../../core/components/overlay/hook';
5
- import StockRulesAddOrUpdate from './add-stock-rules.component';
6
5
 
7
6
  interface AddStockRuleActionButtonProps {
8
7
  stockItemUuid: string;
@@ -12,8 +11,11 @@ const AddStockRuleActionButton: React.FC<AddStockRuleActionButtonProps> = ({ sto
12
11
  const { t } = useTranslation();
13
12
 
14
13
  const handleClick = useCallback(() => {
15
- launchOverlay('Add Stock Rule', <StockRulesAddOrUpdate stockItemUuid={stockItemUuid} />);
16
- }, [stockItemUuid]);
14
+ launchWorkspace('stock-item-rules-form-workspace', {
15
+ workspaceTitle: t('addStockRule', 'Add Stock Rule'),
16
+ stockItemUuid,
17
+ });
18
+ }, [stockItemUuid, t]);
17
19
 
18
20
  return (
19
21
  <Button onClick={handleClick} size="md" kind="primary">