Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#macro(leaf $el)
#if($metadata.taskForm && $el.readonly && $el.model)
<!-- BPM task form: a read-only field is a compact Label: Value row - a fixed-width muted
label column with the value LEFT-aligned beside it, so values line up vertically like a
classic detail card - one cell of the two-column grid.
<!-- BPM task form: a read-only field renders as a detail cell - a muted label above its value,
matching the entity detail/document view's headerless Details card (label text-xs muted,
value text-sm), one cell of the two-column grid.
Editable opt-in fields (readonly=false) fall through to the input below.
A relation.field control's model is the resolver-set name/value variable, so e.g. listing
`customer.name` shows the customer's name here rather than the raw FK id. A number is
formatted with its pattern (grouped, fixed decimals); other values render as-is. -->
<div class="hbox items-center gap-3">
<span x-h-text.muted class="text-sm shrink-0" style="width: 9rem;">$!el.label</span>
<div class="vbox gap-0">
<span x-h-text.muted class="text-xs">$!el.label</span>
#if($el.controlId == "input-number")
<span x-h-text class="font-medium min-w-0 break-words" x-text="fmtNumber(model.$el.model, '$!el.pattern')"></span>
<span x-h-text class="text-sm break-words" x-text="fmtNumber(model.$el.model, '$!el.pattern')"></span>
#elseif($el.controlId == "input-date" || $el.controlId == "input-datetime-local" || $el.controlId == "input-time" || $el.controlId == "input-month")
<span x-h-text class="font-medium min-w-0 break-words" x-text="fmtDate(model.$el.model, '$el.controlId')"></span>
<span x-h-text class="text-sm break-words" x-text="fmtDate(model.$el.model, '$el.controlId')"></span>
#else
<span x-h-text class="font-medium min-w-0 break-words" x-text="(model.$el.model === null || model.$el.model === undefined || model.$el.model === '') ? '—' : model.$el.model"></span>
<span x-h-text class="text-sm break-words" x-text="(model.$el.model === null || model.$el.model === undefined || model.$el.model === '') ? '—' : model.$el.model"></span>
#end
</div>
#elseif($el.controlId == "header")
Expand Down Expand Up @@ -138,10 +138,13 @@
<div x-h-alert-description x-text="message"></div>
</div>
#if($metadata.taskForm)
<!-- Task form: a responsive two-column detail grid (single column below the sm breakpoint) -
compact horizontal Label: Value rows; headers, separators, textareas and the action-button
row span both columns. -->
<div class="grid grid-cols-1 sm:grid-cols-2 gap-x-10 gap-y-3">
<!-- Task form: read-only fields render inside a headerless Details card (framed), matching the
entity detail / document view. A responsive two-column detail grid (single column below the
sm breakpoint); headers, separators, textareas and the action-button row span both columns.
Editable opt-in inputs and the actions live in the same card. -->
<div x-h-card>
<div x-h-card-content>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-x-10 gap-y-3">
#else
<div x-h-field-group>
#end
Expand All @@ -162,7 +165,13 @@
#leaf($element)
#end
#end
#if($metadata.taskForm)
</div>
</div>
</div>
#else
</div>
#end
</form>

<!-- Date/time controls (model + control type + editable) so form.js can convert the backend's
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,14 @@
*/
import { Registry } from "@aerokit/sdk/platform";
import { TemplateEngines as templateEngines } from "@aerokit/sdk/template";
import { sanitizeJavaIdentifier } from "service-generate/template/parameterUtils";
import { sanitizeJavaIdentifier, humanizeName } from "service-generate/template/parameterUtils";

function getTranslationId(str) {
return `${str.replaceAll(' ', '').replaceAll('_', '').replaceAll('.', '').replaceAll(':', '')}`;
}

// Humanize a PascalCase/camelCase identifier for display ("SalesInvoice" -> "Sales Invoice").
// Mirrors org.eclipse.dirigible.components.intent.generator.IntentNaming.humanize, including its
// acronym overrides, so a hand-authored .edm (no entityLabel/menuLabel baked by the intent
// generator) still yields the same labels the intent path would.
const HUMANIZE_OVERRIDES = { 'uom': 'Unit of Measure' };

function humanizeName(name) {
if (!name) return '';
const override = HUMANIZE_OVERRIDES[name.toLowerCase()];
if (override) return override;
let out = '';
for (let i = 0; i < name.length; i++) {
const c = name.charAt(i);
if (i > 0 && c >= 'A' && c <= 'Z' && !(name.charAt(i - 1) >= 'A' && name.charAt(i - 1) <= 'Z')) {
out += ' ';
}
out += i === 0 ? c.toUpperCase() : c;
}
return out;
}
// humanizeName lives in parameterUtils (the lower-level util module this file already imports from)
// so the label default in parameterUtils and the label catalog built here share one implementation.

// Pluralize a humanized label's last word ("Sales Invoice" -> "Sales Invoices", "Country" ->
// "Countries"). Mirrors IntentNaming.pluralize, including its irregular overrides.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,28 @@ import { Configurations } from "@aerokit/sdk/core";
import { Base64 } from "@aerokit/sdk/utils";
import { Bytes } from "@aerokit/sdk/io";

// Humanize a PascalCase/camelCase identifier for display ("PaymentMethod" -> "Payment Method",
// "TaxEventDate" -> "Tax Event Date"). Mirrors
// org.eclipse.dirigible.components.intent.generator.IntentNaming.humanize, including its acronym
// overrides, so a hand-authored .edm with no widgetLabel yields the same labels the intent path
// would. Exported so generateUtils (the label catalog builder) uses the same implementation.
const HUMANIZE_OVERRIDES = { 'uom': 'Unit of Measure' };

export function humanizeName(name) {
if (!name) return '';
const override = HUMANIZE_OVERRIDES[name.toLowerCase()];
if (override) return override;
let out = '';
for (let i = 0; i < name.length; i++) {
const c = name.charAt(i);
if (i > 0 && c >= 'A' && c <= 'Z' && !(name.charAt(i - 1) >= 'A' && name.charAt(i - 1) <= 'Z')) {
out += ' ';
}
out += i === 0 ? c.toUpperCase() : c;
}
return out;
}

export function process(model, parameters) {
parameters.javaGenFolderName = sanitizeJavaIdentifier(parameters.genFolderName);

Expand Down Expand Up @@ -77,7 +99,7 @@ export function process(model, parameters) {
p.isCalculatedProperty = p.isCalculatedProperty === "true";
p.isReadOnlyProperty = p.isReadOnlyProperty === "true";
p.widgetIsMajor = p.widgetIsMajor === "true";
p.widgetLabel = p.widgetLabel ? p.widgetLabel : p.name;
p.widgetLabel = p.widgetLabel ? p.widgetLabel : humanizeName(p.name);

if (p.name === "ProcessId") {
e.hasProcess = true;
Expand Down
Loading