chore(react/ribbon): port inherited attributes partially

This commit is contained in:
Elian Doran 2025-08-23 22:02:33 +03:00
parent 9f217b88e4
commit bc4378cb3e
No known key found for this signature in database
4 changed files with 75 additions and 70 deletions

View File

@ -0,0 +1,56 @@
import { useEffect, useState } from "preact/hooks";
import { TabContext } from "./ribbon-interface";
import FAttribute from "../../entities/fattribute";
import { useTriliumEventBeta } from "../react/hooks";
import attributes from "../../services/attributes";
import { t } from "../../services/i18n";
import attribute_renderer from "../../services/attribute_renderer";
import RawHtml from "../react/RawHtml";
import { joinElements } from "../react/react_utils";
export default function InheritedAttributesTab({ note, componentId }: TabContext) {
const [ inheritedAttributes, setInheritedAttributes ] = useState<FAttribute[]>();
function refresh() {
const attrs = note.getAttributes().filter((attr) => attr.noteId !== this.noteId);
attrs.sort((a, b) => {
if (a.noteId === b.noteId) {
return a.position - b.position;
} else {
// inherited attributes should stay grouped: https://github.com/zadam/trilium/issues/3761
return a.noteId < b.noteId ? -1 : 1;
}
});
setInheritedAttributes(attrs);
}
useEffect(refresh, [ note ]);
useTriliumEventBeta("entitiesReloaded", ({ loadResults }) => {
if (loadResults.getAttributeRows(componentId).find((attr) => attributes.isAffecting(attr, this.note))) {
this.refresh();
}
});
return (
<div className="inherited-attributes-widget">
<div className="inherited-attributes-container">
{inheritedAttributes?.length > 0 ? (
joinElements(inheritedAttributes.map(attribute => (
<InheritedAttribute attribute={attribute} />
)), " ")
) : (
<>{t("inherited_attribute_list.no_inherited_attributes")}</>
)}
</div>
</div>
)
}
function InheritedAttribute({ attribute }: { attribute: FAttribute }) {
const [ html, setHtml ] = useState<JQuery<HTMLElement> | string>("");
useEffect(() => {
attribute_renderer.renderAttribute(attribute, false).then(setHtml);
}, []);
return <RawHtml html={html} />
}

View File

@ -20,6 +20,7 @@ import ImagePropertiesTab from "./ImagePropertiesTab";
import NotePathsTab from "./NotePathsTab";
import NoteMapTab from "./NoteMapTab";
import OwnedAttributesTab from "./OwnedAttributesTab";
import InheritedAttributesTab from "./InheritedAttributesTab";
interface TitleContext {
note: FNote | null | undefined;
@ -113,9 +114,11 @@ const TAB_CONFIGURATION = numberObjectsInPlace<TabConfiguration>([
toggleCommand: "toggleRibbonTabOwnedAttributes"
},
{
// InheritedAttributesWidget
title: t("inherited_attribute_list.title"),
icon: "bx bx-list-plus"
icon: "bx bx-list-plus",
content: InheritedAttributesTab,
show: ({note}) => !note?.isLaunchBarConfig(),
toggleCommand: "toggleRibbonTabInheritedAttributes"
},
{
title: t("note_paths.title"),

View File

@ -336,4 +336,17 @@
contain: none;
}
/* #endregion */
/* #region Inherited attributes */
.inherited-attributes-widget {
position: relative;
}
.inherited-attributes-container {
color: var(--muted-text-color);
max-height: 200px;
overflow: auto;
padding: 14px 12px 13px 12px;
}
/* #endregion */

View File

@ -6,37 +6,10 @@ import { t } from "../../services/i18n.js";
import type FNote from "../../entities/fnote.js";
import type { EventData } from "../../components/app_context.js";
const TPL = /*html*/`
<div class="inherited-attributes-widget">
<style>
.inherited-attributes-widget {
position: relative;
}
.inherited-attributes-container {
color: var(--muted-text-color);
max-height: 200px;
overflow: auto;
padding: 14px 12px 13px 12px;
}
</style>
<div class="inherited-attributes-container"></div>
</div>`;
export default class InheritedAttributesWidget extends NoteContextAwareWidget {
private attributeDetailWidget: AttributeDetailWidget;
private $container!: JQuery<HTMLElement>;
get name() {
return "inheritedAttributes";
}
get toggleCommand() {
return "toggleRibbonTabInheritedAttributes";
}
constructor() {
super();
@ -46,32 +19,15 @@ export default class InheritedAttributesWidget extends NoteContextAwareWidget {
this.child(this.attributeDetailWidget);
}
getTitle() {
return {
show: !this.note?.isLaunchBarConfig()
};
}
doRender() {
this.$widget = $(TPL);
this.contentSized();
this.$container = this.$widget.find(".inherited-attributes-container");
this.$widget.append(this.attributeDetailWidget.render());
}
async refreshWithNote(note: FNote) {
this.$container.empty();
const inheritedAttributes = this.getInheritedAttributes(note);
if (inheritedAttributes.length === 0) {
this.$container.append(t("inherited_attribute_list.no_inherited_attributes"));
return;
}
for (const attribute of inheritedAttributes) {
const $attr = (await attributeRenderer.renderAttribute(attribute, false)).on("click", (e) => {
.on("click", (e) => {
setTimeout(
() =>
this.attributeDetailWidget.showAttributeDetail({
@ -89,29 +45,6 @@ export default class InheritedAttributesWidget extends NoteContextAwareWidget {
100
);
});
this.$container.append($attr).append(" ");
}
}
getInheritedAttributes(note: FNote) {
const attrs = note.getAttributes().filter((attr) => attr.noteId !== this.noteId);
attrs.sort((a, b) => {
if (a.noteId === b.noteId) {
return a.position - b.position;
} else {
// inherited attributes should stay grouped: https://github.com/zadam/trilium/issues/3761
return a.noteId < b.noteId ? -1 : 1;
}
});
return attrs;
}
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
if (loadResults.getAttributeRows(this.componentId).find((attr) => attributeService.isAffecting(attr, this.note))) {
this.refresh();
}
}
}