@ai-table/state 0.1.41 → 0.1.43
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/action/group.d.ts +4 -4
- package/action/group.d.ts.map +1 -1
- package/action/index.d.ts +3 -3
- package/action/record.d.ts +2 -4
- package/action/record.d.ts.map +1 -1
- package/constants/context-menu-item.d.ts.map +1 -1
- package/fesm2022/ai-table-state.mjs +358 -121
- package/fesm2022/ai-table-state.mjs.map +1 -1
- package/package.json +1 -1
- package/utils/build.d.ts +2 -2
- package/utils/build.d.ts.map +1 -1
- package/utils/group/group-calculator.d.ts +5 -5
- package/utils/group/group-calculator.d.ts.map +1 -1
- package/utils/group/index.d.ts +1 -0
- package/utils/group/index.d.ts.map +1 -1
- package/utils/group/utils.d.ts +4 -0
- package/utils/group/utils.d.ts.map +1 -0
- package/utils/record/add-records.d.ts.map +1 -1
- package/utils/record/common.d.ts +18 -0
- package/utils/record/common.d.ts.map +1 -0
- package/utils/record/index.d.ts +1 -0
- package/utils/record/index.d.ts.map +1 -1
- package/utils/record/move-records.d.ts.map +1 -1
- package/utils/record/sort.d.ts +3 -3
- package/utils/record/sort.d.ts.map +1 -1
@@ -1,9 +1,9 @@
|
|
1
1
|
import * as Y from 'yjs';
|
2
2
|
import { UndoManager } from 'yjs';
|
3
|
-
import { getShareTypeNumberPath, ActionName, translateArrayEvent, getSharedRecordIndex, getSharedMapValueIndex, toMapSyncElement, getIdBySystemFieldValuesType, setRecordUpdatedInfo, getPositionsByRecordSyncElement, setRecordPositions as setRecordPositions$1, toRecordSyncElement, AI_TABLE_CONTENT_FIELD_NAME, getValuesByCustomFieldValues, getPositionsBySystemFieldValues, getTrackableEntityBySystemFieldValues, getShortIdBySystemFieldValues, getIdBySystemFieldValues,
|
3
|
+
import { getShareTypeNumberPath, ActionName, translateArrayEvent, getSharedRecordIndex, getSharedMapValueIndex, toMapSyncElement, getIdBySystemFieldValuesType, setRecordUpdatedInfo, getPositionsByRecordSyncElement, setRecordPositions as setRecordPositions$1, toRecordSyncElement, AI_TABLE_CONTENT_FIELD_NAME, getValuesByCustomFieldValues, getPositionsBySystemFieldValues, getTrackableEntityBySystemFieldValues, getShortIdBySystemFieldValues, getIdBySystemFieldValues, SortDirection, AITableFilterLogical, AITableFilterOperation, AITableFieldType, isEmpty, sortByViewPosition, AI_TABLE_DEFAULT_MIN_UNFROZEN_WIDTH, AI_TABLE_MIN_FROZEN_COLUMN_COUNT, idCreator } from '@ai-table/utils';
|
4
4
|
import * as i0 from '@angular/core';
|
5
5
|
import { signal, Injectable } from '@angular/core';
|
6
|
-
import { FieldModelMap, AITableQueries, isSystemField, AITableRowType, AITable, getColumnIndicesSizeMap, shortIdCreator, generateNewName, getDefaultFieldValue, AI_TABLE_GROUP_MAX_LEVEL, idsCreator, shortIdsCreator, setSelection, AI_TABLE_GRID_FIELD_SERVICE_MAP, clearSelection, buildClipboardData, writeToClipboard, getI18nTextByKey, AITableGridI18nKey, isMac, writeToAITable } from '@ai-table/grid';
|
6
|
+
import { FieldModelMap, AITableQueries, isSystemField, AITableRowType, AITable, getColumnIndicesSizeMap, shortIdCreator, generateNewName, getDefaultFieldValue, AI_TABLE_GROUP_MAX_LEVEL, idsCreator, shortIdsCreator, closeExpendCell, setSelection, AI_TABLE_GRID_FIELD_SERVICE_MAP, clearSelection, buildClipboardData, writeToClipboard, getI18nTextByKey, AITableGridI18nKey, isMac, writeToAITable } from '@ai-table/grid';
|
7
7
|
import { nanoid } from 'nanoid';
|
8
8
|
import * as _ from 'lodash';
|
9
9
|
import ___default from 'lodash';
|
@@ -410,14 +410,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
410
410
|
}] });
|
411
411
|
|
412
412
|
function getSortRecords(aiTable, records, activeView, sortKeysMap) {
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
413
|
+
const shallowRecords = [...records];
|
414
|
+
const groups = activeView.settings?.groups;
|
415
|
+
return shallowRecords.sort((record1, record2) => {
|
416
|
+
// 分组排序(高优先级)
|
417
|
+
if (groups && groups.length > 0) {
|
418
|
+
const groupCompareResult = compareByGroups(aiTable, record1, record2, groups);
|
419
|
+
if (groupCompareResult !== 0) {
|
420
|
+
return groupCompareResult;
|
421
|
+
}
|
422
|
+
}
|
423
|
+
// sorts排序(中优先级)
|
424
|
+
let shouldSkipPositionSort = false;
|
425
|
+
if (activeView.settings?.sorts?.length) {
|
426
|
+
const { is_keep_sort, sorts } = activeView.settings;
|
427
|
+
if (sorts?.length) {
|
428
|
+
const sortsCompareResult = compareBySorts(record1, record2, sorts, aiTable, sortKeysMap);
|
429
|
+
if (sortsCompareResult !== 0) {
|
430
|
+
return sortsCompareResult;
|
431
|
+
}
|
432
|
+
shouldSkipPositionSort = Boolean(is_keep_sort);
|
433
|
+
}
|
434
|
+
}
|
435
|
+
// position排序(低优先级)
|
436
|
+
if (shouldSkipPositionSort) {
|
437
|
+
// is_keep_sort为true,禁用position排序
|
438
|
+
return 0;
|
439
|
+
}
|
440
|
+
return compareByPosition(record1, record2, activeView);
|
441
|
+
});
|
421
442
|
}
|
422
443
|
function sortRecordsBySortInfo(aiTable, records, activeView, sortKeysMap) {
|
423
444
|
const shallowRows = [...records];
|
@@ -444,6 +465,59 @@ function sortRecordsBySortInfo(aiTable, records, activeView, sortKeysMap) {
|
|
444
465
|
}
|
445
466
|
return shallowRows;
|
446
467
|
}
|
468
|
+
function compareByGroups(aiTable, record1, record2, groups) {
|
469
|
+
return groups.reduce((result, groupField) => {
|
470
|
+
if (result !== 0)
|
471
|
+
return result;
|
472
|
+
const field = aiTable.fieldsMap()[groupField.field_id];
|
473
|
+
if (!field)
|
474
|
+
return 0;
|
475
|
+
const value1 = AITableQueries.getFieldValue(aiTable, [record1._id, field._id]);
|
476
|
+
const value2 = AITableQueries.getFieldValue(aiTable, [record2._id, field._id]);
|
477
|
+
const fieldModel = FieldModelMap[field.type];
|
478
|
+
if (!fieldModel)
|
479
|
+
return 0;
|
480
|
+
const compareResult = fieldModel.compare(value1, value2, aiTable.context.references(), undefined, {
|
481
|
+
aiTable,
|
482
|
+
field
|
483
|
+
});
|
484
|
+
return compareResult * (groupField.direction === SortDirection.ascending ? 1 : -1);
|
485
|
+
}, 0);
|
486
|
+
}
|
487
|
+
function compareBySorts(record1, record2, sorts, aiTable, sortKeysMap) {
|
488
|
+
return sorts.reduce((acc, rule) => {
|
489
|
+
const field = aiTable.fieldsMap()[rule.sort_by];
|
490
|
+
if (!field || acc !== 0) {
|
491
|
+
return acc;
|
492
|
+
}
|
493
|
+
const fieldMethod = FieldModelMap[field.type];
|
494
|
+
const sortKey = sortKeysMap?.[field.type];
|
495
|
+
const cellValue1 = AITableQueries.getFieldValue(aiTable, [record1._id, field._id]);
|
496
|
+
const cellValue2 = AITableQueries.getFieldValue(aiTable, [record2._id, field._id]);
|
497
|
+
const references = aiTable.context.references();
|
498
|
+
const res = fieldMethod.compare(cellValue1, cellValue2, references, sortKey, {
|
499
|
+
aiTable,
|
500
|
+
field
|
501
|
+
});
|
502
|
+
return res * rule.direction;
|
503
|
+
}, 0);
|
504
|
+
}
|
505
|
+
function compareByPosition(record1, record2, activeView) {
|
506
|
+
const hasPosition1 = record1.positions && record1.positions[activeView._id] !== undefined;
|
507
|
+
const hasPosition2 = record2.positions && record2.positions[activeView._id] !== undefined;
|
508
|
+
if (hasPosition1 && hasPosition2) {
|
509
|
+
return record1.positions[activeView._id] - record2.positions[activeView._id];
|
510
|
+
}
|
511
|
+
// 如果只有一个有位置信息,有位置的排在前面
|
512
|
+
if (hasPosition1 && !hasPosition2) {
|
513
|
+
return -1;
|
514
|
+
}
|
515
|
+
if (!hasPosition1 && hasPosition2) {
|
516
|
+
return 1;
|
517
|
+
}
|
518
|
+
// 如果都没有位置信息,保持原有顺序
|
519
|
+
return 0;
|
520
|
+
}
|
447
521
|
|
448
522
|
function getFilteredRecords(aiTable, records, fields, activeView) {
|
449
523
|
const { conditions, condition_logical } = activeView.settings || {};
|
@@ -593,57 +667,34 @@ function buildFieldStatType(data, activeView) {
|
|
593
667
|
}
|
594
668
|
|
595
669
|
class GroupCalculator {
|
596
|
-
constructor(
|
670
|
+
constructor(aiTable, groups, collapseState) {
|
671
|
+
this.aiTable = aiTable;
|
597
672
|
this.groups = groups;
|
598
673
|
this.groupBreakpoints = new Map();
|
599
674
|
this.groupCollapseState = new Set(collapseState || []);
|
600
|
-
this.
|
675
|
+
this.fieldsMap = this.aiTable.fieldsMap();
|
601
676
|
}
|
602
|
-
calculateLinearRows(records
|
603
|
-
|
604
|
-
this.
|
605
|
-
return this.generateLinearRows(sortedRecords, fields);
|
606
|
-
}
|
607
|
-
sortRecordsByGroup(records, fields) {
|
608
|
-
const fieldsMap = new Map(fields.map((field) => [field._id, field]));
|
609
|
-
return [...records].sort((record1, record2) => {
|
610
|
-
return (this.groups.reduce((result, groupField) => {
|
611
|
-
if (result !== 0)
|
612
|
-
return result;
|
613
|
-
const field = fieldsMap.get(groupField.fieldId);
|
614
|
-
if (!field)
|
615
|
-
return 0;
|
616
|
-
const value1 = AITableQueries.getFieldValue(this.aiTable, [record1._id, field._id]);
|
617
|
-
const value2 = AITableQueries.getFieldValue(this.aiTable, [record2._id, field._id]);
|
618
|
-
const fieldModel = FieldModelMap[field.type];
|
619
|
-
if (!fieldModel)
|
620
|
-
return 0;
|
621
|
-
const compareResult = fieldModel.compare(value1, value2, this.aiTable.context.references(), undefined, {
|
622
|
-
aiTable: this.aiTable,
|
623
|
-
field
|
624
|
-
});
|
625
|
-
return compareResult * (groupField.desc ? -1 : 1);
|
626
|
-
}, 0) || 1);
|
627
|
-
});
|
677
|
+
calculateLinearRows(records) {
|
678
|
+
this.detectGroupBreakpoints(records);
|
679
|
+
return this.generateLinearRows(records);
|
628
680
|
}
|
629
681
|
// 检测断点
|
630
|
-
detectGroupBreakpoints(records
|
682
|
+
detectGroupBreakpoints(records) {
|
631
683
|
this.groupBreakpoints.clear();
|
632
684
|
if (records.length === 0)
|
633
685
|
return;
|
634
|
-
const fieldsMap = new Map(fields.map((field) => [field._id, field]));
|
635
686
|
let previousRecord = null;
|
636
687
|
records.forEach((record, index) => {
|
637
688
|
if (previousRecord === null) {
|
638
689
|
// 第一条记录,所有分组字段都是断点
|
639
690
|
this.groups.forEach((groupField) => {
|
640
|
-
this.addBreakpoint(groupField.
|
691
|
+
this.addBreakpoint(groupField.field_id, index);
|
641
692
|
});
|
642
693
|
}
|
643
694
|
else {
|
644
695
|
// 检查每个分组字段是否发生变化
|
645
696
|
this.groups.forEach((groupField, groupIndex) => {
|
646
|
-
const field = fieldsMap
|
697
|
+
const field = this.fieldsMap[groupField.field_id];
|
647
698
|
if (!field)
|
648
699
|
return;
|
649
700
|
const prevValue = AITableQueries.getFieldValue(this.aiTable, [previousRecord._id, field._id]);
|
@@ -658,7 +709,7 @@ class GroupCalculator {
|
|
658
709
|
if (compareResult !== 0) {
|
659
710
|
// 值发生变化,从当前层级开始的所有层级都是断点
|
660
711
|
for (let i = groupIndex; i < this.groups.length; i++) {
|
661
|
-
this.addBreakpoint(this.groups[i].
|
712
|
+
this.addBreakpoint(this.groups[i].field_id, index);
|
662
713
|
}
|
663
714
|
return;
|
664
715
|
}
|
@@ -678,9 +729,8 @@ class GroupCalculator {
|
|
678
729
|
}
|
679
730
|
}
|
680
731
|
// 生成GroupLinearRows
|
681
|
-
generateLinearRows(records
|
732
|
+
generateLinearRows(records) {
|
682
733
|
const linearRows = [];
|
683
|
-
const fieldsMap = new Map(fields.map((field) => [field._id, field]));
|
684
734
|
let lastGroupDepth = -1;
|
685
735
|
let currentGroupRecords = [];
|
686
736
|
let currentGroupIds = [];
|
@@ -693,7 +743,7 @@ class GroupCalculator {
|
|
693
743
|
});
|
694
744
|
records.forEach((record, index) => {
|
695
745
|
// 生成分组标签
|
696
|
-
const groupTabRows = this.generateGroupTabRows(record, index,
|
746
|
+
const groupTabRows = this.generateGroupTabRows(record, index, records.length);
|
697
747
|
if (groupTabRows.length > 0) {
|
698
748
|
// 如果有新的分组标签,先处理上一个分组的结束
|
699
749
|
if (currentGroupRecords.length > 0) {
|
@@ -740,7 +790,7 @@ class GroupCalculator {
|
|
740
790
|
let groupDisplayRowIndex = 0;
|
741
791
|
currentGroupRecords.forEach((record, i) => {
|
742
792
|
const recordIndex = currentGroupRecordIndices?.[i] ?? 0;
|
743
|
-
if (this.shouldShowRecord(
|
793
|
+
if (this.shouldShowRecord(recordIndex)) {
|
744
794
|
groupDisplayRowIndex++;
|
745
795
|
linearRows.push({
|
746
796
|
type: AITableRowType.record,
|
@@ -752,53 +802,71 @@ class GroupCalculator {
|
|
752
802
|
});
|
753
803
|
// 分组未折叠,为每个分组添加add新增行
|
754
804
|
if (currentGroupRecords.length > 0 && this.shouldShowAddRow(currentGroupIds)) {
|
805
|
+
let startRecordIndex = 0;
|
806
|
+
let endRecordIndex = 0;
|
807
|
+
if (currentGroupRecordIndices) {
|
808
|
+
// 当前添加按钮对于的记录范围
|
809
|
+
startRecordIndex = Math.min(...currentGroupRecordIndices);
|
810
|
+
endRecordIndex = Math.max(...currentGroupRecordIndices);
|
811
|
+
}
|
755
812
|
linearRows.push({
|
756
813
|
type: AITableRowType.add,
|
757
|
-
_id:
|
758
|
-
depth: this.groups.length
|
814
|
+
_id: nanoid(),
|
815
|
+
depth: this.groups.length,
|
816
|
+
range: [startRecordIndex, endRecordIndex]
|
759
817
|
});
|
760
818
|
}
|
761
819
|
}
|
762
820
|
// 生成分组标签
|
763
|
-
generateGroupTabRows(record, recordIndex,
|
821
|
+
generateGroupTabRows(record, recordIndex, totalRecords) {
|
764
822
|
const groupTabRows = [];
|
765
823
|
this.groups.forEach((groupField, depth) => {
|
766
|
-
const breakpoints = this.groupBreakpoints.get(groupField.
|
824
|
+
const breakpoints = this.groupBreakpoints.get(groupField.field_id) || [];
|
767
825
|
if (breakpoints.includes(recordIndex)) {
|
768
|
-
const field = fieldsMap
|
826
|
+
const field = this.fieldsMap[groupField.field_id];
|
769
827
|
if (!field)
|
770
828
|
return;
|
771
829
|
const groupValue = AITableQueries.getFieldValue(this.aiTable, [record._id, field._id]);
|
772
830
|
const breakpointIndex = breakpoints.indexOf(recordIndex);
|
773
|
-
const groupId = this.generateGroupId(groupField.
|
774
|
-
const
|
831
|
+
const groupId = this.generateGroupId(groupField.field_id, depth, breakpointIndex);
|
832
|
+
const recordRange = this.calculateGroupRecordRange(groupField.field_id, breakpointIndex, totalRecords);
|
775
833
|
groupTabRows.push({
|
776
834
|
type: AITableRowType.group,
|
777
835
|
_id: nanoid(),
|
778
836
|
depth,
|
779
|
-
fieldId: groupField.
|
837
|
+
fieldId: groupField.field_id,
|
780
838
|
groupValue,
|
781
839
|
isCollapsed: this.groupCollapseState.has(groupId),
|
782
|
-
|
840
|
+
range: recordRange,
|
783
841
|
groupId
|
784
842
|
});
|
785
843
|
}
|
786
844
|
});
|
787
845
|
return groupTabRows;
|
788
846
|
}
|
847
|
+
calculateGroupRecordRange(fieldId, breakpointIndex, totalRecords) {
|
848
|
+
const breakpoints = this.groupBreakpoints.get(fieldId) || [];
|
849
|
+
const startIndex = breakpoints[breakpointIndex] || 0;
|
850
|
+
let endIndex;
|
851
|
+
if (breakpointIndex + 1 < breakpoints.length) {
|
852
|
+
// 如果不是最后一个分组,结束位置是下一个断点的前一个位置
|
853
|
+
endIndex = breakpoints[breakpointIndex + 1] - 1;
|
854
|
+
}
|
855
|
+
else {
|
856
|
+
// 如果是最后一个分组,结束位置是最后一条记录
|
857
|
+
endIndex = totalRecords - 1;
|
858
|
+
}
|
859
|
+
return [startIndex, endIndex];
|
860
|
+
}
|
789
861
|
// 生成分组ID
|
790
862
|
generateGroupId(fieldId, depth, breakpointIndex) {
|
791
863
|
// 通过字段ID、深度和断点索引确保唯一
|
792
864
|
return `${fieldId}_${depth}_${breakpointIndex}`;
|
793
865
|
}
|
794
|
-
|
795
|
-
// TODO: 实现精确的分组记录数计算
|
796
|
-
return 1;
|
797
|
-
}
|
798
|
-
shouldShowRecord(_record, recordIndex) {
|
866
|
+
shouldShowRecord(recordIndex) {
|
799
867
|
for (let depth = 0; depth < this.groups.length; depth++) {
|
800
868
|
const groupField = this.groups[depth];
|
801
|
-
const breakpoints = this.groupBreakpoints.get(groupField.
|
869
|
+
const breakpoints = this.groupBreakpoints.get(groupField.field_id) || [];
|
802
870
|
// 找到当前记录所属的分组断点
|
803
871
|
let belongsToBreakpointIndex = -1;
|
804
872
|
for (let i = breakpoints.length - 1; i >= 0; i--) {
|
@@ -808,7 +876,7 @@ class GroupCalculator {
|
|
808
876
|
}
|
809
877
|
}
|
810
878
|
if (belongsToBreakpointIndex >= 0) {
|
811
|
-
const groupId = this.generateGroupId(groupField.
|
879
|
+
const groupId = this.generateGroupId(groupField.field_id, depth, belongsToBreakpointIndex);
|
812
880
|
if (this.groupCollapseState.has(groupId)) {
|
813
881
|
return false; // 父级分组被折叠,不显示记录
|
814
882
|
}
|
@@ -853,6 +921,28 @@ class GroupCalculator {
|
|
853
921
|
}
|
854
922
|
}
|
855
923
|
|
924
|
+
function getParentLinearRowGroups(aiTable, targetId) {
|
925
|
+
const linearRows = aiTable.context.linearRows();
|
926
|
+
const targetIndex = aiTable.context.visibleRowsIndexMap().get(targetId);
|
927
|
+
if (targetIndex === -1) {
|
928
|
+
return [];
|
929
|
+
}
|
930
|
+
const targetRow = linearRows[targetIndex];
|
931
|
+
const parentGroups = [];
|
932
|
+
let parentDepthPointer = targetRow.depth - 1;
|
933
|
+
for (let i = targetIndex - 1; i >= 0 && parentDepthPointer >= 0; i--) {
|
934
|
+
const row = linearRows[i];
|
935
|
+
if (row.type === AITableRowType.group) {
|
936
|
+
const rowDepth = row.depth || 0;
|
937
|
+
if (rowDepth <= parentDepthPointer) {
|
938
|
+
parentGroups.push(row);
|
939
|
+
parentDepthPointer--;
|
940
|
+
}
|
941
|
+
}
|
942
|
+
}
|
943
|
+
return parentGroups;
|
944
|
+
}
|
945
|
+
|
856
946
|
function buildRecordsByView(aiTable, records, fields, activeView, sortKeysMap) {
|
857
947
|
const filteredRecords = getFilteredRecords(aiTable, records, fields, activeView);
|
858
948
|
return getSortRecords(aiTable, filteredRecords, activeView, sortKeysMap);
|
@@ -861,14 +951,13 @@ function buildFieldsByView(aiTable, fields, activeView) {
|
|
861
951
|
const sortFields = getSortFields(aiTable, fields, activeView);
|
862
952
|
return buildFieldStatType(sortFields, activeView);
|
863
953
|
}
|
864
|
-
function buildGroupLinearRows(aiTable,
|
865
|
-
if (activeView?.settings?.groups?.length
|
954
|
+
function buildGroupLinearRows(aiTable, activeView, records) {
|
955
|
+
if (aiTable && activeView?.settings?.groups?.length) {
|
866
956
|
try {
|
867
957
|
const groups = activeView.settings?.groups;
|
868
|
-
const collapsedGroupIds = activeView.settings?.
|
869
|
-
const calculator = new GroupCalculator(
|
870
|
-
|
871
|
-
return calculator.calculateLinearRows(filteredRecords, fields);
|
958
|
+
const collapsedGroupIds = activeView.settings?.collapsed_group_ids;
|
959
|
+
const calculator = new GroupCalculator(aiTable, groups, collapsedGroupIds);
|
960
|
+
return calculator.calculateLinearRows(records);
|
872
961
|
}
|
873
962
|
catch (error) {
|
874
963
|
console.warn('Grouped build failed, using the default build method:', error);
|
@@ -1651,12 +1740,7 @@ function addRecord(aiTable, record) {
|
|
1651
1740
|
}
|
1652
1741
|
function addRecords$1(aiTable, records, options) {
|
1653
1742
|
const invalidFieldValues = [];
|
1654
|
-
const
|
1655
|
-
getSortRecords(aiTable, aiTable.records(), aiTable.views().find((item) => item._id === aiTable.activeViewId()));
|
1656
|
-
const targetIndex = options?.targetId
|
1657
|
-
? sortRecords.findIndex((item) => item._id === options.targetId)
|
1658
|
-
: options?.targetIndex || sortRecords.length - 1;
|
1659
|
-
const positions = createMultiplePositions(aiTable.views(), aiTable.activeViewId(), sortRecords, targetIndex, records.length, options?.isInsertBefore);
|
1743
|
+
const positions = getNewRecordsPosition(aiTable, options);
|
1660
1744
|
records.forEach((record, index) => {
|
1661
1745
|
Object.entries(record.values).every(([fieldId, value]) => {
|
1662
1746
|
const field = AITableQueries.getField(aiTable, [fieldId]);
|
@@ -1705,7 +1789,7 @@ function setViewGroup(aiTable, groups) {
|
|
1705
1789
|
const newSettings = {
|
1706
1790
|
...currentSettings,
|
1707
1791
|
groups: groups || [],
|
1708
|
-
|
1792
|
+
collapsed_group_ids: [] // 重置折叠
|
1709
1793
|
};
|
1710
1794
|
const operation = {
|
1711
1795
|
type: ActionName.SetView,
|
@@ -1723,7 +1807,7 @@ function setCollapsedGroup(aiTable, collapsedGroupIds) {
|
|
1723
1807
|
const currentSettings = view.settings || {};
|
1724
1808
|
const newSettings = {
|
1725
1809
|
...currentSettings,
|
1726
|
-
collapsedGroupIds
|
1810
|
+
collapsed_group_ids: collapsedGroupIds
|
1727
1811
|
};
|
1728
1812
|
const operation = {
|
1729
1813
|
type: ActionName.SetView,
|
@@ -1735,29 +1819,28 @@ function setCollapsedGroup(aiTable, collapsedGroupIds) {
|
|
1735
1819
|
}
|
1736
1820
|
// 折叠
|
1737
1821
|
function toggleGroupCollapse(aiTable, groupId) {
|
1738
|
-
const
|
1739
|
-
|
1740
|
-
if (!view)
|
1822
|
+
const activeView = aiTable.viewsMap()[aiTable.activeViewId()];
|
1823
|
+
if (!activeView)
|
1741
1824
|
return;
|
1742
|
-
const currentCollapse =
|
1825
|
+
const currentCollapse = activeView.settings?.collapsed_group_ids || [];
|
1743
1826
|
const newCollapse = currentCollapse.includes(groupId) ? currentCollapse.filter((id) => id !== groupId) : [...currentCollapse, groupId];
|
1744
1827
|
setCollapsedGroup(aiTable, newCollapse);
|
1745
1828
|
}
|
1746
1829
|
// 添加分组
|
1747
|
-
function addGroupField(aiTable, fieldId,
|
1748
|
-
const
|
1749
|
-
if (!
|
1830
|
+
function addGroupField(aiTable, fieldId, direction = SortDirection.ascending) {
|
1831
|
+
const activeView = aiTable.viewsMap()[aiTable.activeViewId()];
|
1832
|
+
if (!activeView)
|
1750
1833
|
return;
|
1751
|
-
const currentGroups =
|
1834
|
+
const currentGroups = activeView.settings?.groups || [];
|
1752
1835
|
// 是否已存在
|
1753
|
-
if (currentGroups.some((group) => group.
|
1836
|
+
if (currentGroups.some((group) => group.field_id === fieldId)) {
|
1754
1837
|
throw new Error('The field has been used for grouping.');
|
1755
1838
|
}
|
1756
1839
|
// 层级限制
|
1757
1840
|
if (currentGroups.length >= AI_TABLE_GROUP_MAX_LEVEL) {
|
1758
1841
|
throw new Error(`The maximum number of groups is ${AI_TABLE_GROUP_MAX_LEVEL}.`);
|
1759
1842
|
}
|
1760
|
-
const newGroups = [...currentGroups, { fieldId,
|
1843
|
+
const newGroups = [...currentGroups, { field_id: fieldId, direction }];
|
1761
1844
|
setViewGroup(aiTable, newGroups);
|
1762
1845
|
}
|
1763
1846
|
// 删除分组
|
@@ -1766,16 +1849,16 @@ function removeGroupField(aiTable, fieldId) {
|
|
1766
1849
|
if (!view)
|
1767
1850
|
return;
|
1768
1851
|
const currentGroups = view.settings?.groups || [];
|
1769
|
-
const newGroups = currentGroups.filter((group) => group.
|
1852
|
+
const newGroups = currentGroups.filter((group) => group.field_id !== fieldId);
|
1770
1853
|
setViewGroup(aiTable, newGroups.length > 0 ? newGroups : null);
|
1771
1854
|
}
|
1772
1855
|
// 更新排序方向
|
1773
|
-
function updateGroupFieldDirection(aiTable, fieldId,
|
1856
|
+
function updateGroupFieldDirection(aiTable, fieldId, direction) {
|
1774
1857
|
const view = aiTable.views().find((v) => v._id === aiTable.activeViewId());
|
1775
1858
|
if (!view)
|
1776
1859
|
return;
|
1777
1860
|
const currentGroups = view.settings?.groups || [];
|
1778
|
-
const newGroups = currentGroups.map((group) => (group.
|
1861
|
+
const newGroups = currentGroups.map((group) => (group.field_id === fieldId ? { ...group, direction } : group));
|
1779
1862
|
setViewGroup(aiTable, newGroups);
|
1780
1863
|
}
|
1781
1864
|
// 重新排序,拖拽顺序
|
@@ -1821,35 +1904,146 @@ function moveFields(aiTable, options) {
|
|
1821
1904
|
Actions.moveField(aiTable, path, newPath);
|
1822
1905
|
}
|
1823
1906
|
|
1824
|
-
function
|
1825
|
-
const
|
1907
|
+
function findNextRecordForTargetInOriginalRecords(aiTable, targetRecordId) {
|
1908
|
+
const viewId = aiTable.activeViewId();
|
1909
|
+
const records = aiTable.records();
|
1910
|
+
const recordsMap = aiTable.recordsMap();
|
1911
|
+
const targetRecord = recordsMap[targetRecordId];
|
1912
|
+
const targetPosition = targetRecord.positions[viewId] || 0;
|
1913
|
+
let nextRecord = null;
|
1914
|
+
for (const record of records) {
|
1915
|
+
const pos = record.positions[viewId] || 0;
|
1916
|
+
// 找到所有position大于目标position的记录中最小的
|
1917
|
+
if (pos > targetPosition && (nextRecord === null || pos < nextRecord.positions[viewId])) {
|
1918
|
+
nextRecord = record;
|
1919
|
+
}
|
1920
|
+
}
|
1921
|
+
return nextRecord;
|
1922
|
+
}
|
1923
|
+
function findPrevRecordForTargetInOriginalRecords(aiTable, targetRecordId) {
|
1924
|
+
const viewId = aiTable.activeViewId();
|
1925
|
+
const records = aiTable.records();
|
1926
|
+
const recordsMap = aiTable.recordsMap();
|
1927
|
+
const targetRecord = recordsMap[targetRecordId];
|
1928
|
+
const targetPosition = targetRecord.positions[viewId] || 0;
|
1929
|
+
let prevRecord = null;
|
1930
|
+
for (const record of records) {
|
1931
|
+
const pos = record.positions[viewId] || 0;
|
1932
|
+
// 找到所有position小于目标记录position的记录中最大的
|
1933
|
+
if (pos < targetPosition && (prevRecord === null || pos > prevRecord.positions[viewId])) {
|
1934
|
+
prevRecord = record;
|
1935
|
+
}
|
1936
|
+
}
|
1937
|
+
return prevRecord;
|
1938
|
+
}
|
1939
|
+
function getPositionByAfterOrBeforeRecordId(aiTable, options) {
|
1940
|
+
const recordsMap = aiTable.recordsMap();
|
1826
1941
|
const activeViewId = aiTable.activeViewId();
|
1827
|
-
const
|
1828
|
-
const {
|
1942
|
+
const originalRecords = aiTable.records();
|
1943
|
+
const { afterRecordId, beforeRecordId } = options;
|
1829
1944
|
let targetPosition = 0;
|
1830
1945
|
let prevPosition = 0;
|
1831
|
-
if (
|
1832
|
-
|
1833
|
-
|
1946
|
+
if (afterRecordId) {
|
1947
|
+
// 移动到指定记录之后
|
1948
|
+
const targetRecord = recordsMap[afterRecordId];
|
1949
|
+
if (!targetRecord) {
|
1950
|
+
throw new Error(`Target record with id ${afterRecordId} not found`);
|
1951
|
+
}
|
1952
|
+
prevPosition = targetRecord.positions[activeViewId] || 0;
|
1953
|
+
const nextPosition = findNextRecordForTargetInOriginalRecords(aiTable, afterRecordId);
|
1954
|
+
if (nextPosition !== null) {
|
1955
|
+
targetPosition = nextPosition.positions[activeViewId] || 0;
|
1956
|
+
}
|
1957
|
+
else {
|
1958
|
+
// 最后一个
|
1959
|
+
targetPosition = getMaxPosition(originalRecords, activeViewId) + 1;
|
1960
|
+
}
|
1834
1961
|
}
|
1835
|
-
else if (
|
1836
|
-
|
1837
|
-
|
1962
|
+
else if (beforeRecordId) {
|
1963
|
+
// 移动到指定记录之前
|
1964
|
+
const targetRecord = recordsMap[beforeRecordId];
|
1965
|
+
if (!targetRecord) {
|
1966
|
+
throw new Error(`Target record with id ${beforeRecordId} not found`);
|
1967
|
+
}
|
1968
|
+
targetPosition = targetRecord.positions[activeViewId] || 0;
|
1969
|
+
const previousPosition = findPrevRecordForTargetInOriginalRecords(aiTable, beforeRecordId);
|
1970
|
+
if (previousPosition !== null) {
|
1971
|
+
prevPosition = previousPosition.positions[activeViewId] || 0;
|
1972
|
+
}
|
1973
|
+
else {
|
1974
|
+
// 第一个
|
1975
|
+
prevPosition = targetPosition - 1;
|
1976
|
+
}
|
1838
1977
|
}
|
1839
1978
|
else {
|
1840
|
-
|
1841
|
-
prevPosition = gridRecords[newPath[0] - 1].positions[activeViewId];
|
1979
|
+
throw new Error('Either afterRecordId or beforeRecordId must be provided');
|
1842
1980
|
}
|
1843
|
-
|
1844
|
-
|
1981
|
+
return {
|
1982
|
+
targetPosition,
|
1983
|
+
prevPosition
|
1984
|
+
};
|
1985
|
+
}
|
1986
|
+
function getNewRecordsPosition(aiTable, options) {
|
1987
|
+
options = options || {};
|
1988
|
+
if (!options.afterRecordId && !options.beforeRecordId) {
|
1989
|
+
options.afterRecordId = aiTable.gridData().records[aiTable.gridData().records.length - 1]._id;
|
1990
|
+
}
|
1991
|
+
options.count = options.count || 1;
|
1992
|
+
const { targetPosition, prevPosition } = getPositionByAfterOrBeforeRecordId(aiTable, options);
|
1993
|
+
const interval = (targetPosition - prevPosition) / ((options.count || 1) + 1);
|
1994
|
+
const positionsOfItems = ___default.range(prevPosition + interval, targetPosition, interval);
|
1995
|
+
const views = aiTable.views();
|
1996
|
+
const activeViewId = aiTable.activeViewId();
|
1997
|
+
const viewsMaxPosition = {};
|
1998
|
+
views.forEach((view) => {
|
1999
|
+
viewsMaxPosition[view._id] = getMaxPosition(aiTable.records(), view._id);
|
2000
|
+
});
|
2001
|
+
const viewPositions = positionsOfItems.map((itemPositions) => {
|
2002
|
+
const viewPositions = {};
|
2003
|
+
views.forEach((view) => {
|
2004
|
+
if (view._id === activeViewId) {
|
2005
|
+
viewPositions[view._id] = itemPositions;
|
2006
|
+
}
|
2007
|
+
else {
|
2008
|
+
viewsMaxPosition[view._id] += 1;
|
2009
|
+
viewPositions[view._id] = viewsMaxPosition[view._id];
|
2010
|
+
}
|
2011
|
+
});
|
2012
|
+
return viewPositions;
|
2013
|
+
});
|
2014
|
+
return viewPositions;
|
2015
|
+
}
|
2016
|
+
function getParentGroupValuesByGroupId(aiTable, groupId) {
|
2017
|
+
const parentGroups = getParentLinearRowGroups(aiTable, groupId);
|
2018
|
+
return parentGroups.reduce((pre, cur) => {
|
2019
|
+
pre[cur.fieldId] = cur.groupValue;
|
2020
|
+
return pre;
|
2021
|
+
}, {});
|
2022
|
+
}
|
2023
|
+
|
2024
|
+
function moveRecords(aiTable, options, updatedInfo) {
|
2025
|
+
const activeViewId = aiTable.activeViewId();
|
2026
|
+
const activeView = aiTable.views().find((view) => view._id === activeViewId);
|
2027
|
+
const { recordIds, afterRecordId, beforeRecordId } = options;
|
2028
|
+
const originalRecords = aiTable.records();
|
2029
|
+
const recordsIndexMap = new Map(originalRecords.map((row, index) => [row._id, index]));
|
1845
2030
|
const sourceRecords = [];
|
1846
|
-
recordIds.forEach((
|
1847
|
-
const index = recordsIndexMap.get(
|
2031
|
+
recordIds.forEach((id) => {
|
2032
|
+
const index = recordsIndexMap.get(id);
|
1848
2033
|
if (index === undefined) {
|
1849
|
-
throw new Error(`Record with id ${
|
2034
|
+
throw new Error(`Record with id ${id} not found`);
|
1850
2035
|
}
|
1851
|
-
sourceRecords.push(
|
2036
|
+
sourceRecords.push(originalRecords[index]);
|
2037
|
+
});
|
2038
|
+
let { targetPosition, prevPosition } = getPositionByAfterOrBeforeRecordId(aiTable, {
|
2039
|
+
afterRecordId,
|
2040
|
+
beforeRecordId
|
1852
2041
|
});
|
2042
|
+
const groups = activeView.settings?.groups;
|
2043
|
+
let needCopyGroupValuesMap = null;
|
2044
|
+
if (groups?.length && (afterRecordId || beforeRecordId)) {
|
2045
|
+
needCopyGroupValuesMap = getParentGroupValuesByGroupId(aiTable, (afterRecordId || beforeRecordId));
|
2046
|
+
}
|
1853
2047
|
// 勾选多行顺序可能不一致,需要排序
|
1854
2048
|
const sortedSourceRecords = sortByViewPosition(sourceRecords, activeView);
|
1855
2049
|
let nextPosition = (prevPosition + targetPosition) / 2;
|
@@ -1858,6 +2052,16 @@ function moveRecords(aiTable, options, updatedInfo) {
|
|
1858
2052
|
if (sourceIndex === undefined) {
|
1859
2053
|
throw new Error(`Record with id ${record._id} not found`);
|
1860
2054
|
}
|
2055
|
+
if (groups?.length && needCopyGroupValuesMap) {
|
2056
|
+
const updateFieldValues = [];
|
2057
|
+
groups.forEach((group) => {
|
2058
|
+
updateFieldValues.push({
|
2059
|
+
path: [record._id, group.field_id],
|
2060
|
+
value: needCopyGroupValuesMap[group.field_id]
|
2061
|
+
});
|
2062
|
+
});
|
2063
|
+
Actions.updateFieldValues(aiTable, updateFieldValues);
|
2064
|
+
}
|
1861
2065
|
Actions.setRecordPositions(aiTable, { [activeViewId]: nextPosition }, [sourceIndex]);
|
1862
2066
|
prevPosition = nextPosition;
|
1863
2067
|
nextPosition = (prevPosition + targetPosition) / 2;
|
@@ -1899,6 +2103,10 @@ const buildRemoveFieldItem = (aiTable, getUpdatedInfo) => {
|
|
1899
2103
|
|
1900
2104
|
function addRecords(aiTable, trackableEntity, options) {
|
1901
2105
|
options = options || {};
|
2106
|
+
const newRecords = [];
|
2107
|
+
const activeViewId = aiTable.activeViewId();
|
2108
|
+
const activeView = aiTable.viewsMap()[activeViewId];
|
2109
|
+
const groups = activeView.settings?.groups;
|
1902
2110
|
let { originId, isDuplicate, count = 1 } = options;
|
1903
2111
|
const recordCount = aiTable.records().length;
|
1904
2112
|
const maxRecordCount = aiTable.context?.maxRecords();
|
@@ -1906,14 +2114,31 @@ function addRecords(aiTable, trackableEntity, options) {
|
|
1906
2114
|
count = maxRecordCount - recordCount;
|
1907
2115
|
options.count = count;
|
1908
2116
|
}
|
1909
|
-
const activeView = aiTable.viewsMap()[aiTable.activeViewId()];
|
1910
2117
|
const newRecordIds = idsCreator(count);
|
1911
2118
|
const newRecordShortIds = shortIdsCreator(count);
|
1912
2119
|
const newRecordValues = getDefaultRecordValues(aiTable, isDuplicate, originId);
|
1913
|
-
const newRecords = [];
|
1914
2120
|
const hiddenRecordIds = [];
|
2121
|
+
let needCopyGroupValuesMap = null;
|
2122
|
+
if (groups?.length && options.forGroupId) {
|
2123
|
+
needCopyGroupValuesMap = getParentGroupValuesByGroupId(aiTable, options.forGroupId);
|
2124
|
+
}
|
2125
|
+
const records = aiTable.gridData().records;
|
1915
2126
|
newRecordIds.forEach((id, index) => {
|
1916
|
-
const record = {
|
2127
|
+
const record = {
|
2128
|
+
_id: id,
|
2129
|
+
short_id: newRecordShortIds[index],
|
2130
|
+
values: newRecordValues,
|
2131
|
+
...trackableEntity,
|
2132
|
+
positions: {
|
2133
|
+
[activeViewId]: getMaxPosition(records, activeViewId) + 1
|
2134
|
+
}
|
2135
|
+
};
|
2136
|
+
if (needCopyGroupValuesMap) {
|
2137
|
+
groups?.forEach((group) => {
|
2138
|
+
// 复制分组字段值
|
2139
|
+
record.values[group.field_id] = needCopyGroupValuesMap[group.field_id];
|
2140
|
+
});
|
2141
|
+
}
|
1917
2142
|
const checkResult = checkConditions(aiTable, aiTable.fields(), record);
|
1918
2143
|
if (!checkResult) {
|
1919
2144
|
hiddenRecordIds.push(id);
|
@@ -1926,9 +2151,10 @@ function addRecords(aiTable, trackableEntity, options) {
|
|
1926
2151
|
});
|
1927
2152
|
}
|
1928
2153
|
Actions.addRecords(aiTable, newRecords, options);
|
1929
|
-
const recentAddRecord = options.
|
2154
|
+
const recentAddRecord = options.beforeRecordId ? newRecords[newRecords.length - 1] : newRecords[0];
|
1930
2155
|
const activeRecordId = recentAddRecord._id;
|
1931
2156
|
const activeFieldId = aiTable.gridData().fields[0]._id;
|
2157
|
+
closeExpendCell(aiTable);
|
1932
2158
|
setSelection(aiTable, {
|
1933
2159
|
selectedRecords: new Set([]),
|
1934
2160
|
selectedFields: new Set([]),
|
@@ -2150,11 +2376,16 @@ const InsertUpwardRecords = (aiTable, actions) => {
|
|
2150
2376
|
count: 1,
|
2151
2377
|
exec: (aiTable, targetName, position, notifyService, count) => {
|
2152
2378
|
let selectedRecordIds = AITable.getActiveRecordIds(aiTable);
|
2153
|
-
|
2154
|
-
|
2155
|
-
|
2156
|
-
|
2157
|
-
|
2379
|
+
const aiViewTable = aiTable;
|
2380
|
+
const activeView = aiViewTable.viewsMap()[aiViewTable.activeViewId()];
|
2381
|
+
const addRecordOptions = {
|
2382
|
+
beforeRecordId: selectedRecordIds[0],
|
2383
|
+
count
|
2384
|
+
};
|
2385
|
+
if (activeView?.settings?.groups?.length) {
|
2386
|
+
addRecordOptions.forGroupId = selectedRecordIds[0];
|
2387
|
+
}
|
2388
|
+
actions.addRecord(addRecordOptions);
|
2158
2389
|
}
|
2159
2390
|
};
|
2160
2391
|
};
|
@@ -2168,10 +2399,16 @@ const InsertDownwardRecords = (aiTable, actions) => {
|
|
2168
2399
|
isInputNumber: true,
|
2169
2400
|
exec: (aiTable, targetName, position, notifyService, count) => {
|
2170
2401
|
let selectedRecordIds = AITable.getActiveRecordIds(aiTable);
|
2171
|
-
|
2172
|
-
|
2402
|
+
const aiViewTable = aiTable;
|
2403
|
+
const activeView = aiViewTable.viewsMap()[aiViewTable.activeViewId()];
|
2404
|
+
const addRecordOptions = {
|
2405
|
+
afterRecordId: selectedRecordIds[0],
|
2173
2406
|
count
|
2174
|
-
}
|
2407
|
+
};
|
2408
|
+
if (activeView?.settings?.groups?.length) {
|
2409
|
+
addRecordOptions.forGroupId = selectedRecordIds[0];
|
2410
|
+
}
|
2411
|
+
actions.addRecord(addRecordOptions);
|
2175
2412
|
}
|
2176
2413
|
};
|
2177
2414
|
};
|
@@ -2222,5 +2459,5 @@ const VIEW_ACTIONS = [ActionName.SetView, ActionName.AddView, ActionName.RemoveV
|
|
2222
2459
|
* Generated bundle index. Do not edit.
|
2223
2460
|
*/
|
2224
2461
|
|
2225
|
-
export { AITableStateI18nKey, AITableStateI18nText, Actions, CopyCellsItem, CopyFieldPropertyItem, DividerMenuItem, EditFieldPropertyItem, FLUSHING, GroupCalculator, InsertDownwardRecords, InsertUpwardRecords, PasteCellsItem, RemoveRecordsItem, UndoManagerService, VIEW_ACTIONS, YjsAITable, actionMappers, addFields, addRecords, addView, applyActionOps, applyActions, applyEvents, applyYjsEvents, buildFieldsByView, buildGroupLinearRows, buildRecordsByView, buildRemoveFieldItem, buildSetFieldAction, buildSetRecordPositionsActon, calculateAdaptiveFrozenColumnCount, checkConditions, createMultiplePositions, createPositions, createSharedType, doFilter, freezeToThisColumn, generateCopyName, getDataBySharedType, getDefaultI18nTextByKey, getDefaultRecordDataByFilter, getDefaultRecordValues, getFieldPositionInView, getFieldsSizeMap, getFilteredRecords, getFrozenFieldId, getMaxPosition, getPosition, getPositions, getRecordsBySharedJson, getSharedTypeByData, getSortFields, getSortRecords, getStateI18nTextByKey, isPathEqual, moveFields, moveRecords, removeView, restoreDefaultFrozenColumn, sortRecordsBySortInfo, sortViews, toSharedType, translateYjsEvent, updateFieldAndValues, updateFieldValues, withState };
|
2462
|
+
export { AITableStateI18nKey, AITableStateI18nText, Actions, CopyCellsItem, CopyFieldPropertyItem, DividerMenuItem, EditFieldPropertyItem, FLUSHING, GroupCalculator, InsertDownwardRecords, InsertUpwardRecords, PasteCellsItem, RemoveRecordsItem, UndoManagerService, VIEW_ACTIONS, YjsAITable, actionMappers, addFields, addRecords, addView, applyActionOps, applyActions, applyEvents, applyYjsEvents, buildFieldsByView, buildGroupLinearRows, buildRecordsByView, buildRemoveFieldItem, buildSetFieldAction, buildSetRecordPositionsActon, calculateAdaptiveFrozenColumnCount, checkConditions, createMultiplePositions, createPositions, createSharedType, doFilter, findNextRecordForTargetInOriginalRecords, findPrevRecordForTargetInOriginalRecords, freezeToThisColumn, generateCopyName, getDataBySharedType, getDefaultI18nTextByKey, getDefaultRecordDataByFilter, getDefaultRecordValues, getFieldPositionInView, getFieldsSizeMap, getFilteredRecords, getFrozenFieldId, getMaxPosition, getNewRecordsPosition, getParentGroupValuesByGroupId, getParentLinearRowGroups, getPosition, getPositionByAfterOrBeforeRecordId, getPositions, getRecordsBySharedJson, getSharedTypeByData, getSortFields, getSortRecords, getStateI18nTextByKey, isPathEqual, moveFields, moveRecords, removeView, restoreDefaultFrozenColumn, sortRecordsBySortInfo, sortViews, toSharedType, translateYjsEvent, updateFieldAndValues, updateFieldValues, withState };
|
2226
2463
|
//# sourceMappingURL=ai-table-state.mjs.map
|