@asteby/metacore-runtime-react 34.0.1 → 34.1.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/dialogs/dynamic-record.d.ts.map +1 -1
  3. package/dist/dialogs/dynamic-record.js +19 -2
  4. package/dist/dialogs/import.d.ts.map +1 -1
  5. package/dist/dialogs/import.js +6 -10
  6. package/dist/display-value.d.ts +23 -0
  7. package/dist/display-value.d.ts.map +1 -1
  8. package/dist/display-value.js +34 -1
  9. package/dist/dynamic-columns.d.ts +3 -0
  10. package/dist/dynamic-columns.d.ts.map +1 -1
  11. package/dist/dynamic-columns.js +36 -6
  12. package/dist/dynamic-select-field.d.ts.map +1 -1
  13. package/dist/dynamic-select-field.js +2 -6
  14. package/dist/dynamic-table.d.ts.map +1 -1
  15. package/dist/dynamic-table.js +10 -7
  16. package/dist/file-pick-button.d.ts +21 -0
  17. package/dist/file-pick-button.d.ts.map +1 -0
  18. package/dist/file-pick-button.js +39 -0
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +3 -0
  22. package/dist/metadata-cache.d.ts.map +1 -1
  23. package/dist/metadata-cache.js +8 -1
  24. package/dist/types.d.ts +1 -1
  25. package/dist/types.d.ts.map +1 -1
  26. package/dist/upload-field.d.ts.map +1 -1
  27. package/dist/upload-field.js +27 -32
  28. package/dist/use-debounced-value.d.ts +8 -0
  29. package/dist/use-debounced-value.d.ts.map +1 -0
  30. package/dist/use-debounced-value.js +15 -0
  31. package/dist/use-dynamic-filters.d.ts.map +1 -1
  32. package/dist/use-dynamic-filters.js +6 -4
  33. package/package.json +1 -1
  34. package/src/__tests__/image-stack.test.tsx +52 -0
  35. package/src/__tests__/use-debounced-value.test.ts +56 -0
  36. package/src/dialogs/dynamic-record.tsx +43 -1
  37. package/src/dialogs/import.tsx +9 -15
  38. package/src/display-value.tsx +82 -4
  39. package/src/dynamic-columns.tsx +79 -6
  40. package/src/dynamic-select-field.tsx +2 -6
  41. package/src/dynamic-table.tsx +9 -6
  42. package/src/file-pick-button.tsx +125 -0
  43. package/src/index.ts +11 -0
  44. package/src/metadata-cache.ts +8 -1
  45. package/src/types.ts +2 -0
  46. package/src/upload-field.tsx +41 -71
  47. package/src/use-debounced-value.ts +17 -0
  48. package/src/use-dynamic-filters.ts +6 -4
@@ -0,0 +1,17 @@
1
+ import { useEffect, useState } from 'react'
2
+
3
+ /** Default delay for free-text search → server/URL (table, kanban, relation). */
4
+ export const SEARCH_DEBOUNCE_MS = 350
5
+
6
+ /**
7
+ * Returns `value` delayed by `ms`. The input stays live; only the returned
8
+ * value lags — use it for fetches and URL sync so typing does not thrash.
9
+ */
10
+ export function useDebouncedValue<T>(value: T, ms: number = SEARCH_DEBOUNCE_MS): T {
11
+ const [debounced, setDebounced] = useState(value)
12
+ useEffect(() => {
13
+ const t = setTimeout(() => setDebounced(value), ms)
14
+ return () => clearTimeout(t)
15
+ }, [value, ms])
16
+ return debounced
17
+ }
@@ -14,6 +14,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
14
14
  import { useApi } from './api-context'
15
15
  import { DATE_CELL_TYPES } from './dynamic-columns'
16
16
  import { getSearchableColumnKeys } from './column-visibility'
17
+ import { useDebouncedValue } from './use-debounced-value'
17
18
  import { useFacetLoaders, isLongTextColumn } from './use-facet-loaders'
18
19
  import type { ColumnFilterConfig, FilterOption } from './dynamic-columns-shim'
19
20
  import type { TableMetadata } from './types'
@@ -82,6 +83,7 @@ export function useDynamicFilters(
82
83
 
83
84
  const [dynamicFilters, setDynamicFilters] = useState<Record<string, string[]>>({})
84
85
  const [globalFilter, setGlobalFilter] = useState('')
86
+ const debouncedGlobalFilter = useDebouncedValue(globalFilter)
85
87
  const [filterOptionsMap, setFilterOptionsMap] = useState<
86
88
  Map<string, FilterOption[]>
87
89
  >(new Map())
@@ -343,11 +345,11 @@ export function useDynamicFilters(
343
345
  // DynamicTable.buildFilterParams (IN:/RANGE:/GTE:/LTE:/ILIKE:/plain).
344
346
  const filterParams = useMemo(() => {
345
347
  const params: Record<string, any> = {}
346
- if (globalFilter) {
348
+ if (debouncedGlobalFilter) {
347
349
  if (searchableKeys === null) {
348
- params.search = globalFilter
350
+ params.search = debouncedGlobalFilter
349
351
  } else if (searchableKeys.length > 0) {
350
- params.search = globalFilter
352
+ params.search = debouncedGlobalFilter
351
353
  params.search_columns = searchableKeys.join(',')
352
354
  }
353
355
  // searchableKeys === [] → no searchable column, skip the search param.
@@ -371,7 +373,7 @@ export function useDynamicFilters(
371
373
  else params[`f_${key}`] = `IN:${values.join(',')}`
372
374
  })
373
375
  return params
374
- }, [globalFilter, searchableKeys, defaultFilters, dynamicFilters])
376
+ }, [debouncedGlobalFilter, searchableKeys, defaultFilters, dynamicFilters])
375
377
 
376
378
  const activeFilterCount = useMemo(() => {
377
379
  let n = Object.values(dynamicFilters).filter((v) => v.length > 0).length