@snapdragonsnursery/react-components 1.25.0 → 1.26.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snapdragonsnursery/react-components",
3
- "version": "1.25.0",
3
+ "version": "1.26.0",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -1,6 +1,7 @@
1
1
  import React, {
2
2
  useState,
3
3
  useEffect,
4
+ useLayoutEffect,
4
5
  useRef,
5
6
  useCallback,
6
7
  useMemo,
@@ -90,6 +91,30 @@ const ChildSearchModal = ({
90
91
  const { instance, accounts } = useMsal();
91
92
  const modalRef = useRef();
92
93
  const searchInputRef = useRef();
94
+ const prevIsOpenRef = useRef(false);
95
+ const statusPropRef = useRef(status);
96
+ const activeOnlyPropRef = useRef(activeOnly);
97
+ statusPropRef.current = status;
98
+ activeOnlyPropRef.current = activeOnly;
99
+
100
+ // When the modal opens (closed → open), reset status from props so a previous session
101
+ // does not stick and cause searches with no status param (API defaults to active-only).
102
+ useLayoutEffect(() => {
103
+ if (!isOpen) {
104
+ prevIsOpenRef.current = false;
105
+ return;
106
+ }
107
+ const wasOpen = prevIsOpenRef.current;
108
+ prevIsOpenRef.current = true;
109
+ if (wasOpen) return;
110
+ setAdvancedFilters((prev) => ({
111
+ ...prev,
112
+ // Match useState initialiser: treat "" like missing so we do not omit status on the API.
113
+ status:
114
+ statusPropRef.current ||
115
+ (activeOnlyPropRef.current ? "active" : "all"),
116
+ }));
117
+ }, [isOpen]);
93
118
 
94
119
  // Debounce search term
95
120
  useEffect(() => {
@@ -232,9 +257,8 @@ const ChildSearchModal = ({
232
257
  );
233
258
  }
234
259
 
235
- // Build query parameters
260
+ // Build query parameters (caller identity: Bearer token — Common API extracts oid from JWT)
236
261
  const params = new URLSearchParams({
237
- entra_id: accounts[0].localAccountId,
238
262
  search_term: debouncedSearchTerm,
239
263
  page: pagination.page,
240
264
  page_size: pagination.pageSize,
@@ -251,11 +275,20 @@ const ChildSearchModal = ({
251
275
  params.append("site_id", siteId.toString());
252
276
  }
253
277
 
254
- // Handle status filtering
255
- // Important: when status is "all", do not send active_only=true.
256
- // The status dropdown is the source of truth for active/inactive/all.
257
- if (advancedFilters.status && advancedFilters.status !== "all") {
258
- params.append("status", advancedFilters.status);
278
+ // Resolve status: prefer non-empty UI state, else props (handles empty/stale state before open sync).
279
+ const resolvedStatus =
280
+ advancedFilters.status != null &&
281
+ String(advancedFilters.status).trim() !== ""
282
+ ? String(advancedFilters.status).trim()
283
+ : status || (activeOnly ? "active" : "all");
284
+
285
+ // Backend (search-children) defaults active_only to true when status is omitted, so "all"
286
+ // must be sent explicitly as status=all — otherwise only active children are returned.
287
+ if (resolvedStatus === "all") {
288
+ params.append("status", "all");
289
+ params.append("active_only", "false");
290
+ } else if (resolvedStatus) {
291
+ params.append("status", resolvedStatus);
259
292
  }
260
293
 
261
294
  // Add room filter
@@ -332,6 +365,8 @@ const ChildSearchModal = ({
332
365
  advancedFilters,
333
366
  applicationContext,
334
367
  bypassPermissions,
368
+ status,
369
+ activeOnly,
335
370
  ]);
336
371
 
337
372
  // Search when debounced term changes
@@ -329,8 +329,8 @@ const ChildSearchPage = ({
329
329
  );
330
330
  }
331
331
 
332
+ // Caller identity: Bearer token — Common API extracts oid from JWT (do not send entra_id in query)
332
333
  const params = new URLSearchParams({
333
- entra_id: accounts[0].localAccountId,
334
334
  search_term: debouncedSearchTerm,
335
335
  page: pagination.page,
336
336
  page_size: pagination.pageSize,
@@ -347,14 +347,19 @@ const ChildSearchPage = ({
347
347
  params.append("site_id", siteId.toString());
348
348
  }
349
349
 
350
- // Handle status filtering
351
- // Important: when status is "all", do not send active_only=true.
352
- // The status dropdown is the source of truth for active/inactive/all.
353
- if (
354
- debouncedAdvancedFilters.status &&
355
- debouncedAdvancedFilters.status !== "all"
356
- ) {
357
- params.append("status", debouncedAdvancedFilters.status);
350
+ const resolvedStatus =
351
+ debouncedAdvancedFilters.status != null &&
352
+ String(debouncedAdvancedFilters.status).trim() !== ""
353
+ ? String(debouncedAdvancedFilters.status).trim()
354
+ : status || (activeOnly ? "active" : "all");
355
+
356
+ // Backend (search-children) defaults active_only to true when status is omitted, so "all"
357
+ // must be sent explicitly as status=all — otherwise only active children are returned.
358
+ if (resolvedStatus === "all") {
359
+ params.append("status", "all");
360
+ params.append("active_only", "false");
361
+ } else if (resolvedStatus) {
362
+ params.append("status", resolvedStatus);
358
363
  }
359
364
 
360
365
  // Add room filter
@@ -437,6 +442,8 @@ const ChildSearchPage = ({
437
442
  debouncedAdvancedFilters,
438
443
  applicationContext,
439
444
  bypassPermissions,
445
+ status,
446
+ activeOnly,
440
447
  ]);
441
448
 
442
449
  // Search when debounced term changes
@@ -613,8 +613,8 @@ const EmployeeSearchModal = ({
613
613
  );
614
614
  }
615
615
 
616
+ // Caller identity: Bearer token — Common API extracts oid from JWT (do not send entra_id in query)
616
617
  const params = new URLSearchParams({
617
- entra_id: accounts[0].localAccountId,
618
618
  search_term: debouncedSearchTerm,
619
619
  page: pagination.page,
620
620
  page_size: pagination.pageSize,
@@ -426,8 +426,8 @@ const EmployeeSearchPage = ({
426
426
  );
427
427
  }
428
428
 
429
+ // Caller identity: Bearer token — Common API extracts oid from JWT (do not send entra_id in query)
429
430
  const params = new URLSearchParams({
430
- entra_id: accounts[0].localAccountId,
431
431
  search_term: debouncedSearchTerm,
432
432
  page: loadAllResults ? 1 : pagination.page,
433
433
  page_size: loadAllResults ? 10000 : pagination.pageSize,