mirror of
https://github.com/zadam/trilium.git
synced 2025-10-20 15:19:01 +02:00
refactor(book_properties): list buttons are now declarative
This commit is contained in:
parent
430ed78d85
commit
196bba9cda
@ -45,31 +45,12 @@ const TPL = /*html*/`
|
|||||||
|
|
||||||
<div class="book-properties-container">
|
<div class="book-properties-container">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="button"
|
|
||||||
class="collapse-all-button btn btn-sm"
|
|
||||||
title="${t("book_properties.collapse_all_notes")}">
|
|
||||||
|
|
||||||
<span class="bx bx-layer-minus"></span>
|
|
||||||
|
|
||||||
${t("book_properties.collapse")}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button type="button"
|
|
||||||
class="expand-children-button btn btn-sm"
|
|
||||||
title="${t("book_properties.expand_all_children")}">
|
|
||||||
<span class="bx bx-move-vertical"></span>
|
|
||||||
|
|
||||||
${t("book_properties.expand")}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default class BookPropertiesWidget extends NoteContextAwareWidget {
|
export default class BookPropertiesWidget extends NoteContextAwareWidget {
|
||||||
|
|
||||||
private $viewTypeSelect!: JQuery<HTMLElement>;
|
private $viewTypeSelect!: JQuery<HTMLElement>;
|
||||||
private $expandChildrenButton!: JQuery<HTMLElement>;
|
|
||||||
private $collapseAllButton!: JQuery<HTMLElement>;
|
|
||||||
private $propertiesContainer!: JQuery<HTMLElement>;
|
private $propertiesContainer!: JQuery<HTMLElement>;
|
||||||
private labelsToWatch: string[] = [];
|
private labelsToWatch: string[] = [];
|
||||||
|
|
||||||
@ -100,33 +81,6 @@ export default class BookPropertiesWidget extends NoteContextAwareWidget {
|
|||||||
this.$viewTypeSelect = this.$widget.find(".view-type-select");
|
this.$viewTypeSelect = this.$widget.find(".view-type-select");
|
||||||
this.$viewTypeSelect.on("change", () => this.toggleViewType(String(this.$viewTypeSelect.val())));
|
this.$viewTypeSelect.on("change", () => this.toggleViewType(String(this.$viewTypeSelect.val())));
|
||||||
|
|
||||||
this.$expandChildrenButton = this.$widget.find(".expand-children-button");
|
|
||||||
this.$expandChildrenButton.on("click", async () => {
|
|
||||||
if (!this.noteId || !this.note) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.note?.isLabelTruthy("expanded")) {
|
|
||||||
await attributeService.addLabel(this.noteId, "expanded");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.triggerCommand("refreshNoteList", { noteId: this.noteId });
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$collapseAllButton = this.$widget.find(".collapse-all-button");
|
|
||||||
this.$collapseAllButton.on("click", async () => {
|
|
||||||
if (!this.noteId || !this.note) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// owned is important - we shouldn't remove inherited expanded labels
|
|
||||||
for (const expandedAttr of this.note.getOwnedLabels("expanded")) {
|
|
||||||
await attributeService.removeAttributeById(this.noteId, expandedAttr.attributeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.triggerCommand("refreshNoteList", { noteId: this.noteId });
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$propertiesContainer = this.$widget.find(".book-properties-container");
|
this.$propertiesContainer = this.$widget.find(".book-properties-container");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,15 +93,15 @@ export default class BookPropertiesWidget extends NoteContextAwareWidget {
|
|||||||
|
|
||||||
this.$viewTypeSelect.val(viewType);
|
this.$viewTypeSelect.val(viewType);
|
||||||
|
|
||||||
this.$expandChildrenButton.toggle(viewType === "list");
|
|
||||||
this.$collapseAllButton.toggle(viewType === "list");
|
|
||||||
|
|
||||||
this.$propertiesContainer.empty();
|
this.$propertiesContainer.empty();
|
||||||
|
|
||||||
const bookPropertiesData = bookPropertiesConfig[viewType];
|
const bookPropertiesData = bookPropertiesConfig[viewType];
|
||||||
if (bookPropertiesData) {
|
if (bookPropertiesData) {
|
||||||
for (const property of bookPropertiesData.properties) {
|
for (const property of bookPropertiesData.properties) {
|
||||||
this.$propertiesContainer.append(renderBookProperty(property, note));
|
this.$propertiesContainer.append(renderBookProperty(property, {
|
||||||
|
note: this.note,
|
||||||
|
triggerCommand: this.triggerCommand.bind(this)
|
||||||
|
}));
|
||||||
this.labelsToWatch.push(property.bindToLabel);
|
this.labelsToWatch.push(property.bindToLabel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,34 @@
|
|||||||
|
import { t } from "i18next";
|
||||||
import FNote from "../../entities/fnote";
|
import FNote from "../../entities/fnote";
|
||||||
import attributes from "../../services/attributes";
|
import attributes from "../../services/attributes";
|
||||||
import { ViewTypeOptions } from "../../services/note_list_renderer"
|
import { ViewTypeOptions } from "../../services/note_list_renderer"
|
||||||
|
import NoteContextAwareWidget from "../note_context_aware_widget";
|
||||||
|
|
||||||
|
type BookProperty = CheckBoxProperty | ButtonProperty;
|
||||||
|
|
||||||
interface BookConfig {
|
interface BookConfig {
|
||||||
properties: BookProperty[]
|
properties: BookProperty[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BookProperty {
|
interface CheckBoxProperty {
|
||||||
label: string;
|
|
||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
|
label: string;
|
||||||
bindToLabel: string
|
bindToLabel: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ButtonProperty {
|
||||||
|
type: "button",
|
||||||
|
label: string;
|
||||||
|
title?: string;
|
||||||
|
icon?: string;
|
||||||
|
onClick: (context: BookContext) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BookContext {
|
||||||
|
note: FNote;
|
||||||
|
triggerCommand: NoteContextAwareWidget["triggerCommand"];
|
||||||
|
}
|
||||||
|
|
||||||
export const bookPropertiesConfig: Record<ViewTypeOptions, BookConfig> = {
|
export const bookPropertiesConfig: Record<ViewTypeOptions, BookConfig> = {
|
||||||
calendar: {
|
calendar: {
|
||||||
properties: [
|
properties: [
|
||||||
@ -26,16 +43,49 @@ export const bookPropertiesConfig: Record<ViewTypeOptions, BookConfig> = {
|
|||||||
bindToLabel: "calendar:weekNumbers"
|
bindToLabel: "calendar:weekNumbers"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
label: t("book_properties.collapse"),
|
||||||
|
title: t("book_properties.collapse_all_notes"),
|
||||||
|
type: "button",
|
||||||
|
icon: "bx bx-layer-minus",
|
||||||
|
async onClick({ note, triggerCommand }) {
|
||||||
|
const { noteId } = note;
|
||||||
|
|
||||||
|
// owned is important - we shouldn't remove inherited expanded labels
|
||||||
|
for (const expandedAttr of note.getOwnedLabels("expanded")) {
|
||||||
|
await attributes.removeAttributeById(noteId, expandedAttr.attributeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerCommand("refreshNoteList", { noteId: noteId });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("book_properties.expand"),
|
||||||
|
title: t("book_properties.expand_all_children"),
|
||||||
|
type: "button",
|
||||||
|
icon: "bx bx-move-vertical",
|
||||||
|
async onClick({ note, triggerCommand }) {
|
||||||
|
const { noteId } = note;
|
||||||
|
if (!note.isLabelTruthy("expanded")) {
|
||||||
|
await attributes.addLabel(noteId, "expanded");
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerCommand("refreshNoteList", { noteId });
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export function renderBookProperty(property: BookProperty, note: FNote) {
|
export function renderBookProperty(property: BookProperty, context: BookContext) {
|
||||||
const $container = $("<div>");
|
const $container = $("<div>");
|
||||||
const $label = $("<label>").text(property.label);
|
const { note } = context;
|
||||||
$container.append($label);
|
|
||||||
|
|
||||||
switch (property.type) {
|
switch (property.type) {
|
||||||
case "checkbox":
|
case "checkbox":
|
||||||
|
const $label = $("<label>").text(property.label);
|
||||||
const $checkbox = $("<input>", {
|
const $checkbox = $("<input>", {
|
||||||
type: "checkbox",
|
type: "checkbox",
|
||||||
class: "form-check-input",
|
class: "form-check-input",
|
||||||
@ -49,9 +99,24 @@ export function renderBookProperty(property: BookProperty, note: FNote) {
|
|||||||
});
|
});
|
||||||
$checkbox.prop("checked", note.hasOwnedLabel(property.bindToLabel));
|
$checkbox.prop("checked", note.hasOwnedLabel(property.bindToLabel));
|
||||||
$label.prepend($checkbox);
|
$label.prepend($checkbox);
|
||||||
|
$container.append($label);
|
||||||
|
break;
|
||||||
|
case "button":
|
||||||
|
const $button = $("<button>", {
|
||||||
|
type: "button",
|
||||||
|
class: "btn btn-sm"
|
||||||
|
}).text(property.label);
|
||||||
|
if (property.title) {
|
||||||
|
$button.attr("title", property.title);
|
||||||
|
}
|
||||||
|
if (property.icon) {
|
||||||
|
$button.prepend($("<span>", { class: property.icon }));
|
||||||
|
}
|
||||||
|
$button.on("click", () => {
|
||||||
|
property.onClick(context);
|
||||||
|
});
|
||||||
|
$container.append($button);
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
throw new Error(`Unknown property type: ${property.type}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $container;
|
return $container;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user