@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.
- package/CHANGELOG.md +20 -0
- package/LICENSE +1 -1
- package/es/index.js +32 -12
- package/es/lib/EditableSettingsList/EditableSettingsList.js +4 -3
- package/es/lib/EditableSettingsList/EditableSettingsListFieldArray/EditableSettingsListFieldArray.js +110 -0
- package/es/lib/EditableSettingsList/{EditableSettingsListFieldArray.test.js → EditableSettingsListFieldArray/EditableSettingsListFieldArray.test.js} +3 -4
- package/es/lib/EditableSettingsList/EditableSettingsListFieldArray/index.js +13 -0
- package/es/lib/EditableSettingsList/SettingField/{EditSettingValue.js → EditSettingValue/EditSettingValue.js} +2 -2
- package/es/lib/EditableSettingsList/SettingField/{EditSettingValue.test.js → EditSettingValue/EditSettingValue.test.js} +2 -3
- package/es/lib/EditableSettingsList/SettingField/EditSettingValue/index.js +13 -0
- package/es/lib/EditableSettingsList/SettingField/{RenderSettingValue.js → RenderSettingValue/RenderSettingValue.js} +1 -1
- package/es/lib/EditableSettingsList/SettingField/{RenderSettingValue.test.js → RenderSettingValue/RenderSettingValue.test.js} +2 -2
- package/es/lib/EditableSettingsList/SettingField/RenderSettingValue/index.js +13 -0
- package/es/lib/EditableSettingsList/SettingField/SettingField.js +5 -5
- package/es/lib/EditableSettingsList/SettingField/SettingField.test.js +54 -44
- package/es/lib/EditableSettingsList/index.js +12 -0
- package/es/lib/SASQLookupComponent/SASQLookupComponent.js +5 -1
- package/es/lib/SearchKeyControl/SearchKeyControl.js +95 -0
- package/es/lib/SearchKeyControl/SearchKeyControl.test.js +177 -0
- package/es/lib/SearchKeyControl/index.js +13 -0
- package/es/lib/SettingPage/SettingPage.js +3 -1
- package/es/lib/SettingPage/{SettingPagePane.js → SettingPagePane/SettingPagePane.js} +2 -2
- package/es/lib/SettingPage/SettingPagePane/index.js +13 -0
- package/es/lib/hooks/__mocks__/index.js +2 -2
- package/es/lib/hooks/index.js +33 -21
- package/es/lib/hooks/intlHooks/index.js +27 -0
- package/es/lib/hooks/intlHooks/useIntlKey/index.js +13 -0
- package/es/lib/hooks/{useIntlKey.js → intlHooks/useIntlKey/useIntlKey.js} +1 -1
- package/es/lib/hooks/intlHooks/useIntlKeyStore/index.js +13 -0
- package/es/lib/hooks/intlHooks/useKintIntl/index.js +13 -0
- package/es/lib/hooks/{useKintIntl.js → intlHooks/useKintIntl/useKintIntl.js} +1 -1
- package/es/lib/hooks/useInvalidateRefdata/index.js +13 -0
- package/es/lib/hooks/{useInvalidateRefdata.js → useInvalidateRefdata/useInvalidateRefdata.js} +1 -1
- package/es/lib/hooks/useMutateCustomProperties/index.js +13 -0
- package/es/lib/hooks/{useMutateCustomProperties.js → useMutateCustomProperties/useMutateCustomProperties.js} +1 -1
- package/es/lib/hooks/useMutateGeneric/index.js +13 -0
- package/es/lib/hooks/useMutateRefdataCategory/index.js +13 -0
- package/es/lib/hooks/{useMutateRefdataCategory.js → useMutateRefdataCategory/useMutateRefdataCategory.js} +2 -2
- package/es/lib/hooks/useMutateRefdataValue/index.js +13 -0
- package/es/lib/hooks/{useMutateRefdataValue.js → useMutateRefdataValue/useMutateRefdataValue.js} +2 -2
- package/es/lib/settingsHooks/useAppSettings/index.js +13 -0
- package/es/lib/settingsHooks/{useAppSettings.js → useAppSettings/useAppSettings.js} +1 -1
- package/es/lib/settingsHooks/useSettingSection/index.js +13 -0
- package/es/lib/settingsHooks/{useSettingSection.js → useSettingSection/useSettingSection.js} +1 -1
- package/es/lib/settingsHooks/useSettings/index.js +13 -0
- package/es/lib/settingsHooks/{useSettings.js → useSettings/useSettings.js} +10 -9
- package/es/lib/utils/refdataQueryKey/index.js +13 -0
- package/package.json +1 -1
- package/src/index.js +8 -3
- package/src/lib/ActionList/README.md +18 -18
- package/src/lib/EditableSettingsList/EditableSettingsList.js +3 -2
- package/src/lib/EditableSettingsList/EditableSettingsListFieldArray/EditableSettingsListFieldArray.js +118 -0
- package/src/lib/EditableSettingsList/{EditableSettingsListFieldArray.test.js → EditableSettingsListFieldArray/EditableSettingsListFieldArray.test.js} +3 -5
- package/src/lib/EditableSettingsList/EditableSettingsListFieldArray/README.md +68 -0
- package/src/lib/EditableSettingsList/EditableSettingsListFieldArray/index.js +1 -0
- package/src/lib/EditableSettingsList/README.md +74 -0
- package/src/lib/EditableSettingsList/SettingField/{EditSettingValue.js → EditSettingValue/EditSettingValue.js} +2 -2
- package/src/lib/EditableSettingsList/SettingField/{EditSettingValue.test.js → EditSettingValue/EditSettingValue.test.js} +2 -5
- package/src/lib/EditableSettingsList/SettingField/EditSettingValue/README.md +63 -0
- package/src/lib/EditableSettingsList/SettingField/EditSettingValue/index.js +1 -0
- package/src/lib/EditableSettingsList/SettingField/README.md +61 -0
- package/src/lib/EditableSettingsList/SettingField/{RenderSettingValue.js → RenderSettingValue/RenderSettingValue.js} +1 -1
- package/src/lib/EditableSettingsList/SettingField/{RenderSettingValue.test.js → RenderSettingValue/RenderSettingValue.test.js} +2 -2
- package/src/lib/EditableSettingsList/SettingField/RenderSettingValue/index.js +1 -0
- package/src/lib/EditableSettingsList/SettingField/SettingField.js +5 -3
- package/src/lib/EditableSettingsList/SettingField/SettingField.test.js +65 -44
- package/src/lib/EditableSettingsList/index.js +1 -1
- package/src/lib/NumberField/README.md +134 -0
- package/src/lib/SASQLookupComponent/README.md +172 -0
- package/src/lib/SASQLookupComponent/SASQLookupComponent.js +6 -1
- package/src/lib/SASQLookupComponent/TableBody/README.md +113 -0
- package/src/lib/SASQRoute/README.md +49 -18
- package/src/lib/SASQViewComponent/README.md +132 -0
- package/src/lib/SearchKeyControl/README.md +70 -0
- package/src/lib/SearchKeyControl/SearchKeyControl.js +98 -0
- package/src/lib/SearchKeyControl/SearchKeyControl.test.js +165 -0
- package/src/lib/SearchKeyControl/index.js +1 -0
- package/src/lib/SettingPage/README.md +66 -0
- package/src/lib/SettingPage/SettingPage.js +3 -1
- package/src/lib/SettingPage/SettingPagePane/README.md +31 -0
- package/src/lib/SettingPage/{SettingPagePane.js → SettingPagePane/SettingPagePane.js} +2 -2
- package/src/lib/SettingPage/SettingPagePane/index.js +1 -0
- package/src/lib/hooks/README.md +26 -121
- package/src/lib/hooks/__mocks__/index.js +2 -2
- package/src/lib/hooks/index.js +2 -3
- package/src/lib/hooks/intlHooks/README.md +31 -0
- package/src/lib/hooks/intlHooks/index.js +3 -0
- package/src/lib/hooks/intlHooks/useIntlKey/README.md +23 -0
- package/src/lib/hooks/intlHooks/useIntlKey/index.js +1 -0
- package/src/lib/hooks/{useIntlKey.js → intlHooks/useIntlKey/useIntlKey.js} +1 -1
- package/src/lib/hooks/intlHooks/useIntlKeyStore/README.md +32 -0
- package/src/lib/hooks/intlHooks/useIntlKeyStore/index.js +1 -0
- package/src/lib/hooks/intlHooks/useKintIntl/README.md +42 -0
- package/src/lib/hooks/intlHooks/useKintIntl/index.js +1 -0
- package/src/lib/hooks/{useKintIntl.js → intlHooks/useKintIntl/useKintIntl.js} +1 -1
- package/src/lib/hooks/useInvalidateRefdata/README.md +72 -0
- package/src/lib/hooks/useInvalidateRefdata/index.js +1 -0
- package/src/lib/hooks/{useInvalidateRefdata.js → useInvalidateRefdata/useInvalidateRefdata.js} +1 -1
- package/src/lib/hooks/useMutateCustomProperties/README.md +88 -0
- package/src/lib/hooks/useMutateCustomProperties/index.js +1 -0
- package/src/lib/hooks/{useMutateCustomProperties.js → useMutateCustomProperties/useMutateCustomProperties.js} +1 -1
- package/src/lib/hooks/useMutateGeneric/README.md +187 -0
- package/src/lib/hooks/useMutateGeneric/index.js +1 -0
- package/src/lib/hooks/useMutateRefdataCategory/README.md +85 -0
- package/src/lib/hooks/useMutateRefdataCategory/index.js +1 -0
- package/src/lib/hooks/{useMutateRefdataCategory.js → useMutateRefdataCategory/useMutateRefdataCategory.js} +2 -2
- package/src/lib/hooks/useMutateRefdataValue/README.md +154 -0
- package/src/lib/hooks/useMutateRefdataValue/index.js +1 -0
- package/src/lib/hooks/{useMutateRefdataValue.js → useMutateRefdataValue/useMutateRefdataValue.js} +2 -2
- package/src/lib/settingsHooks/useAppSettings/README.md +24 -0
- package/src/lib/settingsHooks/useAppSettings/index.js +1 -0
- package/src/lib/settingsHooks/{useAppSettings.js → useAppSettings/useAppSettings.js} +1 -1
- package/src/lib/settingsHooks/useSettingSection/README.md +54 -0
- package/src/lib/settingsHooks/useSettingSection/index.js +1 -0
- package/src/lib/settingsHooks/{useSettingSection.js → useSettingSection/useSettingSection.js} +1 -1
- package/src/lib/settingsHooks/useSettings/README.md +84 -0
- package/src/lib/settingsHooks/useSettings/index.js +1 -0
- package/src/lib/settingsHooks/{useSettings.js → useSettings/useSettings.js} +10 -7
- package/src/lib/utils/refdataQueryKey/README.md +38 -0
- package/src/lib/utils/refdataQueryKey/index.js +1 -0
- package/styles/SearchKeyControl.css +14 -0
- package/es/lib/EditableSettingsList/EditableSettingsListFieldArray.js +0 -57
- package/src/lib/EditableSettingsList/EditableSettingsListFieldArray.js +0 -58
- /package/es/lib/hooks/{useIntlKeyStore.js → intlHooks/useIntlKeyStore/useIntlKeyStore.js} +0 -0
- /package/es/lib/hooks/{useMutateGeneric.js → useMutateGeneric/useMutateGeneric.js} +0 -0
- /package/es/lib/utils/{refdataQueryKey.js → refdataQueryKey/refdataQueryKey.js} +0 -0
- /package/src/lib/hooks/{useIntlKeyStore.js → intlHooks/useIntlKeyStore/useIntlKeyStore.js} +0 -0
- /package/src/lib/hooks/{useMutateGeneric.js → useMutateGeneric/useMutateGeneric.js} +0 -0
- /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';
|
|
@@ -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';
|
|
@@ -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';
|
|
@@ -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 '
|
|
4
|
-
import useMutateGeneric from '
|
|
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';
|
package/src/lib/hooks/{useMutateRefdataValue.js → useMutateRefdataValue/useMutateRefdataValue.js}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import noop from 'lodash/noop';
|
|
2
2
|
|
|
3
|
-
import useInvalidateRefdata from '
|
|
4
|
-
import useMutateGeneric from '
|
|
3
|
+
import useInvalidateRefdata from '../useInvalidateRefdata';
|
|
4
|
+
import useMutateGeneric from '../useMutateGeneric';
|
|
5
5
|
|
|
6
6
|
const useMutateRefdataValue = ({
|
|
7
7
|
afterQueryCalls: {
|