@arrai-innovations/reactive-helpers 10.4.2 → 11.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.
@@ -1,8 +1,8 @@
1
1
  version: 2.1
2
2
  orbs:
3
- eslint: arrai/eslint@7.4.0
4
- prettier: arrai/prettier@5.4.0
5
- npm: arrai/npm@2.4.1
3
+ eslint: arrai/eslint@7.6.0
4
+ prettier: arrai/prettier@5.5.0
5
+ npm: arrai/npm@2.9.0
6
6
  github: arrai/github@1.1.0
7
7
  workflows:
8
8
  test:
package/README.md CHANGED
@@ -21,11 +21,11 @@ Vue.js 3 utility composition functions to help manipulate objects and lists.
21
21
  - [Related](#related)
22
22
  - [Calculated](#calculated)
23
23
  - [Filter](#filter)
24
+ - [Search](#search)
24
25
  - [Sort](#sort)
25
26
  - [All](#all)
26
- - [List](#list-1)
27
27
  - [Object](#object)
28
- - [Search](#search)
28
+ - [Search](#search-1)
29
29
  - [Utils](#utils)
30
30
  - [addOrUpdateReactiveObject & assignReactiveObject](#addorupdatereactiveobject--assignreactiveobject)
31
31
  - [keyDiff](#keydiff)
@@ -148,6 +148,7 @@ setListCrud({
148
148
  ```js
149
149
  // then use in your component
150
150
  import { useListInstance, useListSubscription } from "@arrai-innovations/reactive-helpers";
151
+ import { reactive } from "vue";
151
152
 
152
153
  const listProps = reactive({
153
154
  // crudArgs are implementation specific to your crud functions.
@@ -186,6 +187,7 @@ delete contacts.listArgs.has_organization;
186
187
  ```js
187
188
  // or you can have listSubscription create the listInstance for you.
188
189
  import { useListSubscription } from "@arrai-innovations/reactive-helpers";
190
+ import { reactive } from "vue";
189
191
 
190
192
  const listProps = reactive({
191
193
  // crudArgs are implementation specific to your crud functions.
@@ -214,33 +216,35 @@ Lookup foreign keys between list instances via watch, for using dot notation in
214
216
  ```js
215
217
  // no main.js setup required.
216
218
  // used in example below.
217
- // use in your component
218
- import { useListInstance, useListRelated } from "@arrai-innovations/reactive-helpers";
219
- import { nextTick } from "vue";
219
+ import { useListInstance, useListRelated, doAwaitNot } from "@arrai-innovations/reactive-helpers";
220
+ import { reactive, toRef } from "vue";
220
221
 
222
+ const organizationsProps = reactive({
223
+ retrieveArgs: {
224
+ fields: ["id", "name"],
225
+ },
226
+ });
221
227
  const organizations = useListInstance({
222
- props: {
223
- retrieveArgs: {
224
- fields: ["id", "name"],
225
- },
228
+ props: organizationsProps,
229
+ });
230
+ const contactsProps = reactive({
231
+ retrieveArgs: {
232
+ fields: ["id", "lexical_name", "organization"],
226
233
  },
227
234
  });
228
235
  const contacts = useListInstance({
229
- props: {
230
- retrieveArgs: {
231
- fields: ["id", "lexical_name", "organization"],
232
- },
236
+ props: contactsProps,
237
+ });
238
+ const contactsRelatedRules = reactive({
239
+ organization: {
240
+ // desired key on relatedObjects
241
+ objects: toRef(organizations.state, "objects"), // organizations by id
242
+ pkKey: "organization", // reference key on contact for org id.
233
243
  },
234
244
  });
235
245
  const contactsRelated = useListRelated({
236
246
  parentState: contacts.state,
237
- relatedObjectsRules: {
238
- organization: {
239
- // desired key on relatedObjects
240
- objects: toRef(organizations.state, "objects"), // organizations by id
241
- pkKey: "organization", // reference key on contact for org id.
242
- },
243
- },
247
+ relatedObjectsRules: contactsRelatedRules,
244
248
  });
245
249
  await organizations.list();
246
250
  await contacts.list();
@@ -270,7 +274,10 @@ console.log(contacts.relatedObjects);
270
274
  }
271
275
  */
272
276
  contacts.objects["15"].organization = 24;
273
- await nextTick();
277
+ await doAwaitNot({
278
+ obj: contactsRelated.state,
279
+ prop: "running",
280
+ });
274
281
  console.log(contacts.relatedObjects["15"]);
275
282
  /*
276
283
  {
@@ -278,12 +285,13 @@ console.log(contacts.relatedObjects["15"]);
278
285
  }
279
286
  */
280
287
  delete contactsRelated.relatedObjectRules.organization;
288
+ await doAwaitNot({
289
+ obj: contactsRelated.state,
290
+ prop: "running",
291
+ });
281
292
  await nextTick();
282
293
  console.log(contacts.relatedObjects["15"]);
283
294
  /* {} */
284
- // manual stopage. inside a setup or another effect scope, there isnt a need to manually call this.
285
- contactsRelated.effectScope.stop();
286
- await nextTick();
287
295
  ```
288
296
 
289
297
  #### Calculated
@@ -291,22 +299,25 @@ await nextTick();
291
299
  ```js
292
300
  // no main.js setup required.
293
301
  // used in example below.
294
- // use in your component
295
302
  import { useListInstance, useListCalculated } from "@arrai-innovations/reactive-helpers";
296
- import { nextTick } from "vue";
303
+ import { nextTick, reactive } from "vue";
297
304
 
298
- const contacts = useListInstance({
305
+ const contactsProps = reactive({
299
306
  retrieveArgs: {
300
307
  fields: ["id", "has_name", "has_billing", "lexical_name", "organization"],
301
308
  },
302
309
  });
310
+ const contacts = useListInstance({
311
+ props: contactsProps,
312
+ });
313
+ const contactsCalculatedRules = reactive({
314
+ first_letter_of_name: (object) => {
315
+ return object.lexical_name[0];
316
+ },
317
+ });
303
318
  const contactsCalculated = useListCalculated({
304
319
  parentState: contacts.state,
305
- calculatedObjectsRules: {
306
- first_letter_of_name: (object) => {
307
- return object.lexical_name[0];
308
- },
309
- },
320
+ calculatedObjectsRules: contactsCalculatedRules,
310
321
  });
311
322
  await contacts.list();
312
323
  console.log(contacts.objects);
@@ -342,57 +353,105 @@ console.log(contacts.calculatedObjects);
342
353
  ```js
343
354
  // no main.js setup required.
344
355
  // used in example below.
345
- // use in your component
346
- import { useListInstance, useListFilter } from "@arrai-innovations/reactive-helpers";
347
- import { nextTick } from "vue";
356
+ import { useListInstance, useListFilter, doAwaitNot } from "@arrai-innovations/reactive-helpers";
357
+ import { reactive, ref } from "vue";
348
358
 
349
- const contacts = useListInstance({
359
+ const contactsProps = reactive({
350
360
  retrieveArgs: {
351
361
  fields: ["id", "has_name", "has_billing", "lexical_name", "organization"],
352
362
  },
353
363
  });
364
+ const contacts = useListInstance({
365
+ props: contactsProps,
366
+ });
367
+
368
+ const allowedFilter = ref((object) => {
369
+ return object.has_name === true;
370
+ });
371
+ const excludedFilter = ref((object) => {
372
+ return object.has_billing === true;
373
+ });
354
374
 
355
- const myAllowedValues = ref(["15", "16"]);
356
- const myExcludedValues = ref(["17"]);
357
375
  // conditions are all optional but anded together if present.
358
376
  const contactsFilter = useListFilter({
359
377
  parentState: contacts.state,
360
- allowedValues: myAllowedValues,
361
- allowedFilter: function (object) {
362
- return object.has_name === true;
363
- },
364
- excludedValues: myExcludedValues,
365
- excludedFilter: function (object) {
366
- return object.has_billing === true;
367
- },
378
+ allowedFilter,
379
+ excludedFilter,
368
380
  });
369
381
  await contacts.list();
370
382
  console.log(contactsFilter.state.objects);
371
383
  console.log(contactsFilter.state.objectsInOrder);
372
384
  console.log(contactsFilter.state.order);
373
- myExcludedValues.value.push("15");
374
- await nextTick();
385
+ contacts.objects["15"].has_name = false;
386
+ await doAwaitNot({
387
+ obj: contactsFilter.state,
388
+ prop: "running",
389
+ });
375
390
  console.log(contactsFilter.state.objects);
376
391
  console.log(contactsFilter.state.objectsInOrder);
377
392
  console.log(contactsFilter.state.order);
378
393
  ```
379
394
 
380
- #### Sort
395
+ #### Search
381
396
 
382
397
  ```js
383
398
  // no main.js setup required.
384
399
  // used in example below.
385
- // use in your component
386
- import { useListInstance, useListSort } from "@arrai-innovations/reactive-helpers";
387
- import { nextTick } from "vue";
400
+ import { useListInstance, useListSearch, doAwaitNot } from "@arrai-innovations/reactive-helpers";
401
+ import { reactive } from "vue";
388
402
 
403
+ const contactsProps = reactive({
404
+ retrieveArgs: {
405
+ fields: ["id", "has_name", "has_billing", "lexical_name", "organization"],
406
+ },
407
+ });
389
408
  const contacts = useListInstance({
390
- props: {
391
- retrieveArgs: {
392
- fields: ["id", "has_name", "lexical_name", "organization"],
393
- },
409
+ props: contactsProps,
410
+ });
411
+ const searchProps = reactive({
412
+ textSearchRules: ["lexical_name"],
413
+ textSearchValue: "",
414
+ });
415
+ const search = useListSearch({
416
+ parentState: contacts.state,
417
+ props: searchProps,
418
+ });
419
+ await contacts.list();
420
+ await doAwaitNot({
421
+ obj: search.state,
422
+ prop: "running",
423
+ });
424
+ // all values show when search is empty.
425
+ console.log(search.state.objects);
426
+ console.log(search.state.objectsInOrder);
427
+ console.log(search.state.order);
428
+ searchProps.textSearchValue = "one";
429
+ await doAwaitNot({
430
+ obj: search.state,
431
+ prop: "running",
432
+ });
433
+ // only values that match the search show.
434
+ console.log(search.state.objects);
435
+ console.log(search.state.objectsInOrder);
436
+ console.log(search.state.order);
437
+ ```
438
+
439
+ #### Sort
440
+
441
+ ```js
442
+ // no main.js setup required.
443
+ // used in example below.
444
+ import { useListInstance, useListSort, doAwaitNot } from "@arrai-innovations/reactive-helpers";
445
+ import { reactive } from "vue";
446
+
447
+ const contactsProps = reactive({
448
+ retrieveArgs: {
449
+ fields: ["id", "has_name", "lexical_name", "organization"],
394
450
  },
395
451
  });
452
+ const contacts = useListInstance({
453
+ props: contactsProps,
454
+ });
396
455
  const contactsSort = useListSort({
397
456
  parentState: contacts.state,
398
457
  orderByRules: [
@@ -407,101 +466,20 @@ console.log(contactsSort.state.order);
407
466
  console.log(contactsSort.state.objectsInOrder);
408
467
  // computed array of the previous that also looks up the object ids in .objects
409
468
  contactsSort.state.orderByRules[0].desc = false;
410
- await nextTick();
469
+ await doAwaitNot({
470
+ obj: contactsSort.state,
471
+ prop: "running",
472
+ });
411
473
  console.log(contactsSort.state.order);
412
474
  // array of ids in order, based on updated rules.
413
475
  ```
414
476
 
415
477
  #### All
416
478
 
417
- Example using all of the above.
418
-
419
- ```js
420
- import {
421
- useListInstance,
422
- useListSubscription,
423
- useListRelated,
424
- useListCalculated,
425
- useListFilter,
426
- useListSort,
427
- } from "@arrai-innovations/reactive-helpers";
428
-
429
- const organizationNameSearch = ref("");
430
- const organizations = useListInstance({
431
- // crudArgs are implementation specific to your crud functions.
432
- crudArgs: {
433
- stream: "organizations",
434
- },
435
- });
436
- const contacts = useListInstance({
437
- // crudArgs are implementation specific to your crud functions.
438
- crudArgs: {
439
- stream: "contacts",
440
- },
441
- retrieveArgs: {
442
- fields: ["id", "has_name", "lexical_name", "organization", "phone"],
443
- },
444
- listArgs: {
445
- has_organization: true,
446
- },
447
- });
448
- const contactsSubscription = useListSubscription({
449
- // crudArgs are implementation specific to your crud functions.
450
- crudArgs: {
451
- stream: "contacts",
452
- includeCreateEvents: true,
453
- },
454
- listInstance: contacts,
455
- });
456
- const contactsRelated = useListRelated({
457
- parentState: contactsSubscription.state,
458
- relatedObjectsRules: {
459
- organization: {
460
- // desired key on relatedObjects
461
- objects: toRef(organizations.state, "objects"), // organizations by id
462
- pkKey: "organization", // reference key on contact for org id.
463
- },
464
- },
465
- });
466
- const contactsCalculated = useListCalculated({
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,
476
- useTextSearch: true,
477
- textSearchRules: ["relatedObjects.organization.name"],
478
- textSearchValue: organizationNameSearch,
479
- });
480
- const contactsSorted = useListSort({
481
- parentState: contactsFiltered.state,
482
- orderByRules: [
483
- { key: "relatedObjects.organization.name", desc: false, localeCompare: true },
484
- { key: "lexical_name", desc: false, localeCompare: true },
485
- ],
486
- });
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.
489
- console.log(contactsSorted.state.value.order);
490
- // array of ids in order, based on the specified rules.
491
- console.log(contactsSorted.state.value.objectsInOrder);
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
479
  ```js
502
480
  // you can also let the library manage a full stack for you.
503
481
  import { useList } from "@arrai-innovations/reactive-helpers";
504
- import { reactive } from "vue";
482
+ import { reactive, toRef } from "vue";
505
483
 
506
484
  const managedListProps = reactive({
507
485
  // crudArgs are implementation specific to your crud functions.
@@ -533,7 +511,6 @@ const managedListProps = reactive({
533
511
  { key: "relatedObjects.organization.name", desc: false, localeCompare: true },
534
512
  { key: "lexical_name", desc: false, localeCompare: true },
535
513
  ],
536
- useTextSearch: true,
537
514
  textSearchRules: ["relatedObjects.organization.name"],
538
515
  textSearchValue: organizationNameSearch,
539
516
  sortThrottleWait: 100, // default, ms to wait before sorting after a change.
@@ -12,7 +12,6 @@ const defaultCrud = {
12
12
  export const setListCrud = ({ list, subscribe, args = {}, ...rest }) => {
13
13
  defaultCrud.list = list;
14
14
  defaultCrud.subscribe = subscribe;
15
- // defensive cloning
16
15
  Object.assign(defaultCrud.args, cloneDeep(args));
17
16
  if (Object.keys(rest).length) {
18
17
  throw new Error(`Unknown key(s) passed to setListCrud: ${Object.keys(rest).join(", ")}`);