@openmrs/esm-stock-management-app 1.0.1-pre.543 → 1.0.1-pre.554
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/271.js +1 -1
- package/dist/{157.js → 281.js} +1 -1
- package/dist/281.js.map +1 -0
- package/dist/319.js +1 -1
- package/dist/460.js +1 -1
- package/dist/574.js +1 -1
- package/dist/757.js +1 -1
- package/dist/788.js +1 -1
- package/dist/807.js +1 -1
- package/dist/833.js +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 +52 -52
- package/dist/routes.json +1 -1
- package/package.json +5 -5
- package/src/stock-home/stock-home-detail-cards.component.tsx +3 -3
- package/src/stock-home/stock-home-metrics.tsx +6 -1
- package/src/stock-items/add-stock-item/packaging-units/packaging-units-delete-modal.component.tsx +4 -1
- package/src/stock-items/add-stock-item/stock-item-details/stock-item-details.component.tsx +1 -1
- package/src/stock-items/add-stock-item/stock-item-units-edit/stock-item-units-edit.component.tsx +20 -15
- package/src/stock-operations/add-stock-operation/base-operation-details.component.tsx +4 -4
- package/src/stock-operations/add-stock-operation/received-items.component.tsx +6 -3
- package/src/stock-operations/add-stock-operation/stock-items-addition.component.tsx +3 -3
- package/src/stock-operations/stock-operation-types-selector/stock-operation-types-selector.component.tsx +2 -2
- package/src/stock-operations/stock-operations-dialog/stock-operations-dialog.component.tsx +16 -6
- package/src/stock-operations/stock-operations-filters.component.tsx +1 -1
- package/src/stock-operations/stock-operations-table.component.tsx +82 -122
- package/src/stock-operations/stock-operations-table.scss +61 -0
- package/src/stock-operations/stock-operations.resource.ts +0 -1
- package/src/stock-sources/stock-sources-delete/stock-sources-delete.component.tsx +4 -3
- package/src/stock-sources/stock-sources-delete/stock-sources-delete.test.tsx +190 -0
- package/translations/am.json +20 -11
- package/translations/ar.json +24 -15
- package/translations/en.json +20 -11
- package/translations/es.json +25 -16
- package/translations/fr.json +32 -23
- package/translations/he.json +21 -12
- package/translations/km.json +22 -13
- package/translations/zh.json +20 -11
- package/dist/157.js.map +0 -1
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { useCallback,
|
1
|
+
import React, { useCallback, useMemo, useState } from "react";
|
2
2
|
import { useStockOperationPages } from "./stock-operations-table.resource";
|
3
3
|
import { ResourceRepresentation } from "../core/api/api";
|
4
4
|
import {
|
@@ -30,10 +30,10 @@ import {
|
|
30
30
|
DatePicker,
|
31
31
|
TableToolbarMenu,
|
32
32
|
TableToolbarAction,
|
33
|
+
InlineLoading,
|
33
34
|
} from "@carbon/react";
|
34
35
|
import { ArrowRight } from "@carbon/react/icons";
|
35
36
|
import { formatDisplayDate } from "../core/utils/datetimeUtils";
|
36
|
-
import styles from "../stock-items/stock-items-table.scss";
|
37
37
|
import {
|
38
38
|
StockOperationStatusCancelled,
|
39
39
|
StockOperationStatusNew,
|
@@ -43,8 +43,8 @@ import {
|
|
43
43
|
import {
|
44
44
|
isDesktop,
|
45
45
|
restBaseUrl,
|
46
|
-
showModal,
|
47
46
|
useConfig,
|
47
|
+
showModal,
|
48
48
|
} from "@openmrs/esm-framework";
|
49
49
|
import StockOperationTypesSelector from "./stock-operation-types-selector/stock-operation-types-selector.component";
|
50
50
|
import { launchAddOrEditDialog } from "./stock-operation.utils";
|
@@ -59,6 +59,9 @@ import {
|
|
59
59
|
StockFilters,
|
60
60
|
} from "../constants";
|
61
61
|
import { handleMutate } from "../utils";
|
62
|
+
|
63
|
+
import styles from "./stock-operations-table.scss";
|
64
|
+
|
62
65
|
interface StockOperationsTableProps {
|
63
66
|
status?: string;
|
64
67
|
}
|
@@ -95,6 +98,12 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
95
98
|
[]
|
96
99
|
);
|
97
100
|
|
101
|
+
const [selectedFromDate, setSelectedFromDate] = useState(null);
|
102
|
+
const [selectedToDate, setSelectedToDate] = useState(null);
|
103
|
+
const [selectedSources, setSelectedSources] = useState<string[]>([]);
|
104
|
+
const [selectedStatus, setSelectedStatus] = useState<string[]>([]);
|
105
|
+
const [selectedOperations, setSelectedOperations] = useState<string[]>([]);
|
106
|
+
|
98
107
|
const {
|
99
108
|
items,
|
100
109
|
tableHeaders,
|
@@ -108,17 +117,24 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
108
117
|
} = useStockOperationPages({
|
109
118
|
v: ResourceRepresentation.Full,
|
110
119
|
totalCount: true,
|
120
|
+
operationDateMin: selectedFromDate?.toISOString(),
|
121
|
+
operationDateMax: selectedToDate?.toISOString(),
|
122
|
+
status: selectedStatus.join(","),
|
123
|
+
sourceTypeUuid: selectedSources.join(","),
|
124
|
+
operationTypeUuid: selectedOperations.join(","),
|
111
125
|
});
|
112
126
|
|
113
|
-
const
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
127
|
+
const filterApplied =
|
128
|
+
selectedFromDate ||
|
129
|
+
selectedToDate ||
|
130
|
+
selectedSources.length ||
|
131
|
+
selectedStatus.length ||
|
132
|
+
selectedOperations.length;
|
133
|
+
|
119
134
|
const config = useConfig();
|
120
135
|
|
121
136
|
let operations: StockOperationType[] | null | undefined;
|
137
|
+
|
122
138
|
const handleOnComplete = () => {
|
123
139
|
const dispose = showModal("stock-operation-dialog", {
|
124
140
|
title: "complete",
|
@@ -127,19 +143,6 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
127
143
|
handleMutate(`${restBaseUrl}/stockmanagement/stockoperation`);
|
128
144
|
};
|
129
145
|
|
130
|
-
useEffect(() => {
|
131
|
-
filterItems();
|
132
|
-
}, [
|
133
|
-
selectedFromDate,
|
134
|
-
selectedToDate,
|
135
|
-
selectedSources,
|
136
|
-
selectedStatus,
|
137
|
-
selectedOperations,
|
138
|
-
currentPage,
|
139
|
-
currentPageSize,
|
140
|
-
items,
|
141
|
-
]);
|
142
|
-
|
143
146
|
const handleOnFilterChange = useCallback((selectedItems, filterType) => {
|
144
147
|
if (filterType === StockFilters.SOURCES) {
|
145
148
|
setSelectedSources(selectedItems);
|
@@ -165,51 +168,15 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
165
168
|
}
|
166
169
|
};
|
167
170
|
|
168
|
-
const filterItems = () => {
|
169
|
-
let filtered = items;
|
170
|
-
|
171
|
-
if (selectedSources.length > 0) {
|
172
|
-
filtered = filtered.filter((row) =>
|
173
|
-
selectedSources.includes(row.sourceName)
|
174
|
-
);
|
175
|
-
}
|
176
|
-
if (selectedOperations.length > 0) {
|
177
|
-
filtered = filtered.filter((row) =>
|
178
|
-
selectedOperations.includes(row.operationTypeName)
|
179
|
-
);
|
180
|
-
}
|
181
|
-
if (selectedStatus.length > 0) {
|
182
|
-
filtered = filtered.filter((row) => selectedStatus.includes(row.status));
|
183
|
-
}
|
184
|
-
if (selectedFromDate && selectedToDate) {
|
185
|
-
filtered = filtered.filter((row) => {
|
186
|
-
const itemDate = new Date(row.operationDate);
|
187
|
-
return itemDate >= selectedFromDate && itemDate <= selectedToDate;
|
188
|
-
});
|
189
|
-
} else if (selectedFromDate) {
|
190
|
-
filtered = filtered.filter((row) => {
|
191
|
-
const itemDate = new Date(row.operationDate);
|
192
|
-
return itemDate >= selectedFromDate;
|
193
|
-
});
|
194
|
-
} else if (selectedToDate) {
|
195
|
-
filtered = filtered.filter((row) => {
|
196
|
-
const itemDate = new Date(row.operationDate);
|
197
|
-
return itemDate <= selectedToDate;
|
198
|
-
});
|
199
|
-
}
|
200
|
-
|
201
|
-
setFilteredItems(filtered);
|
202
|
-
};
|
203
|
-
|
204
171
|
const tableRows = useMemo(() => {
|
205
|
-
return
|
172
|
+
return items?.map((stockOperation, index) => ({
|
206
173
|
...stockOperation,
|
207
174
|
id: stockOperation?.uuid,
|
208
175
|
key: `key-${stockOperation?.uuid}`,
|
209
176
|
operationTypeName: `${stockOperation?.operationTypeName}`,
|
210
177
|
operationNumber: (
|
211
178
|
<EditStockOperationActionMenu
|
212
|
-
model={
|
179
|
+
model={items[index]}
|
213
180
|
operations={operations}
|
214
181
|
/>
|
215
182
|
),
|
@@ -348,7 +315,7 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
348
315
|
onClick={() => {
|
349
316
|
launchAddOrEditDialog(
|
350
317
|
t,
|
351
|
-
|
318
|
+
items[index],
|
352
319
|
true,
|
353
320
|
operation,
|
354
321
|
operations,
|
@@ -359,9 +326,9 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
359
326
|
</OverflowMenu>
|
360
327
|
),
|
361
328
|
}));
|
362
|
-
}, [
|
329
|
+
}, [items, operation, operations, t]);
|
363
330
|
|
364
|
-
if (isLoading) {
|
331
|
+
if (isLoading && !filterApplied) {
|
365
332
|
return (
|
366
333
|
<DataTableSkeleton
|
367
334
|
className={styles.dataTableSkeleton}
|
@@ -531,47 +498,39 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
531
498
|
<StructuredListBody>
|
532
499
|
<StructuredListRow>
|
533
500
|
<StructuredListCell noWrap>
|
534
|
-
{
|
535
|
-
? formatDisplayDate(
|
536
|
-
filteredItems[index]?.dateCreated
|
537
|
-
)
|
501
|
+
{items[index]?.dateCreated
|
502
|
+
? formatDisplayDate(items[index]?.dateCreated)
|
538
503
|
: ""}
|
539
504
|
|
540
|
-
{
|
505
|
+
{items[index]?.dateCreated ? "By" : ""}
|
541
506
|
|
542
|
-
{
|
543
|
-
?
|
507
|
+
{items[index]?.dateCreated
|
508
|
+
? items[index]?.creatorFamilyName
|
544
509
|
: ""}
|
545
510
|
</StructuredListCell>
|
546
511
|
<StructuredListCell>
|
547
|
-
{
|
512
|
+
{items[index]?.completedDate
|
548
513
|
? formatDisplayDate(
|
549
|
-
|
514
|
+
items[index]?.completedDate
|
550
515
|
)
|
551
516
|
: ""}
|
552
517
|
|
553
|
-
{
|
554
|
-
? "By"
|
555
|
-
: ""}
|
518
|
+
{items[index]?.completedDate ? "By" : ""}
|
556
519
|
|
557
|
-
{
|
558
|
-
?
|
520
|
+
{items[index]?.completedDate
|
521
|
+
? items[index]?.creatorFamilyName
|
559
522
|
: ""}
|
560
523
|
</StructuredListCell>
|
561
524
|
<StructuredListCell>
|
562
|
-
{
|
563
|
-
?
|
564
|
-
index
|
565
|
-
].stockOperationItems?.map(
|
525
|
+
{items[index]?.stockOperationItems
|
526
|
+
? items[index].stockOperationItems?.map(
|
566
527
|
(item) => item.batchNo
|
567
528
|
)[0]
|
568
529
|
: ""}
|
569
530
|
</StructuredListCell>
|
570
531
|
<StructuredListCell>
|
571
|
-
{
|
572
|
-
?
|
573
|
-
index
|
574
|
-
].stockOperationItems?.map(
|
532
|
+
{items[index]?.stockOperationItems
|
533
|
+
? items[index].stockOperationItems?.map(
|
575
534
|
(item) => item.quantity
|
576
535
|
)[0]
|
577
536
|
: ""}
|
@@ -579,61 +538,55 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
579
538
|
</StructuredListRow>
|
580
539
|
<StructuredListRow>
|
581
540
|
<StructuredListCell noWrap>
|
582
|
-
{
|
541
|
+
{items[index]?.stockOperationItems.map(
|
583
542
|
(item) => item.quantity
|
584
543
|
)[1]
|
585
|
-
? formatDisplayDate(
|
586
|
-
filteredItems[index]?.dateCreated
|
587
|
-
)
|
544
|
+
? formatDisplayDate(items[index]?.dateCreated)
|
588
545
|
: ""}
|
589
546
|
|
590
|
-
{
|
547
|
+
{items[index]?.stockOperationItems.map(
|
591
548
|
(item) => item.quantity
|
592
549
|
)[1]
|
593
550
|
? "By"
|
594
551
|
: ""}
|
595
552
|
|
596
|
-
{
|
553
|
+
{items[index]?.stockOperationItems.map(
|
597
554
|
(item) => item.quantity
|
598
555
|
)[1]
|
599
|
-
?
|
556
|
+
? items[index]?.creatorFamilyName
|
600
557
|
: ""}
|
601
558
|
</StructuredListCell>
|
602
559
|
<StructuredListCell>
|
603
|
-
{
|
560
|
+
{items[index]?.stockOperationItems.map(
|
604
561
|
(item) => item.quantity
|
605
562
|
)[1]
|
606
563
|
? formatDisplayDate(
|
607
|
-
|
564
|
+
items[index]?.completedDate
|
608
565
|
)
|
609
566
|
: ""}
|
610
567
|
|
611
|
-
{
|
568
|
+
{items[index]?.stockOperationItems.map(
|
612
569
|
(item) => item.quantity
|
613
|
-
)[1] &&
|
570
|
+
)[1] && items[index]?.completedDate
|
614
571
|
? "By"
|
615
572
|
: ""}
|
616
573
|
|
617
|
-
{
|
574
|
+
{items[index]?.stockOperationItems.map(
|
618
575
|
(item) => item.quantity
|
619
|
-
)[1] &&
|
576
|
+
)[1] && items[index]?.completedDate
|
620
577
|
? items[index]?.creatorFamilyName
|
621
578
|
: ""}
|
622
579
|
</StructuredListCell>
|
623
580
|
<StructuredListCell>
|
624
|
-
{
|
625
|
-
?
|
626
|
-
index
|
627
|
-
].stockOperationItems?.map(
|
581
|
+
{items[index]?.stockOperationItems
|
582
|
+
? items[index].stockOperationItems?.map(
|
628
583
|
(item) => item.batchNo
|
629
584
|
)[1]
|
630
585
|
: ""}
|
631
586
|
</StructuredListCell>
|
632
587
|
<StructuredListCell>
|
633
|
-
{
|
634
|
-
?
|
635
|
-
index
|
636
|
-
].stockOperationItems?.map(
|
588
|
+
{items[index]?.stockOperationItems
|
589
|
+
? items[index].stockOperationItems?.map(
|
637
590
|
(item) => item.quantity
|
638
591
|
)[1]
|
639
592
|
: ""}
|
@@ -647,7 +600,7 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
647
600
|
})}
|
648
601
|
</TableBody>
|
649
602
|
</Table>
|
650
|
-
{rows.length === 0 ? (
|
603
|
+
{rows.length === 0 && !isLoading ? (
|
651
604
|
<div className={styles.tileContainer}>
|
652
605
|
<Tile className={styles.tile}>
|
653
606
|
<div className={styles.tileContent}>
|
@@ -661,24 +614,31 @@ const StockOperations: React.FC<StockOperationsTableProps> = () => {
|
|
661
614
|
</Tile>
|
662
615
|
</div>
|
663
616
|
) : null}
|
617
|
+
{filterApplied && isLoading && (
|
618
|
+
<div className={styles.rowLoadingContainer}>
|
619
|
+
<InlineLoading description={t("loading", "Loading...")} />
|
620
|
+
</div>
|
621
|
+
)}
|
664
622
|
</TableContainer>
|
665
623
|
)}
|
666
624
|
></DataTable>
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
625
|
+
{items.length > 0 && (
|
626
|
+
<Pagination
|
627
|
+
page={currentPage}
|
628
|
+
pageSize={currentPageSize}
|
629
|
+
pageSizes={pageSizes}
|
630
|
+
totalItems={totalItems}
|
631
|
+
onChange={({ pageSize, page }) => {
|
632
|
+
if (pageSize !== currentPageSize) {
|
633
|
+
setPageSize(pageSize);
|
634
|
+
}
|
635
|
+
if (page !== currentPage) {
|
636
|
+
goTo(page);
|
637
|
+
}
|
638
|
+
}}
|
639
|
+
className={styles.paginationOverride}
|
640
|
+
/>
|
641
|
+
)}
|
682
642
|
</div>
|
683
643
|
);
|
684
644
|
};
|
@@ -0,0 +1,61 @@
|
|
1
|
+
@use '@carbon/styles/scss/spacing';
|
2
|
+
@use '@carbon/styles/scss/type';
|
3
|
+
@import "~@openmrs/esm-styleguide/src/vars";
|
4
|
+
@import '../root.scss';
|
5
|
+
|
6
|
+
.tileContainer {
|
7
|
+
background-color: $ui-02;
|
8
|
+
border-top: 1px solid $ui-03;
|
9
|
+
padding: 5rem 0;
|
10
|
+
}
|
11
|
+
|
12
|
+
.tile {
|
13
|
+
margin: auto;
|
14
|
+
width: fit-content;
|
15
|
+
}
|
16
|
+
|
17
|
+
.tileContent {
|
18
|
+
display: flex;
|
19
|
+
flex-direction: column;
|
20
|
+
align-items: center;
|
21
|
+
}
|
22
|
+
|
23
|
+
.content {
|
24
|
+
@include type.type-style('heading-compact-02');
|
25
|
+
color: $text-02;
|
26
|
+
margin-bottom: 0.5rem;
|
27
|
+
}
|
28
|
+
|
29
|
+
.helper {
|
30
|
+
@include type.type-style('body-compact-01');
|
31
|
+
color: $text-02;
|
32
|
+
}
|
33
|
+
|
34
|
+
.toolbarContent {
|
35
|
+
display: flex;
|
36
|
+
align-items: center;
|
37
|
+
}
|
38
|
+
|
39
|
+
.filterContainer {
|
40
|
+
display: flex;
|
41
|
+
align-items: center;
|
42
|
+
}
|
43
|
+
|
44
|
+
.dateAlign {
|
45
|
+
padding-top: spacing.$spacing-03;
|
46
|
+
height: 100%;
|
47
|
+
}
|
48
|
+
|
49
|
+
.filterContainer {
|
50
|
+
display: flex;
|
51
|
+
align-items: center;
|
52
|
+
justify-content: space-between;
|
53
|
+
margin-bottom: spacing.$spacing-05;
|
54
|
+
}
|
55
|
+
|
56
|
+
.rowLoadingContainer {
|
57
|
+
text-align: center;
|
58
|
+
padding: 5rem 2rem;
|
59
|
+
margin: auto;
|
60
|
+
width: 20%;
|
61
|
+
}
|
@@ -7,7 +7,6 @@ import useSWR from "swr";
|
|
7
7
|
import { ResourceFilterCriteria, toQueryParams } from "../core/api/api";
|
8
8
|
import { PageableResult } from "../core/api/types/PageableResult";
|
9
9
|
import { StockOperationDTO } from "../core/api/types/stockOperation/StockOperationDTO";
|
10
|
-
import { StockOperationLinkDTO } from "../core/api/types/stockOperation/StockOperationLinkDTO";
|
11
10
|
import { StopOperationAction } from "../core/api/types/stockOperation/StockOperationAction";
|
12
11
|
import { InventoryGroupBy } from "../core/api/types/stockItem/StockItem";
|
13
12
|
|
@@ -61,9 +61,10 @@ const StockSourcesDeleteActionMenu: React.FC<
|
|
61
61
|
kind="ghost"
|
62
62
|
size="md"
|
63
63
|
onClick={handleDeleteStockSource}
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
aria-label={t("deleteSource", "Delete Source")}
|
65
|
+
>
|
66
|
+
<TrashCan size={16} />
|
67
|
+
</Button>
|
67
68
|
);
|
68
69
|
|
69
70
|
return deletingSource ? <InlineLoading /> : deleteButton;
|
@@ -0,0 +1,190 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import { render, fireEvent, waitFor, screen } from "@testing-library/react";
|
3
|
+
import "@testing-library/jest-dom/extend-expect";
|
4
|
+
import { showModal, showSnackbar } from "@openmrs/esm-framework";
|
5
|
+
import { deleteStockSource } from "../stock-sources.resource";
|
6
|
+
import StockSourcesDeleteActionMenu from "./stock-sources-delete.component";
|
7
|
+
import DeleteConfirmation from "../../stock-user-role-scopes/delete-stock-user-scope-modal.component";
|
8
|
+
import { handleMutate } from "../../utils";
|
9
|
+
|
10
|
+
jest.mock("react-i18next", () => ({
|
11
|
+
useTranslation: () => ({
|
12
|
+
t: (key) => key,
|
13
|
+
}),
|
14
|
+
}));
|
15
|
+
|
16
|
+
jest.mock("@openmrs/esm-framework", () => ({
|
17
|
+
showModal: jest.fn(),
|
18
|
+
showSnackbar: jest.fn(),
|
19
|
+
restBaseUrl: "http://localhost:8080",
|
20
|
+
}));
|
21
|
+
|
22
|
+
jest.mock("../stock-sources.resource", () => ({
|
23
|
+
deleteStockSource: jest.fn(),
|
24
|
+
}));
|
25
|
+
|
26
|
+
jest.mock("../../utils", () => ({
|
27
|
+
handleMutate: jest.fn(),
|
28
|
+
}));
|
29
|
+
|
30
|
+
describe("StockSourcesDeleteActionMenu", () => {
|
31
|
+
const uuid = "1234-5678";
|
32
|
+
const uuids: string[] = ["1234-5678"];
|
33
|
+
|
34
|
+
beforeEach(() => {
|
35
|
+
jest.clearAllMocks();
|
36
|
+
});
|
37
|
+
|
38
|
+
it("renders the delete button correctly", () => {
|
39
|
+
const { getByRole } = render(<StockSourcesDeleteActionMenu uuid={uuid} />);
|
40
|
+
const button = getByRole("button", { name: "deleteSource" });
|
41
|
+
expect(button).toBeInTheDocument();
|
42
|
+
});
|
43
|
+
|
44
|
+
it("opens the delete modal when the delete button is clicked", () => {
|
45
|
+
const { getByRole } = render(<StockSourcesDeleteActionMenu uuid={uuid} />);
|
46
|
+
const button = getByRole("button", { name: "deleteSource" });
|
47
|
+
fireEvent.click(button);
|
48
|
+
expect(showModal).toHaveBeenCalledWith("delete-stock-modal", expect.objectContaining({
|
49
|
+
close: expect.any(Function),
|
50
|
+
uuid: uuid,
|
51
|
+
onConfirmation: expect.any(Function),
|
52
|
+
}));
|
53
|
+
});
|
54
|
+
|
55
|
+
it('calls onConfirmation when delete is clicked', () => {
|
56
|
+
const mockOnConfirmation = jest.fn();
|
57
|
+
const mockClose = jest.fn();
|
58
|
+
|
59
|
+
render(
|
60
|
+
<DeleteConfirmation
|
61
|
+
close={mockClose}
|
62
|
+
onConfirmation={mockOnConfirmation}
|
63
|
+
/>
|
64
|
+
);
|
65
|
+
|
66
|
+
expect(screen.getByText(/deleteStockUserScope/i)).toBeInTheDocument();
|
67
|
+
|
68
|
+
const deleteButton = screen.getByRole('button', { name: /delete/i });
|
69
|
+
fireEvent.click(deleteButton);
|
70
|
+
|
71
|
+
expect(mockOnConfirmation).toHaveBeenCalledTimes(1);
|
72
|
+
expect(mockClose).not.toHaveBeenCalled();
|
73
|
+
});
|
74
|
+
|
75
|
+
it("calls deleteStockSource with the correct UUID on confirmation", async () => {
|
76
|
+
const mockOnConfirmation = jest.fn();
|
77
|
+
const mockClose = jest.fn();
|
78
|
+
|
79
|
+
render(
|
80
|
+
<DeleteConfirmation
|
81
|
+
close={mockClose}
|
82
|
+
onConfirmation={() => {
|
83
|
+
mockOnConfirmation();
|
84
|
+
deleteStockSource([uuid]);
|
85
|
+
}}
|
86
|
+
/>
|
87
|
+
);
|
88
|
+
|
89
|
+
const deleteButton = screen.getByRole('button', { name: /delete/i });
|
90
|
+
fireEvent.click(deleteButton);
|
91
|
+
|
92
|
+
expect(mockOnConfirmation).toHaveBeenCalledTimes(1);
|
93
|
+
expect(deleteStockSource).toHaveBeenCalledWith([uuid]);
|
94
|
+
});
|
95
|
+
|
96
|
+
it("calls handleMutate with the correct URL on successful deletion", async () => {
|
97
|
+
(deleteStockSource as jest.Mock).mockResolvedValueOnce({});
|
98
|
+
|
99
|
+
const mockOnConfirmation = jest.fn();
|
100
|
+
const mockClose = jest.fn();
|
101
|
+
|
102
|
+
render(
|
103
|
+
<DeleteConfirmation
|
104
|
+
close={mockClose}
|
105
|
+
onConfirmation={async () => {
|
106
|
+
await deleteStockSource([uuid]);
|
107
|
+
handleMutate("/openmrs/ws/rest/v1/stocksource");
|
108
|
+
}}
|
109
|
+
/>
|
110
|
+
);
|
111
|
+
|
112
|
+
const deleteButton = screen.getByRole('button', { name: /delete/i });
|
113
|
+
fireEvent.click(deleteButton);
|
114
|
+
|
115
|
+
await waitFor(() => {
|
116
|
+
expect(deleteStockSource).toHaveBeenCalledWith([uuid]);
|
117
|
+
expect(handleMutate).toHaveBeenCalledWith("/openmrs/ws/rest/v1/stocksource");
|
118
|
+
});
|
119
|
+
});
|
120
|
+
|
121
|
+
it("calls showSnackbar with the correct parameters on deletion error", async () => {
|
122
|
+
(deleteStockSource as jest.Mock).mockRejectedValueOnce(new Error("Deletion failed"));
|
123
|
+
|
124
|
+
const mockOnConfirmation = jest.fn();
|
125
|
+
const mockClose = jest.fn();
|
126
|
+
|
127
|
+
render(
|
128
|
+
<DeleteConfirmation
|
129
|
+
close={mockClose}
|
130
|
+
onConfirmation={async () => {
|
131
|
+
try {
|
132
|
+
await deleteStockSource([uuid]);
|
133
|
+
} catch (error) {
|
134
|
+
showSnackbar({
|
135
|
+
title: "stockSourceDeleteError",
|
136
|
+
kind: "error",
|
137
|
+
});
|
138
|
+
}
|
139
|
+
}}
|
140
|
+
/>
|
141
|
+
);
|
142
|
+
|
143
|
+
const deleteButton = screen.getByRole('button', { name: /delete/i });
|
144
|
+
fireEvent.click(deleteButton);
|
145
|
+
|
146
|
+
await waitFor(() => {
|
147
|
+
expect(deleteStockSource).toHaveBeenCalledWith([uuid]);
|
148
|
+
expect(showSnackbar).toHaveBeenCalledWith({
|
149
|
+
title: "stockSourceDeleteError",
|
150
|
+
kind: "error",
|
151
|
+
});
|
152
|
+
});
|
153
|
+
});
|
154
|
+
|
155
|
+
it("handles the error state correctly when the delete action fails", async () => {
|
156
|
+
(deleteStockSource as jest.Mock).mockRejectedValueOnce(new Error("Deletion failed"));
|
157
|
+
|
158
|
+
const mockOnConfirmation = jest.fn();
|
159
|
+
const mockClose = jest.fn();
|
160
|
+
|
161
|
+
render(
|
162
|
+
<DeleteConfirmation
|
163
|
+
close={mockClose}
|
164
|
+
onConfirmation={async () => {
|
165
|
+
try {
|
166
|
+
await deleteStockSource([uuid]);
|
167
|
+
} catch (error) {
|
168
|
+
showSnackbar({
|
169
|
+
title: "stockSourceDeleteError",
|
170
|
+
kind: "error",
|
171
|
+
});
|
172
|
+
}
|
173
|
+
}}
|
174
|
+
/>
|
175
|
+
);
|
176
|
+
|
177
|
+
const deleteButton = screen.getByRole("button", { name: /delete/i });
|
178
|
+
fireEvent.click(deleteButton);
|
179
|
+
|
180
|
+
await waitFor(() => {
|
181
|
+
expect(deleteStockSource).toHaveBeenCalledWith([uuid]);
|
182
|
+
|
183
|
+
expect(showSnackbar).toHaveBeenCalledWith({
|
184
|
+
title: "stockSourceDeleteError",
|
185
|
+
kind: "error",
|
186
|
+
});
|
187
|
+
expect(deleteButton).toBeInTheDocument();
|
188
|
+
});
|
189
|
+
});
|
190
|
+
});
|