diff --git a/apps/client/src/widgets/view_widgets/table_view/index.ts b/apps/client/src/widgets/view_widgets/table_view/index.ts index 94284dc74..daabc898e 100644 --- a/apps/client/src/widgets/view_widgets/table_view/index.ts +++ b/apps/client/src/widgets/view_widgets/table_view/index.ts @@ -1,10 +1,7 @@ -import froca from "../../../services/froca.js"; import ViewMode, { type ViewModeArgs } from "../view_mode.js"; -import attributes, { setAttribute, setLabel } from "../../../services/attributes.js"; -import server from "../../../services/server.js"; +import attributes from "../../../services/attributes.js"; import SpacedUpdate from "../../../services/spaced_update.js"; -import type { CommandListenerData, EventData } from "../../../components/app_context.js"; -import note_create, { CreateNoteOpts } from "../../../services/note_create.js"; +import type { EventData } from "../../../components/app_context.js"; import {Tabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, ColumnDefinition, DataTreeModule, Options, RowComponent, ColumnComponent} from 'tabulator-tables'; import "tabulator-tables/dist/css/tabulator.css"; import "../../../../src/stylesheets/table.css"; @@ -14,6 +11,7 @@ import getAttributeDefinitionInformation, { buildRowDefinitions } from "./rows.j import { AttributeDefinitionInformation, buildColumnDefinitions } from "./columns.js"; import { setupContextMenu } from "./context_menu.js"; import TableColumnEditing from "./col_editing.js"; +import TableRowEditing from "./row_editing.js"; const TPL = /*html*/`
@@ -171,11 +169,12 @@ export default class TableView extends ViewMode { this.colEditing = new TableColumnEditing(this.args.$parent, this.args.parentNote, this.api); this.child(this.colEditing); + this.child(new TableRowEditing(this.api, this.args.parentNotePath!)); + if (movableRows) { configureReorderingRows(this.api); } setupContextMenu(this.api, this.parentNote); - this.setupEditing(); } private onSave() { @@ -184,51 +183,6 @@ export default class TableView extends ViewMode { }); } - private setupEditing() { - this.api!.on("cellEdited", async (cell) => { - const noteId = cell.getRow().getData().noteId; - const field = cell.getField(); - let newValue = cell.getValue(); - - if (field === "title") { - server.put(`notes/${noteId}/title`, { title: newValue }); - return; - } - - if (field.includes(".")) { - const [ type, name ] = field.split(".", 2); - if (type === "labels") { - if (typeof newValue === "boolean") { - newValue = newValue ? "true" : "false"; - } - setLabel(noteId, name, newValue); - } else if (type === "relations") { - const note = await froca.getNote(noteId); - if (note) { - setAttribute(note, "relation", name, newValue); - } - } - } - }); - } - - addNewRowCommand({ customOpts, parentNotePath: customNotePath }: CommandListenerData<"addNewRow">) { - const parentNotePath = customNotePath ?? this.args.parentNotePath; - if (parentNotePath) { - const opts: CreateNoteOpts = { - activate: false, - ...customOpts - } - note_create.createNote(parentNotePath, opts).then(({ branch }) => { - if (branch) { - setTimeout(() => { - this.focusOnBranch(branch?.branchId); - }); - } - }) - } - } - async onEntitiesReloaded({ loadResults }: EventData<"entitiesReloaded">) { if (!this.api) { return; @@ -285,40 +239,5 @@ export default class TableView extends ViewMode { return false; } - focusOnBranch(branchId: string) { - if (!this.api) { - return; - } - - const row = findRowDataById(this.api.getRows(), branchId); - if (!row) { - return; - } - - // Expand the parent tree if any. - if (this.api.options.dataTree) { - const parent = row.getTreeParent(); - if (parent) { - parent.treeExpand(); - } - } - - row.getCell("title").edit(); - } - } - -function findRowDataById(rows: RowComponent[], branchId: string): RowComponent | null { - for (let row of rows) { - const item = row.getIndex() as string; - - if (item === branchId) { - return row; - } - - let found = findRowDataById(row.getTreeChildren(), branchId); - if (found) return found; - } - return null; -} diff --git a/apps/client/src/widgets/view_widgets/table_view/row_editing.ts b/apps/client/src/widgets/view_widgets/table_view/row_editing.ts new file mode 100644 index 000000000..b1515034c --- /dev/null +++ b/apps/client/src/widgets/view_widgets/table_view/row_editing.ts @@ -0,0 +1,97 @@ +import { RowComponent, Tabulator } from "tabulator-tables"; +import Component from "../../../components/component.js"; +import { setAttribute, setLabel } from "../../../services/attributes.js"; +import server from "../../../services/server.js"; +import froca from "../../../services/froca.js"; +import note_create, { CreateNoteOpts } from "../../../services/note_create.js"; +import { CommandListenerData } from "../../../components/app_context.js"; + +export default class TableRowEditing extends Component { + + private parentNotePath: string; + private api: Tabulator; + + constructor(api: Tabulator, parentNotePath: string) { + super(); + this.api = api; + this.parentNotePath = parentNotePath; + api.on("cellEdited", async (cell) => { + const noteId = cell.getRow().getData().noteId; + const field = cell.getField(); + let newValue = cell.getValue(); + + if (field === "title") { + server.put(`notes/${noteId}/title`, { title: newValue }); + return; + } + + if (field.includes(".")) { + const [ type, name ] = field.split(".", 2); + if (type === "labels") { + if (typeof newValue === "boolean") { + newValue = newValue ? "true" : "false"; + } + setLabel(noteId, name, newValue); + } else if (type === "relations") { + const note = await froca.getNote(noteId); + if (note) { + setAttribute(note, "relation", name, newValue); + } + } + } + }); + } + + addNewRowEvent({ customOpts, parentNotePath: customNotePath }: CommandListenerData<"addNewRow">) { + const parentNotePath = customNotePath ?? this.parentNotePath; + if (parentNotePath) { + const opts: CreateNoteOpts = { + activate: false, + ...customOpts + } + note_create.createNote(parentNotePath, opts).then(({ branch }) => { + if (branch) { + setTimeout(() => { + this.focusOnBranch(branch?.branchId); + }); + } + }) + } + } + + focusOnBranch(branchId: string) { + if (!this.api) { + return; + } + + const row = findRowDataById(this.api.getRows(), branchId); + if (!row) { + return; + } + + // Expand the parent tree if any. + if (this.api.options.dataTree) { + const parent = row.getTreeParent(); + if (parent) { + parent.treeExpand(); + } + } + + row.getCell("title").edit(); + } + +} + +function findRowDataById(rows: RowComponent[], branchId: string): RowComponent | null { + for (let row of rows) { + const item = row.getIndex() as string; + + if (item === branchId) { + return row; + } + + let found = findRowDataById(row.getTreeChildren(), branchId); + if (found) return found; + } + return null; +}