/** * D365FO Form Pattern Templates * * Each static method generates a complete, pattern-correct AxForm XML skeleton * validated against real AOT forms from K:\AosService\PackagesLocalDirectory. * * Reference forms used: * SimpleList → CustGroup.xml (ApplicationSuite\Foundation) * SimpleListDetails → PaymTerm.xml (ApplicationSuite\Foundation) * DetailsMaster → CustTable.xml (ApplicationSuite\Foundation) * DetailsTransaction→ SalesTable.xml (ApplicationSuite\Foundation) * Dialog → ProjTableCreate.xml (ApplicationSuite\Foundation) * TableOfContents → CustParameters.xml (ApplicationSuite\Foundation) * Lookup → SysLanguageLookup.xml (ApplicationPlatform) */ import { type FieldControlMap } from './fieldControlTypes.js'; export interface FormTemplateOptions { /** Form name (also used for classDeclaration) */ formName: string; /** Primary datasource name (usually same as table name) */ dsName?: string; /** Primary datasource table name */ dsTable?: string; /** Caption label text or label reference (@Model:Label) */ caption?: string; /** Field names to put in the grid (for SimpleList, Lookup, etc.) */ gridFields?: string[]; /** Section definitions for TableOfContents / Dialog */ sections?: Array<{ name: string; caption: string; }>; /** Lines datasource name for DetailsTransaction */ linesDsName?: string; /** Lines datasource table name for DetailsTransaction */ linesDsTable?: string; /** Field names to show in the lines grid (DetailsTransaction) */ linesFields?: string[]; /** * Field → control-type map for the primary table. When provided, field * controls render with the correct type (ComboBox for enums, Date for dates, * …) instead of defaulting every field to a string control. */ fieldTypes?: FieldControlMap; /** Field → control-type map for the lines table (DetailsTransaction). */ linesFieldTypes?: FieldControlMap; /** * The datasource table's `TitleField1` — the field a DetailsMaster header * title control must bind to. When omitted the first grid field is used, which * is only ever right by accident: grid fields arrive in ALPHABETICAL order, so * the title ends up bound to whatever field sorts first * (the 2026-07-21 eval sweep, finding #32). */ titleField?: string; /** * Field group the grid/group control binds to via ``. * * Three states on purpose. `undefined` keeps the historical default * (`Overview`), which is what shipped forms bind to and what every caller * relied on before this option existed. A STRING names a different group. * `false` omits the element entirely, and is only ever passed when the bound * table has been READ and positively found not to declare the group — * absence of evidence is not evidence of absence, so a table that cannot be * read leaves the default alone. * * A dangling `` is a build error ("Field group 'Overview' does not * exist") that an INCREMENTAL build passes silently, which is how three * captured goldens ended up carrying one. */ gridDataGroup?: string | false; } /** * Platform label ids for the captions these templates write. * * A `Caption` holding raw text is a Best Practice ERROR — xppbp reports * `BPErrorLabelIsText` ("Property Caption must have a label ID as its value, and * X is not a label ID") — and it is untranslatable, which is why the rule * exists. Every form these templates scaffolded therefore started life BP-dirty * with five findings that were not the caller's doing, and the eval loop's * `bp_clean` dimension scored 0 for a case that had done nothing wrong (#980). * * The ids are not remembered, they are verified: each is the exact text in * ApplicationPlatform's SYS.en-us.label.txt, and each is the most-used caption * of that wording across a census of shipped Foundation forms (@SYS2952 * "General" 93 uses, @SYS9039 "Overview" 52, @SYS23823 "Line details" 8, * @SYS2186 "Setup" 8, @SYS15451 "Lines" 4, @SYS101051 "Header", * @SYS15560 "Summary"). @SYS labels ship with the platform, so no model needs to * declare them. */ export declare const CAPTION_LABELS: { readonly general: '@SYS2952'; readonly overview: '@SYS9039'; readonly header: '@SYS101051'; readonly lines: '@SYS15451'; readonly lineDetails: '@SYS23823'; readonly setup: '@SYS2186'; readonly summary: '@SYS15560'; }; /** * The `` line for a grid or group control, or '' when the caller has * proven the group is not there. `indent` is the tab prefix of the sibling * elements, so the line lands in the same column. */ export declare function dataGroupLine(gridDataGroup: string | false | undefined, indent: string): string; /** * A form control that carries `` MUST also carry a sibling * ``; the field group is resolved on that datasource's table. Without * it a full build fails with `Field group 'Overview' does not exist` — and an * INCREMENTAL build passes it silently, which is why this survived several * captures (the 2026-07-21 eval sweep, finding #32 and its headline (b)). */ /** Supported top-level D365FO form patterns */ export type FormPattern = 'SimpleList' | 'SimpleListDetails' | 'DetailsMaster' | 'DetailsTransaction' | 'Dialog' | 'TableOfContents' | 'Lookup' | 'ListPage' | 'Workspace'; export declare class FormPatternTemplates { /** * Render a single field input control with the correct control type. * * `indent` is the tab string for the opening `` line; child * elements are emitted one tab deeper and the `i:type` attribute two tabs * deeper, matching the surrounding AOT layout. The control type is resolved * from `types` (enum→ComboBox, date→Date, …); unknown fields fall back to a * string control. */ static fieldControl(field: string, dsName: string, indent: string, namePrefix?: string, types?: FieldControlMap): string; static buildSimpleList(opt: FormTemplateOptions): string; static buildSimpleListDetails(opt: FormTemplateOptions): string; static buildDetailsMaster(opt: FormTemplateOptions): string; static buildDetailsTransaction(opt: FormTemplateOptions): string; static buildDialog(opt: FormTemplateOptions): string; static buildTableOfContents(opt: FormTemplateOptions): string; static buildLookup(opt: FormTemplateOptions): string; static buildListPage(opt: FormTemplateOptions): string; static buildWorkspace(opt: FormTemplateOptions): string; static build(pattern: FormPattern, opt: FormTemplateOptions): string; /** * Map common pattern name aliases to canonical FormPattern values. * Handles various casing and abbreviation styles the AI or user might use. */ static normalizePattern(raw: string): FormPattern; } //# sourceMappingURL=formPatternTemplates.d.ts.map