@mintplayer/ng-spark 22.3.0 → 22.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/fesm2022/mintplayer-ng-spark-client-operations.mjs +10 -1
  2. package/fesm2022/mintplayer-ng-spark-client-operations.mjs.map +1 -1
  3. package/fesm2022/mintplayer-ng-spark-grid.mjs +772 -23
  4. package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
  5. package/fesm2022/mintplayer-ng-spark-models.mjs +233 -1
  6. package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
  7. package/fesm2022/mintplayer-ng-spark-pipes.mjs +31 -5
  8. package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
  9. package/fesm2022/mintplayer-ng-spark-po-create.mjs +2 -2
  10. package/fesm2022/mintplayer-ng-spark-po-create.mjs.map +1 -1
  11. package/fesm2022/mintplayer-ng-spark-po-detail.mjs +28 -302
  12. package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
  13. package/fesm2022/mintplayer-ng-spark-po-edit.mjs +2 -2
  14. package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -1
  15. package/fesm2022/mintplayer-ng-spark-po-form.mjs +352 -14
  16. package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -1
  17. package/fesm2022/mintplayer-ng-spark-query-list.mjs +137 -308
  18. package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
  19. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +6 -4
  20. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs.map +1 -1
  21. package/fesm2022/mintplayer-ng-spark-services.mjs +12 -0
  22. package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
  23. package/fesm2022/mintplayer-ng-spark.mjs +1 -1
  24. package/fesm2022/mintplayer-ng-spark.mjs.map +1 -1
  25. package/package.json +2 -2
  26. package/types/mintplayer-ng-spark-client-operations.d.ts +10 -1
  27. package/types/mintplayer-ng-spark-grid.d.ts +455 -19
  28. package/types/mintplayer-ng-spark-models.d.ts +119 -3
  29. package/types/mintplayer-ng-spark-po-detail.d.ts +18 -139
  30. package/types/mintplayer-ng-spark-po-form.d.ts +132 -4
  31. package/types/mintplayer-ng-spark-query-list.d.ts +53 -66
  32. package/types/mintplayer-ng-spark-services.d.ts +10 -0
@@ -1 +1 @@
1
- {"version":3,"file":"mintplayer-ng-spark-models.mjs","sources":["../../models/src/translated-string.ts","../../models/src/showed-on.ts","../../models/src/entity-type.ts","../../models/src/lookup-reference.ts","../../models/src/as-detail-conversions.ts","../../models/src/query-actions.ts","../../models/src/selection-rule.ts","../../models/src/selection-mode.ts","../../models/mintplayer-ng-spark-models.ts"],"sourcesContent":["import { signal, type WritableSignal } from '@angular/core';\n\nexport type TranslatedString = Record<string, string>;\n\n/** Global reactive language state — shared across library boundaries via globalThis */\nexport const currentLanguage: WritableSignal<string> =\n ((globalThis as any).__sparkCurrentLanguage ??= signal('en'));\n\nexport function resolveTranslation(ts: TranslatedString | undefined, lang?: string): string {\n if (!ts) return '';\n const language = lang ?? currentLanguage();\n return ts[language] ?? ts['en'] ?? Object.values(ts)[0] ?? '';\n}\n","/**\n * Flags enum controlling on which pages an attribute should be displayed.\n * Values can be combined: ShowedOn.Query | ShowedOn.PersistentObject\n */\nexport enum ShowedOn {\n Query = 1,\n PersistentObject = 2,\n}\n\n/**\n * Helper function to check if a ShowedOn value includes a specific flag.\n */\nexport function hasShowedOnFlag(value: ShowedOn | string | undefined, flag: ShowedOn): boolean {\n if (value === undefined) return true; // Default: show on all pages\n\n // Handle string values from JSON (e.g., \"Query, PersistentObject\")\n if (typeof value === 'string') {\n const parts = value.split(',').map(s => s.trim());\n const flagName = ShowedOn[flag];\n return parts.includes(flagName);\n }\n\n // Handle numeric flag values\n return (value & flag) === flag;\n}\n","import { ShowedOn } from './showed-on';\nimport { TranslatedString } from './translated-string';\nimport { ValidationRule } from './validation-rule';\n\n/**\n * Controls how a Reference attribute is picked in the PO-edit form.\n * Serialized as a string by the server (mirrors the .NET EReferenceDisplayType).\n */\nexport enum EReferenceDisplayType {\n /** Renders as a `<bs-select>` listing every referenced item. */\n Dropdown = 'Dropdown',\n /** Renders a readonly textbox + \"…\" button that opens a searchable modal grid picker. */\n Modal = 'Modal',\n}\n\nexport interface EntityAttributeDefinition {\n id: string;\n name: string;\n label?: TranslatedString;\n dataType: string;\n isRequired: boolean;\n isVisible: boolean;\n isReadOnly: boolean;\n order: number;\n query?: string;\n /** For reference attributes, specifies the target entity type's CLR type name */\n referenceType?: string;\n /** For AsDetail attributes, specifies the nested entity type's CLR type name */\n asDetailType?: string;\n /** When true, the attribute represents an array/collection of AsDetail objects */\n isArray?: boolean;\n /** For array AsDetail attributes: \"modal\" (default) or \"inline\" */\n editMode?: 'inline' | 'modal';\n /**\n * For Reference attributes: 'Modal' renders the \"…\" + modal query-grid picker;\n * 'Dropdown'/absent (default) renders a `<bs-select>`. Hand-set in the model JSON.\n */\n referenceDisplayType?: EReferenceDisplayType;\n /** For array AsDetail attributes: when true, rows can be drag-reordered (order = array position) */\n isSortable?: boolean;\n /** For LookupReference attributes, specifies the lookup reference type name */\n lookupReferenceType?: string;\n /**\n * Controls on which pages the attribute should be displayed.\n * Query = shown in list views, PersistentObject = shown in detail/edit views.\n * Can be a numeric flag value or a string like \"Query, PersistentObject\".\n */\n showedOn?: ShowedOn | string;\n rules: ValidationRule[];\n /** References an AttributeGroup.id to assign this attribute to a group */\n group?: string;\n /** Number of grid columns this attribute spans within a tab's column layout */\n columnSpan?: number;\n /** Renderer component name for custom display in detail/list views */\n renderer?: string;\n /** Options passed to the renderer component */\n rendererOptions?: Record<string, any>;\n}\n\nexport interface AttributeTab {\n id: string;\n name: string;\n label?: TranslatedString;\n order: number;\n /** Number of columns for the grid layout within this tab */\n columnCount?: number;\n}\n\nexport interface AttributeGroup {\n id: string;\n name: string;\n label?: TranslatedString;\n /** References an AttributeTab.id to assign this group to a tab */\n tab?: string;\n order: number;\n}\n\nexport interface EntityType {\n id: string;\n name: string;\n description?: TranslatedString;\n clrType: string;\n alias?: string;\n /**\n * Breadcrumb template: literal text plus `{AttributeName}` placeholders. A scalar placeholder\n * renders its value; a reference placeholder renders the referenced entity's breadcrumb.\n * The server resolves this — clients only read the resulting strings. Example: \"{Street}, {City}\".\n */\n breadcrumb?: string;\n /**\n * When false, the breadcrumb needs the collection document (a placeholder field is not on the\n * projection). null/absent means renderable from the projection. Informational on the client.\n */\n breadcrumbProjectionSatisfiable?: boolean;\n tabs?: AttributeTab[];\n groups?: AttributeGroup[];\n attributes: EntityAttributeDefinition[];\n /** Query aliases or IDs to display as related query tables on the detail page. */\n queries?: string[];\n}\n","import { TranslatedString } from './translated-string';\n\nexport enum ELookupDisplayType {\n Dropdown = 0,\n Modal = 1\n}\n\nexport interface LookupReferenceListItem {\n name: string;\n isTransient: boolean;\n valueCount: number;\n displayType: ELookupDisplayType;\n}\n\nexport interface LookupReference {\n name: string;\n isTransient: boolean;\n displayType: ELookupDisplayType;\n values: LookupReferenceValue[];\n}\n\nexport interface LookupReferenceValue {\n key: string;\n values: TranslatedString;\n isActive: boolean;\n extra?: Record<string, unknown>;\n}\n","import { EntityAttributeDefinition } from './entity-type';\nimport { EntityType } from './entity-type';\nimport { PersistentObject } from './persistent-object';\nimport { PersistentObjectAttribute } from './persistent-object-attribute';\n\n/**\n * Resolves an `EntityType` by its CLR type name (e.g. `\"HR.Entities.Address\"`).\n * Callers typically close over `sparkService.getEntityTypes()`'s cached list.\n */\nexport type EntityTypeResolver = (clrTypeName: string) => EntityType | undefined;\n\n/**\n * Flattens a nested `PersistentObject` into the plain `Record<string, any>` shape the\n * form state uses throughout ng-spark. Primitive / reference attributes contribute their\n * `value`; nested AsDetail attributes recurse — single becomes an inner dict, array\n * becomes an array of inner dicts. Returns `{}` for `null` / `undefined` input.\n *\n * This is the ONE place that reads the server's new AsDetail wire shape and collapses it\n * back to the flat dict the form components already handle.\n */\nexport function nestedPoToDict(po: PersistentObject | null | undefined): Record<string, any> {\n if (!po) return {};\n const dict: Record<string, any> = {};\n for (const attr of po.attributes ?? []) {\n dict[attr.name] = attributeValueForForm(attr);\n }\n return dict;\n}\n\nfunction attributeValueForForm(attr: PersistentObjectAttribute): any {\n if (attr.dataType === 'AsDetail') {\n if (attr.isArray) return (attr.objects ?? []).map(po => nestedPoToDict(po));\n return attr.object ? nestedPoToDict(attr.object) : null;\n }\n return attr.value;\n}\n\n/**\n * Reserved key under which {@link nestedPoToDisplayRow} stashes the server-resolved breadcrumb of\n * each reference attribute (keyed by attribute name). Lets an AsDetail reference cell render the\n * label the server already resolved by id — page-independent — instead of guessing from a single\n * reference-query options page. Prefixed to avoid colliding with a real attribute name.\n */\nexport const AS_DETAIL_BREADCRUMBS_KEY = '__sparkBreadcrumbs';\n\n/**\n * Like {@link nestedPoToDict}, but for the read-only detail display path. In addition to each\n * attribute's value it preserves the server-resolved per-reference `breadcrumb` under\n * {@link AS_DETAIL_BREADCRUMBS_KEY}, so an AsDetail reference cell can render the label by id\n * regardless of whether the referenced document fits on the reference query's first options page.\n * The form/edit path keeps using {@link nestedPoToDict}, which never carries breadcrumbs.\n */\nexport function nestedPoToDisplayRow(po: PersistentObject | null | undefined): Record<string, any> {\n if (!po) return {};\n const dict: Record<string, any> = {};\n let breadcrumbs: Record<string, string> | undefined;\n for (const attr of po.attributes ?? []) {\n dict[attr.name] = displayValueForAttribute(attr);\n if (attr.dataType === 'Reference' && !attr.isArray && typeof attr.breadcrumb === 'string' && attr.breadcrumb !== '') {\n (breadcrumbs ??= {})[attr.name] = attr.breadcrumb;\n }\n }\n // Only attach the side channel when something resolved — keeps reference-free rows (the common\n // case) byte-for-byte identical to the plain flat dict.\n if (breadcrumbs) dict[AS_DETAIL_BREADCRUMBS_KEY] = breadcrumbs;\n return dict;\n}\n\nfunction displayValueForAttribute(attr: PersistentObjectAttribute): any {\n if (attr.dataType === 'AsDetail') {\n if (attr.isArray) return (attr.objects ?? []).map(po => nestedPoToDisplayRow(po));\n return attr.object ? nestedPoToDisplayRow(attr.object) : null;\n }\n return attr.value;\n}\n\n/**\n * Builds a nested `PersistentObject` from a flat dict against the schema in\n * <paramref name=\"entityType\"/>. Used when the form is about to save — AsDetail attributes\n * are no longer sent as flat dicts in `attribute.value`; the server now requires\n * `attribute.object` / `attribute.objects` with fully scaffolded nested POs.\n *\n * `resolve` walks through AsDetail types registered elsewhere (usually the full\n * `getEntityTypes()` list, keyed by CLR type name). Nested AsDetail inside AsDetail is\n * handled recursively.\n */\nexport function dictToNestedPo(\n dict: Record<string, any> | null | undefined,\n entityType: EntityType,\n resolve: EntityTypeResolver,\n): PersistentObject {\n const attributes: PersistentObjectAttribute[] = (entityType.attributes ?? [])\n .map(attrDef => buildAttribute(attrDef, dict?.[attrDef.name], resolve));\n\n return {\n id: (dict?.['Id'] as string) ?? (dict?.['id'] as string) ?? '',\n name: entityType.name,\n objectTypeId: entityType.id,\n attributes,\n };\n}\n\nfunction buildAttribute(\n attrDef: EntityAttributeDefinition,\n raw: any,\n resolve: EntityTypeResolver,\n): PersistentObjectAttribute {\n const attr: PersistentObjectAttribute = {\n id: attrDef.id,\n name: attrDef.name,\n label: attrDef.label,\n dataType: attrDef.dataType,\n isArray: attrDef.isArray,\n isRequired: attrDef.isRequired,\n isVisible: attrDef.isVisible,\n isReadOnly: attrDef.isReadOnly,\n order: attrDef.order,\n rules: attrDef.rules ?? [],\n isValueChanged: true,\n };\n\n if (attrDef.dataType === 'AsDetail') {\n // Server expects attr.value null for AsDetail; the nested PO carries the data.\n attr.value = null;\n attr.asDetailType = attrDef.asDetailType;\n\n const nestedType = attrDef.asDetailType ? resolve(attrDef.asDetailType) : undefined;\n if (!nestedType) {\n attr.object = null;\n attr.objects = attrDef.isArray ? [] : null;\n return attr;\n }\n\n if (attrDef.isArray) {\n const items: any[] = Array.isArray(raw) ? raw : [];\n attr.objects = items.map(item => dictToNestedPo((item as Record<string, any>) ?? {}, nestedType, resolve));\n } else {\n attr.object = raw ? dictToNestedPo(raw as Record<string, any>, nestedType, resolve) : null;\n }\n return attr;\n }\n\n attr.value = raw;\n return attr;\n}\n","import { CustomActionDefinition } from './custom-action';\n\n/**\n * The custom actions a query should offer, from the entity type's full set.\n *\n * `showedOn` must include the query side. The accepted values are `\"detail\"`, `\"query\"`\n * and `\"both\"` — as the server model and the custom-actions guide have always\n * documented. Both grids previously tested for `\"list\"`, a value nothing emits, so an\n * action authored per the documentation rendered nowhere at all.\n *\n * ⚠️ This narrows what is DISPLAYED. It is NOT an authorization boundary: the grant\n * is, and it is enforced independently in `ExecuteCustomAction` regardless of which\n * query the caller clicked from — a caller can always POST directly.\n */\nexport function filterQueryActions(\n actions: CustomActionDefinition[],\n): CustomActionDefinition[] {\n return actions.filter(a => a.showedOn === 'query' || a.showedOn === 'both');\n}\n","/**\n * Parses a custom action's `selectionRule` — a cardinality expression over the number\n * of selected rows — into a predicate.\n *\n * A port of the server's `SelectionRuleParser`, and the two MUST agree: they are tested\n * against one shared fixture (`selection-rule.fixture.json`) for exactly this reason.\n * Vidyano, where this grammar comes from, has the same algorithm in C# and JavaScript and\n * the two have already drifted — one throws on a non-numeric operand where the other\n * silently permits everything.\n *\n * Grammar: `X` is the count placeholder, whitespace is insignificant, terms split on `X`\n * are AND-combined (`1<X<5` is a range), operators are `<= >= < > != =` matched in that\n * order so `>=` is never read as `>`, and a number-first term is mirrored (`0<X` is `>0`).\n *\n * Client-side this only drives whether a button is disabled. The server enforces the same\n * rule independently — and neither is an authorization boundary: the action's grant is.\n */\nexport function parseSelectionRule(rule?: string | null): (count: number) => boolean {\n if (!rule || !rule.trim()) return () => true;\n try {\n return compile(rule);\n } catch {\n // Unlike the server, which refuses to start on a malformed rule, the client cannot\n // usefully fail: the rule arrived over the wire from a server that already validated\n // it. Disabling the button is the safe direction — it never permits an action the\n // server would refuse.\n return () => false;\n }\n}\n\nconst OPERATORS = ['<=', '>=', '<', '>', '!=', '='] as const;\n\nfunction compile(rule: string): (count: number) => boolean {\n const normalized = rule.replace(/ /g, '').toUpperCase();\n const terms = normalized.split('X').filter(t => t.length > 0);\n if (terms.length === 0) throw new Error(`Selection rule '${rule}' has no condition.`);\n\n const numberFirst = !normalized.startsWith('X') && normalized.includes('X');\n const predicates = terms.map((term, i) => compileTerm(term, rule, numberFirst && i === 0));\n\n return count => predicates.every(p => p(count));\n}\n\nfunction compileTerm(term: string, rule: string, mirrored: boolean): (count: number) => boolean {\n const op = OPERATORS.find(o => (mirrored ? term.endsWith(o) : term.startsWith(o)));\n if (!op) throw new Error(`Selection rule '${rule}' has no recognised operator in '${term}'.`);\n\n const numberPart = mirrored ? term.slice(0, term.length - op.length) : term.slice(op.length);\n // Number(' ') is 0 and Number('1.5') is 1.5 — neither is a valid operand here.\n if (!/^-?\\d+$/.test(numberPart)) {\n throw new Error(`Selection rule '${rule}' has a non-numeric operand in '${term}'.`);\n }\n const value = Number(numberPart);\n const effective = mirrored ? mirror(op) : op;\n\n switch (effective) {\n case '<=': return count => count <= value;\n case '>=': return count => count >= value;\n case '<': return count => count < value;\n case '>': return count => count > value;\n case '!=': return count => count !== value;\n case '=': return count => count === value;\n default: throw new Error(`Selection rule '${rule}' has an unsupported operator '${effective}'.`);\n }\n}\n\nfunction mirror(op: string): string {\n switch (op) {\n case '<': return '>';\n case '>': return '<';\n case '<=': return '>=';\n case '>=': return '<=';\n default: return op;\n }\n}\n","import { CustomActionDefinition } from './custom-action';\nimport { parseSelectionRule } from './selection-rule';\n\nexport type SparkSelectionMode = 'none' | 'single' | 'multiple';\n\n/**\n * The selection mode a grid needs in order to satisfy the actions offered on it.\n *\n * Derived rather than configured, so a grid gains a checkbox column exactly when an\n * action needs one and is otherwise pixel-identical to a grid with no selection at all.\n * Vidyano's query grid does the same thing — it renders the checkbox column only if some\n * action is selection-gated.\n *\n * `'single'` when every gated action is satisfied by one row and refused by two; anything\n * else that cares about the count gets `'multiple'`.\n */\nexport function selectionModeFor(actions: CustomActionDefinition[]): SparkSelectionMode {\n // An action with no rule is not selection-gated: it acts on the query, not on rows.\n const gated = actions.filter(a => !!a.selectionRule?.trim());\n if (gated.length === 0) return 'none';\n\n const everyRuleWantsExactlyOne = gated.every(a => {\n const rule = parseSelectionRule(a.selectionRule);\n return rule(1) && !rule(2);\n });\n\n return everyRuleWantsExactlyOne ? 'single' : 'multiple';\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mintplayer-ng-spark-models.mjs","sources":["../../models/src/translated-string.ts","../../models/src/showed-on.ts","../../models/src/entity-type.ts","../../models/src/lookup-reference.ts","../../models/src/as-detail-conversions.ts","../../models/src/query-actions.ts","../../models/src/selection-rule.ts","../../models/src/selection-mode.ts","../../models/src/refresh-overlay.ts","../../models/src/rule-evaluation.ts","../../models/mintplayer-ng-spark-models.ts"],"sourcesContent":["import { signal, type WritableSignal } from '@angular/core';\n\nexport type TranslatedString = Record<string, string>;\n\n/** Global reactive language state — shared across library boundaries via globalThis */\nexport const currentLanguage: WritableSignal<string> =\n ((globalThis as any).__sparkCurrentLanguage ??= signal('en'));\n\nexport function resolveTranslation(ts: TranslatedString | undefined, lang?: string): string {\n if (!ts) return '';\n const language = lang ?? currentLanguage();\n return ts[language] ?? ts['en'] ?? Object.values(ts)[0] ?? '';\n}\n","/**\n * Flags enum controlling on which pages an attribute should be displayed.\n * Values can be combined: ShowedOn.Query | ShowedOn.PersistentObject\n */\nexport enum ShowedOn {\n Query = 1,\n PersistentObject = 2,\n}\n\n/**\n * Helper function to check if a ShowedOn value includes a specific flag.\n */\nexport function hasShowedOnFlag(value: ShowedOn | string | undefined, flag: ShowedOn): boolean {\n if (value === undefined) return true; // Default: show on all pages\n\n // Handle string values from JSON (e.g., \"Query, PersistentObject\")\n if (typeof value === 'string') {\n const parts = value.split(',').map(s => s.trim());\n const flagName = ShowedOn[flag];\n return parts.includes(flagName);\n }\n\n // Handle numeric flag values\n return (value & flag) === flag;\n}\n","import { ShowedOn } from './showed-on';\nimport { TranslatedString } from './translated-string';\nimport { ValidationRule } from './validation-rule';\n\n/**\n * Controls how a Reference attribute is picked in the PO-edit form.\n * Serialized as a string by the server (mirrors the .NET EReferenceDisplayType).\n */\nexport enum EReferenceDisplayType {\n /** Renders as a `<bs-select>` listing every referenced item. */\n Dropdown = 'Dropdown',\n /** Renders a readonly textbox + \"…\" button that opens a searchable modal grid picker. */\n Modal = 'Modal',\n}\n\nexport interface EntityAttributeDefinition {\n id: string;\n name: string;\n label?: TranslatedString;\n dataType: string;\n isRequired: boolean;\n isVisible: boolean;\n isReadOnly: boolean;\n order: number;\n query?: string;\n /** For reference attributes, specifies the target entity type's CLR type name */\n referenceType?: string;\n /** For AsDetail attributes, specifies the nested entity type's CLR type name */\n asDetailType?: string;\n /** When true, the attribute represents an array/collection of AsDetail objects */\n isArray?: boolean;\n /** For array AsDetail attributes: \"modal\" (default) or \"inline\" */\n editMode?: 'inline' | 'modal';\n /**\n * For Reference attributes: 'Modal' renders the \"…\" + modal query-grid picker;\n * 'Dropdown'/absent (default) renders a `<bs-select>`. Hand-set in the model JSON.\n */\n referenceDisplayType?: EReferenceDisplayType;\n /** For array AsDetail attributes: when true, rows can be drag-reordered (order = array position) */\n isSortable?: boolean;\n /**\n * When true, changing this attribute's value posts the in-progress object to\n * `/spark/po/{objectTypeId}/refresh` and applies the reshaped result as an overlay.\n * Schema-only by design — it never travels on a PersistentObjectAttribute, so a client\n * cannot claim a trigger the model did not declare.\n */\n triggersRefresh?: boolean;\n /** For LookupReference attributes, specifies the lookup reference type name */\n lookupReferenceType?: string;\n /**\n * Controls on which pages the attribute should be displayed.\n * Query = shown in list views, PersistentObject = shown in detail/edit views.\n * Can be a numeric flag value or a string like \"Query, PersistentObject\".\n */\n showedOn?: ShowedOn | string;\n rules: ValidationRule[];\n /** References an AttributeGroup.id to assign this attribute to a group */\n group?: string;\n /** Number of grid columns this attribute spans within a tab's column layout */\n columnSpan?: number;\n /** Renderer component name for custom display in detail/list views */\n renderer?: string;\n /** Options passed to the renderer component */\n rendererOptions?: Record<string, any>;\n}\n\nexport interface AttributeTab {\n id: string;\n name: string;\n label?: TranslatedString;\n order: number;\n /** Number of columns for the grid layout within this tab */\n columnCount?: number;\n}\n\nexport interface AttributeGroup {\n id: string;\n name: string;\n label?: TranslatedString;\n /** References an AttributeTab.id to assign this group to a tab */\n tab?: string;\n order: number;\n}\n\nexport interface EntityType {\n id: string;\n name: string;\n description?: TranslatedString;\n clrType: string;\n alias?: string;\n /**\n * Breadcrumb template: literal text plus `{AttributeName}` placeholders. A scalar placeholder\n * renders its value; a reference placeholder renders the referenced entity's breadcrumb.\n * The server resolves this — clients only read the resulting strings. Example: \"{Street}, {City}\".\n */\n breadcrumb?: string;\n /**\n * When false, the breadcrumb needs the collection document (a placeholder field is not on the\n * projection). null/absent means renderable from the projection. Informational on the client.\n */\n breadcrumbProjectionSatisfiable?: boolean;\n tabs?: AttributeTab[];\n groups?: AttributeGroup[];\n attributes: EntityAttributeDefinition[];\n /** Query aliases or IDs to display as related query tables on the detail page. */\n queries?: string[];\n}\n","import { TranslatedString } from './translated-string';\n\nexport enum ELookupDisplayType {\n Dropdown = 0,\n Modal = 1\n}\n\nexport interface LookupReferenceListItem {\n name: string;\n isTransient: boolean;\n valueCount: number;\n displayType: ELookupDisplayType;\n}\n\nexport interface LookupReference {\n name: string;\n isTransient: boolean;\n displayType: ELookupDisplayType;\n values: LookupReferenceValue[];\n}\n\nexport interface LookupReferenceValue {\n key: string;\n values: TranslatedString;\n isActive: boolean;\n extra?: Record<string, unknown>;\n}\n","import { EntityAttributeDefinition } from './entity-type';\nimport { EntityType } from './entity-type';\nimport { PersistentObject } from './persistent-object';\nimport { PersistentObjectAttribute } from './persistent-object-attribute';\n\n/**\n * Resolves an `EntityType` by its CLR type name (e.g. `\"HR.Entities.Address\"`).\n * Callers typically close over a list they already hold. `getEntityTypes()` is NOT cached --\n * it issues a request per call -- so resolve against a list you fetched once rather than\n * calling it inside the resolver.\n */\nexport type EntityTypeResolver = (clrTypeName: string) => EntityType | undefined;\n\n/**\n * Flattens a nested `PersistentObject` into the plain `Record<string, any>` shape the\n * form state uses throughout ng-spark. Primitive / reference attributes contribute their\n * `value`; nested AsDetail attributes recurse — single becomes an inner dict, array\n * becomes an array of inner dicts. Returns `{}` for `null` / `undefined` input.\n *\n * This is the ONE place that reads the server's new AsDetail wire shape and collapses it\n * back to the flat dict the form components already handle.\n */\nexport function nestedPoToDict(po: PersistentObject | null | undefined): Record<string, any> {\n if (!po) return {};\n const dict: Record<string, any> = {};\n for (const attr of po.attributes ?? []) {\n dict[attr.name] = attributeValueForForm(attr);\n }\n // The object's own server-resolved breadcrumb, kept under a reserved key so the form can label\n // it without re-deriving a template it may be structurally unable to resolve. Safe to carry\n // through save: `dictToNestedPo` walks the entity type's attributes, never the dict's keys, so\n // a reserved key is never sent to the server. Attached only when it resolved, which keeps the\n // common case byte-for-byte identical to the plain flat dict.\n if (typeof po.breadcrumb === 'string' && po.breadcrumb !== '') {\n dict[AS_DETAIL_SELF_BREADCRUMB_KEY] = po.breadcrumb;\n }\n return dict;\n}\n\nfunction attributeValueForForm(attr: PersistentObjectAttribute): any {\n if (attr.dataType === 'AsDetail') {\n if (attr.isArray) return (attr.objects ?? []).map(po => nestedPoToDict(po));\n return attr.object ? nestedPoToDict(attr.object) : null;\n }\n return attr.value;\n}\n\n/**\n * Reserved key under which a flattened nested object keeps the breadcrumb the SERVER resolved for\n * that object itself (as opposed to {@link AS_DETAIL_BREADCRUMBS_KEY}, which keys the breadcrumbs\n * of its reference attributes by attribute name).\n *\n * This exists because a breadcrumb template can name a property the model does not carry. HR's\n * `Address` declares `[Breadcrumb, IgnoreProperty] string Crumb`, and `Address.json` renders it as\n * `\"{Crumb}\"` — the server resolves that by reflecting over the CLR property, which no client can\n * do, because `[IgnoreProperty]` is exactly the instruction to keep it out of the model. Flattening\n * used to discard the resolved string, leaving the form to substitute `{Crumb}` against a dict that\n * can never contain it.\n */\nexport const AS_DETAIL_SELF_BREADCRUMB_KEY = '__sparkBreadcrumb';\n\n/**\n * The breadcrumb the server resolved for a flattened object, or null when it resolved to nothing.\n *\n * `EntityMapper` never emits an empty breadcrumb: when the template renders blank it substitutes\n * the CLR type name, so an unset `Address` arrives as the literal string `\"Address\"`\n * (EntityMapper.cs:209-211). That is a placeholder, not data, and rendering it would be worse than\n * rendering nothing — it reads as a real value. `typeName` lets a caller filter it back out.\n */\nexport function selfBreadcrumb(row: Record<string, any> | null | undefined, typeName?: string): string | null {\n const value = row?.[AS_DETAIL_SELF_BREADCRUMB_KEY];\n if (typeof value !== 'string' || value.trim() === '') return null;\n\n // Callers hold the type name in two shapes — `EntityType.name` is the short model name, while an\n // attribute's `asDetailType` is the full CLR name — and the server's placeholder is always the\n // short one. Compare on the last dotted segment so either shape filters it.\n if (typeName) {\n const shortName = typeName.slice(typeName.lastIndexOf('.') + 1);\n if (value === shortName) return null;\n }\n return value;\n}\n\n/**\n * Reserved key under which {@link nestedPoToDisplayRow} stashes the server-resolved breadcrumb of\n * each reference attribute (keyed by attribute name). Lets an AsDetail reference cell render the\n * label the server already resolved by id — page-independent — instead of guessing from a single\n * reference-query options page. Prefixed to avoid colliding with a real attribute name.\n */\nexport const AS_DETAIL_BREADCRUMBS_KEY = '__sparkBreadcrumbs';\n\n/**\n * Like {@link nestedPoToDict}, but for the read-only detail display path. In addition to each\n * attribute's value it preserves the server-resolved per-reference `breadcrumb` under\n * {@link AS_DETAIL_BREADCRUMBS_KEY}, so an AsDetail reference cell can render the label by id\n * regardless of whether the referenced document fits on the reference query's first options page.\n * The form/edit path keeps using {@link nestedPoToDict}, which never carries breadcrumbs.\n */\nexport function nestedPoToDisplayRow(po: PersistentObject | null | undefined): Record<string, any> {\n if (!po) return {};\n const dict: Record<string, any> = {};\n let breadcrumbs: Record<string, string> | undefined;\n for (const attr of po.attributes ?? []) {\n dict[attr.name] = displayValueForAttribute(attr);\n if (attr.dataType === 'Reference' && !attr.isArray && typeof attr.breadcrumb === 'string' && attr.breadcrumb !== '') {\n (breadcrumbs ??= {})[attr.name] = attr.breadcrumb;\n }\n }\n // Only attach the side channel when something resolved — keeps reference-free rows (the common\n // case) byte-for-byte identical to the plain flat dict.\n if (breadcrumbs) dict[AS_DETAIL_BREADCRUMBS_KEY] = breadcrumbs;\n // Same self-breadcrumb the form path carries: a nested-AsDetail COLUMN in a detail table has an\n // inner dict as its value, which used to stringify to \"[object Object]\".\n if (typeof po.breadcrumb === 'string' && po.breadcrumb !== '') {\n dict[AS_DETAIL_SELF_BREADCRUMB_KEY] = po.breadcrumb;\n }\n return dict;\n}\n\nfunction displayValueForAttribute(attr: PersistentObjectAttribute): any {\n if (attr.dataType === 'AsDetail') {\n if (attr.isArray) return (attr.objects ?? []).map(po => nestedPoToDisplayRow(po));\n return attr.object ? nestedPoToDisplayRow(attr.object) : null;\n }\n return attr.value;\n}\n\n/**\n * Builds a nested `PersistentObject` from a flat dict against the schema in\n * <paramref name=\"entityType\"/>. Used when the form is about to save — AsDetail attributes\n * are no longer sent as flat dicts in `attribute.value`; the server now requires\n * `attribute.object` / `attribute.objects` with fully scaffolded nested POs.\n *\n * `resolve` walks through AsDetail types registered elsewhere (usually the full\n * `getEntityTypes()` list, keyed by CLR type name). Nested AsDetail inside AsDetail is\n * handled recursively.\n */\nexport function dictToNestedPo(\n dict: Record<string, any> | null | undefined,\n entityType: EntityType,\n resolve: EntityTypeResolver,\n): PersistentObject {\n const attributes: PersistentObjectAttribute[] = (entityType.attributes ?? [])\n .map(attrDef => buildAttribute(attrDef, dict?.[attrDef.name], resolve));\n\n return {\n id: (dict?.['Id'] as string) ?? (dict?.['id'] as string) ?? '',\n name: entityType.name,\n objectTypeId: entityType.id,\n attributes,\n };\n}\n\nfunction buildAttribute(\n attrDef: EntityAttributeDefinition,\n raw: any,\n resolve: EntityTypeResolver,\n): PersistentObjectAttribute {\n const attr: PersistentObjectAttribute = {\n id: attrDef.id,\n name: attrDef.name,\n label: attrDef.label,\n dataType: attrDef.dataType,\n isArray: attrDef.isArray,\n isRequired: attrDef.isRequired,\n isVisible: attrDef.isVisible,\n isReadOnly: attrDef.isReadOnly,\n order: attrDef.order,\n rules: attrDef.rules ?? [],\n isValueChanged: true,\n };\n\n if (attrDef.dataType === 'AsDetail') {\n // Server expects attr.value null for AsDetail; the nested PO carries the data.\n attr.value = null;\n attr.asDetailType = attrDef.asDetailType;\n\n const nestedType = attrDef.asDetailType ? resolve(attrDef.asDetailType) : undefined;\n if (!nestedType) {\n attr.object = null;\n attr.objects = attrDef.isArray ? [] : null;\n return attr;\n }\n\n if (attrDef.isArray) {\n const items: any[] = Array.isArray(raw) ? raw : [];\n attr.objects = items.map(item => dictToNestedPo((item as Record<string, any>) ?? {}, nestedType, resolve));\n } else {\n attr.object = raw ? dictToNestedPo(raw as Record<string, any>, nestedType, resolve) : null;\n }\n return attr;\n }\n\n attr.value = raw;\n return attr;\n}\n","import { CustomActionDefinition } from './custom-action';\n\n/**\n * The custom actions a query should offer, from the entity type's full set.\n *\n * `showedOn` must include the query side. The accepted values are `\"detail\"`, `\"query\"`\n * and `\"both\"` — as the server model and the custom-actions guide have always\n * documented. Both grids previously tested for `\"list\"`, a value nothing emits, so an\n * action authored per the documentation rendered nowhere at all.\n *\n * ⚠️ This narrows what is DISPLAYED. It is NOT an authorization boundary: the grant\n * is, and it is enforced independently in `ExecuteCustomAction` regardless of which\n * query the caller clicked from — a caller can always POST directly.\n */\nexport function filterQueryActions(\n actions: CustomActionDefinition[],\n): CustomActionDefinition[] {\n return actions.filter(a => a.showedOn === 'query' || a.showedOn === 'both');\n}\n","/**\n * Parses a custom action's `selectionRule` — a cardinality expression over the number\n * of selected rows — into a predicate.\n *\n * A port of the server's `SelectionRuleParser`, and the two MUST agree: they are tested\n * against one shared fixture (`selection-rule.fixture.json`) for exactly this reason.\n * Vidyano, where this grammar comes from, has the same algorithm in C# and JavaScript and\n * the two have already drifted — one throws on a non-numeric operand where the other\n * silently permits everything.\n *\n * Grammar: `X` is the count placeholder, whitespace is insignificant, terms split on `X`\n * are AND-combined (`1<X<5` is a range), operators are `<= >= < > != =` matched in that\n * order so `>=` is never read as `>`, and a number-first term is mirrored (`0<X` is `>0`).\n *\n * Client-side this only drives whether a button is disabled. The server enforces the same\n * rule independently — and neither is an authorization boundary: the action's grant is.\n */\nexport function parseSelectionRule(rule?: string | null): (count: number) => boolean {\n if (!rule || !rule.trim()) return () => true;\n try {\n return compile(rule);\n } catch {\n // Unlike the server, which refuses to start on a malformed rule, the client cannot\n // usefully fail: the rule arrived over the wire from a server that already validated\n // it. Disabling the button is the safe direction — it never permits an action the\n // server would refuse.\n return () => false;\n }\n}\n\nconst OPERATORS = ['<=', '>=', '<', '>', '!=', '='] as const;\n\nfunction compile(rule: string): (count: number) => boolean {\n const normalized = rule.replace(/ /g, '').toUpperCase();\n const terms = normalized.split('X').filter(t => t.length > 0);\n if (terms.length === 0) throw new Error(`Selection rule '${rule}' has no condition.`);\n\n const numberFirst = !normalized.startsWith('X') && normalized.includes('X');\n const predicates = terms.map((term, i) => compileTerm(term, rule, numberFirst && i === 0));\n\n return count => predicates.every(p => p(count));\n}\n\nfunction compileTerm(term: string, rule: string, mirrored: boolean): (count: number) => boolean {\n const op = OPERATORS.find(o => (mirrored ? term.endsWith(o) : term.startsWith(o)));\n if (!op) throw new Error(`Selection rule '${rule}' has no recognised operator in '${term}'.`);\n\n const numberPart = mirrored ? term.slice(0, term.length - op.length) : term.slice(op.length);\n // Number(' ') is 0 and Number('1.5') is 1.5 — neither is a valid operand here.\n if (!/^-?\\d+$/.test(numberPart)) {\n throw new Error(`Selection rule '${rule}' has a non-numeric operand in '${term}'.`);\n }\n const value = Number(numberPart);\n const effective = mirrored ? mirror(op) : op;\n\n switch (effective) {\n case '<=': return count => count <= value;\n case '>=': return count => count >= value;\n case '<': return count => count < value;\n case '>': return count => count > value;\n case '!=': return count => count !== value;\n case '=': return count => count === value;\n default: throw new Error(`Selection rule '${rule}' has an unsupported operator '${effective}'.`);\n }\n}\n\nfunction mirror(op: string): string {\n switch (op) {\n case '<': return '>';\n case '>': return '<';\n case '<=': return '>=';\n case '>=': return '<=';\n default: return op;\n }\n}\n","import { CustomActionDefinition } from './custom-action';\nimport { parseSelectionRule } from './selection-rule';\n\nexport type SparkSelectionMode = 'none' | 'single' | 'multiple';\n\n/**\n * The selection mode a grid needs in order to satisfy the actions offered on it.\n *\n * Derived rather than configured, so a grid gains a checkbox column exactly when an\n * action needs one and is otherwise pixel-identical to a grid with no selection at all.\n * Vidyano's query grid does the same thing — it renders the checkbox column only if some\n * action is selection-gated.\n *\n * `'single'` when every gated action is satisfied by one row and refused by two; anything\n * else that cares about the count gets `'multiple'`.\n */\nexport function selectionModeFor(actions: CustomActionDefinition[]): SparkSelectionMode {\n // An action with no rule is not selection-gated: it acts on the query, not on rows.\n const gated = actions.filter(a => !!a.selectionRule?.trim());\n if (gated.length === 0) return 'none';\n\n const everyRuleWantsExactlyOne = gated.every(a => {\n const rule = parseSelectionRule(a.selectionRule);\n return rule(1) && !rule(2);\n });\n\n return everyRuleWantsExactlyOne ? 'single' : 'multiple';\n}\n","import { EntityAttributeDefinition } from './entity-type';\nimport { PersistentObject } from './persistent-object';\nimport { ValidationRule } from './validation-rule';\n\n/**\n * One selectable value, as replaced by a refresh hook. Mirrors the server's\n * `PersistentObjectAttributeOption`.\n */\nexport interface RefreshedOption {\n key: string;\n label?: Record<string, string>;\n}\n\n/**\n * What a refresh changed about one attribute's *presentation*.\n *\n * Kept separate from `EntityType` on purpose. The form's option loading hangs off a single effect\n * keyed on `entityType` identity, and `SparkService` caches nothing — so applying a refresh by\n * setting a new `EntityType` re-issues every reference query, every lookup fetch, a full\n * `getEntityTypes()` and a `getPermissions()` per array-AsDetail attribute, on every refresh.\n * Mutating the existing object instead is inert, because the rendering computed would not re-run.\n * An overlay is the only shape that is both reactive and free.\n */\nexport interface AttributeOverlay {\n isRequired?: boolean;\n isReadOnly?: boolean;\n isVisible?: boolean;\n rules?: ValidationRule[];\n query?: string;\n /** `undefined` means the hook did not touch the options; an empty array means there are none. */\n options?: RefreshedOption[];\n}\n\nexport type RefreshOverlay = Record<string, AttributeOverlay>;\n\n/** Applies an overlay to one attribute definition, returning a new object when anything changed. */\nexport function applyOverlay(\n attr: EntityAttributeDefinition,\n overlay: AttributeOverlay | undefined,\n): EntityAttributeDefinition {\n if (!overlay) return attr;\n\n return {\n ...attr,\n isRequired: overlay.isRequired ?? attr.isRequired,\n isReadOnly: overlay.isReadOnly ?? attr.isReadOnly,\n isVisible: overlay.isVisible ?? attr.isVisible,\n rules: overlay.rules ?? attr.rules,\n query: overlay.query ?? attr.query,\n };\n}\n\n/**\n * Reads a refresh response into an overlay.\n *\n * Everything here is presentation the server owns outright, so it is taken verbatim — there is no\n * merging to do on this half, only on values.\n */\nexport function overlayFromResponse(response: PersistentObject): RefreshOverlay {\n const overlay: RefreshOverlay = {};\n\n for (const attr of response.attributes ?? []) {\n overlay[attr.name] = {\n isRequired: attr.isRequired,\n isReadOnly: attr.isReadOnly,\n isVisible: attr.isVisible,\n rules: attr.rules ?? [],\n query: attr.query,\n options: (attr as { options?: RefreshedOption[] | null }).options ?? undefined,\n };\n }\n\n return overlay;\n}\n\n/**\n * Merges a refresh response's values into the live form.\n *\n * The rule, and the reason for it: a refresh is not instant, and the user keeps typing during it —\n * the form is deliberately never frozen. So for each attribute we ask whether the *server* changed\n * it, by comparing the response against the values that were **sent**, not against what is on\n * screen now.\n *\n * - server value equals what we sent → the hook did not touch it, so whatever is in the form now\n * wins, including anything typed while the request was in flight;\n * - server value differs → the hook deliberately changed it, and it wins over a concurrent edit.\n *\n * Comparing against the displayed value instead is the classic \"refresh eats my typing\" bug;\n * refusing to overwrite anything the user touched is the equally wrong opposite, where a dependent\n * field the hook computed never appears.\n *\n * @param sent values as they were POSTed, captured before the request left\n * @param current values as they are now, which may have moved on\n * @param response the reshaped object\n */\nexport function mergeRefreshValues(\n sent: Record<string, any>,\n current: Record<string, any>,\n response: PersistentObject,\n): Record<string, any> {\n const merged = { ...current };\n\n for (const attr of response.attributes ?? []) {\n const serverValue = attr.value ?? null;\n const sentValue = sent[attr.name] ?? null;\n\n if (!valuesEqual(serverValue, sentValue)) {\n merged[attr.name] = attr.value;\n }\n }\n\n return merged;\n}\n\n/**\n * Structural for arrays, `===` otherwise.\n *\n * Multi-reference attributes hold `string[]`, and a fresh array of the same ids is a different\n * object — so reference equality would report every one of them as \"changed by the server\" on\n * every refresh, and clobber in-flight edits to them.\n */\nfunction valuesEqual(a: any, b: any): boolean {\n if (a === b) return true;\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, i) => valuesEqual(item, b[i]));\n }\n // Values arrive off the wire as JSON scalars; anything else compares by JSON shape rather than\n // by identity, which is what a caller means by \"did this change\".\n if (a !== null && b !== null && typeof a === 'object' && typeof b === 'object') {\n return JSON.stringify(a) === JSON.stringify(b);\n }\n return false;\n}\n","import { ValidationRule } from './validation-rule';\nimport { TranslatedString } from './translated-string';\n\n/** One rule failure, in the shape the form already renders per field. */\nexport interface RuleFailure {\n attributeName: string;\n ruleType: string;\n message: string;\n}\n\nexport interface EvaluableAttribute {\n name: string;\n label?: TranslatedString;\n isRequired?: boolean;\n rules?: ValidationRule[];\n}\n\nconst EMAIL = /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/i;\nconst URL = /^https?:\\/\\/[^\\s]+$/i;\n\nfunction isEmpty(value: any): boolean {\n if (value === null || value === undefined) return true;\n if (typeof value === 'string') return value.trim() === '';\n if (Array.isArray(value)) return value.length === 0;\n return false;\n}\n\n/**\n * Evaluates an attribute's rules against a value, mirroring the server's `ValidationService`.\n *\n * ⚠️ **Parity with the server is the point, and disagreement is worse than silence.** A client that\n * rejects something the server would accept blocks legitimate work with no recourse; one that\n * accepts something the server rejects merely defers the error to the round-trip, which is where it\n * used to live anyway. So the rule set here is deliberately limited to the types the server\n * implements, and an unrecognised rule type is ignored rather than guessed at.\n *\n * This exists because a refresh hook that imposes a rule needs it to bite before Save — previously\n * `rules` was carried on the wire and never evaluated in the browser at all.\n */\nexport function evaluateRules(attr: EvaluableAttribute, value: any): RuleFailure[] {\n const failures: RuleFailure[] = [];\n const label = attr.label?.['en'] ?? attr.name;\n\n if (attr.isRequired && isEmpty(value)) {\n return [{ attributeName: attr.name, ruleType: 'required', message: `${label} is required` }];\n }\n\n // A rule other than \"required\" says nothing about an absent value — that is what required is for.\n if (isEmpty(value)) return failures;\n\n const text = value?.toString() ?? '';\n\n for (const rule of attr.rules ?? []) {\n const failure = evaluateRule(attr.name, label, rule, value, text);\n if (failure) failures.push(failure);\n }\n\n return failures;\n}\n\nfunction evaluateRule(\n name: string,\n label: string,\n rule: ValidationRule,\n value: any,\n text: string,\n): RuleFailure | null {\n const message = rule.message?.['en'];\n\n switch (rule.type?.toLowerCase()) {\n case 'maxlength': {\n const max = toInt(rule.value);\n if (max === null || text.length <= max) return null;\n return { attributeName: name, ruleType: 'maxLength', message: message ?? `${label} must be at most ${max} characters` };\n }\n case 'minlength': {\n const min = toInt(rule.value);\n if (min === null || text.length >= min) return null;\n return { attributeName: name, ruleType: 'minLength', message: message ?? `${label} must be at least ${min} characters` };\n }\n case 'range': {\n const numeric = toNumber(value);\n if (numeric === null) return null;\n if (rule.min !== undefined && rule.min !== null && numeric < rule.min) {\n return { attributeName: name, ruleType: 'range', message: message ?? `${label} must be at least ${rule.min}` };\n }\n if (rule.max !== undefined && rule.max !== null && numeric > rule.max) {\n return { attributeName: name, ruleType: 'range', message: message ?? `${label} must be at most ${rule.max}` };\n }\n return null;\n }\n case 'regex': {\n const pattern = rule.value?.toString();\n if (!pattern) return null;\n let re: RegExp;\n try {\n re = new RegExp(pattern);\n } catch {\n // An unparseable pattern is a server-side authoring bug. Staying silent leaves the server to\n // report it, which is strictly better than blocking the user over a rule nobody can evaluate.\n return null;\n }\n return re.test(text) ? null : { attributeName: name, ruleType: 'regex', message: message ?? `${label} is not in the expected format` };\n }\n case 'email':\n return EMAIL.test(text) ? null : { attributeName: name, ruleType: 'email', message: message ?? `${label} must be a valid email address` };\n case 'url':\n return URL.test(text) ? null : { attributeName: name, ruleType: 'url', message: message ?? `${label} must be a valid URL` };\n default:\n return null;\n }\n}\n\nfunction toInt(value: any): number | null {\n const n = Number(value);\n return Number.isFinite(n) ? Math.trunc(n) : null;\n}\n\nfunction toNumber(value: any): number | null {\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, Pipe } from '@angular/core';
3
3
  import { SparkLanguageService } from '@mintplayer/ng-spark/services';
4
- import { resolveTranslation, nestedPoToDict, AS_DETAIL_BREADCRUMBS_KEY, ELookupDisplayType, nestedPoToDisplayRow } from '@mintplayer/ng-spark/models';
4
+ import { resolveTranslation, nestedPoToDict, AS_DETAIL_BREADCRUMBS_KEY, selfBreadcrumb, ELookupDisplayType, nestedPoToDisplayRow } from '@mintplayer/ng-spark/models';
5
5
 
6
6
  class TranslateKeyPipe {
7
7
  lang = inject(SparkLanguageService);
@@ -87,6 +87,14 @@ class AttributeValuePipe {
87
87
  return `${count} item${count !== 1 ? 's' : ''}`;
88
88
  }
89
89
  if (attr.object) {
90
+ // The server has already resolved this object's breadcrumb, and it can resolve templates
91
+ // this side cannot. A type's breadcrumb may name a computed property that `[IgnoreProperty]`
92
+ // keeps out of the model — HR's `Address.Crumb` is exactly that, `[Breadcrumb, IgnoreProperty]`
93
+ // — so the template `{Crumb}` has no matching attribute here and never will. Recomputing it
94
+ // client-side produced an empty string and fell through to "(object)" while the correct
95
+ // "Deinzestraat 231, 9700 Oudenaarde" sat unread on `attr.object.breadcrumb`.
96
+ if (attr.object.breadcrumb)
97
+ return attr.object.breadcrumb;
90
98
  return this.formatAsDetailValue(attrDef, nestedPoToDict(attr.object), allEntityTypes);
91
99
  }
92
100
  }
@@ -111,7 +119,12 @@ class AttributeValuePipe {
111
119
  if (result && result.trim())
112
120
  return result;
113
121
  }
114
- return '(object)';
122
+ // Last resort, reached when the type declares no breadcrumb or its template resolved to
123
+ // nothing. Joining the scalar values is always more use to a reader than "(object)", which
124
+ // named the failure rather than the row and looked identical for every unresolvable cell.
125
+ return Object.values(value)
126
+ .filter(v => v != null && typeof v !== 'object' && String(v).trim() !== '')
127
+ .join(', ');
115
128
  }
116
129
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: AttributeValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
117
130
  static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.0", ngImport: i0, type: AttributeValuePipe, isStandalone: true, name: "attributeValue" });
@@ -283,6 +296,11 @@ class AsDetailCellValuePipe {
283
296
  }
284
297
  }
285
298
  }
299
+ // A nested-AsDetail column's value is an inner dict, so String(value) produced "[object
300
+ // Object]". The flattener kept that object's server-resolved breadcrumb for exactly this.
301
+ if (col.dataType === 'AsDetail' && typeof value === 'object') {
302
+ return selfBreadcrumb(value, col.asDetailType) ?? '';
303
+ }
286
304
  return String(value);
287
305
  }
288
306
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: AsDetailCellValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
@@ -300,9 +318,17 @@ class AsDetailDisplayValuePipe {
300
318
  if (!value)
301
319
  return this.lang.t('notSet');
302
320
  const asDetailType = asDetailTypes[attr.name] || null;
303
- // Resolve the breadcrumb template against the nested object's own fields.
304
- // (Phase 1: flat substitution mirrors the server's transitional behavior; Phase 5
305
- // replaces this with a server-emitted breadcrumb on the nested object.)
321
+ // The server's own resolution wins, because it can render templates this side cannot: a
322
+ // breadcrumb may name a property that `[IgnoreProperty]` deliberately keeps out of the model
323
+ // (HR's `Address.Crumb`), and no amount of client-side substitution will ever find it. Passing
324
+ // the type name filters out the mapper's "template rendered blank" placeholder, which is the
325
+ // bare type name rather than an empty string — see `selfBreadcrumb`.
326
+ const resolved = selfBreadcrumb(value, asDetailType?.name);
327
+ if (resolved)
328
+ return resolved;
329
+ // Still correct for a template naming real, projected attributes (`"{Street}, {City}"`), which
330
+ // is the common case and the only one reachable on the create path, where there is no server
331
+ // object to have resolved anything yet.
306
332
  if (asDetailType?.breadcrumb) {
307
333
  const result = applyFieldTemplate(asDetailType.breadcrumb, value);
308
334
  if (result && result.trim())
@@ -1 +1 @@
1
- {"version":3,"file":"mintplayer-ng-spark-pipes.mjs","sources":["../../pipes/src/translate-key.pipe.ts","../../pipes/src/resolve-translation.pipe.ts","../../pipes/src/input-type.pipe.ts","../../pipes/src/apply-field-template.ts","../../pipes/src/attribute-value.pipe.ts","../../pipes/src/raw-attribute-value.pipe.ts","../../pipes/src/reference-display-value.pipe.ts","../../pipes/src/reference-attr-value.pipe.ts","../../pipes/src/reference-link-route.pipe.ts","../../pipes/src/reference-chips.pipe.ts","../../pipes/src/router-link.pipe.ts","../../pipes/src/as-detail-type.pipe.ts","../../pipes/src/as-detail-columns.pipe.ts","../../pipes/src/as-detail-cell-value.pipe.ts","../../pipes/src/as-detail-display-value.pipe.ts","../../pipes/src/can-create-detail-row.pipe.ts","../../pipes/src/can-delete-detail-row.pipe.ts","../../pipes/src/lookup-display-type.pipe.ts","../../pipes/src/lookup-display-value.pipe.ts","../../pipes/src/lookup-options.pipe.ts","../../pipes/src/inline-ref-options.pipe.ts","../../pipes/src/error-for-attribute.pipe.ts","../../pipes/src/icon-name.pipe.ts","../../pipes/src/array-value.pipe.ts","../../pipes/mintplayer-ng-spark-pipes.ts"],"sourcesContent":["import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { SparkLanguageService } from '@mintplayer/ng-spark/services';\n\n@Pipe({ name: 't', pure: false, standalone: true })\nexport class TranslateKeyPipe implements PipeTransform {\n private readonly lang = inject(SparkLanguageService);\n\n transform(key: string): string {\n return this.lang.t(key);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { TranslatedString, resolveTranslation } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'resolveTranslation', standalone: true, pure: false })\nexport class ResolveTranslationPipe implements PipeTransform {\n transform(value: TranslatedString | undefined, fallback?: string): string {\n return resolveTranslation(value) || fallback || '';\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({ name: 'inputType', standalone: true, pure: true })\nexport class InputTypePipe implements PipeTransform {\n transform(dataType: string): string {\n switch (dataType) {\n case 'number':\n case 'decimal':\n return 'number';\n case 'boolean':\n return 'checkbox';\n case 'datetime':\n return 'datetime-local';\n case 'date':\n return 'date';\n case 'color':\n return 'color';\n default:\n return 'text';\n }\n }\n}\n","/**\n * Fills a `{Field}` template from a plain object's own fields. Used ONLY for AsDetail\n * nested-object summary display: an embedded value object (no id, no document) is rendered\n * client-side from its own fields. This is deliberately distinct from entity/reference\n * breadcrumbs — those are resolved recursively on the server (BreadcrumbResolver) and the\n * client only reads the resulting strings. Unknown or null placeholders render empty.\n */\nexport function applyFieldTemplate(template: string, data: Record<string, any>): string {\n return template.replace(/\\{(\\w+)\\}/g, (_match, propertyName) => {\n const value = data[propertyName];\n return value != null ? String(value) : '';\n });\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, EntityType, LookupReference, PersistentObject, nestedPoToDict, resolveTranslation } from '@mintplayer/ng-spark/models';\nimport { applyFieldTemplate } from './apply-field-template';\n\n@Pipe({ name: 'attributeValue', standalone: true, pure: true })\nexport class AttributeValuePipe implements PipeTransform {\n transform(attrName: string, item: PersistentObject | null, entityType: EntityType | null, lookupRefOptions: Record<string, LookupReference>, allEntityTypes: EntityType[]): any {\n if (!item) return '';\n const attr = item.attributes.find(a => a.name === attrName);\n if (!attr) return '';\n\n if (attr.breadcrumb) return attr.breadcrumb;\n\n const attrDef = entityType?.attributes.find(a => a.name === attrName);\n if (attrDef?.dataType === 'AsDetail') {\n // Server emits nested PO(s) in attr.objects (array) / attr.object (single) — attr.value is null.\n if (attr.isArray) {\n const count = attr.objects?.length ?? 0;\n if (count === 0) return '';\n return `${count} item${count !== 1 ? 's' : ''}`;\n }\n if (attr.object) {\n return this.formatAsDetailValue(attrDef, nestedPoToDict(attr.object), allEntityTypes);\n }\n }\n\n if (attrDef?.lookupReferenceType && attr.value != null && attr.value !== '') {\n const lookupRef = lookupRefOptions[attrDef.lookupReferenceType];\n if (lookupRef) {\n const option = lookupRef.values.find(v => v.key === String(attr.value));\n if (option) {\n return resolveTranslation(option.values) || option.key;\n }\n }\n }\n\n if (attrDef?.dataType === 'boolean') {\n return attr.value ?? null;\n }\n\n return attr.value ?? '';\n }\n\n private formatAsDetailValue(attrDef: EntityAttributeDefinition, value: Record<string, any>, allEntityTypes: EntityType[]): string {\n const asDetailType = allEntityTypes.find(t => t.clrType === attrDef.asDetailType);\n\n if (asDetailType?.breadcrumb) {\n const result = applyFieldTemplate(asDetailType.breadcrumb, value);\n if (result && result.trim()) return result;\n }\n\n return '(object)';\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { PersistentObject } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'rawAttributeValue', standalone: true, pure: true })\nexport class RawAttributeValuePipe implements PipeTransform {\n transform(attrName: string, item: PersistentObject | null): any {\n return item?.attributes.find(a => a.name === attrName)?.value;\n }\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { EntityAttributeDefinition, PersistentObject } from '@mintplayer/ng-spark/models';\nimport { SparkLanguageService } from '@mintplayer/ng-spark/services';\n\n@Pipe({ name: 'referenceDisplayValue', standalone: true, pure: true })\nexport class ReferenceDisplayValuePipe implements PipeTransform {\n private readonly lang = inject(SparkLanguageService);\n\n transform(attr: EntityAttributeDefinition, formData: Record<string, any>, referenceOptions: Record<string, PersistentObject[]>): string {\n const selectedId = formData[attr.name];\n if (!selectedId) return this.lang.t('notSelected');\n\n const options = referenceOptions[attr.name] || [];\n const selected = options.find(o => o.id === selectedId);\n return selected?.breadcrumb || selected?.name || selectedId;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { PersistentObject } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'referenceAttrValue', standalone: true, pure: true })\nexport class ReferenceAttrValuePipe implements PipeTransform {\n transform(item: PersistentObject, attrName: string): any {\n const attr = item.attributes.find(a => a.name === attrName);\n if (!attr) return '';\n if (attr.breadcrumb) return attr.breadcrumb;\n return attr.value ?? '';\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityType } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'referenceLinkRoute', standalone: true, pure: true })\nexport class ReferenceLinkRoutePipe implements PipeTransform {\n transform(referenceClrType: string, referenceId: any, allEntityTypes: EntityType[]): string[] | null {\n if (!referenceId || !referenceClrType) return null;\n const targetType = allEntityTypes.find(t => t.clrType === referenceClrType);\n if (!targetType) return null;\n return ['/po', targetType.alias || targetType.id, referenceId];\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { PersistentObject } from '@mintplayer/ng-spark/models';\n\nexport interface ReferenceChip {\n id: string;\n label: string;\n}\n\n/**\n * Resolves a multi-reference attribute (`dataType === 'Reference'`, `isArray === true`)\n * to a list of chips. The attribute's `value` carries the id array; `breadcrumbs` (a\n * server-resolved id → label map) provides each chip's display label, falling back to\n * the id when no breadcrumb is present. Mirrors the single-reference `breadcrumb`\n * display, applied per id.\n */\n@Pipe({ name: 'referenceChips', standalone: true, pure: true })\nexport class ReferenceChipsPipe implements PipeTransform {\n transform(attrName: string, item: PersistentObject | null): ReferenceChip[] {\n const attr = item?.attributes.find(a => a.name === attrName);\n if (!attr || !Array.isArray(attr.value)) return [];\n const breadcrumbs = attr.breadcrumbs ?? {};\n return attr.value\n .filter(v => v != null && v !== '')\n .map(v => {\n const id = String(v);\n return { id, label: breadcrumbs[id] || id };\n });\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { ProgramUnit } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'routerLink', standalone: true, pure: true })\nexport class RouterLinkPipe implements PipeTransform {\n transform(unit: ProgramUnit): string[] {\n if (unit.type === 'query') {\n return ['/query', unit.alias || unit.queryId!];\n } else if (unit.type === 'persistentObject') {\n return ['/po', unit.alias || unit.persistentObjectId!];\n }\n return ['/'];\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, EntityType } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'asDetailType', standalone: true, pure: true })\nexport class AsDetailTypePipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, asDetailTypes: Record<string, EntityType>): EntityType | null {\n return asDetailTypes[attr.name] || null;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, EntityType } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'asDetailColumns', standalone: true, pure: true })\nexport class AsDetailColumnsPipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, asDetailTypes: Record<string, EntityType>): EntityAttributeDefinition[] {\n const type = asDetailTypes[attr.name];\n if (!type) return [];\n return type.attributes\n .filter(a => a.isVisible)\n .sort((a, b) => a.order - b.order);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { AS_DETAIL_BREADCRUMBS_KEY, EntityAttributeDefinition, PersistentObject } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'asDetailCellValue', standalone: true, pure: true })\nexport class AsDetailCellValuePipe implements PipeTransform {\n transform(row: Record<string, any>, parentAttr: EntityAttributeDefinition, col: EntityAttributeDefinition, asDetailRefOptions: Record<string, Record<string, PersistentObject[]>>): string {\n const value = row[col.name];\n if (value == null) return '';\n\n if (col.dataType === 'Reference' && col.query) {\n // Prefer the breadcrumb the server already resolved by id — it is page-independent, so it\n // renders the label even when the referenced document falls outside the reference query's\n // first options page (issue #185).\n const serverBreadcrumb = (row[AS_DETAIL_BREADCRUMBS_KEY] as Record<string, string> | undefined)?.[col.name];\n if (serverBreadcrumb) return serverBreadcrumb;\n\n // Fallback: resolve against the loaded options page (legacy path).\n const parentOptions = asDetailRefOptions[parentAttr.name];\n if (parentOptions) {\n const options = parentOptions[col.name];\n if (options) {\n const match = options.find(o => o.id === value);\n if (match) return match.breadcrumb || match.name || String(value);\n }\n }\n }\n\n return String(value);\n }\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { EntityAttributeDefinition, EntityType } from '@mintplayer/ng-spark/models';\nimport { SparkLanguageService } from '@mintplayer/ng-spark/services';\nimport { applyFieldTemplate } from './apply-field-template';\n\n@Pipe({ name: 'asDetailDisplayValue', standalone: true, pure: true })\nexport class AsDetailDisplayValuePipe implements PipeTransform {\n private readonly lang = inject(SparkLanguageService);\n\n transform(attr: EntityAttributeDefinition, formData: Record<string, any>, asDetailTypes: Record<string, EntityType>): string {\n const value = formData[attr.name];\n if (!value) return this.lang.t('notSet');\n\n const asDetailType = asDetailTypes[attr.name] || null;\n\n // Resolve the breadcrumb template against the nested object's own fields.\n // (Phase 1: flat substitution mirrors the server's transitional behavior; Phase 5\n // replaces this with a server-emitted breadcrumb on the nested object.)\n if (asDetailType?.breadcrumb) {\n const result = applyFieldTemplate(asDetailType.breadcrumb, value);\n if (result && result.trim()) return result;\n }\n\n return this.lang.t('clickToEdit');\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, EntityPermissions } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'canCreateDetailRow', standalone: true, pure: true })\nexport class CanCreateDetailRowPipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, permissions: Record<string, EntityPermissions>): boolean {\n const perms = permissions[attr.name];\n return perms ? perms.canCreate : true;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, EntityPermissions } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'canDeleteDetailRow', standalone: true, pure: true })\nexport class CanDeleteDetailRowPipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, permissions: Record<string, EntityPermissions>): boolean {\n const perms = permissions[attr.name];\n return perms ? perms.canDelete : true;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { ELookupDisplayType, EntityAttributeDefinition, LookupReference } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'lookupDisplayType', standalone: true, pure: true })\nexport class LookupDisplayTypePipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, lookupRefOptions: Record<string, LookupReference>): ELookupDisplayType {\n const lookupRef = attr.lookupReferenceType ? lookupRefOptions[attr.lookupReferenceType] : null;\n return lookupRef?.displayType ?? ELookupDisplayType.Dropdown;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, LookupReference, resolveTranslation } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'lookupDisplayValue', standalone: true, pure: true })\nexport class LookupDisplayValuePipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, formData: Record<string, any>, lookupRefOptions: Record<string, LookupReference>): string {\n const currentValue = formData[attr.name];\n if (currentValue == null || currentValue === '') return '';\n\n const lookupRef = attr.lookupReferenceType ? lookupRefOptions[attr.lookupReferenceType] : null;\n const options = lookupRef?.values.filter(v => v.isActive) || [];\n const selected = options.find(o => o.key === String(currentValue));\n if (!selected) return String(currentValue);\n\n return resolveTranslation(selected.values) || selected.key;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, LookupReference, LookupReferenceValue } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'lookupOptions', standalone: true, pure: true })\nexport class LookupOptionsPipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, lookupRefOptions: Record<string, LookupReference>): LookupReferenceValue[] {\n const lookupRef = attr.lookupReferenceType ? lookupRefOptions[attr.lookupReferenceType] : null;\n return lookupRef?.values.filter(v => v.isActive) || [];\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, PersistentObject } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'inlineRefOptions', standalone: true, pure: true })\nexport class InlineRefOptionsPipe implements PipeTransform {\n transform(parentAttr: EntityAttributeDefinition, col: EntityAttributeDefinition, asDetailRefOptions: Record<string, Record<string, PersistentObject[]>>): PersistentObject[] {\n return asDetailRefOptions[parentAttr.name]?.[col.name] || [];\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { ValidationError, resolveTranslation } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'errorForAttribute', standalone: true, pure: true })\nexport class ErrorForAttributePipe implements PipeTransform {\n transform(attrName: string, validationErrors: ValidationError[]): string | null {\n const error = validationErrors.find(e => e.attributeName === attrName);\n return error ? resolveTranslation(error.errorMessage) : null;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({ name: 'iconName', standalone: true, pure: true })\nexport class IconNamePipe implements PipeTransform {\n transform(value: string | undefined, fallback: string): string {\n const iconClass = value || fallback;\n // Strip 'bi-' prefix if present\n return iconClass.startsWith('bi-') ? iconClass.substring(3) : iconClass;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { PersistentObject, nestedPoToDisplayRow } from '@mintplayer/ng-spark/models';\n\n/**\n * Resolves an attribute to a list of flat row dicts for the detail-page table.\n * AsDetail array attributes carry their data as nested PersistentObjects in\n * <c>attr.objects</c>, not <c>attr.value</c> — the server stopped putting flat\n * dicts in <c>value</c> when AsDetail moved to its dedicated wire shape. Without\n * this branch, the detail page rendered AsDetail arrays as empty tables even\n * when the edit page (which reads <c>attr.objects</c> directly) showed rows.\n */\n@Pipe({ name: 'arrayValue', standalone: true, pure: true })\nexport class ArrayValuePipe implements PipeTransform {\n transform(attrName: string, item: PersistentObject | null): Record<string, any>[] {\n const attr = item?.attributes.find(a => a.name === attrName);\n if (!attr) return [];\n if (attr.dataType === 'AsDetail' && attr.isArray && Array.isArray(attr.objects)) {\n return attr.objects.map(po => nestedPoToDisplayRow(po));\n }\n if (Array.isArray(attr.value)) return attr.value;\n return [];\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mintplayer-ng-spark-pipes.mjs","sources":["../../pipes/src/translate-key.pipe.ts","../../pipes/src/resolve-translation.pipe.ts","../../pipes/src/input-type.pipe.ts","../../pipes/src/apply-field-template.ts","../../pipes/src/attribute-value.pipe.ts","../../pipes/src/raw-attribute-value.pipe.ts","../../pipes/src/reference-display-value.pipe.ts","../../pipes/src/reference-attr-value.pipe.ts","../../pipes/src/reference-link-route.pipe.ts","../../pipes/src/reference-chips.pipe.ts","../../pipes/src/router-link.pipe.ts","../../pipes/src/as-detail-type.pipe.ts","../../pipes/src/as-detail-columns.pipe.ts","../../pipes/src/as-detail-cell-value.pipe.ts","../../pipes/src/as-detail-display-value.pipe.ts","../../pipes/src/can-create-detail-row.pipe.ts","../../pipes/src/can-delete-detail-row.pipe.ts","../../pipes/src/lookup-display-type.pipe.ts","../../pipes/src/lookup-display-value.pipe.ts","../../pipes/src/lookup-options.pipe.ts","../../pipes/src/inline-ref-options.pipe.ts","../../pipes/src/error-for-attribute.pipe.ts","../../pipes/src/icon-name.pipe.ts","../../pipes/src/array-value.pipe.ts","../../pipes/mintplayer-ng-spark-pipes.ts"],"sourcesContent":["import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { SparkLanguageService } from '@mintplayer/ng-spark/services';\n\n@Pipe({ name: 't', pure: false, standalone: true })\nexport class TranslateKeyPipe implements PipeTransform {\n private readonly lang = inject(SparkLanguageService);\n\n transform(key: string): string {\n return this.lang.t(key);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { TranslatedString, resolveTranslation } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'resolveTranslation', standalone: true, pure: false })\nexport class ResolveTranslationPipe implements PipeTransform {\n transform(value: TranslatedString | undefined, fallback?: string): string {\n return resolveTranslation(value) || fallback || '';\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({ name: 'inputType', standalone: true, pure: true })\nexport class InputTypePipe implements PipeTransform {\n transform(dataType: string): string {\n switch (dataType) {\n case 'number':\n case 'decimal':\n return 'number';\n case 'boolean':\n return 'checkbox';\n case 'datetime':\n return 'datetime-local';\n case 'date':\n return 'date';\n case 'color':\n return 'color';\n default:\n return 'text';\n }\n }\n}\n","/**\n * Fills a `{Field}` template from a plain object's own fields. Used ONLY for AsDetail\n * nested-object summary display: an embedded value object (no id, no document) is rendered\n * client-side from its own fields. This is deliberately distinct from entity/reference\n * breadcrumbs — those are resolved recursively on the server (BreadcrumbResolver) and the\n * client only reads the resulting strings. Unknown or null placeholders render empty.\n */\nexport function applyFieldTemplate(template: string, data: Record<string, any>): string {\n return template.replace(/\\{(\\w+)\\}/g, (_match, propertyName) => {\n const value = data[propertyName];\n return value != null ? String(value) : '';\n });\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, EntityType, LookupReference, PersistentObject, nestedPoToDict, resolveTranslation } from '@mintplayer/ng-spark/models';\nimport { applyFieldTemplate } from './apply-field-template';\n\n@Pipe({ name: 'attributeValue', standalone: true, pure: true })\nexport class AttributeValuePipe implements PipeTransform {\n transform(attrName: string, item: PersistentObject | null, entityType: EntityType | null, lookupRefOptions: Record<string, LookupReference>, allEntityTypes: EntityType[]): any {\n if (!item) return '';\n const attr = item.attributes.find(a => a.name === attrName);\n if (!attr) return '';\n\n if (attr.breadcrumb) return attr.breadcrumb;\n\n const attrDef = entityType?.attributes.find(a => a.name === attrName);\n if (attrDef?.dataType === 'AsDetail') {\n // Server emits nested PO(s) in attr.objects (array) / attr.object (single) — attr.value is null.\n if (attr.isArray) {\n const count = attr.objects?.length ?? 0;\n if (count === 0) return '';\n return `${count} item${count !== 1 ? 's' : ''}`;\n }\n if (attr.object) {\n // The server has already resolved this object's breadcrumb, and it can resolve templates\n // this side cannot. A type's breadcrumb may name a computed property that `[IgnoreProperty]`\n // keeps out of the model — HR's `Address.Crumb` is exactly that, `[Breadcrumb, IgnoreProperty]`\n // — so the template `{Crumb}` has no matching attribute here and never will. Recomputing it\n // client-side produced an empty string and fell through to \"(object)\" while the correct\n // \"Deinzestraat 231, 9700 Oudenaarde\" sat unread on `attr.object.breadcrumb`.\n if (attr.object.breadcrumb) return attr.object.breadcrumb;\n return this.formatAsDetailValue(attrDef, nestedPoToDict(attr.object), allEntityTypes);\n }\n }\n\n if (attrDef?.lookupReferenceType && attr.value != null && attr.value !== '') {\n const lookupRef = lookupRefOptions[attrDef.lookupReferenceType];\n if (lookupRef) {\n const option = lookupRef.values.find(v => v.key === String(attr.value));\n if (option) {\n return resolveTranslation(option.values) || option.key;\n }\n }\n }\n\n if (attrDef?.dataType === 'boolean') {\n return attr.value ?? null;\n }\n\n return attr.value ?? '';\n }\n\n private formatAsDetailValue(attrDef: EntityAttributeDefinition, value: Record<string, any>, allEntityTypes: EntityType[]): string {\n const asDetailType = allEntityTypes.find(t => t.clrType === attrDef.asDetailType);\n\n if (asDetailType?.breadcrumb) {\n const result = applyFieldTemplate(asDetailType.breadcrumb, value);\n if (result && result.trim()) return result;\n }\n\n // Last resort, reached when the type declares no breadcrumb or its template resolved to\n // nothing. Joining the scalar values is always more use to a reader than \"(object)\", which\n // named the failure rather than the row and looked identical for every unresolvable cell.\n return Object.values(value)\n .filter(v => v != null && typeof v !== 'object' && String(v).trim() !== '')\n .join(', ');\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { PersistentObject } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'rawAttributeValue', standalone: true, pure: true })\nexport class RawAttributeValuePipe implements PipeTransform {\n transform(attrName: string, item: PersistentObject | null): any {\n return item?.attributes.find(a => a.name === attrName)?.value;\n }\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { EntityAttributeDefinition, PersistentObject } from '@mintplayer/ng-spark/models';\nimport { SparkLanguageService } from '@mintplayer/ng-spark/services';\n\n@Pipe({ name: 'referenceDisplayValue', standalone: true, pure: true })\nexport class ReferenceDisplayValuePipe implements PipeTransform {\n private readonly lang = inject(SparkLanguageService);\n\n transform(attr: EntityAttributeDefinition, formData: Record<string, any>, referenceOptions: Record<string, PersistentObject[]>): string {\n const selectedId = formData[attr.name];\n if (!selectedId) return this.lang.t('notSelected');\n\n const options = referenceOptions[attr.name] || [];\n const selected = options.find(o => o.id === selectedId);\n return selected?.breadcrumb || selected?.name || selectedId;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { PersistentObject } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'referenceAttrValue', standalone: true, pure: true })\nexport class ReferenceAttrValuePipe implements PipeTransform {\n transform(item: PersistentObject, attrName: string): any {\n const attr = item.attributes.find(a => a.name === attrName);\n if (!attr) return '';\n if (attr.breadcrumb) return attr.breadcrumb;\n return attr.value ?? '';\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityType } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'referenceLinkRoute', standalone: true, pure: true })\nexport class ReferenceLinkRoutePipe implements PipeTransform {\n transform(referenceClrType: string, referenceId: any, allEntityTypes: EntityType[]): string[] | null {\n if (!referenceId || !referenceClrType) return null;\n const targetType = allEntityTypes.find(t => t.clrType === referenceClrType);\n if (!targetType) return null;\n return ['/po', targetType.alias || targetType.id, referenceId];\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { PersistentObject } from '@mintplayer/ng-spark/models';\n\nexport interface ReferenceChip {\n id: string;\n label: string;\n}\n\n/**\n * Resolves a multi-reference attribute (`dataType === 'Reference'`, `isArray === true`)\n * to a list of chips. The attribute's `value` carries the id array; `breadcrumbs` (a\n * server-resolved id → label map) provides each chip's display label, falling back to\n * the id when no breadcrumb is present. Mirrors the single-reference `breadcrumb`\n * display, applied per id.\n */\n@Pipe({ name: 'referenceChips', standalone: true, pure: true })\nexport class ReferenceChipsPipe implements PipeTransform {\n transform(attrName: string, item: PersistentObject | null): ReferenceChip[] {\n const attr = item?.attributes.find(a => a.name === attrName);\n if (!attr || !Array.isArray(attr.value)) return [];\n const breadcrumbs = attr.breadcrumbs ?? {};\n return attr.value\n .filter(v => v != null && v !== '')\n .map(v => {\n const id = String(v);\n return { id, label: breadcrumbs[id] || id };\n });\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { ProgramUnit } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'routerLink', standalone: true, pure: true })\nexport class RouterLinkPipe implements PipeTransform {\n transform(unit: ProgramUnit): string[] {\n if (unit.type === 'query') {\n return ['/query', unit.alias || unit.queryId!];\n } else if (unit.type === 'persistentObject') {\n return ['/po', unit.alias || unit.persistentObjectId!];\n }\n return ['/'];\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, EntityType } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'asDetailType', standalone: true, pure: true })\nexport class AsDetailTypePipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, asDetailTypes: Record<string, EntityType>): EntityType | null {\n return asDetailTypes[attr.name] || null;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, EntityType } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'asDetailColumns', standalone: true, pure: true })\nexport class AsDetailColumnsPipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, asDetailTypes: Record<string, EntityType>): EntityAttributeDefinition[] {\n const type = asDetailTypes[attr.name];\n if (!type) return [];\n return type.attributes\n .filter(a => a.isVisible)\n .sort((a, b) => a.order - b.order);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { AS_DETAIL_BREADCRUMBS_KEY, EntityAttributeDefinition, PersistentObject, selfBreadcrumb } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'asDetailCellValue', standalone: true, pure: true })\nexport class AsDetailCellValuePipe implements PipeTransform {\n transform(row: Record<string, any>, parentAttr: EntityAttributeDefinition, col: EntityAttributeDefinition, asDetailRefOptions: Record<string, Record<string, PersistentObject[]>>): string {\n const value = row[col.name];\n if (value == null) return '';\n\n if (col.dataType === 'Reference' && col.query) {\n // Prefer the breadcrumb the server already resolved by id — it is page-independent, so it\n // renders the label even when the referenced document falls outside the reference query's\n // first options page (issue #185).\n const serverBreadcrumb = (row[AS_DETAIL_BREADCRUMBS_KEY] as Record<string, string> | undefined)?.[col.name];\n if (serverBreadcrumb) return serverBreadcrumb;\n\n // Fallback: resolve against the loaded options page (legacy path).\n const parentOptions = asDetailRefOptions[parentAttr.name];\n if (parentOptions) {\n const options = parentOptions[col.name];\n if (options) {\n const match = options.find(o => o.id === value);\n if (match) return match.breadcrumb || match.name || String(value);\n }\n }\n }\n\n // A nested-AsDetail column's value is an inner dict, so String(value) produced \"[object\n // Object]\". The flattener kept that object's server-resolved breadcrumb for exactly this.\n if (col.dataType === 'AsDetail' && typeof value === 'object') {\n return selfBreadcrumb(value as Record<string, any>, col.asDetailType) ?? '';\n }\n\n return String(value);\n }\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { EntityAttributeDefinition, EntityType, selfBreadcrumb } from '@mintplayer/ng-spark/models';\nimport { SparkLanguageService } from '@mintplayer/ng-spark/services';\nimport { applyFieldTemplate } from './apply-field-template';\n\n@Pipe({ name: 'asDetailDisplayValue', standalone: true, pure: true })\nexport class AsDetailDisplayValuePipe implements PipeTransform {\n private readonly lang = inject(SparkLanguageService);\n\n transform(attr: EntityAttributeDefinition, formData: Record<string, any>, asDetailTypes: Record<string, EntityType>): string {\n const value = formData[attr.name];\n if (!value) return this.lang.t('notSet');\n\n const asDetailType = asDetailTypes[attr.name] || null;\n\n // The server's own resolution wins, because it can render templates this side cannot: a\n // breadcrumb may name a property that `[IgnoreProperty]` deliberately keeps out of the model\n // (HR's `Address.Crumb`), and no amount of client-side substitution will ever find it. Passing\n // the type name filters out the mapper's \"template rendered blank\" placeholder, which is the\n // bare type name rather than an empty string — see `selfBreadcrumb`.\n const resolved = selfBreadcrumb(value, asDetailType?.name);\n if (resolved) return resolved;\n\n // Still correct for a template naming real, projected attributes (`\"{Street}, {City}\"`), which\n // is the common case and the only one reachable on the create path, where there is no server\n // object to have resolved anything yet.\n if (asDetailType?.breadcrumb) {\n const result = applyFieldTemplate(asDetailType.breadcrumb, value);\n if (result && result.trim()) return result;\n }\n\n return this.lang.t('clickToEdit');\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, EntityPermissions } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'canCreateDetailRow', standalone: true, pure: true })\nexport class CanCreateDetailRowPipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, permissions: Record<string, EntityPermissions>): boolean {\n const perms = permissions[attr.name];\n return perms ? perms.canCreate : true;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, EntityPermissions } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'canDeleteDetailRow', standalone: true, pure: true })\nexport class CanDeleteDetailRowPipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, permissions: Record<string, EntityPermissions>): boolean {\n const perms = permissions[attr.name];\n return perms ? perms.canDelete : true;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { ELookupDisplayType, EntityAttributeDefinition, LookupReference } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'lookupDisplayType', standalone: true, pure: true })\nexport class LookupDisplayTypePipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, lookupRefOptions: Record<string, LookupReference>): ELookupDisplayType {\n const lookupRef = attr.lookupReferenceType ? lookupRefOptions[attr.lookupReferenceType] : null;\n return lookupRef?.displayType ?? ELookupDisplayType.Dropdown;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, LookupReference, resolveTranslation } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'lookupDisplayValue', standalone: true, pure: true })\nexport class LookupDisplayValuePipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, formData: Record<string, any>, lookupRefOptions: Record<string, LookupReference>): string {\n const currentValue = formData[attr.name];\n if (currentValue == null || currentValue === '') return '';\n\n const lookupRef = attr.lookupReferenceType ? lookupRefOptions[attr.lookupReferenceType] : null;\n const options = lookupRef?.values.filter(v => v.isActive) || [];\n const selected = options.find(o => o.key === String(currentValue));\n if (!selected) return String(currentValue);\n\n return resolveTranslation(selected.values) || selected.key;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, LookupReference, LookupReferenceValue } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'lookupOptions', standalone: true, pure: true })\nexport class LookupOptionsPipe implements PipeTransform {\n transform(attr: EntityAttributeDefinition, lookupRefOptions: Record<string, LookupReference>): LookupReferenceValue[] {\n const lookupRef = attr.lookupReferenceType ? lookupRefOptions[attr.lookupReferenceType] : null;\n return lookupRef?.values.filter(v => v.isActive) || [];\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { EntityAttributeDefinition, PersistentObject } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'inlineRefOptions', standalone: true, pure: true })\nexport class InlineRefOptionsPipe implements PipeTransform {\n transform(parentAttr: EntityAttributeDefinition, col: EntityAttributeDefinition, asDetailRefOptions: Record<string, Record<string, PersistentObject[]>>): PersistentObject[] {\n return asDetailRefOptions[parentAttr.name]?.[col.name] || [];\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { ValidationError, resolveTranslation } from '@mintplayer/ng-spark/models';\n\n@Pipe({ name: 'errorForAttribute', standalone: true, pure: true })\nexport class ErrorForAttributePipe implements PipeTransform {\n transform(attrName: string, validationErrors: ValidationError[]): string | null {\n const error = validationErrors.find(e => e.attributeName === attrName);\n return error ? resolveTranslation(error.errorMessage) : null;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({ name: 'iconName', standalone: true, pure: true })\nexport class IconNamePipe implements PipeTransform {\n transform(value: string | undefined, fallback: string): string {\n const iconClass = value || fallback;\n // Strip 'bi-' prefix if present\n return iconClass.startsWith('bi-') ? iconClass.substring(3) : iconClass;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { PersistentObject, nestedPoToDisplayRow } from '@mintplayer/ng-spark/models';\n\n/**\n * Resolves an attribute to a list of flat row dicts for the detail-page table.\n * AsDetail array attributes carry their data as nested PersistentObjects in\n * <c>attr.objects</c>, not <c>attr.value</c> — the server stopped putting flat\n * dicts in <c>value</c> when AsDetail moved to its dedicated wire shape. Without\n * this branch, the detail page rendered AsDetail arrays as empty tables even\n * when the edit page (which reads <c>attr.objects</c> directly) showed rows.\n */\n@Pipe({ name: 'arrayValue', standalone: true, pure: true })\nexport class ArrayValuePipe implements PipeTransform {\n transform(attrName: string, item: PersistentObject | null): Record<string, any>[] {\n const attr = item?.attributes.find(a => a.name === attrName);\n if (!attr) return [];\n if (attr.dataType === 'AsDetail' && attr.isArray && Array.isArray(attr.objects)) {\n return attr.objects.map(po => nestedPoToDisplayRow(po));\n }\n if (Array.isArray(attr.value)) return attr.value;\n return [];\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -139,11 +139,11 @@ class SparkPoCreateComponent {
139
139
  window.history.back();
140
140
  }
141
141
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: SparkPoCreateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
142
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: SparkPoCreateComponent, isStandalone: true, selector: "spark-po-create", outputs: { saved: "saved", cancelled: "cancelled" }, ngImport: i0, template: "<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: BsAlertComponent, selector: "bs-alert", inputs: ["type", "announce", "isVisible"], outputs: ["isVisibleChange", "afterOpenedOrClosed"] }, { kind: "component", type: BsContainerComponent, selector: "bs-container" }, { kind: "component", type: BsSpinnerComponent, selector: "bs-spinner", inputs: ["type", "color"] }, { kind: "component", type: SparkPoFormComponent, selector: "spark-po-form", inputs: ["entityType", "formData", "validationErrors", "showButtons", "isSaving", "parentId", "parentType"], outputs: ["formDataChange", "save", "cancel"] }, { kind: "pipe", type: ResolveTranslationPipe, name: "resolveTranslation" }, { kind: "pipe", type: TranslateKeyPipe, name: "t" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
142
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: SparkPoCreateComponent, isStandalone: true, selector: "spark-po-create", outputs: { saved: "saved", cancelled: "cancelled" }, ngImport: i0, template: "<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [objectTypeId]=\"type()\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: BsAlertComponent, selector: "bs-alert", inputs: ["type", "announce", "isVisible"], outputs: ["isVisibleChange", "afterOpenedOrClosed"] }, { kind: "component", type: BsContainerComponent, selector: "bs-container" }, { kind: "component", type: BsSpinnerComponent, selector: "bs-spinner", inputs: ["type", "color"] }, { kind: "component", type: SparkPoFormComponent, selector: "spark-po-form", inputs: ["entityType", "formData", "validationErrors", "showButtons", "isSaving", "parentId", "parentType", "objectTypeId", "objectId"], outputs: ["formDataChange", "save", "cancel"] }, { kind: "pipe", type: ResolveTranslationPipe, name: "resolveTranslation" }, { kind: "pipe", type: TranslateKeyPipe, name: "t" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
143
143
  }
144
144
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: SparkPoCreateComponent, decorators: [{
145
145
  type: Component,
146
- args: [{ selector: 'spark-po-create', imports: [CommonModule, BsAlertComponent, BsContainerComponent, BsSpinnerComponent, SparkPoFormComponent, ResolveTranslationPipe, TranslateKeyPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\n" }]
146
+ args: [{ selector: 'spark-po-create', imports: [CommonModule, BsAlertComponent, BsContainerComponent, BsSpinnerComponent, SparkPoFormComponent, ResolveTranslationPipe, TranslateKeyPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [objectTypeId]=\"type()\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\n" }]
147
147
  }], ctorParameters: () => [], propDecorators: { saved: [{ type: i0.Output, args: ["saved"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
148
148
 
149
149
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"mintplayer-ng-spark-po-create.mjs","sources":["../../po-create/src/spark-po-create.component.ts","../../po-create/src/spark-po-create.component.html","../../po-create/mintplayer-ng-spark-po-create.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { CommonModule } from '@angular/common';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';\nimport { BsContainerComponent } from '@mintplayer/ng-bootstrap/container';\nimport { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';\nimport { SparkService } from '@mintplayer/ng-spark/services';\nimport { SparkPoFormComponent } from '@mintplayer/ng-spark/po-form';\nimport { TranslateKeyPipe, ResolveTranslationPipe } from '@mintplayer/ng-spark/pipes';\nimport {\n EntityType,\n PersistentObject,\n PersistentObjectAttribute,\n ValidationError,\n ShowedOn,\n hasShowedOnFlag,\n dictToNestedPo,\n EntityTypeResolver,\n} from '@mintplayer/ng-spark/models';\n\n@Component({\n selector: 'spark-po-create',\n imports: [CommonModule, BsAlertComponent, BsContainerComponent, BsSpinnerComponent, SparkPoFormComponent, ResolveTranslationPipe, TranslateKeyPipe],\n templateUrl: './spark-po-create.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SparkPoCreateComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly sparkService = inject(SparkService);\n\n saved = output<PersistentObject>();\n cancelled = output<void>();\n\n colors = Color;\n entityType = signal<EntityType | null>(null);\n type = signal('');\n formData = signal<Record<string, any>>({});\n validationErrors = signal<ValidationError[]>([]);\n isSaving = signal(false);\n private allEntityTypes = signal<EntityType[]>([]);\n generalErrors = computed(() => this.validationErrors().filter(e => !e.attributeName));\n\n constructor() {\n this.route.paramMap.pipe(takeUntilDestroyed()).subscribe(params => this.onParamsChange(params));\n }\n\n private async onParamsChange(params: any): Promise<void> {\n this.type.set(params.get('type') || '');\n const types = await this.sparkService.getEntityTypes();\n const entityType = types.find(t => t.id === this.type() || t.alias === this.type()) || null;\n this.entityType.set(entityType);\n this.allEntityTypes.set(types);\n this.initFormData();\n }\n\n initFormData(): void {\n const data: Record<string, any> = {};\n this.getEditableAttributes().forEach(attr => {\n if (attr.dataType === 'Reference') {\n data[attr.name] = null;\n } else if (attr.dataType === 'AsDetail') {\n data[attr.name] = attr.isArray ? [] : {};\n } else if (attr.dataType === 'boolean') {\n data[attr.name] = false;\n } else {\n data[attr.name] = '';\n }\n });\n this.formData.set(data);\n }\n\n getEditableAttributes() {\n return this.entityType()?.attributes\n .filter(a => a.isVisible && !a.isReadOnly && hasShowedOnFlag(a.showedOn, ShowedOn.PersistentObject))\n .sort((a, b) => a.order - b.order) || [];\n }\n\n async onSave(): Promise<void> {\n if (!this.entityType()) return;\n\n this.validationErrors.set([]);\n this.isSaving.set(true);\n\n const resolver: EntityTypeResolver = (clrName) => this.allEntityTypes().find(t => t.clrType === clrName);\n const attributes: PersistentObjectAttribute[] = this.getEditableAttributes().map(attr => {\n const base: PersistentObjectAttribute = {\n id: attr.id,\n name: attr.name,\n value: this.formData()[attr.name],\n dataType: attr.dataType,\n isArray: attr.isArray,\n isRequired: attr.isRequired,\n isVisible: attr.isVisible,\n isReadOnly: attr.isReadOnly,\n isValueChanged: true,\n order: attr.order,\n rules: attr.rules,\n };\n\n // AsDetail: pack the flat form dict into nested PO wire shape. Server's polymorphic\n // converter ignores attr.value for AsDetail and reads attr.object / attr.objects.\n if (attr.dataType === 'AsDetail' && attr.asDetailType) {\n const nestedType = resolver(attr.asDetailType);\n if (nestedType) {\n const raw = this.formData()[attr.name];\n base.value = null;\n base.asDetailType = attr.asDetailType;\n if (attr.isArray) {\n const items: any[] = Array.isArray(raw) ? raw : [];\n base.objects = items.map(item => dictToNestedPo((item ?? {}) as Record<string, any>, nestedType, resolver));\n base.object = null;\n } else {\n base.object = raw ? dictToNestedPo(raw as Record<string, any>, nestedType, resolver) : null;\n base.objects = null;\n }\n }\n }\n return base;\n });\n\n const po: Partial<PersistentObject> = {\n name: this.formData()['Name'] || 'New Item',\n objectTypeId: this.entityType()!.id,\n attributes\n };\n\n try {\n const result = await this.sparkService.create(this.type(), po);\n this.isSaving.set(false);\n this.saved.emit(result);\n this.router.navigate(['/po', this.type(), result.id]);\n } catch (e) {\n this.isSaving.set(false);\n const error = e as HttpErrorResponse;\n if (error.status === 400 && error.error?.errors) {\n this.validationErrors.set(error.error.errors);\n } else {\n this.validationErrors.set([{\n attributeName: '',\n errorMessage: { en: error.message || 'An unexpected error occurred' },\n ruleType: 'error'\n }]);\n }\n }\n }\n\n onCancel(): void {\n this.cancelled.emit();\n window.history.back();\n }\n}\n","<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;;;;MA6Ba,sBAAsB,CAAA;AAChB,IAAA,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AAC9B,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,IAAA,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IAEpD,KAAK,GAAG,MAAM,EAAoB;IAClC,SAAS,GAAG,MAAM,EAAQ;IAE1B,MAAM,GAAG,KAAK;IACd,UAAU,GAAG,MAAM,CAAoB,IAAI;mFAAC;IAC5C,IAAI,GAAG,MAAM,CAAC,EAAE;6EAAC;IACjB,QAAQ,GAAG,MAAM,CAAsB,EAAE;iFAAC;IAC1C,gBAAgB,GAAG,MAAM,CAAoB,EAAE;yFAAC;IAChD,QAAQ,GAAG,MAAM,CAAC,KAAK;iFAAC;IAChB,cAAc,GAAG,MAAM,CAAe,EAAE;uFAAC;IACjD,aAAa,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC;sFAAC;AAErF,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IACjG;IAEQ,MAAM,cAAc,CAAC,MAAW,EAAA;AACtC,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE;AACtD,QAAA,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI;AAC3F,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC;AAC/B,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC;QAC9B,IAAI,CAAC,YAAY,EAAE;IACrB;IAEA,YAAY,GAAA;QACV,MAAM,IAAI,GAAwB,EAAE;QACpC,IAAI,CAAC,qBAAqB,EAAE,CAAC,OAAO,CAAC,IAAI,IAAG;AAC1C,YAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,WAAW,EAAE;AACjC,gBAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI;YACxB;AAAO,iBAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,UAAU,EAAE;AACvC,gBAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,EAAE;YAC1C;AAAO,iBAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;AACtC,gBAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK;YACzB;iBAAO;AACL,gBAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YACtB;AACF,QAAA,CAAC,CAAC;AACF,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;IACzB;IAEA,qBAAqB,GAAA;AACnB,QAAA,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE;aACvB,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,eAAe,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAAC;AAClG,aAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE;IAC5C;AAEA,IAAA,MAAM,MAAM,GAAA;AACV,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YAAE;AAExB,QAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;AAC7B,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;QAEvB,MAAM,QAAQ,GAAuB,CAAC,OAAO,KAAK,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC;QACxG,MAAM,UAAU,GAAgC,IAAI,CAAC,qBAAqB,EAAE,CAAC,GAAG,CAAC,IAAI,IAAG;AACtF,YAAA,MAAM,IAAI,GAA8B;gBACtC,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;gBACjC,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,UAAU,EAAE,IAAI,CAAC,UAAU;AAC3B,gBAAA,cAAc,EAAE,IAAI;gBACpB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB;;;YAID,IAAI,IAAI,CAAC,QAAQ,KAAK,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE;gBACrD,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC;gBAC9C,IAAI,UAAU,EAAE;oBACd,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;AACtC,oBAAA,IAAI,CAAC,KAAK,GAAG,IAAI;AACjB,oBAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY;AACrC,oBAAA,IAAI,IAAI,CAAC,OAAO,EAAE;AAChB,wBAAA,MAAM,KAAK,GAAU,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,EAAE;wBAClD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,cAAc,EAAE,IAAI,IAAI,EAAE,GAA0B,UAAU,EAAE,QAAQ,CAAC,CAAC;AAC3G,wBAAA,IAAI,CAAC,MAAM,GAAG,IAAI;oBACpB;yBAAO;AACL,wBAAA,IAAI,CAAC,MAAM,GAAG,GAAG,GAAG,cAAc,CAAC,GAA0B,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,IAAI;AAC3F,wBAAA,IAAI,CAAC,OAAO,GAAG,IAAI;oBACrB;gBACF;YACF;AACA,YAAA,OAAO,IAAI;AACb,QAAA,CAAC,CAAC;AAEF,QAAA,MAAM,EAAE,GAA8B;YACpC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,IAAI,UAAU;AAC3C,YAAA,YAAY,EAAE,IAAI,CAAC,UAAU,EAAG,CAAC,EAAE;YACnC;SACD;AAED,QAAA,IAAI;AACF,YAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;AAC9D,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AACxB,YAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;AACvB,YAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACvD;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;YACxB,MAAM,KAAK,GAAG,CAAsB;AACpC,YAAA,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE;gBAC/C,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;YAC/C;iBAAO;AACL,gBAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;AACzB,wBAAA,aAAa,EAAE,EAAE;wBACjB,YAAY,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,OAAO,IAAI,8BAA8B,EAAE;AACrE,wBAAA,QAAQ,EAAE;AACX,qBAAA,CAAC,CAAC;YACL;QACF;IACF;IAEA,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;AACrB,QAAA,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;IACvB;uGA5HW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,EAAA,KAAA,EAAA,OAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC7BnC,6wBA2BA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDFY,YAAY,+BAAE,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,iBAAA,EAAA,qBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,oBAAoB,EAAA,QAAA,EAAA,cAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,kBAAkB,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,oBAAoB,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,UAAA,EAAA,YAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAE,sBAAsB,sDAAE,gBAAgB,EAAA,IAAA,EAAA,GAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAIvI,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBANlC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,WAClB,CAAC,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,gBAAgB,CAAC,EAAA,eAAA,EAElI,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,6wBAAA,EAAA;;;AE3BjD;;AAEG;;;;"}
1
+ {"version":3,"file":"mintplayer-ng-spark-po-create.mjs","sources":["../../po-create/src/spark-po-create.component.ts","../../po-create/src/spark-po-create.component.html","../../po-create/mintplayer-ng-spark-po-create.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { CommonModule } from '@angular/common';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';\nimport { BsContainerComponent } from '@mintplayer/ng-bootstrap/container';\nimport { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';\nimport { SparkService } from '@mintplayer/ng-spark/services';\nimport { SparkPoFormComponent } from '@mintplayer/ng-spark/po-form';\nimport { TranslateKeyPipe, ResolveTranslationPipe } from '@mintplayer/ng-spark/pipes';\nimport {\n EntityType,\n PersistentObject,\n PersistentObjectAttribute,\n ValidationError,\n ShowedOn,\n hasShowedOnFlag,\n dictToNestedPo,\n EntityTypeResolver,\n} from '@mintplayer/ng-spark/models';\n\n@Component({\n selector: 'spark-po-create',\n imports: [CommonModule, BsAlertComponent, BsContainerComponent, BsSpinnerComponent, SparkPoFormComponent, ResolveTranslationPipe, TranslateKeyPipe],\n templateUrl: './spark-po-create.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SparkPoCreateComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly sparkService = inject(SparkService);\n\n saved = output<PersistentObject>();\n cancelled = output<void>();\n\n colors = Color;\n entityType = signal<EntityType | null>(null);\n type = signal('');\n formData = signal<Record<string, any>>({});\n validationErrors = signal<ValidationError[]>([]);\n isSaving = signal(false);\n private allEntityTypes = signal<EntityType[]>([]);\n generalErrors = computed(() => this.validationErrors().filter(e => !e.attributeName));\n\n constructor() {\n this.route.paramMap.pipe(takeUntilDestroyed()).subscribe(params => this.onParamsChange(params));\n }\n\n private async onParamsChange(params: any): Promise<void> {\n this.type.set(params.get('type') || '');\n const types = await this.sparkService.getEntityTypes();\n const entityType = types.find(t => t.id === this.type() || t.alias === this.type()) || null;\n this.entityType.set(entityType);\n this.allEntityTypes.set(types);\n this.initFormData();\n }\n\n initFormData(): void {\n const data: Record<string, any> = {};\n this.getEditableAttributes().forEach(attr => {\n if (attr.dataType === 'Reference') {\n data[attr.name] = null;\n } else if (attr.dataType === 'AsDetail') {\n data[attr.name] = attr.isArray ? [] : {};\n } else if (attr.dataType === 'boolean') {\n data[attr.name] = false;\n } else {\n data[attr.name] = '';\n }\n });\n this.formData.set(data);\n }\n\n getEditableAttributes() {\n return this.entityType()?.attributes\n .filter(a => a.isVisible && !a.isReadOnly && hasShowedOnFlag(a.showedOn, ShowedOn.PersistentObject))\n .sort((a, b) => a.order - b.order) || [];\n }\n\n async onSave(): Promise<void> {\n if (!this.entityType()) return;\n\n this.validationErrors.set([]);\n this.isSaving.set(true);\n\n const resolver: EntityTypeResolver = (clrName) => this.allEntityTypes().find(t => t.clrType === clrName);\n const attributes: PersistentObjectAttribute[] = this.getEditableAttributes().map(attr => {\n const base: PersistentObjectAttribute = {\n id: attr.id,\n name: attr.name,\n value: this.formData()[attr.name],\n dataType: attr.dataType,\n isArray: attr.isArray,\n isRequired: attr.isRequired,\n isVisible: attr.isVisible,\n isReadOnly: attr.isReadOnly,\n isValueChanged: true,\n order: attr.order,\n rules: attr.rules,\n };\n\n // AsDetail: pack the flat form dict into nested PO wire shape. Server's polymorphic\n // converter ignores attr.value for AsDetail and reads attr.object / attr.objects.\n if (attr.dataType === 'AsDetail' && attr.asDetailType) {\n const nestedType = resolver(attr.asDetailType);\n if (nestedType) {\n const raw = this.formData()[attr.name];\n base.value = null;\n base.asDetailType = attr.asDetailType;\n if (attr.isArray) {\n const items: any[] = Array.isArray(raw) ? raw : [];\n base.objects = items.map(item => dictToNestedPo((item ?? {}) as Record<string, any>, nestedType, resolver));\n base.object = null;\n } else {\n base.object = raw ? dictToNestedPo(raw as Record<string, any>, nestedType, resolver) : null;\n base.objects = null;\n }\n }\n }\n return base;\n });\n\n const po: Partial<PersistentObject> = {\n name: this.formData()['Name'] || 'New Item',\n objectTypeId: this.entityType()!.id,\n attributes\n };\n\n try {\n const result = await this.sparkService.create(this.type(), po);\n this.isSaving.set(false);\n this.saved.emit(result);\n this.router.navigate(['/po', this.type(), result.id]);\n } catch (e) {\n this.isSaving.set(false);\n const error = e as HttpErrorResponse;\n if (error.status === 400 && error.error?.errors) {\n this.validationErrors.set(error.error.errors);\n } else {\n this.validationErrors.set([{\n attributeName: '',\n errorMessage: { en: error.message || 'An unexpected error occurred' },\n ruleType: 'error'\n }]);\n }\n }\n }\n\n onCancel(): void {\n this.cancelled.emit();\n window.history.back();\n }\n}\n","<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [objectTypeId]=\"type()\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}