@k-int/stripes-kint-components 5.17.0 → 5.19.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 (129) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/LICENSE +1 -1
  3. package/es/index.js +32 -12
  4. package/es/lib/EditableSettingsList/EditableSettingsList.js +4 -3
  5. package/es/lib/EditableSettingsList/EditableSettingsListFieldArray/EditableSettingsListFieldArray.js +110 -0
  6. package/es/lib/EditableSettingsList/{EditableSettingsListFieldArray.test.js → EditableSettingsListFieldArray/EditableSettingsListFieldArray.test.js} +3 -4
  7. package/es/lib/EditableSettingsList/EditableSettingsListFieldArray/index.js +13 -0
  8. package/es/lib/EditableSettingsList/SettingField/{EditSettingValue.js → EditSettingValue/EditSettingValue.js} +2 -2
  9. package/es/lib/EditableSettingsList/SettingField/{EditSettingValue.test.js → EditSettingValue/EditSettingValue.test.js} +2 -3
  10. package/es/lib/EditableSettingsList/SettingField/EditSettingValue/index.js +13 -0
  11. package/es/lib/EditableSettingsList/SettingField/{RenderSettingValue.js → RenderSettingValue/RenderSettingValue.js} +1 -1
  12. package/es/lib/EditableSettingsList/SettingField/{RenderSettingValue.test.js → RenderSettingValue/RenderSettingValue.test.js} +2 -2
  13. package/es/lib/EditableSettingsList/SettingField/RenderSettingValue/index.js +13 -0
  14. package/es/lib/EditableSettingsList/SettingField/SettingField.js +5 -5
  15. package/es/lib/EditableSettingsList/SettingField/SettingField.test.js +54 -44
  16. package/es/lib/EditableSettingsList/index.js +12 -0
  17. package/es/lib/SASQLookupComponent/SASQLookupComponent.js +5 -1
  18. package/es/lib/SearchKeyControl/SearchKeyControl.js +95 -0
  19. package/es/lib/SearchKeyControl/SearchKeyControl.test.js +177 -0
  20. package/es/lib/SearchKeyControl/index.js +13 -0
  21. package/es/lib/SettingPage/SettingPage.js +3 -1
  22. package/es/lib/SettingPage/{SettingPagePane.js → SettingPagePane/SettingPagePane.js} +2 -2
  23. package/es/lib/SettingPage/SettingPagePane/index.js +13 -0
  24. package/es/lib/hooks/__mocks__/index.js +2 -2
  25. package/es/lib/hooks/index.js +33 -21
  26. package/es/lib/hooks/intlHooks/index.js +27 -0
  27. package/es/lib/hooks/intlHooks/useIntlKey/index.js +13 -0
  28. package/es/lib/hooks/{useIntlKey.js → intlHooks/useIntlKey/useIntlKey.js} +1 -1
  29. package/es/lib/hooks/intlHooks/useIntlKeyStore/index.js +13 -0
  30. package/es/lib/hooks/intlHooks/useKintIntl/index.js +13 -0
  31. package/es/lib/hooks/{useKintIntl.js → intlHooks/useKintIntl/useKintIntl.js} +1 -1
  32. package/es/lib/hooks/useInvalidateRefdata/index.js +13 -0
  33. package/es/lib/hooks/{useInvalidateRefdata.js → useInvalidateRefdata/useInvalidateRefdata.js} +1 -1
  34. package/es/lib/hooks/useMutateCustomProperties/index.js +13 -0
  35. package/es/lib/hooks/{useMutateCustomProperties.js → useMutateCustomProperties/useMutateCustomProperties.js} +1 -1
  36. package/es/lib/hooks/useMutateGeneric/index.js +13 -0
  37. package/es/lib/hooks/useMutateRefdataCategory/index.js +13 -0
  38. package/es/lib/hooks/{useMutateRefdataCategory.js → useMutateRefdataCategory/useMutateRefdataCategory.js} +2 -2
  39. package/es/lib/hooks/useMutateRefdataValue/index.js +13 -0
  40. package/es/lib/hooks/{useMutateRefdataValue.js → useMutateRefdataValue/useMutateRefdataValue.js} +2 -2
  41. package/es/lib/settingsHooks/useAppSettings/index.js +13 -0
  42. package/es/lib/settingsHooks/{useAppSettings.js → useAppSettings/useAppSettings.js} +1 -1
  43. package/es/lib/settingsHooks/useSettingSection/index.js +13 -0
  44. package/es/lib/settingsHooks/{useSettingSection.js → useSettingSection/useSettingSection.js} +1 -1
  45. package/es/lib/settingsHooks/useSettings/index.js +13 -0
  46. package/es/lib/settingsHooks/{useSettings.js → useSettings/useSettings.js} +10 -9
  47. package/es/lib/utils/refdataQueryKey/index.js +13 -0
  48. package/package.json +1 -1
  49. package/src/index.js +8 -3
  50. package/src/lib/ActionList/README.md +18 -18
  51. package/src/lib/EditableSettingsList/EditableSettingsList.js +3 -2
  52. package/src/lib/EditableSettingsList/EditableSettingsListFieldArray/EditableSettingsListFieldArray.js +118 -0
  53. package/src/lib/EditableSettingsList/{EditableSettingsListFieldArray.test.js → EditableSettingsListFieldArray/EditableSettingsListFieldArray.test.js} +3 -5
  54. package/src/lib/EditableSettingsList/EditableSettingsListFieldArray/README.md +68 -0
  55. package/src/lib/EditableSettingsList/EditableSettingsListFieldArray/index.js +1 -0
  56. package/src/lib/EditableSettingsList/README.md +74 -0
  57. package/src/lib/EditableSettingsList/SettingField/{EditSettingValue.js → EditSettingValue/EditSettingValue.js} +2 -2
  58. package/src/lib/EditableSettingsList/SettingField/{EditSettingValue.test.js → EditSettingValue/EditSettingValue.test.js} +2 -5
  59. package/src/lib/EditableSettingsList/SettingField/EditSettingValue/README.md +63 -0
  60. package/src/lib/EditableSettingsList/SettingField/EditSettingValue/index.js +1 -0
  61. package/src/lib/EditableSettingsList/SettingField/README.md +61 -0
  62. package/src/lib/EditableSettingsList/SettingField/{RenderSettingValue.js → RenderSettingValue/RenderSettingValue.js} +1 -1
  63. package/src/lib/EditableSettingsList/SettingField/{RenderSettingValue.test.js → RenderSettingValue/RenderSettingValue.test.js} +2 -2
  64. package/src/lib/EditableSettingsList/SettingField/RenderSettingValue/index.js +1 -0
  65. package/src/lib/EditableSettingsList/SettingField/SettingField.js +5 -3
  66. package/src/lib/EditableSettingsList/SettingField/SettingField.test.js +65 -44
  67. package/src/lib/EditableSettingsList/index.js +1 -1
  68. package/src/lib/NumberField/README.md +134 -0
  69. package/src/lib/SASQLookupComponent/README.md +172 -0
  70. package/src/lib/SASQLookupComponent/SASQLookupComponent.js +6 -1
  71. package/src/lib/SASQLookupComponent/TableBody/README.md +113 -0
  72. package/src/lib/SASQRoute/README.md +49 -18
  73. package/src/lib/SASQViewComponent/README.md +132 -0
  74. package/src/lib/SearchKeyControl/README.md +70 -0
  75. package/src/lib/SearchKeyControl/SearchKeyControl.js +98 -0
  76. package/src/lib/SearchKeyControl/SearchKeyControl.test.js +165 -0
  77. package/src/lib/SearchKeyControl/index.js +1 -0
  78. package/src/lib/SettingPage/README.md +66 -0
  79. package/src/lib/SettingPage/SettingPage.js +3 -1
  80. package/src/lib/SettingPage/SettingPagePane/README.md +31 -0
  81. package/src/lib/SettingPage/{SettingPagePane.js → SettingPagePane/SettingPagePane.js} +2 -2
  82. package/src/lib/SettingPage/SettingPagePane/index.js +1 -0
  83. package/src/lib/hooks/README.md +26 -121
  84. package/src/lib/hooks/__mocks__/index.js +2 -2
  85. package/src/lib/hooks/index.js +2 -3
  86. package/src/lib/hooks/intlHooks/README.md +31 -0
  87. package/src/lib/hooks/intlHooks/index.js +3 -0
  88. package/src/lib/hooks/intlHooks/useIntlKey/README.md +23 -0
  89. package/src/lib/hooks/intlHooks/useIntlKey/index.js +1 -0
  90. package/src/lib/hooks/{useIntlKey.js → intlHooks/useIntlKey/useIntlKey.js} +1 -1
  91. package/src/lib/hooks/intlHooks/useIntlKeyStore/README.md +32 -0
  92. package/src/lib/hooks/intlHooks/useIntlKeyStore/index.js +1 -0
  93. package/src/lib/hooks/intlHooks/useKintIntl/README.md +42 -0
  94. package/src/lib/hooks/intlHooks/useKintIntl/index.js +1 -0
  95. package/src/lib/hooks/{useKintIntl.js → intlHooks/useKintIntl/useKintIntl.js} +1 -1
  96. package/src/lib/hooks/useInvalidateRefdata/README.md +72 -0
  97. package/src/lib/hooks/useInvalidateRefdata/index.js +1 -0
  98. package/src/lib/hooks/{useInvalidateRefdata.js → useInvalidateRefdata/useInvalidateRefdata.js} +1 -1
  99. package/src/lib/hooks/useMutateCustomProperties/README.md +88 -0
  100. package/src/lib/hooks/useMutateCustomProperties/index.js +1 -0
  101. package/src/lib/hooks/{useMutateCustomProperties.js → useMutateCustomProperties/useMutateCustomProperties.js} +1 -1
  102. package/src/lib/hooks/useMutateGeneric/README.md +187 -0
  103. package/src/lib/hooks/useMutateGeneric/index.js +1 -0
  104. package/src/lib/hooks/useMutateRefdataCategory/README.md +85 -0
  105. package/src/lib/hooks/useMutateRefdataCategory/index.js +1 -0
  106. package/src/lib/hooks/{useMutateRefdataCategory.js → useMutateRefdataCategory/useMutateRefdataCategory.js} +2 -2
  107. package/src/lib/hooks/useMutateRefdataValue/README.md +154 -0
  108. package/src/lib/hooks/useMutateRefdataValue/index.js +1 -0
  109. package/src/lib/hooks/{useMutateRefdataValue.js → useMutateRefdataValue/useMutateRefdataValue.js} +2 -2
  110. package/src/lib/settingsHooks/useAppSettings/README.md +24 -0
  111. package/src/lib/settingsHooks/useAppSettings/index.js +1 -0
  112. package/src/lib/settingsHooks/{useAppSettings.js → useAppSettings/useAppSettings.js} +1 -1
  113. package/src/lib/settingsHooks/useSettingSection/README.md +54 -0
  114. package/src/lib/settingsHooks/useSettingSection/index.js +1 -0
  115. package/src/lib/settingsHooks/{useSettingSection.js → useSettingSection/useSettingSection.js} +1 -1
  116. package/src/lib/settingsHooks/useSettings/README.md +84 -0
  117. package/src/lib/settingsHooks/useSettings/index.js +1 -0
  118. package/src/lib/settingsHooks/{useSettings.js → useSettings/useSettings.js} +10 -7
  119. package/src/lib/utils/refdataQueryKey/README.md +38 -0
  120. package/src/lib/utils/refdataQueryKey/index.js +1 -0
  121. package/styles/SearchKeyControl.css +14 -0
  122. package/es/lib/EditableSettingsList/EditableSettingsListFieldArray.js +0 -57
  123. package/src/lib/EditableSettingsList/EditableSettingsListFieldArray.js +0 -58
  124. /package/es/lib/hooks/{useIntlKeyStore.js → intlHooks/useIntlKeyStore/useIntlKeyStore.js} +0 -0
  125. /package/es/lib/hooks/{useMutateGeneric.js → useMutateGeneric/useMutateGeneric.js} +0 -0
  126. /package/es/lib/utils/{refdataQueryKey.js → refdataQueryKey/refdataQueryKey.js} +0 -0
  127. /package/src/lib/hooks/{useIntlKeyStore.js → intlHooks/useIntlKeyStore/useIntlKeyStore.js} +0 -0
  128. /package/src/lib/hooks/{useMutateGeneric.js → useMutateGeneric/useMutateGeneric.js} +0 -0
  129. /package/src/lib/utils/{refdataQueryKey.js → refdataQueryKey/refdataQueryKey.js} +0 -0
@@ -0,0 +1,42 @@
1
+ # useKintIntl
2
+
3
+ ## Purpose
4
+ Enhanced internationalization hook that extends `react-intl`'s `useIntl` with automatic key resolution and override support.
5
+
6
+ ## Key Features
7
+ - Automatic key prefixing with module-specific base path
8
+ - Fallback message support
9
+ - Type-safe override validation
10
+ - Message existence checking
11
+
12
+ ## Basic Usage
13
+ ```jsx
14
+ const MyComponent = () => {
15
+ const { formatKintMessage } = useKintIntl('myComponent', 'myModule');
16
+
17
+ return (
18
+ <div>
19
+ {formatKintMessage({ id: 'greeting' })}
20
+ </div>
21
+ );
22
+ };
23
+ ```
24
+
25
+ ## Override Behavior
26
+ Component-level overrides take precedence:
27
+ ```jsx
28
+ <MyComponent
29
+ intlKey="customKey"
30
+ intlNS="customNamespace"
31
+ />
32
+ ```
33
+
34
+ ## Methods
35
+ ### `formatKintMessage(options, values)`
36
+ - `options.id`: Relative translation key (auto-prefixed)
37
+ - `options.overrideValue`: Direct string or alternate translation key
38
+ - `options.fallbackMessage`: Fallback text if translation missing
39
+ - `values`: Injection values for placeholders
40
+
41
+ ### `messageExists(key)`
42
+ Checks if translation exists for resolved key
@@ -0,0 +1 @@
1
+ export { default } from './useKintIntl';
@@ -1,5 +1,5 @@
1
1
  import { useIntl } from 'react-intl';
2
- import useIntlKey from './useIntlKey';
2
+ import useIntlKey from '../useIntlKey';
3
3
 
4
4
  /* A hook to enrich the intl object we get from useIntl */
5
5
  const useKintIntl = (passedIntlKey, passedIntlNS) => {
@@ -0,0 +1,72 @@
1
+ # useInvalidateRefdata
2
+
3
+ ## Reference Data Cache Management Hook
4
+ A specialized utility for maintaining reference data consistency across the application.
5
+ Part of the reference data management ecosystem, designed to work with [`useMutateRefdataCategory`](../useMutateRefdataCategory/README.md) and [`useMutateRefdataValue`](../useMutateRefdataValue/README.md).
6
+
7
+ ## Basic Usage
8
+ ```jsx
9
+ const RefdataUpdater = () => {
10
+ const invalidate = useInvalidateRefdata('license_types');
11
+
12
+ const handleUpdate = async () => {
13
+ await updateLicenseTypes();
14
+ invalidate(); // Triggers cache refresh
15
+ };
16
+
17
+ return <Button onClick={handleUpdate}>Refresh Data</Button>;
18
+ };
19
+ ```
20
+
21
+ ### 2. Query Key Structure
22
+ Uses centralized key generator [`refdataQueryKey`](../../utils/refdataQueryKey/README.md):
23
+ ```js
24
+ refdataQueryKey('media_formats') => ['stripes-kint-components', 'refdata', 'media_formats']
25
+ ```
26
+
27
+ ## Parameters
28
+ | Parameter | Type | Required | Default | Description |
29
+ |-----------|------|----------|---------|-------------|
30
+ | `desc` | string | ✕ | - | Reference data category descriptor |
31
+
32
+ ## Advanced Usage
33
+
34
+ ### Batch Invalidation
35
+ ```jsx
36
+ const invalidateMedia = useInvalidateRefdata('media_types');
37
+ const invalidateLicenses = useInvalidateRefdata('license_types');
38
+
39
+ const handleGlobalRefresh = async () => {
40
+ await Promise.all([
41
+ invalidateMedia(),
42
+ invalidateLicenses()
43
+ ]);
44
+ };
45
+ ```
46
+
47
+ ### Conditional Invalidation
48
+ ```jsx
49
+ const RefdataForm = ({ category }) => {
50
+ const invalidate = useInvalidateRefdata(category?.type);
51
+
52
+ const handleSubmit = async (data) => {
53
+ await saveCategory(data);
54
+ if (category) invalidate();
55
+ };
56
+ };
57
+ ```
58
+
59
+ ## Integration Notes
60
+
61
+ ### Performance Considerations
62
+ - Prefer targeted invalidations over global refresh
63
+ - Combine with mutation hooks for automatic invalidation
64
+ - Avoid in tight loops - debounce if needed
65
+
66
+ ### Error Handling
67
+ - Safe to call multiple times
68
+ - Fails silently if no active queries match
69
+ - Returns promise for error chaining:
70
+ ```js
71
+ invalidate().catch(error => logger.error('Refresh failed', error));
72
+ ```
@@ -0,0 +1 @@
1
+ export { default } from './useInvalidateRefdata';
@@ -1,6 +1,6 @@
1
1
  import { useQueryClient } from 'react-query';
2
2
 
3
- import { refdataQueryKey } from '../utils';
3
+ import { refdataQueryKey } from '../../utils';
4
4
 
5
5
  const useInvalidateRefdata = (desc) => {
6
6
  const queryClient = useQueryClient();
@@ -0,0 +1,88 @@
1
+ # useMutateCustomProperties
2
+
3
+ ## Purpose-Specific Mutation Hook
4
+ A specialized abstraction of [`useMutateGeneric`](./useMutateGeneric.md) optimized for managing custom properties configurations in FOLIO. Designed for operations targeting specific resource identifiers with enforced endpoint structure.
5
+
6
+ ```mermaid
7
+ graph TD
8
+ A[useMutateCustomProperties] --> B[useMutateGeneric]
9
+ B --> C[Pre-configured Endpoints]
10
+ B --> D[Standardized Query Keys]
11
+ ```
12
+
13
+ ## When to Use
14
+ - Managing custom properties for **single-resource endpoints**
15
+ - Operations requiring fixed ID in URL paths
16
+ - Standardizing cache keys for property-related mutations
17
+
18
+ ## Key Differentiators
19
+ || useMutateGeneric | useMutateCustomProperties |
20
+ |---|---|---|
21
+ | **Endpoint Structure** | Configurable | Enforced `/endpoint/{id}` |
22
+ | **Query Key** | Customizable | Auto-generated hierarchy |
23
+ | **ID Handling** | Manual in calls | Built into configuration |
24
+
25
+ ## Usage Example
26
+ ```jsx
27
+ const CustomPropertiesEditor = ({ recordId }) => {
28
+ const { post, put } = useMutateCustomProperties({
29
+ endpoint: 'configurations/custom-properties',
30
+ id: recordId
31
+ });
32
+
33
+ const saveProperty = (property) =>
34
+ property.id ? put(property) : post(property);
35
+
36
+ return <PropertyForm onSubmit={saveProperty} />;
37
+ };
38
+ ```
39
+
40
+ ## Required Props
41
+ | Prop | Type | Description |
42
+ |------|------|-------------|
43
+ | `endpoint` | string | Base API path (e.g., `'license/custom-properties'`) |
44
+ | `id` | string | Unique resource identifier for URL construction |
45
+
46
+ ## Default Behavior
47
+ 1. **Endpoint Construction**
48
+ ```js
49
+ // PUT/DELETE endpoints
50
+ `${endpoint}/${id}`
51
+ ```
52
+ 2. **Query Key Structure**
53
+ ```js
54
+ ['stripes-kint-components', 'useMutateCustomProperties', id]
55
+ ```
56
+
57
+ ## Customization
58
+ While providing opinionated defaults, maintains full compatibility with [`useMutateGeneric`](./useMutateGeneric.md) configuration:
59
+
60
+ ```jsx
61
+ // Override delete endpoint while keeping other defaults
62
+ useMutateCustomProperties({
63
+ endpoint: 'inventory/types',
64
+ id: 'BOOK',
65
+ endpointMutators: {
66
+ delete: () => `inventory/legacy-types/${id}?version=2`
67
+ }
68
+ });
69
+ ```
70
+
71
+ ## Error Handling
72
+ Inherits the [error handling characteristics](./useMutateGeneric.md#error-handling-philosophy) of the base hook. Recommended pattern:
73
+
74
+ ```jsx
75
+ useMutateCustomProperties({
76
+ catchQueryCalls: {
77
+ post: (error) => {
78
+ logger.error('Custom property creation failed', error);
79
+ throw error; // Propagate to error boundary
80
+ }
81
+ }
82
+ });
83
+ ```
84
+
85
+ ## Performance Notes
86
+ - Cache keys automatically include the `id` parameter
87
+ - Memoize configurations when using multiple instances
88
+ - Prefer single instance per resource ID lifecycle
@@ -0,0 +1 @@
1
+ export { default } from './useMutateCustomProperties';
@@ -1,4 +1,4 @@
1
- import useMutateGeneric from './useMutateGeneric';
1
+ import useMutateGeneric from '../useMutateGeneric';
2
2
 
3
3
  const useMutateCustomProperties = ({
4
4
  endpoint,
@@ -0,0 +1,187 @@
1
+ # useMutateGeneric
2
+
3
+ ## Description
4
+ A configurable React Query mutation hook that abstracts CRUD operations for Okapi endpoints. Provides atomic control over POST/PUT/DELETE operations with deep customization while maintaining FOLIO API conventions.
5
+
6
+ **Key Features**:
7
+ - Auto-generated endpoint URLs
8
+ - Built-in error swallowing (silent catch unless overridden)
9
+ - Type-safe mutation separation
10
+ - Query key hierarchy management
11
+ - Full lifecycle event hooks
12
+
13
+ ---
14
+
15
+ ## Basic Usage
16
+ ```jsx
17
+ const { post, put, delete: destroy } = useMutateGeneric({
18
+ endpoint: 'users',
19
+ queryKey: ['user-management']
20
+ });
21
+
22
+ // Create user
23
+ const handleCreate = (userData) => post(userData);
24
+
25
+ // Update user
26
+ const handleUpdate = (updatedUser) => put(updatedUser);
27
+
28
+ // Delete user
29
+ const handleDelete = (userId) => destroy(userId);
30
+ ```
31
+
32
+ **Note**: By default:
33
+ - Errors are caught but not thrown (silent failure)
34
+ - POST goes to `/endpoint`
35
+ - PUT/DELETE go to `/endpoint/{id}`
36
+
37
+ ---
38
+
39
+ ## Advanced Use Cases
40
+
41
+ ### 1. Custom Endpoint Structure
42
+ ```jsx
43
+ // Custom endpoint for legacy system
44
+ useMutateGeneric({
45
+ endpoint: 'v2/inventory',
46
+ endpointMutators: {
47
+ put: (data) => `legacy-inventory/${data.legacyId}?version=1.2`
48
+ }
49
+ });
50
+ ```
51
+
52
+ ### 2. Payload Transformation
53
+ ```jsx
54
+ // Add audit metadata to payload
55
+ useMutateGeneric({
56
+ payloadMutators: {
57
+ post: (data) => ({
58
+ json: {
59
+ ...data,
60
+ metadata: {
61
+ createdBy: getCurrentUserId(),
62
+ createdDate: new Date().toISOString()
63
+ }
64
+ }
65
+ })
66
+ }
67
+ });
68
+ ```
69
+
70
+ ### 3. Custom Promise Handling
71
+ ```jsx
72
+ // Directly override HTTP method
73
+ useMutateGeneric({
74
+ promiseReturns: {
75
+ post: (data, ky) => ky.custom('PATCH', 'custom-endpoint', { data })
76
+ }
77
+ });
78
+ ```
79
+
80
+ ### 4. Full Mutation Control
81
+ ```jsx
82
+ // Access loading states and errors
83
+ const {
84
+ post: postMutation // Returns full mutation object
85
+ } = useMutateGeneric({
86
+ returnQueryObject: { post: true }
87
+ });
88
+
89
+ // Usage
90
+ postMutation.mutateAsync(data);
91
+ console.log('Loading:', postMutation.isLoading);
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Configuration Options
97
+
98
+ ### Core Parameters
99
+ | Parameter | Type | Required | Default | Description |
100
+ |-----------|------|----------|---------|-------------|
101
+ | `endpoint` | string | ✓ | - | Base API path (e.g., `'circulation/loans'`) |
102
+ | `queryKey` | array | ✓ | - | React Query root key (e.g., `['loans']`) |
103
+
104
+ ### Operation-Specific Parameters (post/put/delete)
105
+ | Parameter | Type | Default | Description |
106
+ |-----------|------|---------|-------------|
107
+ | `endpointMutators.{op}` | `(data) => string` | [See below] | Generates final endpoint URL |
108
+ | `payloadMutators.{op}` | `(data) => object` | Returns `{ json: data }` | Shapes request payload |
109
+ | `promiseReturns.{op}` | `(data, ky) => Promise` | Standard CRUD | Full control over fetch implementation |
110
+ | `queryKeyMutators.{op}` | `() => array` | Appends operation type | Custom query key construction |
111
+ | `afterQueryCalls.{op}` | `(response) => void` | - | Success side effects |
112
+ | `catchQueryCalls.{op}` | `(error) => void` | Silent catch | Custom error handling |
113
+ | `returnQueryObject.{op}` | boolean | `false` | Returns full mutation object |
114
+
115
+ **Default Endpoint Mutators**:
116
+ - POST: `() => endpoint`
117
+ - PUT: `(data) => ${endpoint}/${data.id}`
118
+ - DELETE: `(id) => ${endpoint}/${id}`
119
+
120
+ ---
121
+
122
+ ## How It Works
123
+
124
+ ### Architecture Flow
125
+ 1. **Hook Initialization**
126
+ - Receives base configuration
127
+ - Creates three isolated `useMutation` instances (post/put/delete)
128
+
129
+ 2. **Request Execution**
130
+ ```mermaid
131
+ graph TD
132
+ A[User calls post(data)] --> B[Apply payloadMutators]
133
+ B --> C[Build endpoint via endpointMutators]
134
+ C --> D[Execute promiseReturns with ky]
135
+ D --> E[Trigger afterQueryCalls]
136
+ E --> F[Update React Query cache]
137
+ ```
138
+
139
+ 3. **Error Handling**
140
+ - Errors bubble through `catchQueryCalls`
141
+ - Uncaught errors are swallowed unless `catchQueryCalls` re-throws
142
+
143
+ 4. **Cache Management**
144
+ - Automatic query key generation via `queryKeyMutators`
145
+ - No automatic cache invalidation (must use `useQueryClient`)
146
+
147
+ ---
148
+
149
+ ## Critical Implementation Notes
150
+
151
+ ### 1. Error Handling Philosophy
152
+ - Default: Fails silently (prevents uncaught promise warnings)
153
+ - To surface errors:
154
+ ```js
155
+ useMutateGeneric({
156
+ catchQueryCalls: {
157
+ post: (error) => {
158
+ showErrorToast(error);
159
+ throw error; // Propagate to UI errorBoundary if necessary
160
+ }
161
+ }
162
+ });
163
+ ```
164
+
165
+ ### 2. Type Safety
166
+ - No runtime validation of payload shapes
167
+ - Recommend validation in `payloadMutators`:
168
+ ```js
169
+ payloadMutators: {
170
+ post: (data) => {
171
+ const safeData = ItemSchema.parse(data);
172
+ return { json: safeData };
173
+ }
174
+ }
175
+ ```
176
+
177
+ ### 3. Performance Considerations
178
+ - Each operation creates isolated mutation instances
179
+ - Avoid excessive re-renders by memoizing config objects
180
+ - For bulk operations, prefer direct ky usage
181
+
182
+ ---
183
+
184
+ ## When Not to Use
185
+ - **Simple GET requests**: Use `useQuery` directly
186
+ - **Non-Okapi APIs**: Lacks built-in auth headers
187
+ - However this can be achieved by overriding the fetch method with `promiseReturns`
@@ -0,0 +1 @@
1
+ export { default } from './useMutateGeneric';
@@ -0,0 +1,85 @@
1
+ # useMutateRefdataCategory
2
+
3
+ ## Reference Data Mutation Hook
4
+ A specialized abstraction of [`useMutateGeneric`](./useMutateGeneric.md) optimized for managing reference data categories with automatic cache invalidation. Part of the reference data management ecosystem.
5
+
6
+ ```mermaid
7
+ graph TD
8
+ A[CRUD Operation] --> B[Invalidate Refdata Cache]
9
+ B --> C[Trigger UI Refresh]
10
+ ```
11
+
12
+ ## Key Features
13
+ - **Automatic Cache Busting:** Invalidates reference data cache after mutations
14
+ - **Payload Safeguards:** Enforces empty `values` array for new categories
15
+ - **Query Key Standardization:** Pre-configured cache key structure
16
+
17
+ ## Usage Pattern
18
+ ```jsx
19
+ const RefdataCategoryManager = () => {
20
+ const { post } = useMutateRefdataCategory({
21
+ endpoint: 'license/refdata',
22
+ afterQueryCalls: {
23
+ post: (newCategory) => showToast(`Created ${newCategory.desc}`)
24
+ }
25
+ });
26
+
27
+ const handleCreate = (categoryData) => post({
28
+ desc: 'Publication Types',
29
+ id: 'publication_type'
30
+ });
31
+
32
+ return <Button onClick={handleCreate}>Create Category</Button>;
33
+ };
34
+ ```
35
+
36
+ ## Core Enhancements
37
+
38
+ ### 1. Cache Invalidation Pipeline
39
+ Automatic refresh flow after mutations:
40
+ 1. Execute mutation (create/update/delete)
41
+ 2. Invalidate reference data cache
42
+ 3. Trigger dependent queries refresh
43
+ 4. Execute custom `afterQuery` handlers
44
+
45
+ ### 2. Payload Enforcement
46
+ New categories receive empty values array:
47
+ ```js
48
+ // Input payload
49
+ { desc: 'Media Formats', id: 'media_format' }
50
+
51
+ // Actual POST body
52
+ {
53
+ desc: 'Media Formats',
54
+ id: 'media_format',
55
+ values: []
56
+ }
57
+ ```
58
+
59
+ ## Configuration
60
+
61
+ ### Inherited Props
62
+ Supports all [`useMutateGeneric` props](../useMutateGeneric/README.md#configuration-options) except:
63
+
64
+ | Prop | Override | Reason |
65
+ |------------------------|----------|--------------------------|
66
+ | `payloadMutators.post` | Yes | Values array enforcement |
67
+ | `queryKey` | Yes | Standardized refdata key |
68
+
69
+ ### Special Handling
70
+ ```js
71
+ // To bypass empty values array (advanced)
72
+ useMutateRefdataCategory({
73
+ payloadMutators: {
74
+ post: (data) => ({ json: data }) // Not recommended
75
+ }
76
+ });
77
+ ```
78
+
79
+ ## Error Handling
80
+ Maintains base hook's [error handling characteristics](./useMutateGeneric.md#error-handling-philosophy) with added complexity:
81
+ - Cache invalidation occurs **before** custom `afterQuery` handlers
82
+ - Failed invalidations log to console but don't block operations
83
+
84
+ ## Integration Requirements
85
+ Uses [`useInvalidateRefdata`](../useInvalidateRefdata/README.md) to handle refdata query cache invalidation automatically.
@@ -0,0 +1 @@
1
+ export { default } from './useMutateRefdataCategory';
@@ -1,7 +1,7 @@
1
1
  import noop from 'lodash/noop';
2
2
 
3
- import useInvalidateRefdata from './useInvalidateRefdata';
4
- import useMutateGeneric from './useMutateGeneric';
3
+ import useInvalidateRefdata from '../useInvalidateRefdata';
4
+ import useMutateGeneric from '../useMutateGeneric';
5
5
 
6
6
  const useMutateRefdataCategory = ({
7
7
  afterQueryCalls: {
@@ -0,0 +1,154 @@
1
+ # useMutateRefdataValue
2
+
3
+ ## Refdata Value Mutation Hook
4
+ A specialized abstraction of [`useMutateGeneric`](./useMutateGeneric.md) for atomic reference data value operations. Handles value lifecycle management within refdata categories with integrated cache invalidation.
5
+
6
+ ```mermaid
7
+ graph TD
8
+ A[Value Mutation] --> B[Cache Invalidation]
9
+ B --> C[Consistent UI State]
10
+ ```
11
+
12
+ ## Key Features
13
+ - **Value Lifecycle Management:** Unified create/update/delete operations
14
+ - **Atomic Operations:** Batch-safe value modifications
15
+ - **API handling:** Uses `_delete: true` pattern instead of usual `delete` http calls.
16
+ - **Query Key Standardization:** Automatic cache key generation
17
+
18
+ ## Basic Usage
19
+ ```jsx
20
+ const RefdataValueEditor = ({ categoryId }) => {
21
+ const { post: createValue } = useMutateRefdataValue({
22
+ endpoint: 'license/refdata',
23
+ id: categoryId
24
+ });
25
+
26
+ const handleCreate = (valueData) => createValue({
27
+ value: 'eBook',
28
+ label: 'Electronic Book'
29
+ });
30
+
31
+ return <ValueForm onSubmit={handleCreate} />;
32
+ };
33
+ ```
34
+
35
+ ## Core Enhancements
36
+
37
+ ### 1. Value Operation Patterns
38
+ | Operation | HTTP Method | Payload Structure |
39
+ |-----------|-------------|--------------------|
40
+ | Create | PUT | `{values: [newValue]}` |
41
+ | Update | PUT | `{values: [updatedValue]}` |
42
+ | Delete | PUT | `{values: [{id: valueId, _delete: true}]}` |
43
+
44
+ ### 2. Cache Coherence
45
+ Automatic refresh flow:
46
+ 1. Execute value mutation
47
+ 2. Invalidate refdata cache
48
+ 3. Trigger dependent queries
49
+ 4. Execute custom post-hooks
50
+
51
+ ## Configuration
52
+
53
+ ### Essential Props
54
+ | Prop | Type | Description |
55
+ |------|------|-------------|
56
+ | `endpoint` | string | Base refdata endpoint (e.g., `'oa/refdata'`) |
57
+ | `id` | string | Target refdata category ID |
58
+
59
+ ### Inherited Capabilities
60
+ Supports all [`useMutateGeneric` configurations](../useMutateGeneric/README.md#configuration-options) with:
61
+
62
+ | Aspect | Implementation |
63
+ |--------|----------------|
64
+ | Query Key | `['stripes-kint-components', 'useMutateRefdataValue', id]` |
65
+ | Endpoint Structure | Fixed `${endpoint}/${id}` |
66
+
67
+ ## Advanced Use Cases
68
+
69
+ ### Value Updates
70
+ ```jsx
71
+ const { put: updateValue } = useMutateRefdataValue({
72
+ endpoint: 'inventory/types',
73
+ id: 'MEDIA_FORMAT'
74
+ });
75
+
76
+ // Update existing value
77
+ updateValue({
78
+ id: 'DVD',
79
+ label: 'Digital Video Disc',
80
+ value: 'dvd_media'
81
+ });
82
+ ```
83
+
84
+ ### Conditional Operations
85
+ ```jsx
86
+ useMutateRefdataValue({
87
+ queryParams: {
88
+ put: {
89
+ enabled: !!activeCategory
90
+ }
91
+ }
92
+ });
93
+ ```
94
+
95
+ ### Error Recovery
96
+ ```jsx
97
+ useMutateRefdataValue({
98
+ catchQueryCalls: {
99
+ put: (error) => {
100
+ recovery.saveState();
101
+ throw error;
102
+ }
103
+ }
104
+ });
105
+ ```
106
+
107
+ ## Operation Patterns
108
+
109
+ ### Value Creation
110
+ ```js
111
+ createValue({
112
+ value: 'streaming',
113
+ label: 'Streaming Service'
114
+ });
115
+ ```
116
+
117
+ ### Value Deletion
118
+ ```js
119
+ deleteValue(refdataId); // Removes value from the refdata category via _delete pattern
120
+ ```
121
+
122
+ ## Critical Implementation Notes
123
+
124
+ 1. **Idempotent Design**
125
+ - All operations use PUT for atomic updates
126
+ - Multiple changes require sequential calls
127
+
128
+ 2. **Payload Requirements**
129
+ ```js
130
+ // Update requires existing ID
131
+ {
132
+ id: 'existing_value_id',
133
+ label: 'Updated Label'
134
+ }
135
+ ```
136
+
137
+ 3. **Cache Key Dependencies**
138
+ - Keys include category ID for isolation
139
+ - Multiple category instances require separate hooks
140
+
141
+ 4. **Error Handling**
142
+ - Silent failure by default
143
+ - Override with `catchQueryCalls`:
144
+ ```js
145
+ useMutateRefdataValue({
146
+ catchQueryCalls: {
147
+ put: (error) => showErrorToast(error.message)
148
+ }
149
+ });
150
+ ```
151
+
152
+ ## Integration Requirements
153
+ - Uses [`useInvalidateRefdata`](../useInvalidateRefdata/README.md) to handle refdata query cache invalidation automatically.
154
+ - Must be used within React Query provider
@@ -0,0 +1 @@
1
+ export { default } from './useMutateRefdataValue';
@@ -1,7 +1,7 @@
1
1
  import noop from 'lodash/noop';
2
2
 
3
- import useInvalidateRefdata from './useInvalidateRefdata';
4
- import useMutateGeneric from './useMutateGeneric';
3
+ import useInvalidateRefdata from '../useInvalidateRefdata';
4
+ import useMutateGeneric from '../useMutateGeneric';
5
5
 
6
6
  const useMutateRefdataValue = ({
7
7
  afterQueryCalls: {