@openmrs/esm-stock-management-app 3.0.1-pre.833 → 3.0.1-pre.835

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 (34) hide show
  1. package/dist/119.js +1 -0
  2. package/dist/119.js.map +1 -0
  3. package/dist/467.js +1 -0
  4. package/dist/467.js.map +1 -0
  5. package/dist/642.js.map +1 -1
  6. package/dist/{780.js → 769.js} +1 -1
  7. package/dist/769.js.map +1 -0
  8. package/dist/793.js +1 -1
  9. package/dist/93.js +1 -0
  10. package/dist/93.js.map +1 -0
  11. package/dist/main.js +1 -1
  12. package/dist/main.js.map +1 -1
  13. package/dist/openmrs-esm-stock-management-app.js +1 -1
  14. package/dist/openmrs-esm-stock-management-app.js.buildmanifest.json +84 -12
  15. package/dist/routes.json +1 -1
  16. package/package.json +1 -1
  17. package/src/index.ts +21 -0
  18. package/src/routes.json +33 -19
  19. package/src/stock-items/add-stock-item/transactions/transactions.resource.tsx +5 -1
  20. package/src/stock-locations/stock-locations-table.component.tsx +1 -1
  21. package/src/stock-reports/generate-report/create-stock-report.scss +15 -16
  22. package/src/stock-reports/generate-report/{create-stock-report.component.tsx → create-stock-report.workspace.tsx} +29 -18
  23. package/src/stock-reports/report-list/new-report-button.component.tsx +5 -4
  24. package/src/stock-sources/add-stock-source-button.component.tsx +6 -5
  25. package/src/stock-sources/add-stock-sources/add-stock-sources.scss +24 -0
  26. package/src/stock-sources/add-stock-sources/add-stock-sources.test.tsx +68 -39
  27. package/src/stock-sources/add-stock-sources/{add-stock-sources.component.tsx → add-stock-sources.workspace.tsx} +65 -58
  28. package/src/stock-sources/edit-stock-source/edit-stock-source.component.tsx +7 -5
  29. package/src/stock-user-role-scopes/add-stock-user-role-scope-button.component.tsx +5 -4
  30. package/src/stock-user-role-scopes/add-stock-user-scope/add-stock-user-role-scope.scss +21 -0
  31. package/src/stock-user-role-scopes/add-stock-user-scope/{add-stock-user-role-scope.component.tsx → add-stock-user-role-scope.workspace.tsx} +196 -194
  32. package/src/stock-user-role-scopes/edit-stock-user-scope/edit-stock-user-scope-action-menu.component.tsx +7 -5
  33. package/dist/780.js.map +0 -1
  34. /package/src/stock-locations/{add-locations-form.component.tsx → add-locations-form.workspace.tsx} +0 -0
@@ -3,9 +3,6 @@ import {
3
3
  Checkbox,
4
4
  CheckboxGroup,
5
5
  Form,
6
- ModalBody,
7
- ModalFooter,
8
- ModalHeader,
9
6
  InlineLoading,
10
7
  Toggle,
11
8
  DatePickerInput,
@@ -13,6 +10,7 @@ import {
13
10
  ComboBox,
14
11
  Select,
15
12
  SelectItem,
13
+ ButtonSet,
16
14
  } from '@carbon/react';
17
15
  import React, { type ChangeEvent, useEffect, useState } from 'react';
18
16
  import styles from './add-stock-user-role-scope.scss';
@@ -24,11 +22,16 @@ import {
24
22
  useUsers,
25
23
  } from '../../stock-lookups/stock-lookups.resource';
26
24
  import { ResourceRepresentation } from '../../core/api/api';
27
- import { closeOverlay } from '../../core/components/overlay/hook';
28
25
  import { useTranslation } from 'react-i18next';
29
26
  import { type UserRoleScope } from '../../core/api/types/identity/UserRoleScope';
30
27
  import { createOrUpdateUserRoleScope } from '../stock-user-role-scopes.resource';
31
- import { restBaseUrl, showSnackbar, useSession } from '@openmrs/esm-framework';
28
+ import {
29
+ type DefaultWorkspaceProps,
30
+ restBaseUrl,
31
+ showSnackbar,
32
+ useSession,
33
+ getCoreTranslation,
34
+ } from '@openmrs/esm-framework';
32
35
  import { type UserRoleScopeOperationType } from '../../core/api/types/identity/UserRoleScopeOperationType';
33
36
  import { type UserRoleScopeLocation } from '../../core/api/types/identity/UserRoleScopeLocation';
34
37
  import {
@@ -46,15 +49,16 @@ import { type User } from '../../core/api/types/identity/User';
46
49
  import { type Role } from '../../core/api/types/identity/Role';
47
50
  import { type StockOperationType } from '../../core/api/types/stockOperation/StockOperationType';
48
51
  import { handleMutate } from '../../utils';
52
+ import { Save } from '@carbon/react/icons';
49
53
 
50
54
  const MinDate: Date = today();
51
55
 
52
- interface AddStockUserRoleScopeProps {
56
+ type AddStockUserRoleScopeProps = DefaultWorkspaceProps & {
53
57
  model?: UserRoleScope;
54
58
  editMode?: boolean;
55
- }
59
+ };
56
60
 
57
- const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({ model, editMode }) => {
61
+ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({ model, editMode, closeWorkspace }) => {
58
62
  const { t } = useTranslation();
59
63
  const currentUser = useSession();
60
64
  const [formModel, setFormModel] = useState<UserRoleScope>({ ...model });
@@ -220,7 +224,7 @@ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({ model, ed
220
224
  kind: 'success',
221
225
  subtitle: t('successfullysaved', 'You have successfully saved user role scope'),
222
226
  });
223
- closeOverlay();
227
+ closeWorkspace();
224
228
  },
225
229
  (err) => {
226
230
  showSnackbar({
@@ -230,7 +234,7 @@ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({ model, ed
230
234
  subtitle: err?.message,
231
235
  });
232
236
 
233
- closeOverlay();
237
+ closeWorkspace();
234
238
  },
235
239
  );
236
240
  };
@@ -240,195 +244,193 @@ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({ model, ed
240
244
  );
241
245
  }
242
246
  return (
243
- <div>
244
- <Form>
245
- <ModalHeader />
246
- <ModalBody>
247
- <section className={styles.section}>
248
- <div>
249
- {users?.results?.length > 0 && (
250
- <>
251
- <span className={styles.subTitle}>{t('user', 'User')}</span>
252
- <ComboBox
253
- id="userName"
254
- size="md"
255
- labelText={t('user', 'User')}
256
- items={filteredItems.length ? filteredItems : usersResults}
257
- onChange={onUserChanged}
258
- shouldFilterItem={() => true}
259
- itemToString={(item) => `${item?.person?.display ?? item?.display ?? ''}`}
260
- onInputChange={handleSearchQueryChange}
261
- placeholder="Filter..."
262
- initialSelectedItem={usersResults.find((user) => user.uuid === model?.userUuid) ?? null}
263
- />
264
- </>
247
+ <div className={styles.formContainer}>
248
+ <div style={{ padding: '1rem' }}>
249
+ <section className={styles.section}>
250
+ <div>
251
+ {users?.results?.length > 0 && (
252
+ <>
253
+ <span className={styles.subTitle}>{t('user', 'User')}</span>
254
+ <ComboBox
255
+ id="userName"
256
+ size="md"
257
+ labelText={t('user', 'User')}
258
+ items={filteredItems.length ? filteredItems : usersResults}
259
+ onChange={onUserChanged}
260
+ shouldFilterItem={() => true}
261
+ itemToString={(item) => `${item?.person?.display ?? item?.display ?? ''}`}
262
+ onInputChange={handleSearchQueryChange}
263
+ placeholder="Filter..."
264
+ initialSelectedItem={usersResults.find((user) => user.uuid === model?.userUuid) ?? null}
265
+ />
266
+ </>
267
+ )}
268
+ </div>
269
+ </section>
270
+ <section className={styles.section}>
271
+ <div>
272
+ <Select
273
+ name="role"
274
+ className="select-field"
275
+ labelText={t('role', 'Role')}
276
+ id="select-role"
277
+ value={formModel.role ?? 'placeholder-item'}
278
+ onChange={onRoleChange}
279
+ >
280
+ <SelectItem disabled hidden value="placeholder-item" text={t('chooseARole', 'Choose a role')} />
281
+
282
+ {editMode ? (
283
+ <SelectItem key={formModel?.role} value={formModel?.role} text={formModel?.role} />
284
+ ) : (
285
+ (user?.roles ?? roles)?.map((role) => {
286
+ return <SelectItem key={role.display} value={role.display} text={role.display} />;
287
+ })
265
288
  )}
266
- </div>
267
- </section>
268
- <section className={styles.section}>
269
- <div>
270
- <Select
271
- name="role"
272
- className="select-field"
273
- labelText={t('role', 'Role')}
274
- id="select-role"
275
- value={formModel.role ?? 'placeholder-item'}
276
- onChange={onRoleChange}
277
- >
278
- <SelectItem disabled hidden value="placeholder-item" text={t('chooseARole', 'Choose a role')} />
279
-
280
- {editMode ? (
281
- <SelectItem key={formModel?.role} value={formModel?.role} text={formModel?.role} />
282
- ) : (
283
- (user?.roles ?? roles)?.map((role) => {
284
- return <SelectItem key={role.display} value={role.display} text={role.display} />;
285
- })
286
- )}
287
- </Select>
288
- </div>
289
- </section>
290
- <section className={styles.section}>
291
- <CheckboxGroup className={styles.checkboxGrid}>
292
- <Checkbox
293
- onChange={onEnabledChanged}
294
- checked={formModel?.enabled}
295
- labelText={t('enabled', 'Enabled ?')}
296
- value={model?.enabled}
297
- id="chk-userEnabled"
298
- />
299
- <Checkbox
300
- onChange={onPermanentChanged}
301
- name="isPermanent"
302
- checked={formModel?.permanent}
303
- value={model?.permanent}
304
- labelText={t('permanent', 'Permanent ?')}
305
- id="chk-userPermanent"
306
- />
307
-
308
- {!formModel?.permanent && (
309
- <>
310
- <DatePicker
311
- datePickerType="range"
312
- light
313
- minDate={formatForDatePicker(MinDate)}
314
- locale="en"
315
- dateFormat={DATE_PICKER_CONTROL_FORMAT}
316
- onChange={onActiveDatesChange}
317
- >
318
- <DatePickerInput
319
- id="date-picker-input-id-start"
320
- name="activeFrom"
321
- placeholder={DATE_PICKER_FORMAT}
322
- labelText={t('activeFrom', 'Active From')}
323
- value={formatForDatePicker(formModel?.activeFrom)}
289
+ </Select>
290
+ </div>
291
+ </section>
292
+ <section className={styles.section}>
293
+ <CheckboxGroup className={styles.checkboxGrid}>
294
+ <Checkbox
295
+ onChange={onEnabledChanged}
296
+ checked={formModel?.enabled}
297
+ labelText={t('enabled', 'Enabled ?')}
298
+ value={model?.enabled}
299
+ id="chk-userEnabled"
300
+ />
301
+ <Checkbox
302
+ onChange={onPermanentChanged}
303
+ name="isPermanent"
304
+ checked={formModel?.permanent}
305
+ value={model?.permanent}
306
+ labelText={t('permanent', 'Permanent ?')}
307
+ id="chk-userPermanent"
308
+ />
309
+
310
+ {!formModel?.permanent && (
311
+ <>
312
+ <DatePicker
313
+ datePickerType="range"
314
+ light
315
+ minDate={formatForDatePicker(MinDate)}
316
+ locale="en"
317
+ dateFormat={DATE_PICKER_CONTROL_FORMAT}
318
+ onChange={onActiveDatesChange}
319
+ >
320
+ <DatePickerInput
321
+ id="date-picker-input-id-start"
322
+ name="activeFrom"
323
+ placeholder={DATE_PICKER_FORMAT}
324
+ labelText={t('activeFrom', 'Active From')}
325
+ value={formatForDatePicker(formModel?.activeFrom)}
326
+ />
327
+ <DatePickerInput
328
+ id="date-picker-input-id-finish"
329
+ name="activeTo"
330
+ placeholder={DATE_PICKER_FORMAT}
331
+ labelText={t('activeTo', 'Active To')}
332
+ value={formatForDatePicker(formModel?.activeTo)}
333
+ />
334
+ </DatePicker>
335
+ </>
336
+ )}
337
+ </CheckboxGroup>
338
+ </section>
339
+ <br />
340
+ <section className={styles.section}>
341
+ <div style={{ display: 'flex', flexDirection: 'column' }}>
342
+ <span className={styles.sectionTitle}> {t('stockOperation', 'Stock Operations')}</span>
343
+ <div className={styles.hr} />
344
+ <span className={styles.subTitle}>
345
+ {t('roleDescription', 'The role will be applicable to only selected stock operations.')}
346
+ </span>
347
+ </div>
348
+ </section>
349
+ <section className={styles.section}>
350
+ <CheckboxGroup className={styles.checkboxGrid}>
351
+ {stockOperations?.length > 0 &&
352
+ stockOperations.map((type) => {
353
+ return (
354
+ <div style={{ display: 'flex', flexDirection: 'row' }}>
355
+ <Checkbox
356
+ value={type.uuid}
357
+ checked={isOperationChecked(type)}
358
+ className={styles.checkbox}
359
+ onChange={(event) => onStockOperationTypeChanged(event)}
360
+ labelText={type.name}
361
+ id={type.uuid}
324
362
  />
325
- <DatePickerInput
326
- id="date-picker-input-id-finish"
327
- name="activeTo"
328
- placeholder={DATE_PICKER_FORMAT}
329
- labelText={t('activeTo', 'Active To')}
330
- value={formatForDatePicker(formModel?.activeTo)}
363
+ </div>
364
+ );
365
+ })}
366
+ </CheckboxGroup>
367
+ </section>
368
+ <br />
369
+ <section className={styles.section}>
370
+ <div style={{ display: 'flex', flexDirection: 'column' }}>
371
+ <span className={styles.sectionTitle}> {t('locations', 'Locations')}</span>
372
+ <div className={styles.hr} />
373
+ <span className={styles.subTitle}>
374
+ {t('toggleMessage', 'Use the toggle to apply this scope to the locations under the selected location.')}
375
+ </span>
376
+ </div>
377
+ </section>
378
+ <section className={styles.section}>
379
+ <CheckboxGroup className={styles.checkboxGrid}>
380
+ {stockLocations?.length > 0 &&
381
+ stockLocations.map((type) => {
382
+ const checkedLocation = findCheckedLocation(type);
383
+
384
+ const getToggledValue = (locationUuid) => {
385
+ const location = checkedLocation?.locationUuid === locationUuid ? checkedLocation : null;
386
+ return location?.enableDescendants === true;
387
+ };
388
+
389
+ return (
390
+ <div
391
+ style={{
392
+ display: 'flex',
393
+ flexDirection: 'row',
394
+ margin: '4px',
395
+ padding: '5px',
396
+ }}
397
+ >
398
+ <Checkbox
399
+ name="location"
400
+ key={`chk-loc-child-key-${type.id}`}
401
+ id={`chk-loc-child-${type.id}`}
402
+ value={type.id}
403
+ onChange={(event) => onLocationCheckBoxChanged(event)}
404
+ className={styles.checkbox}
405
+ labelText={type.name}
406
+ checked={checkedLocation != null}
331
407
  />
332
- </DatePicker>
333
- </>
334
- )}
335
- </CheckboxGroup>
336
- </section>
337
- <br />
338
- <section className={styles.section}>
339
- <div style={{ display: 'flex', flexDirection: 'column' }}>
340
- <span className={styles.sectionTitle}> {t('stockOperation', 'Stock Operations')}</span>
341
- <div className={styles.hr} />
342
- <span className={styles.subTitle}>
343
- {t('roleDescription', 'The role will be applicable to only selected stock operations.')}
344
- </span>
345
- </div>
346
- </section>
347
- <section className={styles.section}>
348
- <CheckboxGroup className={styles.checkboxGrid}>
349
- {stockOperations?.length > 0 &&
350
- stockOperations.map((type) => {
351
- return (
352
- <div style={{ display: 'flex', flexDirection: 'row' }}>
353
- <Checkbox
354
- value={type.uuid}
355
- checked={isOperationChecked(type)}
356
- className={styles.checkbox}
357
- onChange={(event) => onStockOperationTypeChanged(event)}
358
- labelText={type.name}
359
- id={type.uuid}
360
- />
361
- </div>
362
- );
363
- })}
364
- </CheckboxGroup>
365
- </section>
366
- <br />
367
- <section className={styles.section}>
368
- <div style={{ display: 'flex', flexDirection: 'column' }}>
369
- <span className={styles.sectionTitle}> {t('locations', 'Locations')}</span>
370
- <div className={styles.hr} />
371
- <span className={styles.subTitle}>
372
- {t('toggleMessage', 'Use the toggle to apply this scope to the locations under the selected location.')}
373
- </span>
374
- </div>
375
- </section>
376
- <section className={styles.section}>
377
- <CheckboxGroup className={styles.checkboxGrid}>
378
- {stockLocations?.length > 0 &&
379
- stockLocations.map((type) => {
380
- const checkedLocation = findCheckedLocation(type);
381
-
382
- const getToggledValue = (locationUuid) => {
383
- const location = checkedLocation?.locationUuid === locationUuid ? checkedLocation : null;
384
- return location?.enableDescendants === true;
385
- };
386
-
387
- return (
388
- <div
389
- style={{
390
- display: 'flex',
391
- flexDirection: 'row',
392
- margin: '4px',
393
- padding: '5px',
394
- }}
395
- >
396
- <Checkbox
397
- name="location"
398
- key={`chk-loc-child-key-${type.id}`}
399
- id={`chk-loc-child-${type.id}`}
408
+ {checkedLocation && (
409
+ <Toggle
400
410
  value={type.id}
401
- onChange={(event) => onLocationCheckBoxChanged(event)}
402
- className={styles.checkbox}
403
- labelText={type.name}
404
- checked={checkedLocation != null}
411
+ hideLabel
412
+ className={styles.toggle}
413
+ size={'sm'}
414
+ onToggleClick={getToggledValue(type.id)}
415
+ key={`tg-loc-child-key-${type.id}`}
416
+ id={`tg-loc-child-${type.id}`}
405
417
  />
406
- {checkedLocation && (
407
- <Toggle
408
- value={type.id}
409
- hideLabel
410
- className={styles.toggle}
411
- size={'sm'}
412
- onToggleClick={getToggledValue(type.id)}
413
- key={`tg-loc-child-key-${type.id}`}
414
- id={`tg-loc-child-${type.id}`}
415
- />
416
- )}
417
- </div>
418
- );
419
- })}
420
- </CheckboxGroup>
421
- </section>
422
- </ModalBody>
423
- <ModalFooter>
424
- <Button kind="secondary" onClick={closeOverlay}>
425
- {t('cancel', 'Cancel')}
426
- </Button>
427
- <Button type="submit" onClick={addStockUserRole}>
428
- {t('save', 'Save')}
429
- </Button>
430
- </ModalFooter>
431
- </Form>
418
+ )}
419
+ </div>
420
+ );
421
+ })}
422
+ </CheckboxGroup>
423
+ </section>
424
+ </div>
425
+
426
+ <ButtonSet className={styles.buttonSet}>
427
+ <Button kind="secondary" onClick={closeWorkspace} className={styles.button}>
428
+ {getCoreTranslation('cancel', 'Cancel')}
429
+ </Button>
430
+ <Button type="submit" className={styles.button} onClick={addStockUserRole} renderIcon={Save}>
431
+ {getCoreTranslation('save', 'Save')}
432
+ </Button>
433
+ </ButtonSet>
432
434
  </div>
433
435
  );
434
436
  };
@@ -3,9 +3,8 @@ import { Edit } from '@carbon/react/icons';
3
3
 
4
4
  import React, { useCallback } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
- import { launchOverlay } from '../../core/components/overlay/hook';
7
- import AddStockUserRoleScope from '../add-stock-user-scope/add-stock-user-role-scope.component';
8
6
  import { type UserRoleScope } from '../../core/api/types/identity/UserRoleScope';
7
+ import { launchWorkspace } from '@openmrs/esm-framework';
9
8
 
10
9
  interface EditStockUserRoleActionsMenuProps {
11
10
  data: UserRoleScope;
@@ -15,14 +14,17 @@ const EditStockUserRoleActionsMenu: React.FC<EditStockUserRoleActionsMenuProps>
15
14
  const { t } = useTranslation();
16
15
 
17
16
  const handleClick = useCallback(() => {
18
- launchOverlay('Edit Stock User Role', <AddStockUserRoleScope model={data} editMode={true} />);
19
- }, [data]);
17
+ launchWorkspace('stock-user-role-scopes-form-workspace', {
18
+ workspaceTitle: t('editUserScope', 'Edit user scope role'),
19
+ model: data,
20
+ });
21
+ }, [data, t]);
20
22
 
21
23
  return (
22
24
  <Button
23
25
  kind="ghost"
24
26
  onClick={handleClick}
25
- iconDescription={t('editUserScope', 'Edit UserScope')}
27
+ iconDescription={t('editUserScope', 'Edit user scope role')}
26
28
  renderIcon={(props) => <Edit size={16} {...props} />}
27
29
  />
28
30
  );