@arrai-innovations/reactive-helpers 11.4.2 → 13.0.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/.husky/pre-commit +0 -1
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.prettierignore +1 -0
- package/README.md +11 -10
- package/config/listCrud.js +32 -1
- package/config/objectCrud.js +47 -1
- package/docs/README.md +43 -0
- package/docs/config/listCrud.md +97 -0
- package/docs/config/objectCrud.md +123 -0
- package/docs/use/cancellableIntent.md +163 -0
- package/docs/use/combineClasses.md +52 -0
- package/docs/use/list.md +285 -0
- package/docs/use/listCalculated.md +773 -0
- package/docs/use/listFilter.md +877 -0
- package/docs/use/listInstance.md +483 -0
- package/docs/use/listKeys.md +91 -0
- package/docs/use/listRelated.md +685 -0
- package/docs/use/listSearch.md +889 -0
- package/docs/use/listSort.md +1144 -0
- package/docs/use/listSubscription.md +379 -0
- package/docs/use/loadingError.md +21 -0
- package/docs/use/object.md +437 -0
- package/docs/use/objectCalculated.md +606 -0
- package/docs/use/objectInstance.md +486 -0
- package/docs/use/objectRelated.md +588 -0
- package/docs/use/objectSubscription.md +459 -0
- package/docs/use/paginatedListInstance.md +147 -0
- package/docs/use/search.md +311 -0
- package/docs/use/watchesRunning.md +80 -0
- package/docs/utils/assignReactiveObject.md +351 -0
- package/docs/utils/classes.md +100 -0
- package/docs/utils/compact.md +57 -0
- package/docs/utils/deleteKey.md +53 -0
- package/docs/utils/flattenPaths.md +45 -0
- package/docs/utils/getFakeId.md +34 -0
- package/docs/utils/keyDiff.md +101 -0
- package/docs/utils/loadingCombine.md +28 -0
- package/docs/utils/proxyRunning.md +33 -0
- package/docs/utils/relatedCalculatedHelpers.md +75 -0
- package/docs/utils/set.md +139 -0
- package/docs/utils/transformWalk.md +33 -0
- package/docs/utils/watches.md +441 -0
- package/eslint.config.js +125 -0
- package/index.js +34 -3
- package/lint-staged.config.js +5 -1
- package/makeTypeDoc.sh +25 -0
- package/package.json +27 -19
- package/tests/unit/config/listCrud.spec.js +5 -0
- package/tests/unit/config/objectCrud.spec.js +5 -0
- package/tests/unit/crudPromise.js +22 -3
- package/tests/unit/mockOnUnmounted.js +1 -1
- package/tests/unit/use/cancellableIntent.spec.js +2 -0
- package/tests/unit/use/listCalculated.spec.js +4 -3
- package/tests/unit/use/listFilter.spec.js +11 -7
- package/tests/unit/use/listInstance.spec.js +32 -14
- package/tests/unit/use/listRelated.spec.js +3 -2
- package/tests/unit/use/listSearch.spec.js +9 -7
- package/tests/unit/use/listSort.spec.js +29 -22
- package/tests/unit/use/listSubscription.spec.js +11 -5
- package/tests/unit/use/objectInstance.spec.js +15 -2
- package/tests/unit/use/objectSubscription.spec.js +31 -16
- package/tests/unit/use/search.spec.js +2 -2
- package/tests/unit/utils/assignReactiveObject.spec.js +21 -13
- package/tests/unit/utils/classes.spec.js +7 -6
- package/tests/unit/utils/watches.spec.js +4 -4
- package/tsconfig.json +19 -0
- package/typedoc-local-plugins/customize-output.js +13 -0
- package/typedoc.json +12 -0
- package/use/cancellableIntent.js +73 -2
- package/use/combineClasses.js +41 -31
- package/use/list.js +139 -5
- package/use/listCalculated.js +175 -10
- package/use/listFilter.js +175 -21
- package/use/listInstance.js +215 -94
- package/use/listRelated.js +260 -72
- package/use/listSearch.js +178 -57
- package/use/listSort.js +188 -21
- package/use/listSubscription.js +211 -63
- package/use/loadingError.js +43 -0
- package/use/object.js +187 -23
- package/use/objectCalculated.js +168 -16
- package/use/objectInstance.js +183 -102
- package/use/objectRelated.js +276 -84
- package/use/objectSubscription.js +169 -17
- package/use/paginatedListInstance.js +30 -1
- package/use/search.js +39 -23
- package/use/watchesRunning.js +41 -6
- package/utils/assignReactiveObject.js +139 -88
- package/utils/classes.js +57 -48
- package/utils/compact.js +28 -2
- package/utils/deleteKey.js +14 -1
- package/utils/flattenPaths.js +19 -9
- package/utils/getFakeId.js +11 -1
- package/utils/keyDiff.js +26 -35
- package/utils/loadingCombine.js +7 -4
- package/utils/proxyRunning.js +16 -8
- package/utils/relatedCalculatedHelpers.js +17 -0
- package/utils/set.js +66 -0
- package/utils/transformWalk.js +7 -6
- package/utils/watches.js +205 -71
- package/.eslintignore +0 -2
- package/.eslintrc.cjs +0 -25
- package/.jsdoc2md.json +0 -4
- package/config/index.js +0 -2
- package/docs.md +0 -1002
- package/jsdoc-to-markdown.sh +0 -16
- package/tests/unit/.eslintrc.cjs +0 -11
- package/tests/unit/config/index.spec.js +0 -18
- package/tests/unit/use/index.spec.js +0 -18
- package/tests/unit/utils/index.spec.js +0 -18
- package/use/index.js +0 -19
- package/utils/debugMessage.js +0 -209
- package/utils/debugWatch.js +0 -29
- package/utils/index.js +0 -16
- package/utils/lifecycleDebug.js +0 -126
package/use/listRelated.js
CHANGED
|
@@ -20,6 +20,83 @@ import isEmpty from "lodash-es/isEmpty.js";
|
|
|
20
20
|
import isUndefined from "lodash-es/isUndefined.js";
|
|
21
21
|
import { computed, effectScope, onScopeDispose, reactive, ref, toRef, unref, watch } from "vue";
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Vue Composition API composable function for managing relationships among objects in a list.
|
|
25
|
+
* It enables linking objects based on predefined rules and dynamically adjusts as the underlying data changes.
|
|
26
|
+
*
|
|
27
|
+
* @module use/listRelated.js
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
// todo: pkKey is misnamed, it should be fkKey... this will be a major breaking change
|
|
31
|
+
/**
|
|
32
|
+
* The rule for defining relationships for objects in a list.
|
|
33
|
+
*
|
|
34
|
+
* @typedef {object} ListRelatedRule
|
|
35
|
+
* @property {string} pkKey - Specifies the foreign key used to link objects across lists. Planned to be renamed to
|
|
36
|
+
* 'fkKey' to better reflect its usage.
|
|
37
|
+
* @property {string[]} order - Specifies the order in which related objects should be sorted, if applicable.
|
|
38
|
+
* @property {import('./listInstance.js').ObjectsById} objects - The objects that can be related based on the foreign key.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The rules for defining relationships among objects in a list.
|
|
43
|
+
*
|
|
44
|
+
* @typedef {import('vue').UnwrapNestedRefs<{
|
|
45
|
+
* [rule: string]: ListRelatedRule,
|
|
46
|
+
* }>} ListRelatedRules
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Represents the internal state used by the list related composition function. It manages and computes the relationships
|
|
51
|
+
* between objects based on specified rules, providing real-time updates to related objects as the parent state changes.
|
|
52
|
+
*
|
|
53
|
+
* @typedef {object} ListRelatedRawState
|
|
54
|
+
* @property {{
|
|
55
|
+
* [id: string]: {
|
|
56
|
+
* [rule: string]: import('vue').ComputedRef<any>,
|
|
57
|
+
* },
|
|
58
|
+
* }} relatedObjects - Stores computed references to related objects, allowing for dynamic access based on object ID and specific rules.
|
|
59
|
+
* @property {ListRelatedRules} relatedObjectsRules - Defines the rules for establishing relationships, such as foreign key links and sorting orders.
|
|
60
|
+
* @property {{
|
|
61
|
+
* [id: string]: {
|
|
62
|
+
* [rule: string]: import('vue').ComputedRef<[object, string]>,
|
|
63
|
+
* },
|
|
64
|
+
* }} objAndKeyForIdAndRule - Maps each object ID and rule to a tuple consisting of the related object and its respective key, facilitating direct data manipulation.
|
|
65
|
+
* @property {{
|
|
66
|
+
* [id: string]: {
|
|
67
|
+
* [rule: string]: import('vue').ComputedRef<any>,
|
|
68
|
+
* },
|
|
69
|
+
* }} fkForIdAndRule - Maintains computed references to the foreign keys for each object ID and rule, crucial for navigating complex data relationships.
|
|
70
|
+
* @property {boolean} relatedObjectsParentStateObjectsWatchRunning - Flags whether the watch on parent state objects is currently active, ensuring updates trigger as needed.
|
|
71
|
+
* @property {boolean} relatedObjectsWatchRunning - Indicates if watches on the related objects themselves are active, managing updates efficiently.
|
|
72
|
+
* @property {boolean} relatedRunning - Signals whether any computations related to object relationships are currently in progress.
|
|
73
|
+
* @property {import('vue').Ref<boolean>} running - General flag that indicates if the list-related logic is processing, used to manage UI feedback or prevent concurrent operations.
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The raw state properties for a parent of a list related property.
|
|
78
|
+
*
|
|
79
|
+
* @typedef {(
|
|
80
|
+
* import('./listInstance.js').ListInstanceRawState &
|
|
81
|
+
* Partial<import('./listSubscription.js').ListSubscriptionRawState>
|
|
82
|
+
* )} ListRelatedParentRawState
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The type for a parentState object.
|
|
87
|
+
*
|
|
88
|
+
* @typedef {import('vue').UnwrapNestedRefs<ListRelatedParentRawState>} ListRelatedParentState
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The state for a list related property.
|
|
93
|
+
*
|
|
94
|
+
* @typedef {import('vue').UnwrapNestedRefs<
|
|
95
|
+
* ListRelatedParentRawState &
|
|
96
|
+
* ListRelatedRawState
|
|
97
|
+
* >} ListRelatedState
|
|
98
|
+
*/
|
|
99
|
+
|
|
23
100
|
const parentStateKeys = difference(
|
|
24
101
|
new Set([
|
|
25
102
|
...listInstanceStateKeys,
|
|
@@ -32,39 +109,140 @@ const parentStateKeys = difference(
|
|
|
32
109
|
new Set(listRelatedStateKeys)
|
|
33
110
|
);
|
|
34
111
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
112
|
+
/**
|
|
113
|
+
* The options for the list related composition function.
|
|
114
|
+
*
|
|
115
|
+
* @typedef {object} ListRelatedOptions
|
|
116
|
+
* @property {ListRelatedParentState} parentState - The parent state object.
|
|
117
|
+
* @property {import('vue').Ref<ListRelatedRules>} relatedObjectsRules - The rules for the related objects.
|
|
118
|
+
*/
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The properties for the list related composition function.
|
|
122
|
+
*
|
|
123
|
+
* @typedef {object} ListRelatedProperties
|
|
124
|
+
* @property {ListRelatedState} state - The state for the list related property.
|
|
125
|
+
* @property {ListRelatedParentState} parentState - The parent state object.
|
|
126
|
+
* @property {import('./watchesRunning.js').WatchesRunning} watchesRunning - The watches running instance.
|
|
127
|
+
* @property {import('vue').EffectScope} effectScope - The effect scope for the list related property.
|
|
128
|
+
*/
|
|
129
|
+
|
|
130
|
+
// if we provided functions, we would add a typedef and mix them into ListRelated
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* An instance of `useListRelated`.
|
|
134
|
+
*
|
|
135
|
+
* @typedef {ListRelatedProperties} ListRelated
|
|
136
|
+
*/
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Creates and manages multiple instances of list-related properties, linking each to corresponding parent instances
|
|
140
|
+
* based on provided configuration.
|
|
141
|
+
*
|
|
142
|
+
* @param {{
|
|
143
|
+
* [key: string]: ListRelatedOptions
|
|
144
|
+
* }} listRelatedArgs - The options for the list related properties.
|
|
145
|
+
* @returns {{[key: string]: ListRelated}} - The instances of the list related properties.
|
|
146
|
+
*/
|
|
147
|
+
export function useListRelateds(listRelatedArgs) {
|
|
148
|
+
/** @type {{[key: string]: ListRelated}} */
|
|
149
|
+
const relateds = {};
|
|
150
|
+
for (const [key, value] of Object.entries(listRelatedArgs)) {
|
|
151
|
+
relateds[key] = useListRelated(value);
|
|
41
152
|
}
|
|
153
|
+
return relateds;
|
|
42
154
|
}
|
|
43
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Initializes and returns an instance of a related objects manager. This function sets up reactive states
|
|
158
|
+
* and computations that dynamically adjust as the parent list's state changes. It uses defined rules
|
|
159
|
+
* for object relationships to compute and update related objects in real-time, ensuring that changes in the parent
|
|
160
|
+
* state are reflected in the relationships defined by the rules.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```vue
|
|
164
|
+
* <script setup>
|
|
165
|
+
* import { useListInstance, useListRelated } from "@arrai-innovations/reactive-helpers";
|
|
166
|
+
* import { reactive, toRef } from "vue";
|
|
167
|
+
*
|
|
168
|
+
* const props = defineProps({
|
|
169
|
+
* someListFilter: {
|
|
170
|
+
* type: String,
|
|
171
|
+
* default: "",
|
|
172
|
+
* description: "The filter to apply to the list.",
|
|
173
|
+
* },
|
|
174
|
+
* objects: {
|
|
175
|
+
* type: Object,
|
|
176
|
+
* default: () => ({}),
|
|
177
|
+
* description: "The objects to relate to.",
|
|
178
|
+
* },
|
|
179
|
+
* order: {
|
|
180
|
+
* type: Array,
|
|
181
|
+
* default: () => [],
|
|
182
|
+
* description: "The order of the list.",
|
|
183
|
+
* },
|
|
184
|
+
* });
|
|
185
|
+
*
|
|
186
|
+
* const listInstanceProps = reactive({
|
|
187
|
+
* crudArgs: {
|
|
188
|
+
* // whatever arguments are required for your configured list crud function to get the right endpoint
|
|
189
|
+
* },
|
|
190
|
+
* listArgs: {
|
|
191
|
+
* // whatever arguments are required for your configured list function to get the right list
|
|
192
|
+
* someListFilter: toRef(props, "someListFilter"),
|
|
193
|
+
* },
|
|
194
|
+
* retrieveArgs: {
|
|
195
|
+
* // whatever arguments are required for your configured list function to get items back looking as expected
|
|
196
|
+
* },
|
|
197
|
+
* intendToList: false,
|
|
198
|
+
* });
|
|
199
|
+
* listInstanceProps.intendToList = computed(()=> !!props.someListFilter);
|
|
200
|
+
* const listInstance = useListInstance({ props: listInstanceProps });
|
|
201
|
+
* const listRelatedProps = reactive({
|
|
202
|
+
* parentState: listInstance.state, // reactive-to-reactive so no need for toRef
|
|
203
|
+
* relatedObjectsRules: {
|
|
204
|
+
* someRule: {
|
|
205
|
+
* // this can point to a key or an array of keys to relate to
|
|
206
|
+
* pkKey: "dot.separated.key.to.id.on.an.listInstance.object",
|
|
207
|
+
* objects: toRef(props, "objects"),
|
|
208
|
+
* order: toRef(props, "order"),
|
|
209
|
+
* },
|
|
210
|
+
* },
|
|
211
|
+
* });
|
|
212
|
+
* const listRelated = useListRelated(listRelatedProps);
|
|
213
|
+
* </script>
|
|
214
|
+
* <template>
|
|
215
|
+
* <ul>
|
|
216
|
+
* <!-- reactive list of objects, re-retrieving the list as someListFilter changes. -->
|
|
217
|
+
* <li v-for="obj in listInstance.state.objectsInOrder">
|
|
218
|
+
* {{ obj }}
|
|
219
|
+
* <div>
|
|
220
|
+
* <!-- the related object or objects based on the rule -->
|
|
221
|
+
* {{ listRelated.state.relatedObjects[obj.id].someRule }}
|
|
222
|
+
* </div>
|
|
223
|
+
* </li>
|
|
224
|
+
* </ul>
|
|
225
|
+
* </template>
|
|
226
|
+
* ```
|
|
227
|
+
*
|
|
228
|
+
* @param {ListRelatedOptions} options - The configuration options including the parent state and rules for related
|
|
229
|
+
* objects.
|
|
230
|
+
* @returns {ListRelated} - A reactive instance that manages related objects, providing real-time updates and
|
|
231
|
+
* maintaining the integrity of object relationships as per the specified rules.
|
|
232
|
+
*/
|
|
44
233
|
export function useListRelated({ parentState, relatedObjectsRules }) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// },
|
|
58
|
-
// },
|
|
59
|
-
},
|
|
60
|
-
fkForIdAndRule: {
|
|
61
|
-
// id: {
|
|
62
|
-
// rule: list of ids or single id,
|
|
63
|
-
// },
|
|
64
|
-
},
|
|
65
|
-
relatedObjectsParentStateObjectsWatchRunning: false,
|
|
66
|
-
relatedObjectsWatchRunning: false,
|
|
67
|
-
});
|
|
234
|
+
/** @type {ListRelatedState} */
|
|
235
|
+
// @ts-ignore - we'll add the missing properties later, taking refs from parentState
|
|
236
|
+
const state = reactive(
|
|
237
|
+
/** @type {ListRelatedRawState} */ {
|
|
238
|
+
relatedObjectsRules,
|
|
239
|
+
relatedObjects: {},
|
|
240
|
+
objAndKeyForIdAndRule: {},
|
|
241
|
+
fkForIdAndRule: {},
|
|
242
|
+
relatedObjectsParentStateObjectsWatchRunning: false,
|
|
243
|
+
relatedObjectsWatchRunning: false,
|
|
244
|
+
}
|
|
245
|
+
);
|
|
68
246
|
const relatedObjectsEffectScopes = {};
|
|
69
247
|
|
|
70
248
|
function parentStateObjectsWatch() {
|
|
@@ -89,6 +267,55 @@ export function useListRelated({ parentState, relatedObjectsRules }) {
|
|
|
89
267
|
state.relatedObjectsParentStateObjectsWatchRunning = false;
|
|
90
268
|
}
|
|
91
269
|
|
|
270
|
+
function applyRuleToObject(objectKey, ruleKey, originalObjectRef, relatedObjectRef) {
|
|
271
|
+
const rule = toRef(state.relatedObjectsRules, ruleKey);
|
|
272
|
+
state.objAndKeyForIdAndRule[objectKey][ruleKey] = computed(() => {
|
|
273
|
+
const rulePkKey = unref(rule).pkKey || ruleKey;
|
|
274
|
+
const object = unref(originalObjectRef);
|
|
275
|
+
const relatedObject = unref(relatedObjectRef);
|
|
276
|
+
return getObjectRelatedByKey(object, relatedObject, rulePkKey);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
state.fkForIdAndRule[objectKey][ruleKey] = computed(() =>
|
|
280
|
+
computeForeignKey(ruleKey, objectKey, rule, relatedObjectRef)
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
state.relatedObjects[objectKey][ruleKey] = computed(() => {
|
|
284
|
+
const value = unref(state.fkForIdAndRule[objectKey][ruleKey]);
|
|
285
|
+
const objects = unref(rule).objects;
|
|
286
|
+
if (isArray(value)) {
|
|
287
|
+
return value.map((e) => objects[e]).filter(identity);
|
|
288
|
+
}
|
|
289
|
+
return objects[value];
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function computeForeignKey(ruleKey, objectKey, rule, relatedObjectRef) {
|
|
294
|
+
const ruleOrder = unref(rule).order;
|
|
295
|
+
const relatedObject = unref(relatedObjectRef);
|
|
296
|
+
const [objectForGet, key] = unref(state.objAndKeyForIdAndRule[objectKey][ruleKey]);
|
|
297
|
+
let value = get(objectForGet, key);
|
|
298
|
+
if (objectForGet === relatedObject && isUndefined(value)) {
|
|
299
|
+
// Handle nested arrays
|
|
300
|
+
const firstLevelKey = key.split(".")[0];
|
|
301
|
+
const firstLevelItem = get(relatedObject, firstLevelKey);
|
|
302
|
+
if (isArray(firstLevelItem)) {
|
|
303
|
+
const restOfKey = key.slice(firstLevelKey.length + 1);
|
|
304
|
+
value = firstLevelItem.map((e) => get(e, restOfKey)).flat();
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (isArray(value) && ruleOrder?.length) {
|
|
308
|
+
value = value.filter(identity);
|
|
309
|
+
const indexById = Object.fromEntries(ruleOrder.map((e, i) => [e, i]));
|
|
310
|
+
value.sort((a, b) => {
|
|
311
|
+
const aIndex = indexById[a];
|
|
312
|
+
const bIndex = indexById[b];
|
|
313
|
+
return aIndex - bIndex;
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
return value;
|
|
317
|
+
}
|
|
318
|
+
|
|
92
319
|
function relatedObjectsWatch() {
|
|
93
320
|
const relatedObjectsRulesIsEmpty = !state.relatedObjectsRules || isEmpty(state.relatedObjectsRules);
|
|
94
321
|
for (const objectKey of Object.keys(state.relatedObjects)) {
|
|
@@ -100,7 +327,7 @@ export function useListRelated({ parentState, relatedObjectsRules }) {
|
|
|
100
327
|
));
|
|
101
328
|
} else {
|
|
102
329
|
if (isEmpty(state.relatedObjects[objectKey])) {
|
|
103
|
-
|
|
330
|
+
continue;
|
|
104
331
|
}
|
|
105
332
|
removedRuleKeys = new Set(Object.keys(state.relatedObjects[objectKey]));
|
|
106
333
|
addedRuleKeys = new Set();
|
|
@@ -121,48 +348,7 @@ export function useListRelated({ parentState, relatedObjectsRules }) {
|
|
|
121
348
|
const relatedObjectRef = toRef(state.relatedObjects, objectKey);
|
|
122
349
|
relatedObjectsEffectScopes[objectKey].run(() => {
|
|
123
350
|
for (const addedRuleKey of addedRuleKeys) {
|
|
124
|
-
|
|
125
|
-
state.objAndKeyForIdAndRule[objectKey][addedRuleKey] = computed(() => {
|
|
126
|
-
const rulePkKey = unref(rules).pkKey || addedRuleKey;
|
|
127
|
-
const object = unref(originalObjectRef);
|
|
128
|
-
const relatedObject = unref(relatedObjectRef);
|
|
129
|
-
return getObjectRelatedByKey(object, relatedObject, rulePkKey);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
state.fkForIdAndRule[objectKey][addedRuleKey] = computed(() => {
|
|
133
|
-
const ruleOrder = unref(rules).order;
|
|
134
|
-
const relatedObject = unref(relatedObjectRef);
|
|
135
|
-
const [objectForGet, key] = unref(state.objAndKeyForIdAndRule[objectKey][addedRuleKey]);
|
|
136
|
-
let value = get(objectForGet, key);
|
|
137
|
-
if (objectForGet === relatedObject && isUndefined(value)) {
|
|
138
|
-
// is the first level an array?
|
|
139
|
-
const firstLevelKey = key.split(".")[0];
|
|
140
|
-
const firstLevelItem = get(relatedObject, firstLevelKey);
|
|
141
|
-
if (isArray(firstLevelItem)) {
|
|
142
|
-
const restOfKey = key.slice(firstLevelKey.length + 1);
|
|
143
|
-
value = firstLevelItem.map((e) => get(e, restOfKey)).flat();
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
if (isArray(value) && ruleOrder?.length) {
|
|
147
|
-
value = value.filter(identity);
|
|
148
|
-
const indexById = Object.fromEntries(ruleOrder.map((e, i) => [e, i]));
|
|
149
|
-
value.sort((a, b) => {
|
|
150
|
-
const aIndex = indexById[a];
|
|
151
|
-
const bIndex = indexById[b];
|
|
152
|
-
return aIndex - bIndex;
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
return value;
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
state.relatedObjects[objectKey][addedRuleKey] = computed(() => {
|
|
159
|
-
const value = unref(state.fkForIdAndRule[objectKey][addedRuleKey]);
|
|
160
|
-
const objects = unref(rules).objects;
|
|
161
|
-
if (isArray(value)) {
|
|
162
|
-
return value.map((e) => objects[e]).filter(identity);
|
|
163
|
-
}
|
|
164
|
-
return objects[value];
|
|
165
|
-
});
|
|
351
|
+
applyRuleToObject(objectKey, addedRuleKey, originalObjectRef, relatedObjectRef);
|
|
166
352
|
}
|
|
167
353
|
});
|
|
168
354
|
}
|
|
@@ -198,9 +384,11 @@ export function useListRelated({ parentState, relatedObjectsRules }) {
|
|
|
198
384
|
],
|
|
199
385
|
});
|
|
200
386
|
|
|
387
|
+
// @ts-ignore - proxy the running property
|
|
201
388
|
state.relatedRunning = toRef(watchesRunning.state, "running");
|
|
202
389
|
const parentRunning = ref(undefined);
|
|
203
390
|
proxyRunning(parentState, "running", parentRunning);
|
|
391
|
+
// @ts-ignore - combine the running properties
|
|
204
392
|
state.running = computed(() => loadingCombine(watchesRunning.state.running, parentRunning.value));
|
|
205
393
|
|
|
206
394
|
onScopeDispose(() => {
|