mirror of
https://github.com/zadam/trilium.git
synced 2025-10-26 15:56:29 +01:00
feat(book/table): store hidden columns
This commit is contained in:
@@ -109,24 +109,22 @@ const CALENDAR_VIEWS = [
|
||||
"listMonth"
|
||||
]
|
||||
|
||||
export default class CalendarView extends ViewMode {
|
||||
export default class CalendarView extends ViewMode<{}> {
|
||||
|
||||
private $root: JQuery<HTMLElement>;
|
||||
private $calendarContainer: JQuery<HTMLElement>;
|
||||
private noteIds: string[];
|
||||
private parentNote: FNote;
|
||||
private calendar?: Calendar;
|
||||
private isCalendarRoot: boolean;
|
||||
private lastView?: string;
|
||||
private debouncedSaveView?: DebouncedFunction<() => void>;
|
||||
|
||||
constructor(args: ViewModeArgs) {
|
||||
super(args);
|
||||
super(args, "calendar");
|
||||
|
||||
this.$root = $(TPL);
|
||||
this.$calendarContainer = this.$root.find(".calendar-container");
|
||||
this.noteIds = args.noteIds;
|
||||
this.parentNote = args.parentNote;
|
||||
this.isCalendarRoot = false;
|
||||
args.$parent.append(this.$root);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import treeService from "../../services/tree.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import ViewMode, { type ViewModeArgs } from "./view_mode.js";
|
||||
import type { ViewTypeOptions } from "../../services/note_list_renderer.js";
|
||||
|
||||
const TPL = /*html*/`
|
||||
<div class="note-list">
|
||||
@@ -157,26 +158,22 @@ const TPL = /*html*/`
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
class ListOrGridView extends ViewMode {
|
||||
class ListOrGridView extends ViewMode<{}> {
|
||||
private $noteList: JQuery<HTMLElement>;
|
||||
|
||||
private parentNote: FNote;
|
||||
private noteIds: string[];
|
||||
private page?: number;
|
||||
private pageSize?: number;
|
||||
private viewType?: string | null;
|
||||
private showNotePath?: boolean;
|
||||
private highlightRegex?: RegExp | null;
|
||||
|
||||
/*
|
||||
* We're using noteIds so that it's not necessary to load all notes at once when paging
|
||||
*/
|
||||
constructor(viewType: string, args: ViewModeArgs) {
|
||||
super(args);
|
||||
constructor(viewType: ViewTypeOptions, args: ViewModeArgs) {
|
||||
super(args, viewType);
|
||||
this.$noteList = $(TPL);
|
||||
this.viewType = viewType;
|
||||
|
||||
this.parentNote = args.parentNote;
|
||||
const includedNoteIds = this.getIncludedNoteIds();
|
||||
|
||||
this.noteIds = args.noteIds.filter((noteId) => !includedNoteIds.has(noteId) && noteId !== "_hidden");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import froca from "../../services/froca.js";
|
||||
import renderTable from "./table_view/renderer.js";
|
||||
import type { StateInfo } from "./table_view/storage.js";
|
||||
import ViewMode, { ViewModeArgs } from "./view_mode";
|
||||
|
||||
const TPL = /*html*/`
|
||||
@@ -24,14 +25,14 @@ const TPL = /*html*/`
|
||||
</div>
|
||||
`;
|
||||
|
||||
export default class TableView extends ViewMode {
|
||||
export default class TableView extends ViewMode<StateInfo> {
|
||||
|
||||
private $root: JQuery<HTMLElement>;
|
||||
private $container: JQuery<HTMLElement>;
|
||||
private args: ViewModeArgs;
|
||||
|
||||
constructor(args: ViewModeArgs) {
|
||||
super(args);
|
||||
super(args, "table");
|
||||
|
||||
this.$root = $(TPL);
|
||||
this.$container = this.$root.find(".table-view-container");
|
||||
@@ -48,7 +49,7 @@ export default class TableView extends ViewMode {
|
||||
const notes = await froca.getNotes(noteIds);
|
||||
|
||||
this.$container.empty();
|
||||
renderTable(this.$container[0], parentNote, notes);
|
||||
renderTable(this.$container[0], parentNote, notes, this.viewStorage);
|
||||
return this.$root;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,25 +1,35 @@
|
||||
import { createGrid, AllCommunityModule, ModuleRegistry, columnDropStyleBordered, GridOptions } from "ag-grid-community";
|
||||
import { createGrid, AllCommunityModule, ModuleRegistry, GridOptions } from "ag-grid-community";
|
||||
import { buildData, type TableData } from "./data.js";
|
||||
import FNote from "../../../entities/fnote.js";
|
||||
import getPromotedAttributeInformation, { PromotedAttributeInformation } from "./parser.js";
|
||||
import getPromotedAttributeInformation from "./parser.js";
|
||||
import { setLabel } from "../../../services/attributes.js";
|
||||
import applyHeaderCustomization from "./header-customization.js";
|
||||
import ViewModeStorage from "../view_mode_storage.js";
|
||||
import { type StateInfo } from "./storage.js";
|
||||
|
||||
ModuleRegistry.registerModules([ AllCommunityModule ]);
|
||||
|
||||
export default function renderTable(el: HTMLElement, parentNote: FNote, notes: FNote[]) {
|
||||
export default async function renderTable(el: HTMLElement, parentNote: FNote, notes: FNote[], storage: ViewModeStorage<StateInfo>) {
|
||||
const info = getPromotedAttributeInformation(parentNote);
|
||||
const viewStorage = await storage.restore();
|
||||
const initialState = viewStorage?.gridState;
|
||||
|
||||
createGrid(el, {
|
||||
...buildData(info, notes),
|
||||
...setupEditing(info),
|
||||
onGridReady(event) {
|
||||
...setupEditing(),
|
||||
initialState,
|
||||
async onGridReady(event) {
|
||||
applyHeaderCustomization(el, event.api);
|
||||
},
|
||||
onStateUpdated(event) {
|
||||
storage.store({
|
||||
gridState: event.api.getState()
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setupEditing(info: PromotedAttributeInformation[]): GridOptions<TableData> {
|
||||
function setupEditing(): GridOptions<TableData> {
|
||||
return {
|
||||
onCellValueChanged(event) {
|
||||
if (event.type !== "cellValueChanged") {
|
||||
@@ -37,3 +47,4 @@ function setupEditing(info: PromotedAttributeInformation[]): GridOptions<TableDa
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { GridState } from "ag-grid-community";
|
||||
|
||||
export interface StateInfo {
|
||||
gridState: GridState;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { EventData } from "../../components/app_context.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import type { ViewTypeOptions } from "../../services/note_list_renderer.js";
|
||||
import ViewModeStorage from "./view_mode_storage.js";
|
||||
|
||||
export interface ViewModeArgs {
|
||||
$parent: JQuery<HTMLElement>;
|
||||
@@ -8,11 +10,18 @@ export interface ViewModeArgs {
|
||||
showNotePath?: boolean;
|
||||
}
|
||||
|
||||
export default abstract class ViewMode {
|
||||
export default abstract class ViewMode<T extends object> {
|
||||
|
||||
constructor(args: ViewModeArgs) {
|
||||
private _viewStorage: ViewModeStorage<T> | null;
|
||||
protected parentNote: FNote;
|
||||
protected viewType: ViewTypeOptions;
|
||||
|
||||
constructor(args: ViewModeArgs, viewType: ViewTypeOptions) {
|
||||
this.parentNote = args.parentNote;
|
||||
this._viewStorage = null;
|
||||
// note list must be added to the DOM immediately, otherwise some functionality scripting (canvas) won't work
|
||||
args.$parent.empty();
|
||||
this.viewType = viewType;
|
||||
}
|
||||
|
||||
abstract renderList(): Promise<JQuery<HTMLElement> | undefined>;
|
||||
@@ -32,4 +41,13 @@ export default abstract class ViewMode {
|
||||
return false;
|
||||
}
|
||||
|
||||
get viewStorage() {
|
||||
if (this._viewStorage) {
|
||||
return this._viewStorage;
|
||||
}
|
||||
|
||||
this._viewStorage = new ViewModeStorage(this.parentNote, this.viewType);
|
||||
return this._viewStorage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
43
apps/client/src/widgets/view_widgets/view_mode_storage.ts
Normal file
43
apps/client/src/widgets/view_widgets/view_mode_storage.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import type FNote from "../../entities/fnote";
|
||||
import type { ViewTypeOptions } from "../../services/note_list_renderer";
|
||||
import server from "../../services/server";
|
||||
|
||||
const ATTACHMENT_ROLE = "viewConfig";
|
||||
|
||||
export default class ViewModeStorage<T extends object> {
|
||||
|
||||
private note: FNote;
|
||||
private attachmentName: string;
|
||||
|
||||
constructor(note: FNote, viewType: ViewTypeOptions) {
|
||||
this.note = note;
|
||||
this.attachmentName = viewType + ".json";
|
||||
}
|
||||
|
||||
async store(data: T) {
|
||||
const payload = {
|
||||
role: ATTACHMENT_ROLE,
|
||||
title: this.attachmentName,
|
||||
mime: "application/json",
|
||||
content: JSON.stringify(data),
|
||||
position: 0
|
||||
};
|
||||
await server.post(`notes/${this.note.noteId}/attachments?matchBy=title`, payload);
|
||||
}
|
||||
|
||||
async restore() {
|
||||
const existingAttachments = await this.note.getAttachmentsByRole(ATTACHMENT_ROLE);
|
||||
if (existingAttachments.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const attachment = existingAttachments
|
||||
.find(a => a.title === this.attachmentName);
|
||||
if (!attachment) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const attachmentData = await server.get<{ content: string } | null>(`attachments/${attachment.attachmentId}/blob`);
|
||||
return JSON.parse(attachmentData?.content ?? "{}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user