@arrai-innovations/reactive-helpers 9.0.2 → 10.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/.idea/inspectionProfiles/Project_Default.xml +1 -0
- package/README.md +405 -65
- package/config/index.js +2 -0
- package/config/listCrud.js +37 -0
- package/config/objectCrud.js +45 -0
- package/docs.md +169 -14
- package/index.js +1 -0
- package/package.json +1 -1
- package/tests/unit/config/index.spec.js +18 -0
- package/tests/unit/config/listCrud.spec.js +107 -0
- package/tests/unit/config/objectCrud.spec.js +155 -0
- package/tests/unit/use/cancellableIntent.spec.js +1 -1
- package/tests/unit/use/listInstance.spec.js +5 -4
- package/tests/unit/use/listSubscription.spec.js +3 -5
- package/use/list.js +48 -14
- package/use/listCalculated.js +3 -0
- package/use/listFilter.js +40 -0
- package/use/listInstance.js +80 -27
- package/use/listRelated.js +5 -1
- package/use/listSort.js +34 -1
- package/use/listSubscription.js +56 -14
- package/use/object.js +26 -5
- package/use/objectCalculated.js +26 -39
- package/use/objectInstance.js +19 -35
- package/use/objectRelated.js +24 -34
- package/use/objectSubscription.js +25 -28
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<component name="InspectionProjectProfileManager">
|
|
2
2
|
<profile version="1.0">
|
|
3
3
|
<option name="myName" value="Project Default" />
|
|
4
|
+
<inspection_tool class="ES6PreferShortImport" enabled="true" level="WEAK WARNING" enabled_by_default="true" editorAttributes="INFO_ATTRIBUTES" />
|
|
4
5
|
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
5
6
|
</profile>
|
|
6
7
|
</component>
|
package/README.md
CHANGED
|
@@ -19,9 +19,11 @@ Vue.js 3 utility composition functions to help manipulate objects and lists.
|
|
|
19
19
|
- [Instance](#instance)
|
|
20
20
|
- [Subscription](#subscription)
|
|
21
21
|
- [Related](#related)
|
|
22
|
-
- [
|
|
22
|
+
- [Calculated](#calculated)
|
|
23
23
|
- [Filter](#filter)
|
|
24
|
+
- [Sort](#sort)
|
|
24
25
|
- [All](#all)
|
|
26
|
+
- [List](#list-1)
|
|
25
27
|
- [Object](#object)
|
|
26
28
|
- [Search](#search)
|
|
27
29
|
- [Utils](#utils)
|
|
@@ -67,12 +69,9 @@ The container for your list of objects, providing loading or error status.
|
|
|
67
69
|
|
|
68
70
|
```js
|
|
69
71
|
// do this in your main.js
|
|
70
|
-
import {
|
|
71
|
-
import { useListInstance } from "@arrai-innovations/reactive-helpers";
|
|
72
|
-
// then use in your component
|
|
73
|
-
import { reactive } from "vue";
|
|
72
|
+
import { setListCrud } from "@arrai-innovations/reactive-helpers";
|
|
74
73
|
|
|
75
|
-
|
|
74
|
+
setListCrud({
|
|
76
75
|
list: async function listCrudAdaptor({ crudArgs, retrieveArgs, listArgs, pageCallback }) {
|
|
77
76
|
// todo: your implemenation here.
|
|
78
77
|
const listOfObjects = await talkToServer(crudArgs, retrieveArgs, listArgs);
|
|
@@ -81,11 +80,15 @@ setListInstanceCrud({
|
|
|
81
80
|
pageCallback(nextListOfObjects);
|
|
82
81
|
},
|
|
83
82
|
});
|
|
83
|
+
```
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
85
|
+
```js
|
|
86
|
+
// then use in your component
|
|
87
|
+
import { useListInstance } from "@arrai-innovations/reactive-helpers";
|
|
88
|
+
import { reactive } from "vue";
|
|
89
|
+
|
|
90
|
+
const listProps = reactive({
|
|
91
|
+
// crudArgs are implementation specific to your crud functions.
|
|
89
92
|
crudArgs: {
|
|
90
93
|
stream: "contacts",
|
|
91
94
|
},
|
|
@@ -94,6 +97,9 @@ const contacts = useListInstance({
|
|
|
94
97
|
},
|
|
95
98
|
listArgs,
|
|
96
99
|
});
|
|
100
|
+
const contacts = useListInstance({
|
|
101
|
+
props: listProps,
|
|
102
|
+
});
|
|
97
103
|
|
|
98
104
|
await contacts.list();
|
|
99
105
|
console.log(contacts.loading);
|
|
@@ -110,7 +116,7 @@ await contacts.list();
|
|
|
110
116
|
console.log(contacts.objects);
|
|
111
117
|
// { contacts keyed by 'id' with message_count }
|
|
112
118
|
// change list or retrieve args indirectly
|
|
113
|
-
listArgs.has_organization = false;
|
|
119
|
+
listProps.listArgs.has_organization = false;
|
|
114
120
|
await contacts.list();
|
|
115
121
|
console.log(contacts.objects);
|
|
116
122
|
// { contacts keyed by 'id' with organizationless contacts }
|
|
@@ -122,11 +128,9 @@ Adds functionality to a list instance to receive updates from the server.
|
|
|
122
128
|
|
|
123
129
|
```js
|
|
124
130
|
// do this in your main.js
|
|
125
|
-
import {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
setListSubscriptionCrud({
|
|
131
|
+
import { setListCrud } from "@arrai-innovations/reactive-helpers";
|
|
132
|
+
setListCrud({
|
|
133
|
+
..., // in addition to the list crud adaptor above
|
|
130
134
|
subscribe: function subscribeCrudAdaptor({ crudArgs, retrieveArgs, listArgs, eventCallback }) {
|
|
131
135
|
// todo: your implemenation here.
|
|
132
136
|
const subscription = talkToServer(function (data, action) {
|
|
@@ -139,10 +143,19 @@ setListSubscriptionCrud({
|
|
|
139
143
|
return subscription;
|
|
140
144
|
},
|
|
141
145
|
});
|
|
146
|
+
```
|
|
142
147
|
|
|
143
|
-
|
|
148
|
+
```js
|
|
149
|
+
// then use in your component
|
|
150
|
+
import { useListInstance, useListSubscription } from "@arrai-innovations/reactive-helpers";
|
|
151
|
+
|
|
152
|
+
const listProps = reactive({
|
|
153
|
+
// crudArgs are implementation specific to your crud functions.
|
|
144
154
|
crudArgs: {
|
|
145
155
|
stream: "contacts",
|
|
156
|
+
includeCreateEvents: true,
|
|
157
|
+
subscribeAction: "subscribe_contacts",
|
|
158
|
+
unsubscribeAction: "unsubscribe_contacts",
|
|
146
159
|
},
|
|
147
160
|
retrieveArgs: {
|
|
148
161
|
fields: ["id", "has_name", "lexical_name", "organization", "phone"],
|
|
@@ -151,14 +164,11 @@ const contacts = useListInstance({
|
|
|
151
164
|
has_organization: true,
|
|
152
165
|
},
|
|
153
166
|
});
|
|
167
|
+
const contacts = useListInstance({
|
|
168
|
+
props: listProps,
|
|
169
|
+
});
|
|
154
170
|
const contactsSubscription = useListSubscription({
|
|
155
171
|
listInstance: contacts,
|
|
156
|
-
crudArgs: {
|
|
157
|
-
stream: "contacts",
|
|
158
|
-
includeCreateEvents: true,
|
|
159
|
-
subscribeAction: "subscribe_contacts",
|
|
160
|
-
unsubscribeAction: "unsubscribe_contacts",
|
|
161
|
-
},
|
|
162
172
|
});
|
|
163
173
|
|
|
164
174
|
// only get new or updated contacts, not existing.
|
|
@@ -173,6 +183,30 @@ contacts.retrieveArgs.fields.push("message_count");
|
|
|
173
183
|
delete contacts.listArgs.has_organization;
|
|
174
184
|
```
|
|
175
185
|
|
|
186
|
+
```js
|
|
187
|
+
// or you can have listSubscription create the listInstance for you.
|
|
188
|
+
import { useListSubscription } from "@arrai-innovations/reactive-helpers";
|
|
189
|
+
|
|
190
|
+
const listProps = reactive({
|
|
191
|
+
// crudArgs are implementation specific to your crud functions.
|
|
192
|
+
crudArgs: {
|
|
193
|
+
stream: "contacts",
|
|
194
|
+
includeCreateEvents: true,
|
|
195
|
+
subscribeAction: "subscribe_contacts",
|
|
196
|
+
unsubscribeAction: "unsubscribe_contacts",
|
|
197
|
+
},
|
|
198
|
+
retrieveArgs: {
|
|
199
|
+
fields: ["id", "has_name", "lexical_name", "organization", "phone"],
|
|
200
|
+
},
|
|
201
|
+
listArgs: {
|
|
202
|
+
has_organization: true,
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
const contactsSubscription = useListSubscription({
|
|
206
|
+
props: listProps,
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
176
210
|
#### Related
|
|
177
211
|
|
|
178
212
|
Lookup foreign keys between list instances via watch, for using dot notation in templates to cross object relations.
|
|
@@ -184,14 +218,22 @@ Lookup foreign keys between list instances via watch, for using dot notation in
|
|
|
184
218
|
import { useListInstance, useListRelated } from "@arrai-innovations/reactive-helpers";
|
|
185
219
|
import { nextTick } from "vue";
|
|
186
220
|
|
|
187
|
-
const organizations = useListInstance({
|
|
221
|
+
const organizations = useListInstance({
|
|
222
|
+
props: {
|
|
223
|
+
retrieveArgs: {
|
|
224
|
+
fields: ["id", "name"],
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
});
|
|
188
228
|
const contacts = useListInstance({
|
|
189
|
-
|
|
190
|
-
|
|
229
|
+
props: {
|
|
230
|
+
retrieveArgs: {
|
|
231
|
+
fields: ["id", "lexical_name", "organization"],
|
|
232
|
+
},
|
|
191
233
|
},
|
|
192
234
|
});
|
|
193
235
|
const contactsRelated = useListRelated({
|
|
194
|
-
|
|
236
|
+
parentState: contacts.state,
|
|
195
237
|
relatedObjectsRules: {
|
|
196
238
|
organization: {
|
|
197
239
|
// desired key on relatedObjects
|
|
@@ -199,7 +241,6 @@ const contactsRelated = useListRelated({
|
|
|
199
241
|
pkKey: "organization", // reference key on contact for org id.
|
|
200
242
|
},
|
|
201
243
|
},
|
|
202
|
-
relatedObjectsPropertyName: "myRelatedObjects",
|
|
203
244
|
});
|
|
204
245
|
await organizations.list();
|
|
205
246
|
await contacts.list();
|
|
@@ -217,15 +258,20 @@ console.log(contacts.objects);
|
|
|
217
258
|
"id": 15,
|
|
218
259
|
"lexical_name": "one, contact",
|
|
219
260
|
"organization": 42,
|
|
220
|
-
"relatedObjects": {
|
|
221
|
-
"organization": { "id": 42, "name": "org 42" }
|
|
222
|
-
}
|
|
223
261
|
}
|
|
224
262
|
}
|
|
225
263
|
*/
|
|
264
|
+
console.log(contacts.relatedObjects);
|
|
265
|
+
/*
|
|
266
|
+
{
|
|
267
|
+
"15": {
|
|
268
|
+
"organization": { "id": 42, "name": "org 42" }
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
*/
|
|
226
272
|
contacts.objects["15"].organization = 24;
|
|
227
273
|
await nextTick();
|
|
228
|
-
console.log(contacts.
|
|
274
|
+
console.log(contacts.relatedObjects["15"]);
|
|
229
275
|
/*
|
|
230
276
|
{
|
|
231
277
|
"organization": { "id": 24, "name": "org 24" }
|
|
@@ -233,45 +279,62 @@ console.log(contacts.objects["15"].myRelatedObjects);
|
|
|
233
279
|
*/
|
|
234
280
|
delete contactsRelated.relatedObjectRules.organization;
|
|
235
281
|
await nextTick();
|
|
236
|
-
console.log(contacts.
|
|
282
|
+
console.log(contacts.relatedObjects["15"]);
|
|
237
283
|
/* {} */
|
|
238
|
-
// manual stopage
|
|
284
|
+
// manual stopage. inside a setup or another effect scope, there isnt a need to manually call this.
|
|
239
285
|
contactsRelated.effectScope.stop();
|
|
240
286
|
await nextTick();
|
|
241
|
-
console.log(contacts.objects["15"].myRelatedObjects);
|
|
242
|
-
/* undefined */
|
|
243
287
|
```
|
|
244
288
|
|
|
245
|
-
####
|
|
289
|
+
#### Calculated
|
|
246
290
|
|
|
247
291
|
```js
|
|
248
292
|
// no main.js setup required.
|
|
249
293
|
// used in example below.
|
|
250
294
|
// use in your component
|
|
251
|
-
import { useListInstance,
|
|
295
|
+
import { useListInstance, useListCalculated } from "@arrai-innovations/reactive-helpers";
|
|
252
296
|
import { nextTick } from "vue";
|
|
253
297
|
|
|
254
298
|
const contacts = useListInstance({
|
|
255
299
|
retrieveArgs: {
|
|
256
|
-
fields: ["id", "has_name", "lexical_name", "organization"],
|
|
300
|
+
fields: ["id", "has_name", "has_billing", "lexical_name", "organization"],
|
|
257
301
|
},
|
|
258
302
|
});
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
303
|
+
const contactsCalculated = useListCalculated({
|
|
304
|
+
parentState: contacts.state,
|
|
305
|
+
calculatedObjectsRules: {
|
|
306
|
+
first_letter_of_name: (object) => {
|
|
307
|
+
return object.lexical_name[0];
|
|
308
|
+
},
|
|
309
|
+
},
|
|
265
310
|
});
|
|
266
311
|
await contacts.list();
|
|
267
|
-
console.log(
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
312
|
+
console.log(contacts.objects);
|
|
313
|
+
/*
|
|
314
|
+
{
|
|
315
|
+
"15": {
|
|
316
|
+
"id": 15,
|
|
317
|
+
"lexical_name": "one, contact",
|
|
318
|
+
"organization": 42,
|
|
319
|
+
},
|
|
320
|
+
"16": {
|
|
321
|
+
"id": 16,
|
|
322
|
+
"lexical_name": "two, contact",
|
|
323
|
+
"organization": 42,
|
|
324
|
+
},
|
|
325
|
+
}
|
|
326
|
+
*/
|
|
327
|
+
console.log(contacts.calculatedObjects);
|
|
328
|
+
/*
|
|
329
|
+
{
|
|
330
|
+
"15": {
|
|
331
|
+
"first_letter_of_name": "o"
|
|
332
|
+
},
|
|
333
|
+
"16": {
|
|
334
|
+
"first_letter_of_name": "t"
|
|
335
|
+
},
|
|
336
|
+
}
|
|
337
|
+
*/
|
|
275
338
|
```
|
|
276
339
|
|
|
277
340
|
#### Filter
|
|
@@ -285,24 +348,67 @@ import { nextTick } from "vue";
|
|
|
285
348
|
|
|
286
349
|
const contacts = useListInstance({
|
|
287
350
|
retrieveArgs: {
|
|
288
|
-
fields: ["id", "has_name", "lexical_name", "organization"],
|
|
351
|
+
fields: ["id", "has_name", "has_billing", "lexical_name", "organization"],
|
|
289
352
|
},
|
|
290
353
|
});
|
|
291
|
-
|
|
354
|
+
|
|
355
|
+
const myAllowedValues = ref(["15", "16"]);
|
|
356
|
+
const myExcludedValues = ref(["17"]);
|
|
357
|
+
// conditions are all optional but anded together if present.
|
|
292
358
|
const contactsFilter = useListFilter({
|
|
293
|
-
|
|
359
|
+
parentState: contacts.state,
|
|
294
360
|
allowedValues: myAllowedValues,
|
|
295
361
|
allowedFilter: function (object) {
|
|
296
362
|
return object.has_name === true;
|
|
297
363
|
},
|
|
364
|
+
excludedValues: myExcludedValues,
|
|
365
|
+
excludedFilter: function (object) {
|
|
366
|
+
return object.has_billing === true;
|
|
367
|
+
},
|
|
298
368
|
});
|
|
299
369
|
await contacts.list();
|
|
300
370
|
console.log(contactsFilter.state.objects);
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
371
|
+
console.log(contactsFilter.state.objectsInOrder);
|
|
372
|
+
console.log(contactsFilter.state.order);
|
|
373
|
+
myExcludedValues.value.push("15");
|
|
304
374
|
await nextTick();
|
|
305
375
|
console.log(contactsFilter.state.objects);
|
|
376
|
+
console.log(contactsFilter.state.objectsInOrder);
|
|
377
|
+
console.log(contactsFilter.state.order);
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
#### Sort
|
|
381
|
+
|
|
382
|
+
```js
|
|
383
|
+
// no main.js setup required.
|
|
384
|
+
// used in example below.
|
|
385
|
+
// use in your component
|
|
386
|
+
import { useListInstance, useListSort } from "@arrai-innovations/reactive-helpers";
|
|
387
|
+
import { nextTick } from "vue";
|
|
388
|
+
|
|
389
|
+
const contacts = useListInstance({
|
|
390
|
+
props: {
|
|
391
|
+
retrieveArgs: {
|
|
392
|
+
fields: ["id", "has_name", "lexical_name", "organization"],
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
});
|
|
396
|
+
const contactsSort = useListSort({
|
|
397
|
+
parentState: contacts.state,
|
|
398
|
+
orderByRules: [
|
|
399
|
+
{ key: "has_name", desc: true, localeCompare: false },
|
|
400
|
+
{ key: "lexical_name", desc: false, localeCompare: true },
|
|
401
|
+
],
|
|
402
|
+
sortThrottleWait: 100, // default, ms to wait before sorting after a change.
|
|
403
|
+
});
|
|
404
|
+
await contacts.list();
|
|
405
|
+
console.log(contactsSort.state.order);
|
|
406
|
+
// array of ids in order, based on the specified rules.
|
|
407
|
+
console.log(contactsSort.state.objectsInOrder);
|
|
408
|
+
// computed array of the previous that also looks up the object ids in .objects
|
|
409
|
+
contactsSort.state.orderByRules[0].desc = false;
|
|
410
|
+
await nextTick();
|
|
411
|
+
console.log(contactsSort.state.order);
|
|
306
412
|
// array of ids in order, based on updated rules.
|
|
307
413
|
```
|
|
308
414
|
|
|
@@ -315,17 +421,20 @@ import {
|
|
|
315
421
|
useListInstance,
|
|
316
422
|
useListSubscription,
|
|
317
423
|
useListRelated,
|
|
424
|
+
useListCalculated,
|
|
318
425
|
useListFilter,
|
|
319
426
|
useListSort,
|
|
320
427
|
} from "@arrai-innovations/reactive-helpers";
|
|
321
428
|
|
|
322
429
|
const organizationNameSearch = ref("");
|
|
323
430
|
const organizations = useListInstance({
|
|
431
|
+
// crudArgs are implementation specific to your crud functions.
|
|
324
432
|
crudArgs: {
|
|
325
433
|
stream: "organizations",
|
|
326
434
|
},
|
|
327
435
|
});
|
|
328
436
|
const contacts = useListInstance({
|
|
437
|
+
// crudArgs are implementation specific to your crud functions.
|
|
329
438
|
crudArgs: {
|
|
330
439
|
stream: "contacts",
|
|
331
440
|
},
|
|
@@ -337,6 +446,7 @@ const contacts = useListInstance({
|
|
|
337
446
|
},
|
|
338
447
|
});
|
|
339
448
|
const contactsSubscription = useListSubscription({
|
|
449
|
+
// crudArgs are implementation specific to your crud functions.
|
|
340
450
|
crudArgs: {
|
|
341
451
|
stream: "contacts",
|
|
342
452
|
includeCreateEvents: true,
|
|
@@ -353,8 +463,16 @@ const contactsRelated = useListRelated({
|
|
|
353
463
|
},
|
|
354
464
|
},
|
|
355
465
|
});
|
|
356
|
-
const
|
|
466
|
+
const contactsCalculated = useListCalculated({
|
|
357
467
|
parentState: contactsRelated.state,
|
|
468
|
+
calculatedObjectsRules: {
|
|
469
|
+
first_letter_of_name: (object) => {
|
|
470
|
+
return object.lexical_name[0];
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
});
|
|
474
|
+
const contactsFiltered = useListFilter({
|
|
475
|
+
parentState: contactsCalculated.state,
|
|
358
476
|
useTextSearch: true,
|
|
359
477
|
textSearchRules: ["relatedObjects.organization.name"],
|
|
360
478
|
textSearchValue: organizationNameSearch,
|
|
@@ -367,19 +485,241 @@ const contactsSorted = useListSort({
|
|
|
367
485
|
],
|
|
368
486
|
});
|
|
369
487
|
console.log(contactsSorted.state.value.objects);
|
|
488
|
+
// object of contacts, updating as new ones are created, filtered by organziation name, sort organization name & lexical name.
|
|
370
489
|
console.log(contactsSorted.state.value.order);
|
|
490
|
+
// array of ids in order, based on the specified rules.
|
|
371
491
|
console.log(contactsSorted.state.value.objectsInOrder);
|
|
372
|
-
// array of contacts, updating as new ones are created,
|
|
492
|
+
// array of contacts, updating as new ones are created, filtered by organziation name, sort organization name & lexical name.
|
|
493
|
+
console.log(contactsSorted.state.value.calculatedObjects);
|
|
494
|
+
// object of calculated objects, updating as new ones are created, for objects above.
|
|
495
|
+
console.log(contactsSorted.state.value.relatedObjects);
|
|
496
|
+
// object of related objects, updating as new ones are created, for objects above.
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
#### List
|
|
500
|
+
|
|
501
|
+
```js
|
|
502
|
+
// you can also let the library manage a full stack for you.
|
|
503
|
+
import { useList } from "@arrai-innovations/reactive-helpers";
|
|
504
|
+
import { reactive } from "vue";
|
|
505
|
+
|
|
506
|
+
const managedListProps = reactive({
|
|
507
|
+
// crudArgs are implementation specific to your crud functions.
|
|
508
|
+
crudArgs: {
|
|
509
|
+
stream: "contacts",
|
|
510
|
+
includeCreateEvents: true,
|
|
511
|
+
subscribeAction: "subscribe_contacts",
|
|
512
|
+
unsubscribeAction: "unsubscribe_contacts",
|
|
513
|
+
},
|
|
514
|
+
retrieveArgs: {
|
|
515
|
+
fields: ["id", "has_name", "lexical_name", "organization", "phone"],
|
|
516
|
+
},
|
|
517
|
+
listArgs: {
|
|
518
|
+
has_organization: true,
|
|
519
|
+
},
|
|
520
|
+
relatedObjectsRules: {
|
|
521
|
+
organization: {
|
|
522
|
+
// desired key on relatedObjects
|
|
523
|
+
objects: toRef(organizations.state, "objects"), // organizations by id
|
|
524
|
+
pkKey: "organization", // reference key on contact for org id.
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
calculatedObjectsRules: {
|
|
528
|
+
first_letter_of_name: (object) => {
|
|
529
|
+
return object.lexical_name[0];
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
orderByRules: [
|
|
533
|
+
{ key: "relatedObjects.organization.name", desc: false, localeCompare: true },
|
|
534
|
+
{ key: "lexical_name", desc: false, localeCompare: true },
|
|
535
|
+
],
|
|
536
|
+
useTextSearch: true,
|
|
537
|
+
textSearchRules: ["relatedObjects.organization.name"],
|
|
538
|
+
textSearchValue: organizationNameSearch,
|
|
539
|
+
sortThrottleWait: 100, // default, ms to wait before sorting after a change.
|
|
540
|
+
});
|
|
541
|
+
const managedList = useList({
|
|
542
|
+
props: managedListProps,
|
|
543
|
+
functions: {
|
|
544
|
+
list: customListFunction,
|
|
545
|
+
subscribe: customSubscribeFunction,
|
|
546
|
+
},
|
|
547
|
+
});
|
|
548
|
+
// the state expected of each are all available on the same state.
|
|
549
|
+
console.log(managedList.state.value.objects);
|
|
550
|
+
// managed instances can also be accessed directly.
|
|
551
|
+
console.log(managedList.managed);
|
|
552
|
+
/*
|
|
553
|
+
{
|
|
554
|
+
listInstance: {...},
|
|
555
|
+
listSubscription: {...},
|
|
556
|
+
listRelated: {...},
|
|
557
|
+
listCalculated: {...},
|
|
558
|
+
listFilter: {...},
|
|
559
|
+
listSort: {...},
|
|
560
|
+
}
|
|
561
|
+
*/
|
|
562
|
+
// the stack is applied in the order of the keys as by managedList.managed.
|
|
373
563
|
```
|
|
374
564
|
|
|
375
565
|
### Object
|
|
376
566
|
|
|
377
567
|
```js
|
|
378
|
-
|
|
379
|
-
|
|
568
|
+
// do this in your main.js
|
|
569
|
+
import { setObjectCrud } from "@arrai-innovations/reactive-helpers";
|
|
570
|
+
|
|
571
|
+
setObjectCrud({
|
|
572
|
+
create: async function createCrudAdaptor({ crudArgs, retrieveArgs, object }) {
|
|
573
|
+
// todo: your implemenation here.
|
|
574
|
+
const newObject = await talkToServer(object);
|
|
575
|
+
return newObject;
|
|
576
|
+
},
|
|
577
|
+
retrieve: async function retrieveCrudAdaptor({ crudArgs, retrieveArgs, id }) {
|
|
578
|
+
// todo: your implemenation here.
|
|
579
|
+
const retrievedObject = await talkToServer(id);
|
|
580
|
+
return retrievedObject;
|
|
581
|
+
},
|
|
582
|
+
update: async function updateCrudAdaptor({ crudArgs, retrieveArgs, object }) {
|
|
583
|
+
// todo: your implemenation here.
|
|
584
|
+
const updatedObject = await talkToServer(object);
|
|
585
|
+
return updatedObject;
|
|
586
|
+
},
|
|
587
|
+
delete: async function deleteCrudAdaptor({ crudArgs, id }) {
|
|
588
|
+
// todo: your implemenation here.
|
|
589
|
+
await talkToServer(id);
|
|
590
|
+
},
|
|
591
|
+
patch: async function patchCrudAdaptor({ crudArgs, retrieveArgs, id, partialObject }) {
|
|
592
|
+
// todo: your implemenation here.
|
|
593
|
+
const patchedObject = await talkToServer(object);
|
|
594
|
+
return patchedObject; // still return the full object.
|
|
595
|
+
},
|
|
596
|
+
subscribe: function subscribeCrudAdaptor({ crudArgs, retrieveArgs, listArgs, eventCallback }) {
|
|
597
|
+
// todo: your implemenation here.
|
|
598
|
+
const subscription = talkToServer(function (data, action) {
|
|
599
|
+
eventCallback(data, action);
|
|
600
|
+
});
|
|
601
|
+
// return a promise with a cancel action
|
|
602
|
+
subscription.cancel = async () => {
|
|
603
|
+
await cancelSubOnServer();
|
|
604
|
+
};
|
|
605
|
+
return subscription;
|
|
606
|
+
},
|
|
607
|
+
});
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
```js
|
|
611
|
+
// similar to list, but for a single object.
|
|
612
|
+
import {
|
|
613
|
+
useObjectInstance, useObjectSubscription, useObjectRelated, useObjectCalculated
|
|
614
|
+
} from "@arrai-innovations/reactive-helpers";
|
|
615
|
+
|
|
616
|
+
const contactObject = useObjectInstance({
|
|
617
|
+
props: {
|
|
618
|
+
crudArgs: {
|
|
619
|
+
stream: "contacts",
|
|
620
|
+
},
|
|
621
|
+
retrieveArgs: {
|
|
622
|
+
fields: ["id", "has_name", "lexical_name", "organization", "phone"],
|
|
623
|
+
},
|
|
624
|
+
id: contactId,
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
console.log(contactObject.state.object);
|
|
628
|
+
const contactSubscription = useObjectSubscription({
|
|
629
|
+
objectInstance: contactObject,
|
|
630
|
+
})
|
|
380
631
|
// or
|
|
381
|
-
|
|
382
|
-
|
|
632
|
+
const contactSubscription = useObjectSubscription({
|
|
633
|
+
props: {
|
|
634
|
+
crudArgs: {
|
|
635
|
+
stream: "contacts",
|
|
636
|
+
},
|
|
637
|
+
retrieveArgs: {
|
|
638
|
+
fields: ["id", "has_name", "lexical_name", "organization", "phone"],
|
|
639
|
+
},
|
|
640
|
+
id: contactId,
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
console.log(contactSubscription.state.object);
|
|
644
|
+
const organizations = useList({
|
|
645
|
+
props: {
|
|
646
|
+
crudArgs: {
|
|
647
|
+
stream: "organizations",
|
|
648
|
+
},
|
|
649
|
+
retrieveArgs: {
|
|
650
|
+
fields: ["id", "name"],
|
|
651
|
+
},
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
await organizations.list();
|
|
655
|
+
const contactRelated = useObjectRelated({
|
|
656
|
+
parentState: contactSubscription.state,
|
|
657
|
+
relatedObjectRules: {
|
|
658
|
+
organization: {
|
|
659
|
+
// desired key on relatedObjects
|
|
660
|
+
objects: toRef(organizations.state, "objects"), // organizations by id
|
|
661
|
+
pkKey: "organization", // reference key on contact for org id.
|
|
662
|
+
},
|
|
663
|
+
},
|
|
664
|
+
});
|
|
665
|
+
console.log(contactRelated.state.object.relatedObject.organization.name);
|
|
666
|
+
const contactCalculated = useObjectCalculated({
|
|
667
|
+
parentState: contactSubscription.state,
|
|
668
|
+
calculatedObjectRules: {
|
|
669
|
+
first_letter_of_name: (object) => {
|
|
670
|
+
return object.lexical_name[0];
|
|
671
|
+
},
|
|
672
|
+
},
|
|
673
|
+
});
|
|
674
|
+
console.log(contactCalculated.state.object.calculatedObject.first_letter_of_name);
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
```js
|
|
678
|
+
// you can also let the library managed a full stack for you.
|
|
679
|
+
import { useObject } from "@arrai-innovations/reactive-helpers";
|
|
680
|
+
import { reactive } from "vue";
|
|
681
|
+
|
|
682
|
+
const managedObjectProps = reactive({
|
|
683
|
+
crudArgs: {
|
|
684
|
+
stream: "contacts",
|
|
685
|
+
},
|
|
686
|
+
retrieveArgs: {
|
|
687
|
+
fields: ["id", "has_name", "lexical_name", "organization", "phone"],
|
|
688
|
+
},
|
|
689
|
+
id: contactId,
|
|
690
|
+
relatedObjectRules: {
|
|
691
|
+
organization: {
|
|
692
|
+
// desired key on relatedObjects
|
|
693
|
+
objects: toRef(organizations.state, "objects"), // organizations by id
|
|
694
|
+
pkKey: "organization", // reference key on contact for org id.
|
|
695
|
+
},
|
|
696
|
+
},
|
|
697
|
+
calculatedObjectRules: {
|
|
698
|
+
first_letter_of_name: (object) => {
|
|
699
|
+
return object.lexical_name[0];
|
|
700
|
+
},
|
|
701
|
+
},
|
|
702
|
+
});
|
|
703
|
+
const managedObject = useObject({
|
|
704
|
+
props: managedObjectProps,
|
|
705
|
+
functions: {
|
|
706
|
+
retrieve: customRetrieveFunction,
|
|
707
|
+
subscribe: customSubscribeFunction,
|
|
708
|
+
},
|
|
709
|
+
});
|
|
710
|
+
// the state expected of each are all available on the same state.
|
|
711
|
+
console.log(managedObject.state.value.objects);
|
|
712
|
+
// managed instances can also be accessed directly.
|
|
713
|
+
console.log(managedObject.managed);
|
|
714
|
+
/*
|
|
715
|
+
{
|
|
716
|
+
objectInstance: {...},
|
|
717
|
+
objectSubscription: {...},
|
|
718
|
+
objectRelated: {...},
|
|
719
|
+
objectCalculated: {...},\
|
|
720
|
+
}
|
|
721
|
+
*/
|
|
722
|
+
// the stack is applied in the order of the keys as by managedObject.managed.
|
|
383
723
|
```
|
|
384
724
|
|
|
385
725
|
### Search
|
package/config/index.js
ADDED