feat(collections/table): support archived notes

This commit is contained in:
Elian Doran 2025-09-12 19:02:10 +03:00
parent 0c0bcb87f9
commit 0a813f9b53
No known key found for this signature in database
3 changed files with 21 additions and 8 deletions

View File

@ -36,6 +36,10 @@
border-right-width: 1px; border-right-width: 1px;
} }
.tabulator .tabulator-row.archived {
opacity: 0.5;
}
.tabulator .tabulator-footer { .tabulator .tabulator-footer {
background-color: unset; background-color: unset;
padding: 5px 0; padding: 5px 0;

View File

@ -4,7 +4,7 @@ import { buildColumnDefinitions } from "./columns";
import getAttributeDefinitionInformation, { buildRowDefinitions, TableData } from "./rows"; import getAttributeDefinitionInformation, { buildRowDefinitions, TableData } from "./rows";
import { useLegacyWidget, useNoteLabel, useNoteLabelBoolean, useNoteLabelInt, useSpacedUpdate, useTriliumEvent } from "../../react/hooks"; import { useLegacyWidget, useNoteLabel, useNoteLabelBoolean, useNoteLabelInt, useSpacedUpdate, useTriliumEvent } from "../../react/hooks";
import Tabulator from "./tabulator"; 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 { useContextMenu } from "./context_menu";
import { ParentComponent } from "../../react/react_utils"; import { ParentComponent } from "../../react/react_utils";
import FNote from "../../../entities/fnote"; import FNote from "../../../entities/fnote";
@ -46,6 +46,11 @@ export default function TableView({ note, noteIds, notePath, viewConfig, saveCon
} }
}, [ hasChildren ]); }, [ hasChildren ]);
const rowFormatter = useCallback((row: RowComponent) => {
const data = row.getData() as TableData;
row.getElement().classList.toggle("archived", !!data.isArchived);
}, []);
return ( return (
<div className="table-view"> <div className="table-view">
{columnDefs && ( {columnDefs && (
@ -66,7 +71,7 @@ export default function TableView({ note, noteIds, notePath, viewConfig, saveCon
index="branchId" index="branchId"
movableColumns movableColumns
movableRows={movableRows} movableRows={movableRows}
rowFormatter={rowFormatter}
{...dataTreeProps} {...dataTreeProps}
/> />
<TableFooter note={note} /> <TableFooter note={note} />
@ -110,6 +115,7 @@ function usePersistence(initialConfig: TableConfig | null | undefined, saveConfi
function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undefined, newAttributePosition: RefObject<number | undefined>, resetNewAttributePosition: () => void) { function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undefined, newAttributePosition: RefObject<number | undefined>, resetNewAttributePosition: () => void) {
const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1; const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1;
const [ includeArchived ] = useNoteLabelBoolean(note, "includeArchived");
const [ columnDefs, setColumnDefs ] = useState<ColumnDefinition[]>(); const [ columnDefs, setColumnDefs ] = useState<ColumnDefinition[]>();
const [ rowData, setRowData ] = useState<TableData[]>(); const [ rowData, setRowData ] = useState<TableData[]>();
@ -119,7 +125,7 @@ function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undef
function refresh() { function refresh() {
const info = getAttributeDefinitionInformation(note); 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({ const columnDefs = buildColumnDefinitions({
info, info,
movableRows, movableRows,
@ -149,7 +155,8 @@ function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undef
// React to external row updates. // React to external row updates.
if (loadResults.getBranchRows().some(branch => branch.parentNoteId === note.noteId || noteIds.includes(branch.parentNoteId ?? "")) if (loadResults.getBranchRows().some(branch => branch.parentNoteId === note.noteId || noteIds.includes(branch.parentNoteId ?? ""))
|| loadResults.getNoteIds().some(noteId => noteIds.includes(noteId)) || 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(); refresh();
return; return;
} }

View File

@ -10,10 +10,11 @@ export type TableData = {
relations: Record<string, boolean | string | null>; relations: Record<string, boolean | string | null>;
branchId: string; branchId: string;
colorClass: string | undefined; colorClass: string | undefined;
isArchived: boolean;
_children?: TableData[]; _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 definitions: TableData[] = [];
const childBranches = parentNote.getChildBranches(); const childBranches = parentNote.getChildBranches();
let hasSubtree = false; let hasSubtree = false;
@ -21,8 +22,8 @@ export async function buildRowDefinitions(parentNote: FNote, infos: AttributeDef
for (const branch of childBranches) { for (const branch of childBranches) {
const note = await branch.getNote(); const note = await branch.getNote();
if (!note) { if (!note || (!includeArchived && note.isArchived)) {
continue; // Skip if the note is not found continue;
} }
const labels: typeof definitions[0]["labels"] = {}; const labels: typeof definitions[0]["labels"] = {};
@ -41,12 +42,13 @@ export async function buildRowDefinitions(parentNote: FNote, infos: AttributeDef
title: note.title, title: note.title,
labels, labels,
relations, relations,
isArchived: note.isArchived,
branchId: branch.branchId, branchId: branch.branchId,
colorClass: note.getColorClass() colorClass: note.getColorClass()
} }
if (note.hasChildren() && (maxDepth < 0 || currentDepth < maxDepth)) { 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; def._children = definitions;
hasSubtree = true; hasSubtree = true;
rowNumber += subRowNumber; rowNumber += subRowNumber;