@openmrs/esm-stock-management-app 3.0.1-pre.848 → 3.0.1-pre.853

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/.husky/pre-commit +4 -1
  2. package/__mocks__/react-i18next.js +8 -9
  3. package/dist/10.js +1 -1
  4. package/dist/10.js.map +1 -1
  5. package/dist/119.js +1 -1
  6. package/dist/119.js.map +1 -1
  7. package/dist/14.js +1 -1
  8. package/dist/14.js.map +1 -1
  9. package/dist/172.js +1 -1
  10. package/dist/172.js.map +1 -1
  11. package/dist/20.js +1 -1
  12. package/dist/20.js.map +1 -1
  13. package/dist/290.js +1 -1
  14. package/dist/290.js.map +1 -1
  15. package/dist/33.js +1 -0
  16. package/dist/33.js.map +1 -0
  17. package/dist/467.js +1 -1
  18. package/dist/467.js.map +1 -1
  19. package/dist/574.js +1 -1
  20. package/dist/606.js +1 -1
  21. package/dist/606.js.map +1 -1
  22. package/dist/642.js +1 -1
  23. package/dist/642.js.map +1 -1
  24. package/dist/675.js +1 -1
  25. package/dist/675.js.map +1 -1
  26. package/dist/727.js +1 -1
  27. package/dist/727.js.map +1 -1
  28. package/dist/842.js +1 -1
  29. package/dist/842.js.map +1 -1
  30. package/dist/93.js +1 -1
  31. package/dist/93.js.map +1 -1
  32. package/dist/main.js +1 -1
  33. package/dist/main.js.map +1 -1
  34. package/dist/openmrs-esm-stock-management-app.js.buildmanifest.json +70 -70
  35. package/dist/routes.json +1 -1
  36. package/jest.config.js +6 -3
  37. package/package.json +1 -1
  38. package/src/core/components/table/table.component.tsx +2 -2
  39. package/src/index.ts +5 -5
  40. package/src/stock-items/add-bulk-stock-item/add-stock-items-bulk-import-action-button.component.tsx +3 -3
  41. package/src/stock-items/add-bulk-stock-item/{stock-items-bulk-import.component.tsx → stock-items-bulk-import.modal.tsx} +20 -19
  42. package/src/stock-items/add-bulk-stock-item/stock-items-bulk-import.resource.ts +1 -1
  43. package/src/stock-items/add-bulk-stock-item/stock-items-bulk-import.test.tsx +59 -59
  44. package/src/stock-items/add-stock-item/add-stock-action-button.component.tsx +6 -6
  45. package/src/stock-items/add-stock-item/add-stock-item.component.tsx +6 -4
  46. package/src/stock-items/add-stock-item/add-stock-item.scss +5 -0
  47. package/src/stock-items/add-stock-item/add-stock-item.test.tsx +28 -43
  48. package/src/stock-items/add-stock-item/packaging-units/packaging-units-delete-modal.component.tsx +3 -4
  49. package/src/stock-items/add-stock-item/packaging-units/packaging-units.component.tsx +9 -10
  50. package/src/stock-items/add-stock-item/packaging-units/packaging-units.scss +4 -4
  51. package/src/stock-items/add-stock-item/stock-item-details/stock-item-details.component.tsx +27 -19
  52. package/src/stock-items/add-stock-item/stock-item-references/stock-item-references.scss +4 -4
  53. package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rules.component.tsx +15 -9
  54. package/src/stock-items/add-stock-item/stock-item-rules/add-stock-rules.scss +1 -0
  55. package/src/stock-items/add-stock-item/stock-item-rules/delete-stock-rule-modal.component.tsx +2 -1
  56. package/src/stock-items/add-stock-item/stock-item-rules/stock-item-rules.component.tsx +14 -16
  57. package/src/stock-items/add-stock-item/stock-item-rules/stock-item-rules.scss +7 -3
  58. package/src/stock-items/add-stock-item/transactions/printout/transactions-print-bincard-preview.modal.tsx +14 -6
  59. package/src/stock-items/add-stock-item/transactions/printout/transactions-print-stockcard-preview.modal.tsx +14 -8
  60. package/src/stock-items/edit-stock-item/edit-stock-item-action-menu.component.tsx +2 -2
  61. package/src/stock-items/stock-item.utils.tsx +3 -5
  62. package/src/stock-items/stock-items-table.component.tsx +47 -45
  63. package/src/stock-items/stock-items-table.resource.ts +2 -2
  64. package/src/stock-items/stock-items-table.scss +5 -1
  65. package/src/stock-items/stock-items-table.test.tsx +106 -65
  66. package/src/stock-locations/location-admin-form.component.tsx +5 -4
  67. package/src/stock-locations/stock-locations-table.component.tsx +10 -8
  68. package/src/stock-lookups/stock-lookups.resource.ts +3 -2
  69. package/src/stock-operations/stock-operations-dialog/stock-operations-dialog.component.tsx +2 -2
  70. package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.component.tsx +11 -11
  71. package/src/stock-operations/stock-operations-forms/input-components/batch-no-selector.test.tsx +115 -25
  72. package/src/stock-operations/stock-operations-forms/input-components/qty-uim-selector.test.tsx +107 -65
  73. package/src/stock-operations/stock-operations-forms/input-components/quantity-uom-selector.component.tsx +9 -9
  74. package/src/stock-operations/stock-operations-forms/input-components/stock-operation-reason-selector.test.tsx +35 -153
  75. package/src/stock-operations/stock-operations-forms/input-components/user-selector.test.tsx +82 -29
  76. package/src/stock-operations/stock-operations-forms/step1.test.tsx +204 -69
  77. package/src/stock-operations/stock-operations-forms/step2.test.tsx +140 -63
  78. package/src/stock-operations/stock-operations-forms/step3.test.tsx +79 -60
  79. package/src/stock-operations/stock-operations-forms/steps/stock-operation-items-form-step.component.tsx +6 -5
  80. package/src/stock-operations/stock-operations-forms/steps/stock-operation-submission-form-step.component.tsx +12 -11
  81. package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.scss +1 -0
  82. package/src/stock-operations/stock-operations-forms/stock-item-form/stock-item-form.workspace.tsx +20 -12
  83. package/src/stock-operations/stock-operations-forms/stock-operation-form.scss +1 -0
  84. package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stepper.scss +1 -3
  85. package/src/stock-operations/stock-operations-forms/stock-operation-stepper/stock-operation-stepper.component.tsx +2 -1
  86. package/src/stock-reports/generate-report/create-stock-report.scss +3 -2
  87. package/src/stock-reports/generate-report/create-stock-report.workspace.tsx +32 -25
  88. package/src/stock-reports/report-list/stock-report-parameters.component.tsx +1 -1
  89. package/src/stock-reports/report-list/stock-report-status.component.tsx +1 -1
  90. package/src/stock-reports/report-list/stock-reports.component.tsx +24 -25
  91. package/src/stock-reports/report-list/stock-reports.scss +10 -2
  92. package/src/stock-sources/add-stock-sources/add-stock-sources.scss +11 -4
  93. package/src/stock-sources/add-stock-sources/add-stock-sources.test.tsx +38 -36
  94. package/src/stock-sources/add-stock-sources/add-stock-sources.workspace.tsx +35 -30
  95. package/src/stock-sources/delete-stock-modal.component.tsx +2 -1
  96. package/src/stock-sources/stock-sources-delete/stock-sources-delete.test.tsx +27 -36
  97. package/src/stock-sources/stock-sources-filter/stock-sources-filter.component.tsx +33 -21
  98. package/src/stock-sources/stock-sources-items-table.component.tsx +16 -17
  99. package/src/stock-sources/stock-sources-items-table.resource.ts +8 -6
  100. package/src/stock-sources/stock-sources-items-table.test.tsx +60 -37
  101. package/src/stock-sources/stock-sources.scss +6 -2
  102. package/src/stock-user-role-scopes/add-stock-user-scope/add-stock-user-role-scope.scss +5 -13
  103. package/src/stock-user-role-scopes/add-stock-user-scope/add-stock-user-role-scope.workspace.tsx +2 -2
  104. package/src/stock-user-role-scopes/delete-stock-user-scope-modal.component.tsx +2 -1
  105. package/translations/en.json +5 -6
  106. package/tsconfig.json +4 -0
  107. package/dist/627.js +0 -1
  108. package/dist/627.js.map +0 -1
@@ -1,20 +1,20 @@
1
+ import React, { useCallback, useMemo, useState } from 'react';
1
2
  import { Button, Column, InlineLoading, RadioButton, RadioButtonGroup, Stack } from '@carbon/react';
2
3
  import { ArrowLeft, ArrowRight, Departure, ListChecked, Save, SendFilled } from '@carbon/react/icons';
3
- import { restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
4
- import React, { useCallback, useMemo, useState } from 'react';
5
4
  import { useFormContext } from 'react-hook-form';
6
5
  import { useTranslation } from 'react-i18next';
6
+ import { restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
7
+ import { createStockOperation, deleteStockOperationItem, updateStockOperation } from '../../stock-operations.resource';
7
8
  import { extractErrorMessagesFromResponse } from '../../../constants';
8
- import { type StockOperationDTO } from '../../../core/api/types/stockOperation/StockOperationDTO';
9
- import { type StockOperationItemDTO } from '../../../core/api/types/stockOperation/StockOperationItemDTO';
9
+ import { handleMutate } from '../../../utils';
10
10
  import { OperationType, type StockOperationType } from '../../../core/api/types/stockOperation/StockOperationType';
11
11
  import { otherUser } from '../../../core/utils/utils';
12
- import { handleMutate } from '../../../utils';
13
12
  import { showActionDialogButton } from '../../stock-operation.utils';
14
- import { createStockOperation, deleteStockOperationItem, updateStockOperation } from '../../stock-operations.resource';
13
+ import { type StockOperationDTO } from '../../../core/api/types/stockOperation/StockOperationDTO';
14
+ import { type StockOperationItemDTO } from '../../../core/api/types/stockOperation/StockOperationItemDTO';
15
15
  import { type StockOperationItemDtoSchema } from '../../validation-schema';
16
- import useOperationTypePermisions from '../hooks/useOperationTypePermisions';
17
16
  import styles from '../stock-operation-form.scss';
17
+ import useOperationTypePermisions from '../hooks/useOperationTypePermisions';
18
18
 
19
19
  type StockOperationSubmissionFormStepProps = {
20
20
  onPrevious?: () => void;
@@ -23,6 +23,7 @@ type StockOperationSubmissionFormStepProps = {
23
23
  onNext?: () => void;
24
24
  dismissWorkspace?: () => void;
25
25
  };
26
+
26
27
  const StockOperationSubmissionFormStep: React.FC<StockOperationSubmissionFormStepProps> = ({
27
28
  onPrevious,
28
29
  stockOperationType,
@@ -152,12 +153,12 @@ const StockOperationSubmissionFormStep: React.FC<StockOperationSubmissionFormSte
152
153
  <RadioButtonGroup
153
154
  name="rbgApprovelRequired"
154
155
  legendText={t('doesThisTransactionRequireApproval', 'Does the transaction require approval ?')}
155
- onChange={handleRadioButtonChange}
156
+ onChange={(value) => handleRadioButtonChange(value === 'true')}
156
157
  readOnly={!editable}
157
- valueSelected={approvalRequired === true ? true : approvalRequired === false ? false : null}
158
+ valueSelected={approvalRequired === true ? 'true' : approvalRequired === false ? 'false' : null}
158
159
  >
159
- <RadioButton value={true} id="rbgApprovelRequired-true" labelText={t('yes', 'Yes')} />
160
- <RadioButton value={false} id="rbgApprovelRequired-false" labelText={t('no', 'No')} />
160
+ <RadioButton value="true" id="rbgApprovelRequired-true" labelText={t('yes', 'Yes')} />
161
+ <RadioButton value="false" id="rbgApprovelRequired-false" labelText={t('no', 'No')} />
161
162
  </RadioButtonGroup>
162
163
  </Column>
163
164
  {editable && (
@@ -16,6 +16,7 @@
16
16
  }
17
17
 
18
18
  .button {
19
+ height: layout.$spacing-10;
19
20
  display: flex;
20
21
  align-content: flex-start;
21
22
  align-items: baseline;
@@ -1,3 +1,5 @@
1
+ import React, { useMemo } from 'react';
2
+ import classNames from 'classnames';
1
3
  import {
2
4
  Button,
3
5
  ButtonSet,
@@ -10,8 +12,7 @@ import {
10
12
  TextInput,
11
13
  } from '@carbon/react';
12
14
  import { zodResolver } from '@hookform/resolvers/zod';
13
- import { DefaultWorkspaceProps, useConfig } from '@openmrs/esm-framework';
14
- import React, { useMemo } from 'react';
15
+ import { useConfig, useLayoutType } from '@openmrs/esm-framework';
15
16
  import { Controller, useForm } from 'react-hook-form';
16
17
  import { useTranslation } from 'react-i18next';
17
18
  import { type z } from 'zod';
@@ -20,14 +21,14 @@ import {
20
21
  operationFromString,
21
22
  type StockOperationType,
22
23
  } from '../../../core/api/types/stockOperation/StockOperationType';
23
- import { useStockItem } from '../../../stock-items/stock-items.resource';
24
24
  import { type BaseStockOperationItemFormData, getStockOperationItemFormSchema } from '../../validation-schema';
25
- import useOperationTypePermisions from '../hooks/useOperationTypePermisions';
25
+ import { type ConfigObject } from '../../../config-schema';
26
+ import { useStockItem } from '../../../stock-items/stock-items.resource';
26
27
  import BatchNoSelector from '../input-components/batch-no-selector.component';
27
28
  import QtyUomSelector from '../input-components/quantity-uom-selector.component';
28
- import styles from './stock-item-form.scss';
29
29
  import UniqueBatchNoEntryInput from '../input-components/unique-batch-no-entry-input.component';
30
- import { type ConfigObject } from '../../../config-schema';
30
+ import useOperationTypePermisions from '../hooks/useOperationTypePermisions';
31
+ import styles from './stock-item-form.scss';
31
32
 
32
33
  export interface StockItemFormProps {
33
34
  stockOperationType: StockOperationType;
@@ -37,18 +38,19 @@ export interface StockItemFormProps {
37
38
  }
38
39
 
39
40
  const StockItemForm: React.FC<StockItemFormProps> = ({ stockOperationType, stockOperationItem, onSave, onBack }) => {
41
+ const isTablet = useLayoutType() === 'tablet';
40
42
  const operationType = useMemo(() => {
41
43
  return operationFromString(stockOperationType.operationType);
42
44
  }, [stockOperationType]);
43
- const formschema = useMemo(() => {
45
+ const formSchema = useMemo(() => {
44
46
  return getStockOperationItemFormSchema(operationType);
45
47
  }, [operationType]);
46
48
  const operationTypePermision = useOperationTypePermisions(stockOperationType);
47
49
  const { useItemCommonNameAsDisplay } = useConfig<ConfigObject>();
48
50
 
49
- const fields = formschema.keyof().options;
50
- const form = useForm<z.infer<typeof formschema>>({
51
- resolver: zodResolver(formschema),
51
+ const fields = formSchema.keyof().options;
52
+ const form = useForm<z.infer<typeof formSchema>>({
53
+ resolver: zodResolver(formSchema),
52
54
  defaultValues: stockOperationItem,
53
55
  mode: 'all',
54
56
  });
@@ -66,9 +68,10 @@ const StockItemForm: React.FC<StockItemFormProps> = ({ stockOperationType, stock
66
68
  return `${item?.drugName || t('noDrugNameAvailable', 'No drug name available') + (commonName ?? '')}`;
67
69
  }, [item, useItemCommonNameAsDisplay, t]);
68
70
 
69
- const onSubmit = (data: z.infer<typeof formschema>) => {
71
+ const onSubmit = (data: z.infer<typeof formSchema>) => {
70
72
  onSave?.(data);
71
73
  };
74
+
72
75
  return (
73
76
  <Form onSubmit={form.handleSubmit(onSubmit)} className={styles.form}>
74
77
  <Stack gap={4} className={styles.grid}>
@@ -197,7 +200,12 @@ const StockItemForm: React.FC<StockItemFormProps> = ({ stockOperationType, stock
197
200
  )}
198
201
  </Stack>
199
202
 
200
- <ButtonSet className={styles.buttonSet}>
203
+ <ButtonSet
204
+ className={classNames(styles.buttonSet, {
205
+ [styles.tablet]: isTablet,
206
+ [styles.desktop]: !isTablet,
207
+ })}
208
+ >
201
209
  <Button className={styles.button} kind="secondary" onClick={onBack}>
202
210
  {t('discard', 'Discard')}
203
211
  </Button>
@@ -17,6 +17,7 @@
17
17
  }
18
18
 
19
19
  .button {
20
+ height: layout.$spacing-10;
20
21
  display: flex;
21
22
  align-content: flex-start;
22
23
  align-items: baseline;
@@ -5,8 +5,7 @@
5
5
  .layer {
6
6
  display: flex;
7
7
  flex-direction: row;
8
- gap: layout.$spacing-05;
9
- padding: layout.$spacing-03;
8
+ padding: 0 layout.$spacing-03 0;
10
9
  height: 100%;
11
10
  }
12
11
 
@@ -40,5 +39,4 @@
40
39
 
41
40
  .content {
42
41
  flex: 1;
43
- overflow: auto;
44
42
  }
@@ -1,5 +1,5 @@
1
- import { Layer } from '@carbon/react';
2
1
  import React from 'react';
2
+ import { Layer } from '@carbon/react';
3
3
  import styles from './stepper.scss';
4
4
 
5
5
  export type Step = {
@@ -17,6 +17,7 @@ type StockOperationStepperProps = {
17
17
  selectedIndex?: number;
18
18
  onChange?: (index: number) => void;
19
19
  };
20
+
20
21
  const StockOperationStepper: React.FC<StockOperationStepperProps> = ({
21
22
  steps,
22
23
  hasContainer,
@@ -1,5 +1,5 @@
1
- @use '@carbon/styles/scss/spacing';
2
- @use '@carbon/styles/scss/type';
1
+ @use '@carbon/layout';
2
+ @use '@carbon/type';
3
3
  @use '@openmrs/esm-styleguide/src/vars' as *;
4
4
 
5
5
  .formContainer {
@@ -11,6 +11,7 @@
11
11
  }
12
12
 
13
13
  .button {
14
+ height: layout.$spacing-10;
14
15
  display: flex;
15
16
  align-content: flex-start;
16
17
  align-items: baseline;
@@ -1,48 +1,48 @@
1
1
  import React, { useEffect, useMemo, useState } from 'react';
2
+ import classNames from 'classnames';
3
+ import { useTranslation } from 'react-i18next';
2
4
  import {
3
5
  Button,
4
- InlineLoading,
6
+ ButtonSet,
7
+ Checkbox,
5
8
  ComboBox,
6
- DatePickerInput,
7
9
  DatePicker,
10
+ DatePickerInput,
11
+ InlineLoading,
12
+ NumberInput,
13
+ RadioButton,
14
+ RadioButtonGroup,
8
15
  Select,
9
16
  SelectItem,
10
- RadioButtonGroup,
11
- RadioButton,
12
- Form,
13
- Checkbox,
14
- NumberInput,
15
- ButtonSet,
16
17
  } from '@carbon/react';
17
- import styles from './create-stock-report.scss';
18
- import { useTranslation } from 'react-i18next';
19
- import { useReportTypes } from '../stock-reports.resource';
20
- import { DATE_PICKER_CONTROL_FORMAT, DATE_PICKER_FORMAT, formatForDatePicker, today } from '../../constants';
21
- import { Controller, useForm } from 'react-hook-form';
22
- import { zodResolver } from '@hookform/resolvers/zod';
23
- import { type StockReportSchema, reportSchema } from '../report-validation-schema';
24
- import { useConcept, useStockTagLocations } from '../../stock-lookups/stock-lookups.resource';
25
18
  import {
26
19
  type ConfigObject,
27
20
  type DefaultWorkspaceProps,
21
+ getCoreTranslation,
28
22
  restBaseUrl,
29
23
  showSnackbar,
30
24
  useConfig,
31
- getCoreTranslation,
25
+ useLayoutType,
32
26
  } from '@openmrs/esm-framework';
33
- import { type Concept } from '../../core/api/types/concept/Concept';
34
- import { createBatchJob } from '../../stock-batch/stock-batch.resource';
27
+ import { Controller, useForm } from 'react-hook-form';
28
+ import { zodResolver } from '@hookform/resolvers/zod';
35
29
  import {
36
- ReportParameter,
37
30
  getParamDefaultLimit,
38
31
  getReportEndDateLabel,
39
32
  getReportLimitLabel,
40
33
  getReportStartDateLabel,
34
+ ReportParameter,
41
35
  } from '../ReportType';
42
- import { formatDisplayDate } from '../../core/utils/datetimeUtils';
36
+ import { DATE_PICKER_CONTROL_FORMAT, DATE_PICKER_FORMAT, formatForDatePicker, today } from '../../constants';
43
37
  import { BatchJobTypeReport } from '../../core/api/types/BatchJob';
38
+ import { createBatchJob } from '../../stock-batch/stock-batch.resource';
39
+ import { formatDisplayDate } from '../../core/utils/datetimeUtils';
44
40
  import { handleMutate } from '../../utils';
45
- import { Save } from '@carbon/react/icons';
41
+ import { type Concept } from '../../core/api/types/concept/Concept';
42
+ import { type StockReportSchema, reportSchema } from '../report-validation-schema';
43
+ import { useConcept, useStockTagLocations } from '../../stock-lookups/stock-lookups.resource';
44
+ import { useReportTypes } from '../stock-reports.resource';
45
+ import styles from './create-stock-report.scss';
46
46
 
47
47
  type CreateReportProps = DefaultWorkspaceProps & {
48
48
  model?: ReportModel;
@@ -76,9 +76,11 @@ export interface ReportModel {
76
76
  mostLeastMovingName?: string;
77
77
  fullFillment?: string[];
78
78
  }
79
+
79
80
  const CreateReport: React.FC<CreateReportProps> = ({ model, closeWorkspace }) => {
80
81
  const { t } = useTranslation();
81
82
  const { stockItemCategoryUUID } = useConfig<ConfigObject>();
83
+ const isTablet = useLayoutType() === 'tablet';
82
84
 
83
85
  const { reportTypes, isLoading } = useReportTypes();
84
86
  const { stockLocations } = useStockTagLocations();
@@ -640,12 +642,17 @@ const CreateReport: React.FC<CreateReportProps> = ({ model, closeWorkspace }) =>
640
642
  )}
641
643
  </div>
642
644
 
643
- <ButtonSet className={styles.buttonSet}>
645
+ <ButtonSet
646
+ className={classNames(styles.buttonSet, {
647
+ [styles.tablet]: isTablet,
648
+ [styles.desktop]: !isTablet,
649
+ })}
650
+ >
644
651
  <Button kind="secondary" onClick={closeWorkspace} className={styles.button}>
645
- {getCoreTranslation('cancel', 'Cancel')}
652
+ {getCoreTranslation('cancel')}
646
653
  </Button>
647
654
  <Button type="submit" className={styles.button} onClick={handleSave}>
648
- {getCoreTranslation('save', 'Save')}
655
+ {getCoreTranslation('save')}
649
656
  </Button>
650
657
  </ButtonSet>
651
658
  </div>
@@ -35,7 +35,7 @@ const StockReportParameters = (props: StockReportParametersProps) => {
35
35
  parseParametersToMap(props.model?.parameters, ['param.report']),
36
36
  );
37
37
  } catch (ex) {
38
- console.log(ex);
38
+ console.error(ex);
39
39
  }
40
40
 
41
41
  return <span>{parameterMap}</span>;
@@ -37,7 +37,7 @@ const StockReportStatus = (props: StockReportStatusProps) => {
37
37
  try {
38
38
  executionStateMap = displayParameterMap(props.model?.uuid, parseParametersToMap(props.model?.executionState));
39
39
  } catch (ex) {
40
- console.log(ex);
40
+ console.error(ex);
41
41
  }
42
42
  return (
43
43
  <div className={styles.statusContainer}>
@@ -1,32 +1,39 @@
1
1
  import React, { useCallback, useMemo } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
3
  import {
4
+ Button,
4
5
  DataTable,
5
6
  DataTableSkeleton,
6
- TabPanel,
7
+ InlineLoading,
7
8
  Pagination,
8
9
  Table,
9
10
  TableBody,
10
11
  TableCell,
11
12
  TableContainer,
13
+ TableExpandedRow,
14
+ TableExpandHeader,
15
+ TableExpandRow,
12
16
  TableHead,
13
17
  TableHeader,
14
18
  TableRow,
15
19
  TableToolbar,
20
+ TableToolbarAction,
16
21
  TableToolbarContent,
22
+ TableToolbarMenu,
17
23
  TableToolbarSearch,
24
+ TabPanel,
18
25
  Tile,
19
- Button,
20
- InlineLoading,
21
- TableToolbarMenu,
22
- TableToolbarAction,
23
- TableExpandHeader,
24
- TableExpandRow,
25
- TableExpandedRow,
26
26
  } from '@carbon/react';
27
+ import {
28
+ CheckmarkOutline,
29
+ Copy,
30
+ Download,
31
+ IncompleteCancel,
32
+ MisuseOutline,
33
+ View,
34
+ WarningAltFilled,
35
+ } from '@carbon/react/icons';
27
36
  import { isDesktop, restBaseUrl, useSession } from '@openmrs/esm-framework';
28
- import NewReportActionButton from './new-report-button.component';
29
- import styles from './stock-reports.scss';
30
37
  import { useGetReports } from '../stock-reports.resource';
31
38
  import {
32
39
  URL_BATCH_JOB_ARTIFACT,
@@ -41,19 +48,12 @@ import {
41
48
  BatchJobStatusFailed,
42
49
  BatchJobStatusPending,
43
50
  } from '../../core/api/types/BatchJob';
44
- import {
45
- CheckmarkOutline,
46
- Copy,
47
- Download,
48
- IncompleteCancel,
49
- MisuseOutline,
50
- View,
51
- WarningAltFilled,
52
- } from '@carbon/react/icons';
53
51
  import { handleMutate } from '../../utils';
54
52
  import { PrivilagedView } from '../../core/components/privilages-component/privilages.component';
53
+ import NewReportActionButton from './new-report-button.component';
55
54
  import StockReportStatus from './stock-report-status.component';
56
55
  import StockReportParameters from './stock-report-parameters.component';
56
+ import styles from './stock-reports.scss';
57
57
 
58
58
  const StockReports: React.FC = () => {
59
59
  const { t } = useTranslation();
@@ -202,12 +202,9 @@ const StockReports: React.FC = () => {
202
202
  }
203
203
 
204
204
  return (
205
- <div className={styles.tableOverride}>
205
+ <div className={styles.container}>
206
206
  <TabPanel>{t('ReportDescription', 'List of reports requested by users')}</TabPanel>
207
- <div id="table-tool-bar">
208
- <div></div>
209
- <div className="right-filters"></div>
210
- </div>
207
+
211
208
  <DataTable
212
209
  rows={tableRows}
213
210
  headers={tableHeaders}
@@ -225,7 +222,9 @@ const StockReports: React.FC = () => {
225
222
  <TableToolbarContent className={styles.toolbarContent}>
226
223
  <TableToolbarSearch persistent onChange={onInputChange} />
227
224
  <TableToolbarMenu>
228
- <TableToolbarAction onClick={handleRefresh}>Refresh</TableToolbarAction>
225
+ <TableToolbarAction className={styles.toolbarMenuAction} onClick={handleRefresh}>
226
+ {t('refresh', 'Refresh')}
227
+ </TableToolbarAction>
229
228
  </TableToolbarMenu>
230
229
  {canCreateReport && <NewReportActionButton />}
231
230
  </TableToolbarContent>
@@ -1,8 +1,12 @@
1
- @use '@carbon/styles/scss/colors';
2
- @use '@carbon/styles/scss/type';
1
+ @use '@carbon/colors';
3
2
  @use '@carbon/layout';
3
+ @use '@carbon/type';
4
4
  @use '@openmrs/esm-styleguide/src/vars' as *;
5
5
 
6
+ .container {
7
+ margin: layout.$spacing-05;
8
+ }
9
+
6
10
  .content {
7
11
  @include type.type-style('heading-compact-02');
8
12
  color: $text-02;
@@ -78,3 +82,7 @@
78
82
  margin-right: 4px;
79
83
  }
80
84
  }
85
+
86
+ .toolbarMenuAction {
87
+ max-width: none;
88
+ }
@@ -2,10 +2,6 @@
2
2
  @use '@carbon/type';
3
3
  @use '@openmrs/esm-styleguide/src/vars' as *;
4
4
 
5
- .section {
6
- margin: layout.$spacing-03;
7
- }
8
-
9
5
  .sectionTitle {
10
6
  @include type.type-style('heading-compact-02');
11
7
  color: $text-02;
@@ -15,6 +11,7 @@
15
11
  .modalBody {
16
12
  padding-bottom: layout.$spacing-05;
17
13
  }
14
+
18
15
  .formContainer {
19
16
  display: flex;
20
17
  flex-direction: column;
@@ -24,6 +21,7 @@
24
21
  }
25
22
 
26
23
  .button {
24
+ height: layout.$spacing-10;
27
25
  display: flex;
28
26
  align-content: flex-start;
29
27
  align-items: baseline;
@@ -39,3 +37,12 @@
39
37
  .body {
40
38
  padding: 1rem;
41
39
  }
40
+
41
+ .tablet {
42
+ padding: layout.$spacing-06 layout.$spacing-05;
43
+ background-color: white;
44
+ }
45
+
46
+ .desktop {
47
+ padding: 0;
48
+ }
@@ -1,24 +1,16 @@
1
1
  import React from 'react';
2
- import { render, screen } from '@testing-library/react';
3
2
  import userEvent from '@testing-library/user-event';
4
- import '@testing-library/jest-dom/extend-expect';
5
- import StockSourcesAddOrUpdate from './add-stock-sources.workspace';
3
+ import { render, screen } from '@testing-library/react';
4
+ import { type FetchResponse, useConfig } from '@openmrs/esm-framework';
5
+ import { type StockSource } from '../../core/api/types/stockOperation/StockSource';
6
6
  import { createOrUpdateStockSource } from '../stock-sources.resource';
7
- import { useConfig } from '@openmrs/esm-framework';
7
+ import StockSourcesAddOrUpdate from './add-stock-sources.workspace';
8
8
 
9
- import { type StockSource } from '../../core/api/types/stockOperation/StockSource';
9
+ const mockCreateOrUpdateStockSource = jest.mocked(createOrUpdateStockSource);
10
+ const mockUseConfig = jest.mocked(useConfig);
10
11
 
11
- jest.mock('../stock-sources.resource');
12
- jest.mock('@openmrs/esm-framework', () => ({
13
- showSnackbar: jest.fn(),
14
- useConfig: jest.fn(),
15
- getCoreTranslation: jest.fn((key, defaultValue) => {
16
- const translations: Record<string, string> = {
17
- cancel: 'Cancel',
18
- save: 'Save',
19
- };
20
- return translations[key] ?? defaultValue;
21
- }),
12
+ jest.mock('../stock-sources.resource', () => ({
13
+ createOrUpdateStockSource: jest.fn(),
22
14
  }));
23
15
 
24
16
  jest.mock('../../stock-lookups/stock-lookups.resource', () => ({
@@ -34,7 +26,7 @@ jest.mock('../../stock-lookups/stock-lookups.resource', () => ({
34
26
 
35
27
  describe('StockSourcesAddOrUpdate', () => {
36
28
  beforeEach(() => {
37
- (useConfig as jest.Mock).mockReturnValue({ stockSourceTypeUUID: 'mock-uuid' });
29
+ mockUseConfig.mockReturnValue({ stockSourceTypeUUID: 'mock-uuid' });
38
30
  });
39
31
 
40
32
  it('renders correctly without model prop', () => {
@@ -46,9 +38,9 @@ describe('StockSourcesAddOrUpdate', () => {
46
38
  promptBeforeClosing={jest.fn()}
47
39
  />,
48
40
  );
49
- expect(screen.getByLabelText('Full Name')).toBeInTheDocument();
50
- expect(screen.getByLabelText('Acronym/Code')).toBeInTheDocument();
51
- expect(screen.getByLabelText('Source Type')).toBeInTheDocument();
41
+ expect(screen.getByLabelText(/full name/i)).toBeInTheDocument();
42
+ expect(screen.getByLabelText(/acronym\/code/i)).toBeInTheDocument();
43
+ expect(screen.getByLabelText(/source type/i)).toBeInTheDocument();
52
44
  });
53
45
 
54
46
  it('renders correctly with model prop', () => {
@@ -110,9 +102,9 @@ describe('StockSourcesAddOrUpdate', () => {
110
102
  promptBeforeClosing={jest.fn()}
111
103
  />,
112
104
  );
113
- expect(screen.getByLabelText('Full Name')).toHaveValue('Test Source');
114
- expect(screen.getByLabelText('Acronym/Code')).toHaveValue('TS');
115
- expect(screen.getByLabelText('Source Type')).toHaveValue('type1');
105
+ expect(screen.getByLabelText(/full name/i)).toHaveValue('Test Source');
106
+ expect(screen.getByLabelText(/acronym\/code/i)).toHaveValue('TS');
107
+ expect(screen.getByLabelText(/source type/i)).toHaveValue('type1');
116
108
  });
117
109
 
118
110
  it('updates form fields correctly on user input', async () => {
@@ -126,16 +118,21 @@ describe('StockSourcesAddOrUpdate', () => {
126
118
  />,
127
119
  );
128
120
 
129
- await user.type(screen.getByLabelText('Full Name'), 'New Source');
130
- await user.type(screen.getByLabelText('Acronym/Code'), 'NS');
121
+ await user.type(screen.getByLabelText(/full name/i), 'New Source');
122
+ await user.type(screen.getByLabelText(/acronym\/code/i), 'NS');
131
123
 
132
- expect(screen.getByLabelText('Full Name')).toHaveValue('New Source');
133
- expect(screen.getByLabelText('Acronym/Code')).toHaveValue('NS');
124
+ expect(screen.getByLabelText(/full name/i)).toHaveValue('New Source');
125
+ expect(screen.getByLabelText(/acronym\/code/i)).toHaveValue('NS');
134
126
  });
135
127
 
136
128
  it('calls createOrUpdateStockSource with correct data on form submission', async () => {
137
129
  const user = userEvent.setup();
138
- (createOrUpdateStockSource as jest.Mock).mockResolvedValue({});
130
+ mockCreateOrUpdateStockSource.mockResolvedValue({
131
+ data: {},
132
+ ok: true,
133
+ status: 200,
134
+ statusText: 'OK',
135
+ } as unknown as FetchResponse);
139
136
 
140
137
  render(
141
138
  <StockSourcesAddOrUpdate
@@ -146,15 +143,20 @@ describe('StockSourcesAddOrUpdate', () => {
146
143
  />,
147
144
  );
148
145
 
149
- await user.type(screen.getByLabelText('Full Name'), 'New Source');
150
- await user.type(screen.getByLabelText('Acronym/Code'), 'NS');
151
- await user.selectOptions(screen.getByLabelText('Source Type'), 'type2');
146
+ await user.type(screen.getByLabelText(/full name/i), 'New Source');
147
+ await user.type(screen.getByLabelText(/acronym\/code/i), 'NS');
148
+ await user.selectOptions(screen.getByLabelText(/source type/i), 'type2');
152
149
  await user.click(screen.getByText('Save'));
153
150
  });
154
151
 
155
152
  it('shows success message and closes overlay on successful submission', async () => {
156
153
  const user = userEvent.setup();
157
- (createOrUpdateStockSource as jest.Mock).mockResolvedValue({});
154
+ mockCreateOrUpdateStockSource.mockResolvedValue({
155
+ data: {},
156
+ ok: true,
157
+ status: 200,
158
+ statusText: 'OK',
159
+ } as unknown as FetchResponse);
158
160
 
159
161
  render(
160
162
  <StockSourcesAddOrUpdate
@@ -165,12 +167,12 @@ describe('StockSourcesAddOrUpdate', () => {
165
167
  />,
166
168
  );
167
169
 
168
- await user.click(screen.getByText('Save'));
170
+ await user.click(screen.getByText(/save/i));
169
171
  });
170
172
 
171
173
  it('shows error message on failed submission', async () => {
172
174
  const user = userEvent.setup();
173
- (createOrUpdateStockSource as jest.Mock).mockRejectedValue(new Error('API Error'));
175
+ mockCreateOrUpdateStockSource.mockRejectedValue(new Error('API Error'));
174
176
 
175
177
  render(
176
178
  <StockSourcesAddOrUpdate
@@ -181,7 +183,7 @@ describe('StockSourcesAddOrUpdate', () => {
181
183
  />,
182
184
  );
183
185
 
184
- await user.click(screen.getByText('Save'));
186
+ await user.click(screen.getByText(/save/i));
185
187
  });
186
188
 
187
189
  it('closes overlay when cancel button is clicked', async () => {
@@ -195,6 +197,6 @@ describe('StockSourcesAddOrUpdate', () => {
195
197
  />,
196
198
  );
197
199
 
198
- await user.click(screen.getByText('Cancel'));
200
+ await user.click(screen.getByText(/cancel/i));
199
201
  });
200
202
  });