From 5da9a8e39d5aefb4780eee1a87eeed5b5bc7bd4f Mon Sep 17 00:00:00 2001 From: delchev Date: Wed, 22 Jul 2026 23:07:26 +0300 Subject: [PATCH 1/2] feat(intent+harmonia): process task-form UX - full-height layout, status step indicator, dialog close icon Three fixes to the BPM task-form experience (a form opened in the app-wide task dialog): 1. Form layout (template-form-builder-harmonia/ui/index.html.template): drop the hard-coded `max-width: 720px` and let the form fill the dialog; the body is a flex column and, on a task form, the card grows to full height with the action buttons pulled into a bottom-pinned footer. The 720px cap left the form floating tiny in the top-left of the full-screen dialog. 2. Document status step indicator (FormIntentGenerator + the same template): a task form whose bound entity has a `function: EntityStatus` relation now renders a read-only horizontal `x-h-step-indicator` of the document's status flow, active = the current status. The steps are extracted from the intent - the status entity's base seed rows in order, dropping terminal cancel/reject/void-style statuses (the same heuristic the badge colouring uses). Emitted as `metadata.steps` + `metadata.statusVar`; skipped for a cross-model status entity or a <2-step flow. Requires harmonia 2.6.0 (dynamic step number, harmonia #45). New FormStepIndicatorTest covers the emission (ordered non-terminal steps, translation seeds ignored, none on a non-task form). 3. Dialog close button icon (13 shell / page-view templates + static shells): every `x-h-dialog-close` button was emitted empty, so the close control was invisible (only its focus ring showed). Added the standard `` glyph to all of them (application / my / partner shells, the document/master/manage/form views, and the document dialogs). Co-Authored-By: Claude Opus 4.8 --- .../generator/form/FormIntentGenerator.java | 90 ++++++++++++++++- .../generator/form/FormStepIndicatorTest.java | 97 +++++++++++++++++++ .../shell/views/_documents.html | 6 +- .../META-INF/dirigible/application/index.html | 4 +- .../META-INF/dirigible/my/index.html | 4 +- .../META-INF/dirigible/partner/index.html | 4 +- .../ui/my/my-document-view.html.template | 4 +- .../ui/my/my-form-view.html.template | 2 +- .../partner-document-view.html.template | 4 +- .../partner/partner-form-view.html.template | 2 +- .../document/document-view.html.template | 8 +- .../manage/form-view.html.template | 4 +- .../manage/list-view.html.template | 2 +- .../master/master-view.html.template | 2 +- .../ui/shell/index.html.template | 6 +- .../ui/index.html.template | 68 ++++++++++--- 16 files changed, 263 insertions(+), 44 deletions(-) create mode 100644 components/engine/engine-intent/src/test/java/org/eclipse/dirigible/components/intent/generator/form/FormStepIndicatorTest.java diff --git a/components/engine/engine-intent/src/main/java/org/eclipse/dirigible/components/intent/generator/form/FormIntentGenerator.java b/components/engine/engine-intent/src/main/java/org/eclipse/dirigible/components/intent/generator/form/FormIntentGenerator.java index 0791207c898..948d7306a61 100644 --- a/components/engine/engine-intent/src/main/java/org/eclipse/dirigible/components/intent/generator/form/FormIntentGenerator.java +++ b/components/engine/engine-intent/src/main/java/org/eclipse/dirigible/components/intent/generator/form/FormIntentGenerator.java @@ -17,6 +17,7 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; import org.eclipse.dirigible.components.base.helpers.JsonHelper; import org.eclipse.dirigible.components.intent.generator.IntentGenerationContext; @@ -28,6 +29,7 @@ import org.eclipse.dirigible.components.intent.model.IntentModel; import org.eclipse.dirigible.components.intent.model.ProcessIntent; import org.eclipse.dirigible.components.intent.model.RelationIntent; +import org.eclipse.dirigible.components.intent.model.SeedIntent; import org.eclipse.dirigible.components.intent.model.StepIntent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -101,6 +103,13 @@ public class FormIntentGenerator implements IntentTargetGenerator { private static final Logger LOGGER = LoggerFactory.getLogger(FormIntentGenerator.class); + /** + * Terminal / negative status names excluded from the step indicator - a cancel/reject/void is an + * off-path outcome (it stays the status pill), not a forward step. Same heuristic the badge + * colouring uses so the two stay consistent. + */ + private static final Pattern TERMINAL_STATUS = Pattern.compile("(cancel|reject|declin|void|fail|overdue|insufficient|exhaust)"); + @Override public String name() { return "form"; @@ -137,7 +146,7 @@ public void generate(IntentGenerationContext context) { continue; } EntityIntent boundEntity = form.getForEntity() == null ? null : entitiesByName.get(form.getForEntity()); - Map document = buildForm(form, boundEntity, entitiesByName, taskFormNames.contains(form.getName())); + Map document = buildForm(form, boundEntity, entitiesByName, taskFormNames.contains(form.getName()), model); context.writeModelFile(fileName, JsonHelper.toJson(document)); } } @@ -169,10 +178,29 @@ private static Map indexEntities(IntentModel model) { return index; } + /** + * Test seam: build the form documents ({@code form name -> document}) for a parsed model without + * writing any files - so emission (e.g. the status-flow step-indicator metadata) can be asserted. + */ + static Map> buildFormsForTest(IntentModel model) { + Map entitiesByName = indexEntities(model); + Set taskFormNames = taskFormNames(model); + Map> documents = new LinkedHashMap<>(); + for (FormIntent form : model.getForms()) { + if (form.getName() == null || form.getName() + .isBlank()) { + continue; + } + EntityIntent boundEntity = form.getForEntity() == null ? null : entitiesByName.get(form.getForEntity()); + documents.put(form.getName(), buildForm(form, boundEntity, entitiesByName, taskFormNames.contains(form.getName()), model)); + } + return documents; + } + private static Map buildForm(FormIntent form, EntityIntent entity, Map entitiesByName, - boolean isTaskForm) { + boolean isTaskForm, IntentModel model) { Map document = new LinkedHashMap<>(); - document.put("metadata", buildMetadata(form, isTaskForm)); + document.put("metadata", buildMetadata(form, isTaskForm, entity, model)); document.put("feeds", new ArrayList<>()); document.put("scripts", new ArrayList<>()); document.put("code", buildCode(form, isTaskForm)); @@ -186,7 +214,7 @@ private static Map buildForm(FormIntent form, EntityIntent entit * bound entity's logical name and the editable-field set. Only logical model names are emitted - * never a template-engine output path, which the intent layer must stay agnostic about. */ - private static Map buildMetadata(FormIntent form, boolean isTaskForm) { + private static Map buildMetadata(FormIntent form, boolean isTaskForm, EntityIntent entity, IntentModel model) { Map metadata = new LinkedHashMap<>(); if (isTaskForm) { metadata.put("taskForm", true); @@ -194,10 +222,64 @@ private static Map buildMetadata(FormIntent form, boolean isTask metadata.put("entity", form.getForEntity()); } metadata.put("editable", new ArrayList<>(form.getEditable())); + putStatusSteps(metadata, entity, model); } return metadata; } + /** + * The document status flow for the read-only step indicator. When the bound entity has a + * {@code function: EntityStatus} relation to a LOCAL status entity, emit that entity's non-terminal + * status names (its base seed rows, in seed order, dropping cancel/reject/void-style terminal + * statuses via {@link #TERMINAL_STATUS}) as {@code steps}, plus {@code statusVar} - the model + * variable holding the current status name (the relation name). The runtime renders these as a + * horizontal step indicator with the current status active. Skipped when the status entity is + * cross-model (its seeds are not on this model) or the flow has fewer than two steps. + */ + private static void putStatusSteps(Map metadata, EntityIntent entity, IntentModel model) { + if (entity == null || entity.getRelations() == null || model == null) { + return; + } + RelationIntent statusRel = null; + for (RelationIntent relation : entity.getRelations()) { + if (relation.isEntityStatus()) { + statusRel = relation; + break; + } + } + if (statusRel == null || statusRel.getTo() == null) { + return; + } + if (statusRel.getModel() != null && !statusRel.getModel() + .isBlank()) { + return; // cross-model status entity: its seeds live in the owner module, not resolvable here + } + List steps = new ArrayList<>(); + for (SeedIntent seed : model.getSeeds()) { + if (seed.getLanguage() != null || !statusRel.getTo() + .equals(seed.getEntity()) + || seed.getRows() == null) { + continue; // base rows of the status entity only (skip translation seeds) + } + for (Map row : seed.getRows()) { + Object name = row.get("name"); + if (name == null) { + continue; + } + String label = name.toString(); + if (TERMINAL_STATUS.matcher(label.toLowerCase(Locale.ROOT)) + .find()) { + continue; // terminal / off-path status - stays the pill, not a step + } + steps.add(label); + } + } + if (steps.size() >= 2) { + metadata.put("steps", steps); + metadata.put("statusVar", statusRel.getName()); + } + } + /** * The form's actions, with a {@code close} action appended for a BPM task form when the author did * not declare one. {@code close} is a non-completing action - it just closes the form/dialog (the diff --git a/components/engine/engine-intent/src/test/java/org/eclipse/dirigible/components/intent/generator/form/FormStepIndicatorTest.java b/components/engine/engine-intent/src/test/java/org/eclipse/dirigible/components/intent/generator/form/FormStepIndicatorTest.java new file mode 100644 index 00000000000..773739a709d --- /dev/null +++ b/components/engine/engine-intent/src/test/java/org/eclipse/dirigible/components/intent/generator/form/FormStepIndicatorTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2010-2026 Eclipse Dirigible contributors + * + * All rights reserved. This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * SPDX-FileCopyrightText: Eclipse Dirigible contributors SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.dirigible.components.intent.generator.form; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.Map; + +import org.eclipse.dirigible.components.intent.model.IntentModel; +import org.eclipse.dirigible.components.intent.parser.IntentParser; +import org.junit.jupiter.api.Test; + +/** + * Verifies the document-status-flow step-indicator metadata the {@link FormIntentGenerator} emits + * on a BPM task form: the ordered non-terminal status names ({@code steps}) taken from the bound + * entity's {@code function: EntityStatus} relation seeds, plus the current-status variable + * ({@code statusVar}). A terminal (cancel/void/…) status is excluded, translation seeds are + * ignored, and a non-task form gets no steps. + */ +class FormStepIndicatorTest { + + private static final String YAML = """ + name: sales + entities: + - name: OrderStatus + function: Setting + multilingual: true + fields: + - { name: id, type: integer, primaryKey: true, generated: true } + - { name: name, type: string } + - name: SalesOrder + fields: + - { name: id, type: integer, primaryKey: true, generated: true } + relations: + - { name: Status, kind: manyToOne, to: OrderStatus, function: EntityStatus, init: 1 } + processes: + - name: OrderApproval + trigger: { onCreate: SalesOrder } + steps: + - { name: confirm, kind: userTask, args: { assignee: manager, form: ConfirmOrder } } + - { name: end, kind: end } + forms: + - { name: ConfirmOrder, forEntity: SalesOrder, fields: [Status], actions: [confirm] } + - { name: PlainOrder, forEntity: SalesOrder, fields: [Status] } + seeds: + - name: order-statuses + entity: OrderStatus + rows: + - { id: 1, name: DRAFT } + - { id: 2, name: APPROVED } + - { id: 3, name: SHIPPED } + - { id: 4, name: CANCELLED } + - name: order-statuses-bg + entity: OrderStatus + language: bg + rows: + - { id: 1, name: "Чернова" } + """; + + @SuppressWarnings("unchecked") + @Test + void emitsTheStatusFlowStepsOnTheTaskForm() { + IntentModel model = IntentParser.parse(YAML); + Map> forms = FormIntentGenerator.buildFormsForTest(model); + + Map meta = (Map) forms.get("ConfirmOrder") + .get("metadata"); + assertEquals(Boolean.TRUE, meta.get("taskForm")); + // CANCELLED is terminal (excluded); the bg translation seed is ignored; order is seed order. + assertEquals(List.of("DRAFT", "APPROVED", "SHIPPED"), meta.get("steps")); + // The current-status model variable is the EntityStatus relation name. + assertEquals("Status", meta.get("statusVar")); + } + + @SuppressWarnings("unchecked") + @Test + void noStepsOnANonTaskForm() { + IntentModel model = IntentParser.parse(YAML); + Map> forms = FormIntentGenerator.buildFormsForTest(model); + + Map meta = (Map) forms.get("PlainOrder") + .get("metadata"); + assertFalse(meta.containsKey("taskForm")); + assertFalse(meta.containsKey("steps")); + assertTrue(meta.get("statusVar") == null); + } +} diff --git a/components/resources/application-core/src/main/resources/META-INF/dirigible/application-core/shell/views/_documents.html b/components/resources/application-core/src/main/resources/META-INF/dirigible/application-core/shell/views/_documents.html index ec74a220b0a..d4497026c7c 100644 --- a/components/resources/application-core/src/main/resources/META-INF/dirigible/application-core/shell/views/_documents.html +++ b/components/resources/application-core/src/main/resources/META-INF/dirigible/application-core/shell/views/_documents.html @@ -155,7 +155,7 @@
-

+

@@ -173,7 +173,7 @@
-

+

@@ -191,7 +191,7 @@
-

+

Delete ? This cannot be undone.

Delete items? This cannot be undone.

diff --git a/components/resources/resources-application/src/main/resources/META-INF/dirigible/application/index.html b/components/resources/resources-application/src/main/resources/META-INF/dirigible/application/index.html index 3635fe388ea..1ec9fba8c87 100644 --- a/components/resources/resources-application/src/main/resources/META-INF/dirigible/application/index.html +++ b/components/resources/resources-application/src/main/resources/META-INF/dirigible/application/index.html @@ -262,7 +262,7 @@

- +
diff --git a/components/template/template-form-builder-harmonia/src/main/resources/META-INF/dirigible/template-form-builder-harmonia/ui/index.html.template b/components/template/template-form-builder-harmonia/src/main/resources/META-INF/dirigible/template-form-builder-harmonia/ui/index.html.template index e854b255207..ecece5c93b5 100644 --- a/components/template/template-form-builder-harmonia/src/main/resources/META-INF/dirigible/template-form-builder-harmonia/ui/index.html.template +++ b/components/template/template-form-builder-harmonia/src/main/resources/META-INF/dirigible/template-form-builder-harmonia/ui/index.html.template @@ -128,26 +128,71 @@ applied by harmonia.min.js (below), which reads the shared `codbex.harmonia.colorMode` the shell set — so this iframe'd form matches the shell (light/dark) automatically. */ html { background-color: var(--background); color: var(--foreground); } - body { min-height: 100vh; } + /* Fill the host dialog/viewport: the body is a flex column so the form (and, on a task form, + its card) grow to the full height instead of floating at content height in the top-left. */ + body { min-height: 100vh; display: flex; flex-direction: column; } [x-cloak] { display: none !important; } -
+
#if($metadata.taskForm) - -
-
+ +
+
+#if($metadata.steps && $metadata.steps.size() > 0) +
+ + +
+#end +#foreach($element in $form) +#if($element.controlId == "container-hbox") +## action row: rendered as the bottom-pinned footer below (outside the detail grid) +#elseif($element.controlId == "container-vbox") +
+#foreach($child in $element.children) +#leaf($child) +#end +
#else -
+#leaf($element) +#end +#end +
+#foreach($element in $form) +#if($element.controlId == "container-hbox") +
+#foreach($child in $element.children) +#leaf($child) +#end +
+#end #end +
+
+#else +
#foreach($element in $form) #if($element.controlId == "container-hbox")
@@ -165,11 +210,6 @@ #leaf($element) #end #end -#if($metadata.taskForm) -
-
-
-#else
#end From 15c49d6edd6ba95be772df642741b92370a3d8b9 Mon Sep 17 00:00:00 2001 From: delchev Date: Wed, 22 Jul 2026 23:53:16 +0300 Subject: [PATCH 2/2] feat(intent+harmonia): step descriptions from the seed + status stepper on the document page Extends the step-indicator feature: - Step descriptions: a status entity's optional `description` seed column is now surfaced under each step title. FormIntentGenerator emits steps as {label, description} objects (description omitted when blank); the task-form template renders an x-h-step-indicator-description. FormStepIndicatorTest updated to assert the description flows and is absent when the seed row has none. - Single-record document page: the document view now shows the same read-only status flow as a VERTICAL x-h-step-indicator card under the Details box in the right sidebar, active = the current status, descriptions from the same seed column. Driven by two small page.js helpers (statusSteps() = the loaded status options minus terminal ones; activeStep() = 1-based current index) reusing the existing statusVariant() heuristic; the status option map now carries `description`. The title-bar pill is kept. The sidebar renders for a status-bearing document even with no audit/read-only fields. Follow-up (same pattern): the manage/form view (has a sidebar) and the my-document / my-form views (no sidebar - placement TBD). Co-Authored-By: Claude Opus 4.8 --- .../generator/form/FormIntentGenerator.java | 13 +++++++-- .../generator/form/FormStepIndicatorTest.java | 11 +++++--- .../document/document-page.js.template | 17 +++++++++-- .../document/document-view.html.template | 28 ++++++++++++++++++- .../ui/index.html.template | 9 ++++-- 5 files changed, 66 insertions(+), 12 deletions(-) diff --git a/components/engine/engine-intent/src/main/java/org/eclipse/dirigible/components/intent/generator/form/FormIntentGenerator.java b/components/engine/engine-intent/src/main/java/org/eclipse/dirigible/components/intent/generator/form/FormIntentGenerator.java index 948d7306a61..2b4d0c656d6 100644 --- a/components/engine/engine-intent/src/main/java/org/eclipse/dirigible/components/intent/generator/form/FormIntentGenerator.java +++ b/components/engine/engine-intent/src/main/java/org/eclipse/dirigible/components/intent/generator/form/FormIntentGenerator.java @@ -254,7 +254,7 @@ private static void putStatusSteps(Map metadata, EntityIntent en .isBlank()) { return; // cross-model status entity: its seeds live in the owner module, not resolvable here } - List steps = new ArrayList<>(); + List> steps = new ArrayList<>(); for (SeedIntent seed : model.getSeeds()) { if (seed.getLanguage() != null || !statusRel.getTo() .equals(seed.getEntity()) @@ -271,7 +271,16 @@ private static void putStatusSteps(Map metadata, EntityIntent en .find()) { continue; // terminal / off-path status - stays the pill, not a step } - steps.add(label); + Map step = new LinkedHashMap<>(); + step.put("label", label); + Object description = row.get("description"); + if (description != null && !description.toString() + .isBlank()) { + // Optional per-status help text, authored as a `description` seed column on the + // status entity - shown under the step title. Absent -> title only. + step.put("description", description.toString()); + } + steps.add(step); } } if (steps.size() >= 2) { diff --git a/components/engine/engine-intent/src/test/java/org/eclipse/dirigible/components/intent/generator/form/FormStepIndicatorTest.java b/components/engine/engine-intent/src/test/java/org/eclipse/dirigible/components/intent/generator/form/FormStepIndicatorTest.java index 773739a709d..ca93bd83bbe 100644 --- a/components/engine/engine-intent/src/test/java/org/eclipse/dirigible/components/intent/generator/form/FormStepIndicatorTest.java +++ b/components/engine/engine-intent/src/test/java/org/eclipse/dirigible/components/intent/generator/form/FormStepIndicatorTest.java @@ -38,6 +38,7 @@ class FormStepIndicatorTest { fields: - { name: id, type: integer, primaryKey: true, generated: true } - { name: name, type: string } + - { name: description, type: string } - name: SalesOrder fields: - { name: id, type: integer, primaryKey: true, generated: true } @@ -56,10 +57,10 @@ class FormStepIndicatorTest { - name: order-statuses entity: OrderStatus rows: - - { id: 1, name: DRAFT } - - { id: 2, name: APPROVED } + - { id: 1, name: DRAFT, description: Being prepared } + - { id: 2, name: APPROVED, description: Ready to ship } - { id: 3, name: SHIPPED } - - { id: 4, name: CANCELLED } + - { id: 4, name: CANCELLED, description: Called off } - name: order-statuses-bg entity: OrderStatus language: bg @@ -77,7 +78,9 @@ void emitsTheStatusFlowStepsOnTheTaskForm() { .get("metadata"); assertEquals(Boolean.TRUE, meta.get("taskForm")); // CANCELLED is terminal (excluded); the bg translation seed is ignored; order is seed order. - assertEquals(List.of("DRAFT", "APPROVED", "SHIPPED"), meta.get("steps")); + // Each step carries its label plus the optional `description` seed column (absent -> no key). + assertEquals(List.of(Map.of("label", "DRAFT", "description", "Being prepared"), + Map.of("label", "APPROVED", "description", "Ready to ship"), Map.of("label", "SHIPPED")), meta.get("steps")); // The current-status model variable is the EntityStatus relation name. assertEquals("Status", meta.get("statusVar")); } diff --git a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-page.js.template b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-page.js.template index 29295e791ca..a5c5c95a02a 100644 --- a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-page.js.template +++ b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-page.js.template @@ -375,7 +375,7 @@ document.addEventListener('alpine:init', () => { parent: '${property.widgetHierarchyProperty}', leafOnly: true }); #else - this.options${property.name} = (rows${property.name} || []).map(e => ({ value: e.${property.widgetDropDownKey}, text: e.${property.widgetDropDownValue} })); + this.options${property.name} = (rows${property.name} || []).map(e => ({ value: e.${property.widgetDropDownKey}, text: e.${property.widgetDropDownValue}#if($property.widgetType == "DOCUMENT_STATUS"), description: e.description#end })); #end } catch (e) { console.error('[${name}DocumentPage] failed to load options for ${property.name}', e); @@ -415,7 +415,7 @@ document.addEventListener('alpine:init', () => { conditions: [{ propertyName: '${property.widgetDependsOnFilterBy}', operator: 'EQ', value: from }#if($property.widgetOptionsFilterBy), { propertyName: '${property.widgetOptionsFilterBy}', operator: 'EQ', value: ${property.widgetOptionsFilterValueJs} }#end] }, { baseUrl: '' }); - this.options${property.name} = (rows || []).map(e => ({ value: e.${property.widgetDropDownKey}, text: e.${property.widgetDropDownValue} })); + this.options${property.name} = (rows || []).map(e => ({ value: e.${property.widgetDropDownKey}, text: e.${property.widgetDropDownValue}#if($property.widgetType == "DOCUMENT_STATUS"), description: e.description#end })); if (adjust) { this.form.${property.name} = this.options${property.name}.length === 1 ? String(this.options${property.name}[0].value) : ''; } @@ -756,6 +756,19 @@ document.addEventListener('alpine:init', () => { if (/(issu|sent|ship|process|submit)/.test(t)) return 'information'; return 'default'; }, + // Forward status flow for the read-only step indicator: the loaded status options minus the + // terminal / off-path ones (cancel/void/... stay the pill). Each option carries {value, text} and, + // when the status entity has a `description` seed column, `description` (shown under the title). + statusSteps() { + return (this.options${docStatusProp} || []).filter(o => this.statusVariant(o.text) !== 'negative'); + }, + // 1-based index of the current status among the steps (0 when the status is terminal or unset, + // so no step is active). + activeStep() { + const current = this.statusText(); + return this.statusSteps() + .findIndex(o => String(o.text) === String(current)) + 1; + }, #end // Render a line-item date/datetime value through the instance Date/Timestamp patterns (shell format.js). diff --git a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template index 974c425f0b3..f7e19a39128 100644 --- a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template +++ b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template @@ -446,8 +446,9 @@ #foreach($property in $properties) #if($property.isReadOnlyProperty == "true" || ($property.auditType && $property.auditType != "NONE"))#set($hasReadOnly = true)#end #end -#if($hasReadOnly) +#if($hasReadOnly || $docStatusProp != "")
+#if($hasReadOnly)

@@ -468,6 +469,31 @@
+#end +#if($docStatusProp != "") + +
+

+
+ +
+
+#end
#end diff --git a/components/template/template-form-builder-harmonia/src/main/resources/META-INF/dirigible/template-form-builder-harmonia/ui/index.html.template b/components/template/template-form-builder-harmonia/src/main/resources/META-INF/dirigible/template-form-builder-harmonia/ui/index.html.template index ecece5c93b5..487b6d19168 100644 --- a/components/template/template-form-builder-harmonia/src/main/resources/META-INF/dirigible/template-form-builder-harmonia/ui/index.html.template +++ b/components/template/template-form-builder-harmonia/src/main/resources/META-INF/dirigible/template-form-builder-harmonia/ui/index.html.template @@ -153,12 +153,15 @@ -