ngx-t-forms 2.0.29 → 2.0.31
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.
- package/fesm2022/ngx-t-forms-auto-complete-input-element.component-DCKuXHAW.mjs +104 -0
- package/fesm2022/ngx-t-forms-auto-complete-input-element.component-DCKuXHAW.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-basic-input-input-element.component-Ce4ipSUc.mjs +85 -0
- package/fesm2022/ngx-t-forms-basic-input-input-element.component-Ce4ipSUc.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-calculated-field-rules.component-C5TPddVe.mjs +643 -0
- package/fesm2022/ngx-t-forms-calculated-field-rules.component-C5TPddVe.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-chip-options-creator-editor.component-CICQaqz6.mjs +97 -0
- package/fesm2022/ngx-t-forms-chip-options-creator-editor.component-CICQaqz6.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-config-mscoa-additional-inputs.component-CzisLSIP.mjs +195 -0
- package/fesm2022/ngx-t-forms-config-mscoa-additional-inputs.component-CzisLSIP.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-data-source-picker.component-Dzz_o6fJ.mjs +261 -0
- package/fesm2022/ngx-t-forms-data-source-picker.component-Dzz_o6fJ.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-date-picker-input-element.component-CYUbVyzP.mjs +85 -0
- package/fesm2022/ngx-t-forms-date-picker-input-element.component-CYUbVyzP.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-date-range-picker-input-element.component-CmoquQGV.mjs +156 -0
- package/fesm2022/ngx-t-forms-date-range-picker-input-element.component-CmoquQGV.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-CLUOXreG.mjs +368 -0
- package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-CLUOXreG.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-document-picker.component-qObjcqhE.mjs +704 -0
- package/fesm2022/ngx-t-forms-document-picker.component-qObjcqhE.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-editor-input-element.component-BLXlfb6F.mjs +294 -0
- package/fesm2022/ngx-t-forms-editor-input-element.component-BLXlfb6F.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-editor-js-input.component-BQL0AH7H.mjs +240 -0
- package/fesm2022/ngx-t-forms-editor-js-input.component-BQL0AH7H.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-file-upload-input-element.component-C7mMeEjF.mjs +205 -0
- package/fesm2022/ngx-t-forms-file-upload-input-element.component-C7mMeEjF.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-form-input-selector.component-C9u8zq9B.mjs +86 -0
- package/fesm2022/ngx-t-forms-form-input-selector.component-C9u8zq9B.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-form-json-view.component-856Hx1Bg.mjs +22 -0
- package/fesm2022/ngx-t-forms-form-json-view.component-856Hx1Bg.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-form-payload-projection.component-CDkTuX9S.mjs +179 -0
- package/fesm2022/ngx-t-forms-form-payload-projection.component-CDkTuX9S.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-form-section-stepper.component-Bs50-nEB.mjs +319 -0
- package/fesm2022/ngx-t-forms-form-section-stepper.component-Bs50-nEB.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-forms-builder-menu.component-qrhM0jGL.mjs +379 -0
- package/fesm2022/ngx-t-forms-forms-builder-menu.component-qrhM0jGL.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-geo-location.component-Bosp1UzR.mjs +124 -0
- package/fesm2022/ngx-t-forms-geo-location.component-Bosp1UzR.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-getInputIcon-B4ADgevZ.mjs +31 -0
- package/fesm2022/ngx-t-forms-getInputIcon-B4ADgevZ.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-image-capture-input-element.component-C1g7Z0cK.mjs +180 -0
- package/fesm2022/ngx-t-forms-image-capture-input-element.component-C1g7Z0cK.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-index-dDSobs6A.mjs +2 -0
- package/fesm2022/ngx-t-forms-index-dDSobs6A.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-input-custom.component-BkbHFAyR.mjs +105 -0
- package/fesm2022/ngx-t-forms-input-custom.component-BkbHFAyR.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-input-editor.component-BPUOM9kQ.mjs +181 -0
- package/fesm2022/ngx-t-forms-input-editor.component-BPUOM9kQ.mjs.map +1 -0
- package/fesm2022/{ngx-t-forms-map-mat-options-keys-CbdW82su.mjs → ngx-t-forms-map-mat-options-keys-B6hJ7Io5.mjs} +12 -14
- package/fesm2022/ngx-t-forms-map-mat-options-keys-B6hJ7Io5.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-c7uZT1sr.mjs +66 -0
- package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-c7uZT1sr.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mat-slider-editor.component-CTSBrM-j.mjs +211 -0
- package/fesm2022/ngx-t-forms-mat-slider-editor.component-CTSBrM-j.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mat-slider-toggle-editor.component-CcYiwx-8.mjs +165 -0
- package/fesm2022/ngx-t-forms-mat-slider-toggle-editor.component-CcYiwx-8.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-missing-form-configs.component-DrnH8qdG.mjs +38 -0
- package/fesm2022/ngx-t-forms-missing-form-configs.component-DrnH8qdG.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-C_abEBQ5.mjs +38 -0
- package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-C_abEBQ5.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mscoa-error-display.component-99DpVSy7.mjs +126 -0
- package/fesm2022/ngx-t-forms-mscoa-error-display.component-99DpVSy7.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mscoa-segment-config.component-C0qsMfsq.mjs +336 -0
- package/fesm2022/ngx-t-forms-mscoa-segment-config.component-C0qsMfsq.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-B1Z-IXSL.mjs +74 -0
- package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-B1Z-IXSL.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-multiple-input-input-element.component-C7y1OGPx.mjs +905 -0
- package/fesm2022/ngx-t-forms-multiple-input-input-element.component-C7y1OGPx.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-ngx-t-forms-u_kigDid.mjs +19461 -0
- package/fesm2022/ngx-t-forms-ngx-t-forms-u_kigDid.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-paginated-selection-table-AQZSMmhr.mjs +555 -0
- package/fesm2022/ngx-t-forms-paginated-selection-table-AQZSMmhr.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-pipeline-generator.component-DmNSc5aw.mjs +748 -0
- package/fesm2022/ngx-t-forms-pipeline-generator.component-DmNSc5aw.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-record-list-manager.component-CUMMvMch.mjs +358 -0
- package/fesm2022/ngx-t-forms-record-list-manager.component-CUMMvMch.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-required-inputs.component-Ch2yNcIS.mjs +272 -0
- package/fesm2022/ngx-t-forms-required-inputs.component-Ch2yNcIS.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-rest-api-call-setup.component-C_aFtdvW.mjs +398 -0
- package/fesm2022/ngx-t-forms-rest-api-call-setup.component-C_aFtdvW.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-search-field.component-B2ZO7lqO.mjs +38 -0
- package/fesm2022/ngx-t-forms-search-field.component-B2ZO7lqO.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-section-report.component-BxOhR6C0.mjs +98 -0
- package/fesm2022/ngx-t-forms-section-report.component-BxOhR6C0.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-select-input-element.component-DbgZdNoe.mjs +150 -0
- package/fesm2022/ngx-t-forms-select-input-element.component-DbgZdNoe.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-selection-options-editor.component-Dhln81DL.mjs +169 -0
- package/fesm2022/ngx-t-forms-selection-options-editor.component-Dhln81DL.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-t-workflow-picker.component-leBokXvM.mjs +204 -0
- package/fesm2022/ngx-t-forms-t-workflow-picker.component-leBokXvM.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-textarea-input-element.component-BEbXJjFA.mjs +95 -0
- package/fesm2022/ngx-t-forms-textarea-input-element.component-BEbXJjFA.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-toggle-input-element.component-DDErRUJd.mjs +82 -0
- package/fesm2022/ngx-t-forms-toggle-input-element.component-DDErRUJd.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-validators-config.component-oGjQVGE2.mjs +733 -0
- package/fesm2022/ngx-t-forms-validators-config.component-oGjQVGE2.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-workflow-adjudication.component-CtU8dECN.mjs +1303 -0
- package/fesm2022/ngx-t-forms-workflow-adjudication.component-CtU8dECN.mjs.map +1 -0
- package/fesm2022/ngx-t-forms.mjs +2 -1
- package/fesm2022/ngx-t-forms.mjs.map +1 -1
- package/package.json +20 -18
- package/styles/_editor-mixins.scss +62 -0
- package/styles/_json-editor-syntax.scss +26 -0
- package/styles/_signature-pad.scss +26 -0
- package/styles/_tokens.scss +148 -0
- package/types/ngx-t-forms.d.ts +1767 -621
- package/fesm2022/ngx-t-forms-calculated-field-rules.component-D-SBMdYg.mjs +0 -313
- package/fesm2022/ngx-t-forms-calculated-field-rules.component-D-SBMdYg.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-chip-options-creator-editor.component-1cpszpPN.mjs +0 -191
- package/fesm2022/ngx-t-forms-chip-options-creator-editor.component-1cpszpPN.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-config-mscoa-additional-inputs.component-DFdAVWTg.mjs +0 -207
- package/fesm2022/ngx-t-forms-config-mscoa-additional-inputs.component-DFdAVWTg.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-data-source-picker.component-DxORinAD.mjs +0 -204
- package/fesm2022/ngx-t-forms-data-source-picker.component-DxORinAD.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-DcWS1txl.mjs +0 -289
- package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-DcWS1txl.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-form-input-selector.component-B2QEnvkq.mjs +0 -134
- package/fesm2022/ngx-t-forms-form-input-selector.component-B2QEnvkq.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-form-json-view.component-DePf44w6.mjs +0 -22
- package/fesm2022/ngx-t-forms-form-json-view.component-DePf44w6.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-form-section-stepper.component-BTkcSjg7.mjs +0 -270
- package/fesm2022/ngx-t-forms-form-section-stepper.component-BTkcSjg7.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-forms-builder-menu.component-Wamzf_sq.mjs +0 -345
- package/fesm2022/ngx-t-forms-forms-builder-menu.component-Wamzf_sq.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-input-editor.component-D4xHO76K.mjs +0 -147
- package/fesm2022/ngx-t-forms-input-editor.component-D4xHO76K.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-map-mat-options-keys-CbdW82su.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-DmTyO9Wi.mjs +0 -105
- package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-DmTyO9Wi.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mat-slider-editor.component-DZ4TenrI.mjs +0 -109
- package/fesm2022/ngx-t-forms-mat-slider-editor.component-DZ4TenrI.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mat-slider-toggle-editor.component-DPyBYE4p.mjs +0 -155
- package/fesm2022/ngx-t-forms-mat-slider-toggle-editor.component-DPyBYE4p.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-missing-form-configs.component-BRmnwAK6.mjs +0 -28
- package/fesm2022/ngx-t-forms-missing-form-configs.component-BRmnwAK6.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-D_umeAPL.mjs +0 -43
- package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-D_umeAPL.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mscoa-error-display.component-CSX2NCNU.mjs +0 -116
- package/fesm2022/ngx-t-forms-mscoa-error-display.component-CSX2NCNU.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mscoa-segment-config.component-B6IF8kGg.mjs +0 -296
- package/fesm2022/ngx-t-forms-mscoa-segment-config.component-B6IF8kGg.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-BPkjsRmH.mjs +0 -83
- package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-BPkjsRmH.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-ngx-t-forms-D9qmig6g.mjs +0 -16844
- package/fesm2022/ngx-t-forms-ngx-t-forms-D9qmig6g.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-pipeline-generator.component-DBJEyCbd.mjs +0 -613
- package/fesm2022/ngx-t-forms-pipeline-generator.component-DBJEyCbd.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-record-list-manager.component-Dgs9lNSr.mjs +0 -269
- package/fesm2022/ngx-t-forms-record-list-manager.component-Dgs9lNSr.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-required-inputs.component-CSIJvSHq.mjs +0 -190
- package/fesm2022/ngx-t-forms-required-inputs.component-CSIJvSHq.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-rest-api-call-setup.component-CY-JSkGs.mjs +0 -291
- package/fesm2022/ngx-t-forms-rest-api-call-setup.component-CY-JSkGs.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-section-report.component-12-KdKT6.mjs +0 -156
- package/fesm2022/ngx-t-forms-section-report.component-12-KdKT6.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-selection-options-editor.component-Be3QAG_L.mjs +0 -186
- package/fesm2022/ngx-t-forms-selection-options-editor.component-Be3QAG_L.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-t-workflow-picker.component-a4f1r8gH.mjs +0 -187
- package/fesm2022/ngx-t-forms-t-workflow-picker.component-a4f1r8gH.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-validators-config.component-B3j9Dmgu.mjs +0 -215
- package/fesm2022/ngx-t-forms-validators-config.component-B3j9Dmgu.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngx-t-forms-record-list-manager.component-CUMMvMch.mjs","sources":["../../../projects/ngx-t-forms/src/lib/components/t-dynamic-data-edit/elements/record-list-manager/record-list-manager.component.ts","../../../projects/ngx-t-forms/src/lib/components/t-dynamic-data-edit/elements/record-list-manager/record-list-manager.component.html"],"sourcesContent":["import { CdkPortalOutletAttachedRef, ComponentPortal, PortalModule } from '@angular/cdk/portal';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport {\n ChangeDetectionStrategy,\n Component,\n ComponentRef,\n DestroyRef,\n ElementRef,\n Input,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { outputToObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NgControl } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCardModule } from '@angular/material/card';\nimport { MatDividerModule } from '@angular/material/divider';\nimport { MatExpansionModule } from '@angular/material/expansion';\nimport { MatFormFieldControl } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { MatTableDataSource, MatTableModule } from '@angular/material/table';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport type {\n ElementEditorConfigSectionInterface,\n ElementEditorInnerSectionElementInterface,\n FormColumnInputs,\n} from 'ngx-t-forms-types';\nimport { Subject, Subscription } from 'rxjs';\nimport { _isEqual } from '../../../../shared/functions/isEqual';\nimport { assignDeepPropertyToObject } from '../../../../shared/functions/assignDeepPropertyToObject';\nimport { safeReturnDeepProperty } from '../../../../shared/functions/getDeepObject';\nimport { EmptyStateComponent } from '../_shared/empty-state/empty-state.component';\nimport type { IConfigElementError } from '../../t-dynamic-data-edit.component';\nimport type { TDynamicDataEditComponent } from '../../t-dynamic-data-edit.component';\nimport { NESTED_EDITOR_COMPONENT } from '../../nested-editor.token';\n\n/** Row shape held by the record list. Heterogeneous wrapper-defined records. */\ntype RecordListRow = Record<string, unknown> & { id?: string };\n\n/** Table column descriptor (label header + the row key it renders). */\ninterface RecordColumn {\n readonly label: string;\n readonly value: string;\n}\n\n/** Synthetic column key for the per-row edit/delete action cell. */\nconst ACTIONS_COLUMN = 'actions';\n\n/**\n * Internal record-list manager. Implements `MatFormFieldControl<unknown[]>` and is\n * embedded by `t-dynamic-data-edit` for `RecordListManager` editor types.\n *\n * Owns only its content (table + edit panel). The parent `mat-form-field` renders\n * the label, hint, and validation errors, so this component adds neither a header\n * nor an inline error list.\n *\n * Per-record editing is delegated to a dynamically-attached `TDynamicDataEditComponent`\n * portal per inner-section element; the portal's `valueChange` output is patched back\n * into the in-edit buffer via the element's `deepBind` path.\n *\n * NOTE: `MatFormFieldControl<T>` mandates plain mutable `value` / `disabled` /\n * `required` / `placeholder` / `id` members, `@Input()` decorators, the\n * `focused` / `touched` / `stateChanges` members, and the `useExisting` provider.\n * These are framework wiring, not defects — the CLAUDE.md bans on `@Input()` /\n * `useExisting` do not apply to MatFormFieldControl integration.\n *\n * @internal Not exported via public-api.ts.\n */\n@Component({\n selector: 'lib-record-list-manager',\n templateUrl: './record-list-manager.component.html',\n styleUrl: './record-list-manager.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n imports: [\n MatButtonModule,\n MatCardModule,\n MatDividerModule,\n MatExpansionModule,\n MatIconModule,\n MatProgressSpinnerModule,\n MatTableModule,\n MatTooltipModule,\n PortalModule,\n EmptyStateComponent,\n ],\n providers: [{ provide: MatFormFieldControl, useExisting: RecordListManagerComponent }],\n host: {\n 'class': 'lib-record-list-manager',\n '[id]': 'id',\n '[attr.aria-describedby]': 'describedBy',\n '[class.lib-record-list-manager--floating]': 'shouldLabelFloat',\n },\n})\nexport class RecordListManagerComponent implements MatFormFieldControl<unknown[]> {\n static nextId = 0;\n\n // --- MatFormFieldControl wiring (plain mutable members, framework-mandated) ---\n readonly stateChanges = new Subject<void>();\n readonly controlType = 'lib-record-list-manager';\n\n focused = false;\n touched = false;\n autofilled = false;\n id = `lib-record-list-manager-${RecordListManagerComponent.nextId++}`;\n describedBy = '';\n\n /** Optional wrapper-supplied mapping payload (shape determined by wrapper). */\n @Input() mapToData: unknown;\n\n /** Validation errors surfaced by the parent for error-state derivation. */\n @Input() errors: IConfigElementError[] | undefined = [];\n\n #disabled = false;\n @Input()\n get disabled(): boolean {\n return this.#disabled;\n }\n set disabled(value: boolean) {\n this.#disabled = coerceBooleanProperty(value);\n this.stateChanges.next();\n }\n\n #required = false;\n @Input()\n get required(): boolean {\n return this.#required;\n }\n set required(value: boolean) {\n this.#required = coerceBooleanProperty(value);\n this.stateChanges.next();\n }\n\n #placeholder = '';\n @Input()\n get placeholder(): string {\n return this.#placeholder;\n }\n set placeholder(value: string) {\n this.#placeholder = value;\n this.stateChanges.next();\n }\n\n /**\n * Record rows held by the table. Parent passes heterogeneous payloads\n * (`{}` initial / arrays / null); non-array writes coerce to an empty list.\n */\n @Input()\n get value(): RecordListRow[] {\n return this.#rows();\n }\n set value(val: unknown) {\n const next = Array.isArray(val) ? (val as RecordListRow[]) : [];\n this.#rows.set(next);\n this.onChange(next);\n this.stateChanges.next();\n }\n\n get shouldLabelFloat(): boolean {\n return this.focused || !this.empty;\n }\n\n get empty(): boolean {\n return this.#rows().length === 0;\n }\n\n get errorState(): boolean {\n const requiredUnset = this.empty && this.#required && this.touched;\n const ngControlError = this.ngControl?.errors != null;\n const externalError = (this.errors?.length ?? 0) > 0;\n return requiredUnset || ngControlError || externalError;\n }\n\n // --- DI ---\n readonly ngControl = inject(NgControl, { self: true, optional: true });\n readonly #elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n readonly #destroyRef = inject(DestroyRef);\n /** The component portalled per record — injected to avoid a circular import. */\n readonly #nestedEditor = inject(NESTED_EDITOR_COMPONENT);\n\n constructor() {\n if (this.ngControl != null) {\n this.ngControl.valueAccessor = this;\n }\n this.#destroyRef.onDestroy(() => {\n this.stateChanges.complete();\n this.#teardownPortalSubscriptions();\n });\n }\n\n // --- ControlValueAccessor ---\n onChange: (_: unknown) => void = () => {\n /* noop until registered */\n };\n onTouched: () => void = () => {\n /* noop until registered */\n };\n\n writeValue(value: unknown): void {\n this.#rows.set(Array.isArray(value) ? (value as RecordListRow[]) : []);\n this.stateChanges.next();\n }\n\n registerOnChange(fn: (_: unknown) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n\n setDescribedByIds(ids: string[]): void {\n this.describedBy = ids.join(' ');\n this.#elementRef.nativeElement.setAttribute('aria-describedby', this.describedBy);\n this.stateChanges.next();\n }\n\n onContainerClick(): void {\n this.markAsTouched();\n if (!this.focused) {\n this.focused = true;\n this.stateChanges.next();\n }\n }\n\n markAsTouched(): void {\n if (!this.touched) {\n this.touched = true;\n this.onTouched();\n this.stateChanges.next();\n }\n }\n\n // --- Internal reactive state (signal-first) ---\n\n /** Backing rows; the `MatTableDataSource` is kept in sync via an effect. */\n readonly #rows = signal<RecordListRow[]>([]);\n\n /** Table data source whose `.data` mirrors `#rows()`. */\n readonly dataSource = new MatTableDataSource<RecordListRow>([]);\n\n /** Row currently being edited, or `null` when no edit is in progress. */\n readonly #inEdit = signal<RecordListRow | null>(null);\n\n /** Inner editor sections derived from the active editor config. */\n readonly #sections = signal<readonly ElementEditorConfigSectionInterface[]>([]);\n\n /** Lazily-built portals keyed by inner-section element id. */\n readonly #portals = signal<Readonly<Record<string, ComponentPortal<TDynamicDataEditComponent>>>>(\n {},\n );\n\n /** Active per-element portal output subscriptions, keyed by element id. */\n readonly #portalSubscriptions = new Map<string, Subscription>();\n\n /** Form input definitions forwarded into the dynamic editor portals. */\n readonly formInputs = input<Array<FormColumnInputs>>([]);\n\n /** Editor configuration for this record-list element. */\n readonly editorConfig = input<ElementEditorInnerSectionElementInterface | undefined>(undefined);\n\n /** Emits whenever the record list value changes. */\n readonly valueChange = output<RecordListRow[]>();\n\n // --- Template-facing derived state ---\n\n protected readonly inEditRow = this.#inEdit.asReadonly();\n protected readonly sections = this.#sections.asReadonly();\n protected readonly portals = this.#portals.asReadonly();\n\n protected readonly tableColumns = computed<readonly RecordColumn[]>(() => [\n ...(this.editorConfig()?.options ?? []).map((opt) => ({\n label: String(opt.label),\n value: String(opt.value),\n })),\n { label: ' ', value: ACTIONS_COLUMN },\n ]);\n\n protected readonly displayedColumns = computed<readonly string[]>(() =>\n this.tableColumns().map((c) => c.value),\n );\n\n protected readonly rowCount = computed<number>(() => this.#rows().length);\n\n protected readonly isActionsColumn = (column: string): boolean => column === ACTIONS_COLUMN;\n\n /**\n * Whether the in-edit record may be saved: every `required` inner element must\n * resolve to a non-empty value via its `deepBind` path.\n */\n protected readonly canSaveRecord = computed<boolean>(() => {\n const editing = this.#inEdit();\n if (!editing || !this.editorConfig()) {\n return false;\n }\n for (const section of this.#sections()) {\n for (const element of section.elements) {\n if (!element.required) {\n continue;\n }\n const { value } = safeReturnDeepProperty(editing, element.deepBind ?? []);\n if (value == null || value === '') {\n return false;\n }\n }\n }\n return true;\n });\n\n // --- Effects (framework-state sync, not signal writes within) ---\n\n /** Mirror the rows signal into the Material table data source. */\n protected readonly tableSync = effect(() => {\n this.dataSource.data = this.#rows();\n });\n\n /**\n * Rebuild the inner-section list and portal map whenever the editor config\n * changes. Portals are recreated per config so a stale `ComponentPortal`\n * (already attached) is never re-used.\n */\n protected readonly configSync = effect(() => {\n const next = this.editorConfig()?.secondaryElementEditorConfig ?? [];\n if (_isEqual(this.#sections(), next)) {\n return;\n }\n this.#teardownPortalSubscriptions();\n this.#sections.set(next);\n const portals: Record<string, ComponentPortal<TDynamicDataEditComponent>> = {};\n for (const section of next) {\n for (const element of section.elements) {\n portals[element.id] = new ComponentPortal(this.#nestedEditor);\n }\n }\n this.#portals.set(portals);\n });\n\n // --- Record actions ---\n\n addNewItem(): void {\n this.#inEdit.set({});\n }\n\n editItem(row: RecordListRow): void {\n this.#inEdit.set(row);\n }\n\n cancelEdit(): void {\n this.#inEdit.set(null);\n }\n\n saveRecord(): void {\n const editing = this.#inEdit();\n if (!editing) {\n return;\n }\n let next: RecordListRow[];\n if (editing.id != null) {\n next = this.value.map((item) => (item.id === editing.id ? editing : item));\n } else {\n next = [...this.value, { ...editing, id: crypto.randomUUID() }];\n }\n this.value = next;\n this.#inEdit.set(null);\n this.valueChange.emit(this.value);\n }\n\n removeItem(item: RecordListRow): void {\n this.value = this.value.filter((row) => row.id !== item.id);\n if (this.#inEdit()?.id === item.id) {\n this.#inEdit.set(null);\n }\n this.valueChange.emit(this.value);\n }\n\n /**\n * Wire a freshly-attached per-record editor portal: push the current inputs in,\n * and patch the in-edit buffer whenever the inner editor emits a value. The\n * subscription is keyed by element id and torn down on config change / destroy.\n */\n onPortalAttached(\n portalRef: CdkPortalOutletAttachedRef,\n element: ElementEditorInnerSectionElementInterface,\n ): void {\n const componentRef = portalRef as ComponentRef<TDynamicDataEditComponent>;\n componentRef.setInput('formInputs', this.formInputs());\n componentRef.setInput('editorConfig', element);\n componentRef.setInput('data', this.#inEdit());\n\n this.#portalSubscriptions.get(element.id)?.unsubscribe();\n const sub = outputToObservable(componentRef.instance.valueChange)\n .pipe(takeUntilDestroyed(this.#destroyRef))\n .subscribe((event: unknown) => {\n const current = this.#inEdit();\n const draft = (current ? structuredClone(current) : {}) as RecordListRow;\n const patched = assignDeepPropertyToObject(\n draft,\n element.deepBind ?? [],\n event,\n ) as RecordListRow;\n this.#inEdit.set(patched);\n componentRef.setInput('data', patched);\n componentRef.changeDetectorRef.markForCheck();\n });\n this.#portalSubscriptions.set(element.id, sub);\n }\n\n #teardownPortalSubscriptions(): void {\n this.#portalSubscriptions.forEach((sub) => sub.unsubscribe());\n this.#portalSubscriptions.clear();\n }\n}\n","<div class=\"lib-record-list-manager__table\">\n <table mat-table [dataSource]=\"dataSource\" class=\"lib-record-list-manager__grid\">\n @for (col of tableColumns(); track col.value) {\n <ng-container [matColumnDef]=\"col.value\">\n <th mat-header-cell *matHeaderCellDef>{{ col.label }}</th>\n <td mat-cell *matCellDef=\"let row\" class=\"lib-record-list-manager__cell\">\n @if (isActionsColumn(col.value)) {\n <button\n type=\"button\"\n mat-icon-button\n matTooltip=\"Edit\"\n aria-label=\"Edit record\"\n [disabled]=\"disabled\"\n (click)=\"editItem(row)\"\n >\n <mat-icon>edit</mat-icon>\n </button>\n <button\n type=\"button\"\n mat-icon-button\n color=\"warn\"\n matTooltip=\"Delete\"\n aria-label=\"Delete record\"\n [disabled]=\"disabled\"\n (click)=\"removeItem(row)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n } @else {\n {{ row[col.value] }}\n }\n </td>\n </ng-container>\n }\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns()\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns()\"\n class=\"lib-record-list-manager__row\"\n ></tr>\n </table>\n\n @if (rowCount() === 0) {\n <lib-empty-state\n icon=\"inbox\"\n message=\"No records yet. Use Add Record to get started.\"\n ></lib-empty-state>\n }\n</div>\n\n@if (inEditRow(); as editing) {\n <div class=\"lib-record-list-manager__editor\">\n <mat-accordion class=\"lib-record-list-manager__sections\" togglePosition=\"after\">\n @for (section of sections(); track section.id) {\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title class=\"lib-record-list-manager__section-title\">\n <span>{{ section.label }}</span>\n @if (section.showItemValue && editing[section.showItemValue] != null) {\n <span class=\"lib-record-list-manager__section-value\">\n {{ editing[section.showItemValue] }}\n </span>\n }\n </mat-panel-title>\n </mat-expansion-panel-header>\n\n @for (element of section.elements; track element.id) {\n <div class=\"lib-record-list-manager__field\">\n @defer (on viewport) {\n <ng-template\n [cdkPortalOutlet]=\"portals()[element.id]\"\n (attached)=\"onPortalAttached($event, element)\"\n ></ng-template>\n } @placeholder {\n <div class=\"lib-record-list-manager__loading\">\n <mat-spinner diameter=\"18\"></mat-spinner>\n </div>\n }\n </div>\n }\n </mat-expansion-panel>\n }\n </mat-accordion>\n\n <div class=\"lib-record-list-manager__actions\">\n <button type=\"button\" mat-button color=\"primary\" (click)=\"cancelEdit()\">Cancel</button>\n <button\n type=\"button\"\n mat-stroked-button\n color=\"primary\"\n [disabled]=\"!canSaveRecord()\"\n (click)=\"saveRecord()\"\n >\n {{ editing.id ? 'Update' : 'Save new' }} record\n <mat-icon>save</mat-icon>\n </button>\n </div>\n </div>\n} @else {\n <div class=\"lib-record-list-manager__actions lib-record-list-manager__actions--list\">\n <span class=\"lib-record-list-manager__count\">Records ({{ rowCount() }})</span>\n <button\n type=\"button\"\n mat-stroked-button\n color=\"primary\"\n matTooltip=\"Add a new record\"\n aria-label=\"Add a new record\"\n [disabled]=\"disabled\"\n (click)=\"addNewItem()\"\n >\n <mat-icon>add</mat-icon>\n Add Record\n </button>\n </div>\n}\n"],"names":["i4","i5","i6","i7"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAmDA;AACA,MAAM,cAAc,GAAG,SAAS;AAEhC;;;;;;;;;;;;;;;;;;;AAmBG;MA2BU,0BAA0B,CAAA;aAC9B,IAAA,CAAA,MAAM,GAAG,CAAH,CAAK;AAkBlB,IAAA,SAAS;AACT,IAAA,IACI,QAAQ,GAAA;QACV,OAAO,IAAI,CAAC,SAAS;IACvB;IACA,IAAI,QAAQ,CAAC,KAAc,EAAA;AACzB,QAAA,IAAI,CAAC,SAAS,GAAG,qBAAqB,CAAC,KAAK,CAAC;AAC7C,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;IAC1B;AAEA,IAAA,SAAS;AACT,IAAA,IACI,QAAQ,GAAA;QACV,OAAO,IAAI,CAAC,SAAS;IACvB;IACA,IAAI,QAAQ,CAAC,KAAc,EAAA;AACzB,QAAA,IAAI,CAAC,SAAS,GAAG,qBAAqB,CAAC,KAAK,CAAC;AAC7C,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;IAC1B;AAEA,IAAA,YAAY;AACZ,IAAA,IACI,WAAW,GAAA;QACb,OAAO,IAAI,CAAC,YAAY;IAC1B;IACA,IAAI,WAAW,CAAC,KAAa,EAAA;AAC3B,QAAA,IAAI,CAAC,YAAY,GAAG,KAAK;AACzB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;IAC1B;AAEA;;;AAGG;AACH,IAAA,IACI,KAAK,GAAA;AACP,QAAA,OAAO,IAAI,CAAC,KAAK,EAAE;IACrB;IACA,IAAI,KAAK,CAAC,GAAY,EAAA;AACpB,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAI,GAAuB,GAAG,EAAE;AAC/D,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;AACpB,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;AACnB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;IAC1B;AAEA,IAAA,IAAI,gBAAgB,GAAA;QAClB,OAAO,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK;IACpC;AAEA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,KAAK,CAAC;IAClC;AAEA,IAAA,IAAI,UAAU,GAAA;AACZ,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO;QAClE,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,IAAI,IAAI;AACrD,QAAA,MAAM,aAAa,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC;AACpD,QAAA,OAAO,aAAa,IAAI,cAAc,IAAI,aAAa;IACzD;AAIS,IAAA,WAAW;AACX,IAAA,WAAW;;AAEX,IAAA,aAAa;AAEtB,IAAA,WAAA,GAAA;;AAlFS,QAAA,IAAA,CAAA,YAAY,GAAG,IAAI,OAAO,EAAQ;QAClC,IAAA,CAAA,WAAW,GAAG,yBAAyB;QAEhD,IAAA,CAAA,OAAO,GAAG,KAAK;QACf,IAAA,CAAA,OAAO,GAAG,KAAK;QACf,IAAA,CAAA,UAAU,GAAG,KAAK;AAClB,QAAA,IAAA,CAAA,EAAE,GAAG,CAAA,wBAAA,EAA2B,0BAA0B,CAAC,MAAM,EAAE,EAAE;QACrE,IAAA,CAAA,WAAW,GAAG,EAAE;;QAMP,IAAA,CAAA,MAAM,GAAsC,EAAE;QAEvD,IAAA,CAAA,SAAS,GAAG,KAAK;QAUjB,IAAA,CAAA,SAAS,GAAG,KAAK;QAUjB,IAAA,CAAA,YAAY,GAAG,EAAE;;AAyCR,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC7D,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAA0B,UAAU,CAAC;AACzD,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;;AAEhC,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAC,uBAAuB,CAAC;;QAaxD,IAAA,CAAA,QAAQ,GAAyB,MAAK;;AAEtC,QAAA,CAAC;QACD,IAAA,CAAA,SAAS,GAAe,MAAK;;AAE7B,QAAA,CAAC;;;AA4CQ,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAkB,EAAE,4EAAC;;AAGnC,QAAA,IAAA,CAAA,UAAU,GAAG,IAAI,kBAAkB,CAAgB,EAAE,CAAC;;AAGtD,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAuB,IAAI,8EAAC;;AAG5C,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAiD,EAAE,gFAAC;;AAGtE,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CACxB,EAAE,+EACH;;AAGQ,QAAA,IAAA,CAAA,oBAAoB,GAAG,IAAI,GAAG,EAAwB;;AAGtD,QAAA,IAAA,CAAA,UAAU,GAAG,KAAK,CAA0B,EAAE,iFAAC;;AAG/C,QAAA,IAAA,CAAA,YAAY,GAAG,KAAK,CAAwD,SAAS,mFAAC;;QAGtF,IAAA,CAAA,WAAW,GAAG,MAAM,EAAmB;;AAI7B,QAAA,IAAA,CAAA,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;AACrC,QAAA,IAAA,CAAA,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;AACtC,QAAA,IAAA,CAAA,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE;AAEpC,QAAA,IAAA,CAAA,YAAY,GAAG,QAAQ,CAA0B,MAAM;AACxE,YAAA,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,MAAM;AACpD,gBAAA,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACxB,gBAAA,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AACzB,aAAA,CAAC,CAAC;AACH,YAAA,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE;AACtC,SAAA,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,cAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;QAEiB,IAAA,CAAA,gBAAgB,GAAG,QAAQ,CAAoB,MAChE,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,kBAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CACxC;AAEkB,QAAA,IAAA,CAAA,QAAQ,GAAG,QAAQ,CAAS,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,+EAAC;QAEtD,IAAA,CAAA,eAAe,GAAG,CAAC,MAAc,KAAc,MAAM,KAAK,cAAc;AAE3F;;;AAGG;AACgB,QAAA,IAAA,CAAA,aAAa,GAAG,QAAQ,CAAU,MAAK;AACxD,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE;YAC9B,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE;AACpC,gBAAA,OAAO,KAAK;YACd;YACA,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE;AACtC,gBAAA,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE;AACtC,oBAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;wBACrB;oBACF;AACA,oBAAA,MAAM,EAAE,KAAK,EAAE,GAAG,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;oBACzE,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,EAAE,EAAE;AACjC,wBAAA,OAAO,KAAK;oBACd;gBACF;YACF;AACA,YAAA,OAAO,IAAI;AACb,QAAA,CAAC,oFAAC;;;AAKiB,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,MAAK;YACzC,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE;AACrC,QAAA,CAAC,gFAAC;AAEF;;;;AAIG;AACgB,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,MAAK;YAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,4BAA4B,IAAI,EAAE;YACpE,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,EAAE;gBACpC;YACF;YACA,IAAI,CAAC,4BAA4B,EAAE;AACnC,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YACxB,MAAM,OAAO,GAA+D,EAAE;AAC9E,YAAA,KAAK,MAAM,OAAO,IAAI,IAAI,EAAE;AAC1B,gBAAA,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE;AACtC,oBAAA,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC;gBAC/D;YACF;AACA,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;AAC5B,QAAA,CAAC,iFAAC;AA9JA,QAAA,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,EAAE;AAC1B,YAAA,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,IAAI;QACrC;AACA,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,MAAK;AAC9B,YAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;YAC5B,IAAI,CAAC,4BAA4B,EAAE;AACrC,QAAA,CAAC,CAAC;IACJ;AAUA,IAAA,UAAU,CAAC,KAAc,EAAA;QACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAI,KAAyB,GAAG,EAAE,CAAC;AACtE,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;IAC1B;AAEA,IAAA,gBAAgB,CAAC,EAAwB,EAAA;AACvC,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAE;IACpB;AAEA,IAAA,iBAAiB,CAAC,EAAc,EAAA;AAC9B,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;IACrB;AAEA,IAAA,gBAAgB,CAAC,UAAmB,EAAA;AAClC,QAAA,IAAI,CAAC,QAAQ,GAAG,UAAU;IAC5B;AAEA,IAAA,iBAAiB,CAAC,GAAa,EAAA;QAC7B,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AAChC,QAAA,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,YAAY,CAAC,kBAAkB,EAAE,IAAI,CAAC,WAAW,CAAC;AACjF,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;IAC1B;IAEA,gBAAgB,GAAA;QACd,IAAI,CAAC,aAAa,EAAE;AACpB,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACjB,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;QAC1B;IACF;IAEA,aAAa,GAAA;AACX,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACjB,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI;YACnB,IAAI,CAAC,SAAS,EAAE;AAChB,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;QAC1B;IACF;;;AAKS,IAAA,KAAK;;AAML,IAAA,OAAO;;AAGP,IAAA,SAAS;;AAGT,IAAA,QAAQ;;AAKR,IAAA,oBAAoB;;IAsF7B,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;IACtB;AAEA,IAAA,QAAQ,CAAC,GAAkB,EAAA;AACzB,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;IACvB;IAEA,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IACxB;IAEA,UAAU,GAAA;AACR,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE;QAC9B,IAAI,CAAC,OAAO,EAAE;YACZ;QACF;AACA,QAAA,IAAI,IAAqB;AACzB,QAAA,IAAI,OAAO,CAAC,EAAE,IAAI,IAAI,EAAE;AACtB,YAAA,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;QAC5E;aAAO;AACL,YAAA,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;QACjE;AACA,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI;AACjB,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IACnC;AAEA,IAAA,UAAU,CAAC,IAAmB,EAAA;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC3D,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE;AAClC,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;QACxB;QACA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IACnC;AAEA;;;;AAIG;IACH,gBAAgB,CACd,SAAqC,EACrC,OAAkD,EAAA;QAElD,MAAM,YAAY,GAAG,SAAoD;QACzE,YAAY,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;AACtD,QAAA,YAAY,CAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;QAC9C,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;AAE7C,QAAA,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE;QACxD,MAAM,GAAG,GAAG,kBAAkB,CAAC,YAAY,CAAC,QAAQ,CAAC,WAAW;AAC7D,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC;AACzC,aAAA,SAAS,CAAC,CAAC,KAAc,KAAI;AAC5B,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE;AAC9B,YAAA,MAAM,KAAK,IAAI,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAkB;AACxE,YAAA,MAAM,OAAO,GAAG,0BAA0B,CACxC,KAAK,EACL,OAAO,CAAC,QAAQ,IAAI,EAAE,EACtB,KAAK,CACW;AAClB,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AACzB,YAAA,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;AACtC,YAAA,YAAY,CAAC,iBAAiB,CAAC,YAAY,EAAE;AAC/C,QAAA,CAAC,CAAC;QACJ,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC;IAChD;IAEA,4BAA4B,GAAA;AAC1B,QAAA,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC;AAC7D,QAAA,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE;IACnC;+GAhUW,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAA1B,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,0BAA0B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,yBAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,IAAA,EAAA,uBAAA,EAAA,aAAA,EAAA,yCAAA,EAAA,kBAAA,EAAA,EAAA,cAAA,EAAA,yBAAA,EAAA,EAAA,SAAA,EAR1B,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC5FxF,s7HAmHA,EAAA,MAAA,EAAA,CAAA,y+CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDlCI,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,iOAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,sFAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACf,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACb,gBAAgB,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAChB,kBAAkB,unBAClB,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACb,wBAAwB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,mCAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,aAAA,CAAA,EAAA,QAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACxB,cAAc,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,QAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,QAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,gBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,uBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,YAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,UAAA,EAAA,QAAA,EAAA,cAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,SAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,EAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,aAAA,EAAA,QAAA,EAAA,sCAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,OAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,YAAA,EAAA,QAAA,EAAA,oCAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,MAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACd,gBAAgB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,UAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAChB,YAAY,+BACZ,mBAAmB,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,SAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,sBAAA,EAAA,CAAA,MAAA,CAAAC,EAAA,CAAA,eAAA,CAAA,CAAA,EAAA,CAAA,CAAA;;4FAUV,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBA1BtC,SAAS;+BACE,yBAAyB,EAAA,eAAA,EAGlB,uBAAuB,CAAC,MAAM,iBAChC,iBAAiB,CAAC,QAAQ,EAAA,OAAA,EAChC;wBACP,eAAe;wBACf,aAAa;wBACb,gBAAgB;wBAChB,kBAAkB;wBAClB,aAAa;wBACb,wBAAwB;wBACxB,cAAc;wBACd,gBAAgB;wBAChB,YAAY;wBACZ,mBAAmB;qBACpB,EAAA,SAAA,EACU,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAA,0BAA4B,EAAE,CAAC,EAAA,IAAA,EAChF;AACJ,wBAAA,OAAO,EAAE,yBAAyB;AAClC,wBAAA,MAAM,EAAE,IAAI;AACZ,wBAAA,yBAAyB,EAAE,aAAa;AACxC,wBAAA,2CAA2C,EAAE,kBAAkB;AAChE,qBAAA,EAAA,QAAA,EAAA,s7HAAA,EAAA,MAAA,EAAA,CAAA,y+CAAA,CAAA,EAAA;;sBAgBA;;sBAGA;;sBAGA;;sBAUA;;sBAUA;;sBAaA;;;;;"}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, linkedSignal, signal, computed, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import * as i1$1 from '@angular/material/button';
|
|
4
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
5
|
+
import * as i2 from '@angular/material/form-field';
|
|
6
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
7
|
+
import * as i3 from '@angular/material/icon';
|
|
8
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
9
|
+
import * as i2$1 from '@angular/material/input';
|
|
10
|
+
import { MatInputModule } from '@angular/material/input';
|
|
11
|
+
import * as i4 from '@angular/material/list';
|
|
12
|
+
import { MatListModule } from '@angular/material/list';
|
|
13
|
+
import * as i7 from '@angular/material/core';
|
|
14
|
+
import { MatRippleModule } from '@angular/material/core';
|
|
15
|
+
import * as i8 from '@angular/material/select';
|
|
16
|
+
import { MatSelectModule } from '@angular/material/select';
|
|
17
|
+
import * as i1 from '@angular/forms';
|
|
18
|
+
import { FormsModule } from '@angular/forms';
|
|
19
|
+
import { MinInputTypes, ElementTypes, InputDataTypes } from 'ngx-t-forms-types';
|
|
20
|
+
import { g as getInputIcon } from './ngx-t-forms-getInputIcon-B4ADgevZ.mjs';
|
|
21
|
+
import { E as EmptyStateComponent } from './ngx-t-forms-ngx-t-forms-u_kigDid.mjs';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Internal editor element for configuring a form's required (minimum) inputs.
|
|
25
|
+
* Child of `t-dynamic-data-edit`, which supplies the field label, hint, and
|
|
26
|
+
* validation errors — so this component owns only the chip row + edit content.
|
|
27
|
+
*
|
|
28
|
+
* Each required input can be handled three ways: a literal default value, a
|
|
29
|
+
* single-input map (`MapTo`), or a multi-input filter (`MapDocFilter`).
|
|
30
|
+
* Re-selecting the active handling method, chip, or a mapped input toggles it
|
|
31
|
+
* off again.
|
|
32
|
+
*/
|
|
33
|
+
class RequiredInputsComponent {
|
|
34
|
+
constructor() {
|
|
35
|
+
/** Handling-method enum, exposed to the template. */
|
|
36
|
+
this.minInputTypes = MinInputTypes;
|
|
37
|
+
/**
|
|
38
|
+
* Required-input descriptors to render. Heterogeneous wrapper binding — the
|
|
39
|
+
* parent feeds whatever the editor config holds; narrowing here would force
|
|
40
|
+
* wrapper changes.
|
|
41
|
+
*/
|
|
42
|
+
this.value = input([], ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
43
|
+
/** All available form inputs the user can map a required input to. */
|
|
44
|
+
this.formInputs = input([], ...(ngDevMode ? [{ debugName: "formInputs" }] : /* istanbul ignore next */ []));
|
|
45
|
+
/** Disable user interaction. */
|
|
46
|
+
this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
47
|
+
/**
|
|
48
|
+
* Validation errors passed down by the parent editor. Retained on the contract
|
|
49
|
+
* but not rendered here — `t-dynamic-data-edit` owns error display.
|
|
50
|
+
*/
|
|
51
|
+
this.errors = input([], ...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
52
|
+
/** Optional id attribute supplied by the parent editor (used to disambiguate). */
|
|
53
|
+
this.id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
54
|
+
/** Emits the mutated required-input list whenever the user changes a mapping. */
|
|
55
|
+
this.valueChanged = output();
|
|
56
|
+
/**
|
|
57
|
+
* Local, immutable working copy of `value`. Tracks the bound value (the parent
|
|
58
|
+
* re-feeds it after each emit) but stays locally overridable; mutations always
|
|
59
|
+
* produce a new array, and entries are cloned so the parent's array is never
|
|
60
|
+
* mutated in place.
|
|
61
|
+
*/
|
|
62
|
+
this.#workingValue = linkedSignal(() => this.value().map((item) => ({ ...item })), ...(ngDevMode ? [{ debugName: "#workingValue" }] : /* istanbul ignore next */ []));
|
|
63
|
+
/** Name of the required input currently open in the edit panel; `''` when none. */
|
|
64
|
+
this.activeInput = signal('', ...(ngDevMode ? [{ debugName: "activeInput" }] : /* istanbul ignore next */ []));
|
|
65
|
+
/** The chip row: one entry per required input, with derived link/active state. */
|
|
66
|
+
this.chips = computed(() => {
|
|
67
|
+
const active = this.activeInput();
|
|
68
|
+
return this.#workingValue().map((item) => ({
|
|
69
|
+
name: item.name,
|
|
70
|
+
linked: this.#isLinked(item),
|
|
71
|
+
active: item.name === active,
|
|
72
|
+
}));
|
|
73
|
+
}, ...(ngDevMode ? [{ debugName: "chips" }] : /* istanbul ignore next */ []));
|
|
74
|
+
/** The required input currently being edited, or `undefined` when none is active. */
|
|
75
|
+
this.inEdit = computed(() => {
|
|
76
|
+
const active = this.activeInput();
|
|
77
|
+
if (!active) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
return this.#workingValue().find((item) => item.name === active);
|
|
81
|
+
}, ...(ngDevMode ? [{ debugName: "inEdit" }] : /* istanbul ignore next */ []));
|
|
82
|
+
/** Handling method of the input in edit; `null` keeps the `mat-select` empty. */
|
|
83
|
+
this.activeType = computed(() => {
|
|
84
|
+
const type = this.inEdit()?.type;
|
|
85
|
+
return type === MinInputTypes.Default ||
|
|
86
|
+
type === MinInputTypes.MapTo ||
|
|
87
|
+
type === MinInputTypes.MapDocFilter
|
|
88
|
+
? type
|
|
89
|
+
: null;
|
|
90
|
+
}, ...(ngDevMode ? [{ debugName: "activeType" }] : /* istanbul ignore next */ []));
|
|
91
|
+
/** Whether the edit panel should show the mappable-input list. */
|
|
92
|
+
this.showMapList = computed(() => {
|
|
93
|
+
const type = this.activeType();
|
|
94
|
+
return type === MinInputTypes.MapTo || type === MinInputTypes.MapDocFilter;
|
|
95
|
+
}, ...(ngDevMode ? [{ debugName: "showMapList" }] : /* istanbul ignore next */ []));
|
|
96
|
+
/**
|
|
97
|
+
* The list of mappable form inputs for the input in edit. Single-select
|
|
98
|
+
* (`MapTo`) collapses to the chosen input once one is picked; multi-select
|
|
99
|
+
* (`MapDocFilter`) always shows the full list with each chosen input flagged.
|
|
100
|
+
*/
|
|
101
|
+
this.mapTargets = computed(() => {
|
|
102
|
+
const edit = this.inEdit();
|
|
103
|
+
if (!edit) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
const all = this.formInputs().map((item) => this.#toTarget(item, edit));
|
|
107
|
+
if (edit.type === MinInputTypes.MapTo) {
|
|
108
|
+
const selected = all.find((target) => target.selected);
|
|
109
|
+
return selected ? [selected] : all;
|
|
110
|
+
}
|
|
111
|
+
return all;
|
|
112
|
+
}, ...(ngDevMode ? [{ debugName: "mapTargets" }] : /* istanbul ignore next */ []));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Local, immutable working copy of `value`. Tracks the bound value (the parent
|
|
116
|
+
* re-feeds it after each emit) but stays locally overridable; mutations always
|
|
117
|
+
* produce a new array, and entries are cloned so the parent's array is never
|
|
118
|
+
* mutated in place.
|
|
119
|
+
*/
|
|
120
|
+
#workingValue;
|
|
121
|
+
/** Toggle the edit panel for a required input. Re-selecting the active one closes it. */
|
|
122
|
+
toggleActive(name) {
|
|
123
|
+
if (this.disabled()) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
this.activeInput.update((current) => (current === name ? '' : name));
|
|
127
|
+
}
|
|
128
|
+
/** Close the edit panel without changing anything. */
|
|
129
|
+
close() {
|
|
130
|
+
this.activeInput.set('');
|
|
131
|
+
}
|
|
132
|
+
/** Choose (or, when re-selected, clear) the handling method for the input in edit. */
|
|
133
|
+
selectType(type) {
|
|
134
|
+
this.#patchActive((current) => {
|
|
135
|
+
if (current.type === type) {
|
|
136
|
+
return { ...current, type: undefined, mapTo: undefined, defaultValue: undefined };
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
...current,
|
|
140
|
+
type,
|
|
141
|
+
mapTo: type === MinInputTypes.MapDocFilter ? [] : undefined,
|
|
142
|
+
defaultValue: type === MinInputTypes.Default ? current.defaultValue : undefined,
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/** Update the literal default value of the input in edit. */
|
|
147
|
+
setDefaultValue(value) {
|
|
148
|
+
this.#patchActive((current) => ({ ...current, defaultValue: value }));
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Map (or, when re-selected, unmap) a form input to the input in edit. `MapTo`
|
|
152
|
+
* holds a single mapping; `MapDocFilter` accumulates a list.
|
|
153
|
+
*/
|
|
154
|
+
toggleMap(target) {
|
|
155
|
+
if (this.disabled() || !target.mappable) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const mapping = this.#toMapping(target);
|
|
159
|
+
this.#patchActive((current) => {
|
|
160
|
+
if (current.type === MinInputTypes.MapTo) {
|
|
161
|
+
const existing = this.#asSingle(current.mapTo);
|
|
162
|
+
const sameSelected = existing?.formControlName === mapping.formControlName;
|
|
163
|
+
return { ...current, mapTo: sameSelected ? undefined : mapping };
|
|
164
|
+
}
|
|
165
|
+
if (current.type === MinInputTypes.MapDocFilter) {
|
|
166
|
+
const list = this.#asList(current.mapTo);
|
|
167
|
+
const has = list.some((m) => m.formControlName === mapping.formControlName);
|
|
168
|
+
return {
|
|
169
|
+
...current,
|
|
170
|
+
mapTo: has
|
|
171
|
+
? list.filter((m) => m.formControlName !== mapping.formControlName)
|
|
172
|
+
: [...list, mapping],
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
return current;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
/** Replace the active entry via `patch` and emit the new list. */
|
|
179
|
+
#patchActive(patch) {
|
|
180
|
+
const active = this.activeInput();
|
|
181
|
+
let changed = false;
|
|
182
|
+
const next = this.#workingValue().map((item) => {
|
|
183
|
+
if (item.name !== active) {
|
|
184
|
+
return item;
|
|
185
|
+
}
|
|
186
|
+
changed = true;
|
|
187
|
+
return patch(item);
|
|
188
|
+
});
|
|
189
|
+
if (!changed) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
this.#workingValue.set(next);
|
|
193
|
+
this.valueChanged.emit([...next]);
|
|
194
|
+
}
|
|
195
|
+
#isLinked(item) {
|
|
196
|
+
if (item.type === MinInputTypes.Default) {
|
|
197
|
+
return !!item.defaultValue;
|
|
198
|
+
}
|
|
199
|
+
if (item.type === MinInputTypes.MapTo) {
|
|
200
|
+
return !!this.#asSingle(item.mapTo);
|
|
201
|
+
}
|
|
202
|
+
if (item.type === MinInputTypes.MapDocFilter) {
|
|
203
|
+
return this.#asList(item.mapTo).length > 0;
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
#toTarget(item, edit) {
|
|
208
|
+
const mappable = item.element !== ElementTypes.SectionTitle;
|
|
209
|
+
const selected = this.#isMapped(edit, item.formControlName);
|
|
210
|
+
return {
|
|
211
|
+
id: item.id,
|
|
212
|
+
label: item.label,
|
|
213
|
+
icon: getInputIcon(item.element),
|
|
214
|
+
formControlName: item.formControlName,
|
|
215
|
+
dataType: item.dataType ?? '',
|
|
216
|
+
selected,
|
|
217
|
+
mappable,
|
|
218
|
+
ariaLabel: `${item.label}.${mappable ? '' : ' Not mappable.'}`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
#isMapped(edit, formControlName) {
|
|
222
|
+
if (edit.type === MinInputTypes.MapTo) {
|
|
223
|
+
return this.#asSingle(edit.mapTo)?.formControlName === formControlName;
|
|
224
|
+
}
|
|
225
|
+
if (edit.type === MinInputTypes.MapDocFilter) {
|
|
226
|
+
return this.#asList(edit.mapTo).some((m) => m.formControlName === formControlName);
|
|
227
|
+
}
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
#toMapping(target) {
|
|
231
|
+
const source = this.formInputs().find((item) => item.id === target.id);
|
|
232
|
+
return {
|
|
233
|
+
formControlName: target.formControlName,
|
|
234
|
+
dataType: source?.dataType ?? InputDataTypes.String,
|
|
235
|
+
element: source?.element ?? ElementTypes.Input,
|
|
236
|
+
inputId: target.id,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
#asSingle(mapTo) {
|
|
240
|
+
if (!mapTo || Array.isArray(mapTo)) {
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
// `Array.isArray` does not narrow a `readonly[]` out of the union, so assert
|
|
244
|
+
// the remaining single-mapping shape after the guard.
|
|
245
|
+
return mapTo;
|
|
246
|
+
}
|
|
247
|
+
#asList(mapTo) {
|
|
248
|
+
return Array.isArray(mapTo) ? mapTo : [];
|
|
249
|
+
}
|
|
250
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: RequiredInputsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
251
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: RequiredInputsComponent, isStandalone: true, selector: "lib-required-inputs", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, formInputs: { classPropertyName: "formInputs", publicName: "formInputs", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChanged: "valueChanged" }, host: { properties: { "attr.id": "id()" }, classAttribute: "lib-required-inputs" }, ngImport: i0, template: "@if (chips().length) {\n<div class=\"lib-required-inputs__chips\" role=\"list\" aria-label=\"Required inputs\">\n @for (chip of chips(); track chip.name) {\n <button\n type=\"button\"\n role=\"listitem\"\n class=\"lib-required-inputs__chip\"\n [class.lib-required-inputs__chip--linked]=\"chip.linked\"\n [class.lib-required-inputs__chip--active]=\"chip.active\"\n [disabled]=\"disabled()\"\n [attr.aria-pressed]=\"chip.active\"\n [attr.aria-label]=\"chip.name + (chip.linked ? ', linked' : ', not linked')\"\n (click)=\"toggleActive(chip.name)\">\n <span class=\"lib-required-inputs__chip-label\">{{ chip.name }}</span>\n <mat-icon class=\"lib-required-inputs__chip-icon\" aria-hidden=\"true\">\n {{ chip.linked ? 'link' : 'link_off' }}\n </mat-icon>\n </button>\n }\n</div>\n} @else {\n<lib-empty-state icon=\"link_off\" message=\"No required inputs to configure.\" />\n}\n\n@if (inEdit(); as edit) {\n<div class=\"lib-required-inputs__panel\">\n <mat-form-field\n class=\"lib-required-inputs__field\"\n appearance=\"outline\"\n subscriptSizing=\"dynamic\">\n <mat-label>Input handling method</mat-label>\n <mat-select\n [value]=\"activeType()\"\n [disabled]=\"disabled()\"\n (selectionChange)=\"selectType($event.value)\">\n <mat-option [value]=\"minInputTypes.Default\">Default value</mat-option>\n <mat-option [value]=\"minInputTypes.MapTo\">Map to a form input</mat-option>\n <mat-option [value]=\"minInputTypes.MapDocFilter\">Filter by an input value</mat-option>\n </mat-select>\n <mat-hint>Choose how this required input is resolved</mat-hint>\n </mat-form-field>\n\n @if (activeType() === minInputTypes.Default) {\n <mat-form-field\n class=\"lib-required-inputs__field\"\n appearance=\"outline\"\n subscriptSizing=\"dynamic\">\n <mat-label>Default value</mat-label>\n <input\n matInput\n [ngModel]=\"edit.defaultValue\"\n [disabled]=\"disabled()\"\n (ngModelChange)=\"setDefaultValue($event)\"\n placeholder=\"Enter a default value\" />\n <mat-hint>Used when no value is supplied at runtime</mat-hint>\n </mat-form-field>\n }\n\n @if (showMapList()) {\n <p class=\"lib-required-inputs__list-label\">\n Link <strong>{{ activeInput() }}</strong> to a form input\n </p>\n\n @if (mapTargets().length) {\n <mat-nav-list class=\"lib-required-inputs__list\">\n {{mapTargets().length}}\n @for (target of mapTargets(); track target.id) {\n <mat-list-item\n class=\"lib-required-inputs__item\"\n matRipple\n role=\"button\"\n [disabled]=\"disabled() || !target.mappable\"\n [activated]=\"target.selected\"\n [attr.aria-pressed]=\"target.selected\"\n [attr.aria-label]=\"target.ariaLabel\"\n (click)=\"toggleMap(target); $event.stopPropagation()\">\n <mat-icon\n matListItemAvatar\n class=\"lib-required-inputs__avatar\"\n aria-hidden=\"true\">\n {{ target.icon }}\n </mat-icon>\n <span matListItemTitle class=\"lib-required-inputs__item-title\">{{ target.label }}</span>\n <span matListItemLine class=\"lib-required-inputs__item-meta\">\n <span>{{ target.formControlName }}</span>\n @if (target.dataType) {\n <span>{{ target.dataType }}</span>\n }\n </span>\n <mat-icon\n matListItemMeta\n class=\"lib-required-inputs__indicator\"\n [class.lib-required-inputs__indicator--on]=\"target.selected\"\n aria-hidden=\"true\">\n {{ target.selected ? 'check_circle' : 'radio_button_unchecked' }}\n </mat-icon>\n </mat-list-item>\n }\n </mat-nav-list>\n } @else {\n <lib-empty-state icon=\"add_link\" message=\"Add form inputs before mapping this input.\" />\n }\n }\n\n <div class=\"lib-required-inputs__actions\">\n <button type=\"button\" mat-flat-button color=\"primary\" (click)=\"close()\">Done</button>\n </div>\n</div>\n}\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:1.5rem;color:var(--lib-forms-on-surface)}.lib-required-inputs__chips{display:flex;flex-wrap:wrap;gap:.5rem}.lib-required-inputs__chip{display:inline-flex;align-items:center;gap:.5rem;padding:.25rem .5rem .25rem .625rem;background:color-mix(in srgb,var(--lib-forms-primary) 10%,transparent);border-radius:var(--lib-forms-radius-pill, 6px);font-size:.8125rem;color:var(--lib-forms-on-surface);cursor:pointer;border:1px solid color-mix(in srgb,var(--lib-forms-outline) 30%,transparent);background:var(--lib-forms-surface);transition:background-color var(--lib-forms-duration-hover) var(--lib-forms-easing),border-color var(--lib-forms-duration-hover) var(--lib-forms-easing)}.lib-required-inputs__chip:hover:not(:disabled){border-color:var(--lib-forms-primary)}.lib-required-inputs__chip:focus-visible{outline:none;border-color:var(--lib-forms-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--lib-forms-primary) 25%,transparent)}.lib-required-inputs__chip:disabled{opacity:.55;pointer-events:none}.lib-required-inputs__chip--linked{background:color-mix(in srgb,var(--lib-forms-primary) 14%,transparent);border-color:color-mix(in srgb,var(--lib-forms-primary) 30%,transparent)}.lib-required-inputs__chip--active{border-color:var(--lib-forms-primary);background:color-mix(in srgb,var(--lib-forms-primary) 22%,transparent)}.lib-required-inputs__chip-icon{width:1rem;height:1rem;font-size:1rem;color:var(--lib-forms-on-surface-variant)}.lib-required-inputs__chip--linked .lib-required-inputs__chip-icon,.lib-required-inputs__chip--active .lib-required-inputs__chip-icon{color:var(--lib-forms-primary)}.lib-required-inputs__panel{display:flex;flex-direction:column;gap:1.5rem}.lib-required-inputs__field{width:100%}.lib-required-inputs__list-label{margin:0;font-size:.625rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--lib-forms-on-surface-variant)}.lib-required-inputs__list-label strong{color:var(--lib-forms-primary)}.lib-required-inputs__list{width:100%;box-sizing:border-box;max-height:65vh;overflow:auto;padding:.5rem;background:var(--lib-forms-surface);border:1px solid color-mix(in srgb,var(--lib-forms-outline) 12%,transparent);border-radius:var(--lib-forms-radius-lg, 12px)}.lib-required-inputs__item{min-height:3rem;height:fit-content;margin-bottom:.25rem;border-radius:var(--lib-forms-radius-sm, 8px);cursor:pointer;transition:background-color var(--lib-forms-duration-hover) var(--lib-forms-easing)}.lib-required-inputs__item:last-child{margin-bottom:0}.lib-required-inputs__item:hover{background:color-mix(in srgb,var(--lib-forms-primary) 6%,transparent)}.lib-required-inputs__item:focus-visible{outline:none;border-color:var(--lib-forms-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--lib-forms-primary) 25%,transparent)}.lib-required-inputs__item.mdc-list-item--activated{background:color-mix(in srgb,var(--lib-forms-primary) 12%,transparent)}mat-icon.lib-required-inputs__avatar{display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;border-radius:var(--lib-forms-radius-sm, 8px);font-size:1.5rem;line-height:1;background:var(--lib-forms-surface-container-high);color:var(--lib-forms-on-surface-variant)}.lib-required-inputs__item-title{font-size:.9375rem;font-weight:600}.lib-required-inputs__item-meta{display:flex;flex-wrap:wrap;gap:.5rem;font-size:.75rem;color:var(--lib-forms-on-surface-variant)}.lib-required-inputs__indicator{color:var(--lib-forms-on-surface-variant)}.lib-required-inputs__indicator--on{color:var(--lib-forms-primary)}.lib-required-inputs__actions{display:flex;justify-content:flex-end;gap:.75rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i4.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i4.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i4.MatListItemAvatar, selector: "[matListItemAvatar]" }, { kind: "directive", type: i4.MatListItemLine, selector: "[matListItemLine]" }, { kind: "directive", type: i4.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "directive", type: i4.MatListItemMeta, selector: "[matListItemMeta]" }, { kind: "ngmodule", type: MatRippleModule }, { kind: "directive", type: i7.MatRipple, selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i8.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i8.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: EmptyStateComponent, selector: "lib-empty-state", inputs: ["icon", "message"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
252
|
+
}
|
|
253
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: RequiredInputsComponent, decorators: [{
|
|
254
|
+
type: Component,
|
|
255
|
+
args: [{ selector: 'lib-required-inputs', imports: [
|
|
256
|
+
FormsModule,
|
|
257
|
+
MatButtonModule,
|
|
258
|
+
MatFormFieldModule,
|
|
259
|
+
MatIconModule,
|
|
260
|
+
MatInputModule,
|
|
261
|
+
MatListModule,
|
|
262
|
+
MatRippleModule,
|
|
263
|
+
MatSelectModule,
|
|
264
|
+
EmptyStateComponent,
|
|
265
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, host: {
|
|
266
|
+
'class': 'lib-required-inputs',
|
|
267
|
+
'[attr.id]': 'id()',
|
|
268
|
+
}, template: "@if (chips().length) {\n<div class=\"lib-required-inputs__chips\" role=\"list\" aria-label=\"Required inputs\">\n @for (chip of chips(); track chip.name) {\n <button\n type=\"button\"\n role=\"listitem\"\n class=\"lib-required-inputs__chip\"\n [class.lib-required-inputs__chip--linked]=\"chip.linked\"\n [class.lib-required-inputs__chip--active]=\"chip.active\"\n [disabled]=\"disabled()\"\n [attr.aria-pressed]=\"chip.active\"\n [attr.aria-label]=\"chip.name + (chip.linked ? ', linked' : ', not linked')\"\n (click)=\"toggleActive(chip.name)\">\n <span class=\"lib-required-inputs__chip-label\">{{ chip.name }}</span>\n <mat-icon class=\"lib-required-inputs__chip-icon\" aria-hidden=\"true\">\n {{ chip.linked ? 'link' : 'link_off' }}\n </mat-icon>\n </button>\n }\n</div>\n} @else {\n<lib-empty-state icon=\"link_off\" message=\"No required inputs to configure.\" />\n}\n\n@if (inEdit(); as edit) {\n<div class=\"lib-required-inputs__panel\">\n <mat-form-field\n class=\"lib-required-inputs__field\"\n appearance=\"outline\"\n subscriptSizing=\"dynamic\">\n <mat-label>Input handling method</mat-label>\n <mat-select\n [value]=\"activeType()\"\n [disabled]=\"disabled()\"\n (selectionChange)=\"selectType($event.value)\">\n <mat-option [value]=\"minInputTypes.Default\">Default value</mat-option>\n <mat-option [value]=\"minInputTypes.MapTo\">Map to a form input</mat-option>\n <mat-option [value]=\"minInputTypes.MapDocFilter\">Filter by an input value</mat-option>\n </mat-select>\n <mat-hint>Choose how this required input is resolved</mat-hint>\n </mat-form-field>\n\n @if (activeType() === minInputTypes.Default) {\n <mat-form-field\n class=\"lib-required-inputs__field\"\n appearance=\"outline\"\n subscriptSizing=\"dynamic\">\n <mat-label>Default value</mat-label>\n <input\n matInput\n [ngModel]=\"edit.defaultValue\"\n [disabled]=\"disabled()\"\n (ngModelChange)=\"setDefaultValue($event)\"\n placeholder=\"Enter a default value\" />\n <mat-hint>Used when no value is supplied at runtime</mat-hint>\n </mat-form-field>\n }\n\n @if (showMapList()) {\n <p class=\"lib-required-inputs__list-label\">\n Link <strong>{{ activeInput() }}</strong> to a form input\n </p>\n\n @if (mapTargets().length) {\n <mat-nav-list class=\"lib-required-inputs__list\">\n {{mapTargets().length}}\n @for (target of mapTargets(); track target.id) {\n <mat-list-item\n class=\"lib-required-inputs__item\"\n matRipple\n role=\"button\"\n [disabled]=\"disabled() || !target.mappable\"\n [activated]=\"target.selected\"\n [attr.aria-pressed]=\"target.selected\"\n [attr.aria-label]=\"target.ariaLabel\"\n (click)=\"toggleMap(target); $event.stopPropagation()\">\n <mat-icon\n matListItemAvatar\n class=\"lib-required-inputs__avatar\"\n aria-hidden=\"true\">\n {{ target.icon }}\n </mat-icon>\n <span matListItemTitle class=\"lib-required-inputs__item-title\">{{ target.label }}</span>\n <span matListItemLine class=\"lib-required-inputs__item-meta\">\n <span>{{ target.formControlName }}</span>\n @if (target.dataType) {\n <span>{{ target.dataType }}</span>\n }\n </span>\n <mat-icon\n matListItemMeta\n class=\"lib-required-inputs__indicator\"\n [class.lib-required-inputs__indicator--on]=\"target.selected\"\n aria-hidden=\"true\">\n {{ target.selected ? 'check_circle' : 'radio_button_unchecked' }}\n </mat-icon>\n </mat-list-item>\n }\n </mat-nav-list>\n } @else {\n <lib-empty-state icon=\"add_link\" message=\"Add form inputs before mapping this input.\" />\n }\n }\n\n <div class=\"lib-required-inputs__actions\">\n <button type=\"button\" mat-flat-button color=\"primary\" (click)=\"close()\">Done</button>\n </div>\n</div>\n}\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:1.5rem;color:var(--lib-forms-on-surface)}.lib-required-inputs__chips{display:flex;flex-wrap:wrap;gap:.5rem}.lib-required-inputs__chip{display:inline-flex;align-items:center;gap:.5rem;padding:.25rem .5rem .25rem .625rem;background:color-mix(in srgb,var(--lib-forms-primary) 10%,transparent);border-radius:var(--lib-forms-radius-pill, 6px);font-size:.8125rem;color:var(--lib-forms-on-surface);cursor:pointer;border:1px solid color-mix(in srgb,var(--lib-forms-outline) 30%,transparent);background:var(--lib-forms-surface);transition:background-color var(--lib-forms-duration-hover) var(--lib-forms-easing),border-color var(--lib-forms-duration-hover) var(--lib-forms-easing)}.lib-required-inputs__chip:hover:not(:disabled){border-color:var(--lib-forms-primary)}.lib-required-inputs__chip:focus-visible{outline:none;border-color:var(--lib-forms-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--lib-forms-primary) 25%,transparent)}.lib-required-inputs__chip:disabled{opacity:.55;pointer-events:none}.lib-required-inputs__chip--linked{background:color-mix(in srgb,var(--lib-forms-primary) 14%,transparent);border-color:color-mix(in srgb,var(--lib-forms-primary) 30%,transparent)}.lib-required-inputs__chip--active{border-color:var(--lib-forms-primary);background:color-mix(in srgb,var(--lib-forms-primary) 22%,transparent)}.lib-required-inputs__chip-icon{width:1rem;height:1rem;font-size:1rem;color:var(--lib-forms-on-surface-variant)}.lib-required-inputs__chip--linked .lib-required-inputs__chip-icon,.lib-required-inputs__chip--active .lib-required-inputs__chip-icon{color:var(--lib-forms-primary)}.lib-required-inputs__panel{display:flex;flex-direction:column;gap:1.5rem}.lib-required-inputs__field{width:100%}.lib-required-inputs__list-label{margin:0;font-size:.625rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--lib-forms-on-surface-variant)}.lib-required-inputs__list-label strong{color:var(--lib-forms-primary)}.lib-required-inputs__list{width:100%;box-sizing:border-box;max-height:65vh;overflow:auto;padding:.5rem;background:var(--lib-forms-surface);border:1px solid color-mix(in srgb,var(--lib-forms-outline) 12%,transparent);border-radius:var(--lib-forms-radius-lg, 12px)}.lib-required-inputs__item{min-height:3rem;height:fit-content;margin-bottom:.25rem;border-radius:var(--lib-forms-radius-sm, 8px);cursor:pointer;transition:background-color var(--lib-forms-duration-hover) var(--lib-forms-easing)}.lib-required-inputs__item:last-child{margin-bottom:0}.lib-required-inputs__item:hover{background:color-mix(in srgb,var(--lib-forms-primary) 6%,transparent)}.lib-required-inputs__item:focus-visible{outline:none;border-color:var(--lib-forms-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--lib-forms-primary) 25%,transparent)}.lib-required-inputs__item.mdc-list-item--activated{background:color-mix(in srgb,var(--lib-forms-primary) 12%,transparent)}mat-icon.lib-required-inputs__avatar{display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;border-radius:var(--lib-forms-radius-sm, 8px);font-size:1.5rem;line-height:1;background:var(--lib-forms-surface-container-high);color:var(--lib-forms-on-surface-variant)}.lib-required-inputs__item-title{font-size:.9375rem;font-weight:600}.lib-required-inputs__item-meta{display:flex;flex-wrap:wrap;gap:.5rem;font-size:.75rem;color:var(--lib-forms-on-surface-variant)}.lib-required-inputs__indicator{color:var(--lib-forms-on-surface-variant)}.lib-required-inputs__indicator--on{color:var(--lib-forms-primary)}.lib-required-inputs__actions{display:flex;justify-content:flex-end;gap:.75rem}\n"] }]
|
|
269
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], formInputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "formInputs", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], valueChanged: [{ type: i0.Output, args: ["valueChanged"] }] } });
|
|
270
|
+
|
|
271
|
+
export { RequiredInputsComponent };
|
|
272
|
+
//# sourceMappingURL=ngx-t-forms-required-inputs.component-Ch2yNcIS.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngx-t-forms-required-inputs.component-Ch2yNcIS.mjs","sources":["../../../projects/ngx-t-forms/src/lib/components/t-dynamic-data-edit/elements/required-inputs/required-inputs.component.ts","../../../projects/ngx-t-forms/src/lib/components/t-dynamic-data-edit/elements/required-inputs/required-inputs.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n linkedSignal,\n output,\n signal,\n} from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatListModule } from '@angular/material/list';\nimport { MatRippleModule } from '@angular/material/core';\nimport { MatSelectModule } from '@angular/material/select';\nimport { FormsModule } from '@angular/forms';\nimport {\n ElementTypes,\n FormColumnInputs,\n InputDataTypes,\n MinInputMapInput,\n MinInputTypes,\n MinimumInputRequiredInterface,\n} from 'ngx-t-forms-types';\nimport { getInputIcon } from '../../../../shared/functions/getInputIcon';\nimport type { IConfigElementError } from '../../t-dynamic-data-edit.component';\nimport { EmptyStateComponent } from '../_shared/empty-state/empty-state.component';\n\n/** A required input decorated with the derived view-model fields the chip row renders. */\ninterface RequiredInputChip {\n readonly name: string;\n readonly linked: boolean;\n readonly active: boolean;\n}\n\n/** A mappable form input decorated with the derived view-model fields the list renders. */\ninterface MapTarget {\n readonly id: string;\n readonly label: string;\n readonly icon: string;\n readonly formControlName: string;\n readonly dataType: string;\n readonly selected: boolean;\n readonly mappable: boolean;\n readonly ariaLabel: string;\n}\n\n/**\n * Internal editor element for configuring a form's required (minimum) inputs.\n * Child of `t-dynamic-data-edit`, which supplies the field label, hint, and\n * validation errors — so this component owns only the chip row + edit content.\n *\n * Each required input can be handled three ways: a literal default value, a\n * single-input map (`MapTo`), or a multi-input filter (`MapDocFilter`).\n * Re-selecting the active handling method, chip, or a mapped input toggles it\n * off again.\n */\n@Component({\n selector: 'lib-required-inputs',\n imports: [\n FormsModule,\n MatButtonModule,\n MatFormFieldModule,\n MatIconModule,\n MatInputModule,\n MatListModule,\n MatRippleModule,\n MatSelectModule,\n EmptyStateComponent,\n ],\n templateUrl: './required-inputs.component.html',\n styleUrl: './required-inputs.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.Emulated,\n host: {\n 'class': 'lib-required-inputs',\n '[attr.id]': 'id()',\n },\n})\nexport class RequiredInputsComponent {\n /** Handling-method enum, exposed to the template. */\n protected readonly minInputTypes = MinInputTypes;\n\n /**\n * Required-input descriptors to render. Heterogeneous wrapper binding — the\n * parent feeds whatever the editor config holds; narrowing here would force\n * wrapper changes.\n */\n readonly value = input<readonly MinimumInputRequiredInterface[]>([]);\n\n /** All available form inputs the user can map a required input to. */\n readonly formInputs = input<readonly FormColumnInputs[]>([]);\n\n /** Disable user interaction. */\n readonly disabled = input<boolean>(false);\n\n /**\n * Validation errors passed down by the parent editor. Retained on the contract\n * but not rendered here — `t-dynamic-data-edit` owns error display.\n */\n readonly errors = input<IConfigElementError[] | undefined>([]);\n\n /** Optional id attribute supplied by the parent editor (used to disambiguate). */\n readonly id = input<string | undefined>(undefined);\n\n /** Emits the mutated required-input list whenever the user changes a mapping. */\n readonly valueChanged = output<MinimumInputRequiredInterface[]>();\n\n /**\n * Local, immutable working copy of `value`. Tracks the bound value (the parent\n * re-feeds it after each emit) but stays locally overridable; mutations always\n * produce a new array, and entries are cloned so the parent's array is never\n * mutated in place.\n */\n readonly #workingValue = linkedSignal<readonly MinimumInputRequiredInterface[]>(() =>\n this.value().map((item) => ({ ...item })),\n );\n\n /** Name of the required input currently open in the edit panel; `''` when none. */\n protected readonly activeInput = signal<string>('');\n\n /** The chip row: one entry per required input, with derived link/active state. */\n protected readonly chips = computed<readonly RequiredInputChip[]>(() => {\n const active = this.activeInput();\n return this.#workingValue().map((item) => ({\n name: item.name,\n linked: this.#isLinked(item),\n active: item.name === active,\n }));\n });\n\n /** The required input currently being edited, or `undefined` when none is active. */\n protected readonly inEdit = computed<MinimumInputRequiredInterface | undefined>(() => {\n const active = this.activeInput();\n if (!active) {\n return undefined;\n }\n return this.#workingValue().find((item) => item.name === active);\n });\n\n /** Handling method of the input in edit; `null` keeps the `mat-select` empty. */\n protected readonly activeType = computed<MinInputTypes | null>(() => {\n const type = this.inEdit()?.type;\n return type === MinInputTypes.Default ||\n type === MinInputTypes.MapTo ||\n type === MinInputTypes.MapDocFilter\n ? type\n : null;\n });\n\n /** Whether the edit panel should show the mappable-input list. */\n protected readonly showMapList = computed<boolean>(() => {\n const type = this.activeType();\n return type === MinInputTypes.MapTo || type === MinInputTypes.MapDocFilter;\n });\n\n /**\n * The list of mappable form inputs for the input in edit. Single-select\n * (`MapTo`) collapses to the chosen input once one is picked; multi-select\n * (`MapDocFilter`) always shows the full list with each chosen input flagged.\n */\n protected readonly mapTargets = computed<readonly MapTarget[]>(() => {\n const edit = this.inEdit();\n if (!edit) {\n return [];\n }\n const all = this.formInputs().map((item) => this.#toTarget(item, edit));\n if (edit.type === MinInputTypes.MapTo) {\n const selected = all.find((target) => target.selected);\n return selected ? [selected] : all;\n }\n return all;\n });\n\n /** Toggle the edit panel for a required input. Re-selecting the active one closes it. */\n protected toggleActive(name: string): void {\n if (this.disabled()) {\n return;\n }\n this.activeInput.update((current) => (current === name ? '' : name));\n }\n\n /** Close the edit panel without changing anything. */\n protected close(): void {\n this.activeInput.set('');\n }\n\n /** Choose (or, when re-selected, clear) the handling method for the input in edit. */\n protected selectType(type: MinInputTypes): void {\n this.#patchActive((current) => {\n if (current.type === type) {\n return { ...current, type: undefined, mapTo: undefined, defaultValue: undefined };\n }\n return {\n ...current,\n type,\n mapTo: type === MinInputTypes.MapDocFilter ? [] : undefined,\n defaultValue: type === MinInputTypes.Default ? current.defaultValue : undefined,\n };\n });\n }\n\n /** Update the literal default value of the input in edit. */\n protected setDefaultValue(value: string): void {\n this.#patchActive((current) => ({ ...current, defaultValue: value }));\n }\n\n /**\n * Map (or, when re-selected, unmap) a form input to the input in edit. `MapTo`\n * holds a single mapping; `MapDocFilter` accumulates a list.\n */\n protected toggleMap(target: MapTarget): void {\n if (this.disabled() || !target.mappable) {\n return;\n }\n const mapping = this.#toMapping(target);\n this.#patchActive((current) => {\n if (current.type === MinInputTypes.MapTo) {\n const existing = this.#asSingle(current.mapTo);\n const sameSelected = existing?.formControlName === mapping.formControlName;\n return { ...current, mapTo: sameSelected ? undefined : mapping };\n }\n if (current.type === MinInputTypes.MapDocFilter) {\n const list = this.#asList(current.mapTo);\n const has = list.some((m) => m.formControlName === mapping.formControlName);\n return {\n ...current,\n mapTo: has\n ? list.filter((m) => m.formControlName !== mapping.formControlName)\n : [...list, mapping],\n };\n }\n return current;\n });\n }\n\n /** Replace the active entry via `patch` and emit the new list. */\n #patchActive(\n patch: (current: MinimumInputRequiredInterface) => MinimumInputRequiredInterface,\n ): void {\n const active = this.activeInput();\n let changed = false;\n const next = this.#workingValue().map((item) => {\n if (item.name !== active) {\n return item;\n }\n changed = true;\n return patch(item);\n });\n if (!changed) {\n return;\n }\n this.#workingValue.set(next);\n this.valueChanged.emit([...next]);\n }\n\n #isLinked(item: MinimumInputRequiredInterface): boolean {\n if (item.type === MinInputTypes.Default) {\n return !!item.defaultValue;\n }\n if (item.type === MinInputTypes.MapTo) {\n return !!this.#asSingle(item.mapTo);\n }\n if (item.type === MinInputTypes.MapDocFilter) {\n return this.#asList(item.mapTo).length > 0;\n }\n return false;\n }\n\n #toTarget(item: FormColumnInputs, edit: MinimumInputRequiredInterface): MapTarget {\n const mappable = item.element !== ElementTypes.SectionTitle;\n const selected = this.#isMapped(edit, item.formControlName);\n return {\n id: item.id,\n label: item.label,\n icon: getInputIcon(item.element),\n formControlName: item.formControlName,\n dataType: item.dataType ?? '',\n selected,\n mappable,\n ariaLabel: `${item.label}.${mappable ? '' : ' Not mappable.'}`,\n };\n }\n\n #isMapped(edit: MinimumInputRequiredInterface, formControlName: string): boolean {\n if (edit.type === MinInputTypes.MapTo) {\n return this.#asSingle(edit.mapTo)?.formControlName === formControlName;\n }\n if (edit.type === MinInputTypes.MapDocFilter) {\n return this.#asList(edit.mapTo).some((m) => m.formControlName === formControlName);\n }\n return false;\n }\n\n #toMapping(target: MapTarget): MinInputMapInput {\n const source = this.formInputs().find((item) => item.id === target.id);\n return {\n formControlName: target.formControlName,\n dataType: source?.dataType ?? InputDataTypes.String,\n element: source?.element ?? ElementTypes.Input,\n inputId: target.id,\n };\n }\n\n #asSingle(\n mapTo: MinInputMapInput | readonly MinInputMapInput[] | undefined,\n ): MinInputMapInput | undefined {\n if (!mapTo || Array.isArray(mapTo)) {\n return undefined;\n }\n // `Array.isArray` does not narrow a `readonly[]` out of the union, so assert\n // the remaining single-mapping shape after the guard.\n return mapTo as MinInputMapInput;\n }\n\n #asList(\n mapTo: MinInputMapInput | readonly MinInputMapInput[] | undefined,\n ): readonly MinInputMapInput[] {\n return Array.isArray(mapTo) ? mapTo : [];\n }\n}\n","@if (chips().length) {\n<div class=\"lib-required-inputs__chips\" role=\"list\" aria-label=\"Required inputs\">\n @for (chip of chips(); track chip.name) {\n <button\n type=\"button\"\n role=\"listitem\"\n class=\"lib-required-inputs__chip\"\n [class.lib-required-inputs__chip--linked]=\"chip.linked\"\n [class.lib-required-inputs__chip--active]=\"chip.active\"\n [disabled]=\"disabled()\"\n [attr.aria-pressed]=\"chip.active\"\n [attr.aria-label]=\"chip.name + (chip.linked ? ', linked' : ', not linked')\"\n (click)=\"toggleActive(chip.name)\">\n <span class=\"lib-required-inputs__chip-label\">{{ chip.name }}</span>\n <mat-icon class=\"lib-required-inputs__chip-icon\" aria-hidden=\"true\">\n {{ chip.linked ? 'link' : 'link_off' }}\n </mat-icon>\n </button>\n }\n</div>\n} @else {\n<lib-empty-state icon=\"link_off\" message=\"No required inputs to configure.\" />\n}\n\n@if (inEdit(); as edit) {\n<div class=\"lib-required-inputs__panel\">\n <mat-form-field\n class=\"lib-required-inputs__field\"\n appearance=\"outline\"\n subscriptSizing=\"dynamic\">\n <mat-label>Input handling method</mat-label>\n <mat-select\n [value]=\"activeType()\"\n [disabled]=\"disabled()\"\n (selectionChange)=\"selectType($event.value)\">\n <mat-option [value]=\"minInputTypes.Default\">Default value</mat-option>\n <mat-option [value]=\"minInputTypes.MapTo\">Map to a form input</mat-option>\n <mat-option [value]=\"minInputTypes.MapDocFilter\">Filter by an input value</mat-option>\n </mat-select>\n <mat-hint>Choose how this required input is resolved</mat-hint>\n </mat-form-field>\n\n @if (activeType() === minInputTypes.Default) {\n <mat-form-field\n class=\"lib-required-inputs__field\"\n appearance=\"outline\"\n subscriptSizing=\"dynamic\">\n <mat-label>Default value</mat-label>\n <input\n matInput\n [ngModel]=\"edit.defaultValue\"\n [disabled]=\"disabled()\"\n (ngModelChange)=\"setDefaultValue($event)\"\n placeholder=\"Enter a default value\" />\n <mat-hint>Used when no value is supplied at runtime</mat-hint>\n </mat-form-field>\n }\n\n @if (showMapList()) {\n <p class=\"lib-required-inputs__list-label\">\n Link <strong>{{ activeInput() }}</strong> to a form input\n </p>\n\n @if (mapTargets().length) {\n <mat-nav-list class=\"lib-required-inputs__list\">\n {{mapTargets().length}}\n @for (target of mapTargets(); track target.id) {\n <mat-list-item\n class=\"lib-required-inputs__item\"\n matRipple\n role=\"button\"\n [disabled]=\"disabled() || !target.mappable\"\n [activated]=\"target.selected\"\n [attr.aria-pressed]=\"target.selected\"\n [attr.aria-label]=\"target.ariaLabel\"\n (click)=\"toggleMap(target); $event.stopPropagation()\">\n <mat-icon\n matListItemAvatar\n class=\"lib-required-inputs__avatar\"\n aria-hidden=\"true\">\n {{ target.icon }}\n </mat-icon>\n <span matListItemTitle class=\"lib-required-inputs__item-title\">{{ target.label }}</span>\n <span matListItemLine class=\"lib-required-inputs__item-meta\">\n <span>{{ target.formControlName }}</span>\n @if (target.dataType) {\n <span>{{ target.dataType }}</span>\n }\n </span>\n <mat-icon\n matListItemMeta\n class=\"lib-required-inputs__indicator\"\n [class.lib-required-inputs__indicator--on]=\"target.selected\"\n aria-hidden=\"true\">\n {{ target.selected ? 'check_circle' : 'radio_button_unchecked' }}\n </mat-icon>\n </mat-list-item>\n }\n </mat-nav-list>\n } @else {\n <lib-empty-state icon=\"add_link\" message=\"Add form inputs before mapping this input.\" />\n }\n }\n\n <div class=\"lib-required-inputs__actions\">\n <button type=\"button\" mat-flat-button color=\"primary\" (click)=\"close()\">Done</button>\n </div>\n</div>\n}\n"],"names":["i3","i4","i6"],"mappings":"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"}
|