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,319 @@
|
|
|
1
|
+
import { AsyncPipe } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { inject, DestroyRef, ChangeDetectorRef, viewChild, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
|
+
import * as i1 from '@angular/forms';
|
|
6
|
+
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
|
|
7
|
+
import * as i1$1 from '@angular/cdk/drag-drop';
|
|
8
|
+
import { DragDropModule } from '@angular/cdk/drag-drop';
|
|
9
|
+
import * as i1$2 from '@angular/material/button';
|
|
10
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
11
|
+
import * as i3 from '@angular/material/card';
|
|
12
|
+
import { MatCardModule } from '@angular/material/card';
|
|
13
|
+
import * as i3$1 from '@angular/material/icon';
|
|
14
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
15
|
+
import * as i2 from '@angular/material/input';
|
|
16
|
+
import { MatInputModule } from '@angular/material/input';
|
|
17
|
+
import * as i6 from '@angular/material/menu';
|
|
18
|
+
import { MatMenuModule } from '@angular/material/menu';
|
|
19
|
+
import * as i3$2 from '@angular/material/progress-spinner';
|
|
20
|
+
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
21
|
+
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
22
|
+
import * as i4 from '@angular/material/stepper';
|
|
23
|
+
import { MatStepperModule } from '@angular/material/stepper';
|
|
24
|
+
import * as i5$1 from '@angular/material/toolbar';
|
|
25
|
+
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
26
|
+
import * as i5 from '@angular/material/tooltip';
|
|
27
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
28
|
+
import { take, filter, tap, map, Subject, timer, takeUntil } from 'rxjs';
|
|
29
|
+
import * as i7 from 'ngx-ui-tour-md-menu';
|
|
30
|
+
import { TourMatMenu } from 'ngx-ui-tour-md-menu';
|
|
31
|
+
import { validateFormColumnInputs } from 'ngx-t-forms-types';
|
|
32
|
+
import { c as TFormEngine, F as FormsStoreService, d as TourManagerService, e as getSubmissionStatusFn } from './ngx-t-forms-ngx-t-forms-u_kigDid.mjs';
|
|
33
|
+
|
|
34
|
+
class FormSectionStepperComponent {
|
|
35
|
+
constructor() {
|
|
36
|
+
/**
|
|
37
|
+
* Runtime form engine, held by composition (SIGNAL_FORMS Phase 0, D-025).
|
|
38
|
+
* Provided per-component instance; replaces the former `extends` of the tower.
|
|
39
|
+
*/
|
|
40
|
+
this.engine = inject(TFormEngine);
|
|
41
|
+
this.#destroyRef = inject(DestroyRef);
|
|
42
|
+
this.#store = inject(FormsStoreService);
|
|
43
|
+
this.#ref = inject(ChangeDetectorRef);
|
|
44
|
+
this.#snackBar = inject(MatSnackBar);
|
|
45
|
+
this.#tourManagerService = inject(TourManagerService);
|
|
46
|
+
this.stepper = viewChild('stepper', ...(ngDevMode ? [{ debugName: "stepper" }] : /* istanbul ignore next */ []));
|
|
47
|
+
this.loadingForm$ = this.#store.selectors.selectLoadingForm$;
|
|
48
|
+
this.selectInputInEditId$ = this.#store.selectors.selectInputInEditId$;
|
|
49
|
+
this.isEditable = true;
|
|
50
|
+
this.dragging = false;
|
|
51
|
+
this.mouseOverSection = null;
|
|
52
|
+
this.overId = null;
|
|
53
|
+
this.openSectionReports = {};
|
|
54
|
+
this.countdownSeconds = {};
|
|
55
|
+
// CDK drag-drop generics retained loose because the template's `<mat-step [stepControl]>`/
|
|
56
|
+
// `<div cdkDropList [cdkDropListData]>` bindings pass `ITowerFormSteps[]` / `ITowerStepColumn[]`
|
|
57
|
+
// which structurally differ from the store-action payload types (`FormSlideInterface[]` / `FormColumnInputs[]`).
|
|
58
|
+
// The downstream store actions accept the looser `<any, any, unknown>` shape so this is type-safe at the call boundary.
|
|
59
|
+
// Phase-4 TODO: tighten once FormBuilderFunctions.reorderItems generics are typed upstream.
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
|
+
this.drop = (event) => this.#store.actionsFormBuilder.handleSectionDragDrop(event);
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
+
this.dropItems = (event, sectionId) => this.#store.actionsFormBuilder.handleInputDragDrop(event, sectionId);
|
|
64
|
+
this.formDeleteSection = (sectionId) => this.#store.actionsFormBuilder.formDeleteSection(sectionId);
|
|
65
|
+
this.formDeleteSectionInputs = (sectionId) => this.#store.actionsFormBuilder.formDeleteSectionInputs(sectionId);
|
|
66
|
+
this.addMultipleFormInput = (sectionId, multipleInputId) => this.#store.actionsFormBuilder.addMultipleFormInput(sectionId, multipleInputId);
|
|
67
|
+
this.moveInputToSection = (inputId, targetSectionId) => this.#store.actionsFormBuilder.moveInputToSection(inputId, targetSectionId);
|
|
68
|
+
this.reorderMultipleInputItems = (
|
|
69
|
+
// Mirrors `FormBuilderFunctions.reorderItems` (now generic over the row
|
|
70
|
+
// shape). The lib-internal store action requires symmetric container data,
|
|
71
|
+
// so we narrow the second slot to `FormColumnInputs[]` at the boundary.
|
|
72
|
+
event, multipleInputId) => this.#store.actionsFormBuilder.reorderMultipleInputItems(event, multipleInputId);
|
|
73
|
+
this.cloneCopyFormInput = (inputId) => this.#store.actionsFormBuilder.cloneCopyFormInput(inputId);
|
|
74
|
+
this.multipleInputToggleLabel = (item) => this.#store.actionsFormBuilder.multipleInputToggleLabel(item);
|
|
75
|
+
this.editInput = (item) => this.#store.actionsFormBuilder.editInput(item);
|
|
76
|
+
this.addMultipleInputValueCalculationFunction = (item, multipleInputId) => this.#store.actionsFormBuilder.addMultipleInputValueCalculationFunction(item, multipleInputId);
|
|
77
|
+
this.setActiveSection = ($event) => this.setMatActiveStepper($event.selectedIndex);
|
|
78
|
+
this.addInputToScoaSelection = (sectionId, scoaInputId) => this.#store.actionsFormBuilder.addInputToScoaSelection(sectionId, scoaInputId);
|
|
79
|
+
this.addNewInput = (sectionId) => this.#store.actionsFormBuilder.saveInput(sectionId);
|
|
80
|
+
this.addSection = () => this.#store.actionsFormBuilder.handleAddSection();
|
|
81
|
+
this.setMatActiveStepper = (index) => {
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
const stepper = this.stepper();
|
|
84
|
+
if (stepper === undefined)
|
|
85
|
+
return;
|
|
86
|
+
stepper.selectedIndex = index;
|
|
87
|
+
}, 0);
|
|
88
|
+
};
|
|
89
|
+
this.handleInput = (event, sectionId) => {
|
|
90
|
+
const inputValue = event.target.value;
|
|
91
|
+
this.#store.actionsFormBuilder?.stepTitleChangeStep(sectionId, inputValue);
|
|
92
|
+
event.stopPropagation();
|
|
93
|
+
event.preventDefault();
|
|
94
|
+
};
|
|
95
|
+
this.inputWillBeRemovedIn = (id) => this.countdownSeconds[id]?.count;
|
|
96
|
+
// Template binds `step.sectionForm || getPlaceHolerForSection(...)` to `<mat-step [stepControl]>`
|
|
97
|
+
// which requires a non-undefined AbstractControl; the placeholder is always present at render time
|
|
98
|
+
// (created by the store ahead of the @if(step.sectionForm || ...) guard). Phase-4 TODO: tighten store
|
|
99
|
+
// contract to guarantee placeholder presence and make this non-nullable.
|
|
100
|
+
this.getPlaceHolerForSection = (sectionId) => this.#store.sectionPlaceholder[sectionId];
|
|
101
|
+
this.formDeleteInput = (item) => this.#store.actionsFormBuilder.formDeleteInput(item);
|
|
102
|
+
this.toggleSectionReports = (sectionId) => (this.openSectionReports[sectionId] = !this.openSectionReports[sectionId]);
|
|
103
|
+
this.refreshASection = (sectionId) => {
|
|
104
|
+
this.engine.refreshSection(sectionId)
|
|
105
|
+
.pipe(take(1), takeUntilDestroyed(this.#destroyRef))
|
|
106
|
+
.subscribe();
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
#destroyRef;
|
|
110
|
+
#store;
|
|
111
|
+
#ref;
|
|
112
|
+
#snackBar;
|
|
113
|
+
#tourManagerService;
|
|
114
|
+
ngOnDestroy() {
|
|
115
|
+
this.#store.deregisterFormChangeFn();
|
|
116
|
+
// The per-component TFormEngine is torn down automatically by Angular when
|
|
117
|
+
// this component is destroyed (component-provided service ngOnDestroy).
|
|
118
|
+
}
|
|
119
|
+
ngOnInit() {
|
|
120
|
+
this.#store.registerFormChangeFn(this.engine.initialize);
|
|
121
|
+
this.engine.registerFormInputConfigChangeFn((inputId, config) => {
|
|
122
|
+
this.#store.actions.updateFormInputConfigFromTower({ inputId, config });
|
|
123
|
+
});
|
|
124
|
+
this.#store.selectors.selectFormInEdit$
|
|
125
|
+
.pipe(take(1), filter(form => form !== null && form !== undefined), tap(form => this.engine.initialize(form.form)), takeUntilDestroyed(this.#destroyRef))
|
|
126
|
+
.subscribe();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Handles the key down event and reverts the last form change on Ctrl+Z.
|
|
130
|
+
* @param event The keyboard event object.
|
|
131
|
+
*/
|
|
132
|
+
onKeyDown(event) {
|
|
133
|
+
if (event.ctrlKey && event.key === 'z') {
|
|
134
|
+
this.engine.revertBackHistory();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
get formBuilderFunctions() {
|
|
138
|
+
const fns = {
|
|
139
|
+
getLatestAccountTree: () => this.engine.NGX_T_FORMS_CONFIG.formBuilder.getScoaTree(),
|
|
140
|
+
getSCOAAccount: (SCOAAccount) => this.engine.NGX_T_FORMS_CONFIG.formBuilder.getSCOAAccount(SCOAAccount),
|
|
141
|
+
multipleInputToggleForm: this.engine.toggleMultipleInput.bind(this.engine),
|
|
142
|
+
multipleInputSaveForm: this.engine.saveMultipleInputForm.bind(this.engine),
|
|
143
|
+
editInput: this.editInput.bind(this),
|
|
144
|
+
deleteInput: this.formDeleteInput.bind(this),
|
|
145
|
+
addFunction: this.addMultipleInputValueCalculationFunction.bind(this),
|
|
146
|
+
// Pre-existing node_modules duplication (ngx-t-forms-typings ships its own @angular/cdk copy).
|
|
147
|
+
// CdkDragDrop types are nominally distinct due to private `_changeDetectorRef`. Cast at the boundary.
|
|
148
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Phase-4 TODO: deduplicate @angular/cdk peer dep in typings package.
|
|
149
|
+
reorderItems: this.reorderMultipleInputItems.bind(this),
|
|
150
|
+
multipleInputToggleLabel: this.multipleInputToggleLabel.bind(this),
|
|
151
|
+
multipleInputEditRow: this.engine.multipleInputEditRow.bind(this.engine),
|
|
152
|
+
multipleInputDuplicateRow: this.engine.multipleInputDuplicateRow.bind(this.engine),
|
|
153
|
+
};
|
|
154
|
+
return fns;
|
|
155
|
+
}
|
|
156
|
+
getPreviousStepLabel() {
|
|
157
|
+
const stepper = this.stepper();
|
|
158
|
+
if (stepper === undefined)
|
|
159
|
+
return '';
|
|
160
|
+
const currentIndex = stepper.selectedIndex;
|
|
161
|
+
if (currentIndex > 0) {
|
|
162
|
+
return this.engine.selectFormSteps()?.[currentIndex - 1]?.label;
|
|
163
|
+
}
|
|
164
|
+
return '';
|
|
165
|
+
}
|
|
166
|
+
getNextStepLabel() {
|
|
167
|
+
const stepper = this.stepper();
|
|
168
|
+
if (stepper === undefined)
|
|
169
|
+
return '';
|
|
170
|
+
const currentIndex = stepper.selectedIndex;
|
|
171
|
+
const steps = this.engine.selectFormSteps();
|
|
172
|
+
if (!steps)
|
|
173
|
+
return '';
|
|
174
|
+
if (currentIndex < steps.length - 1) {
|
|
175
|
+
return steps[currentIndex + 1]?.label;
|
|
176
|
+
}
|
|
177
|
+
return '';
|
|
178
|
+
}
|
|
179
|
+
getStepState(step, index) {
|
|
180
|
+
const activeStep = this.stepper()?.selectedIndex === index;
|
|
181
|
+
if (activeStep)
|
|
182
|
+
return 'edit';
|
|
183
|
+
if (step.sectionForm?.touched && !step.sectionForm?.valid)
|
|
184
|
+
return 'error';
|
|
185
|
+
if (step.sectionForm?.valid)
|
|
186
|
+
return 'done';
|
|
187
|
+
return 'number';
|
|
188
|
+
}
|
|
189
|
+
get getSubmissionStatus$() {
|
|
190
|
+
const progress = this.engine.formProgress() || 0;
|
|
191
|
+
const steps = this.engine.selectFormSteps();
|
|
192
|
+
return this.loadingForm$.pipe(map(loading => getSubmissionStatusFn(this.stepper(), this.engine.mainForm, progress, steps, loading)));
|
|
193
|
+
}
|
|
194
|
+
get selectFormStepsComputed() {
|
|
195
|
+
return this.engine.selectFormSteps().map(step => ({
|
|
196
|
+
...step,
|
|
197
|
+
columns: step.columns.map(col => ({
|
|
198
|
+
...col,
|
|
199
|
+
inputConfigErrors: validateFormColumnInputs(col),
|
|
200
|
+
})),
|
|
201
|
+
}));
|
|
202
|
+
}
|
|
203
|
+
stopDeletion(id) {
|
|
204
|
+
if (this.countdownSeconds[id]) {
|
|
205
|
+
this.countdownSeconds[id]?.stop$.next();
|
|
206
|
+
delete this.countdownSeconds[id];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
removeInput(item) {
|
|
210
|
+
if (this.countdownSeconds[item.id]) {
|
|
211
|
+
this.stopDeletion(item.id);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
this.countdownSeconds[item.id] = {
|
|
215
|
+
count: 5,
|
|
216
|
+
stop$: new Subject(),
|
|
217
|
+
deleteInputs: false,
|
|
218
|
+
};
|
|
219
|
+
const countdown$ = timer(0, 1000).pipe(tap(secondsElapsed => {
|
|
220
|
+
const data = this.countdownSeconds[item.id];
|
|
221
|
+
if (!data) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const remainingTime = 5 - secondsElapsed;
|
|
225
|
+
if (remainingTime <= 0) {
|
|
226
|
+
this.formDeleteInput(item);
|
|
227
|
+
this.stopDeletion(item.id);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
data.count = remainingTime;
|
|
231
|
+
}
|
|
232
|
+
}), takeUntil(this.countdownSeconds[item.id]?.stop$), takeUntilDestroyed(this.#destroyRef));
|
|
233
|
+
countdown$?.subscribe({ complete: () => { } });
|
|
234
|
+
}
|
|
235
|
+
deleteSection(sectionId, deleteInputs = false) {
|
|
236
|
+
if (!sectionId) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (this.countdownSeconds[sectionId]) {
|
|
240
|
+
this.stopDeletion(sectionId);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
this.countdownSeconds[sectionId] = {
|
|
244
|
+
count: 5,
|
|
245
|
+
stop$: new Subject(),
|
|
246
|
+
deleteInputs: deleteInputs,
|
|
247
|
+
};
|
|
248
|
+
const countdown$ = timer(0, 1000).pipe(tap(secondsElapsed => {
|
|
249
|
+
const data = this.countdownSeconds[sectionId];
|
|
250
|
+
if (!data) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const remainingTime = 5 - secondsElapsed;
|
|
254
|
+
if (remainingTime <= 0) {
|
|
255
|
+
if (data.deleteInputs) {
|
|
256
|
+
this.formDeleteSectionInputs(sectionId);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
this.formDeleteSection(sectionId);
|
|
260
|
+
}
|
|
261
|
+
this.stopDeletion(sectionId);
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
data.count = remainingTime;
|
|
265
|
+
}
|
|
266
|
+
}), takeUntil(this.countdownSeconds[sectionId]?.stop$), takeUntilDestroyed(this.#destroyRef));
|
|
267
|
+
countdown$?.subscribe({ complete: () => { } });
|
|
268
|
+
}
|
|
269
|
+
refresh() {
|
|
270
|
+
this.#ref.markForCheck();
|
|
271
|
+
this.#ref.detectChanges();
|
|
272
|
+
}
|
|
273
|
+
sectionIncludesDefault(columns) {
|
|
274
|
+
return columns.some(col => col.systemDefault);
|
|
275
|
+
}
|
|
276
|
+
startTour(sectionId) {
|
|
277
|
+
const tourOptions = this.engine.selectAllFormTours().filter(step => step.sectionId === sectionId);
|
|
278
|
+
this.#tourManagerService.startTourByOption(tourOptions);
|
|
279
|
+
}
|
|
280
|
+
onSpaceKey(event, sectionId) {
|
|
281
|
+
const inputValue = event.target.value;
|
|
282
|
+
this.#store.actionsFormBuilder?.stepTitleChangeStep(sectionId, inputValue + ' ');
|
|
283
|
+
event.stopPropagation();
|
|
284
|
+
event.preventDefault();
|
|
285
|
+
}
|
|
286
|
+
addColAndOpen(col) {
|
|
287
|
+
this.addMultipleFormInput(col.sectionId, col.id);
|
|
288
|
+
if (!col.formIsOpen) {
|
|
289
|
+
this.engine.toggleMultipleInput(col.id, true);
|
|
290
|
+
}
|
|
291
|
+
this.#snackBar.open('✨Input field successfully added to the row entry form. Open the form to configure it further.', 'OK', { duration: 3000 });
|
|
292
|
+
}
|
|
293
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: FormSectionStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
294
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: FormSectionStepperComponent, isStandalone: true, selector: "lib-form-section-stepper", providers: [TFormEngine], viewQueries: [{ propertyName: "stepper", first: true, predicate: ["stepper"], descendants: true, isSignal: true }], ngImport: i0, template: "<mat-card class=\"mainCard\" appearance=\"raised\">\r\n\r\n @if (loadingForm$ | async) {\r\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\">\r\n <mat-spinner diameter=\"48\" aria-label=\"Loading form\" />\r\n </div>\r\n }\r\n <mat-stepper [style.display]=\"(loadingForm$ | async) ? 'none' : 'block'\" #stepper class=\"form-stepper\"\r\n orientation=\"vertical\" [linear]=\"!isEditable\" aria-label=\"Form sections stepper\" [animationDuration]=\"'300'\"\r\n cdkDropList #formSections=\"cdkDropList\" [cdkDropListData]=\"selectFormStepsComputed\"\r\n (cdkDropListDropped)=\"drop($event)\" (selectionChange)=\"engine.handleStepChange($event)\">\r\n\r\n @for (step of selectFormStepsComputed; track step.sectionId) {\r\n @if (step.sectionForm || getPlaceHolerForSection(step.sectionId)) {\r\n <mat-step [stepControl]=\"step.sectionForm || getPlaceHolerForSection(step.sectionId)\"\r\n [completed]=\"step.sectionIsSeen && !step.sectionIsInvalid\" [editable]=\"isEditable\"\r\n [errorMessage]=\"step.sectionFormErrorMessage||''\" [state]=\"getStepState(step,$index)\"\r\n [hasError]=\"!step.sectionForm?.valid && !!step.sectionForm?.touched\">\r\n <ng-template matStepLabel>\r\n <div cdkDrag class=\"step-label-container\" [attr.aria-label]=\"'Section ' + step.label\">\r\n <button cdkDragHandle type=\"button\" class=\"section-drag-handle\" (click)=\"$event.stopPropagation()\"\r\n matTooltip=\"Drag to reorder section\" aria-label=\"Drag to reorder section\" mat-icon-button>\r\n <mat-icon>drag_indicator</mat-icon>\r\n </button>\r\n <span class=\"step-label-text\">\r\n <input (input)=\"handleInput($event, step.sectionId)\" class=\"section-title-input\" matInput\r\n (keydown.space)=\"onSpaceKey($event, step.sectionId)\" placeholder=\"Untitled section \u2014 click to name\"\r\n [value]=\"step.label\" aria-label=\"Section title\">\r\n <mat-icon class=\"section-title-edit-hint\" aria-hidden=\"true\">edit</mat-icon>\r\n </span>\r\n @if (step.sectionIsSeen) {\r\n <mat-icon class=\"section-status-icon\" [class.error]=\"step.sectionIsInvalid\"\r\n [attr.aria-label]=\"step.sectionIsInvalid ? 'Section has errors' : 'Section completed'\">\r\n {{ step.sectionIsInvalid ? 'error' : 'check_circle' }}\r\n </mat-icon>\r\n }\r\n @if ((step)?.activeSectionHasTour && !!step.isActive) {\r\n <span class=\"tour-trigger\">\r\n <button tourAnchor=\"Form-Tour-trigger\" (click)=\"startTour(step.sectionId)\" matTooltip=\"Start section tour\"\r\n mat-icon-button aria-label=\"Start section tour\">\r\n <mat-icon>tour</mat-icon>\r\n </button>\r\n </span>\r\n }\r\n <span class=\"spacer\"></span>\r\n\r\n @if (!!inputWillBeRemovedIn(step.sectionId)) {\r\n <button\r\n (mouseover)=\"overId = step.sectionId\" (mouseout)=\"overId = null\"\r\n (click)=\"deleteSection(step.sectionId)\" color=\"warn\" mat-stroked-button class=\"countdown-button\"\r\n [attr.aria-label]=\"overId === step.sectionId ? 'Cancel section deletion' : 'Section deleting in ' + inputWillBeRemovedIn(step.sectionId) + ' seconds'\">\r\n <div class=\"delete-countdown\">\r\n <mat-progress-spinner color=\"primary\" class=\"cancelProgress\"\r\n [value]=\"((inputWillBeRemovedIn(step.sectionId)||0)/5)*100\">\r\n </mat-progress-spinner>\r\n {{ overId === step.sectionId ? 'Click to cancel' : 'Deleting in' }}\r\n {{ inputWillBeRemovedIn(step.sectionId) }}\r\n </div>\r\n </button>\r\n }\r\n\r\n @if(engine.canRefreshSection(step.sectionId)&& step.isActive){\r\n <button mat-icon-button\r\n class=\"input-sync-button\"\r\n matTooltip=\"Click to refresh this section.\"\r\n (click)=\"refreshASection(step.sectionId)\" >\r\n <mat-icon>sync</mat-icon>\r\n </button>\r\n }\r\n <button (click)=\"$event.stopPropagation()\"\r\n [matMenuTriggerData]=\"{ sectionId: step.sectionId, columns: step.columns }\" [matMenuTriggerFor]=\"sectionMenu\"\r\n mat-icon-button aria-label=\"Section options menu\">\r\n <mat-icon>more_horiz</mat-icon>\r\n </button>\r\n </div>\r\n </ng-template>\r\n\r\n @defer (on viewport; prefetch on idle) {\r\n <div class=\"step-content\">\r\n @if (!openSectionReports[step.sectionId]) {\r\n <div (cdkDropListDropped)=\"dropItems($event,step.sectionId)\" [cdkDropListData]=\"step.columns\" cdkDropList\r\n #InputList=\"cdkDropList\" class=\"row form-section\">\r\n @for (col of step.columns; track col.id) {\r\n <mat-card cdkDrag (cdkDragStarted)=\"dragging = true\" (cdkDragReleased)=\"dragging = false\"\r\n [class.inEditCol]=\"(selectInputInEditId$ | async) === col.id\"\r\n [class]=\"'box inputCard col-md-' + (dragging ? '12' : col.colSize)\" (mouseover)=\"activeInput = col.id\"\r\n (focusin)=\"activeInput = col.id\">\r\n @if (step.sectionForm) {\r\n <lib-t-form-input [editorMode]=\"true\" [tourAnchor]=\"col.id\" (valueChange)=\"engine.updateValue(col.id,$event)\"\r\n [formBuilderFunctions]=\"formBuilderFunctions\" [inputConfig]=\"col\" [formGroup]=\"step.sectionForm\"\r\n [attr.aria-label]=\"col?.label || ''\">\r\n </lib-t-form-input>\r\n }\r\n\r\n\r\n\r\n @if (col.inputConfigErrors.length > 0) {\r\n <div class=\"error\">\r\n <ul class=\"error-list\">\r\n @for (error of col.inputConfigErrors; track error.key + error.message) {\r\n <li class=\"error-item\">{{ error.message }}</li>\r\n }\r\n </ul>\r\n\r\n </div>\r\n }\r\n @if (activeInput === col.id) {\r\n <mat-card-actions>\r\n\r\n <button color=\"primary\" [matTooltip]=\"'Edit ' + col.label + ' input'\" (click)=\"editInput(col)\"\r\n mat-icon-button aria-label=\"Edit input\">\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n\r\n <button [matTooltip]=\"'Move this input to another section'\" [matMenuTriggerFor]=\"moveInput\"\r\n [matMenuTriggerData]=\"col\" mat-icon-button aria-label=\"Move input to another section\">\r\n <mat-icon>drive_file_move</mat-icon>\r\n </button>\r\n\r\n <button [matTooltip]=\"'Clone form input'\" (click)=\"cloneCopyFormInput(col.id)\" mat-icon-button\r\n aria-label=\"Clone input\">\r\n <mat-icon>file_copy</mat-icon>\r\n </button>\r\n\r\n <span class=\"spacer\"></span>\r\n\r\n\r\n\r\n @if (!!inputWillBeRemovedIn(col.id)) {\r\n <button (mouseover)=\"overId = col.id\" (mouseout)=\"overId = null\" (click)=\"removeInput(col)\" color=\"warn\"\r\n mat-stroked-button>\r\n <div class=\"delete-countdown\">\r\n <mat-progress-spinner color=\"primary\" class=\"cancelProgress\"\r\n [value]=\"((inputWillBeRemovedIn(col.id)||0)/5)*100\">\r\n </mat-progress-spinner>\r\n\r\n {{ overId === col.id ? 'Click to cancel' : 'Deleting in' }} {{ inputWillBeRemovedIn(col.id) }}\r\n </div>\r\n\r\n </button>\r\n\r\n } @else if (col.systemDefault !== true) {\r\n <button color=\"warn\" [matTooltip]=\"'Delete ' + col.label + ' input'\" (click)=\"removeInput(col)\"\r\n mat-icon-button aria-label=\"Delete input\">\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n\r\n\r\n @if (activeInput === col.id && col.element ==='multipleInput') {\r\n @if (!col.formIsOpen) {\r\n <button matTooltip=\"Open the row entry form \u2014 configure each column's input type here\"\r\n (click)=\"engine.toggleMultipleInput(col.id, true)\" mat-button>\r\n <mat-icon>table_rows</mat-icon>\r\n Row Entry Form\r\n </button>\r\n }\r\n <button \r\n [disabled]=\"col.systemDefault\"\r\n matTooltip=\"Add a new column field to this table\" (click)=\"\r\n addColAndOpen(col)\"\r\n color=\"accent\" mat-stroked-button>\r\n <mat-icon>view_column</mat-icon>\r\n Add Column\r\n </button>\r\n }\r\n @if (activeInput === col.id && col.element === 'mscoaSelection') {\r\n <button matTooltip=\"Extend SCOA Segments with additional inputs\"\r\n (click)=\"addInputToScoaSelection(col.sectionId, col.id)\" color=\"accent\" mat-flat-button>\r\n <mat-icon>add</mat-icon>\r\n Add Form Input\r\n </button>\r\n }\r\n\r\n </mat-card-actions>\r\n }\r\n </mat-card>\r\n }\r\n </div>\r\n @if (step.columns.length === 0) {\r\n <section class=\"empty-state-section\">\r\n <p class=\"empty-state-text\">This section has no fields yet.</p>\r\n <p class=\"empty-state-hint\">Add a field to start collecting information.</p>\r\n <div class=\"empty-state-actions\">\r\n <button matTooltip=\"Add a field to this section\" (click)=\"addNewInput(step.sectionId)\" color=\"primary\"\r\n mat-flat-button>\r\n <mat-icon>add</mat-icon>\r\n Add field\r\n </button>\r\n </div>\r\n </section>\r\n } @else {\r\n <div class=\"section-add-field\">\r\n <button class=\"add-field-button\" matTooltip=\"Add another field to this section\"\r\n (click)=\"addNewInput(step.sectionId)\" mat-stroked-button aria-label=\"Add field to this section\">\r\n <mat-icon>add</mat-icon>\r\n Add field\r\n </button>\r\n </div>\r\n }\r\n\r\n\r\n } @else {\r\n <lib-section-report [sectionId]=\"step.sectionId\"></lib-section-report>\r\n }\r\n <div class=\"step-actions\">\r\n @if (!$first) {\r\n <button mat-button matStepperPrevious type=\"button\" class=\"navigation-button\"\r\n [attr.aria-label]=\"'Go back to ' + getPreviousStepLabel()\">\r\n\r\n Back\r\n </button>\r\n }\r\n @if (!$last) {\r\n <button mat-flat-button matStepperNext color=\"primary\" type=\"button\" class=\"navigation-button\"\r\n matTooltip=\"Continue to next section\" [attr.aria-label]=\"'Continue to ' + getNextStepLabel()\">\r\n Next\r\n </button>\r\n }\r\n @if ($last) {\r\n <button mat-button (click)=\"stepper.reset()\" aria-label=\"Reset form\">Reset</button>\r\n }\r\n\r\n </div>\r\n </div>\r\n } @placeholder {\r\n <div class=\"step-placeholder\">\r\n <mat-spinner diameter=\"24\" aria-label=\"Loading step content\" />\r\n </div>\r\n }\r\n\r\n </mat-step>\r\n }\r\n }\r\n </mat-stepper>\r\n @if (engine.selectFormSteps().length === 0) {\r\n <section class=\"empty-state-section add-section-hint\">\r\n <p class=\"empty-state-text\">A form section groups related fields together.</p>\r\n <p class=\"empty-state-hint\">Click <strong>\"Add Section\"</strong> below to create your first section.</p>\r\n </section>\r\n }\r\n <mat-card-actions class=\"sticky-actions\">\r\n <span class=\"spacer\"></span>\r\n <button (click)=\"addSection()\" color=\"accent\" mat-flat-button aria-label=\"Add new section\">\r\n <mat-icon>add</mat-icon>\r\n Add Section\r\n </button>\r\n <span class=\"spacer\"></span>\r\n </mat-card-actions>\r\n <!-- Defer the footer toolbar until after the main form is loaded -->\r\n @defer (on idle; prefetch on viewport) {\r\n <footer><mat-toolbar class=\"submission-toolbar\" role=\"toolbar\" aria-label=\"Form submission actions\">\r\n <span class=\"submission-status\" role=\"status\">\r\n {{ getSubmissionStatus$ | async }}\r\n </span>\r\n <button mat-raised-button color=\"primary\" [disabled]=\"true\" aria-label=\"Submit form\">\r\n <span>\r\n {{ engine.formSubmissionMessage()}}\r\n </span>\r\n @if (engine.submittingForm) {\r\n <mat-spinner diameter=\"10\"></mat-spinner>\r\n }\r\n\r\n </button>\r\n </mat-toolbar>\r\n </footer>\r\n } @placeholder {\r\n <!-- Simple placeholder for the footer that maintains layout -->\r\n <footer>\r\n <div class=\"submission-toolbar-placeholder\"></div>\r\n </footer>\r\n }\r\n\r\n</mat-card>\r\n<mat-menu #sectionMenu=\"matMenu\">\r\n <ng-template matMenuContent let-sectionId=\"sectionId\" let-columns=\"columns\">\r\n <!-- <button mat-menu-item [matMenuTriggerFor]=\"sectionType\">\r\n <mat-icon> disabled_visible</mat-icon>\r\n Set visibility type</button> -->\r\n @if (sectionIncludesDefault(columns) === false) {\r\n <button (click)=\"deleteSection(sectionId, false)\" matTooltip=\"Deletes this section and all its inputs\"\r\n matTooltipPosition=\"right\" mat-menu-item>\r\n <mat-icon style=\"color: var(--mat-sys-error, #b3261e)\">delete</mat-icon>\r\n <span style=\"color: var(--mat-sys-error, #b3261e)\">Delete section</span>\r\n </button>\r\n <button (click)=\"deleteSection(sectionId, true)\" matTooltip=\"Deletes all inputs in this section\"\r\n matTooltipPosition=\"right\" mat-menu-item>\r\n <mat-icon style=\"color: var(--mat-sys-error, #b3261e)\">delete_sweep</mat-icon>\r\n <span style=\"color: var(--mat-sys-error, #b3261e)\">Delete section inputs</span>\r\n </button>\r\n }\r\n\r\n <button (click)=\"toggleSectionReports(sectionId)\" mat-menu-item>\r\n <mat-icon>leaderboard</mat-icon>\r\n {{ openSectionReports[sectionId] ? 'Close report' : 'Section report' }}</button>\r\n </ng-template>\r\n</mat-menu>\r\n<mat-menu #sectionType=\"matMenu\">\r\n <button mat-menu-item>\r\n <mat-icon>visibility</mat-icon>\r\n view only</button>\r\n <button mat-menu-item>\r\n <mat-icon>visibility_off</mat-icon>\r\n system</button>\r\n <button mat-menu-item>\r\n <mat-icon>edit</mat-icon>\r\n user edit</button>\r\n</mat-menu>\r\n<mat-menu #moveInput=\"matMenu\">\r\n <ng-template matMenuContent let-id=\"id\" let-sectionId=\"sectionId\">\r\n @for (section of ( selectFormStepsComputed); track section.sectionId) {\r\n <button [disabled]=\"section.sectionId === sectionId\" (click)=\"moveInputToSection(id,section.sectionId)\"\r\n mat-menu-item>\r\n <mat-icon>folder</mat-icon>\r\n {{section.label || 'Untitled section'}}\r\n </button>\r\n }\r\n\r\n </ng-template>\r\n</mat-menu>\r\n\r\n", styles: [".mainCard{margin:0 auto;min-height:45vh;box-shadow:var(--lib-forms-shadow-resting);max-width:768px;padding:2rem;border-radius:12px;background:var(--lib-forms-surface-container-low)}.loading-container{display:flex;justify-content:center;align-items:center;padding:1.5rem;min-height:12rem}:host .inEditCol{box-shadow:var(--mdc-elevated-card-container-elevation);border:1px solid var(--lib-forms-primary)}.inputCard{box-shadow:none}:host .cancelProgress{height:24px;width:24px}.delete-countdown{display:flex;align-items:center;gap:.25rem;padding:.5rem}:host .numbers{position:absolute;right:0}mat-vertical-stepper{margin:.5rem}.form-section{min-height:60px}.box{padding:.5rem;cursor:move;box-sizing:border-box}.cdk-drag-preview{box-sizing:border-box;border:none;border-radius:8px;box-shadow:var(--lib-forms-shadow-floating)}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.box:last-child{border:none}.form-section.cdk-drop-list-dragging .box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.step-label-container{display:flex;align-items:center;gap:.5rem;width:100%}.spacer{flex:1 1 auto}.section-drag-handle{flex:none;cursor:grab;color:var(--lib-forms-on-surface-variant);max-width:0;margin-right:-.5rem;opacity:0;overflow:hidden;transition:max-width var(--lib-forms-duration-hover) var(--lib-forms-easing),margin-right var(--lib-forms-duration-hover) var(--lib-forms-easing),opacity var(--lib-forms-duration-hover) var(--lib-forms-easing)}.section-drag-handle:active{cursor:grabbing}.step-label-container:hover .section-drag-handle,.section-drag-handle:focus-visible{max-width:3rem;margin-right:0;opacity:.7}.step-label-text{position:relative;display:flex;align-items:center;flex:1 1 auto;min-width:0}.section-title-edit-hint{flex:none;font-size:1rem;width:1rem;height:1rem;margin-left:.5rem;color:var(--lib-forms-on-surface-variant);opacity:0;transition:opacity var(--lib-forms-duration-hover) var(--lib-forms-easing)}.step-label-text:hover .section-title-edit-hint,.section-title-input:focus~.section-title-edit-hint{opacity:.5}.section-status-icon{flex:none;color:var(--sem-emerald)}.section-status-icon.error{color:var(--sem-error)}.input-sync-button{margin-right:.5rem}.input-sync-button mat-icon{color:var(--lib-forms-primary)}.section-title-input{border:none;border-bottom:1px solid transparent;background-color:transparent;font-size:.9375rem;font-weight:600;color:var(--lib-forms-on-surface);padding:.5rem 0;outline:none;width:100%;transition:border-color var(--lib-forms-duration-hover) var(--lib-forms-easing),box-shadow var(--lib-forms-duration-hover) var(--lib-forms-easing)}.section-title-input::placeholder{color:var(--lib-forms-on-surface-variant);font-weight:400;opacity:.6}.section-title-input:hover{border-bottom-color:var(--lib-forms-outline-variant)}.section-title-input:focus{border-bottom-color:var(--lib-forms-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--lib-forms-primary) 25%,transparent)}.inputElement:focus{box-shadow:0 0 0 2px color-mix(in srgb,var(--lib-forms-primary) 25%,transparent)}.headerToolbar{position:sticky;top:0;min-width:100%;background:var(--mdc-elevated-card-container-color)}::ng-deep mat-step-header .mat-step-label{width:100%}.error{color:var(--sem-error);display:flex;align-items:center}.error-list{padding-left:1.75rem;margin:.25rem 0}.error-item{color:var(--sem-error);font-size:.75rem}.empty-state-section{text-align:center;padding:1rem 1.5rem}.empty-state-text{font-size:.875rem;color:var(--lib-forms-on-surface-variant);margin:0 0 .5rem}.empty-state-hint{font-size:.8125rem;color:var(--lib-forms-on-surface-variant);margin:0 0 1rem}.empty-state-actions{margin-top:1rem}.add-section-hint{padding-top:1.5rem}.section-add-field{display:flex;justify-content:center;padding:1rem 0 .5rem}.add-field-button{border:1px dashed color-mix(in srgb,var(--lib-forms-outline) 30%,transparent);color:var(--lib-forms-on-surface-variant);transition:border-color var(--lib-forms-duration) var(--lib-forms-easing),color var(--lib-forms-duration) var(--lib-forms-easing),background var(--lib-forms-duration) var(--lib-forms-easing)}.add-field-button:hover{border-color:var(--lib-forms-primary);color:var(--lib-forms-primary);background:color-mix(in srgb,var(--lib-forms-primary) 6%,transparent)}.step-placeholder{padding:3.125rem;display:flex;justify-content:center;align-items:center;text-align:center}.step-actions{display:flex;gap:.75rem;margin-top:1.5rem;padding-top:1rem}.navigation-button{min-height:2.25rem}.sticky-actions{position:sticky;bottom:0;background:var(--mat-sys-surface-container, var(--mdc-elevated-card-container-color))}.submission-toolbar{z-index:1000;background:color-mix(in srgb,var(--lib-forms-surface) 95%,transparent);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border-top:var(--mat-divider-width) solid var(--mat-divider-color);padding:1rem 1.5rem;display:flex;justify-content:flex-end;align-items:center;gap:1rem}@media(prefers-color-scheme:dark){.submission-toolbar{background:color-mix(in srgb,var(--mat-sys-surface) 95%,transparent)}}.submission-status{font-size:.75rem;opacity:.87;display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1$1.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.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: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2.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: MatMenuModule }, { kind: "component", type: i6.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i6.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i6.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i6.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i3$2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatStepperModule }, { kind: "component", type: i4.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i4.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i4.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "aria-label", "headerPrefix", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i7.TourAnchorMatMenuDirective, selector: "[tourAnchor]", inputs: ["tourAnchor"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [i1.NgControlStatusGroup, i1.FormGroupDirective, i1$1.CdkDropList, i1$1.CdkDrag, i1$2.MatButton, i1$2.MatIconButton, i3.MatCard, i3.MatCardActions, i3$1.MatIcon, i6.MatMenuTrigger, i3$2.MatProgressSpinner, i4.MatStepperNext, i4.MatStepperPrevious, i5.MatTooltip, import('./ngx-t-forms-index-dDSobs6A.mjs').then(m => m.TFormInputComponent), import('./ngx-t-forms-section-report.component-BxOhR6C0.mjs').then(m => m.SectionReportComponent), i7.TourAnchorMatMenuDirective, AsyncPipe], () => [i1$2.MatButton, i3$2.MatProgressSpinner, i5$1.MatToolbar, AsyncPipe]] }); }
|
|
295
|
+
}
|
|
296
|
+
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "21.2.12", ngImport: i0, type: FormSectionStepperComponent, resolveDeferredDeps: () => [import('./ngx-t-forms-index-dDSobs6A.mjs').then(m => m.TFormInputComponent), import('./ngx-t-forms-section-report.component-BxOhR6C0.mjs').then(m => m.SectionReportComponent)], resolveMetadata: (TFormInputComponent, SectionReportComponent) => ({ decorators: [{
|
|
297
|
+
type: Component,
|
|
298
|
+
args: [{ selector: 'lib-form-section-stepper', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, imports: [
|
|
299
|
+
AsyncPipe,
|
|
300
|
+
ReactiveFormsModule,
|
|
301
|
+
FormsModule,
|
|
302
|
+
DragDropModule,
|
|
303
|
+
MatButtonModule,
|
|
304
|
+
MatCardModule,
|
|
305
|
+
MatIconModule,
|
|
306
|
+
MatInputModule,
|
|
307
|
+
MatMenuModule,
|
|
308
|
+
MatProgressSpinnerModule,
|
|
309
|
+
MatStepperModule,
|
|
310
|
+
MatToolbarModule,
|
|
311
|
+
MatTooltipModule,
|
|
312
|
+
TFormInputComponent,
|
|
313
|
+
SectionReportComponent,
|
|
314
|
+
...TourMatMenu,
|
|
315
|
+
], providers: [TFormEngine], template: "<mat-card class=\"mainCard\" appearance=\"raised\">\r\n\r\n @if (loadingForm$ | async) {\r\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\">\r\n <mat-spinner diameter=\"48\" aria-label=\"Loading form\" />\r\n </div>\r\n }\r\n <mat-stepper [style.display]=\"(loadingForm$ | async) ? 'none' : 'block'\" #stepper class=\"form-stepper\"\r\n orientation=\"vertical\" [linear]=\"!isEditable\" aria-label=\"Form sections stepper\" [animationDuration]=\"'300'\"\r\n cdkDropList #formSections=\"cdkDropList\" [cdkDropListData]=\"selectFormStepsComputed\"\r\n (cdkDropListDropped)=\"drop($event)\" (selectionChange)=\"engine.handleStepChange($event)\">\r\n\r\n @for (step of selectFormStepsComputed; track step.sectionId) {\r\n @if (step.sectionForm || getPlaceHolerForSection(step.sectionId)) {\r\n <mat-step [stepControl]=\"step.sectionForm || getPlaceHolerForSection(step.sectionId)\"\r\n [completed]=\"step.sectionIsSeen && !step.sectionIsInvalid\" [editable]=\"isEditable\"\r\n [errorMessage]=\"step.sectionFormErrorMessage||''\" [state]=\"getStepState(step,$index)\"\r\n [hasError]=\"!step.sectionForm?.valid && !!step.sectionForm?.touched\">\r\n <ng-template matStepLabel>\r\n <div cdkDrag class=\"step-label-container\" [attr.aria-label]=\"'Section ' + step.label\">\r\n <button cdkDragHandle type=\"button\" class=\"section-drag-handle\" (click)=\"$event.stopPropagation()\"\r\n matTooltip=\"Drag to reorder section\" aria-label=\"Drag to reorder section\" mat-icon-button>\r\n <mat-icon>drag_indicator</mat-icon>\r\n </button>\r\n <span class=\"step-label-text\">\r\n <input (input)=\"handleInput($event, step.sectionId)\" class=\"section-title-input\" matInput\r\n (keydown.space)=\"onSpaceKey($event, step.sectionId)\" placeholder=\"Untitled section \u2014 click to name\"\r\n [value]=\"step.label\" aria-label=\"Section title\">\r\n <mat-icon class=\"section-title-edit-hint\" aria-hidden=\"true\">edit</mat-icon>\r\n </span>\r\n @if (step.sectionIsSeen) {\r\n <mat-icon class=\"section-status-icon\" [class.error]=\"step.sectionIsInvalid\"\r\n [attr.aria-label]=\"step.sectionIsInvalid ? 'Section has errors' : 'Section completed'\">\r\n {{ step.sectionIsInvalid ? 'error' : 'check_circle' }}\r\n </mat-icon>\r\n }\r\n @if ((step)?.activeSectionHasTour && !!step.isActive) {\r\n <span class=\"tour-trigger\">\r\n <button tourAnchor=\"Form-Tour-trigger\" (click)=\"startTour(step.sectionId)\" matTooltip=\"Start section tour\"\r\n mat-icon-button aria-label=\"Start section tour\">\r\n <mat-icon>tour</mat-icon>\r\n </button>\r\n </span>\r\n }\r\n <span class=\"spacer\"></span>\r\n\r\n @if (!!inputWillBeRemovedIn(step.sectionId)) {\r\n <button\r\n (mouseover)=\"overId = step.sectionId\" (mouseout)=\"overId = null\"\r\n (click)=\"deleteSection(step.sectionId)\" color=\"warn\" mat-stroked-button class=\"countdown-button\"\r\n [attr.aria-label]=\"overId === step.sectionId ? 'Cancel section deletion' : 'Section deleting in ' + inputWillBeRemovedIn(step.sectionId) + ' seconds'\">\r\n <div class=\"delete-countdown\">\r\n <mat-progress-spinner color=\"primary\" class=\"cancelProgress\"\r\n [value]=\"((inputWillBeRemovedIn(step.sectionId)||0)/5)*100\">\r\n </mat-progress-spinner>\r\n {{ overId === step.sectionId ? 'Click to cancel' : 'Deleting in' }}\r\n {{ inputWillBeRemovedIn(step.sectionId) }}\r\n </div>\r\n </button>\r\n }\r\n\r\n @if(engine.canRefreshSection(step.sectionId)&& step.isActive){\r\n <button mat-icon-button\r\n class=\"input-sync-button\"\r\n matTooltip=\"Click to refresh this section.\"\r\n (click)=\"refreshASection(step.sectionId)\" >\r\n <mat-icon>sync</mat-icon>\r\n </button>\r\n }\r\n <button (click)=\"$event.stopPropagation()\"\r\n [matMenuTriggerData]=\"{ sectionId: step.sectionId, columns: step.columns }\" [matMenuTriggerFor]=\"sectionMenu\"\r\n mat-icon-button aria-label=\"Section options menu\">\r\n <mat-icon>more_horiz</mat-icon>\r\n </button>\r\n </div>\r\n </ng-template>\r\n\r\n @defer (on viewport; prefetch on idle) {\r\n <div class=\"step-content\">\r\n @if (!openSectionReports[step.sectionId]) {\r\n <div (cdkDropListDropped)=\"dropItems($event,step.sectionId)\" [cdkDropListData]=\"step.columns\" cdkDropList\r\n #InputList=\"cdkDropList\" class=\"row form-section\">\r\n @for (col of step.columns; track col.id) {\r\n <mat-card cdkDrag (cdkDragStarted)=\"dragging = true\" (cdkDragReleased)=\"dragging = false\"\r\n [class.inEditCol]=\"(selectInputInEditId$ | async) === col.id\"\r\n [class]=\"'box inputCard col-md-' + (dragging ? '12' : col.colSize)\" (mouseover)=\"activeInput = col.id\"\r\n (focusin)=\"activeInput = col.id\">\r\n @if (step.sectionForm) {\r\n <lib-t-form-input [editorMode]=\"true\" [tourAnchor]=\"col.id\" (valueChange)=\"engine.updateValue(col.id,$event)\"\r\n [formBuilderFunctions]=\"formBuilderFunctions\" [inputConfig]=\"col\" [formGroup]=\"step.sectionForm\"\r\n [attr.aria-label]=\"col?.label || ''\">\r\n </lib-t-form-input>\r\n }\r\n\r\n\r\n\r\n @if (col.inputConfigErrors.length > 0) {\r\n <div class=\"error\">\r\n <ul class=\"error-list\">\r\n @for (error of col.inputConfigErrors; track error.key + error.message) {\r\n <li class=\"error-item\">{{ error.message }}</li>\r\n }\r\n </ul>\r\n\r\n </div>\r\n }\r\n @if (activeInput === col.id) {\r\n <mat-card-actions>\r\n\r\n <button color=\"primary\" [matTooltip]=\"'Edit ' + col.label + ' input'\" (click)=\"editInput(col)\"\r\n mat-icon-button aria-label=\"Edit input\">\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n\r\n <button [matTooltip]=\"'Move this input to another section'\" [matMenuTriggerFor]=\"moveInput\"\r\n [matMenuTriggerData]=\"col\" mat-icon-button aria-label=\"Move input to another section\">\r\n <mat-icon>drive_file_move</mat-icon>\r\n </button>\r\n\r\n <button [matTooltip]=\"'Clone form input'\" (click)=\"cloneCopyFormInput(col.id)\" mat-icon-button\r\n aria-label=\"Clone input\">\r\n <mat-icon>file_copy</mat-icon>\r\n </button>\r\n\r\n <span class=\"spacer\"></span>\r\n\r\n\r\n\r\n @if (!!inputWillBeRemovedIn(col.id)) {\r\n <button (mouseover)=\"overId = col.id\" (mouseout)=\"overId = null\" (click)=\"removeInput(col)\" color=\"warn\"\r\n mat-stroked-button>\r\n <div class=\"delete-countdown\">\r\n <mat-progress-spinner color=\"primary\" class=\"cancelProgress\"\r\n [value]=\"((inputWillBeRemovedIn(col.id)||0)/5)*100\">\r\n </mat-progress-spinner>\r\n\r\n {{ overId === col.id ? 'Click to cancel' : 'Deleting in' }} {{ inputWillBeRemovedIn(col.id) }}\r\n </div>\r\n\r\n </button>\r\n\r\n } @else if (col.systemDefault !== true) {\r\n <button color=\"warn\" [matTooltip]=\"'Delete ' + col.label + ' input'\" (click)=\"removeInput(col)\"\r\n mat-icon-button aria-label=\"Delete input\">\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n\r\n\r\n @if (activeInput === col.id && col.element ==='multipleInput') {\r\n @if (!col.formIsOpen) {\r\n <button matTooltip=\"Open the row entry form \u2014 configure each column's input type here\"\r\n (click)=\"engine.toggleMultipleInput(col.id, true)\" mat-button>\r\n <mat-icon>table_rows</mat-icon>\r\n Row Entry Form\r\n </button>\r\n }\r\n <button \r\n [disabled]=\"col.systemDefault\"\r\n matTooltip=\"Add a new column field to this table\" (click)=\"\r\n addColAndOpen(col)\"\r\n color=\"accent\" mat-stroked-button>\r\n <mat-icon>view_column</mat-icon>\r\n Add Column\r\n </button>\r\n }\r\n @if (activeInput === col.id && col.element === 'mscoaSelection') {\r\n <button matTooltip=\"Extend SCOA Segments with additional inputs\"\r\n (click)=\"addInputToScoaSelection(col.sectionId, col.id)\" color=\"accent\" mat-flat-button>\r\n <mat-icon>add</mat-icon>\r\n Add Form Input\r\n </button>\r\n }\r\n\r\n </mat-card-actions>\r\n }\r\n </mat-card>\r\n }\r\n </div>\r\n @if (step.columns.length === 0) {\r\n <section class=\"empty-state-section\">\r\n <p class=\"empty-state-text\">This section has no fields yet.</p>\r\n <p class=\"empty-state-hint\">Add a field to start collecting information.</p>\r\n <div class=\"empty-state-actions\">\r\n <button matTooltip=\"Add a field to this section\" (click)=\"addNewInput(step.sectionId)\" color=\"primary\"\r\n mat-flat-button>\r\n <mat-icon>add</mat-icon>\r\n Add field\r\n </button>\r\n </div>\r\n </section>\r\n } @else {\r\n <div class=\"section-add-field\">\r\n <button class=\"add-field-button\" matTooltip=\"Add another field to this section\"\r\n (click)=\"addNewInput(step.sectionId)\" mat-stroked-button aria-label=\"Add field to this section\">\r\n <mat-icon>add</mat-icon>\r\n Add field\r\n </button>\r\n </div>\r\n }\r\n\r\n\r\n } @else {\r\n <lib-section-report [sectionId]=\"step.sectionId\"></lib-section-report>\r\n }\r\n <div class=\"step-actions\">\r\n @if (!$first) {\r\n <button mat-button matStepperPrevious type=\"button\" class=\"navigation-button\"\r\n [attr.aria-label]=\"'Go back to ' + getPreviousStepLabel()\">\r\n\r\n Back\r\n </button>\r\n }\r\n @if (!$last) {\r\n <button mat-flat-button matStepperNext color=\"primary\" type=\"button\" class=\"navigation-button\"\r\n matTooltip=\"Continue to next section\" [attr.aria-label]=\"'Continue to ' + getNextStepLabel()\">\r\n Next\r\n </button>\r\n }\r\n @if ($last) {\r\n <button mat-button (click)=\"stepper.reset()\" aria-label=\"Reset form\">Reset</button>\r\n }\r\n\r\n </div>\r\n </div>\r\n } @placeholder {\r\n <div class=\"step-placeholder\">\r\n <mat-spinner diameter=\"24\" aria-label=\"Loading step content\" />\r\n </div>\r\n }\r\n\r\n </mat-step>\r\n }\r\n }\r\n </mat-stepper>\r\n @if (engine.selectFormSteps().length === 0) {\r\n <section class=\"empty-state-section add-section-hint\">\r\n <p class=\"empty-state-text\">A form section groups related fields together.</p>\r\n <p class=\"empty-state-hint\">Click <strong>\"Add Section\"</strong> below to create your first section.</p>\r\n </section>\r\n }\r\n <mat-card-actions class=\"sticky-actions\">\r\n <span class=\"spacer\"></span>\r\n <button (click)=\"addSection()\" color=\"accent\" mat-flat-button aria-label=\"Add new section\">\r\n <mat-icon>add</mat-icon>\r\n Add Section\r\n </button>\r\n <span class=\"spacer\"></span>\r\n </mat-card-actions>\r\n <!-- Defer the footer toolbar until after the main form is loaded -->\r\n @defer (on idle; prefetch on viewport) {\r\n <footer><mat-toolbar class=\"submission-toolbar\" role=\"toolbar\" aria-label=\"Form submission actions\">\r\n <span class=\"submission-status\" role=\"status\">\r\n {{ getSubmissionStatus$ | async }}\r\n </span>\r\n <button mat-raised-button color=\"primary\" [disabled]=\"true\" aria-label=\"Submit form\">\r\n <span>\r\n {{ engine.formSubmissionMessage()}}\r\n </span>\r\n @if (engine.submittingForm) {\r\n <mat-spinner diameter=\"10\"></mat-spinner>\r\n }\r\n\r\n </button>\r\n </mat-toolbar>\r\n </footer>\r\n } @placeholder {\r\n <!-- Simple placeholder for the footer that maintains layout -->\r\n <footer>\r\n <div class=\"submission-toolbar-placeholder\"></div>\r\n </footer>\r\n }\r\n\r\n</mat-card>\r\n<mat-menu #sectionMenu=\"matMenu\">\r\n <ng-template matMenuContent let-sectionId=\"sectionId\" let-columns=\"columns\">\r\n <!-- <button mat-menu-item [matMenuTriggerFor]=\"sectionType\">\r\n <mat-icon> disabled_visible</mat-icon>\r\n Set visibility type</button> -->\r\n @if (sectionIncludesDefault(columns) === false) {\r\n <button (click)=\"deleteSection(sectionId, false)\" matTooltip=\"Deletes this section and all its inputs\"\r\n matTooltipPosition=\"right\" mat-menu-item>\r\n <mat-icon style=\"color: var(--mat-sys-error, #b3261e)\">delete</mat-icon>\r\n <span style=\"color: var(--mat-sys-error, #b3261e)\">Delete section</span>\r\n </button>\r\n <button (click)=\"deleteSection(sectionId, true)\" matTooltip=\"Deletes all inputs in this section\"\r\n matTooltipPosition=\"right\" mat-menu-item>\r\n <mat-icon style=\"color: var(--mat-sys-error, #b3261e)\">delete_sweep</mat-icon>\r\n <span style=\"color: var(--mat-sys-error, #b3261e)\">Delete section inputs</span>\r\n </button>\r\n }\r\n\r\n <button (click)=\"toggleSectionReports(sectionId)\" mat-menu-item>\r\n <mat-icon>leaderboard</mat-icon>\r\n {{ openSectionReports[sectionId] ? 'Close report' : 'Section report' }}</button>\r\n </ng-template>\r\n</mat-menu>\r\n<mat-menu #sectionType=\"matMenu\">\r\n <button mat-menu-item>\r\n <mat-icon>visibility</mat-icon>\r\n view only</button>\r\n <button mat-menu-item>\r\n <mat-icon>visibility_off</mat-icon>\r\n system</button>\r\n <button mat-menu-item>\r\n <mat-icon>edit</mat-icon>\r\n user edit</button>\r\n</mat-menu>\r\n<mat-menu #moveInput=\"matMenu\">\r\n <ng-template matMenuContent let-id=\"id\" let-sectionId=\"sectionId\">\r\n @for (section of ( selectFormStepsComputed); track section.sectionId) {\r\n <button [disabled]=\"section.sectionId === sectionId\" (click)=\"moveInputToSection(id,section.sectionId)\"\r\n mat-menu-item>\r\n <mat-icon>folder</mat-icon>\r\n {{section.label || 'Untitled section'}}\r\n </button>\r\n }\r\n\r\n </ng-template>\r\n</mat-menu>\r\n\r\n", styles: [".mainCard{margin:0 auto;min-height:45vh;box-shadow:var(--lib-forms-shadow-resting);max-width:768px;padding:2rem;border-radius:12px;background:var(--lib-forms-surface-container-low)}.loading-container{display:flex;justify-content:center;align-items:center;padding:1.5rem;min-height:12rem}:host .inEditCol{box-shadow:var(--mdc-elevated-card-container-elevation);border:1px solid var(--lib-forms-primary)}.inputCard{box-shadow:none}:host .cancelProgress{height:24px;width:24px}.delete-countdown{display:flex;align-items:center;gap:.25rem;padding:.5rem}:host .numbers{position:absolute;right:0}mat-vertical-stepper{margin:.5rem}.form-section{min-height:60px}.box{padding:.5rem;cursor:move;box-sizing:border-box}.cdk-drag-preview{box-sizing:border-box;border:none;border-radius:8px;box-shadow:var(--lib-forms-shadow-floating)}.cdk-drag-placeholder{opacity:0}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.box:last-child{border:none}.form-section.cdk-drop-list-dragging .box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.step-label-container{display:flex;align-items:center;gap:.5rem;width:100%}.spacer{flex:1 1 auto}.section-drag-handle{flex:none;cursor:grab;color:var(--lib-forms-on-surface-variant);max-width:0;margin-right:-.5rem;opacity:0;overflow:hidden;transition:max-width var(--lib-forms-duration-hover) var(--lib-forms-easing),margin-right var(--lib-forms-duration-hover) var(--lib-forms-easing),opacity var(--lib-forms-duration-hover) var(--lib-forms-easing)}.section-drag-handle:active{cursor:grabbing}.step-label-container:hover .section-drag-handle,.section-drag-handle:focus-visible{max-width:3rem;margin-right:0;opacity:.7}.step-label-text{position:relative;display:flex;align-items:center;flex:1 1 auto;min-width:0}.section-title-edit-hint{flex:none;font-size:1rem;width:1rem;height:1rem;margin-left:.5rem;color:var(--lib-forms-on-surface-variant);opacity:0;transition:opacity var(--lib-forms-duration-hover) var(--lib-forms-easing)}.step-label-text:hover .section-title-edit-hint,.section-title-input:focus~.section-title-edit-hint{opacity:.5}.section-status-icon{flex:none;color:var(--sem-emerald)}.section-status-icon.error{color:var(--sem-error)}.input-sync-button{margin-right:.5rem}.input-sync-button mat-icon{color:var(--lib-forms-primary)}.section-title-input{border:none;border-bottom:1px solid transparent;background-color:transparent;font-size:.9375rem;font-weight:600;color:var(--lib-forms-on-surface);padding:.5rem 0;outline:none;width:100%;transition:border-color var(--lib-forms-duration-hover) var(--lib-forms-easing),box-shadow var(--lib-forms-duration-hover) var(--lib-forms-easing)}.section-title-input::placeholder{color:var(--lib-forms-on-surface-variant);font-weight:400;opacity:.6}.section-title-input:hover{border-bottom-color:var(--lib-forms-outline-variant)}.section-title-input:focus{border-bottom-color:var(--lib-forms-primary);box-shadow:0 0 0 2px color-mix(in srgb,var(--lib-forms-primary) 25%,transparent)}.inputElement:focus{box-shadow:0 0 0 2px color-mix(in srgb,var(--lib-forms-primary) 25%,transparent)}.headerToolbar{position:sticky;top:0;min-width:100%;background:var(--mdc-elevated-card-container-color)}::ng-deep mat-step-header .mat-step-label{width:100%}.error{color:var(--sem-error);display:flex;align-items:center}.error-list{padding-left:1.75rem;margin:.25rem 0}.error-item{color:var(--sem-error);font-size:.75rem}.empty-state-section{text-align:center;padding:1rem 1.5rem}.empty-state-text{font-size:.875rem;color:var(--lib-forms-on-surface-variant);margin:0 0 .5rem}.empty-state-hint{font-size:.8125rem;color:var(--lib-forms-on-surface-variant);margin:0 0 1rem}.empty-state-actions{margin-top:1rem}.add-section-hint{padding-top:1.5rem}.section-add-field{display:flex;justify-content:center;padding:1rem 0 .5rem}.add-field-button{border:1px dashed color-mix(in srgb,var(--lib-forms-outline) 30%,transparent);color:var(--lib-forms-on-surface-variant);transition:border-color var(--lib-forms-duration) var(--lib-forms-easing),color var(--lib-forms-duration) var(--lib-forms-easing),background var(--lib-forms-duration) var(--lib-forms-easing)}.add-field-button:hover{border-color:var(--lib-forms-primary);color:var(--lib-forms-primary);background:color-mix(in srgb,var(--lib-forms-primary) 6%,transparent)}.step-placeholder{padding:3.125rem;display:flex;justify-content:center;align-items:center;text-align:center}.step-actions{display:flex;gap:.75rem;margin-top:1.5rem;padding-top:1rem}.navigation-button{min-height:2.25rem}.sticky-actions{position:sticky;bottom:0;background:var(--mat-sys-surface-container, var(--mdc-elevated-card-container-color))}.submission-toolbar{z-index:1000;background:color-mix(in srgb,var(--lib-forms-surface) 95%,transparent);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border-top:var(--mat-divider-width) solid var(--mat-divider-color);padding:1rem 1.5rem;display:flex;justify-content:flex-end;align-items:center;gap:1rem}@media(prefers-color-scheme:dark){.submission-toolbar{background:color-mix(in srgb,var(--mat-sys-surface) 95%,transparent)}}.submission-status{font-size:.75rem;opacity:.87;display:flex;align-items:center}\n"] }]
|
|
316
|
+
}], ctorParameters: null, propDecorators: { stepper: [{ type: i0.ViewChild, args: ['stepper', { isSignal: true }] }] } }) });
|
|
317
|
+
|
|
318
|
+
export { FormSectionStepperComponent };
|
|
319
|
+
//# sourceMappingURL=ngx-t-forms-form-section-stepper.component-Bs50-nEB.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngx-t-forms-form-section-stepper.component-Bs50-nEB.mjs","sources":["../../../projects/ngx-t-forms/src/lib/components/form-builder/elements/form-section-stepper/form-section-stepper.component.ts","../../../projects/ngx-t-forms/src/lib/components/form-builder/elements/form-section-stepper/form-section-stepper.component.html"],"sourcesContent":["import { AsyncPipe } from '@angular/common';\r\nimport {\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n Component,\r\n DestroyRef,\r\n OnDestroy,\r\n OnInit,\r\n ViewEncapsulation,\r\n inject,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { AbstractControl, ReactiveFormsModule, FormsModule } from '@angular/forms';\r\nimport { CdkDragDrop, DragDropModule } from '@angular/cdk/drag-drop';\r\nimport { StepperSelectionEvent, StepState } from '@angular/cdk/stepper';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatCardModule } from '@angular/material/card';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatMenuModule } from '@angular/material/menu';\r\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\r\nimport { MatSnackBar } from '@angular/material/snack-bar';\r\nimport { MatStepper, MatStepperModule } from '@angular/material/stepper';\r\nimport { MatToolbarModule } from '@angular/material/toolbar';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\nimport { filter, map, Observable, Subject, take, takeUntil, tap, timer } from 'rxjs';\r\nimport { TourMatMenu } from 'ngx-ui-tour-md-menu';\r\n\r\nimport {\r\n FormBuilderFunctions,\r\n FormColumnInputs,\r\n IMultipleInputCal,\r\n ITowerFormSteps,\r\n ITowerStepColumn,\r\n validateFormColumnInputs,\r\n} from 'ngx-t-forms-types';\r\n\r\nimport { TFormInputComponent } from '../../..';\r\nimport { FormsStoreService } from '../../../forms/store/forms-store.service';\r\nimport { TFormEngine } from '../../../../services/core/t-form-engine/t-form-engine';\r\nimport { getSubmissionStatusFn } from '../../../../services/core/t-form-tower-controller/functions/getSubmissionStatus';\r\nimport { TourManagerService } from '../../../../services/core/tour/tour-manager.service';\r\nimport { SectionReportComponent } from '../section-report/section-report.component';\r\n\r\ninterface CountdownEntry {\r\n count: number | null;\r\n stop$: Subject<void>;\r\n deleteInputs: boolean;\r\n}\r\n\r\n@Component({\r\n selector: 'lib-form-section-stepper',\r\n templateUrl: './form-section-stepper.component.html',\r\n styleUrl: './form-section-stepper.component.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n encapsulation: ViewEncapsulation.Emulated,\r\n imports: [\r\n AsyncPipe,\r\n ReactiveFormsModule,\r\n FormsModule,\r\n DragDropModule,\r\n MatButtonModule,\r\n MatCardModule,\r\n MatIconModule,\r\n MatInputModule,\r\n MatMenuModule,\r\n MatProgressSpinnerModule,\r\n MatStepperModule,\r\n MatToolbarModule,\r\n MatTooltipModule,\r\n TFormInputComponent,\r\n SectionReportComponent,\r\n ...TourMatMenu,\r\n ],\r\n providers: [TFormEngine],\r\n})\r\nexport class FormSectionStepperComponent\r\n implements OnInit, OnDestroy\r\n{\r\n /**\r\n * Runtime form engine, held by composition (SIGNAL_FORMS Phase 0, D-025).\r\n * Provided per-component instance; replaces the former `extends` of the tower.\r\n */\r\n protected readonly engine = inject(TFormEngine);\r\n\r\n readonly #destroyRef = inject(DestroyRef);\r\n readonly #store: FormsStoreService = inject(FormsStoreService);\r\n readonly #ref = inject(ChangeDetectorRef);\r\n readonly #snackBar = inject(MatSnackBar);\r\n readonly #tourManagerService = inject(TourManagerService);\r\n\r\n protected readonly stepper = viewChild<MatStepper>('stepper');\r\n\r\n protected readonly loadingForm$ = this.#store.selectors.selectLoadingForm$;\r\n protected readonly selectInputInEditId$ = this.#store.selectors.selectInputInEditId$;\r\n protected isEditable = true;\r\n protected activeInput: string | undefined;\r\n protected dragging = false;\r\n protected mouseOverSection: string | null = null;\r\n protected overId: string | null = null;\r\n protected openSectionReports: Record<string, boolean> = {};\r\n\r\n protected countdownSeconds: Record<string, CountdownEntry> = {};\r\n\r\n ngOnDestroy(): void {\r\n this.#store.deregisterFormChangeFn();\r\n // The per-component TFormEngine is torn down automatically by Angular when\r\n // this component is destroyed (component-provided service ngOnDestroy).\r\n }\r\n\r\n ngOnInit(): void {\r\n this.#store.registerFormChangeFn(this.engine.initialize);\r\n this.engine.registerFormInputConfigChangeFn((inputId, config) => {\r\n this.#store.actions.updateFormInputConfigFromTower({ inputId, config });\r\n });\r\n this.#store.selectors.selectFormInEdit$\r\n .pipe(\r\n take(1),\r\n filter(form => form !== null && form !== undefined),\r\n tap(form => this.engine.initialize(form.form)),\r\n takeUntilDestroyed(this.#destroyRef),\r\n )\r\n .subscribe();\r\n }\r\n\r\n /**\r\n * Handles the key down event and reverts the last form change on Ctrl+Z.\r\n * @param event The keyboard event object.\r\n */\r\n protected onKeyDown(event: KeyboardEvent): void {\r\n if (event.ctrlKey && event.key === 'z') {\r\n this.engine.revertBackHistory();\r\n }\r\n }\r\n\r\n get formBuilderFunctions(): FormBuilderFunctions {\r\n const fns: FormBuilderFunctions = {\r\n getLatestAccountTree: () => this.engine.NGX_T_FORMS_CONFIG.formBuilder.getScoaTree(),\r\n getSCOAAccount: (SCOAAccount: string) =>\r\n this.engine.NGX_T_FORMS_CONFIG.formBuilder.getSCOAAccount(SCOAAccount),\r\n multipleInputToggleForm: this.engine.toggleMultipleInput.bind(this.engine),\r\n multipleInputSaveForm: this.engine.saveMultipleInputForm.bind(this.engine),\r\n editInput: this.editInput.bind(this),\r\n deleteInput: this.formDeleteInput.bind(this),\r\n addFunction: this.addMultipleInputValueCalculationFunction.bind(this),\r\n // Pre-existing node_modules duplication (ngx-t-forms-typings ships its own @angular/cdk copy).\r\n // CdkDragDrop types are nominally distinct due to private `_changeDetectorRef`. Cast at the boundary.\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Phase-4 TODO: deduplicate @angular/cdk peer dep in typings package.\r\n reorderItems: this.reorderMultipleInputItems.bind(this) as any,\r\n multipleInputToggleLabel: this.multipleInputToggleLabel.bind(this),\r\n multipleInputEditRow: this.engine.multipleInputEditRow.bind(this.engine),\r\n multipleInputDuplicateRow: this.engine.multipleInputDuplicateRow.bind(this.engine),\r\n };\r\n return fns;\r\n }\r\n\r\n getPreviousStepLabel(): string | undefined {\r\n const stepper = this.stepper();\r\n if (stepper === undefined) return '';\r\n const currentIndex = stepper.selectedIndex;\r\n if (currentIndex > 0) {\r\n return this.engine.selectFormSteps()?.[currentIndex - 1]?.label;\r\n }\r\n return '';\r\n }\r\n\r\n getNextStepLabel(): string | undefined {\r\n const stepper = this.stepper();\r\n if (stepper === undefined) return '';\r\n const currentIndex = stepper.selectedIndex;\r\n const steps = this.engine.selectFormSteps();\r\n if (!steps) return '';\r\n if (currentIndex < steps.length - 1) {\r\n return steps[currentIndex + 1]?.label;\r\n }\r\n return '';\r\n }\r\n\r\n getStepState(step: ITowerFormSteps, index: number): StepState {\r\n const activeStep = this.stepper()?.selectedIndex === index;\r\n if (activeStep) return 'edit';\r\n if (step.sectionForm?.touched && !step.sectionForm?.valid) return 'error';\r\n if (step.sectionForm?.valid) return 'done';\r\n return 'number';\r\n }\r\n\r\n get getSubmissionStatus$(): Observable<string> {\r\n const progress = this.engine.formProgress() || 0;\r\n const steps = this.engine.selectFormSteps();\r\n return this.loadingForm$.pipe(\r\n map(loading =>\r\n getSubmissionStatusFn(this.stepper(), this.engine.mainForm, progress, steps, loading),\r\n ),\r\n );\r\n }\r\n\r\n // CDK drag-drop generics retained loose because the template's `<mat-step [stepControl]>`/\r\n // `<div cdkDropList [cdkDropListData]>` bindings pass `ITowerFormSteps[]` / `ITowerStepColumn[]`\r\n // which structurally differ from the store-action payload types (`FormSlideInterface[]` / `FormColumnInputs[]`).\r\n // The downstream store actions accept the looser `<any, any, unknown>` shape so this is type-safe at the call boundary.\r\n // Phase-4 TODO: tighten once FormBuilderFunctions.reorderItems generics are typed upstream.\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n drop = (event: CdkDragDrop<any, any, unknown>): void =>\r\n this.#store.actionsFormBuilder.handleSectionDragDrop(event);\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n dropItems = (event: CdkDragDrop<any, any, unknown>, sectionId: string): void =>\r\n this.#store.actionsFormBuilder.handleInputDragDrop(event, sectionId);\r\n formDeleteSection = (sectionId: string): void =>\r\n this.#store.actionsFormBuilder.formDeleteSection(sectionId);\r\n formDeleteSectionInputs = (sectionId: string): void =>\r\n this.#store.actionsFormBuilder.formDeleteSectionInputs(sectionId);\r\n addMultipleFormInput = (sectionId: string, multipleInputId: string): void =>\r\n this.#store.actionsFormBuilder.addMultipleFormInput(sectionId, multipleInputId);\r\n moveInputToSection = (inputId: string, targetSectionId: string): void =>\r\n this.#store.actionsFormBuilder.moveInputToSection(inputId, targetSectionId);\r\n reorderMultipleInputItems = (\r\n // Mirrors `FormBuilderFunctions.reorderItems` (now generic over the row\r\n // shape). The lib-internal store action requires symmetric container data,\r\n // so we narrow the second slot to `FormColumnInputs[]` at the boundary.\r\n event: CdkDragDrop<FormColumnInputs[], FormColumnInputs[], unknown>,\r\n multipleInputId: string,\r\n ): void => this.#store.actionsFormBuilder.reorderMultipleInputItems(event, multipleInputId);\r\n cloneCopyFormInput = (inputId: string): void =>\r\n this.#store.actionsFormBuilder.cloneCopyFormInput(inputId);\r\n\r\n multipleInputToggleLabel = (item: FormColumnInputs): void =>\r\n this.#store.actionsFormBuilder.multipleInputToggleLabel(item);\r\n editInput = (item: FormColumnInputs): void =>\r\n this.#store.actionsFormBuilder.editInput(item);\r\n addMultipleInputValueCalculationFunction = (\r\n item: IMultipleInputCal,\r\n multipleInputId: string | undefined,\r\n ): void =>\r\n this.#store.actionsFormBuilder.addMultipleInputValueCalculationFunction(item, multipleInputId);\r\n setActiveSection = ($event: StepperSelectionEvent): void =>\r\n this.setMatActiveStepper($event.selectedIndex);\r\n addInputToScoaSelection = (sectionId: string, scoaInputId: string): void =>\r\n this.#store.actionsFormBuilder.addInputToScoaSelection(sectionId, scoaInputId);\r\n addNewInput = (sectionId: string): void => this.#store.actionsFormBuilder.saveInput(sectionId);\r\n\r\n addSection = (): void => this.#store.actionsFormBuilder.handleAddSection();\r\n\r\n setMatActiveStepper = (index: number): void => {\r\n setTimeout(() => {\r\n const stepper = this.stepper();\r\n if (stepper === undefined) return;\r\n stepper.selectedIndex = index;\r\n }, 0);\r\n };\r\n\r\n handleInput = (event: Event, sectionId: string): void => {\r\n const inputValue = (event.target as HTMLInputElement).value;\r\n this.#store.actionsFormBuilder?.stepTitleChangeStep(sectionId, inputValue);\r\n event.stopPropagation();\r\n event.preventDefault();\r\n };\r\n\r\n get selectFormStepsComputed(): ITowerFormSteps[] {\r\n return this.engine.selectFormSteps().map(step => ({\r\n ...step,\r\n columns: step.columns.map(col => ({\r\n ...col,\r\n inputConfigErrors: validateFormColumnInputs(col),\r\n })),\r\n }));\r\n }\r\n\r\n stopDeletion(id: string): void {\r\n if (this.countdownSeconds[id]) {\r\n this.countdownSeconds[id]?.stop$.next();\r\n delete this.countdownSeconds[id];\r\n }\r\n }\r\n\r\n inputWillBeRemovedIn = (id: string): number | null | undefined =>\r\n this.countdownSeconds[id]?.count;\r\n\r\n removeInput(item: FormColumnInputs): void {\r\n if (this.countdownSeconds[item.id]) {\r\n this.stopDeletion(item.id);\r\n return;\r\n }\r\n\r\n this.countdownSeconds[item.id] = {\r\n count: 5,\r\n stop$: new Subject<void>(),\r\n deleteInputs: false,\r\n };\r\n\r\n const countdown$ = timer(0, 1000).pipe(\r\n tap(secondsElapsed => {\r\n const data = this.countdownSeconds[item.id];\r\n if (!data) {\r\n return;\r\n }\r\n\r\n const remainingTime = 5 - secondsElapsed;\r\n if (remainingTime <= 0) {\r\n this.formDeleteInput(item);\r\n this.stopDeletion(item.id);\r\n } else {\r\n data.count = remainingTime;\r\n }\r\n }),\r\n takeUntil(this.countdownSeconds[item.id]?.stop$!),\r\n takeUntilDestroyed(this.#destroyRef),\r\n );\r\n\r\n countdown$?.subscribe({ complete: () => {} });\r\n }\r\n\r\n deleteSection(sectionId: string | null, deleteInputs: boolean = false): void {\r\n if (!sectionId) {\r\n return;\r\n }\r\n if (this.countdownSeconds[sectionId]) {\r\n this.stopDeletion(sectionId);\r\n return;\r\n }\r\n\r\n this.countdownSeconds[sectionId] = {\r\n count: 5,\r\n stop$: new Subject<void>(),\r\n deleteInputs: deleteInputs,\r\n };\r\n\r\n const countdown$ = timer(0, 1000).pipe(\r\n tap(secondsElapsed => {\r\n const data = this.countdownSeconds[sectionId];\r\n if (!data) {\r\n return;\r\n }\r\n\r\n const remainingTime = 5 - secondsElapsed;\r\n if (remainingTime <= 0) {\r\n if (data.deleteInputs) {\r\n this.formDeleteSectionInputs(sectionId);\r\n } else {\r\n this.formDeleteSection(sectionId);\r\n }\r\n this.stopDeletion(sectionId);\r\n } else {\r\n data.count = remainingTime;\r\n }\r\n }),\r\n takeUntil(this.countdownSeconds[sectionId]?.stop$!),\r\n takeUntilDestroyed(this.#destroyRef),\r\n );\r\n\r\n countdown$?.subscribe({ complete: () => {} });\r\n }\r\n\r\n // Template binds `step.sectionForm || getPlaceHolerForSection(...)` to `<mat-step [stepControl]>`\r\n // which requires a non-undefined AbstractControl; the placeholder is always present at render time\r\n // (created by the store ahead of the @if(step.sectionForm || ...) guard). Phase-4 TODO: tighten store\r\n // contract to guarantee placeholder presence and make this non-nullable.\r\n getPlaceHolerForSection = (sectionId: string): AbstractControl =>\r\n this.#store.sectionPlaceholder[sectionId] as AbstractControl;\r\n\r\n formDeleteInput = (item: FormColumnInputs): void =>\r\n this.#store.actionsFormBuilder.formDeleteInput(item);\r\n\r\n toggleSectionReports = (sectionId: string): boolean =>\r\n (this.openSectionReports[sectionId] = !this.openSectionReports[sectionId]);\r\n\r\n refresh(): void {\r\n this.#ref.markForCheck();\r\n this.#ref.detectChanges();\r\n }\r\n\r\n sectionIncludesDefault(columns: FormColumnInputs[]): boolean {\r\n return columns.some(col => col.systemDefault);\r\n }\r\n\r\n startTour(sectionId: string): void {\r\n const tourOptions = this.engine.selectAllFormTours().filter(step => step.sectionId === sectionId);\r\n this.#tourManagerService.startTourByOption(tourOptions);\r\n }\r\n\r\n onSpaceKey(event: Event, sectionId: string): void {\r\n const inputValue = (event.target as HTMLInputElement).value;\r\n this.#store.actionsFormBuilder?.stepTitleChangeStep(sectionId, inputValue + ' ');\r\n event.stopPropagation();\r\n event.preventDefault();\r\n }\r\n\r\n refreshASection = (sectionId: string): void => {\r\n this.engine.refreshSection(sectionId)\r\n .pipe(take(1), takeUntilDestroyed(this.#destroyRef))\r\n .subscribe();\r\n };\r\n\r\n addColAndOpen(col: ITowerStepColumn): void {\r\n this.addMultipleFormInput(col.sectionId, col.id);\r\n if (!col.formIsOpen) {\r\n this.engine.toggleMultipleInput(col.id, true);\r\n }\r\n this.#snackBar.open(\r\n '✨Input field successfully added to the row entry form. Open the form to configure it further.',\r\n 'OK',\r\n { duration: 3000 },\r\n );\r\n }\r\n}\r\n","<mat-card class=\"mainCard\" appearance=\"raised\">\r\n\r\n @if (loadingForm$ | async) {\r\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\">\r\n <mat-spinner diameter=\"48\" aria-label=\"Loading form\" />\r\n </div>\r\n }\r\n <mat-stepper [style.display]=\"(loadingForm$ | async) ? 'none' : 'block'\" #stepper class=\"form-stepper\"\r\n orientation=\"vertical\" [linear]=\"!isEditable\" aria-label=\"Form sections stepper\" [animationDuration]=\"'300'\"\r\n cdkDropList #formSections=\"cdkDropList\" [cdkDropListData]=\"selectFormStepsComputed\"\r\n (cdkDropListDropped)=\"drop($event)\" (selectionChange)=\"engine.handleStepChange($event)\">\r\n\r\n @for (step of selectFormStepsComputed; track step.sectionId) {\r\n @if (step.sectionForm || getPlaceHolerForSection(step.sectionId)) {\r\n <mat-step [stepControl]=\"step.sectionForm || getPlaceHolerForSection(step.sectionId)\"\r\n [completed]=\"step.sectionIsSeen && !step.sectionIsInvalid\" [editable]=\"isEditable\"\r\n [errorMessage]=\"step.sectionFormErrorMessage||''\" [state]=\"getStepState(step,$index)\"\r\n [hasError]=\"!step.sectionForm?.valid && !!step.sectionForm?.touched\">\r\n <ng-template matStepLabel>\r\n <div cdkDrag class=\"step-label-container\" [attr.aria-label]=\"'Section ' + step.label\">\r\n <button cdkDragHandle type=\"button\" class=\"section-drag-handle\" (click)=\"$event.stopPropagation()\"\r\n matTooltip=\"Drag to reorder section\" aria-label=\"Drag to reorder section\" mat-icon-button>\r\n <mat-icon>drag_indicator</mat-icon>\r\n </button>\r\n <span class=\"step-label-text\">\r\n <input (input)=\"handleInput($event, step.sectionId)\" class=\"section-title-input\" matInput\r\n (keydown.space)=\"onSpaceKey($event, step.sectionId)\" placeholder=\"Untitled section — click to name\"\r\n [value]=\"step.label\" aria-label=\"Section title\">\r\n <mat-icon class=\"section-title-edit-hint\" aria-hidden=\"true\">edit</mat-icon>\r\n </span>\r\n @if (step.sectionIsSeen) {\r\n <mat-icon class=\"section-status-icon\" [class.error]=\"step.sectionIsInvalid\"\r\n [attr.aria-label]=\"step.sectionIsInvalid ? 'Section has errors' : 'Section completed'\">\r\n {{ step.sectionIsInvalid ? 'error' : 'check_circle' }}\r\n </mat-icon>\r\n }\r\n @if ((step)?.activeSectionHasTour && !!step.isActive) {\r\n <span class=\"tour-trigger\">\r\n <button tourAnchor=\"Form-Tour-trigger\" (click)=\"startTour(step.sectionId)\" matTooltip=\"Start section tour\"\r\n mat-icon-button aria-label=\"Start section tour\">\r\n <mat-icon>tour</mat-icon>\r\n </button>\r\n </span>\r\n }\r\n <span class=\"spacer\"></span>\r\n\r\n @if (!!inputWillBeRemovedIn(step.sectionId)) {\r\n <button\r\n (mouseover)=\"overId = step.sectionId\" (mouseout)=\"overId = null\"\r\n (click)=\"deleteSection(step.sectionId)\" color=\"warn\" mat-stroked-button class=\"countdown-button\"\r\n [attr.aria-label]=\"overId === step.sectionId ? 'Cancel section deletion' : 'Section deleting in ' + inputWillBeRemovedIn(step.sectionId) + ' seconds'\">\r\n <div class=\"delete-countdown\">\r\n <mat-progress-spinner color=\"primary\" class=\"cancelProgress\"\r\n [value]=\"((inputWillBeRemovedIn(step.sectionId)||0)/5)*100\">\r\n </mat-progress-spinner>\r\n {{ overId === step.sectionId ? 'Click to cancel' : 'Deleting in' }}\r\n {{ inputWillBeRemovedIn(step.sectionId) }}\r\n </div>\r\n </button>\r\n }\r\n\r\n @if(engine.canRefreshSection(step.sectionId)&& step.isActive){\r\n <button mat-icon-button\r\n class=\"input-sync-button\"\r\n matTooltip=\"Click to refresh this section.\"\r\n (click)=\"refreshASection(step.sectionId)\" >\r\n <mat-icon>sync</mat-icon>\r\n </button>\r\n }\r\n <button (click)=\"$event.stopPropagation()\"\r\n [matMenuTriggerData]=\"{ sectionId: step.sectionId, columns: step.columns }\" [matMenuTriggerFor]=\"sectionMenu\"\r\n mat-icon-button aria-label=\"Section options menu\">\r\n <mat-icon>more_horiz</mat-icon>\r\n </button>\r\n </div>\r\n </ng-template>\r\n\r\n @defer (on viewport; prefetch on idle) {\r\n <div class=\"step-content\">\r\n @if (!openSectionReports[step.sectionId]) {\r\n <div (cdkDropListDropped)=\"dropItems($event,step.sectionId)\" [cdkDropListData]=\"step.columns\" cdkDropList\r\n #InputList=\"cdkDropList\" class=\"row form-section\">\r\n @for (col of step.columns; track col.id) {\r\n <mat-card cdkDrag (cdkDragStarted)=\"dragging = true\" (cdkDragReleased)=\"dragging = false\"\r\n [class.inEditCol]=\"(selectInputInEditId$ | async) === col.id\"\r\n [class]=\"'box inputCard col-md-' + (dragging ? '12' : col.colSize)\" (mouseover)=\"activeInput = col.id\"\r\n (focusin)=\"activeInput = col.id\">\r\n @if (step.sectionForm) {\r\n <lib-t-form-input [editorMode]=\"true\" [tourAnchor]=\"col.id\" (valueChange)=\"engine.updateValue(col.id,$event)\"\r\n [formBuilderFunctions]=\"formBuilderFunctions\" [inputConfig]=\"col\" [formGroup]=\"step.sectionForm\"\r\n [attr.aria-label]=\"col?.label || ''\">\r\n </lib-t-form-input>\r\n }\r\n\r\n\r\n\r\n @if (col.inputConfigErrors.length > 0) {\r\n <div class=\"error\">\r\n <ul class=\"error-list\">\r\n @for (error of col.inputConfigErrors; track error.key + error.message) {\r\n <li class=\"error-item\">{{ error.message }}</li>\r\n }\r\n </ul>\r\n\r\n </div>\r\n }\r\n @if (activeInput === col.id) {\r\n <mat-card-actions>\r\n\r\n <button color=\"primary\" [matTooltip]=\"'Edit ' + col.label + ' input'\" (click)=\"editInput(col)\"\r\n mat-icon-button aria-label=\"Edit input\">\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n\r\n <button [matTooltip]=\"'Move this input to another section'\" [matMenuTriggerFor]=\"moveInput\"\r\n [matMenuTriggerData]=\"col\" mat-icon-button aria-label=\"Move input to another section\">\r\n <mat-icon>drive_file_move</mat-icon>\r\n </button>\r\n\r\n <button [matTooltip]=\"'Clone form input'\" (click)=\"cloneCopyFormInput(col.id)\" mat-icon-button\r\n aria-label=\"Clone input\">\r\n <mat-icon>file_copy</mat-icon>\r\n </button>\r\n\r\n <span class=\"spacer\"></span>\r\n\r\n\r\n\r\n @if (!!inputWillBeRemovedIn(col.id)) {\r\n <button (mouseover)=\"overId = col.id\" (mouseout)=\"overId = null\" (click)=\"removeInput(col)\" color=\"warn\"\r\n mat-stroked-button>\r\n <div class=\"delete-countdown\">\r\n <mat-progress-spinner color=\"primary\" class=\"cancelProgress\"\r\n [value]=\"((inputWillBeRemovedIn(col.id)||0)/5)*100\">\r\n </mat-progress-spinner>\r\n\r\n {{ overId === col.id ? 'Click to cancel' : 'Deleting in' }} {{ inputWillBeRemovedIn(col.id) }}\r\n </div>\r\n\r\n </button>\r\n\r\n } @else if (col.systemDefault !== true) {\r\n <button color=\"warn\" [matTooltip]=\"'Delete ' + col.label + ' input'\" (click)=\"removeInput(col)\"\r\n mat-icon-button aria-label=\"Delete input\">\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n }\r\n\r\n\r\n @if (activeInput === col.id && col.element ==='multipleInput') {\r\n @if (!col.formIsOpen) {\r\n <button matTooltip=\"Open the row entry form — configure each column's input type here\"\r\n (click)=\"engine.toggleMultipleInput(col.id, true)\" mat-button>\r\n <mat-icon>table_rows</mat-icon>\r\n Row Entry Form\r\n </button>\r\n }\r\n <button \r\n [disabled]=\"col.systemDefault\"\r\n matTooltip=\"Add a new column field to this table\" (click)=\"\r\n addColAndOpen(col)\"\r\n color=\"accent\" mat-stroked-button>\r\n <mat-icon>view_column</mat-icon>\r\n Add Column\r\n </button>\r\n }\r\n @if (activeInput === col.id && col.element === 'mscoaSelection') {\r\n <button matTooltip=\"Extend SCOA Segments with additional inputs\"\r\n (click)=\"addInputToScoaSelection(col.sectionId, col.id)\" color=\"accent\" mat-flat-button>\r\n <mat-icon>add</mat-icon>\r\n Add Form Input\r\n </button>\r\n }\r\n\r\n </mat-card-actions>\r\n }\r\n </mat-card>\r\n }\r\n </div>\r\n @if (step.columns.length === 0) {\r\n <section class=\"empty-state-section\">\r\n <p class=\"empty-state-text\">This section has no fields yet.</p>\r\n <p class=\"empty-state-hint\">Add a field to start collecting information.</p>\r\n <div class=\"empty-state-actions\">\r\n <button matTooltip=\"Add a field to this section\" (click)=\"addNewInput(step.sectionId)\" color=\"primary\"\r\n mat-flat-button>\r\n <mat-icon>add</mat-icon>\r\n Add field\r\n </button>\r\n </div>\r\n </section>\r\n } @else {\r\n <div class=\"section-add-field\">\r\n <button class=\"add-field-button\" matTooltip=\"Add another field to this section\"\r\n (click)=\"addNewInput(step.sectionId)\" mat-stroked-button aria-label=\"Add field to this section\">\r\n <mat-icon>add</mat-icon>\r\n Add field\r\n </button>\r\n </div>\r\n }\r\n\r\n\r\n } @else {\r\n <lib-section-report [sectionId]=\"step.sectionId\"></lib-section-report>\r\n }\r\n <div class=\"step-actions\">\r\n @if (!$first) {\r\n <button mat-button matStepperPrevious type=\"button\" class=\"navigation-button\"\r\n [attr.aria-label]=\"'Go back to ' + getPreviousStepLabel()\">\r\n\r\n Back\r\n </button>\r\n }\r\n @if (!$last) {\r\n <button mat-flat-button matStepperNext color=\"primary\" type=\"button\" class=\"navigation-button\"\r\n matTooltip=\"Continue to next section\" [attr.aria-label]=\"'Continue to ' + getNextStepLabel()\">\r\n Next\r\n </button>\r\n }\r\n @if ($last) {\r\n <button mat-button (click)=\"stepper.reset()\" aria-label=\"Reset form\">Reset</button>\r\n }\r\n\r\n </div>\r\n </div>\r\n } @placeholder {\r\n <div class=\"step-placeholder\">\r\n <mat-spinner diameter=\"24\" aria-label=\"Loading step content\" />\r\n </div>\r\n }\r\n\r\n </mat-step>\r\n }\r\n }\r\n </mat-stepper>\r\n @if (engine.selectFormSteps().length === 0) {\r\n <section class=\"empty-state-section add-section-hint\">\r\n <p class=\"empty-state-text\">A form section groups related fields together.</p>\r\n <p class=\"empty-state-hint\">Click <strong>\"Add Section\"</strong> below to create your first section.</p>\r\n </section>\r\n }\r\n <mat-card-actions class=\"sticky-actions\">\r\n <span class=\"spacer\"></span>\r\n <button (click)=\"addSection()\" color=\"accent\" mat-flat-button aria-label=\"Add new section\">\r\n <mat-icon>add</mat-icon>\r\n Add Section\r\n </button>\r\n <span class=\"spacer\"></span>\r\n </mat-card-actions>\r\n <!-- Defer the footer toolbar until after the main form is loaded -->\r\n @defer (on idle; prefetch on viewport) {\r\n <footer><mat-toolbar class=\"submission-toolbar\" role=\"toolbar\" aria-label=\"Form submission actions\">\r\n <span class=\"submission-status\" role=\"status\">\r\n {{ getSubmissionStatus$ | async }}\r\n </span>\r\n <button mat-raised-button color=\"primary\" [disabled]=\"true\" aria-label=\"Submit form\">\r\n <span>\r\n {{ engine.formSubmissionMessage()}}\r\n </span>\r\n @if (engine.submittingForm) {\r\n <mat-spinner diameter=\"10\"></mat-spinner>\r\n }\r\n\r\n </button>\r\n </mat-toolbar>\r\n </footer>\r\n } @placeholder {\r\n <!-- Simple placeholder for the footer that maintains layout -->\r\n <footer>\r\n <div class=\"submission-toolbar-placeholder\"></div>\r\n </footer>\r\n }\r\n\r\n</mat-card>\r\n<mat-menu #sectionMenu=\"matMenu\">\r\n <ng-template matMenuContent let-sectionId=\"sectionId\" let-columns=\"columns\">\r\n <!-- <button mat-menu-item [matMenuTriggerFor]=\"sectionType\">\r\n <mat-icon> disabled_visible</mat-icon>\r\n Set visibility type</button> -->\r\n @if (sectionIncludesDefault(columns) === false) {\r\n <button (click)=\"deleteSection(sectionId, false)\" matTooltip=\"Deletes this section and all its inputs\"\r\n matTooltipPosition=\"right\" mat-menu-item>\r\n <mat-icon style=\"color: var(--mat-sys-error, #b3261e)\">delete</mat-icon>\r\n <span style=\"color: var(--mat-sys-error, #b3261e)\">Delete section</span>\r\n </button>\r\n <button (click)=\"deleteSection(sectionId, true)\" matTooltip=\"Deletes all inputs in this section\"\r\n matTooltipPosition=\"right\" mat-menu-item>\r\n <mat-icon style=\"color: var(--mat-sys-error, #b3261e)\">delete_sweep</mat-icon>\r\n <span style=\"color: var(--mat-sys-error, #b3261e)\">Delete section inputs</span>\r\n </button>\r\n }\r\n\r\n <button (click)=\"toggleSectionReports(sectionId)\" mat-menu-item>\r\n <mat-icon>leaderboard</mat-icon>\r\n {{ openSectionReports[sectionId] ? 'Close report' : 'Section report' }}</button>\r\n </ng-template>\r\n</mat-menu>\r\n<mat-menu #sectionType=\"matMenu\">\r\n <button mat-menu-item>\r\n <mat-icon>visibility</mat-icon>\r\n view only</button>\r\n <button mat-menu-item>\r\n <mat-icon>visibility_off</mat-icon>\r\n system</button>\r\n <button mat-menu-item>\r\n <mat-icon>edit</mat-icon>\r\n user edit</button>\r\n</mat-menu>\r\n<mat-menu #moveInput=\"matMenu\">\r\n <ng-template matMenuContent let-id=\"id\" let-sectionId=\"sectionId\">\r\n @for (section of ( selectFormStepsComputed); track section.sectionId) {\r\n <button [disabled]=\"section.sectionId === sectionId\" (click)=\"moveInputToSection(id,section.sectionId)\"\r\n mat-menu-item>\r\n <mat-icon>folder</mat-icon>\r\n {{section.label || 'Untitled section'}}\r\n </button>\r\n }\r\n\r\n </ng-template>\r\n</mat-menu>\r\n\r\n"],"names":["i1","i4","i5","i8","i9","i10","i11","i2","i7"],"mappings":"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"}
|