From 15e8379302c76620abfc106cd164eacdc86879e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Jusevi=C4=8Dius?= Date: Wed, 15 Apr 2026 23:45:50 +0200 Subject: [PATCH 01/10] Add external document tabs and fix related CSS/XPath regressions (#293) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Render proxied external documents in tab panes (bs2:TabBody/ldh:CreateTab/ldh:ActivateTab/ldh:RenderTabPane) - Convert breadcrumb-nav from id to CSS class to support per-pane breadcrumbs; populate breadcrumbs in external tab panes; extract ldh:PopulateBreadcrumbNav named template to DRY up local/external breadcrumb logic - Fix CSS block border selectors: #content-body → .content-body, add intermediate container-fluid level - Narrow btn-edit and btn-create-chart match patterns to require .block ancestor, preventing false matches on action-bar - Fix drag handler match patterns: update stale direct-child path to match new two-level content-body/container-fluid/block structure - Fix modal content-body lookup: use ancestor:: for action-bar buttons, active tab-pane for global buttons, so modals append to the visible pane for proxied documents - Remove dead document-mode-tabs template and broken progress bar update targeting hidden #content-body - Remove unused getModes() override from XSLTWriterBase Co-Authored-By: Claude Sonnet 4.6 --- .../linkeddatahub/writer/XSLTWriterBase.java | 17 - .../atomgraph/linkeddatahub/css/bootstrap.css | 26 +- .../xsl/bootstrap/2.3.2/admin/acl/layout.xsl | 12 - .../xsl/bootstrap/2.3.2/client/block.xsl | 235 ++++---- .../bootstrap/2.3.2/client/block/chart.xsl | 2 +- .../bootstrap/2.3.2/client/block/query.xsl | 2 +- .../xsl/bootstrap/2.3.2/client/form.xsl | 28 +- .../xsl/bootstrap/2.3.2/client/functions.xsl | 45 +- .../bootstrap/2.3.2/client/merge-rdfxml.xsl | 2 +- .../xsl/bootstrap/2.3.2/client/modal.xsl | 10 +- .../xsl/bootstrap/2.3.2/document.xsl | 160 +++++- .../xsl/bootstrap/2.3.2/imports/default.xsl | 33 +- .../xsl/bootstrap/2.3.2/layout.xsl | 183 ++----- .../xsl/bootstrap/2.3.2/resource.xsl | 4 +- .../atomgraph/linkeddatahub/xsl/client.xsl | 511 +++++++++++++----- 15 files changed, 770 insertions(+), 500 deletions(-) diff --git a/src/main/java/com/atomgraph/linkeddatahub/writer/XSLTWriterBase.java b/src/main/java/com/atomgraph/linkeddatahub/writer/XSLTWriterBase.java index 00818c9de..31d319233 100644 --- a/src/main/java/com/atomgraph/linkeddatahub/writer/XSLTWriterBase.java +++ b/src/main/java/com/atomgraph/linkeddatahub/writer/XSLTWriterBase.java @@ -90,7 +90,6 @@ public abstract class XSLTWriterBase extends com.atomgraph.client.writer.XSLTWri @Inject jakarta.inject.Provider> application; @Inject jakarta.inject.Provider dataManager; @Inject jakarta.inject.Provider xsltExecSupplier; - @Inject jakarta.inject.Provider> modes; @Inject jakarta.inject.Provider crc; @Inject jakarta.inject.Provider> authorizationContext; @@ -314,22 +313,6 @@ public XsltExecutable getXsltExecutable() return xsltExecSupplier.get().get(); } - @Override - public List getModes(Set namespaces) - { - return getModes().stream().map(Mode::get).collect(Collectors.toList()); - } - - /** - * Returns a list of enabled layout modes. - * - * @return list of modes - */ - public List getModes() - { - return modes.get(); - } - @Override public Set getSupportedNamespaces() { diff --git a/src/main/webapp/static/com/atomgraph/linkeddatahub/css/bootstrap.css b/src/main/webapp/static/com/atomgraph/linkeddatahub/css/bootstrap.css index c4e40f8f1..963a7a93d 100644 --- a/src/main/webapp/static/com/atomgraph/linkeddatahub/css/bootstrap.css +++ b/src/main/webapp/static/com/atomgraph/linkeddatahub/css/bootstrap.css @@ -1,5 +1,16 @@ html { height: 100%; } -body { height: calc(100% - 120px); padding-top: 120px; padding-bottom: 0; } +/* only the main navbar is fixed-top now; tab bar + action bar are sticky inside #tab-body */ +body { height: calc(100% - 55px); padding-top: 55px; padding-bottom: 0; } +#tab-bar { position: sticky; top: 55px; z-index: 1000; margin-bottom: 0; } +/* Override Bootstrap's overflow:auto which would make action-bar sticky relative to #tab-content instead of the viewport */ +#tab-content { overflow: visible; } +#tab-bar .navbar-inner { min-height: 36px; padding: 4px 0; background: #ccc; box-shadow: none; } +#tab-bar .nav-tabs { border-bottom: none; } +#tab-bar .nav-tabs > li > a { padding: 4px 10px; max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #555; display: inline-block; } +#tab-bar .nav-tabs > li > a:hover { color: #222; } +#tab-bar .nav-tabs > li.active > a, #tab-bar .nav-tabs > li.active > a:hover { color: #333; background-color: #fff; border-color: #aaa #aaa transparent; } +#tab-bar .tab-close { margin-left: 4px; font-size: 10px; color: #888; cursor: pointer; vertical-align: middle; } +#tab-bar .tab-close:hover { color: #333; } body.embed { padding-top: 0; } ul.dropdown-menu { max-height: 26em; overflow-x: hidden; overflow-y: auto; } ul.dropdown-menu ul { margin: 0; } @@ -17,16 +28,17 @@ ul.dropdown-menu ul { margin: 0; } .navbar-form .input-append { margin-top: 10px; } .navbar-form .input-append select { margin-top: 0; height: 34px; } .navbar-form .btn-search { background-image: url('../icons/ic_search_white_24px.svg'); background-position: center center; background-repeat: no-repeat; width: 34px; height: 34px; } -.action-bar { background-color: #dfdfdf; } +.action-bar { position: sticky; top: var(--action-bar-top, 55px); z-index: 999; background: #dfdfdf; padding: 0; box-shadow: none; } .action-bar form { margin-bottom: 0; } .action-bar .span7 .row-fluid > * { margin-top: 10px; } +.action-bar .row-fluid > .span2, .action-bar .row-fluid > .span3 { margin-top: 10px; } .action-bar .add-constructor, .dropdown-menu .add-constructor { background-color: inherit; display: block; text-align: left; width: 100%; } .action-bar .add-constructor:hover { color: #ffffff; background-color: #007af5; } .action-bar .breadcrumb { background-color: inherit; margin-bottom: 0; padding-left: 0; padding-top: 5px; } .action-bar .breadcrumb .container-logo { background-image: url('../icons/folder.svg'); background-position: left center; background-repeat: no-repeat; padding-left: 28px; } .action-bar .breadcrumb .item-logo { background-image: url('../icons/file.svg'); background-position: left center; background-repeat: no-repeat; padding-left: 28px; } .action-bar .breadcrumb .btn-group { margin-top: -4px; } -.action-bar #breadcrumb-nav > .label-info { padding: 8px 15px; margin-right: 8px; font-size: inherit; background-color: #9954bb; } +.action-bar .breadcrumb-nav > .label-info { padding: 8px 15px; margin-right: 8px; font-size: inherit; background-color: #9954bb; } .action-bar #doc-controls { text-align: right; padding-top: 5px; } .action-bar #doc-controls .btn-edit { margin-top: -5px; margin-left: 10px; } .action-bar p.alert { margin-bottom: 0; } @@ -107,10 +119,10 @@ li button.btn-edit-constructors, li button.btn-add-data, li button.btn-add-ontol .caret.caret-reversed { border-bottom: 4px solid #000000; border-top-width: 0; } .faceted-nav input[type=checkbox]:checked + span { font-weight: bold; } .parallax-nav a { cursor: pointer; } -#content-body { min-height: calc(100% - 14em); } -#content-body > [about].row-fluid { overflow-x: auto; margin-bottom: 20px; } -#content-body > [about].row-fluid, .constructor-triple.row-fluid { border-bottom: 2px solid rgb(223, 223, 223); } -#content-body > [about].row-fluid.drag-over { border-bottom: 4px dotted #0f82f5; } +.content-body { min-height: calc(100% - 14em); } +.content-body > [about] > [about].row-fluid { overflow-x: auto; margin-bottom: 20px; } +.content-body > [about] > [about].row-fluid, .constructor-triple.row-fluid { border-bottom: 2px solid rgb(223, 223, 223); } +.content-body > [about] > [about].row-fluid.drag-over { border-bottom: 4px dotted #0f82f5; } .row-fluid.block { max-height: 80em; } .row-fluid.block .drag-handle { display: none; width: 30px; background-color: #149bdf; background-image: radial-gradient(circle at 3px 3px, #0480be 1px, transparent 1.5px); background-size: 6px 6px; border-radius: 2px; cursor: move; } .list-mode.active { background-image: url('../icons/ic_navigate_before_black_24px.svg'); } diff --git a/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/admin/acl/layout.xsl b/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/admin/acl/layout.xsl index 0c4a69c4f..08664947c 100644 --- a/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/admin/acl/layout.xsl +++ b/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/admin/acl/layout.xsl @@ -32,18 +32,6 @@ exclude-result-prefixes="#all">