From b356b355cab71adc8586502bb3de2938875fa058 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Fri, 20 Mar 2026 21:38:38 +0200 Subject: [PATCH] fix(layout): attribute details not visible in new layout (closes #9005) --- .../attribute_widgets/attribute_detail.ts | 53 +++++++++++-------- .../widgets/ribbon/InheritedAttributesTab.tsx | 3 +- .../ribbon/components/AttributeEditor.tsx | 3 +- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/apps/client/src/widgets/attribute_widgets/attribute_detail.ts b/apps/client/src/widgets/attribute_widgets/attribute_detail.ts index 452c6aecc3..73bf2cc2d6 100644 --- a/apps/client/src/widgets/attribute_widgets/attribute_detail.ts +++ b/apps/client/src/widgets/attribute_widgets/attribute_detail.ts @@ -1,18 +1,18 @@ -import { t } from "../../services/i18n.js"; -import server from "../../services/server.js"; -import froca from "../../services/froca.js"; -import linkService from "../../services/link.js"; +import appContext from "../../components/app_context.js"; import attributeAutocompleteService from "../../services/attribute_autocomplete.js"; +import type { Attribute } from "../../services/attribute_parser.js"; +import { isExperimentalFeatureEnabled } from "../../services/experimental_features.js"; +import { focusSavedElement, saveFocusedElement } from "../../services/focus.js"; +import froca from "../../services/froca.js"; +import { t } from "../../services/i18n.js"; +import linkService from "../../services/link.js"; import noteAutocompleteService from "../../services/note_autocomplete.js"; import promotedAttributeDefinitionParser from "../../services/promoted_attribute_definition_parser.js"; -import NoteContextAwareWidget from "../note_context_aware_widget.js"; +import server from "../../services/server.js"; +import shortcutService from "../../services/shortcuts.js"; import SpacedUpdate from "../../services/spaced_update.js"; import utils from "../../services/utils.js"; -import shortcutService from "../../services/shortcuts.js"; -import appContext from "../../components/app_context.js"; -import type { Attribute } from "../../services/attribute_parser.js"; -import { focusSavedElement, saveFocusedElement } from "../../services/focus.js"; -import { isExperimentalFeatureEnabled } from "../../services/experimental_features.js"; +import NoteContextAwareWidget from "../note_context_aware_widget.js"; const TPL = /*html*/`
@@ -29,6 +29,7 @@ const TPL = /*html*/` max-height: 600px; overflow: auto; box-shadow: 10px 10px 93px -25px black; + contain: none; } .attr-help td { @@ -343,6 +344,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget { private $relatedNotesList!: JQuery; private $relatedNotesMoreNotes!: JQuery; private $attrHelp!: JQuery; + private $statusBar?: JQuery; private relatedNotesSpacedUpdate!: SpacedUpdate; private attribute!: Attribute; @@ -577,17 +579,24 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget { return; } - this.$widget - .css("left", detPosition.left) - .css("right", detPosition.right) - .css("top", y - offset.top + 70) - .css("max-height", outerHeight + y > height - 50 ? height - y - 50 : 10000); - if (isNewLayout) { + if (!this.$statusBar) { + this.$statusBar = $(document.body).find(".component.status-bar"); + } + + const statusBarHeight = this.$statusBar.outerHeight() ?? 0; + const maxHeight = document.body.clientHeight - statusBarHeight; this.$widget + .css("left", offset.left + (typeof detPosition.left === "number" ? detPosition.left : 0)) .css("top", "unset") - .css("bottom", 70) - .css("max-height", "80vh"); + .css("bottom", statusBarHeight ?? 0) + .css("max-height", maxHeight); + } else { + this.$widget + .css("left", detPosition.left) + .css("right", detPosition.right) + .css("top", y - offset.top + 70) + .css("max-height", outerHeight + y > height - 50 ? height - y - 50 : 10000); } if (focus === "name") { @@ -695,14 +704,14 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget { return "label-definition"; } else if (attribute.name.startsWith("relation:")) { return "relation-definition"; - } else { - return "label"; } + return "label"; + } else if (attribute.type === "relation") { return "relation"; - } else { - this.$title.text(""); } + this.$title.text(""); + } updateAttributeInEditor() { diff --git a/apps/client/src/widgets/ribbon/InheritedAttributesTab.tsx b/apps/client/src/widgets/ribbon/InheritedAttributesTab.tsx index fcee7c1da1..4e2257c146 100644 --- a/apps/client/src/widgets/ribbon/InheritedAttributesTab.tsx +++ b/apps/client/src/widgets/ribbon/InheritedAttributesTab.tsx @@ -1,3 +1,4 @@ +import { createPortal } from "preact/compat"; import { useEffect, useState } from "preact/hooks"; import FAttribute from "../../entities/fattribute"; @@ -74,7 +75,7 @@ export default function InheritedAttributesTab({ note, componentId, emptyListStr )}
- {attributeDetailWidgetEl} + {createPortal(attributeDetailWidgetEl, document.body)} ); } diff --git a/apps/client/src/widgets/ribbon/components/AttributeEditor.tsx b/apps/client/src/widgets/ribbon/components/AttributeEditor.tsx index 3871e0790d..18c4a3b93a 100644 --- a/apps/client/src/widgets/ribbon/components/AttributeEditor.tsx +++ b/apps/client/src/widgets/ribbon/components/AttributeEditor.tsx @@ -1,5 +1,6 @@ import { AttributeEditor as CKEditorAttributeEditor, MentionFeed, ModelElement, ModelNode, ModelPosition } from "@triliumnext/ckeditor5"; import { AttributeType } from "@triliumnext/commons"; +import { createPortal } from "preact/compat"; import { MutableRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from "preact/hooks"; import type { CommandData, FilteredCommandNames } from "../../../components/app_context"; @@ -407,7 +408,7 @@ export default function AttributeEditor({ api, note, componentId, notePath, ntxI )} } - {attributeDetailWidgetEl} + {createPortal(attributeDetailWidgetEl, document.body)} ); }