feat(react/ribbon): finalize port of inherited attributes tab

This commit is contained in:
Elian Doran 2025-08-23 22:18:04 +03:00
parent 17cd2128fd
commit 652114c7b5
No known key found for this signature in database
4 changed files with 39 additions and 57 deletions

View File

@ -6,6 +6,7 @@ interface RawHtmlProps {
className?: string; className?: string;
html?: HTMLElementLike; html?: HTMLElementLike;
style?: CSSProperties; style?: CSSProperties;
onClick?: (e: MouseEvent) => void;
} }
export default function RawHtml(props: RawHtmlProps) { export default function RawHtml(props: RawHtmlProps) {
@ -16,11 +17,12 @@ export function RawHtmlBlock(props: RawHtmlProps) {
return <div {...getProps(props)} /> return <div {...getProps(props)} />
} }
function getProps({ className, html, style }: RawHtmlProps) { function getProps({ className, html, style, onClick }: RawHtmlProps) {
return { return {
className: className, className: className,
dangerouslySetInnerHTML: getHtml(html ?? ""), dangerouslySetInnerHTML: getHtml(html ?? ""),
style style,
onClick
} }
} }

View File

@ -1,15 +1,17 @@
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { TabContext } from "./ribbon-interface"; import { TabContext } from "./ribbon-interface";
import FAttribute from "../../entities/fattribute"; import FAttribute from "../../entities/fattribute";
import { useTriliumEventBeta } from "../react/hooks"; import { useLegacyWidget, useTriliumEventBeta } from "../react/hooks";
import attributes from "../../services/attributes"; import attributes from "../../services/attributes";
import { t } from "../../services/i18n"; import { t } from "../../services/i18n";
import attribute_renderer from "../../services/attribute_renderer"; import attribute_renderer from "../../services/attribute_renderer";
import RawHtml from "../react/RawHtml"; import RawHtml from "../react/RawHtml";
import { joinElements } from "../react/react_utils"; import { joinElements } from "../react/react_utils";
import AttributeDetailWidget from "../attribute_widgets/attribute_detail";
export default function InheritedAttributesTab({ note, componentId }: TabContext) { export default function InheritedAttributesTab({ note, componentId }: TabContext) {
const [ inheritedAttributes, setInheritedAttributes ] = useState<FAttribute[]>(); const [ inheritedAttributes, setInheritedAttributes ] = useState<FAttribute[]>();
const [ attributeDetailWidgetEl, attributeDetailWidget ] = useLegacyWidget(() => new AttributeDetailWidget());
function refresh() { function refresh() {
const attrs = note.getAttributes().filter((attr) => attr.noteId !== this.noteId); const attrs = note.getAttributes().filter((attr) => attr.noteId !== this.noteId);
@ -37,20 +39,47 @@ export default function InheritedAttributesTab({ note, componentId }: TabContext
<div className="inherited-attributes-container"> <div className="inherited-attributes-container">
{inheritedAttributes?.length > 0 ? ( {inheritedAttributes?.length > 0 ? (
joinElements(inheritedAttributes.map(attribute => ( joinElements(inheritedAttributes.map(attribute => (
<InheritedAttribute attribute={attribute} /> <InheritedAttribute
attribute={attribute}
onClick={(e) => {
setTimeout(
() =>
attributeDetailWidget.showAttributeDetail({
attribute: {
noteId: attribute.noteId,
type: attribute.type,
name: attribute.name,
value: attribute.value,
isInheritable: attribute.isInheritable
},
isOwned: false,
x: e.pageX,
y: e.pageY
}),
100
);
}}
/>
)), " ") )), " ")
) : ( ) : (
<>{t("inherited_attribute_list.no_inherited_attributes")}</> <>{t("inherited_attribute_list.no_inherited_attributes")}</>
)} )}
</div> </div>
{attributeDetailWidgetEl}
</div> </div>
) )
} }
function InheritedAttribute({ attribute }: { attribute: FAttribute }) { function InheritedAttribute({ attribute, onClick }: { attribute: FAttribute, onClick: (e: MouseEvent) => void }) {
const [ html, setHtml ] = useState<JQuery<HTMLElement> | string>(""); const [ html, setHtml ] = useState<JQuery<HTMLElement> | string>("");
useEffect(() => { useEffect(() => {
attribute_renderer.renderAttribute(attribute, false).then(setHtml); attribute_renderer.renderAttribute(attribute, false).then(setHtml);
}, []); }, []);
return <RawHtml html={html} /> return (
<RawHtml
html={html}
onClick={onClick}
/>
);
} }

View File

@ -332,7 +332,8 @@
margin: 0 !important; margin: 0 !important;
} }
.attribute-list .attr-detail { .attribute-list .attr-detail,
.inherited-attributes-widget .attr-detail {
contain: none; contain: none;
} }

View File

@ -1,50 +0,0 @@
import NoteContextAwareWidget from "../note_context_aware_widget.js";
import AttributeDetailWidget from "../attribute_widgets/attribute_detail.js";
import attributeRenderer from "../../services/attribute_renderer.js";
import attributeService from "../../services/attributes.js";
import { t } from "../../services/i18n.js";
import type FNote from "../../entities/fnote.js";
import type { EventData } from "../../components/app_context.js";
export default class InheritedAttributesWidget extends NoteContextAwareWidget {
private attributeDetailWidget: AttributeDetailWidget;
constructor() {
super();
this.attributeDetailWidget = new AttributeDetailWidget().contentSized().setParent(this);
this.child(this.attributeDetailWidget);
}
doRender() {
this.contentSized();
this.$widget.append(this.attributeDetailWidget.render());
}
async refreshWithNote(note: FNote) {
for (const attribute of inheritedAttributes) {
.on("click", (e) => {
setTimeout(
() =>
this.attributeDetailWidget.showAttributeDetail({
attribute: {
noteId: attribute.noteId,
type: attribute.type,
name: attribute.name,
value: attribute.value,
isInheritable: attribute.isInheritable
},
isOwned: false,
x: e.pageX,
y: e.pageY
}),
100
);
});
}
}
}