From e4a44ec48910341edd4e74ac05fbc113d3addf10 Mon Sep 17 00:00:00 2001
From: huanhuanwa <2323666215@qq.com>
Date: Mon, 5 Aug 2024 11:42:51 +0800
Subject: [PATCH] fix: adjust code
---
src/app/app.routes.ts | 22 ++---
src/app/component/basic/basic.component.html | 9 --
src/app/component/basic/basic.component.ts | 35 --------
.../basic/table/table.component.html | 16 ----
.../component/basic/table/table.component.ts | 15 ----
.../content/content.component.html} | 1 -
.../content.component.ts} | 87 +++++++++----------
.../component/share/table/table.component.ts | 69 ---------------
...re.component.html => table.component.html} | 0
.../share.component.ts => table.component.ts} | 24 ++---
src/app/service/table.service.ts | 50 +++++------
src/app/share/shared.ts | 33 ++-----
src/app/share/utils/translate-to-table.ts | 21 ++---
src/app/utils/utils.ts | 6 +-
14 files changed, 96 insertions(+), 292 deletions(-)
delete mode 100644 src/app/component/basic/basic.component.html
delete mode 100644 src/app/component/basic/basic.component.ts
delete mode 100644 src/app/component/basic/table/table.component.html
delete mode 100644 src/app/component/basic/table/table.component.ts
rename src/app/component/{share/table/table.component.html => common/content/content.component.html} (99%)
rename src/app/component/common/{table.component.ts => content/content.component.ts} (71%)
delete mode 100644 src/app/component/share/table/table.component.ts
rename src/app/component/{share/share.component.html => table.component.html} (100%)
rename src/app/component/{share/share.component.ts => table.component.ts} (62%)
diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts
index 6531edda..81bcb6c6 100644
--- a/src/app/app.routes.ts
+++ b/src/app/app.routes.ts
@@ -1,29 +1,17 @@
import { Routes } from '@angular/router';
-import { BasicComponent } from './component/basic/basic.component';
-import { ShareComponent } from './component/share/share.component';
-import { TableComponent } from './component/basic/table/table.component';
-import { ShareTableComponent } from './component/share/table/table.component';
+import { DemoTableContent } from './component/common/content/content.component';
+import { DemoTable } from './component/table.component';
export const routes: Routes = [
- {
- path: 'share',
- component: ShareComponent,
- children:[
- {
- path: ':viewId',
- component: ShareTableComponent,
- }
- ]
- },
{
path: '',
- component: BasicComponent,
+ component: DemoTable,
children:[
{
path: ':viewId',
- component: TableComponent,
+ component: DemoTableContent,
}
]
- },
+ }
];
diff --git a/src/app/component/basic/basic.component.html b/src/app/component/basic/basic.component.html
deleted file mode 100644
index 51c98079..00000000
--- a/src/app/component/basic/basic.component.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
- @for (item of tableService.views(); track $index) {
-
- @if (item.isActive) {
-
- }
-
- }
-
diff --git a/src/app/component/basic/basic.component.ts b/src/app/component/basic/basic.component.ts
deleted file mode 100644
index b498d386..00000000
--- a/src/app/component/basic/basic.component.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { Component, inject, OnInit } from '@angular/core';
-import { Router, RouterOutlet } from '@angular/router';
-import { AITableGrid } from '@ai-table/grid';
-import { ThyAction } from 'ngx-tethys/action';
-import { ThyTabs, ThyTab } from 'ngx-tethys/tabs';
-import { ThyPopoverModule } from 'ngx-tethys/popover';
-import { TableService } from '../../service/table.service';
-
-const initViews = [
- { id: 'view1', name: '表格视图1', isActive: true },
- { id: 'view2', name: '表格视图2' }
-];
-
-@Component({
- selector: 'ai-table-basic',
- standalone: true,
- imports: [RouterOutlet, AITableGrid, ThyAction, ThyTabs, ThyTab, ThyPopoverModule],
- templateUrl: './basic.component.html',
- providers: [TableService]
-})
-export class BasicComponent implements OnInit {
- router = inject(Router);
-
- tableService = inject(TableService);
-
- ngOnInit(): void {
- this.tableService.initViews(initViews);
- this.router.navigate(['/view1']);
- }
-
- activeTabChange(data: any) {
- this.tableService.updateActiveView(data);
- this.router.navigateByUrl(`/${this.tableService.activeView().id}`);
- }
-}
diff --git a/src/app/component/basic/table/table.component.html b/src/app/component/basic/table/table.component.html
deleted file mode 100644
index 90691847..00000000
--- a/src/app/component/basic/table/table.component.html
+++ /dev/null
@@ -1,16 +0,0 @@
-@if (tableService.activeView()) {
-
-
-
-}
\ No newline at end of file
diff --git a/src/app/component/basic/table/table.component.ts b/src/app/component/basic/table/table.component.ts
deleted file mode 100644
index 7f3b232d..00000000
--- a/src/app/component/basic/table/table.component.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { AITableGrid } from '@ai-table/grid';
-import { Component } from '@angular/core';
-import { RouterOutlet } from '@angular/router';
-import { ThyAction } from 'ngx-tethys/action';
-import { ThyPopoverModule } from 'ngx-tethys/popover';
-import { CommonTableComponent } from '../../common/table.component';
-import { FieldPropertyEditor } from '../../common/field-property-editor/field-property-editor.component';
-
-@Component({
- selector: 'ai-table-demo',
- standalone: true,
- imports: [RouterOutlet, CommonTableComponent, AITableGrid, ThyPopoverModule, FieldPropertyEditor, ThyAction],
- templateUrl: './table.component.html'
-})
-export class TableComponent extends CommonTableComponent {}
diff --git a/src/app/component/share/table/table.component.html b/src/app/component/common/content/content.component.html
similarity index 99%
rename from src/app/component/share/table/table.component.html
rename to src/app/component/common/content/content.component.html
index bb75d8fa..2daae67d 100644
--- a/src/app/component/share/table/table.component.html
+++ b/src/app/component/common/content/content.component.html
@@ -4,7 +4,6 @@
移动选中行到第三行
移动选中列到第三列
-
;
-
- fields!: WritableSignal;
-
+export class DemoTableContent {
aiTable!: AITable;
plugins = [withCustomApply];
@@ -86,10 +84,14 @@ export class CommonTableComponent implements OnInit, AfterViewInit {
}
ngOnInit(): void {
- const value = getDefaultValue();
- const { records, fields } = getSortFieldsAndRecordsByPositions(value.records, value.fields, this.tableService.activeView().id);
- this.records = signal(records);
- this.fields = signal(fields);
+ if (this.tableService.sharedType) {
+ this.tableService.buildRenderRecords();
+ this.tableService.buildRenderFields();
+ } else {
+ const value = getDefaultValue();
+ this.tableService.buildRenderRecords(value.records);
+ this.tableService.buildRenderFields(value.fields);
+ }
console.time('render');
}
@@ -102,7 +104,14 @@ export class CommonTableComponent implements OnInit, AfterViewInit {
}
onChange(data: AITableChangeOptions) {
- this.setPositions(data.actions);
+ // TODO:获取当前的 view 和 path,转换为 sharedType 中原数据的 path
+ if (this.tableService.sharedType) {
+ if (!YjsAITable.isRemote(this.aiTable) && !YjsAITable.isUndo(this.aiTable)) {
+ YjsAITable.asLocal(this.aiTable, () => {
+ applyActionOps(this.tableService.sharedType!, data.actions, this.aiTable);
+ });
+ }
+ }
}
prevent(event: Event) {
@@ -113,17 +122,7 @@ export class CommonTableComponent implements OnInit, AfterViewInit {
aiTableInitialized(aiTable: AITable) {
this.aiTable = aiTable;
(this.aiTable as AIViewTable).views = this.tableService.views;
- }
-
- setPositions(actions: AITableAction[]) {
- if (actions.some((item) => UpdateRecordTypes.includes(item.type))) {
- const records = setActiveViewPositions(this.records(), this.tableService.activeView().id) as DemoAIRecord[];
- this.records.set(records);
- }
- if (actions.some((item) => UpdateFieldTypes.includes(item.type))) {
- const fields = setActiveViewPositions(this.fields(), this.tableService.activeView().id) as DemoAIField[];
- this.fields.set(fields);
- }
+ this.tableService.setAITable(aiTable);
}
removeRecord() {
diff --git a/src/app/component/share/table/table.component.ts b/src/app/component/share/table/table.component.ts
deleted file mode 100644
index b784b45f..00000000
--- a/src/app/component/share/table/table.component.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { AITable, AITableAction, AITableChangeOptions, AITableGrid } from '@ai-table/grid';
-import { Component, inject } from '@angular/core';
-import { RouterOutlet } from '@angular/router';
-import { ThyAction } from 'ngx-tethys/action';
-import { ThyPopoverModule } from 'ngx-tethys/popover';
-import { CommonTableComponent } from '../../common/table.component';
-import { FieldPropertyEditor } from '../../common/field-property-editor/field-property-editor.component';
-import applyActionOps from '../../../share/apply-to-yjs';
-import { YjsAITable } from '../../../share/yjs-table';
-import { FormsModule } from '@angular/forms';
-import { ThyInputDirective } from 'ngx-tethys/input';
-import { setActiveViewPositions } from '../../../utils/utils';
-import { DemoAIField, DemoAIRecord, UpdateFieldTypes, UpdateRecordTypes } from '../../../types';
-import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
-import { TableService } from '../../../service/table.service';
-
-@Component({
- selector: 'ai-share-table-demo',
- standalone: true,
- imports: [
- RouterOutlet,
- CommonTableComponent,
- AITableGrid,
- ThyPopoverModule,
- FieldPropertyEditor,
- ThyAction,
- FormsModule,
- ThyInputDirective
- ],
- templateUrl: './table.component.html'
-})
-export class ShareTableComponent extends CommonTableComponent {
- takeUntilDestroyed = takeUntilDestroyed();
-
- override ngOnInit(): void {
- this.tableService.activeViewChange$.pipe(this.takeUntilDestroyed).subscribe(() => {
- this.tableService.setRecords();
- this.tableService.setFields();
- });
- console.time('render');
- }
-
- override aiTableInitialized(aiTable: AITable) {
- super.aiTableInitialized(aiTable);
- this.tableService.setAITable(aiTable);
- }
-
- override setPositions(actions: AITableAction[]) {
- if (actions.some((item) => UpdateRecordTypes.includes(item.type))) {
- const records = setActiveViewPositions(this.tableService.records(), this.tableService.activeView().id) as DemoAIRecord[];
- this.tableService.setRecords(records);
- }
- if (actions.some((item) => UpdateFieldTypes.includes(item.type))) {
- const fields = setActiveViewPositions(this.tableService.fields(), this.tableService.activeView().id) as DemoAIField[];
- this.tableService.setFields(fields);
- }
- }
-
- override onChange(data: AITableChangeOptions) {
- this.setPositions(data.actions);
- if (this.tableService.sharedType) {
- if (!YjsAITable.isRemote(this.aiTable) && !YjsAITable.isUndo(this.aiTable)) {
- YjsAITable.asLocal(this.aiTable, () => {
- applyActionOps(this.tableService.sharedType!, data.actions, this.aiTable);
- });
- }
- }
- }
-}
diff --git a/src/app/component/share/share.component.html b/src/app/component/table.component.html
similarity index 100%
rename from src/app/component/share/share.component.html
rename to src/app/component/table.component.html
diff --git a/src/app/component/share/share.component.ts b/src/app/component/table.component.ts
similarity index 62%
rename from src/app/component/share/share.component.ts
rename to src/app/component/table.component.ts
index 1085f3da..30734dff 100644
--- a/src/app/component/share/share.component.ts
+++ b/src/app/component/table.component.ts
@@ -6,10 +6,8 @@ import { AITableGrid } from '@ai-table/grid';
import { FormsModule } from '@angular/forms';
import { ThyPopoverModule } from 'ngx-tethys/popover';
import { ThyTabs, ThyTab } from 'ngx-tethys/tabs';
-import { DemoAIRecord, DemoAIField } from '../../types';
import { ThyInputDirective } from 'ngx-tethys/input';
-import { getDefaultValue } from '../../utils/utils';
-import { TableService } from '../../service/table.service';
+import { TableService } from '../service/table.service';
const initViews = [
{ id: 'view1', name: '表格视图1', isActive: true },
@@ -17,35 +15,29 @@ const initViews = [
];
@Component({
- selector: 'ai-table-share',
+ selector: 'demo-ai-table',
standalone: true,
imports: [RouterOutlet, AITableGrid, ThyAction, ThyTabs, ThyTab, ThyPopoverModule, FormsModule, ThyInputDirective],
- templateUrl: './share.component.html',
+ templateUrl: './table.component.html',
providers: [TableService]
})
-export class ShareComponent implements OnInit, OnDestroy {
+export class DemoTable implements OnInit, OnDestroy {
provider!: WebsocketProvider | null;
- room = 'share-room-1';
-
- records!: WritableSignal;
-
- fields!: WritableSignal;
+ room = 'share-room-2';
router = inject(Router);
tableService = inject(TableService);
ngOnInit(): void {
- this.router.navigate(['/share/view1']);
- this.tableService.initViews(initViews);
- const value = getDefaultValue();
- this.tableService.initRecordsAndFields(value.records, value.fields);
+ this.router.navigate(['/view1']);
+ this.tableService.initData(initViews);
}
activeTabChange(data: any) {
this.tableService.updateActiveView(data);
- this.router.navigateByUrl(`/share/${this.tableService.activeView().id}`);
+ this.router.navigateByUrl(`/${this.tableService.activeView().id}`);
}
handleShared() {
diff --git a/src/app/service/table.service.ts b/src/app/service/table.service.ts
index 4d98b4db..06cbcc48 100644
--- a/src/app/service/table.service.ts
+++ b/src/app/service/table.service.ts
@@ -3,12 +3,11 @@ import { createSharedType, initSharedType, SharedType } from '../share/shared';
import { WebsocketProvider } from 'y-websocket';
import { getProvider } from '../share/provider';
import { DemoAIField, DemoAIRecord } from '../types';
-import { sortDataByPositions } from '../utils/utils';
+import { getDefaultValue, sortDataByView } from '../utils/utils';
import { applyYjsEvents } from '../share/apply-to-table';
import { translateSharedTypeToTable } from '../share/utils/translate-to-table';
import { YjsAITable } from '../share/yjs-table';
import { AITable } from '@ai-table/grid';
-import { Subject } from 'rxjs';
import { AITableView } from '../types/view';
@Injectable()
@@ -26,45 +25,37 @@ export class TableService {
sharedType!: SharedType | null;
activeView = computed(() => {
- const activeView = this.views().find((view) => view?.isActive) as AITableView;
- return activeView;
+ return this.views().find((view) => view?.isActive) as AITableView;
});
- activeViewChange$ = new Subject();
-
-
- initViews(views: AITableView[]) {
+ initData(views: AITableView[]) {
this.views = signal(views);
}
updateActiveView(activeViewId: string) {
this.views.update((value) => {
- const result = value.map((item) => {
- return {
- ...item,
- isActive: item.id === activeViewId
- };
+ value.forEach((item) => {
+ if (item.isActive && item.id !== activeViewId) {
+ item.isActive = false;
+ }
+ if (!item.isActive && item.id === activeViewId) {
+ item.isActive = true;
+ }
});
- return result;
+ return [...value];
});
- this.activeViewChange$.next(this.activeView());
}
setAITable(aiTable: AITable) {
this.aiTable = aiTable;
}
- initRecordsAndFields(records: DemoAIRecord[], fields: DemoAIField[]) {
- this.records = signal(sortDataByPositions(records, this.activeView().id) as DemoAIRecord[]);
- this.fields = signal(sortDataByPositions(fields, this.activeView().id) as DemoAIField[]);
- }
-
- setRecords(records?: DemoAIRecord[]) {
- this.records.set(sortDataByPositions(records ?? this.records(), this.activeView().id) as DemoAIRecord[]);
+ buildRenderRecords(records?: DemoAIRecord[]) {
+ this.records = signal(sortDataByView(records ?? this.records(), this.activeView().id) as DemoAIRecord[]);
}
- setFields(fields?: DemoAIField[]) {
- this.fields.set(sortDataByPositions(fields ?? this.fields(), this.activeView().id) as DemoAIField[]);
+ buildRenderFields(fields?: DemoAIField[]) {
+ this.fields = signal(sortDataByView(fields ?? this.fields(), this.activeView().id) as DemoAIField[]);
}
handleShared(room: string) {
@@ -79,9 +70,9 @@ export class TableService {
this.sharedType.observeDeep((events: any) => {
if (!YjsAITable.isLocal(this.aiTable)) {
if (!isInitialized) {
- const data = translateSharedTypeToTable(this.sharedType!, this.views());
- this.records.set(data.records);
- this.fields.set(data.fields);
+ const data = translateSharedTypeToTable(this.sharedType!);
+ this.buildRenderRecords(data.records);
+ this.buildRenderFields(data.fields);
isInitialized = true;
} else {
applyYjsEvents(this.aiTable, events);
@@ -94,9 +85,10 @@ export class TableService {
this.provider.once('synced', () => {
if (this.provider!.synced && [...this.sharedType!.doc!.store.clients.keys()].length === 0) {
console.log('init shared type');
+ const value = getDefaultValue();
initSharedType(this.sharedType!.doc!, {
- records: this.records(),
- fields: this.fields()
+ records: value.records,
+ fields: value.fields
});
}
});
diff --git a/src/app/share/shared.ts b/src/app/share/shared.ts
index d0e43f71..64d744c5 100644
--- a/src/app/share/shared.ts
+++ b/src/app/share/shared.ts
@@ -1,13 +1,12 @@
import { isArray, isObject } from 'ngx-tethys/util';
import * as Y from 'yjs';
-import { DemoAIField, DemoAIRecord } from '../types';
+import { DemoAIField, DemoAIRecord, Positions } from '../types';
export type SyncMapElement = Y.Map;
export type SyncArrayElement = Y.Array>;
export type SyncElement = Y.Array;
export type SharedType = Y.Map;
-
export const createSharedType = () => {
const doc = new Y.Doc();
const sharedType = doc.getMap('ai-table');
@@ -19,7 +18,7 @@ export const initSharedType = (
initializeValue: {
fields: DemoAIField[];
records: DemoAIRecord[];
- },
+ }
) => {
const sharedType = doc.getMap('ai-table');
toSharedType(sharedType, initializeValue);
@@ -43,24 +42,6 @@ export function toSharedType(
});
}
-
-
-// export function toSharedType(
-// sharedType: Y.Map,
-// data: {
-// fields: DemoAIField[];
-// records: DemoAIRecord[];
-// }
-// ): void {
-// const fieldSharedType = new Y.Array();
-// sharedType.set('fields', fieldSharedType);
-// fieldSharedType.insert(0, data.fields.map(toSyncElement));
-
-// const recordSharedType = new Y.Array>();
-// sharedType.set('records', recordSharedType);
-// recordSharedType.insert(0, data.records.map(toRecordSyncElement));
-// }
-
export function toSyncElement(node: any): SyncMapElement {
const element: SyncMapElement = new Y.Map();
for (const key in node) {
@@ -91,15 +72,17 @@ export function toRecordSyncElement(record: DemoAIRecord): Y.Array>
}
customFieldArray.insert(0, customFields);
- const positionArray = new Y.Array();
+ const positionsArray: Y.Array = new Y.Array();
const positions = [];
for (const viewId in record['positions']) {
- positions.push(record['positions'][viewId]);
+ positions.push({
+ [viewId]: record['positions'][viewId]
+ });
}
- positionArray.insert(0, positions);
+ positionsArray.insert(0, positions);
// To save memory, convert map to array.
const element = new Y.Array>();
- element.insert(0, [fixedFieldArray, customFieldArray, positionArray]);
+ element.insert(0, [fixedFieldArray, customFieldArray, positionsArray]);
return element;
}
diff --git a/src/app/share/utils/translate-to-table.ts b/src/app/share/utils/translate-to-table.ts
index c4664b70..5756eb9d 100644
--- a/src/app/share/utils/translate-to-table.ts
+++ b/src/app/share/utils/translate-to-table.ts
@@ -1,7 +1,6 @@
import { AITableFields, Path } from '@ai-table/grid';
import { SharedType } from '../shared';
import { DemoAIField, DemoAIRecord } from '../../types';
-import { AITableView } from '../../types/view';
export const translateRecord = (arrayRecord: any[], fields: AITableFields) => {
const fieldIds = fields.map((item) => item.id);
@@ -12,27 +11,23 @@ export const translateRecord = (arrayRecord: any[], fields: AITableFields) => {
return recordValue;
};
-export const translatePositions = (arrayPositions: any[], views: AITableView[]) => {
- const viewIds = views.map((item) => item.id);
- const positions: Record = {};
- viewIds.forEach((item, index) => {
- positions[item] = arrayPositions[index] || 0;
- });
- return positions;
+export const translatePositions = (arrayPositions: any[]) => {
+ return arrayPositions.reduce((acc, obj) => {
+ const key = Object.keys(obj)[0];
+ acc[key] = obj[key];
+ return acc;
+ }, {});
};
-
-export const translateSharedTypeToTable = (sharedType: SharedType, views: AITableView[]) => {
+export const translateSharedTypeToTable = (sharedType: SharedType) => {
const data = sharedType.toJSON();
const fields: DemoAIField[] = data['fields'];
- // TODO: views 支持协同后移除传入
- // const views: AITableView[] = data['fields'];
const records: DemoAIRecord[] = data['records'].map((record: any) => {
const [fixedField, customField, positions] = record;
return {
id: fixedField[0],
values: translateRecord(customField, fields),
- positions: translatePositions(positions, views),
+ positions: translatePositions(positions)
};
});
return {
diff --git a/src/app/utils/utils.ts b/src/app/utils/utils.ts
index b12bb1ac..5eddcc9e 100644
--- a/src/app/utils/utils.ts
+++ b/src/app/utils/utils.ts
@@ -2,7 +2,7 @@ import { AITableFieldType } from '@ai-table/grid';
import { DemoAIField, DemoAIRecord } from '../types';
const LOCAL_STORAGE_KEY = 'ai-table-data';
-export function sortDataByPositions(data: DemoAIRecord[] | DemoAIField[], activeViewId: string) {
+export function sortDataByView(data: DemoAIRecord[] | DemoAIField[], activeViewId: string) {
const hasPositions = data.every((item) => item.positions && item.positions);
if (hasPositions) {
return [...data].sort((a, b) => a.positions[activeViewId] - b.positions[activeViewId]);
@@ -11,8 +11,8 @@ export function sortDataByPositions(data: DemoAIRecord[] | DemoAIField[], active
}
export function getSortFieldsAndRecordsByPositions(records: DemoAIRecord[], fields: DemoAIField[], activeViewId: string) {
- const newRecords = sortDataByPositions(records, activeViewId) as DemoAIRecord[];
- const newFields = sortDataByPositions(fields, activeViewId) as DemoAIField[];
+ const newRecords = sortDataByView(records, activeViewId) as DemoAIRecord[];
+ const newFields = sortDataByView(fields, activeViewId) as DemoAIField[];
return {
records: newRecords,
fields: newFields