From 0a813f9b5361fc336dcc332fda2bd93741f21f9d Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Fri, 12 Sep 2025 19:02:10 +0300 Subject: [PATCH] feat(collections/table): support archived notes --- .../src/widgets/collections/table/index.css | 4 ++++ .../src/widgets/collections/table/index.tsx | 15 +++++++++++---- apps/client/src/widgets/collections/table/rows.ts | 10 ++++++---- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/apps/client/src/widgets/collections/table/index.css b/apps/client/src/widgets/collections/table/index.css index cc1eb1329..48249b0c9 100644 --- a/apps/client/src/widgets/collections/table/index.css +++ b/apps/client/src/widgets/collections/table/index.css @@ -36,6 +36,10 @@ border-right-width: 1px; } +.tabulator .tabulator-row.archived { + opacity: 0.5; +} + .tabulator .tabulator-footer { background-color: unset; padding: 5px 0; diff --git a/apps/client/src/widgets/collections/table/index.tsx b/apps/client/src/widgets/collections/table/index.tsx index fc2e71a7b..0c4e3e8f8 100644 --- a/apps/client/src/widgets/collections/table/index.tsx +++ b/apps/client/src/widgets/collections/table/index.tsx @@ -4,7 +4,7 @@ import { buildColumnDefinitions } from "./columns"; import getAttributeDefinitionInformation, { buildRowDefinitions, TableData } from "./rows"; import { useLegacyWidget, useNoteLabel, useNoteLabelBoolean, useNoteLabelInt, useSpacedUpdate, useTriliumEvent } from "../../react/hooks"; import Tabulator from "./tabulator"; -import { Tabulator as VanillaTabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, ColumnDefinition, DataTreeModule, Options} from 'tabulator-tables'; +import { Tabulator as VanillaTabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, ColumnDefinition, DataTreeModule, Options, RowComponent} from 'tabulator-tables'; import { useContextMenu } from "./context_menu"; import { ParentComponent } from "../../react/react_utils"; import FNote from "../../../entities/fnote"; @@ -46,6 +46,11 @@ export default function TableView({ note, noteIds, notePath, viewConfig, saveCon } }, [ hasChildren ]); + const rowFormatter = useCallback((row: RowComponent) => { + const data = row.getData() as TableData; + row.getElement().classList.toggle("archived", !!data.isArchived); + }, []); + return (
{columnDefs && ( @@ -66,7 +71,7 @@ export default function TableView({ note, noteIds, notePath, viewConfig, saveCon index="branchId" movableColumns movableRows={movableRows} - + rowFormatter={rowFormatter} {...dataTreeProps} /> @@ -110,6 +115,7 @@ function usePersistence(initialConfig: TableConfig | null | undefined, saveConfi function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undefined, newAttributePosition: RefObject, resetNewAttributePosition: () => void) { const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1; + const [ includeArchived ] = useNoteLabelBoolean(note, "includeArchived"); const [ columnDefs, setColumnDefs ] = useState(); const [ rowData, setRowData ] = useState(); @@ -119,7 +125,7 @@ function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undef function refresh() { const info = getAttributeDefinitionInformation(note); - buildRowDefinitions(note, info, maxDepth).then(({ definitions: rowData, hasSubtree: hasChildren, rowNumber }) => { + buildRowDefinitions(note, info, includeArchived, maxDepth).then(({ definitions: rowData, hasSubtree: hasChildren, rowNumber }) => { const columnDefs = buildColumnDefinitions({ info, movableRows, @@ -149,7 +155,8 @@ function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undef // React to external row updates. if (loadResults.getBranchRows().some(branch => branch.parentNoteId === note.noteId || noteIds.includes(branch.parentNoteId ?? "")) || loadResults.getNoteIds().some(noteId => noteIds.includes(noteId)) - || loadResults.getAttributeRows().some(attr => noteIds.includes(attr.noteId!))) { + || loadResults.getAttributeRows().some(attr => noteIds.includes(attr.noteId!)) + || loadResults.getAttributeRows().some(attr => attr.name === "archived" && attr.noteId && noteIds.includes(attr.noteId))) { refresh(); return; } diff --git a/apps/client/src/widgets/collections/table/rows.ts b/apps/client/src/widgets/collections/table/rows.ts index 460f169ac..84b4c5882 100644 --- a/apps/client/src/widgets/collections/table/rows.ts +++ b/apps/client/src/widgets/collections/table/rows.ts @@ -10,10 +10,11 @@ export type TableData = { relations: Record; branchId: string; colorClass: string | undefined; + isArchived: boolean; _children?: TableData[]; }; -export async function buildRowDefinitions(parentNote: FNote, infos: AttributeDefinitionInformation[], maxDepth = -1, currentDepth = 0) { +export async function buildRowDefinitions(parentNote: FNote, infos: AttributeDefinitionInformation[], includeArchived: boolean, maxDepth = -1, currentDepth = 0) { const definitions: TableData[] = []; const childBranches = parentNote.getChildBranches(); let hasSubtree = false; @@ -21,8 +22,8 @@ export async function buildRowDefinitions(parentNote: FNote, infos: AttributeDef for (const branch of childBranches) { const note = await branch.getNote(); - if (!note) { - continue; // Skip if the note is not found + if (!note || (!includeArchived && note.isArchived)) { + continue; } const labels: typeof definitions[0]["labels"] = {}; @@ -41,12 +42,13 @@ export async function buildRowDefinitions(parentNote: FNote, infos: AttributeDef title: note.title, labels, relations, + isArchived: note.isArchived, branchId: branch.branchId, colorClass: note.getColorClass() } if (note.hasChildren() && (maxDepth < 0 || currentDepth < maxDepth)) { - const { definitions, rowNumber: subRowNumber } = (await buildRowDefinitions(note, infos, maxDepth, currentDepth + 1)); + const { definitions, rowNumber: subRowNumber } = (await buildRowDefinitions(note, infos, includeArchived, maxDepth, currentDepth + 1)); def._children = definitions; hasSubtree = true; rowNumber += subRowNumber;