@openmrs/esm-stock-management-app 1.0.1-pre.352 → 1.0.1-pre.359

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,22 @@
1
1
  import { StockOperationFilter } from "../stock-operations/stock-operations.resource";
2
2
  import { useMemo, useState } from "react";
3
- import { usePagination } from "@openmrs/esm-framework";
3
+ import {
4
+ FetchResponse,
5
+ openmrsFetch,
6
+ restBaseUrl,
7
+ showToast,
8
+ usePagination,
9
+ } from "@openmrs/esm-framework";
4
10
  import { useTranslation } from "react-i18next";
5
- import { useStockLocations } from "../stock-lookups/stock-lookups.resource";
11
+ import {
12
+ useStockLocations,
13
+ useStockTagLocations,
14
+ } from "../stock-lookups/stock-lookups.resource";
15
+ import useSWR from "swr";
16
+ import { extractErrorMessagesFromResponse } from "../constants";
6
17
 
7
18
  export function useStockLocationPages(filter: StockOperationFilter) {
8
- const { locations, isErrorLocation, isLoadingLocations } =
9
- useStockLocations(filter);
19
+ const { stockLocations, error, isLoading } = useStockTagLocations();
10
20
 
11
21
  const pageSizes = [10, 20, 30, 40, 50];
12
22
  const [currentPageSize, setPageSize] = useState(10);
@@ -15,7 +25,7 @@ export function useStockLocationPages(filter: StockOperationFilter) {
15
25
  goTo,
16
26
  results: paginatedQueueEntries,
17
27
  currentPage,
18
- } = usePagination(locations.results, currentPageSize);
28
+ } = usePagination(stockLocations, currentPageSize);
19
29
 
20
30
  const { t } = useTranslation();
21
31
 
@@ -46,28 +56,73 @@ export function useStockLocationPages(filter: StockOperationFilter) {
46
56
  );
47
57
 
48
58
  const tableRows = useMemo(() => {
49
- return locations?.results?.map((location) => ({
59
+ return stockLocations.map((location) => ({
50
60
  id: location?.uuid,
51
61
  key: `key-${location?.uuid}`,
52
62
  uuid: `${location?.uuid}`,
53
63
  name: `${location?.name}`,
54
- tags: location?.tags?.map((p) => p.display)?.join(", ") ?? "",
64
+ tags:
65
+ location?.meta.tag
66
+ ?.filter((tag) => tag.code !== "SUBSETTED")
67
+ .map((p) => p.code)
68
+ ?.join(", ") ?? "",
55
69
  childLocations:
56
70
  location?.childLocations?.map((p) => p.display)?.join(", ") ?? "",
57
71
  }));
58
- }, [locations?.results]);
59
-
72
+ }, [stockLocations]);
60
73
  return {
61
- items: locations.results,
74
+ items: stockLocations,
62
75
  currentPage,
63
76
  currentPageSize,
64
77
  paginatedQueueEntries,
65
78
  goTo,
66
79
  pageSizes,
67
- isLoadingLocations,
68
- isErrorLocation,
80
+ isLoading,
81
+ error,
69
82
  setPageSize,
70
83
  tableHeaders,
71
84
  tableRows,
72
85
  };
73
86
  }
87
+
88
+ export const useLocationTags = () => {
89
+ const url = `${restBaseUrl}/locationtag/`;
90
+
91
+ // eslint-disable-next-line react-hooks/rules-of-hooks
92
+ const { data, error, isLoading, isValidating, mutate } = useSWR<
93
+ { data },
94
+ Error
95
+ >(url, openmrsFetch);
96
+ const results = data?.data?.results ? data?.data?.results : [];
97
+ return {
98
+ locationTagList: results,
99
+ loading: isLoading,
100
+ mutate,
101
+ };
102
+ };
103
+ interface LocationName {
104
+ name: string;
105
+ }
106
+ export async function saveLocation({
107
+ locationPayload,
108
+ }): Promise<FetchResponse<LocationName>> {
109
+ try {
110
+ const response: FetchResponse = await openmrsFetch(
111
+ `${restBaseUrl}/location/`,
112
+ {
113
+ method: "POST",
114
+ headers: { "Content-Type": "application/json" },
115
+ body: locationPayload,
116
+ }
117
+ );
118
+ return response;
119
+ } catch (error) {
120
+ const errorMessages = extractErrorMessagesFromResponse(error);
121
+ showToast({
122
+ description: errorMessages.join(", "),
123
+ title: "Error on saving form",
124
+ kind: "error",
125
+ critical: true,
126
+ });
127
+ }
128
+ }
@@ -0,0 +1,3 @@
1
+ .loaderContainer {
2
+ margin-bottom: 150px;
3
+ }
@@ -22,7 +22,12 @@ import StockOperationApproveDispatchButton from "../stock-operations-dialog/stoc
22
22
  import StockOperationCompleteDispatchButton from "../stock-operations-dialog/stock-operations-completed-dispatch-button.component";
23
23
  import StockOperationIssueStockButton from "../stock-operations-dialog/stock-operations-issue-stock-button.component";
24
24
  import { StockOperation } from "./stock-operation-context/useStockOperationContext";
25
- import { formatDate, parseDate, showToast } from "@openmrs/esm-framework";
25
+ import {
26
+ formatDate,
27
+ parseDate,
28
+ showSnackbar,
29
+ showToast,
30
+ } from "@openmrs/esm-framework";
26
31
  import {
27
32
  OperationType,
28
33
  StockOperationType,
@@ -43,12 +48,12 @@ const AddStockOperation: React.FC<AddStockOperationProps> = (props) => {
43
48
  if (isLoading) return <AccordionSkeleton />;
44
49
  if (isError) {
45
50
  closeOverlay();
46
- showToast({
51
+ showSnackbar({
47
52
  kind: "error",
48
53
  title: t("error", "Error"),
49
- description: t("errorLoadingStockOperation", "Error loading stock item"),
50
- millis: 5000,
51
- critical: true,
54
+ subtitle: t("errorLoadingStockOperation", "Error loading stock item"),
55
+ timeoutInMs: 5000,
56
+ isLowContrast: true,
52
57
  });
53
58
  return;
54
59
  }
@@ -65,6 +65,7 @@ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({
65
65
  const [roles, setRoles] = useState<Role[]>([]);
66
66
 
67
67
  const { data: user } = useUser(model?.uuid);
68
+ const [showItems, setShowItems] = useState(false);
68
69
 
69
70
  // operation types
70
71
  const {
@@ -110,6 +111,28 @@ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({
110
111
  });
111
112
  };
112
113
 
114
+ const [searchQuery, setSearchQuery] = useState<string>("");
115
+ const [filteredItems, setFilteredItems] = useState<any[]>([]);
116
+
117
+ const usersResults = users?.results ?? [];
118
+
119
+ const filterItems = (query: string) => {
120
+ if (query.trim() === "") {
121
+ setShowItems(false);
122
+ } else {
123
+ setShowItems(true);
124
+ const filtered = usersResults.filter((item: any) => {
125
+ const displayName = item?.person?.display ?? item?.display ?? "";
126
+ return displayName.toLowerCase().includes(query.toLowerCase());
127
+ });
128
+ setFilteredItems(filtered);
129
+ }
130
+ };
131
+
132
+ const handleSearchQueryChange = (query: string) => {
133
+ setSearchQuery(query);
134
+ filterItems(query);
135
+ };
113
136
  const onStockOperationTypeChanged = (
114
137
  event: React.ChangeEvent<HTMLInputElement>,
115
138
  uuid: string,
@@ -186,7 +209,7 @@ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({
186
209
  v: ResourceRepresentation.Default,
187
210
  q: searchTerm,
188
211
  } as any as UserFilterCriteria);
189
- }, 300),
212
+ }, 3),
190
213
  []
191
214
  );
192
215
 
@@ -288,7 +311,6 @@ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({
288
311
  }
289
312
  );
290
313
  };
291
-
292
314
  if (isLoading || loadingRoles || loadingUsers) {
293
315
  return (
294
316
  <InlineLoading
@@ -298,7 +320,6 @@ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({
298
320
  />
299
321
  );
300
322
  }
301
-
302
323
  return (
303
324
  <div>
304
325
  <Form>
@@ -313,16 +334,13 @@ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({
313
334
  id="userName"
314
335
  size="md"
315
336
  labelText={t("user", "User")}
316
- items={users?.results}
337
+ items={filteredItems}
317
338
  onChange={onUserChanged}
318
- shouldFilterItem={(data) => true}
319
- onFocus={() => users?.results || handleUsersSearch("")}
320
- onToggleClick={() =>
321
- users?.results || handleUsersSearch("")
322
- }
339
+ shouldFilterItem={() => true}
323
340
  itemToString={(item) =>
324
341
  `${item?.person?.display ?? item?.display ?? ""}`
325
342
  }
343
+ onInputChange={handleSearchQueryChange}
326
344
  placeholder="Filter..."
327
345
  />
328
346
  </>
@@ -429,6 +447,7 @@ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({
429
447
  <Checkbox
430
448
  value={type.uuid}
431
449
  checked={isOperationChecked(type)}
450
+ className={styles.checkbox}
432
451
  onChange={(event) =>
433
452
  onStockOperationTypeChanged(
434
453
  event,
@@ -436,7 +455,6 @@ const AddStockUserRoleScope: React.FC<AddStockUserRoleScopeProps> = ({
436
455
  isOperationChecked(type)
437
456
  )
438
457
  }
439
- className={styles.checkbox}
440
458
  labelText={type.name}
441
459
  id={type.uuid}
442
460
  />