diff --git a/packages/grid/src/components/cell-editors/single-select/single-select-editor.component.ts b/packages/grid/src/components/cell-editors/select/select-editor.component.ts similarity index 80% rename from packages/grid/src/components/cell-editors/single-select/single-select-editor.component.ts rename to packages/grid/src/components/cell-editors/select/select-editor.component.ts index 4202170f..18bfc22b 100644 --- a/packages/grid/src/components/cell-editors/single-select/single-select-editor.component.ts +++ b/packages/grid/src/components/cell-editors/select/select-editor.component.ts @@ -1,5 +1,5 @@ import { NgForOf, NgIf } from '@angular/common'; -import { ChangeDetectionStrategy, Component, computed } from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, Input } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { ThySelect } from 'ngx-tethys/select'; import { AbstractEditCellEditor } from '../abstract-cell-editor.component'; @@ -8,7 +8,7 @@ import { ThyIcon } from 'ngx-tethys/icon'; import { ThyOption } from 'ngx-tethys/shared'; import { AITableSelectOption, AITableField } from '../../../core'; -export interface AITableSingleSelectField extends AITableField { +export interface AITableSingleSelectField extends AITableField { options: AITableSelectOption[]; } @@ -24,7 +24,9 @@ export interface AITableSingleSelectField extends AITableField { }, imports: [NgIf, NgForOf, FormsModule, ThySelect, ThyOption, ThyTag, ThyIcon] }) -export class SingleSelectCellEditorComponent extends AbstractEditCellEditor { +export class SelectCellEditorComponent extends AbstractEditCellEditor { + @Input() isMultiple!: boolean; + selectOptions = computed(() => { return this.field().options; }); diff --git a/packages/grid/src/constants/editor.ts b/packages/grid/src/constants/editor.ts index c360888e..7d035506 100644 --- a/packages/grid/src/constants/editor.ts +++ b/packages/grid/src/constants/editor.ts @@ -1,16 +1,16 @@ import { AITableFieldType } from '../core'; -import { SingleSelectCellEditorComponent } from '../components/cell-editors/single-select/single-select-editor.component'; import { TextCellEditorComponent } from '../components/cell-editors/text/text-editor.component'; import { NumberCellEditorComponent } from '../components/cell-editors/number/number-editor.component'; import { DateTimeCellEditorComponent } from '../components/cell-editors/date-time/date-time-editor.component'; import { RatingCellEditorComponent } from '../components/cell-editors/rating/rating-editor.component'; import { LinkCellEditorComponent } from '../components/cell-editors/link/number-editor.component'; +import { SelectCellEditorComponent } from '../components/cell-editors/select/select-editor.component'; -export const GRID_CELL_EDITOR_MAP: Record = { - [AITableFieldType.Text]: TextCellEditorComponent, - [AITableFieldType.SingleSelect]: SingleSelectCellEditorComponent, - [AITableFieldType.Number]: NumberCellEditorComponent, - [AITableFieldType.DateTime]: DateTimeCellEditorComponent, - [AITableFieldType.Rating]: RatingCellEditorComponent, - [AITableFieldType.Link]: LinkCellEditorComponent +export const GRID_CELL_EDITOR_MAP: Partial> = { + [AITableFieldType.text]: TextCellEditorComponent, + [AITableFieldType.select]: SelectCellEditorComponent, + [AITableFieldType.number]: NumberCellEditorComponent, + [AITableFieldType.date]: DateTimeCellEditorComponent, + [AITableFieldType.rate]: RatingCellEditorComponent, + [AITableFieldType.link]: LinkCellEditorComponent }; diff --git a/packages/grid/src/constants/grid.ts b/packages/grid/src/constants/grid.ts index a91945cf..caeb3db1 100644 --- a/packages/grid/src/constants/grid.ts +++ b/packages/grid/src/constants/grid.ts @@ -5,10 +5,10 @@ export const DEFAULT_COLUMN_WIDTH = 200; export const MIN_COLUMN_WIDTH = 80; export const DBL_CLICK_EDIT_TYPE = [ - AITableFieldType.Text, - AITableFieldType.Number, - AITableFieldType.SingleSelect, - AITableFieldType.DateTime + AITableFieldType.text, + AITableFieldType.number, + AITableFieldType.select, + AITableFieldType.date ]; export const RowHeight = { diff --git a/packages/grid/src/core/action/general.ts b/packages/grid/src/core/action/general.ts index a789381d..d6c9e790 100644 --- a/packages/grid/src/core/action/general.ts +++ b/packages/grid/src/core/action/general.ts @@ -6,7 +6,7 @@ const apply = (aiTable: AITable, records: AITableRecords, fields: AITableFields, case ActionName.UpdateFieldValue: { const [recordIndex, fieldIndex] = options.path; const fieldId = aiTable.fields()[fieldIndex].id; - records[recordIndex].value[fieldId] = options.newFieldValue; + records[recordIndex].values[fieldId] = options.newFieldValue; break; } case ActionName.AddRecord: { @@ -22,8 +22,8 @@ const apply = (aiTable: AITable, records: AITableRecords, fields: AITableFields, [newField.id]: '' }; records.forEach((item) => { - item.value = { - ...item.value, + item.values = { + ...item.values, ...newRecord }; }); diff --git a/packages/grid/src/core/constants/field.ts b/packages/grid/src/core/constants/field.ts index 8a96f7d9..e24d8049 100644 --- a/packages/grid/src/core/constants/field.ts +++ b/packages/grid/src/core/constants/field.ts @@ -3,37 +3,37 @@ import { helpers } from 'ngx-tethys/util'; export const BasicFields = [ { - type: AITableFieldType.Text, + type: AITableFieldType.text, name: '文本', icon: 'font', width: 300 }, { - type: AITableFieldType.SingleSelect, + type: AITableFieldType.select, name: '单选', icon: 'check-circle', width: 200 }, { - type: AITableFieldType.Number, + type: AITableFieldType.number, name: '数字', icon: 'hashtag', width: 200 }, { - type: AITableFieldType.DateTime, + type: AITableFieldType.date, name: '日期', icon: 'calendar', width: 200 }, { - type: AITableFieldType.Rating, + type: AITableFieldType.rate, name: '评分', icon: 'star-circle', width: 200 }, { - type: AITableFieldType.Link, + type: AITableFieldType.link, name: '链接', icon: 'link-insert', width: 300 diff --git a/packages/grid/src/core/types/core.ts b/packages/grid/src/core/types/core.ts index e8771ca3..d59f3f90 100644 --- a/packages/grid/src/core/types/core.ts +++ b/packages/grid/src/core/types/core.ts @@ -1,21 +1,19 @@ import { WritableSignal } from '@angular/core'; import { AITableAction } from './action'; import { AITableSelection } from '../../types'; +import { Id } from 'ngx-tethys/types'; export enum AITableFieldType { - // NotSupport = 0, - Text = 1, - Number = 2, - SingleSelect = 3, - // MultiSelect = 4, - DateTime = 5, - // Attachment = 6, - Link = 7, - // Email = 9, - // Phone = 10, - // Checkbox = 11, - Rating = 12 - // Member = 13 + text = 'text', // 包含多行文本 + richText = 'rich_text', // 包含多行文本 + select = 'select', // 包含单选和多选 + number = 'number', + date = 'date', + member = 'member', // 包含单个和多个 + // cascadeSelect = "cascade_select", // 包含单选和多选,参数复杂后续再进行设计 + progress = 'progress', + rate = 'rate', + link = 'link' } export enum AITableStatType { @@ -45,7 +43,7 @@ export interface AITableSelectOption { color?: string; } -export interface AITableField { +export interface AITableField { id: string; name: string; type: AITableFieldType; @@ -54,13 +52,38 @@ export interface AITableField { hidden?: boolean; frozen?: boolean; statType?: AITableStatType; - [key: string]: AITableSelectOption[] | any; + isMultiple?: boolean; + [key: string]: T | any; } +export type TextFieldValue = string; + +export type SelectFieldValue = Id[]; // 数字 + +export type NumberFieldValue = number; + +export type DateFieldValue = { timestamp: number }; // 时间戳 + +export type MemberFieldValue = Id[]; + +export type ProgressFieldValue = number; // [0,1] + +export type RateFieldValue = 1 | 2 | 3 | 4 | 5; + +export type FieldValue = + | TextFieldValue + | SelectFieldValue + | NumberFieldValue + | DateFieldValue + | MemberFieldValue + | ProgressFieldValue + | RateFieldValue + | any; + export interface AITableRecord { id: string; checked?: boolean; - value: Record; + values: Record; } export type AITableRecords = AITableRecord[]; diff --git a/packages/grid/src/core/utils/field.ts b/packages/grid/src/core/utils/field.ts index 2855860f..bac45ca0 100644 --- a/packages/grid/src/core/utils/field.ts +++ b/packages/grid/src/core/utils/field.ts @@ -6,12 +6,12 @@ export function getDefaultFieldValue(type: AITableFieldType) { return ''; } -export function createDefaultFieldName(aiTable: AITable, type: AITableFieldType = AITableFieldType.Text) { +export function createDefaultFieldName(aiTable: AITable, type: AITableFieldType = AITableFieldType.text) { const fields = aiTable.fields(); const count = fields.filter((item) => item.type === type).length; return count === 0 ? FieldsMap[type].name : FieldsMap[type].name + count; } -export function createDefaultField(aiTable: AITable, type: AITableFieldType = AITableFieldType.Text) { +export function createDefaultField(aiTable: AITable, type: AITableFieldType = AITableFieldType.text) { return { id: idCreator(), type, name: createDefaultFieldName(aiTable, type) }; } diff --git a/packages/grid/src/core/utils/queries.ts b/packages/grid/src/core/utils/queries.ts index ae96d4bc..2eeeb016 100644 --- a/packages/grid/src/core/utils/queries.ts +++ b/packages/grid/src/core/utils/queries.ts @@ -31,6 +31,6 @@ export const AITableQueries = { if (!field) { throw new Error(`can not find field at path [${path}]`); } - return aiTable.records()[path[0]].value[field.id]; + return aiTable.records()[path[0]].values[field.id]; } }; diff --git a/packages/grid/src/core/utils/record.ts b/packages/grid/src/core/utils/record.ts index 4d6921d5..f64b680b 100644 --- a/packages/grid/src/core/utils/record.ts +++ b/packages/grid/src/core/utils/record.ts @@ -5,10 +5,10 @@ import { idCreator } from './id-creator'; export function getDefaultRecord(fields: AITableFields) { const newRow: AITableRecord = { id: idCreator(), - value: {} + values: {} }; fields.map((item) => { - newRow.value[item.id] = getDefaultFieldValue(item.type); + newRow.values[item.id] = getDefaultFieldValue(item.type); }); return newRow; } diff --git a/packages/grid/src/grid.component.html b/packages/grid/src/grid.component.html index 9ee30bb3..264201b9 100644 --- a/packages/grid/src/grid.component.html +++ b/packages/grid/src/grid.component.html @@ -14,7 +14,14 @@ {{ field.name }} - + @@ -52,30 +59,30 @@ #cell > @switch (field.type) { - @case (AITableFieldType.SingleSelect) { - @if (record.value[field.id] | selectOption: field['options']; as selectedOption) { + @case (AITableFieldType.select) { + @if (!field.isMultiple && record.values[field.id] | selectOption: field['options']; as selectedOption) { {{ selectedOption.name }} } } - @case (AITableFieldType.DateTime) { - {{ record.value[field.id] | thyDatePickerFormat }} + @case (AITableFieldType.date) { + {{ record.values[field.id] | thyDatePickerFormat }} } - @case (AITableFieldType.Rating) { - + @case (AITableFieldType.rate) { + } - @case (AITableFieldType.Link) { + @case (AITableFieldType.link) { {{ record.value[field.id]?.text }}{{ record.values[field.id]?.text }} } @default { - {{ record.value[field.id] }} + {{ record.values[field.id] }} } }
diff --git a/packages/grid/src/grid.component.ts b/packages/grid/src/grid.component.ts index 85106e8d..c438828b 100644 --- a/packages/grid/src/grid.component.ts +++ b/packages/grid/src/grid.component.ts @@ -161,7 +161,7 @@ export class AITableGrid implements OnInit { } addField(gridColumnBlank: HTMLElement) { - const field = signal(createDefaultField(this.aiTable, AITableFieldType.Text)); + const field = signal(createDefaultField(this.aiTable, AITableFieldType.text)); this.aiTableGridFieldService.editFieldProperty(gridColumnBlank, this.aiTable, field, false); } } diff --git a/packages/grid/src/services/event.service.ts b/packages/grid/src/services/event.service.ts index 78b0ddd7..489fdf16 100644 --- a/packages/grid/src/services/event.service.ts +++ b/packages/grid/src/services/event.service.ts @@ -41,8 +41,8 @@ export class AITableGridEventService { private dblClick(event: MouseEvent) { const cellDom = (event.target as HTMLElement).closest('.grid-cell') as HTMLElement; - const type = cellDom && cellDom.getAttribute('type')!; - if (type && DBL_CLICK_EDIT_TYPE.includes(Number(type))) { + const type = cellDom && cellDom.getAttribute('type')! as AITableFieldType; + if (type && DBL_CLICK_EDIT_TYPE.includes(type)) { this.openEdit(cellDom); } } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 133bc7d2..b4b112c3 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -36,7 +36,7 @@ const initValue = { records: [ { id: 'row-1', - value: { + values: { 'column-1': '文本 1-1', 'column-2': '1', 'column-3': { @@ -48,7 +48,7 @@ const initValue = { }, { id: 'row-2', - value: { + values: { 'column-1': '文本 2-1', 'column-2': '2', 'column-3': {}, @@ -57,7 +57,7 @@ const initValue = { }, { id: 'row-3', - value: { + values: { 'column-1': '文本 3-1', 'column-2': '3', 'column-3': {}, @@ -69,12 +69,12 @@ const initValue = { { id: 'column-1', name: '文本', - type: AITableFieldType.Text + type: AITableFieldType.text }, { id: 'column-2', name: '单选', - type: AITableFieldType.SingleSelect, + type: AITableFieldType.select, options: [ { id: '1', @@ -96,12 +96,12 @@ const initValue = { { id: 'column-3', name: '链接', - type: AITableFieldType.Link + type: AITableFieldType.link }, { id: 'column-4', name: '评分', - type: AITableFieldType.Rating + type: AITableFieldType.rate } ] }; @@ -112,7 +112,7 @@ const initValue = { // initValue.fields.push({ // id: `column-${index}`, // name: "文本", -// type: AITableFieldType.Text, +// type: AITableFieldType.text, // }); // } // initValue.records = []; diff --git a/src/app/component/field-property-editor/field-property-editor.component.html b/src/app/component/field-property-editor/field-property-editor.component.html index 24958794..aa002e61 100644 --- a/src/app/component/field-property-editor/field-property-editor.component.html +++ b/src/app/component/field-property-editor/field-property-editor.component.html @@ -2,7 +2,7 @@ - @if (aiField().type === AITableFieldType.SingleSelect) { + @if (aiField().type === AITableFieldType.select) { 下拉选项选择 } diff --git a/src/app/share/apply-to-table/array-event.ts b/src/app/share/apply-to-table/array-event.ts index 3263fc90..dfe6ed18 100644 --- a/src/app/share/apply-to-table/array-event.ts +++ b/src/app/share/apply-to-table/array-event.ts @@ -42,7 +42,7 @@ export default function translateArrayEvent(aiTable: AITable, event: Y.YEvent { - const provider = new WebsocketProvider('wss://demos.yjs.dev/ws', 'ai-table-demo-2024/7/25', doc); + const provider = new WebsocketProvider('wss://demos.yjs.dev/ws', 'ai-table-demo-2024/7/30', doc); provider.connect(); return provider; }; diff --git a/src/app/share/shared.ts b/src/app/share/shared.ts index 800cdf46..8d7fe83a 100644 --- a/src/app/share/shared.ts +++ b/src/app/share/shared.ts @@ -63,8 +63,8 @@ export function toRecordSyncElement(record: AITableRecord): Y.Array const customFieldArray = new Y.Array(); const customFields = []; - for (const fieldId in record['value']) { - customFields.push(record['value'][fieldId]); + for (const fieldId in record['values']) { + customFields.push(record['values'][fieldId]); } customFieldArray.insert(0, customFields);