Skip to content

feat(intent): document (header-items) layout + aggregate totals + kebab table-name fix - #6091

Merged
delchev merged 3 commits into
feat/intent-cross-model-referencesfrom
feat/intent-document-layout
Jun 27, 2026
Merged

feat(intent): document (header-items) layout + aggregate totals + kebab table-name fix#6091
delchev merged 3 commits into
feat/intent-cross-model-referencesfrom
feat/intent-document-layout

Conversation

@delchev

@delchev delchev commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Stacked on #6089 (feat/intent-cross-model-references) - base is that branch, so the diff here is only the document-layout work.

Changes

  • Kebab-case table-name fix (IntentNaming.upperSnake): collapse any run of non-alphanumeric separators (-, space, ., /) to a single underscore so a kebab-case intent/project name produces a valid SQL identifier - sales-invoicesSALES_INVOICES, not the invalid SALES-INVOICES (an unquoted - breaks table creation). Pure-identifier entity/field names are unaffected. This is needed by the hyphenated sample model names.
  • Document (header-items) layout: a master that owns a composition child whose name ends in Item (e.g. SalesInvoiceSalesInvoiceItem) is emitted with layoutType: MANAGE_DOCUMENT + documentItemsEntity, so it renders as a document - header form, inline items table, totals footer - instead of the default master-detail. The items child stays a DEPENDENT detail. generateUtils gains a uiDocumentModels collection.
  • aggregate: true field attribute: emits an aggregate render hint so a (typically calculated) total appears in the document's totals footer rather than the header form. Presentational only.
  • Sample: SalesInvoice totals (net/vat/gross/discount/total/paid) marked aggregate: true.

Verification

  • Unit: mvn -pl components/engine/engine-intent test (21 pass), incl. new assertions that SalesInvoice gets MANAGE_DOCUMENT + documentItemsEntity: SalesInvoiceItem, that aggregate fields carry the hint, and that the items child stays MANAGE_DETAILS.

Note / follow-up

The Harmonia template does not yet have a generator bound to the new uiDocumentModels collection, so a MANAGE_DOCUMENT master currently produces no UI from the Harmonia recipe (it's excluded from the MANAGE/MANAGE_MASTER collections). The document view template is the remaining piece. This also interacts with the shared-shell PR (#6090), which keys perspectives off the manage/master collections - a MANAGE_DOCUMENT entity would need adding there too.

🤖 Generated with Claude Code

delchev and others added 3 commits June 27, 2026 18:39
…ab table-name fix

- IntentNaming.upperSnake now collapses non-alphanumeric separators (-, space, ., /)
  to a single underscore, so a kebab-case intent/project name yields a valid SQL
  identifier (sales-invoices -> SALES_INVOICES, not the invalid SALES-INVOICES that
  breaks table creation). Pure-identifier entity/field names are unaffected.
- Document (header-items) layout: a master that owns a composition child whose name
  ends in "Item" (SalesInvoice -> SalesInvoiceItem) is emitted with layoutType
  MANAGE_DOCUMENT + documentItemsEntity, so it renders as a document (header form,
  inline items table, totals footer) instead of the default master-detail. The items
  child stays a DEPENDENT detail. generateUtils gains a uiDocumentModels collection.
- New field attribute `aggregate: true` -> emits an "aggregate" render hint so a
  (typically calculated) total shows in the document's totals footer, not the header
  form. Presentational only.
- Billing sample: SalesInvoice totals marked aggregate. Tests cover the document
  layout, documentItemsEntity, and the aggregate hint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The document (header-items) view templates and the kebab-fix unit test that were not
captured by the earlier diff: document.js manifest, document-page.js + document-view
templates, and IntentNamingTest (3 cases). NOTE: document.js is not yet imported in
template/ui/template.js and index.html.template has no MANAGE_DOCUMENT route branch,
so the document UI does not generate yet - wiring is the remaining step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…es' into feat/intent-document-layout

# Conflicts:
#	components/engine/engine-intent/src/main/java/org/eclipse/dirigible/components/intent/generator/edm/EdmIntentGenerator.java
@delchev
delchev merged commit 1b853c6 into feat/intent-cross-model-references Jun 27, 2026
9 checks passed
@delchev
delchev deleted the feat/intent-document-layout branch June 27, 2026 18:45
delchev added a commit that referenced this pull request Jun 27, 2026
…attributes (#6089)

* feat(intent): cross-model entity references, n:m, and faithful field attributes

Lets a multi-project app (e.g. Billing: uoms, countries, currencies, customers,
customer-payments, sales-invoices) be authored as separate .intent models that
reference each other cross-model, reusing the proven PROJECTION mechanism.

Tranche A - cross-model references:
- New top-level `uses:` block (UsesIntent) + optional `model:` on a relation.
- Parser allows a to-one relation to target an entity in a declared uses model
  (forbids cross-model composition; rejects undeclared models).
- EdmIntentGenerator emits a PROJECTION entity per cross-model target (owner
  table + PK resolved from the owner .model when present, else by convention)
  plus an integer FK + dropdown; projections carry no perspective so they stay
  out of the consuming app's nav. No template changes (existing parameterUtils /
  generateUtils / schema template already handle PROJECTION).
- workspaceName plumbed through endpoint -> service -> context for the
  projectionReferencedModel path.

Tranche B - n:m via an explicit intermediate entity (composition to one side,
cross-model manyToOne to the other, plus bridge fields like Amount). Reuses the
composition + cross-model paths; no extra generator logic.

Tranche C - faithful field attributes: FieldIntent unique / precision / scale /
calculatedOnCreate / calculatedOnUpdate, and entity-level `audit: true` (emits the
four standard audit columns). EdmIntentGenerator emits dataUnique, precision/scale,
isCalculatedProperty + calculatedPropertyExpression*, and auditType.

Includes the 6 Billing example .intent files (test resources), parser + EDM
generator unit tests (21 pass), and intent-assistant-guide.md docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(intent): contribute generated apps to one shared shell, grouped (#6090)

Multi-project intent apps generated a standalone Harmonia shell each, forcing the
user to jump between per-domain UIs. This makes each project ALSO contribute its
entities as perspectives to the platform's shared application shell, grouped, so
they appear as one app. The standalone per-project shell is unchanged (still ideal
for an all-in-one model and for testing a domain in isolation).

- New entity-level `group:` (EntityIntent.group); EdmIntentGenerator sets the
  perspective's groupId (perspectiveNavId) from it.
- Harmonia template emits a per-entity perspective .js + .extension registered to
  `application-perspectives` (namespaced id, groupId, path = this project's own SPA
  route in embedded mode), across the list/manage/master/setting collections.
- Harmonia shell gains an embedded (chromeless) mode: when loaded with ?embedded
  (how the shared shell hosts a perspective) it hides its own sidebar so the shared
  shell provides the single chrome. Standalone mode unaffected.
- Navigation groups are defined once (a dedicated navigation-groups project that
  exports getPerspectiveGroup per id); entities only reference the id - avoids the
  shell's duplicate-group-id drop.
- Billing example models tagged with groups (master-data / sales / payments /
  settings); guide documents `group:`.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* feat(intent): document (header-items) layout + aggregate totals + kebab table-name fix (#6091)

* feat(intent): document (header-items) layout + aggregate totals + kebab table-name fix

- IntentNaming.upperSnake now collapses non-alphanumeric separators (-, space, ., /)
  to a single underscore, so a kebab-case intent/project name yields a valid SQL
  identifier (sales-invoices -> SALES_INVOICES, not the invalid SALES-INVOICES that
  breaks table creation). Pure-identifier entity/field names are unaffected.
- Document (header-items) layout: a master that owns a composition child whose name
  ends in "Item" (SalesInvoice -> SalesInvoiceItem) is emitted with layoutType
  MANAGE_DOCUMENT + documentItemsEntity, so it renders as a document (header form,
  inline items table, totals footer) instead of the default master-detail. The items
  child stays a DEPENDENT detail. generateUtils gains a uiDocumentModels collection.
- New field attribute `aggregate: true` -> emits an "aggregate" render hint so a
  (typically calculated) total shows in the document's totals footer, not the header
  form. Presentational only.
- Billing sample: SalesInvoice totals marked aggregate. Tests cover the document
  layout, documentItemsEntity, and the aggregate hint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add document-layout UI templates + IntentNaming test

The document (header-items) view templates and the kebab-fix unit test that were not
captured by the earlier diff: document.js manifest, document-page.js + document-view
templates, and IntentNamingTest (3 cases). NOTE: document.js is not yet imported in
template/ui/template.js and index.html.template has no MANAGE_DOCUMENT route branch,
so the document UI does not generate yet - wiring is the remaining step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant