feat(book/table): allow editing cell values

This commit is contained in:
Elian Doran 2025-06-25 13:06:38 +03:00
parent 66761a69d3
commit 7e20e41521
No known key found for this signature in database
4 changed files with 73 additions and 40 deletions

View File

@ -11,7 +11,7 @@ async function addLabel(noteId: string, name: string, value: string = "") {
}); });
} }
async function setLabel(noteId: string, name: string, value: string = "") { export async function setLabel(noteId: string, name: string, value: string = "") {
await server.put(`notes/${noteId}/set-attribute`, { await server.put(`notes/${noteId}/set-attribute`, {
type: "label", type: "label",
name: name, name: name,

View File

@ -1,21 +1,17 @@
import { GridOptions } from "ag-grid-community"; import { GridOptions } from "ag-grid-community";
import FNote from "../../../entities/fnote"; import FNote from "../../../entities/fnote.js";
import type { LabelType } from "../../../services/promoted_attribute_definition_parser.js"; import type { LabelType } from "../../../services/promoted_attribute_definition_parser.js";
import { default as getPromotedAttributeInformation, type PromotedAttributeInformation } from "./parser.js";
type Data = { export type TableData = {
noteId: string;
title: string; title: string;
} & Record<string, string>; } & Record<string, string>;
interface PromotedAttributeInformation {
name: string;
title?: string;
type?: LabelType;
}
type GridLabelType = 'text' | 'number' | 'boolean' | 'date' | 'dateString' | 'object'; type GridLabelType = 'text' | 'number' | 'boolean' | 'date' | 'dateString' | 'object';
export function buildData(parentNote: FNote, notes: FNote[]) { export function buildData(info: PromotedAttributeInformation[], notes: FNote[]) {
const info = getPromotedAttributeInformation(parentNote);
const columnDefs = buildColumnDefinitions(info); const columnDefs = buildColumnDefinitions(info);
const rowData = buildRowDefinitions(notes, info); const rowData = buildRowDefinitions(notes, info);
@ -26,7 +22,10 @@ export function buildData(parentNote: FNote, notes: FNote[]) {
} }
export function buildColumnDefinitions(info: PromotedAttributeInformation[]) { export function buildColumnDefinitions(info: PromotedAttributeInformation[]) {
const columnDefs: GridOptions<Data>["columnDefs"] = [ const columnDefs: GridOptions<TableData>["columnDefs"] = [
{
field: "noteId"
},
{ {
field: "title" field: "title"
} }
@ -36,36 +35,14 @@ export function buildColumnDefinitions(info: PromotedAttributeInformation[]) {
columnDefs.push({ columnDefs.push({
field: name, field: name,
headerName: title, headerName: title,
cellDataType: mapDataType(type) cellDataType: mapDataType(type),
editable: true
}); });
} }
return columnDefs; return columnDefs;
} }
function getPromotedAttributeInformation(parentNote: FNote) {
const info: PromotedAttributeInformation[] = [];
for (const promotedAttribute of parentNote.getPromotedDefinitionAttributes()) {
if (promotedAttribute.type !== "label") {
console.warn("Relations are not supported for now");
continue;
}
const def = promotedAttribute.getDefinition();
if (def.multiplicity !== "single") {
console.warn("Multiple values are not supported for now");
continue;
}
info.push({
name: promotedAttribute.name.split(":", 2)[1],
title: def.promotedAlias,
type: def.labelType
})
}
return info;
}
function mapDataType(labelType: LabelType | undefined): GridLabelType { function mapDataType(labelType: LabelType | undefined): GridLabelType {
if (!labelType) { if (!labelType) {
return "text"; return "text";
@ -84,10 +61,11 @@ function mapDataType(labelType: LabelType | undefined): GridLabelType {
} }
} }
export function buildRowDefinitions(notes: FNote[], infos: PromotedAttributeInformation[]): GridOptions<Data>["rowData"] { export function buildRowDefinitions(notes: FNote[], infos: PromotedAttributeInformation[]) {
const definitions: GridOptions<Data>["rowData"] = []; const definitions: GridOptions<TableData>["rowData"] = [];
for (const note of notes) { for (const note of notes) {
const data = { const data = {
noteId: note.noteId,
title: note.title title: note.title
}; };

View File

@ -0,0 +1,31 @@
import FNote from "../../../entities/fnote";
import { LabelType } from "../../../services/promoted_attribute_definition_parser";
export interface PromotedAttributeInformation {
name: string;
title?: string;
type?: LabelType;
}
export default function getPromotedAttributeInformation(parentNote: FNote) {
const info: PromotedAttributeInformation[] = [];
for (const promotedAttribute of parentNote.getPromotedDefinitionAttributes()) {
if (promotedAttribute.type !== "label") {
console.warn("Relations are not supported for now");
continue;
}
const def = promotedAttribute.getDefinition();
if (def.multiplicity !== "single") {
console.warn("Multiple values are not supported for now");
continue;
}
info.push({
name: promotedAttribute.name.split(":", 2)[1],
title: def.promotedAlias,
type: def.labelType
})
}
return info;
}

View File

@ -1,11 +1,35 @@
import { createGrid, AllCommunityModule, ModuleRegistry } from "ag-grid-community"; import { createGrid, AllCommunityModule, ModuleRegistry, columnDropStyleBordered, GridOptions } from "ag-grid-community";
import { buildData } from "./data.js"; import { buildData, type TableData } from "./data.js";
import FNote from "../../../entities/fnote.js"; import FNote from "../../../entities/fnote.js";
import getPromotedAttributeInformation, { PromotedAttributeInformation } from "./parser.js";
import { setLabel } from "../../../services/attributes.js";
ModuleRegistry.registerModules([ AllCommunityModule ]); ModuleRegistry.registerModules([ AllCommunityModule ]);
export default function renderTable(el: HTMLElement, parentNote: FNote, notes: FNote[]) { export default function renderTable(el: HTMLElement, parentNote: FNote, notes: FNote[]) {
const info = getPromotedAttributeInformation(parentNote);
createGrid(el, { createGrid(el, {
...buildData(parentNote, notes) ...buildData(info, notes),
...setupEditing(info)
}); });
} }
function setupEditing(info: PromotedAttributeInformation[]): GridOptions<TableData> {
return {
onCellValueChanged(event) {
if (event.type !== "cellValueChanged") {
return;
}
const noteId = event.data.noteId;
const name = event.colDef.field;
if (!name) {
return;
}
const { newValue } = event;
setLabel(noteId, name, newValue);
}
}
}