@ai-table/state 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/esm2022/public-api.mjs +2 -1
  2. package/esm2022/shared/to-table/array-event.mjs +45 -15
  3. package/esm2022/shared/to-table/index.mjs +8 -8
  4. package/esm2022/shared/to-yjs/add-node.mjs +21 -10
  5. package/esm2022/shared/to-yjs/index.mjs +3 -1
  6. package/esm2022/shared/to-yjs/remove-node.mjs +21 -10
  7. package/esm2022/types/view.mjs +28 -25
  8. package/esm2022/utils/build.mjs +16 -0
  9. package/esm2022/utils/common.mjs +11 -0
  10. package/esm2022/utils/field/date.mjs +56 -0
  11. package/esm2022/utils/field/field.mjs +32 -0
  12. package/esm2022/utils/field/index.mjs +22 -0
  13. package/esm2022/utils/field/number.mjs +28 -0
  14. package/esm2022/utils/field/rate.mjs +20 -0
  15. package/esm2022/utils/field/select.mjs +33 -0
  16. package/esm2022/utils/field/text.mjs +21 -0
  17. package/esm2022/utils/filter-records.mjs +52 -0
  18. package/esm2022/utils/index.mjs +6 -0
  19. package/esm2022/utils/view.mjs +69 -0
  20. package/esm2022/view/action/general.mjs +89 -5
  21. package/esm2022/view/action/index.mjs +2 -1
  22. package/esm2022/view/action/position.mjs +21 -0
  23. package/esm2022/view/action/view.mjs +4 -4
  24. package/esm2022/view/constants/view.mjs +3 -2
  25. package/esm2022/view/plugins/view.plugin.mjs +15 -6
  26. package/fesm2022/ai-table-state.mjs +565 -67
  27. package/fesm2022/ai-table-state.mjs.map +1 -1
  28. package/package.json +1 -1
  29. package/public-api.d.ts +1 -0
  30. package/public-api.d.ts.map +1 -1
  31. package/shared/to-table/array-event.d.ts +3 -2
  32. package/shared/to-table/array-event.d.ts.map +1 -1
  33. package/shared/to-table/index.d.ts +3 -3
  34. package/shared/to-table/index.d.ts.map +1 -1
  35. package/shared/to-yjs/add-node.d.ts +2 -2
  36. package/shared/to-yjs/add-node.d.ts.map +1 -1
  37. package/shared/to-yjs/index.d.ts.map +1 -1
  38. package/shared/to-yjs/remove-node.d.ts +2 -2
  39. package/shared/to-yjs/remove-node.d.ts.map +1 -1
  40. package/types/view.d.ts +32 -14
  41. package/types/view.d.ts.map +1 -1
  42. package/utils/build.d.ts +5 -0
  43. package/utils/build.d.ts.map +1 -0
  44. package/utils/common.d.ts +2 -0
  45. package/utils/common.d.ts.map +1 -0
  46. package/utils/field/date.d.ts +8 -0
  47. package/utils/field/date.d.ts.map +1 -0
  48. package/utils/field/field.d.ts +8 -0
  49. package/utils/field/field.d.ts.map +1 -0
  50. package/utils/field/index.d.ts +4 -0
  51. package/utils/field/index.d.ts.map +1 -0
  52. package/utils/field/number.d.ts +7 -0
  53. package/utils/field/number.d.ts.map +1 -0
  54. package/utils/field/rate.d.ts +7 -0
  55. package/utils/field/rate.d.ts.map +1 -0
  56. package/utils/field/select.d.ts +7 -0
  57. package/utils/field/select.d.ts.map +1 -0
  58. package/utils/field/text.d.ts +8 -0
  59. package/utils/field/text.d.ts.map +1 -0
  60. package/utils/filter-records.d.ts +5 -0
  61. package/utils/filter-records.d.ts.map +1 -0
  62. package/utils/index.d.ts +6 -0
  63. package/utils/index.d.ts.map +1 -0
  64. package/utils/view.d.ts +6 -0
  65. package/utils/view.d.ts.map +1 -0
  66. package/view/action/general.d.ts +9 -1
  67. package/view/action/general.d.ts.map +1 -1
  68. package/view/action/index.d.ts +1 -0
  69. package/view/action/index.d.ts.map +1 -1
  70. package/view/action/position.d.ts +8 -0
  71. package/view/action/position.d.ts.map +1 -0
  72. package/view/action/view.d.ts +4 -3
  73. package/view/action/view.d.ts.map +1 -1
  74. package/view/constants/view.d.ts +2 -1
  75. package/view/constants/view.d.ts.map +1 -1
  76. package/view/plugins/view.plugin.d.ts.map +1 -1
@@ -1,7 +1,8 @@
1
1
  import * as Y from 'yjs';
2
- import { ActionName, AITableQueries, getDefaultFieldValue, Actions, FLUSHING } from '@ai-table/grid';
3
- import { isArray } from 'ngx-tethys/util';
2
+ import { ActionName, AITableQueries, getDefaultFieldValue, idCreator, Actions, FLUSHING, AITableFieldType } from '@ai-table/grid';
3
+ import { isArray, isEmpty as isEmpty$1, isObject, isUndefinedOrNull, TinyDate } from 'ngx-tethys/util';
4
4
  import { createDraft, finishDraft } from 'immer';
5
+ import { fromUnixTime, subDays } from 'date-fns';
5
6
 
6
7
  class Positions {
7
8
  }
@@ -11,36 +12,39 @@ var Direction;
11
12
  Direction[Direction["ascending"] = 1] = "ascending";
12
13
  Direction[Direction["descending"] = -1] = "descending";
13
14
  })(Direction || (Direction = {}));
14
- var LogicalOperator;
15
- (function (LogicalOperator) {
16
- LogicalOperator["and"] = "and";
17
- LogicalOperator["or"] = "or";
18
- })(LogicalOperator || (LogicalOperator = {}));
19
- var FilterOperationSymbol;
20
- (function (FilterOperationSymbol) {
21
- FilterOperationSymbol["eq"] = "eq";
22
- FilterOperationSymbol["gte"] = "gte";
23
- FilterOperationSymbol["lte"] = "lte";
24
- FilterOperationSymbol["gt"] = "gt";
25
- FilterOperationSymbol["lt"] = "lt";
26
- FilterOperationSymbol["in"] = "in";
27
- FilterOperationSymbol["contain"] = "contain";
28
- FilterOperationSymbol["ne"] = "ne";
29
- FilterOperationSymbol["nin"] = "nin";
30
- FilterOperationSymbol["between"] = "between";
31
- FilterOperationSymbol["besides"] = "besides";
32
- FilterOperationSymbol["empty"] = "empty";
33
- FilterOperationSymbol["exists"] = "exists";
34
- FilterOperationSymbol["notContain"] = "not_contain";
35
- })(FilterOperationSymbol || (FilterOperationSymbol = {}));
36
- class GridSettings {
37
- }
15
+ var AITableFilterLogical;
16
+ (function (AITableFilterLogical) {
17
+ AITableFilterLogical["and"] = "and";
18
+ AITableFilterLogical["or"] = "or";
19
+ })(AITableFilterLogical || (AITableFilterLogical = {}));
20
+ var AITableFilterOperation;
21
+ (function (AITableFilterOperation) {
22
+ AITableFilterOperation["eq"] = "eq";
23
+ AITableFilterOperation["gte"] = "gte";
24
+ AITableFilterOperation["lte"] = "lte";
25
+ AITableFilterOperation["gt"] = "gt";
26
+ AITableFilterOperation["lt"] = "lt";
27
+ AITableFilterOperation["in"] = "in";
28
+ AITableFilterOperation["contain"] = "contain";
29
+ AITableFilterOperation["ne"] = "ne";
30
+ AITableFilterOperation["nin"] = "nin";
31
+ AITableFilterOperation["between"] = "between";
32
+ AITableFilterOperation["besides"] = "besides";
33
+ AITableFilterOperation["empty"] = "empty";
34
+ AITableFilterOperation["exists"] = "exists";
35
+ AITableFilterOperation["notContain"] = "not_contain";
36
+ })(AITableFilterOperation || (AITableFilterOperation = {}));
38
37
  var ViewActionName;
39
38
  (function (ViewActionName) {
40
39
  ViewActionName["SetView"] = "set_view";
41
40
  ViewActionName["AddView"] = "add_view";
42
41
  ViewActionName["RemoveView"] = "remove_view";
43
42
  })(ViewActionName || (ViewActionName = {}));
43
+ var PositionActionName;
44
+ (function (PositionActionName) {
45
+ PositionActionName["AddRecordPosition"] = "add_record_position";
46
+ PositionActionName["RemoveRecordPosition"] = "remove_record_position";
47
+ })(PositionActionName || (PositionActionName = {}));
44
48
 
45
49
  const createSharedType = () => {
46
50
  const doc = new Y.Doc();
@@ -163,13 +167,14 @@ const initTable = (sharedType) => {
163
167
  };
164
168
  };
165
169
 
166
- function translateArrayEvent(aiTable, activeViewId, sharedType, event) {
170
+ function translateArrayEvent(aiTable, sharedType, event) {
167
171
  let offset = 0;
168
172
  let targetPath = getShareTypeNumberPath(event.path);
169
173
  const isRecordsTranslate = event.path.includes('records');
170
174
  const isFieldsTranslate = event.path.includes('fields');
171
175
  const isViewsTranslate = event.path.includes('views');
172
176
  const actions = [];
177
+ const activeViewId = aiTable.activeViewId();
173
178
  event.changes.delta.forEach((delta) => {
174
179
  if ('retain' in delta) {
175
180
  offset += delta.retain ?? 0;
@@ -220,21 +225,47 @@ function translateArrayEvent(aiTable, activeViewId, sharedType, event) {
220
225
  }
221
226
  else {
222
227
  try {
228
+ const sharedRecords = sharedType.get('records');
229
+ const sharedFields = sharedType.get('fields');
223
230
  delta.insert?.map((item) => {
224
231
  const recordIndex = targetPath[0];
225
232
  const fieldIndex = offset;
226
- const recordId = getSharedRecordId(sharedType.get('records'), recordIndex);
227
- const fieldId = getSharedMapValueId(sharedType.get('fields'), fieldIndex);
228
- const path = [recordId, fieldId];
229
- const fieldValue = AITableQueries.getFieldValue(aiTable, path);
230
- // To exclude insert triggered by field inserts.
231
- if (fieldValue !== item) {
232
- actions.push({
233
- type: ActionName.UpdateFieldValue,
234
- path,
235
- fieldValue,
236
- newFieldValue: item
237
- });
233
+ const record = aiTable.records()[recordIndex];
234
+ if (isPositionOperation(fieldIndex, sharedFields)) {
235
+ for (const key in item) {
236
+ if (!record.positions[key] && record.positions[key] !== 0) {
237
+ actions.push({
238
+ type: PositionActionName.AddRecordPosition,
239
+ path: [record._id],
240
+ position: {
241
+ [key]: item[key]
242
+ }
243
+ });
244
+ }
245
+ }
246
+ for (const key in record.positions) {
247
+ if (!item[key] && item[key] !== 0) {
248
+ actions.push({
249
+ type: PositionActionName.RemoveRecordPosition,
250
+ path: [key, record._id]
251
+ });
252
+ }
253
+ }
254
+ }
255
+ else {
256
+ const recordId = getSharedRecordId(sharedRecords, recordIndex);
257
+ const fieldId = getSharedMapValueId(sharedFields, fieldIndex);
258
+ const path = [recordId, fieldId];
259
+ const fieldValue = AITableQueries.getFieldValue(aiTable, path);
260
+ // To exclude insert triggered by field inserts.
261
+ if (fieldValue !== item) {
262
+ actions.push({
263
+ type: ActionName.UpdateFieldValue,
264
+ path,
265
+ fieldValue,
266
+ newFieldValue: item
267
+ });
268
+ }
238
269
  }
239
270
  });
240
271
  }
@@ -270,6 +301,9 @@ function translateArrayEvent(aiTable, activeViewId, sharedType, event) {
270
301
  function isAddOrRemove(targetPath) {
271
302
  return targetPath.length === 0;
272
303
  }
304
+ function isPositionOperation(fieldIndex, sharedFields) {
305
+ return fieldIndex === sharedFields.length;
306
+ }
273
307
  function getRemoveIds(event, type) {
274
308
  const ids = [];
275
309
  if (!type) {
@@ -378,27 +412,27 @@ const YjsAITable = {
378
412
  }
379
413
  };
380
414
 
381
- function translateYjsEvent(aiTable, activeViewId, sharedType, event) {
415
+ function translateYjsEvent(aiTable, sharedType, event) {
382
416
  if (event instanceof Y.YArrayEvent) {
383
- return translateArrayEvent(aiTable, activeViewId, sharedType, event);
417
+ return translateArrayEvent(aiTable, sharedType, event);
384
418
  }
385
419
  if (event instanceof Y.YMapEvent) {
386
420
  return translateMapEvent(aiTable, sharedType, event);
387
421
  }
388
422
  return [];
389
423
  }
390
- function applyEvents(aiTable, activeViewId, sharedType, events) {
391
- events.forEach((event) => translateYjsEvent(aiTable, activeViewId, sharedType, event).forEach((item) => {
424
+ function applyEvents(aiTable, sharedType, events) {
425
+ events.forEach((event) => translateYjsEvent(aiTable, sharedType, event).forEach((item) => {
392
426
  aiTable.apply(item);
393
427
  }));
394
428
  }
395
- function applyYjsEvents(aiTable, activeViewId, sharedType, events) {
429
+ function applyYjsEvents(aiTable, sharedType, events) {
396
430
  if (YjsAITable.isUndo(aiTable)) {
397
- applyEvents(aiTable, activeViewId, sharedType, events);
431
+ applyEvents(aiTable, sharedType, events);
398
432
  }
399
433
  else {
400
434
  YjsAITable.asRemote(aiTable, () => {
401
- applyEvents(aiTable, activeViewId, sharedType, events);
435
+ applyEvents(aiTable, sharedType, events);
402
436
  });
403
437
  }
404
438
  }
@@ -450,22 +484,33 @@ function setNode(sharedType, action) {
450
484
  }
451
485
 
452
486
  function addNode(sharedType, action) {
487
+ const records = sharedType.get('records');
488
+ const views = sharedType.get('views');
489
+ const fields = sharedType.get('fields');
453
490
  switch (action.type) {
454
491
  case ActionName.AddRecord:
455
- const records = sharedType.get('records');
456
492
  records && records.push([toRecordSyncElement(action.record)]);
457
493
  break;
458
494
  case ViewActionName.AddView:
459
- const views = sharedType.get('views');
460
495
  views && views.push([toSyncElement(action.view)]);
461
496
  break;
497
+ case PositionActionName.AddRecordPosition:
498
+ if (records) {
499
+ const recordIndex = getSharedRecordIndex(records, action.path[0]);
500
+ const record = records.get(recordIndex);
501
+ const customField = record.get(1);
502
+ const positionsIndex = customField.length - 1;
503
+ const positions = customField.get(positionsIndex);
504
+ const newPositions = { ...positions, ...action.position };
505
+ customField.delete(positionsIndex);
506
+ customField.insert(positionsIndex, [newPositions]);
507
+ }
508
+ break;
462
509
  case ActionName.AddField:
463
- const sharedFields = sharedType.get('fields');
464
- const sharedRecords = sharedType.get('records');
465
- if (sharedFields && sharedRecords) {
466
- sharedFields.push([toSyncElement(action.field)]);
510
+ if (fields && records) {
511
+ fields.push([toSyncElement(action.field)]);
467
512
  const path = action.path[0];
468
- for (let value of sharedRecords) {
513
+ for (let value of records) {
469
514
  const newRecord = getDefaultFieldValue(action.field);
470
515
  const customField = value.get(1);
471
516
  customField.insert(path, [newRecord]);
@@ -477,9 +522,11 @@ function addNode(sharedType, action) {
477
522
  }
478
523
 
479
524
  function removeNode(sharedType, action) {
525
+ const fields = sharedType.get('fields');
526
+ const records = sharedType.get('records');
527
+ const views = sharedType.get('views');
480
528
  switch (action.type) {
481
529
  case ActionName.RemoveRecord:
482
- const records = sharedType.get('records');
483
530
  if (records) {
484
531
  const recordIndex = getSharedRecordIndex(records, action.path[0]);
485
532
  if (recordIndex > -1) {
@@ -488,7 +535,6 @@ function removeNode(sharedType, action) {
488
535
  }
489
536
  break;
490
537
  case ViewActionName.RemoveView:
491
- const views = sharedType.get('views');
492
538
  if (views) {
493
539
  const viewIndex = getSharedMapValueIndex(views, action.path[0]);
494
540
  if (viewIndex > -1) {
@@ -496,14 +542,24 @@ function removeNode(sharedType, action) {
496
542
  }
497
543
  }
498
544
  break;
545
+ case PositionActionName.RemoveRecordPosition:
546
+ if (records) {
547
+ const recordIndex = getSharedRecordIndex(records, action.path[1]);
548
+ const record = records.get(recordIndex);
549
+ const customField = record.get(1);
550
+ const positionsIndex = customField.length - 1;
551
+ const positions = customField.get(positionsIndex);
552
+ delete positions[action.path[0]];
553
+ customField.delete(positionsIndex);
554
+ customField.insert(positionsIndex, [positions]);
555
+ }
556
+ break;
499
557
  case ActionName.RemoveField:
500
- const sharedFields = sharedType.get('fields');
501
- const sharedRecords = sharedType.get('records');
502
- if (sharedFields && sharedRecords) {
503
- const fieldIndex = getSharedMapValueIndex(sharedFields, action.path[0]);
558
+ if (fields && records) {
559
+ const fieldIndex = getSharedMapValueIndex(fields, action.path[0]);
504
560
  if (fieldIndex > -1) {
505
- sharedFields.delete(fieldIndex);
506
- for (let value of sharedRecords) {
561
+ fields.delete(fieldIndex);
562
+ for (let value of records) {
507
563
  value.get(1).delete(fieldIndex);
508
564
  }
509
565
  }
@@ -523,6 +579,8 @@ const actionMappers = {
523
579
  set_view: setNode,
524
580
  add_view: addNode,
525
581
  remove_view: removeNode,
582
+ add_record_position: addNode,
583
+ remove_record_position: removeNode
526
584
  };
527
585
  function applyActionOps(sharedType, actions, aiTable) {
528
586
  if (actions.length > 0) {
@@ -539,13 +597,78 @@ function applyActionOps(sharedType, actions, aiTable) {
539
597
  return sharedType;
540
598
  }
541
599
 
600
+ function createDefaultPositions(views, activeId, data, index) {
601
+ const positions = {};
602
+ const position = getPosition(data, activeId, index);
603
+ const maxPosition = data[data.length - 1].positions[activeId];
604
+ views.forEach((element) => {
605
+ positions[element._id] = element._id === activeId ? position : maxPosition + 1;
606
+ });
607
+ return positions;
608
+ }
609
+ function getPosition(data, activeViewId, index) {
610
+ let position = data.length - 1;
611
+ if (index !== 0 && index !== data.length) {
612
+ const previousViewPosition = data[index - 1].positions[activeViewId];
613
+ const nextViewPosition = data[index].positions[activeViewId];
614
+ position = (previousViewPosition + nextViewPosition) / 2;
615
+ }
616
+ else {
617
+ position = index;
618
+ }
619
+ return position;
620
+ }
621
+ function addView$1(aiTable, type) {
622
+ let index = aiTable.views().length;
623
+ const newId = idCreator();
624
+ let newView = {
625
+ _id: newId,
626
+ name: '表格视图 ' + index
627
+ };
628
+ let originViewId = aiTable.views()[aiTable.views().length - 1]._id;
629
+ if (type === 'copy') {
630
+ originViewId = aiTable.activeViewId();
631
+ const copyView = aiTable.views().find((item) => item._id === aiTable.activeViewId());
632
+ newView = {
633
+ ...copyView,
634
+ _id: newId,
635
+ name: copyView.name + '-副本'
636
+ };
637
+ index = aiTable.views().indexOf(copyView) + 1;
638
+ }
639
+ ViewActions.addView(aiTable, newView, [index]);
640
+ aiTable.records().forEach((record) => {
641
+ PositionActions.addRecordPosition(aiTable, { [newId]: record.positions[originViewId] }, [record._id]);
642
+ });
643
+ aiTable.fields().forEach((field) => {
644
+ Actions.setField(aiTable, {
645
+ positions: {
646
+ ...field.positions,
647
+ [newId]: field.positions[originViewId]
648
+ }
649
+ }, [field._id]);
650
+ });
651
+ return newView;
652
+ }
653
+ function removeView$1(aiTable, records, fields, activeViewId) {
654
+ records.forEach((record) => {
655
+ PositionActions.removeRecordPosition(aiTable, [activeViewId, record._id]);
656
+ });
657
+ fields.forEach((field) => {
658
+ const positions = { ...field.positions };
659
+ delete positions[activeViewId];
660
+ Actions.setField(aiTable, {
661
+ positions
662
+ }, [field._id]);
663
+ });
664
+ ViewActions.removeView(aiTable, [activeViewId]);
665
+ }
666
+
542
667
  const GeneralViewActions = {
543
668
  transform(aiTable, action) {
544
669
  const views = createDraft(aiTable.views());
545
670
  applyView(aiTable, views, action);
546
- aiTable.views.update(() => {
547
- return finishDraft(views);
548
- });
671
+ aiTable.views.set(finishDraft(views));
549
672
  }
550
673
  };
551
674
  const applyView = (aiTable, views, action) => {
@@ -589,6 +712,90 @@ const applyView = (aiTable, views, action) => {
589
712
  }
590
713
  }
591
714
  };
715
+ const GeneralActions = {
716
+ transform(aiTable, action) {
717
+ const records = createDraft(aiTable.records());
718
+ const fields = createDraft(aiTable.fields());
719
+ apply(aiTable, records, fields, action);
720
+ if (action.type === ActionName.AddRecord) {
721
+ aiTable.records.set(finishDraft(records));
722
+ }
723
+ if (action.type === ActionName.AddField) {
724
+ aiTable.fields.set(finishDraft(fields));
725
+ }
726
+ }
727
+ };
728
+ const apply = (aiTable, records, fields, action) => {
729
+ switch (action.type) {
730
+ case ActionName.AddRecord: {
731
+ const [recordIndex] = action.path;
732
+ if (recordIndex > -1) {
733
+ if (!action.record.positions) {
734
+ const activeView = aiTable.views().find((item) => item._id === aiTable.activeViewId());
735
+ let index = recordIndex;
736
+ if (activeView?.settings?.conditions) {
737
+ index = records.length;
738
+ }
739
+ action.record.positions = createDefaultPositions(aiTable.views(), aiTable.activeViewId(), aiTable.records(), index);
740
+ }
741
+ records.splice(recordIndex, 0, action.record);
742
+ }
743
+ break;
744
+ }
745
+ case ActionName.AddField: {
746
+ const [fieldIndex] = action.path;
747
+ if (fieldIndex > -1) {
748
+ const newField = action.field;
749
+ newField.positions = createDefaultPositions(aiTable.views(), aiTable.activeViewId(), aiTable.fields(), action.path[0]);
750
+ fields.splice(fieldIndex, 0, newField);
751
+ const newRecord = {
752
+ [newField._id]: getDefaultFieldValue(action.field)
753
+ };
754
+ records.forEach((item) => {
755
+ item.values = {
756
+ ...item.values,
757
+ ...newRecord
758
+ };
759
+ });
760
+ }
761
+ break;
762
+ }
763
+ }
764
+ };
765
+ const GeneralPositionActions = {
766
+ transform(aiTable, action) {
767
+ const records = createDraft(aiTable.records());
768
+ const fields = createDraft(aiTable.fields());
769
+ applyPosition(aiTable, records, action);
770
+ aiTable.records.update(() => {
771
+ return finishDraft(records);
772
+ });
773
+ aiTable.fields.update(() => {
774
+ return finishDraft(fields);
775
+ });
776
+ }
777
+ };
778
+ const applyPosition = (aiTable, records, action) => {
779
+ switch (action.type) {
780
+ case PositionActionName.AddRecordPosition: {
781
+ const { position, path } = action;
782
+ const record = records.find((item) => item._id === path[0]);
783
+ if (record) {
784
+ record.positions = {
785
+ ...record.positions,
786
+ ...position
787
+ };
788
+ }
789
+ break;
790
+ }
791
+ case PositionActionName.RemoveRecordPosition: {
792
+ const { path } = action;
793
+ const record = records.find((item) => item._id === path[1]);
794
+ delete record?.positions[path[0]];
795
+ break;
796
+ }
797
+ }
798
+ };
592
799
 
593
800
  function setView(aiTable, value, path) {
594
801
  const view = aiTable.views().find((item) => item._id === path[0]);
@@ -636,17 +843,47 @@ const ViewActions = {
636
843
  removeView
637
844
  };
638
845
 
846
+ function addRecordPosition(aiTable, position, path) {
847
+ const operation = {
848
+ type: PositionActionName.AddRecordPosition,
849
+ position,
850
+ path
851
+ };
852
+ aiTable.apply(operation);
853
+ }
854
+ function removeRecordPosition(aiTable, path) {
855
+ const operation = {
856
+ type: PositionActionName.RemoveRecordPosition,
857
+ path
858
+ };
859
+ aiTable.apply(operation);
860
+ }
861
+ const PositionActions = {
862
+ addRecordPosition,
863
+ removeRecordPosition
864
+ };
865
+
639
866
  const VIEW_ACTIONS = [ViewActionName.SetView, ViewActionName.AddView, ViewActionName.RemoveView];
867
+ const POSITION_ACTIONS = [PositionActionName.AddRecordPosition, PositionActionName.RemoveRecordPosition];
640
868
 
641
869
  const withView = (aiTable) => {
642
870
  const viewTable = aiTable;
643
871
  viewTable.apply = (action) => {
644
- aiTable.actions.push(action);
872
+ const sharedActions = viewTable.actions;
873
+ sharedActions.push(action);
645
874
  if (VIEW_ACTIONS.includes(action.type)) {
646
875
  GeneralViewActions.transform(viewTable, action);
647
876
  }
877
+ else if (POSITION_ACTIONS.includes(action.type)) {
878
+ GeneralPositionActions.transform(viewTable, action);
879
+ }
648
880
  else {
649
- Actions.transform(aiTable, action);
881
+ if (action.type === ActionName.AddField || action.type === ActionName.AddRecord) {
882
+ GeneralActions.transform(viewTable, action);
883
+ }
884
+ else {
885
+ Actions.transform(aiTable, action);
886
+ }
650
887
  }
651
888
  if (!FLUSHING.get(aiTable)) {
652
889
  FLUSHING.set(aiTable, true);
@@ -660,9 +897,270 @@ const withView = (aiTable) => {
660
897
  return aiTable;
661
898
  };
662
899
 
900
+ function isEmpty(value) {
901
+ if (isArray(value)) {
902
+ return isEmpty$1(value);
903
+ }
904
+ if (isObject(value)) {
905
+ return Reflect.ownKeys(value).length === 0;
906
+ }
907
+ return isUndefinedOrNull(value) || value == '';
908
+ }
909
+
910
+ class Field {
911
+ stringInclude(str, searchStr) {
912
+ return str.toLowerCase().includes(searchStr.trim().toLowerCase());
913
+ }
914
+ isMeetFilter(condition, cellValue) {
915
+ switch (condition.operation) {
916
+ case AITableFilterOperation.empty:
917
+ case AITableFilterOperation.exists: {
918
+ return this.isEmptyOrNot(condition.operation, cellValue);
919
+ }
920
+ default: {
921
+ return true;
922
+ }
923
+ }
924
+ }
925
+ isEmptyOrNot(operation, cellValue) {
926
+ switch (operation) {
927
+ case AITableFilterOperation.empty: {
928
+ return isEmpty(cellValue);
929
+ }
930
+ case AITableFilterOperation.exists: {
931
+ return !isEmpty(cellValue);
932
+ }
933
+ default: {
934
+ throw new Error('compare operator type error');
935
+ }
936
+ }
937
+ }
938
+ }
939
+
940
+ class TextField extends Field {
941
+ isMeetFilter(condition, cellValue) {
942
+ switch (condition.operation) {
943
+ case AITableFilterOperation.empty:
944
+ return isEmpty(cellValue);
945
+ case AITableFilterOperation.exists:
946
+ return !isEmpty(cellValue);
947
+ case AITableFilterOperation.contain:
948
+ return !isEmpty(cellValue) && this.stringInclude(cellValue, condition.value);
949
+ default:
950
+ return super.isMeetFilter(condition, cellValue);
951
+ }
952
+ }
953
+ static stringInclude(str, searchStr) {
954
+ return str.toLowerCase().includes(searchStr.trim().toLowerCase());
955
+ }
956
+ }
957
+
958
+ class SelectField extends Field {
959
+ isMeetFilter(condition, cellValue) {
960
+ switch (condition.operation) {
961
+ case AITableFilterOperation.empty:
962
+ return isEmpty(cellValue);
963
+ case AITableFilterOperation.exists:
964
+ return !isEmpty(cellValue);
965
+ case AITableFilterOperation.in:
966
+ return Array.isArray(condition.value) && hasIntersect(cellValue, condition.value);
967
+ case AITableFilterOperation.nin:
968
+ return Array.isArray(condition.value) && !hasIntersect(cellValue, condition.value);
969
+ default:
970
+ return super.isMeetFilter(condition, cellValue);
971
+ }
972
+ }
973
+ }
974
+ function hasIntersect(array1, array2) {
975
+ if (!Array.isArray(array1) || !Array.isArray(array2)) {
976
+ return false;
977
+ }
978
+ const set1 = new Set(array1);
979
+ const set2 = new Set(array2);
980
+ for (const ele of set1) {
981
+ if (set2.has(ele)) {
982
+ return true;
983
+ }
984
+ }
985
+ return false;
986
+ }
987
+
988
+ class DateField extends Field {
989
+ isMeetFilter(condition, cellValue) {
990
+ const [left, right] = this.getTimeRange(condition.value);
991
+ switch (condition.operation) {
992
+ case AITableFilterOperation.empty:
993
+ return isEmpty(cellValue.timestamp) || cellValue.timestamp === 0;
994
+ case AITableFilterOperation.exists:
995
+ return !isEmpty(cellValue.timestamp) && cellValue.timestamp !== 0;
996
+ case AITableFilterOperation.eq:
997
+ return left <= cellValue.timestamp && cellValue.timestamp < right;
998
+ case AITableFilterOperation.gt:
999
+ return cellValue.timestamp > right;
1000
+ case AITableFilterOperation.lt:
1001
+ return cellValue.timestamp < left;
1002
+ case AITableFilterOperation.between:
1003
+ return left <= cellValue.timestamp && cellValue.timestamp < right;
1004
+ default:
1005
+ return super.isMeetFilter(condition, cellValue);
1006
+ }
1007
+ }
1008
+ getTimeRange(value) {
1009
+ switch (value) {
1010
+ case 'today':
1011
+ return [new TinyDate(new Date()).startOfDay().getUnixTime(), new TinyDate(new Date()).endOfDay().getUnixTime()];
1012
+ case 'current_week':
1013
+ return [
1014
+ new TinyDate().startOfWeek({ weekStartsOn: 1 }).getUnixTime(),
1015
+ new TinyDate().endOfWeek({ weekStartsOn: 1 }).getUnixTime()
1016
+ ];
1017
+ case 'yesterday':
1018
+ return [
1019
+ new TinyDate(subDays(new Date(), 1)).startOfDay().getUnixTime(),
1020
+ new TinyDate(subDays(new Date(), 1)).endOfDay().getUnixTime()
1021
+ ];
1022
+ case 'current_month':
1023
+ return [new TinyDate().startOfMonth().getUnixTime(), new TinyDate().endOfMonth().getUnixTime()];
1024
+ default:
1025
+ if (isArray(value)) {
1026
+ return [
1027
+ new TinyDate(fromUnixTime(value[0])).startOfDay().getUnixTime(),
1028
+ new TinyDate(fromUnixTime(value[1])).endOfDay().getUnixTime()
1029
+ ];
1030
+ }
1031
+ return [
1032
+ new TinyDate(fromUnixTime(value)).startOfDay().getUnixTime(),
1033
+ new TinyDate(fromUnixTime(value)).endOfDay().getUnixTime()
1034
+ ];
1035
+ }
1036
+ }
1037
+ }
1038
+
1039
+ class NumberField extends Field {
1040
+ isMeetFilter(condition, cellValue) {
1041
+ switch (condition.operation) {
1042
+ case AITableFilterOperation.empty:
1043
+ return isEmpty(cellValue);
1044
+ case AITableFilterOperation.exists:
1045
+ return !isEmpty(cellValue);
1046
+ case AITableFilterOperation.eq:
1047
+ return !Number.isNaN(condition.value) && cellValue != null && cellValue !== '' && condition.value === cellValue;
1048
+ case AITableFilterOperation.gte:
1049
+ return cellValue != null && cellValue !== '' && cellValue >= condition.value;
1050
+ case AITableFilterOperation.lte:
1051
+ return cellValue != null && cellValue !== '' && cellValue <= condition.value;
1052
+ case AITableFilterOperation.gt:
1053
+ return cellValue != null && cellValue !== '' && cellValue > condition.value;
1054
+ case AITableFilterOperation.lt:
1055
+ return cellValue != null && cellValue !== '' && cellValue < condition.value;
1056
+ case AITableFilterOperation.ne:
1057
+ return cellValue == null || cellValue == '' || Number.isNaN(condition.value) || cellValue !== condition.value;
1058
+ default:
1059
+ return super.isMeetFilter(condition, cellValue);
1060
+ }
1061
+ }
1062
+ }
1063
+
1064
+ class RateField extends Field {
1065
+ isMeetFilter(condition, cellValue) {
1066
+ switch (condition.operation) {
1067
+ case AITableFilterOperation.empty:
1068
+ return isEmpty(cellValue);
1069
+ case AITableFilterOperation.exists:
1070
+ return !isEmpty(cellValue);
1071
+ case AITableFilterOperation.in:
1072
+ return !isEmpty(cellValue) && condition.value.includes(cellValue.toString());
1073
+ case AITableFilterOperation.nin:
1074
+ return isEmpty(cellValue) || !condition.value.includes(cellValue.toString());
1075
+ default:
1076
+ return super.isMeetFilter(condition, cellValue);
1077
+ }
1078
+ }
1079
+ }
1080
+
1081
+ const ViewOperationMap = {
1082
+ [AITableFieldType.text]: new TextField(),
1083
+ [AITableFieldType.richText]: new TextField(),
1084
+ [AITableFieldType.select]: new SelectField(),
1085
+ [AITableFieldType.date]: new DateField(),
1086
+ [AITableFieldType.createdAt]: new DateField(),
1087
+ [AITableFieldType.updatedAt]: new DateField(),
1088
+ [AITableFieldType.number]: new NumberField(),
1089
+ [AITableFieldType.rate]: new RateField(),
1090
+ [AITableFieldType.link]: new TextField(),
1091
+ [AITableFieldType.member]: new SelectField(),
1092
+ [AITableFieldType.progress]: new NumberField(),
1093
+ [AITableFieldType.createdBy]: new SelectField(),
1094
+ [AITableFieldType.updatedBy]: new SelectField()
1095
+ };
1096
+
1097
+ function getFilteredRecords(records, fields, activeView) {
1098
+ const { conditions, condition_logical } = activeView.settings || {};
1099
+ if (!conditions) {
1100
+ return records;
1101
+ }
1102
+ const illegalConditions = conditions.filter((item) => item.operation) || [];
1103
+ if (!illegalConditions.length) {
1104
+ return records;
1105
+ }
1106
+ return records.filter((record) => {
1107
+ return checkConditions(fields, record, { conditions: illegalConditions, condition_logical });
1108
+ });
1109
+ }
1110
+ function checkConditions(fields, record, filterConditions) {
1111
+ if (!record) {
1112
+ return false;
1113
+ }
1114
+ if (!filterConditions?.conditions) {
1115
+ return true;
1116
+ }
1117
+ const { condition_logical, conditions } = filterConditions;
1118
+ if (condition_logical === AITableFilterLogical.and) {
1119
+ return conditions.every((condition) => doFilterOperations(fields, record, condition));
1120
+ }
1121
+ if (!condition_logical || condition_logical === AITableFilterLogical.or) {
1122
+ return conditions.some((condition) => doFilterOperations(fields, record, condition));
1123
+ }
1124
+ return false;
1125
+ }
1126
+ function doFilterOperations(fields, record, condition) {
1127
+ const field = fields.find((item) => item._id === condition.field_id);
1128
+ const cellValue = record.values[condition.field_id];
1129
+ try {
1130
+ return field && doFilter(condition, field, cellValue);
1131
+ }
1132
+ catch (error) {
1133
+ return false;
1134
+ }
1135
+ }
1136
+ function doFilter(condition, field, cellValue) {
1137
+ if (condition.operation === AITableFilterOperation.empty) {
1138
+ return isEmpty(cellValue);
1139
+ }
1140
+ if (condition.operation === AITableFilterOperation.exists) {
1141
+ return !isEmpty(cellValue);
1142
+ }
1143
+ return ViewOperationMap[field.type].isMeetFilter(condition, cellValue);
1144
+ }
1145
+
1146
+ function sortByView(data, activeViewId) {
1147
+ const hasPositions = data.every((item) => item.positions && item.positions);
1148
+ if (hasPositions) {
1149
+ return [...data].sort((a, b) => a.positions[activeViewId] - b.positions[activeViewId]);
1150
+ }
1151
+ return data;
1152
+ }
1153
+ function buildRecordsByView(records, fields, activeView) {
1154
+ const filteredRecords = getFilteredRecords(records, fields, activeView);
1155
+ return sortByView(filteredRecords, activeView._id);
1156
+ }
1157
+ function buildFieldsByView(fields, activeView) {
1158
+ return sortByView(fields, activeView._id);
1159
+ }
1160
+
663
1161
  /**
664
1162
  * Generated bundle index. Do not edit.
665
1163
  */
666
1164
 
667
- export { Direction, FilterOperationSymbol, GeneralViewActions, GridSettings, LogicalOperator, Positions, VIEW_ACTIONS, ViewActionName, ViewActions, YjsAITable, actionMappers, addView, applyActionOps, applyEvents, applyView, applyYjsEvents, createSharedType, getShareTypeNumberPath, getSharedMapValueId, getSharedMapValueIndex, getSharedRecordId, getSharedRecordIndex, initSharedType, initTable, removeView, setView, toRecordSyncElement, toSharedType, toSyncElement, translatePositionToPath, translateToRecordValues, translateToRecords, translateYjsEvent, withView };
1165
+ export { AITableFilterLogical, AITableFilterOperation, Direction, GeneralActions, GeneralPositionActions, GeneralViewActions, POSITION_ACTIONS, PositionActionName, PositionActions, Positions, VIEW_ACTIONS, ViewActionName, ViewActions, ViewOperationMap, YjsAITable, actionMappers, addRecordPosition, addView$1 as addView, apply, applyActionOps, applyEvents, applyPosition, applyView, applyYjsEvents, buildFieldsByView, buildRecordsByView, createDefaultPositions, createSharedType, doFilter, getFilteredRecords, getPosition, getShareTypeNumberPath, getSharedMapValueId, getSharedMapValueIndex, getSharedRecordId, getSharedRecordIndex, initSharedType, initTable, isEmpty, removeRecordPosition, removeView$1 as removeView, sortByView, toRecordSyncElement, toSharedType, toSyncElement, translatePositionToPath, translateToRecordValues, translateToRecords, translateYjsEvent, withView };
668
1166
  //# sourceMappingURL=ai-table-state.mjs.map