@ai-table/state 0.1.40 → 0.1.41
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 +22 -0
- package/action/group.d.ts.map +1 -0
- package/action/index.d.ts +8 -0
- package/action/index.d.ts.map +1 -1
- package/fesm2022/ai-table-state.mjs +392 -3
- package/fesm2022/ai-table-state.mjs.map +1 -1
- package/package.json +1 -1
- package/utils/build.d.ts +1 -0
- package/utils/build.d.ts.map +1 -1
- package/utils/group/group-calculator.d.ts +23 -0
- package/utils/group/group-calculator.d.ts.map +1 -0
- package/utils/group/index.d.ts +2 -0
- package/utils/group/index.d.ts.map +1 -0
- package/utils/index.d.ts +1 -0
- package/utils/index.d.ts.map +1 -1
@@ -0,0 +1,22 @@
|
|
1
|
+
import { AITableGroups } from '@ai-table/utils';
|
2
|
+
import { AIViewTable } from '../types/ai-table';
|
3
|
+
declare function setViewGroup(aiTable: AIViewTable, groups: AITableGroups | null): void;
|
4
|
+
declare function setCollapsedGroup(aiTable: AIViewTable, collapsedGroupIds: string[]): void;
|
5
|
+
declare function toggleGroupCollapse(aiTable: AIViewTable, groupId: string): void;
|
6
|
+
declare function addGroupField(aiTable: AIViewTable, fieldId: string, desc?: boolean): void;
|
7
|
+
declare function removeGroupField(aiTable: AIViewTable, fieldId: string): void;
|
8
|
+
declare function updateGroupFieldDirection(aiTable: AIViewTable, fieldId: string, desc: boolean): void;
|
9
|
+
declare function reorderGroupFields(aiTable: AIViewTable, fromIndex: number, toIndex: number): void;
|
10
|
+
declare function clearAllGroups(aiTable: AIViewTable): void;
|
11
|
+
export declare const GroupActions: {
|
12
|
+
setViewGroup: typeof setViewGroup;
|
13
|
+
setCollapsedGroup: typeof setCollapsedGroup;
|
14
|
+
toggleGroupCollapse: typeof toggleGroupCollapse;
|
15
|
+
addGroupField: typeof addGroupField;
|
16
|
+
removeGroupField: typeof removeGroupField;
|
17
|
+
updateGroupFieldDirection: typeof updateGroupFieldDirection;
|
18
|
+
reorderGroupFields: typeof reorderGroupFields;
|
19
|
+
clearAllGroups: typeof clearAllGroups;
|
20
|
+
};
|
21
|
+
export {};
|
22
|
+
//# sourceMappingURL=group.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../../packages/state/src/action/group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA0C,MAAM,iBAAiB,CAAC;AACxF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,iBAAS,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,QAmBvE;AAED,iBAAS,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAkB3E;AAGD,iBAAS,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,QASjE;AAGD,iBAAS,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,OAAe,QAkBlF;AAGD,iBAAS,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,QAQ9D;AAGD,iBAAS,yBAAyB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,QAQtF;AAGD,iBAAS,kBAAkB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,QAenF;AAGD,iBAAS,cAAc,CAAC,OAAO,EAAE,WAAW,QAE3C;AAED,eAAO,MAAM,YAAY;;;;;;;;;CASxB,CAAC"}
|
package/action/index.d.ts
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
export declare const Actions: {
|
2
|
+
setViewGroup: (aiTable: import("@ai-table/state").AIViewTable, groups: import("@ai-table/utils").AITableGroups | null) => void;
|
3
|
+
setCollapsedGroup: (aiTable: import("@ai-table/state").AIViewTable, collapsedGroupIds: string[]) => void;
|
4
|
+
toggleGroupCollapse: (aiTable: import("@ai-table/state").AIViewTable, groupId: string) => void;
|
5
|
+
addGroupField: (aiTable: import("@ai-table/state").AIViewTable, fieldId: string, desc?: boolean) => void;
|
6
|
+
removeGroupField: (aiTable: import("@ai-table/state").AIViewTable, fieldId: string) => void;
|
7
|
+
updateGroupFieldDirection: (aiTable: import("@ai-table/state").AIViewTable, fieldId: string, desc: boolean) => void;
|
8
|
+
reorderGroupFields: (aiTable: import("@ai-table/state").AIViewTable, fromIndex: number, toIndex: number) => void;
|
9
|
+
clearAllGroups: (aiTable: import("@ai-table/state").AIViewTable) => void;
|
2
10
|
setRecordPositions: typeof import("./position").setRecordPositions;
|
3
11
|
setView: (aiTable: import("@ai-table/state").AIViewTable, value: Partial<import("@ai-table/utils").AITableView>, path: [string]) => void;
|
4
12
|
addView: (aiTable: import("@ai-table/state").AIViewTable, originId: string, newView: import("@ai-table/utils").AITableView, isDuplicate?: boolean) => void;
|
package/action/index.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../packages/state/src/action/index.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../packages/state/src/action/index.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;CAOnB,CAAC;AAEF,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC"}
|
@@ -3,7 +3,8 @@ import { UndoManager } from 'yjs';
|
|
3
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, sortByViewPosition, AITableFilterLogical, AITableFilterOperation, AITableFieldType, isEmpty, 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, AITable, getColumnIndicesSizeMap, shortIdCreator, generateNewName, getDefaultFieldValue, 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, setSelection, AI_TABLE_GRID_FIELD_SERVICE_MAP, clearSelection, buildClipboardData, writeToClipboard, getI18nTextByKey, AITableGridI18nKey, isMac, writeToAITable } from '@ai-table/grid';
|
7
|
+
import { nanoid } from 'nanoid';
|
7
8
|
import * as _ from 'lodash';
|
8
9
|
import ___default from 'lodash';
|
9
10
|
import { createDraft, finishDraft } from 'immer';
|
@@ -591,6 +592,267 @@ function buildFieldStatType(data, activeView) {
|
|
591
592
|
});
|
592
593
|
}
|
593
594
|
|
595
|
+
class GroupCalculator {
|
596
|
+
constructor(groups, aiTable, collapseState) {
|
597
|
+
this.groups = groups;
|
598
|
+
this.groupBreakpoints = new Map();
|
599
|
+
this.groupCollapseState = new Set(collapseState || []);
|
600
|
+
this.aiTable = aiTable;
|
601
|
+
}
|
602
|
+
calculateLinearRows(records, fields) {
|
603
|
+
const sortedRecords = this.sortRecordsByGroup(records, fields);
|
604
|
+
this.detectGroupBreakpoints(sortedRecords, fields);
|
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
|
+
});
|
628
|
+
}
|
629
|
+
// 检测断点
|
630
|
+
detectGroupBreakpoints(records, fields) {
|
631
|
+
this.groupBreakpoints.clear();
|
632
|
+
if (records.length === 0)
|
633
|
+
return;
|
634
|
+
const fieldsMap = new Map(fields.map((field) => [field._id, field]));
|
635
|
+
let previousRecord = null;
|
636
|
+
records.forEach((record, index) => {
|
637
|
+
if (previousRecord === null) {
|
638
|
+
// 第一条记录,所有分组字段都是断点
|
639
|
+
this.groups.forEach((groupField) => {
|
640
|
+
this.addBreakpoint(groupField.fieldId, index);
|
641
|
+
});
|
642
|
+
}
|
643
|
+
else {
|
644
|
+
// 检查每个分组字段是否发生变化
|
645
|
+
this.groups.forEach((groupField, groupIndex) => {
|
646
|
+
const field = fieldsMap.get(groupField.fieldId);
|
647
|
+
if (!field)
|
648
|
+
return;
|
649
|
+
const prevValue = AITableQueries.getFieldValue(this.aiTable, [previousRecord._id, field._id]);
|
650
|
+
const currValue = AITableQueries.getFieldValue(this.aiTable, [record._id, field._id]);
|
651
|
+
const fieldModel = FieldModelMap[field.type];
|
652
|
+
if (!fieldModel)
|
653
|
+
return;
|
654
|
+
const compareResult = fieldModel.compare(prevValue, currValue, this.aiTable.context.references(), undefined, {
|
655
|
+
aiTable: this.aiTable,
|
656
|
+
field
|
657
|
+
});
|
658
|
+
if (compareResult !== 0) {
|
659
|
+
// 值发生变化,从当前层级开始的所有层级都是断点
|
660
|
+
for (let i = groupIndex; i < this.groups.length; i++) {
|
661
|
+
this.addBreakpoint(this.groups[i].fieldId, index);
|
662
|
+
}
|
663
|
+
return;
|
664
|
+
}
|
665
|
+
});
|
666
|
+
}
|
667
|
+
previousRecord = record;
|
668
|
+
});
|
669
|
+
}
|
670
|
+
// 添加断点
|
671
|
+
addBreakpoint(fieldId, recordIndex) {
|
672
|
+
if (!this.groupBreakpoints.has(fieldId)) {
|
673
|
+
this.groupBreakpoints.set(fieldId, []);
|
674
|
+
}
|
675
|
+
const breakpoints = this.groupBreakpoints.get(fieldId);
|
676
|
+
if (!breakpoints.includes(recordIndex)) {
|
677
|
+
breakpoints.push(recordIndex);
|
678
|
+
}
|
679
|
+
}
|
680
|
+
// 生成GroupLinearRows
|
681
|
+
generateLinearRows(records, fields) {
|
682
|
+
const linearRows = [];
|
683
|
+
const fieldsMap = new Map(fields.map((field) => [field._id, field]));
|
684
|
+
let lastGroupDepth = -1;
|
685
|
+
let currentGroupRecords = [];
|
686
|
+
let currentGroupIds = [];
|
687
|
+
let currentGroupRecordIndices = []; // 记录当前分组中每个记录的原始索引
|
688
|
+
// 开始添加一个空白行
|
689
|
+
linearRows.push({
|
690
|
+
type: AITableRowType.blank,
|
691
|
+
_id: nanoid(),
|
692
|
+
depth: 0
|
693
|
+
});
|
694
|
+
records.forEach((record, index) => {
|
695
|
+
// 生成分组标签
|
696
|
+
const groupTabRows = this.generateGroupTabRows(record, index, fieldsMap);
|
697
|
+
if (groupTabRows.length > 0) {
|
698
|
+
// 如果有新的分组标签,先处理上一个分组的结束
|
699
|
+
if (currentGroupRecords.length > 0) {
|
700
|
+
this.handleGroupEnd(currentGroupRecords, linearRows, currentGroupIds, currentGroupRecordIndices);
|
701
|
+
currentGroupRecords = [];
|
702
|
+
currentGroupRecordIndices = [];
|
703
|
+
}
|
704
|
+
currentGroupIds = groupTabRows.map((row) => row.groupId);
|
705
|
+
const depths = groupTabRows.filter((d) => d.depth !== undefined).map((d) => d.depth);
|
706
|
+
const minDepth = depths.length > 0 ? Math.min(...depths) : 0;
|
707
|
+
// 如果当前分组的最小深度小于等于上一个分组的深度,说明是同级或上级分组,需添加空白行
|
708
|
+
if (lastGroupDepth >= 0 && minDepth <= lastGroupDepth) {
|
709
|
+
linearRows.push({
|
710
|
+
type: AITableRowType.blank,
|
711
|
+
_id: nanoid(),
|
712
|
+
depth: minDepth
|
713
|
+
});
|
714
|
+
}
|
715
|
+
// 只添加未被父级折叠的分组
|
716
|
+
const visibleGroupTabRows = this.filterVisibleGroupTabs(groupTabRows);
|
717
|
+
linearRows.push(...visibleGroupTabRows);
|
718
|
+
lastGroupDepth = depths.length > 0 ? Math.max(...depths) : 0;
|
719
|
+
}
|
720
|
+
// 将记录添加到当前分组
|
721
|
+
currentGroupRecords.push(record);
|
722
|
+
currentGroupRecordIndices.push(index);
|
723
|
+
});
|
724
|
+
// 处理最后一个分组
|
725
|
+
if (currentGroupRecords.length > 0) {
|
726
|
+
this.handleGroupEnd(currentGroupRecords, linearRows, currentGroupIds, currentGroupRecordIndices);
|
727
|
+
}
|
728
|
+
// 添加分组结束的空白行
|
729
|
+
if (lastGroupDepth >= 0) {
|
730
|
+
linearRows.push({
|
731
|
+
type: AITableRowType.blank,
|
732
|
+
_id: nanoid(),
|
733
|
+
depth: 0
|
734
|
+
});
|
735
|
+
}
|
736
|
+
return linearRows;
|
737
|
+
}
|
738
|
+
handleGroupEnd(currentGroupRecords, linearRows, currentGroupIds, currentGroupRecordIndices) {
|
739
|
+
// 分组结束时添加该分组的记录和add行
|
740
|
+
let groupDisplayRowIndex = 0;
|
741
|
+
currentGroupRecords.forEach((record, i) => {
|
742
|
+
const recordIndex = currentGroupRecordIndices?.[i] ?? 0;
|
743
|
+
if (this.shouldShowRecord(record, recordIndex)) {
|
744
|
+
groupDisplayRowIndex++;
|
745
|
+
linearRows.push({
|
746
|
+
type: AITableRowType.record,
|
747
|
+
_id: record._id,
|
748
|
+
displayIndex: groupDisplayRowIndex,
|
749
|
+
depth: this.groups.length
|
750
|
+
});
|
751
|
+
}
|
752
|
+
});
|
753
|
+
// 分组未折叠,为每个分组添加add新增行
|
754
|
+
if (currentGroupRecords.length > 0 && this.shouldShowAddRow(currentGroupIds)) {
|
755
|
+
linearRows.push({
|
756
|
+
type: AITableRowType.add,
|
757
|
+
_id: '',
|
758
|
+
depth: this.groups.length
|
759
|
+
});
|
760
|
+
}
|
761
|
+
}
|
762
|
+
// 生成分组标签
|
763
|
+
generateGroupTabRows(record, recordIndex, fieldsMap) {
|
764
|
+
const groupTabRows = [];
|
765
|
+
this.groups.forEach((groupField, depth) => {
|
766
|
+
const breakpoints = this.groupBreakpoints.get(groupField.fieldId) || [];
|
767
|
+
if (breakpoints.includes(recordIndex)) {
|
768
|
+
const field = fieldsMap.get(groupField.fieldId);
|
769
|
+
if (!field)
|
770
|
+
return;
|
771
|
+
const groupValue = AITableQueries.getFieldValue(this.aiTable, [record._id, field._id]);
|
772
|
+
const breakpointIndex = breakpoints.indexOf(recordIndex);
|
773
|
+
const groupId = this.generateGroupId(groupField.fieldId, depth, breakpointIndex);
|
774
|
+
const recordCount = this.calculateGroupRecordCount(record, recordIndex, depth);
|
775
|
+
groupTabRows.push({
|
776
|
+
type: AITableRowType.group,
|
777
|
+
_id: nanoid(),
|
778
|
+
depth,
|
779
|
+
fieldId: groupField.fieldId,
|
780
|
+
groupValue,
|
781
|
+
isCollapsed: this.groupCollapseState.has(groupId),
|
782
|
+
recordCount,
|
783
|
+
groupId
|
784
|
+
});
|
785
|
+
}
|
786
|
+
});
|
787
|
+
return groupTabRows;
|
788
|
+
}
|
789
|
+
// 生成分组ID
|
790
|
+
generateGroupId(fieldId, depth, breakpointIndex) {
|
791
|
+
// 通过字段ID、深度和断点索引确保唯一
|
792
|
+
return `${fieldId}_${depth}_${breakpointIndex}`;
|
793
|
+
}
|
794
|
+
calculateGroupRecordCount(_record, _recordIndex, _depth) {
|
795
|
+
// TODO: 实现精确的分组记录数计算
|
796
|
+
return 1;
|
797
|
+
}
|
798
|
+
shouldShowRecord(_record, recordIndex) {
|
799
|
+
for (let depth = 0; depth < this.groups.length; depth++) {
|
800
|
+
const groupField = this.groups[depth];
|
801
|
+
const breakpoints = this.groupBreakpoints.get(groupField.fieldId) || [];
|
802
|
+
// 找到当前记录所属的分组断点
|
803
|
+
let belongsToBreakpointIndex = -1;
|
804
|
+
for (let i = breakpoints.length - 1; i >= 0; i--) {
|
805
|
+
if (breakpoints[i] <= recordIndex) {
|
806
|
+
belongsToBreakpointIndex = i;
|
807
|
+
break;
|
808
|
+
}
|
809
|
+
}
|
810
|
+
if (belongsToBreakpointIndex >= 0) {
|
811
|
+
const groupId = this.generateGroupId(groupField.fieldId, depth, belongsToBreakpointIndex);
|
812
|
+
if (this.groupCollapseState.has(groupId)) {
|
813
|
+
return false; // 父级分组被折叠,不显示记录
|
814
|
+
}
|
815
|
+
}
|
816
|
+
}
|
817
|
+
return true;
|
818
|
+
}
|
819
|
+
// 检查当前分组是否应该显示添加行
|
820
|
+
shouldShowAddRow(currentGroupIds) {
|
821
|
+
if (!currentGroupIds || currentGroupIds.length === 0) {
|
822
|
+
return true; // 默认显示
|
823
|
+
}
|
824
|
+
// 检查当前组的所有分组层级是否都展开
|
825
|
+
for (const groupId of currentGroupIds) {
|
826
|
+
if (this.groupCollapseState.has(groupId)) {
|
827
|
+
return false; // 有层级被折叠,不显示添加行
|
828
|
+
}
|
829
|
+
}
|
830
|
+
return true;
|
831
|
+
}
|
832
|
+
// 过滤可见的分组标签
|
833
|
+
filterVisibleGroupTabs(groupTabRows) {
|
834
|
+
const visibleRows = [];
|
835
|
+
for (let i = 0; i < groupTabRows.length; i++) {
|
836
|
+
const currentRow = groupTabRows[i];
|
837
|
+
let show = true;
|
838
|
+
// 检查当前分组标签的所有父级是否都展开
|
839
|
+
const currentDepth = currentRow.depth ?? 0;
|
840
|
+
for (let parentDepth = 0; parentDepth < currentDepth; parentDepth++) {
|
841
|
+
// 找到同一记录索引下的父级分组ID
|
842
|
+
const parentRow = groupTabRows.find((row) => row.depth === parentDepth);
|
843
|
+
if (parentRow && this.groupCollapseState.has(parentRow.groupId)) {
|
844
|
+
show = false;
|
845
|
+
break;
|
846
|
+
}
|
847
|
+
}
|
848
|
+
if (show) {
|
849
|
+
visibleRows.push(currentRow);
|
850
|
+
}
|
851
|
+
}
|
852
|
+
return visibleRows;
|
853
|
+
}
|
854
|
+
}
|
855
|
+
|
594
856
|
function buildRecordsByView(aiTable, records, fields, activeView, sortKeysMap) {
|
595
857
|
const filteredRecords = getFilteredRecords(aiTable, records, fields, activeView);
|
596
858
|
return getSortRecords(aiTable, filteredRecords, activeView, sortKeysMap);
|
@@ -599,6 +861,21 @@ function buildFieldsByView(aiTable, fields, activeView) {
|
|
599
861
|
const sortFields = getSortFields(aiTable, fields, activeView);
|
600
862
|
return buildFieldStatType(sortFields, activeView);
|
601
863
|
}
|
864
|
+
function buildGroupLinearRows(aiTable, records, fields, activeView) {
|
865
|
+
if (activeView?.settings?.groups?.length && fields && aiTable) {
|
866
|
+
try {
|
867
|
+
const groups = activeView.settings?.groups;
|
868
|
+
const collapsedGroupIds = activeView.settings?.collapsedGroupIds;
|
869
|
+
const calculator = new GroupCalculator(groups, aiTable, collapsedGroupIds);
|
870
|
+
const filteredRecords = getFilteredRecords(aiTable, records, fields, activeView);
|
871
|
+
return calculator.calculateLinearRows(filteredRecords, fields);
|
872
|
+
}
|
873
|
+
catch (error) {
|
874
|
+
console.warn('Grouped build failed, using the default build method:', error);
|
875
|
+
}
|
876
|
+
}
|
877
|
+
return null;
|
878
|
+
}
|
602
879
|
|
603
880
|
function setView(aiTable, value, path) {
|
604
881
|
const view = aiTable.views().find((item) => item._id === path[0]);
|
@@ -1419,12 +1696,124 @@ const RecordActions = {
|
|
1419
1696
|
updateSystemFieldValues
|
1420
1697
|
};
|
1421
1698
|
|
1699
|
+
function setViewGroup(aiTable, groups) {
|
1700
|
+
const viewId = aiTable.activeViewId();
|
1701
|
+
const view = aiTable.views().find((v) => v._id === viewId);
|
1702
|
+
if (!view)
|
1703
|
+
return;
|
1704
|
+
const currentSettings = view.settings || {};
|
1705
|
+
const newSettings = {
|
1706
|
+
...currentSettings,
|
1707
|
+
groups: groups || [],
|
1708
|
+
collapsedGroupIds: [] // 重置折叠
|
1709
|
+
};
|
1710
|
+
const operation = {
|
1711
|
+
type: ActionName.SetView,
|
1712
|
+
properties: { settings: currentSettings },
|
1713
|
+
newProperties: { settings: newSettings },
|
1714
|
+
path: [viewId]
|
1715
|
+
};
|
1716
|
+
aiTable.apply(operation);
|
1717
|
+
}
|
1718
|
+
function setCollapsedGroup(aiTable, collapsedGroupIds) {
|
1719
|
+
const viewId = aiTable.activeViewId();
|
1720
|
+
const view = aiTable.views().find((v) => v._id === viewId);
|
1721
|
+
if (!view)
|
1722
|
+
return;
|
1723
|
+
const currentSettings = view.settings || {};
|
1724
|
+
const newSettings = {
|
1725
|
+
...currentSettings,
|
1726
|
+
collapsedGroupIds
|
1727
|
+
};
|
1728
|
+
const operation = {
|
1729
|
+
type: ActionName.SetView,
|
1730
|
+
properties: { settings: currentSettings },
|
1731
|
+
newProperties: { settings: newSettings },
|
1732
|
+
path: [viewId]
|
1733
|
+
};
|
1734
|
+
aiTable.apply(operation);
|
1735
|
+
}
|
1736
|
+
// 折叠
|
1737
|
+
function toggleGroupCollapse(aiTable, groupId) {
|
1738
|
+
const viewId = aiTable.activeViewId();
|
1739
|
+
const view = aiTable.views().find((v) => v._id === viewId);
|
1740
|
+
if (!view)
|
1741
|
+
return;
|
1742
|
+
const currentCollapse = view.settings?.collapsedGroupIds || [];
|
1743
|
+
const newCollapse = currentCollapse.includes(groupId) ? currentCollapse.filter((id) => id !== groupId) : [...currentCollapse, groupId];
|
1744
|
+
setCollapsedGroup(aiTable, newCollapse);
|
1745
|
+
}
|
1746
|
+
// 添加分组
|
1747
|
+
function addGroupField(aiTable, fieldId, desc = false) {
|
1748
|
+
const view = aiTable.views().find((v) => v._id === aiTable.activeViewId());
|
1749
|
+
if (!view)
|
1750
|
+
return;
|
1751
|
+
const currentGroups = view.settings?.groups || [];
|
1752
|
+
// 是否已存在
|
1753
|
+
if (currentGroups.some((group) => group.fieldId === fieldId)) {
|
1754
|
+
throw new Error('The field has been used for grouping.');
|
1755
|
+
}
|
1756
|
+
// 层级限制
|
1757
|
+
if (currentGroups.length >= AI_TABLE_GROUP_MAX_LEVEL) {
|
1758
|
+
throw new Error(`The maximum number of groups is ${AI_TABLE_GROUP_MAX_LEVEL}.`);
|
1759
|
+
}
|
1760
|
+
const newGroups = [...currentGroups, { fieldId, desc }];
|
1761
|
+
setViewGroup(aiTable, newGroups);
|
1762
|
+
}
|
1763
|
+
// 删除分组
|
1764
|
+
function removeGroupField(aiTable, fieldId) {
|
1765
|
+
const view = aiTable.views().find((v) => v._id === aiTable.activeViewId());
|
1766
|
+
if (!view)
|
1767
|
+
return;
|
1768
|
+
const currentGroups = view.settings?.groups || [];
|
1769
|
+
const newGroups = currentGroups.filter((group) => group.fieldId !== fieldId);
|
1770
|
+
setViewGroup(aiTable, newGroups.length > 0 ? newGroups : null);
|
1771
|
+
}
|
1772
|
+
// 更新排序方向
|
1773
|
+
function updateGroupFieldDirection(aiTable, fieldId, desc) {
|
1774
|
+
const view = aiTable.views().find((v) => v._id === aiTable.activeViewId());
|
1775
|
+
if (!view)
|
1776
|
+
return;
|
1777
|
+
const currentGroups = view.settings?.groups || [];
|
1778
|
+
const newGroups = currentGroups.map((group) => (group.fieldId === fieldId ? { ...group, desc } : group));
|
1779
|
+
setViewGroup(aiTable, newGroups);
|
1780
|
+
}
|
1781
|
+
// 重新排序,拖拽顺序
|
1782
|
+
function reorderGroupFields(aiTable, fromIndex, toIndex) {
|
1783
|
+
const view = aiTable.views().find((v) => v._id === aiTable.activeViewId());
|
1784
|
+
if (!view)
|
1785
|
+
return;
|
1786
|
+
const currentGroups = view.settings?.groups || [];
|
1787
|
+
if (fromIndex < 0 || fromIndex >= currentGroups.length || toIndex < 0 || toIndex >= currentGroups.length) {
|
1788
|
+
return;
|
1789
|
+
}
|
1790
|
+
const newGroups = [...currentGroups];
|
1791
|
+
const [movedItem] = newGroups.splice(fromIndex, 1);
|
1792
|
+
newGroups.splice(toIndex, 0, movedItem);
|
1793
|
+
setViewGroup(aiTable, newGroups);
|
1794
|
+
}
|
1795
|
+
// 清空分组
|
1796
|
+
function clearAllGroups(aiTable) {
|
1797
|
+
setViewGroup(aiTable, null);
|
1798
|
+
}
|
1799
|
+
const GroupActions = {
|
1800
|
+
setViewGroup,
|
1801
|
+
setCollapsedGroup,
|
1802
|
+
toggleGroupCollapse,
|
1803
|
+
addGroupField,
|
1804
|
+
removeGroupField,
|
1805
|
+
updateGroupFieldDirection,
|
1806
|
+
reorderGroupFields,
|
1807
|
+
clearAllGroups
|
1808
|
+
};
|
1809
|
+
|
1422
1810
|
const Actions = {
|
1423
1811
|
...GeneralActions,
|
1424
1812
|
...RecordActions,
|
1425
1813
|
...FieldActions,
|
1426
1814
|
...ViewActions,
|
1427
|
-
...PositionsActions
|
1815
|
+
...PositionsActions,
|
1816
|
+
...GroupActions
|
1428
1817
|
};
|
1429
1818
|
|
1430
1819
|
function moveFields(aiTable, options) {
|
@@ -1833,5 +2222,5 @@ const VIEW_ACTIONS = [ActionName.SetView, ActionName.AddView, ActionName.RemoveV
|
|
1833
2222
|
* Generated bundle index. Do not edit.
|
1834
2223
|
*/
|
1835
2224
|
|
1836
|
-
export { AITableStateI18nKey, AITableStateI18nText, Actions, CopyCellsItem, CopyFieldPropertyItem, DividerMenuItem, EditFieldPropertyItem, FLUSHING, InsertDownwardRecords, InsertUpwardRecords, PasteCellsItem, RemoveRecordsItem, UndoManagerService, VIEW_ACTIONS, YjsAITable, actionMappers, addFields, addRecords, addView, applyActionOps, applyActions, applyEvents, applyYjsEvents, buildFieldsByView, 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 };
|
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 };
|
1837
2226
|
//# sourceMappingURL=ai-table-state.mjs.map
|