commons-shared-web-ui 0.0.52 → 0.0.54

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.
@@ -8835,7 +8835,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
8835
8835
  type: Input
8836
8836
  }] } });
8837
8837
 
8838
- const COMPONENTS$1 = [
8838
+ const COMPONENTS$2 = [
8839
8839
  FieldSelectionComponent,
8840
8840
  FieldConfiguratorComponent,
8841
8841
  GroupNodeComponent,
@@ -8863,7 +8863,7 @@ class FormBuilderModule {
8863
8863
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormBuilderModule, decorators: [{
8864
8864
  type: NgModule,
8865
8865
  args: [{
8866
- declarations: [...COMPONENTS$1],
8866
+ declarations: [...COMPONENTS$2],
8867
8867
  imports: [
8868
8868
  CommonModule,
8869
8869
  SmartFormModule,
@@ -8981,6 +8981,8 @@ class ConfigSchemaTreeService {
8981
8981
  mandatory: visible ? field.required === true : false,
8982
8982
  lockVisibility: field.lockVisibility === true,
8983
8983
  lockMandatory: field.lockMandatory === true,
8984
+ parentName: field.optionConfig?.dependencies?.['parentDataCode'],
8985
+ visibilityLockedByParent: false,
8984
8986
  };
8985
8987
  }
8986
8988
  _isSection(field) {
@@ -9030,7 +9032,10 @@ class FieldConfigurationService {
9030
9032
  */
9031
9033
  loadSchema(schema) {
9032
9034
  const workingSchema = JSON.parse(JSON.stringify(schema));
9033
- const sections = this.tree.parseSchema(workingSchema);
9035
+ const parsed = this.tree.parseSchema(workingSchema);
9036
+ // Apply dependency rules up-front so a schema that ships with a hidden parent
9037
+ // (e.g. country off) starts with its dependents hidden + locked.
9038
+ const sections = this._applyDependencyRules(parsed);
9034
9039
  this._state.set({ sections, workingSchema });
9035
9040
  }
9036
9041
  // ── Mutations ─────────────────────────────────────────────────────────────────
@@ -9050,16 +9055,22 @@ class FieldConfigurationService {
9050
9055
  const visible = !s.visible;
9051
9056
  return this._cascadeVisibility(s, visible);
9052
9057
  });
9058
+ this._normalizeDependencies();
9053
9059
  }
9054
- /** Toggle a field's visibility. Locked fields are ignored. */
9060
+ /**
9061
+ * Toggle a field's visibility. Ignored for locked fields and for fields whose
9062
+ * dependency parent is currently hidden (their toggle is disabled in the UI).
9063
+ * Hiding a field also hides every field that depends on it (transitively).
9064
+ */
9055
9065
  toggleFieldVisible(path, fieldIndex) {
9056
9066
  this._updateFieldAtPath(path, fieldIndex, f => {
9057
- if (f.lockVisibility)
9067
+ if (f.lockVisibility || f.visibilityLockedByParent)
9058
9068
  return f;
9059
9069
  const visible = !f.visible;
9060
9070
  // "Mandatory only if visible" — drop the mandatory flag when hiding.
9061
9071
  return { ...f, visible, mandatory: visible ? f.mandatory : false };
9062
9072
  });
9073
+ this._normalizeDependencies();
9063
9074
  }
9064
9075
  /** Toggle a field's mandatory flag. Ignored when locked or hidden. */
9065
9076
  toggleFieldMandatory(path, fieldIndex) {
@@ -9107,6 +9118,75 @@ class FieldConfigurationService {
9107
9118
  };
9108
9119
  });
9109
9120
  }
9121
+ /** Re-apply field dependency rules to the current tree and commit the result. */
9122
+ _normalizeDependencies() {
9123
+ this._state.update(state => ({
9124
+ ...state,
9125
+ sections: this._applyDependencyRules(state.sections),
9126
+ }));
9127
+ }
9128
+ /**
9129
+ * Enforce field dependencies expressed via `optionConfig.dependencies.parentDataCode`.
9130
+ * A field can only be visible when its dependency parent is visible; hiding a
9131
+ * parent cascades (transitively) to every dependent field. Locked-visible fields
9132
+ * are never force-hidden.
9133
+ *
9134
+ * Returns a new tree with each field's `visible` / `mandatory` adjusted and its
9135
+ * derived `visibilityLockedByParent` flag set (drives the disabled toggle in the UI).
9136
+ */
9137
+ _applyDependencyRules(sections) {
9138
+ // 1. Gather every named field.
9139
+ const allFields = [];
9140
+ const collect = (secs) => {
9141
+ for (const s of secs) {
9142
+ allFields.push(...s.fields);
9143
+ collect(s.subsections);
9144
+ }
9145
+ };
9146
+ collect(sections);
9147
+ // 2. Resolve effective visibility to a fixed point over the parent chain.
9148
+ const effective = new Map();
9149
+ for (const f of allFields) {
9150
+ const name = f.fieldConfig.name;
9151
+ if (name)
9152
+ effective.set(name, f.visible);
9153
+ }
9154
+ let changed = true;
9155
+ let guard = 0;
9156
+ const maxIterations = allFields.length + 2;
9157
+ while (changed && guard++ < maxIterations) {
9158
+ changed = false;
9159
+ for (const f of allFields) {
9160
+ const name = f.fieldConfig.name;
9161
+ if (!name || f.lockVisibility || !f.parentName)
9162
+ continue;
9163
+ // Parent hidden (and known) → this field must be hidden.
9164
+ if (effective.get(f.parentName) === false && effective.get(name) !== false) {
9165
+ effective.set(name, false);
9166
+ changed = true;
9167
+ }
9168
+ }
9169
+ }
9170
+ // 3. Rebuild the tree applying the resolved visibility + lock flag.
9171
+ const rebuildFields = (fields) => fields.map(f => {
9172
+ const name = f.fieldConfig.name;
9173
+ const resolved = name && effective.has(name) ? effective.get(name) : f.visible;
9174
+ const newVisible = f.lockVisibility ? f.visible : resolved;
9175
+ const parentHidden = !!f.parentName && effective.get(f.parentName) === false;
9176
+ return {
9177
+ ...f,
9178
+ visible: newVisible,
9179
+ mandatory: newVisible ? f.mandatory : false,
9180
+ visibilityLockedByParent: parentHidden && !f.lockVisibility,
9181
+ };
9182
+ });
9183
+ const rebuildSections = (secs) => secs.map(s => ({
9184
+ ...s,
9185
+ fields: rebuildFields(s.fields),
9186
+ subsections: rebuildSections(s.subsections),
9187
+ }));
9188
+ return rebuildSections(sections);
9189
+ }
9110
9190
  /** Recursively set visibility on a section and all its descendants (respecting locks). */
9111
9191
  _cascadeVisibility(section, visible) {
9112
9192
  return {
@@ -9141,11 +9221,11 @@ class ConfigFieldNodeComponent {
9141
9221
  return this.translate ? this.translate(label) : label;
9142
9222
  }
9143
9223
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfigFieldNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9144
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ConfigFieldNodeComponent, isStandalone: false, selector: "lib-config-field-node", inputs: { field: "field", translate: "translate" }, outputs: { toggleVisible: "toggleVisible", toggleMandatory: "toggleMandatory" }, ngImport: i0, template: "<div\r\n class=\"ffc-field\"\r\n [class.ffc-field--hidden]=\"!field.visible\"\r\n [class.ffc-field--locked]=\"field.lockVisibility\"\r\n>\r\n <!-- Visibility indicator (eye / eye-off) -->\r\n <span class=\"ffc-field__eye\" [class.ffc-field__eye--off]=\"!field.visible\" aria-hidden=\"true\">\r\n @if (field.visible) {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z\"></path>\r\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\r\n </svg>\r\n } @else {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24\"></path>\r\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>\r\n </svg>\r\n }\r\n </span>\r\n\r\n <span class=\"ffc-field__label\" [title]=\"displayLabel\">{{ displayLabel }}</span>\r\n\r\n <!-- Mandatory control (only meaningful when visible) -->\r\n <button\r\n type=\"button\"\r\n class=\"ffc-field__mandatory\"\r\n [class.ffc-field__mandatory--disabled]=\"!field.visible || field.lockMandatory\"\r\n [disabled]=\"!field.visible || field.lockMandatory\"\r\n [attr.aria-pressed]=\"field.mandatory\"\r\n (click)=\"toggleMandatory.emit()\"\r\n >\r\n <span class=\"ffc-check\" [class.ffc-check--on]=\"field.mandatory\">\r\n <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg>\r\n </span>\r\n <span class=\"ffc-field__mandatory-text\">Mandatory</span>\r\n </button>\r\n\r\n <!-- Visibility toggle / lock -->\r\n @if (field.lockVisibility) {\r\n <span class=\"ffc-lock\" title=\"This field is always visible\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\r\n </svg>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"ffc-toggle\"\r\n [class.ffc-toggle--on]=\"field.visible\"\r\n role=\"switch\"\r\n [attr.aria-checked]=\"field.visible\"\r\n [attr.aria-label]=\"'Show ' + displayLabel\"\r\n (click)=\"toggleVisible.emit()\"\r\n >\r\n <span class=\"ffc-toggle__thumb\"></span>\r\n </button>\r\n }\r\n</div>\r\n", styles: [".ffc-toggle{position:relative;flex-shrink:0;width:var(--ffc-toggle-width, 38px);height:var(--ffc-toggle-height, 22px);padding:0;border:none;border-radius:999px;background:var(--ffc-toggle-off-bg, #cbd2d9);cursor:pointer;transition:background .18s ease}.ffc-toggle__thumb{position:absolute;top:2px;left:2px;width:calc(var(--ffc-toggle-height, 22px) - 4px);height:calc(var(--ffc-toggle-height, 22px) - 4px);border-radius:50%;background:var(--ffc-toggle-thumb, #ffffff);box-shadow:0 1px 2px #00000040;transition:left .18s ease}.ffc-toggle--on{background:var(--ffc-toggle-on-bg, #2f9e6f)}.ffc-toggle--on .ffc-toggle__thumb{left:calc(100% - (var(--ffc-toggle-height, 22px) - 2px))}.ffc-toggle:focus-visible{outline:2px solid var(--ffc-focus-ring, #2f9e6f);outline-offset:2px}.ffc-check{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-check-size, 18px);height:var(--ffc-check-size, 18px);border-radius:4px;border:2px solid var(--ffc-check-border, #c3c9d0);background:var(--ffc-check-bg, #ffffff);color:transparent;transition:background .15s ease,border-color .15s ease,color .15s ease}.ffc-check svg{opacity:0;transition:opacity .15s ease}.ffc-check--on{background:var(--ffc-check-on-bg, #d97757);border-color:var(--ffc-check-on-bg, #d97757);color:#fff}.ffc-check--on svg{opacity:1}.ffc-lock{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-toggle-width, 38px);color:var(--ffc-lock-color, #9aa2ab)}.ffc-field{display:flex;align-items:center;gap:var(--ffc-field-gap, 12px);padding:var(--ffc-field-padding, 10px 14px);border-radius:var(--ffc-field-radius, 8px);background:var(--ffc-field-bg, #ffffff);border:1px solid var(--ffc-field-border, #eef0f2);transition:background .15s,border-color .15s,opacity .15s}.ffc-field:hover:not(.ffc-field--locked){background:var(--ffc-field-hover-bg, #f8fafc)}.ffc-field--hidden .ffc-field__eye,.ffc-field--hidden .ffc-field__label,.ffc-field--hidden .ffc-field__mandatory{opacity:.55}.ffc-field--locked{background:var(--ffc-field-locked-bg, #f6f7f8)}.ffc-field__eye{display:flex;align-items:center;color:var(--ffc-eye-color, #6b7280);flex-shrink:0}.ffc-field__eye--off{color:var(--ffc-eye-off-color, #b0b6be)}.ffc-field__label{flex:1 1 auto;min-width:0;font-size:var(--ffc-field-label-size, 14px);color:var(--ffc-field-label-color, #1f2933);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ffc-field__mandatory{display:inline-flex;align-items:center;gap:7px;flex-shrink:0;padding:0;border:none;background:transparent;cursor:pointer;font:inherit}.ffc-field__mandatory--disabled{cursor:not-allowed}.ffc-field__mandatory-text{font-size:var(--ffc-mandatory-size, 13px);color:var(--ffc-mandatory-color, #52606d);white-space:nowrap}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9224
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ConfigFieldNodeComponent, isStandalone: false, selector: "lib-config-field-node", inputs: { field: "field", translate: "translate" }, outputs: { toggleVisible: "toggleVisible", toggleMandatory: "toggleMandatory" }, ngImport: i0, template: "<div\r\n class=\"ffc-field\"\r\n [class.ffc-field--hidden]=\"!field.visible\"\r\n [class.ffc-field--locked]=\"field.lockVisibility\"\r\n>\r\n <!-- Visibility indicator (eye / eye-off) -->\r\n <span class=\"ffc-field__eye\" [class.ffc-field__eye--off]=\"!field.visible\" aria-hidden=\"true\">\r\n @if (field.visible) {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z\"></path>\r\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\r\n </svg>\r\n } @else {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24\"></path>\r\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>\r\n </svg>\r\n }\r\n </span>\r\n\r\n <span class=\"ffc-field__label\" [title]=\"displayLabel\">{{ displayLabel }}</span>\r\n\r\n <!-- Mandatory control (only meaningful when visible) -->\r\n <button\r\n type=\"button\"\r\n class=\"ffc-field__mandatory\"\r\n [class.ffc-field__mandatory--disabled]=\"!field.visible || field.lockMandatory\"\r\n [disabled]=\"!field.visible || field.lockMandatory\"\r\n [attr.aria-pressed]=\"field.mandatory\"\r\n (click)=\"toggleMandatory.emit()\"\r\n >\r\n <span class=\"ffc-check\" [class.ffc-check--on]=\"field.mandatory\">\r\n <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg>\r\n </span>\r\n <span class=\"ffc-field__mandatory-text\">Mandatory</span>\r\n </button>\r\n\r\n <!-- Visibility toggle / lock -->\r\n @if (field.lockVisibility) {\r\n <span class=\"ffc-lock\" title=\"This field is always visible\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\r\n </svg>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"ffc-toggle\"\r\n [class.ffc-toggle--on]=\"field.visible\"\r\n [class.ffc-toggle--disabled]=\"field.visibilityLockedByParent\"\r\n [disabled]=\"field.visibilityLockedByParent\"\r\n role=\"switch\"\r\n [attr.aria-checked]=\"field.visible\"\r\n [attr.aria-label]=\"'Show ' + displayLabel\"\r\n [attr.title]=\"field.visibilityLockedByParent ? 'Show the field it depends on first' : null\"\r\n (click)=\"toggleVisible.emit()\"\r\n >\r\n <span class=\"ffc-toggle__thumb\"></span>\r\n </button>\r\n }\r\n</div>\r\n", styles: [".ffc-toggle{position:relative;flex-shrink:0;width:var(--ffc-toggle-width, 38px);height:var(--ffc-toggle-height, 22px);padding:0;border:none;border-radius:999px;background:var(--ffc-toggle-off-bg, #cbd2d9);cursor:pointer;transition:background .18s ease}.ffc-toggle__thumb{position:absolute;top:2px;left:2px;width:calc(var(--ffc-toggle-height, 22px) - 4px);height:calc(var(--ffc-toggle-height, 22px) - 4px);border-radius:50%;background:var(--ffc-toggle-thumb, #ffffff);box-shadow:0 1px 2px #00000040;transition:left .18s ease}.ffc-toggle--on{background:var(--ffc-toggle-on-bg, #2f9e6f)}.ffc-toggle--on .ffc-toggle__thumb{left:calc(100% - (var(--ffc-toggle-height, 22px) - 2px))}.ffc-toggle:focus-visible{outline:2px solid var(--ffc-focus-ring, #2f9e6f);outline-offset:2px}.ffc-toggle--disabled{opacity:.45;cursor:not-allowed}.ffc-check{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-check-size, 18px);height:var(--ffc-check-size, 18px);border-radius:4px;border:2px solid var(--ffc-check-border, #c3c9d0);background:var(--ffc-check-bg, #ffffff);color:transparent;transition:background .15s ease,border-color .15s ease,color .15s ease}.ffc-check svg{opacity:0;transition:opacity .15s ease}.ffc-check--on{background:var(--ffc-check-on-bg, #d97757);border-color:var(--ffc-check-on-bg, #d97757);color:#fff}.ffc-check--on svg{opacity:1}.ffc-lock{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-toggle-width, 38px);color:var(--ffc-lock-color, #9aa2ab)}.ffc-field{display:flex;align-items:center;gap:var(--ffc-field-gap, 12px);padding:var(--ffc-field-padding, 10px 14px);border-radius:var(--ffc-field-radius, 8px);background:var(--ffc-field-bg, #ffffff);border:1px solid var(--ffc-field-border, #eef0f2);transition:background .15s,border-color .15s,opacity .15s}.ffc-field:hover:not(.ffc-field--locked){background:var(--ffc-field-hover-bg, #f8fafc)}.ffc-field--hidden .ffc-field__eye,.ffc-field--hidden .ffc-field__label,.ffc-field--hidden .ffc-field__mandatory{opacity:.55}.ffc-field--locked{background:var(--ffc-field-locked-bg, #f6f7f8)}.ffc-field__eye{display:flex;align-items:center;color:var(--ffc-eye-color, #6b7280);flex-shrink:0}.ffc-field__eye--off{color:var(--ffc-eye-off-color, #b0b6be)}.ffc-field__label{flex:1 1 auto;min-width:0;font-size:var(--ffc-field-label-size, 14px);color:var(--ffc-field-label-color, #1f2933);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ffc-field__mandatory{display:inline-flex;align-items:center;gap:7px;flex-shrink:0;padding:0;border:none;background:transparent;cursor:pointer;font:inherit}.ffc-field__mandatory--disabled{cursor:not-allowed}.ffc-field__mandatory-text{font-size:var(--ffc-mandatory-size, 13px);color:var(--ffc-mandatory-color, #52606d);white-space:nowrap}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9145
9225
  }
9146
9226
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfigFieldNodeComponent, decorators: [{
9147
9227
  type: Component,
9148
- args: [{ selector: 'lib-config-field-node', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"ffc-field\"\r\n [class.ffc-field--hidden]=\"!field.visible\"\r\n [class.ffc-field--locked]=\"field.lockVisibility\"\r\n>\r\n <!-- Visibility indicator (eye / eye-off) -->\r\n <span class=\"ffc-field__eye\" [class.ffc-field__eye--off]=\"!field.visible\" aria-hidden=\"true\">\r\n @if (field.visible) {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z\"></path>\r\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\r\n </svg>\r\n } @else {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24\"></path>\r\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>\r\n </svg>\r\n }\r\n </span>\r\n\r\n <span class=\"ffc-field__label\" [title]=\"displayLabel\">{{ displayLabel }}</span>\r\n\r\n <!-- Mandatory control (only meaningful when visible) -->\r\n <button\r\n type=\"button\"\r\n class=\"ffc-field__mandatory\"\r\n [class.ffc-field__mandatory--disabled]=\"!field.visible || field.lockMandatory\"\r\n [disabled]=\"!field.visible || field.lockMandatory\"\r\n [attr.aria-pressed]=\"field.mandatory\"\r\n (click)=\"toggleMandatory.emit()\"\r\n >\r\n <span class=\"ffc-check\" [class.ffc-check--on]=\"field.mandatory\">\r\n <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg>\r\n </span>\r\n <span class=\"ffc-field__mandatory-text\">Mandatory</span>\r\n </button>\r\n\r\n <!-- Visibility toggle / lock -->\r\n @if (field.lockVisibility) {\r\n <span class=\"ffc-lock\" title=\"This field is always visible\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\r\n </svg>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"ffc-toggle\"\r\n [class.ffc-toggle--on]=\"field.visible\"\r\n role=\"switch\"\r\n [attr.aria-checked]=\"field.visible\"\r\n [attr.aria-label]=\"'Show ' + displayLabel\"\r\n (click)=\"toggleVisible.emit()\"\r\n >\r\n <span class=\"ffc-toggle__thumb\"></span>\r\n </button>\r\n }\r\n</div>\r\n", styles: [".ffc-toggle{position:relative;flex-shrink:0;width:var(--ffc-toggle-width, 38px);height:var(--ffc-toggle-height, 22px);padding:0;border:none;border-radius:999px;background:var(--ffc-toggle-off-bg, #cbd2d9);cursor:pointer;transition:background .18s ease}.ffc-toggle__thumb{position:absolute;top:2px;left:2px;width:calc(var(--ffc-toggle-height, 22px) - 4px);height:calc(var(--ffc-toggle-height, 22px) - 4px);border-radius:50%;background:var(--ffc-toggle-thumb, #ffffff);box-shadow:0 1px 2px #00000040;transition:left .18s ease}.ffc-toggle--on{background:var(--ffc-toggle-on-bg, #2f9e6f)}.ffc-toggle--on .ffc-toggle__thumb{left:calc(100% - (var(--ffc-toggle-height, 22px) - 2px))}.ffc-toggle:focus-visible{outline:2px solid var(--ffc-focus-ring, #2f9e6f);outline-offset:2px}.ffc-check{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-check-size, 18px);height:var(--ffc-check-size, 18px);border-radius:4px;border:2px solid var(--ffc-check-border, #c3c9d0);background:var(--ffc-check-bg, #ffffff);color:transparent;transition:background .15s ease,border-color .15s ease,color .15s ease}.ffc-check svg{opacity:0;transition:opacity .15s ease}.ffc-check--on{background:var(--ffc-check-on-bg, #d97757);border-color:var(--ffc-check-on-bg, #d97757);color:#fff}.ffc-check--on svg{opacity:1}.ffc-lock{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-toggle-width, 38px);color:var(--ffc-lock-color, #9aa2ab)}.ffc-field{display:flex;align-items:center;gap:var(--ffc-field-gap, 12px);padding:var(--ffc-field-padding, 10px 14px);border-radius:var(--ffc-field-radius, 8px);background:var(--ffc-field-bg, #ffffff);border:1px solid var(--ffc-field-border, #eef0f2);transition:background .15s,border-color .15s,opacity .15s}.ffc-field:hover:not(.ffc-field--locked){background:var(--ffc-field-hover-bg, #f8fafc)}.ffc-field--hidden .ffc-field__eye,.ffc-field--hidden .ffc-field__label,.ffc-field--hidden .ffc-field__mandatory{opacity:.55}.ffc-field--locked{background:var(--ffc-field-locked-bg, #f6f7f8)}.ffc-field__eye{display:flex;align-items:center;color:var(--ffc-eye-color, #6b7280);flex-shrink:0}.ffc-field__eye--off{color:var(--ffc-eye-off-color, #b0b6be)}.ffc-field__label{flex:1 1 auto;min-width:0;font-size:var(--ffc-field-label-size, 14px);color:var(--ffc-field-label-color, #1f2933);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ffc-field__mandatory{display:inline-flex;align-items:center;gap:7px;flex-shrink:0;padding:0;border:none;background:transparent;cursor:pointer;font:inherit}.ffc-field__mandatory--disabled{cursor:not-allowed}.ffc-field__mandatory-text{font-size:var(--ffc-mandatory-size, 13px);color:var(--ffc-mandatory-color, #52606d);white-space:nowrap}\n"] }]
9228
+ args: [{ selector: 'lib-config-field-node', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"ffc-field\"\r\n [class.ffc-field--hidden]=\"!field.visible\"\r\n [class.ffc-field--locked]=\"field.lockVisibility\"\r\n>\r\n <!-- Visibility indicator (eye / eye-off) -->\r\n <span class=\"ffc-field__eye\" [class.ffc-field__eye--off]=\"!field.visible\" aria-hidden=\"true\">\r\n @if (field.visible) {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z\"></path>\r\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\r\n </svg>\r\n } @else {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24\"></path>\r\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>\r\n </svg>\r\n }\r\n </span>\r\n\r\n <span class=\"ffc-field__label\" [title]=\"displayLabel\">{{ displayLabel }}</span>\r\n\r\n <!-- Mandatory control (only meaningful when visible) -->\r\n <button\r\n type=\"button\"\r\n class=\"ffc-field__mandatory\"\r\n [class.ffc-field__mandatory--disabled]=\"!field.visible || field.lockMandatory\"\r\n [disabled]=\"!field.visible || field.lockMandatory\"\r\n [attr.aria-pressed]=\"field.mandatory\"\r\n (click)=\"toggleMandatory.emit()\"\r\n >\r\n <span class=\"ffc-check\" [class.ffc-check--on]=\"field.mandatory\">\r\n <svg width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <polyline points=\"20 6 9 17 4 12\"></polyline>\r\n </svg>\r\n </span>\r\n <span class=\"ffc-field__mandatory-text\">Mandatory</span>\r\n </button>\r\n\r\n <!-- Visibility toggle / lock -->\r\n @if (field.lockVisibility) {\r\n <span class=\"ffc-lock\" title=\"This field is always visible\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\r\n </svg>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"ffc-toggle\"\r\n [class.ffc-toggle--on]=\"field.visible\"\r\n [class.ffc-toggle--disabled]=\"field.visibilityLockedByParent\"\r\n [disabled]=\"field.visibilityLockedByParent\"\r\n role=\"switch\"\r\n [attr.aria-checked]=\"field.visible\"\r\n [attr.aria-label]=\"'Show ' + displayLabel\"\r\n [attr.title]=\"field.visibilityLockedByParent ? 'Show the field it depends on first' : null\"\r\n (click)=\"toggleVisible.emit()\"\r\n >\r\n <span class=\"ffc-toggle__thumb\"></span>\r\n </button>\r\n }\r\n</div>\r\n", styles: [".ffc-toggle{position:relative;flex-shrink:0;width:var(--ffc-toggle-width, 38px);height:var(--ffc-toggle-height, 22px);padding:0;border:none;border-radius:999px;background:var(--ffc-toggle-off-bg, #cbd2d9);cursor:pointer;transition:background .18s ease}.ffc-toggle__thumb{position:absolute;top:2px;left:2px;width:calc(var(--ffc-toggle-height, 22px) - 4px);height:calc(var(--ffc-toggle-height, 22px) - 4px);border-radius:50%;background:var(--ffc-toggle-thumb, #ffffff);box-shadow:0 1px 2px #00000040;transition:left .18s ease}.ffc-toggle--on{background:var(--ffc-toggle-on-bg, #2f9e6f)}.ffc-toggle--on .ffc-toggle__thumb{left:calc(100% - (var(--ffc-toggle-height, 22px) - 2px))}.ffc-toggle:focus-visible{outline:2px solid var(--ffc-focus-ring, #2f9e6f);outline-offset:2px}.ffc-toggle--disabled{opacity:.45;cursor:not-allowed}.ffc-check{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-check-size, 18px);height:var(--ffc-check-size, 18px);border-radius:4px;border:2px solid var(--ffc-check-border, #c3c9d0);background:var(--ffc-check-bg, #ffffff);color:transparent;transition:background .15s ease,border-color .15s ease,color .15s ease}.ffc-check svg{opacity:0;transition:opacity .15s ease}.ffc-check--on{background:var(--ffc-check-on-bg, #d97757);border-color:var(--ffc-check-on-bg, #d97757);color:#fff}.ffc-check--on svg{opacity:1}.ffc-lock{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-toggle-width, 38px);color:var(--ffc-lock-color, #9aa2ab)}.ffc-field{display:flex;align-items:center;gap:var(--ffc-field-gap, 12px);padding:var(--ffc-field-padding, 10px 14px);border-radius:var(--ffc-field-radius, 8px);background:var(--ffc-field-bg, #ffffff);border:1px solid var(--ffc-field-border, #eef0f2);transition:background .15s,border-color .15s,opacity .15s}.ffc-field:hover:not(.ffc-field--locked){background:var(--ffc-field-hover-bg, #f8fafc)}.ffc-field--hidden .ffc-field__eye,.ffc-field--hidden .ffc-field__label,.ffc-field--hidden .ffc-field__mandatory{opacity:.55}.ffc-field--locked{background:var(--ffc-field-locked-bg, #f6f7f8)}.ffc-field__eye{display:flex;align-items:center;color:var(--ffc-eye-color, #6b7280);flex-shrink:0}.ffc-field__eye--off{color:var(--ffc-eye-off-color, #b0b6be)}.ffc-field__label{flex:1 1 auto;min-width:0;font-size:var(--ffc-field-label-size, 14px);color:var(--ffc-field-label-color, #1f2933);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ffc-field__mandatory{display:inline-flex;align-items:center;gap:7px;flex-shrink:0;padding:0;border:none;background:transparent;cursor:pointer;font:inherit}.ffc-field__mandatory--disabled{cursor:not-allowed}.ffc-field__mandatory-text{font-size:var(--ffc-mandatory-size, 13px);color:var(--ffc-mandatory-color, #52606d);white-space:nowrap}\n"] }]
9149
9229
  }], propDecorators: { field: [{
9150
9230
  type: Input,
9151
9231
  args: [{ required: true }]
@@ -9216,11 +9296,11 @@ class ConfigSectionNodeComponent {
9216
9296
  return index;
9217
9297
  }
9218
9298
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfigSectionNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9219
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ConfigSectionNodeComponent, isStandalone: false, selector: "lib-config-section-node", inputs: { section: "section", depth: "depth", translate: "translate" }, outputs: { toggleVisible: "toggleVisible", toggleExpanded: "toggleExpanded", fieldToggleVisible: "fieldToggleVisible", fieldToggleMandatory: "fieldToggleMandatory" }, ngImport: i0, template: "<div\r\n class=\"ffc-section\"\r\n [class.ffc-section--nested]=\"depth > 0\"\r\n [class.ffc-section--hidden]=\"hasToggle && !section.visible\"\r\n>\r\n <div class=\"ffc-section__header\">\r\n <button\r\n class=\"ffc-section__expand-btn\"\r\n type=\"button\"\r\n [attr.aria-expanded]=\"section.expanded\"\r\n (click)=\"onToggleExpanded()\"\r\n >\r\n <svg\r\n class=\"ffc-section__chevron\"\r\n [class.ffc-section__chevron--open]=\"section.expanded\"\r\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"\r\n >\r\n <polyline points=\"6 9 12 15 18 9\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n\r\n <span class=\"ffc-section__label\" [title]=\"displayLabel\">{{ displayLabel }}</span>\r\n\r\n @if (section.fields.length) {\r\n <span class=\"ffc-section__count\">{{ visibleFieldCount }}/{{ section.fields.length }} visible</span>\r\n }\r\n\r\n @if (hasToggle) {\r\n @if (section.lockVisibility) {\r\n <span class=\"ffc-lock\" title=\"This section is always visible\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\r\n </svg>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"ffc-toggle\"\r\n [class.ffc-toggle--on]=\"section.visible\"\r\n role=\"switch\"\r\n [attr.aria-checked]=\"section.visible\"\r\n [attr.aria-label]=\"'Show ' + displayLabel\"\r\n (click)=\"onToggleVisible()\"\r\n >\r\n <span class=\"ffc-toggle__thumb\"></span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n @if (section.expanded) {\r\n <div class=\"ffc-section__body\">\r\n @for (field of section.fields; track trackByIndex($index); let fi = $index) {\r\n <lib-config-field-node\r\n [field]=\"field\"\r\n [translate]=\"translate\"\r\n (toggleVisible)=\"onFieldToggleVisible(fi)\"\r\n (toggleMandatory)=\"onFieldToggleMandatory(fi)\"\r\n />\r\n }\r\n\r\n @for (sub of section.subsections; track trackByIndex($index); let si = $index) {\r\n <lib-config-section-node\r\n [section]=\"sub\"\r\n [depth]=\"depth + 1\"\r\n [translate]=\"translate\"\r\n (toggleVisible)=\"onSubToggleVisible(si, $event)\"\r\n (toggleExpanded)=\"onSubToggleExpanded(si, $event)\"\r\n (fieldToggleVisible)=\"onSubFieldToggleVisible(si, $event)\"\r\n (fieldToggleMandatory)=\"onSubFieldToggleMandatory(si, $event)\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".ffc-toggle{position:relative;flex-shrink:0;width:var(--ffc-toggle-width, 38px);height:var(--ffc-toggle-height, 22px);padding:0;border:none;border-radius:999px;background:var(--ffc-toggle-off-bg, #cbd2d9);cursor:pointer;transition:background .18s ease}.ffc-toggle__thumb{position:absolute;top:2px;left:2px;width:calc(var(--ffc-toggle-height, 22px) - 4px);height:calc(var(--ffc-toggle-height, 22px) - 4px);border-radius:50%;background:var(--ffc-toggle-thumb, #ffffff);box-shadow:0 1px 2px #00000040;transition:left .18s ease}.ffc-toggle--on{background:var(--ffc-toggle-on-bg, #2f9e6f)}.ffc-toggle--on .ffc-toggle__thumb{left:calc(100% - (var(--ffc-toggle-height, 22px) - 2px))}.ffc-toggle:focus-visible{outline:2px solid var(--ffc-focus-ring, #2f9e6f);outline-offset:2px}.ffc-check{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-check-size, 18px);height:var(--ffc-check-size, 18px);border-radius:4px;border:2px solid var(--ffc-check-border, #c3c9d0);background:var(--ffc-check-bg, #ffffff);color:transparent;transition:background .15s ease,border-color .15s ease,color .15s ease}.ffc-check svg{opacity:0;transition:opacity .15s ease}.ffc-check--on{background:var(--ffc-check-on-bg, #d97757);border-color:var(--ffc-check-on-bg, #d97757);color:#fff}.ffc-check--on svg{opacity:1}.ffc-lock{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-toggle-width, 38px);color:var(--ffc-lock-color, #9aa2ab)}.ffc-section{border:1px solid var(--ffc-section-border, #e5e7eb);border-radius:var(--ffc-section-radius, 10px);background:var(--ffc-section-bg, #ffffff);overflow:hidden}.ffc-section--nested{border-color:var(--ffc-section-nested-border, #eef0f2);background:var(--ffc-section-nested-bg, #fbfcfd)}.ffc-section--hidden .ffc-section__label,.ffc-section--hidden .ffc-section__count{opacity:.55}.ffc-section__header{display:flex;align-items:center;gap:10px;padding:var(--ffc-section-header-padding, 12px 14px);background:var(--ffc-section-header-bg, #f6f7f8);-webkit-user-select:none;user-select:none}.ffc-section--nested .ffc-section__header{background:var(--ffc-section-nested-header-bg, #f1f3f5)}.ffc-section__expand-btn{background:none;border:none;cursor:pointer;padding:2px;display:flex;color:var(--ffc-chevron-color, #6b7280);flex-shrink:0}.ffc-section__chevron{transform:rotate(-90deg);transition:transform .2s}.ffc-section__chevron--open{transform:rotate(0)}.ffc-section__label{flex:1 1 auto;min-width:0;font-size:var(--ffc-section-label-size, 14px);font-weight:600;color:var(--ffc-section-label-color, #1f2933);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ffc-section__count{flex-shrink:0;font-size:var(--ffc-count-size, 12px);color:var(--ffc-count-color, #7b8794);white-space:nowrap}.ffc-section__body{padding:var(--ffc-section-body-padding, 8px 14px 14px 32px);display:flex;flex-direction:column;gap:var(--ffc-field-row-gap, 8px)}@media(max-width:640px){.ffc-section__body{padding:8px 10px 10px 18px;gap:6px}}\n"], dependencies: [{ kind: "component", type: ConfigSectionNodeComponent, selector: "lib-config-section-node", inputs: ["section", "depth", "translate"], outputs: ["toggleVisible", "toggleExpanded", "fieldToggleVisible", "fieldToggleMandatory"] }, { kind: "component", type: ConfigFieldNodeComponent, selector: "lib-config-field-node", inputs: ["field", "translate"], outputs: ["toggleVisible", "toggleMandatory"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9299
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ConfigSectionNodeComponent, isStandalone: false, selector: "lib-config-section-node", inputs: { section: "section", depth: "depth", translate: "translate" }, outputs: { toggleVisible: "toggleVisible", toggleExpanded: "toggleExpanded", fieldToggleVisible: "fieldToggleVisible", fieldToggleMandatory: "fieldToggleMandatory" }, ngImport: i0, template: "<div\r\n class=\"ffc-section\"\r\n [class.ffc-section--nested]=\"depth > 0\"\r\n [class.ffc-section--hidden]=\"hasToggle && !section.visible\"\r\n>\r\n <div class=\"ffc-section__header\">\r\n <button\r\n class=\"ffc-section__expand-btn\"\r\n type=\"button\"\r\n [attr.aria-expanded]=\"section.expanded\"\r\n (click)=\"onToggleExpanded()\"\r\n >\r\n <svg\r\n class=\"ffc-section__chevron\"\r\n [class.ffc-section__chevron--open]=\"section.expanded\"\r\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"\r\n >\r\n <polyline points=\"6 9 12 15 18 9\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n\r\n <span class=\"ffc-section__label\" [title]=\"displayLabel\">{{ displayLabel }}</span>\r\n\r\n @if (section.fields.length) {\r\n <span class=\"ffc-section__count\">{{ visibleFieldCount }}/{{ section.fields.length }} visible</span>\r\n }\r\n\r\n @if (hasToggle) {\r\n @if (section.lockVisibility) {\r\n <span class=\"ffc-lock\" title=\"This section is always visible\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\r\n </svg>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"ffc-toggle\"\r\n [class.ffc-toggle--on]=\"section.visible\"\r\n role=\"switch\"\r\n [attr.aria-checked]=\"section.visible\"\r\n [attr.aria-label]=\"'Show ' + displayLabel\"\r\n (click)=\"onToggleVisible()\"\r\n >\r\n <span class=\"ffc-toggle__thumb\"></span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n @if (section.expanded) {\r\n <div class=\"ffc-section__body\">\r\n @for (field of section.fields; track trackByIndex($index); let fi = $index) {\r\n <lib-config-field-node\r\n [field]=\"field\"\r\n [translate]=\"translate\"\r\n (toggleVisible)=\"onFieldToggleVisible(fi)\"\r\n (toggleMandatory)=\"onFieldToggleMandatory(fi)\"\r\n />\r\n }\r\n\r\n @for (sub of section.subsections; track trackByIndex($index); let si = $index) {\r\n <lib-config-section-node\r\n [section]=\"sub\"\r\n [depth]=\"depth + 1\"\r\n [translate]=\"translate\"\r\n (toggleVisible)=\"onSubToggleVisible(si, $event)\"\r\n (toggleExpanded)=\"onSubToggleExpanded(si, $event)\"\r\n (fieldToggleVisible)=\"onSubFieldToggleVisible(si, $event)\"\r\n (fieldToggleMandatory)=\"onSubFieldToggleMandatory(si, $event)\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".ffc-toggle{position:relative;flex-shrink:0;width:var(--ffc-toggle-width, 38px);height:var(--ffc-toggle-height, 22px);padding:0;border:none;border-radius:999px;background:var(--ffc-toggle-off-bg, #cbd2d9);cursor:pointer;transition:background .18s ease}.ffc-toggle__thumb{position:absolute;top:2px;left:2px;width:calc(var(--ffc-toggle-height, 22px) - 4px);height:calc(var(--ffc-toggle-height, 22px) - 4px);border-radius:50%;background:var(--ffc-toggle-thumb, #ffffff);box-shadow:0 1px 2px #00000040;transition:left .18s ease}.ffc-toggle--on{background:var(--ffc-toggle-on-bg, #2f9e6f)}.ffc-toggle--on .ffc-toggle__thumb{left:calc(100% - (var(--ffc-toggle-height, 22px) - 2px))}.ffc-toggle:focus-visible{outline:2px solid var(--ffc-focus-ring, #2f9e6f);outline-offset:2px}.ffc-toggle--disabled{opacity:.45;cursor:not-allowed}.ffc-check{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-check-size, 18px);height:var(--ffc-check-size, 18px);border-radius:4px;border:2px solid var(--ffc-check-border, #c3c9d0);background:var(--ffc-check-bg, #ffffff);color:transparent;transition:background .15s ease,border-color .15s ease,color .15s ease}.ffc-check svg{opacity:0;transition:opacity .15s ease}.ffc-check--on{background:var(--ffc-check-on-bg, #d97757);border-color:var(--ffc-check-on-bg, #d97757);color:#fff}.ffc-check--on svg{opacity:1}.ffc-lock{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-toggle-width, 38px);color:var(--ffc-lock-color, #9aa2ab)}.ffc-section{border:1px solid var(--ffc-section-border, #e5e7eb);border-radius:var(--ffc-section-radius, 10px);background:var(--ffc-section-bg, #ffffff);overflow:hidden}.ffc-section--nested{border-color:var(--ffc-section-nested-border, #eef0f2);background:var(--ffc-section-nested-bg, #fbfcfd)}.ffc-section--hidden .ffc-section__label,.ffc-section--hidden .ffc-section__count{opacity:.55}.ffc-section__header{display:flex;align-items:center;gap:10px;padding:var(--ffc-section-header-padding, 12px 14px);background:var(--ffc-section-header-bg, #f6f7f8);-webkit-user-select:none;user-select:none}.ffc-section--nested .ffc-section__header{background:var(--ffc-section-nested-header-bg, #f1f3f5)}.ffc-section__expand-btn{background:none;border:none;cursor:pointer;padding:2px;display:flex;color:var(--ffc-chevron-color, #6b7280);flex-shrink:0}.ffc-section__chevron{transform:rotate(-90deg);transition:transform .2s}.ffc-section__chevron--open{transform:rotate(0)}.ffc-section__label{flex:1 1 auto;min-width:0;font-size:var(--ffc-section-label-size, 14px);font-weight:600;color:var(--ffc-section-label-color, #1f2933);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ffc-section__count{flex-shrink:0;font-size:var(--ffc-count-size, 12px);color:var(--ffc-count-color, #7b8794);white-space:nowrap}.ffc-section__body{padding:var(--ffc-section-body-padding, 8px 14px 14px 32px);display:flex;flex-direction:column;gap:var(--ffc-field-row-gap, 8px)}@media(max-width:640px){.ffc-section__body{padding:8px 10px 10px 18px;gap:6px}}\n"], dependencies: [{ kind: "component", type: ConfigSectionNodeComponent, selector: "lib-config-section-node", inputs: ["section", "depth", "translate"], outputs: ["toggleVisible", "toggleExpanded", "fieldToggleVisible", "fieldToggleMandatory"] }, { kind: "component", type: ConfigFieldNodeComponent, selector: "lib-config-field-node", inputs: ["field", "translate"], outputs: ["toggleVisible", "toggleMandatory"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9220
9300
  }
9221
9301
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfigSectionNodeComponent, decorators: [{
9222
9302
  type: Component,
9223
- args: [{ selector: 'lib-config-section-node', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"ffc-section\"\r\n [class.ffc-section--nested]=\"depth > 0\"\r\n [class.ffc-section--hidden]=\"hasToggle && !section.visible\"\r\n>\r\n <div class=\"ffc-section__header\">\r\n <button\r\n class=\"ffc-section__expand-btn\"\r\n type=\"button\"\r\n [attr.aria-expanded]=\"section.expanded\"\r\n (click)=\"onToggleExpanded()\"\r\n >\r\n <svg\r\n class=\"ffc-section__chevron\"\r\n [class.ffc-section__chevron--open]=\"section.expanded\"\r\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"\r\n >\r\n <polyline points=\"6 9 12 15 18 9\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n\r\n <span class=\"ffc-section__label\" [title]=\"displayLabel\">{{ displayLabel }}</span>\r\n\r\n @if (section.fields.length) {\r\n <span class=\"ffc-section__count\">{{ visibleFieldCount }}/{{ section.fields.length }} visible</span>\r\n }\r\n\r\n @if (hasToggle) {\r\n @if (section.lockVisibility) {\r\n <span class=\"ffc-lock\" title=\"This section is always visible\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\r\n </svg>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"ffc-toggle\"\r\n [class.ffc-toggle--on]=\"section.visible\"\r\n role=\"switch\"\r\n [attr.aria-checked]=\"section.visible\"\r\n [attr.aria-label]=\"'Show ' + displayLabel\"\r\n (click)=\"onToggleVisible()\"\r\n >\r\n <span class=\"ffc-toggle__thumb\"></span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n @if (section.expanded) {\r\n <div class=\"ffc-section__body\">\r\n @for (field of section.fields; track trackByIndex($index); let fi = $index) {\r\n <lib-config-field-node\r\n [field]=\"field\"\r\n [translate]=\"translate\"\r\n (toggleVisible)=\"onFieldToggleVisible(fi)\"\r\n (toggleMandatory)=\"onFieldToggleMandatory(fi)\"\r\n />\r\n }\r\n\r\n @for (sub of section.subsections; track trackByIndex($index); let si = $index) {\r\n <lib-config-section-node\r\n [section]=\"sub\"\r\n [depth]=\"depth + 1\"\r\n [translate]=\"translate\"\r\n (toggleVisible)=\"onSubToggleVisible(si, $event)\"\r\n (toggleExpanded)=\"onSubToggleExpanded(si, $event)\"\r\n (fieldToggleVisible)=\"onSubFieldToggleVisible(si, $event)\"\r\n (fieldToggleMandatory)=\"onSubFieldToggleMandatory(si, $event)\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".ffc-toggle{position:relative;flex-shrink:0;width:var(--ffc-toggle-width, 38px);height:var(--ffc-toggle-height, 22px);padding:0;border:none;border-radius:999px;background:var(--ffc-toggle-off-bg, #cbd2d9);cursor:pointer;transition:background .18s ease}.ffc-toggle__thumb{position:absolute;top:2px;left:2px;width:calc(var(--ffc-toggle-height, 22px) - 4px);height:calc(var(--ffc-toggle-height, 22px) - 4px);border-radius:50%;background:var(--ffc-toggle-thumb, #ffffff);box-shadow:0 1px 2px #00000040;transition:left .18s ease}.ffc-toggle--on{background:var(--ffc-toggle-on-bg, #2f9e6f)}.ffc-toggle--on .ffc-toggle__thumb{left:calc(100% - (var(--ffc-toggle-height, 22px) - 2px))}.ffc-toggle:focus-visible{outline:2px solid var(--ffc-focus-ring, #2f9e6f);outline-offset:2px}.ffc-check{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-check-size, 18px);height:var(--ffc-check-size, 18px);border-radius:4px;border:2px solid var(--ffc-check-border, #c3c9d0);background:var(--ffc-check-bg, #ffffff);color:transparent;transition:background .15s ease,border-color .15s ease,color .15s ease}.ffc-check svg{opacity:0;transition:opacity .15s ease}.ffc-check--on{background:var(--ffc-check-on-bg, #d97757);border-color:var(--ffc-check-on-bg, #d97757);color:#fff}.ffc-check--on svg{opacity:1}.ffc-lock{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-toggle-width, 38px);color:var(--ffc-lock-color, #9aa2ab)}.ffc-section{border:1px solid var(--ffc-section-border, #e5e7eb);border-radius:var(--ffc-section-radius, 10px);background:var(--ffc-section-bg, #ffffff);overflow:hidden}.ffc-section--nested{border-color:var(--ffc-section-nested-border, #eef0f2);background:var(--ffc-section-nested-bg, #fbfcfd)}.ffc-section--hidden .ffc-section__label,.ffc-section--hidden .ffc-section__count{opacity:.55}.ffc-section__header{display:flex;align-items:center;gap:10px;padding:var(--ffc-section-header-padding, 12px 14px);background:var(--ffc-section-header-bg, #f6f7f8);-webkit-user-select:none;user-select:none}.ffc-section--nested .ffc-section__header{background:var(--ffc-section-nested-header-bg, #f1f3f5)}.ffc-section__expand-btn{background:none;border:none;cursor:pointer;padding:2px;display:flex;color:var(--ffc-chevron-color, #6b7280);flex-shrink:0}.ffc-section__chevron{transform:rotate(-90deg);transition:transform .2s}.ffc-section__chevron--open{transform:rotate(0)}.ffc-section__label{flex:1 1 auto;min-width:0;font-size:var(--ffc-section-label-size, 14px);font-weight:600;color:var(--ffc-section-label-color, #1f2933);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ffc-section__count{flex-shrink:0;font-size:var(--ffc-count-size, 12px);color:var(--ffc-count-color, #7b8794);white-space:nowrap}.ffc-section__body{padding:var(--ffc-section-body-padding, 8px 14px 14px 32px);display:flex;flex-direction:column;gap:var(--ffc-field-row-gap, 8px)}@media(max-width:640px){.ffc-section__body{padding:8px 10px 10px 18px;gap:6px}}\n"] }]
9303
+ args: [{ selector: 'lib-config-section-node', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"ffc-section\"\r\n [class.ffc-section--nested]=\"depth > 0\"\r\n [class.ffc-section--hidden]=\"hasToggle && !section.visible\"\r\n>\r\n <div class=\"ffc-section__header\">\r\n <button\r\n class=\"ffc-section__expand-btn\"\r\n type=\"button\"\r\n [attr.aria-expanded]=\"section.expanded\"\r\n (click)=\"onToggleExpanded()\"\r\n >\r\n <svg\r\n class=\"ffc-section__chevron\"\r\n [class.ffc-section__chevron--open]=\"section.expanded\"\r\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"\r\n >\r\n <polyline points=\"6 9 12 15 18 9\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n\r\n <span class=\"ffc-section__label\" [title]=\"displayLabel\">{{ displayLabel }}</span>\r\n\r\n @if (section.fields.length) {\r\n <span class=\"ffc-section__count\">{{ visibleFieldCount }}/{{ section.fields.length }} visible</span>\r\n }\r\n\r\n @if (hasToggle) {\r\n @if (section.lockVisibility) {\r\n <span class=\"ffc-lock\" title=\"This section is always visible\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\r\n </svg>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"ffc-toggle\"\r\n [class.ffc-toggle--on]=\"section.visible\"\r\n role=\"switch\"\r\n [attr.aria-checked]=\"section.visible\"\r\n [attr.aria-label]=\"'Show ' + displayLabel\"\r\n (click)=\"onToggleVisible()\"\r\n >\r\n <span class=\"ffc-toggle__thumb\"></span>\r\n </button>\r\n }\r\n }\r\n </div>\r\n\r\n @if (section.expanded) {\r\n <div class=\"ffc-section__body\">\r\n @for (field of section.fields; track trackByIndex($index); let fi = $index) {\r\n <lib-config-field-node\r\n [field]=\"field\"\r\n [translate]=\"translate\"\r\n (toggleVisible)=\"onFieldToggleVisible(fi)\"\r\n (toggleMandatory)=\"onFieldToggleMandatory(fi)\"\r\n />\r\n }\r\n\r\n @for (sub of section.subsections; track trackByIndex($index); let si = $index) {\r\n <lib-config-section-node\r\n [section]=\"sub\"\r\n [depth]=\"depth + 1\"\r\n [translate]=\"translate\"\r\n (toggleVisible)=\"onSubToggleVisible(si, $event)\"\r\n (toggleExpanded)=\"onSubToggleExpanded(si, $event)\"\r\n (fieldToggleVisible)=\"onSubFieldToggleVisible(si, $event)\"\r\n (fieldToggleMandatory)=\"onSubFieldToggleMandatory(si, $event)\"\r\n />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".ffc-toggle{position:relative;flex-shrink:0;width:var(--ffc-toggle-width, 38px);height:var(--ffc-toggle-height, 22px);padding:0;border:none;border-radius:999px;background:var(--ffc-toggle-off-bg, #cbd2d9);cursor:pointer;transition:background .18s ease}.ffc-toggle__thumb{position:absolute;top:2px;left:2px;width:calc(var(--ffc-toggle-height, 22px) - 4px);height:calc(var(--ffc-toggle-height, 22px) - 4px);border-radius:50%;background:var(--ffc-toggle-thumb, #ffffff);box-shadow:0 1px 2px #00000040;transition:left .18s ease}.ffc-toggle--on{background:var(--ffc-toggle-on-bg, #2f9e6f)}.ffc-toggle--on .ffc-toggle__thumb{left:calc(100% - (var(--ffc-toggle-height, 22px) - 2px))}.ffc-toggle:focus-visible{outline:2px solid var(--ffc-focus-ring, #2f9e6f);outline-offset:2px}.ffc-toggle--disabled{opacity:.45;cursor:not-allowed}.ffc-check{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-check-size, 18px);height:var(--ffc-check-size, 18px);border-radius:4px;border:2px solid var(--ffc-check-border, #c3c9d0);background:var(--ffc-check-bg, #ffffff);color:transparent;transition:background .15s ease,border-color .15s ease,color .15s ease}.ffc-check svg{opacity:0;transition:opacity .15s ease}.ffc-check--on{background:var(--ffc-check-on-bg, #d97757);border-color:var(--ffc-check-on-bg, #d97757);color:#fff}.ffc-check--on svg{opacity:1}.ffc-lock{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--ffc-toggle-width, 38px);color:var(--ffc-lock-color, #9aa2ab)}.ffc-section{border:1px solid var(--ffc-section-border, #e5e7eb);border-radius:var(--ffc-section-radius, 10px);background:var(--ffc-section-bg, #ffffff);overflow:hidden}.ffc-section--nested{border-color:var(--ffc-section-nested-border, #eef0f2);background:var(--ffc-section-nested-bg, #fbfcfd)}.ffc-section--hidden .ffc-section__label,.ffc-section--hidden .ffc-section__count{opacity:.55}.ffc-section__header{display:flex;align-items:center;gap:10px;padding:var(--ffc-section-header-padding, 12px 14px);background:var(--ffc-section-header-bg, #f6f7f8);-webkit-user-select:none;user-select:none}.ffc-section--nested .ffc-section__header{background:var(--ffc-section-nested-header-bg, #f1f3f5)}.ffc-section__expand-btn{background:none;border:none;cursor:pointer;padding:2px;display:flex;color:var(--ffc-chevron-color, #6b7280);flex-shrink:0}.ffc-section__chevron{transform:rotate(-90deg);transition:transform .2s}.ffc-section__chevron--open{transform:rotate(0)}.ffc-section__label{flex:1 1 auto;min-width:0;font-size:var(--ffc-section-label-size, 14px);font-weight:600;color:var(--ffc-section-label-color, #1f2933);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ffc-section__count{flex-shrink:0;font-size:var(--ffc-count-size, 12px);color:var(--ffc-count-color, #7b8794);white-space:nowrap}.ffc-section__body{padding:var(--ffc-section-body-padding, 8px 14px 14px 32px);display:flex;flex-direction:column;gap:var(--ffc-field-row-gap, 8px)}@media(max-width:640px){.ffc-section__body{padding:8px 10px 10px 18px;gap:6px}}\n"] }]
9224
9304
  }], propDecorators: { section: [{
9225
9305
  type: Input,
9226
9306
  args: [{ required: true }]
@@ -9314,7 +9394,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
9314
9394
  type: Input
9315
9395
  }] } });
9316
9396
 
9317
- const COMPONENTS = [
9397
+ const COMPONENTS$1 = [
9318
9398
  FormFieldConfigurationComponent,
9319
9399
  ConfigSectionNodeComponent,
9320
9400
  ConfigFieldNodeComponent,
@@ -9329,7 +9409,7 @@ class FormFieldConfigurationModule {
9329
9409
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormFieldConfigurationModule, decorators: [{
9330
9410
  type: NgModule,
9331
9411
  args: [{
9332
- declarations: [...COMPONENTS],
9412
+ declarations: [...COMPONENTS$1],
9333
9413
  imports: [
9334
9414
  CommonModule,
9335
9415
  ],
@@ -9339,6 +9419,186 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
9339
9419
  }]
9340
9420
  }] });
9341
9421
 
9422
+ /**
9423
+ * Signal-based store for the table-column-configuration component.
9424
+ * Owns the column list and the visibility toggle logic.
9425
+ * Provided at the component level (one store instance per configurator).
9426
+ */
9427
+ class TableColumnConfigurationService {
9428
+ _state = signal({
9429
+ columns: [],
9430
+ workingConfig: null,
9431
+ }, ...(ngDevMode ? [{ debugName: "_state" }] : []));
9432
+ columns = computed(() => this._state().columns, ...(ngDevMode ? [{ debugName: "columns" }] : []));
9433
+ // ── Load ──────────────────────────────────────────────────────────────────
9434
+ /**
9435
+ * Initialise from an input table config. The config is deep-cloned so the
9436
+ * caller's object is never mutated; the nodes reference the clone.
9437
+ */
9438
+ loadConfig(config) {
9439
+ const workingConfig = JSON.parse(JSON.stringify(config));
9440
+ const columns = (workingConfig.columns ?? []).map(col => this._buildColumn(col));
9441
+ this._state.set({ columns, workingConfig });
9442
+ }
9443
+ // ── Mutations ─────────────────────────────────────────────────────────────
9444
+ /** Toggle a column's visibility. Locked columns are ignored. */
9445
+ toggleColumnVisible(index) {
9446
+ this._state.update(state => ({
9447
+ ...state,
9448
+ columns: state.columns.map((c, i) => i === index && !c.lockVisibility ? { ...c, visible: !c.visible } : c),
9449
+ }));
9450
+ }
9451
+ // ── Output ────────────────────────────────────────────────────────────────
9452
+ /**
9453
+ * Produce the updated config. Writes the current node state onto the working
9454
+ * clone and returns a fresh deep clone (safe to hand to the host / persist).
9455
+ * Returns null if no config has been loaded.
9456
+ */
9457
+ buildUpdatedConfig() {
9458
+ const { columns, workingConfig } = this._state();
9459
+ if (!workingConfig)
9460
+ return null;
9461
+ for (const node of columns) {
9462
+ node.column.isEnabled = node.visible;
9463
+ node.column.visible = node.visible; // backward compatibility
9464
+ }
9465
+ return JSON.parse(JSON.stringify(workingConfig));
9466
+ }
9467
+ // ── Private helpers ─────────────────────────────────────────────────────────
9468
+ _buildColumn(column) {
9469
+ const visible = column.isEnabled ?? column.visible ?? true;
9470
+ return {
9471
+ column,
9472
+ label: column.label || column.key || 'Column',
9473
+ visible,
9474
+ lockVisibility: column.lockVisibility === true,
9475
+ };
9476
+ }
9477
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableColumnConfigurationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
9478
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableColumnConfigurationService });
9479
+ }
9480
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableColumnConfigurationService, decorators: [{
9481
+ type: Injectable
9482
+ }] });
9483
+
9484
+ /**
9485
+ * A single column row inside the table-column-configuration list.
9486
+ * Shows a visibility indicator + column name on the left and a visibility
9487
+ * toggle (or a lock, when the column is locked visible) on the right.
9488
+ */
9489
+ class ConfigColumnNodeComponent {
9490
+ column;
9491
+ /** Optional label translator (e.g. an ngx-translate instant fn). */
9492
+ translate;
9493
+ toggleVisible = new EventEmitter();
9494
+ get displayLabel() {
9495
+ const label = this.column.label;
9496
+ return this.translate ? this.translate(label) : label;
9497
+ }
9498
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfigColumnNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9499
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ConfigColumnNodeComponent, isStandalone: false, selector: "lib-config-column-node", inputs: { column: "column", translate: "translate" }, outputs: { toggleVisible: "toggleVisible" }, ngImport: i0, template: "<div\r\n class=\"tcc-col\"\r\n [class.tcc-col--hidden]=\"!column.visible\"\r\n [class.tcc-col--locked]=\"column.lockVisibility\"\r\n>\r\n <!-- Visibility indicator (eye / eye-off) -->\r\n <span class=\"tcc-col__eye\" [class.tcc-col__eye--off]=\"!column.visible\" aria-hidden=\"true\">\r\n @if (column.visible) {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z\"></path>\r\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\r\n </svg>\r\n } @else {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24\"></path>\r\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>\r\n </svg>\r\n }\r\n </span>\r\n\r\n <span class=\"tcc-col__label\" [title]=\"displayLabel\">{{ displayLabel }}</span>\r\n\r\n <!-- Visibility toggle / lock -->\r\n @if (column.lockVisibility) {\r\n <span class=\"tcc-lock\" title=\"This column is always visible\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\r\n </svg>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"tcc-toggle\"\r\n [class.tcc-toggle--on]=\"column.visible\"\r\n role=\"switch\"\r\n [attr.aria-checked]=\"column.visible\"\r\n [attr.aria-label]=\"'Show ' + displayLabel\"\r\n (click)=\"toggleVisible.emit()\"\r\n >\r\n <span class=\"tcc-toggle__thumb\"></span>\r\n </button>\r\n }\r\n</div>\r\n", styles: [".tcc-toggle{position:relative;flex-shrink:0;width:var(--tcc-toggle-width, 38px);height:var(--tcc-toggle-height, 22px);padding:0;border:none;border-radius:999px;background:var(--tcc-toggle-off-bg, #cbd2d9);cursor:pointer;transition:background .18s ease}.tcc-toggle__thumb{position:absolute;top:2px;left:2px;width:calc(var(--tcc-toggle-height, 22px) - 4px);height:calc(var(--tcc-toggle-height, 22px) - 4px);border-radius:50%;background:var(--tcc-toggle-thumb, #ffffff);box-shadow:0 1px 2px #00000040;transition:left .18s ease}.tcc-toggle--on{background:var(--tcc-toggle-on-bg, #2f9e6f)}.tcc-toggle--on .tcc-toggle__thumb{left:calc(100% - (var(--tcc-toggle-height, 22px) - 2px))}.tcc-toggle:focus-visible{outline:2px solid var(--tcc-focus-ring, #2f9e6f);outline-offset:2px}.tcc-lock{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--tcc-toggle-width, 38px);color:var(--tcc-lock-color, #9aa2ab)}.tcc-col{display:flex;align-items:center;gap:var(--tcc-col-gap, 12px);padding:var(--tcc-col-padding, 10px 14px);border-radius:var(--tcc-col-radius, 8px);background:var(--tcc-col-bg, #ffffff);border:1px solid var(--tcc-col-border, #eef0f2);transition:background .15s,border-color .15s,opacity .15s}.tcc-col:hover:not(.tcc-col--locked){background:var(--tcc-col-hover-bg, #f8fafc)}.tcc-col--hidden .tcc-col__eye,.tcc-col--hidden .tcc-col__label{opacity:.55}.tcc-col--locked{background:var(--tcc-col-locked-bg, #f6f7f8)}.tcc-col__eye{display:flex;align-items:center;color:var(--tcc-eye-color, #6b7280);flex-shrink:0}.tcc-col__eye--off{color:var(--tcc-eye-off-color, #b0b6be)}.tcc-col__label{flex:1 1 auto;min-width:0;font-size:var(--tcc-col-label-size, 14px);color:var(--tcc-col-label-color, #1f2933);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9500
+ }
9501
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfigColumnNodeComponent, decorators: [{
9502
+ type: Component,
9503
+ args: [{ selector: 'lib-config-column-node', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"tcc-col\"\r\n [class.tcc-col--hidden]=\"!column.visible\"\r\n [class.tcc-col--locked]=\"column.lockVisibility\"\r\n>\r\n <!-- Visibility indicator (eye / eye-off) -->\r\n <span class=\"tcc-col__eye\" [class.tcc-col__eye--off]=\"!column.visible\" aria-hidden=\"true\">\r\n @if (column.visible) {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z\"></path>\r\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\r\n </svg>\r\n } @else {\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24\"></path>\r\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>\r\n </svg>\r\n }\r\n </span>\r\n\r\n <span class=\"tcc-col__label\" [title]=\"displayLabel\">{{ displayLabel }}</span>\r\n\r\n <!-- Visibility toggle / lock -->\r\n @if (column.lockVisibility) {\r\n <span class=\"tcc-lock\" title=\"This column is always visible\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\r\n </svg>\r\n </span>\r\n } @else {\r\n <button\r\n type=\"button\"\r\n class=\"tcc-toggle\"\r\n [class.tcc-toggle--on]=\"column.visible\"\r\n role=\"switch\"\r\n [attr.aria-checked]=\"column.visible\"\r\n [attr.aria-label]=\"'Show ' + displayLabel\"\r\n (click)=\"toggleVisible.emit()\"\r\n >\r\n <span class=\"tcc-toggle__thumb\"></span>\r\n </button>\r\n }\r\n</div>\r\n", styles: [".tcc-toggle{position:relative;flex-shrink:0;width:var(--tcc-toggle-width, 38px);height:var(--tcc-toggle-height, 22px);padding:0;border:none;border-radius:999px;background:var(--tcc-toggle-off-bg, #cbd2d9);cursor:pointer;transition:background .18s ease}.tcc-toggle__thumb{position:absolute;top:2px;left:2px;width:calc(var(--tcc-toggle-height, 22px) - 4px);height:calc(var(--tcc-toggle-height, 22px) - 4px);border-radius:50%;background:var(--tcc-toggle-thumb, #ffffff);box-shadow:0 1px 2px #00000040;transition:left .18s ease}.tcc-toggle--on{background:var(--tcc-toggle-on-bg, #2f9e6f)}.tcc-toggle--on .tcc-toggle__thumb{left:calc(100% - (var(--tcc-toggle-height, 22px) - 2px))}.tcc-toggle:focus-visible{outline:2px solid var(--tcc-focus-ring, #2f9e6f);outline-offset:2px}.tcc-lock{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--tcc-toggle-width, 38px);color:var(--tcc-lock-color, #9aa2ab)}.tcc-col{display:flex;align-items:center;gap:var(--tcc-col-gap, 12px);padding:var(--tcc-col-padding, 10px 14px);border-radius:var(--tcc-col-radius, 8px);background:var(--tcc-col-bg, #ffffff);border:1px solid var(--tcc-col-border, #eef0f2);transition:background .15s,border-color .15s,opacity .15s}.tcc-col:hover:not(.tcc-col--locked){background:var(--tcc-col-hover-bg, #f8fafc)}.tcc-col--hidden .tcc-col__eye,.tcc-col--hidden .tcc-col__label{opacity:.55}.tcc-col--locked{background:var(--tcc-col-locked-bg, #f6f7f8)}.tcc-col__eye{display:flex;align-items:center;color:var(--tcc-eye-color, #6b7280);flex-shrink:0}.tcc-col__eye--off{color:var(--tcc-eye-off-color, #b0b6be)}.tcc-col__label{flex:1 1 auto;min-width:0;font-size:var(--tcc-col-label-size, 14px);color:var(--tcc-col-label-color, #1f2933);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"] }]
9504
+ }], propDecorators: { column: [{
9505
+ type: Input,
9506
+ args: [{ required: true }]
9507
+ }], translate: [{
9508
+ type: Input
9509
+ }], toggleVisible: [{
9510
+ type: Output
9511
+ }] } });
9512
+
9513
+ /**
9514
+ * Table Column Configuration
9515
+ * --------------------------
9516
+ * Renders a compact list of a table config's columns, each with a **visibility**
9517
+ * toggle. Intended to be embedded inside a `cc-confirmation-modal` on a host page
9518
+ * ("Configure columns").
9519
+ *
9520
+ * Pass a `TableConfig` via `[config]`. The input is deep-cloned, so it is never
9521
+ * mutated. When the user confirms, call `getUpdatedConfig()` to read back the
9522
+ * modified config (isEnabled/visible flags updated per column).
9523
+ *
9524
+ * Columns carrying `lockVisibility: true` cannot be hidden — their toggle is
9525
+ * replaced by a lock icon.
9526
+ *
9527
+ * @example
9528
+ * ```html
9529
+ * <cc-confirmation-modal [isOpen]="open" (confirm)="save()" (cancel)="open = false">
9530
+ * <lib-table-column-configuration #cfg [config]="tableConfig" [translate]="translateFn" />
9531
+ * </cc-confirmation-modal>
9532
+ * ```
9533
+ * ```ts
9534
+ * @ViewChild('cfg') cfg!: TableColumnConfigurationComponent;
9535
+ * save() { this.updatedConfig = this.cfg.getUpdatedConfig(); }
9536
+ * ```
9537
+ */
9538
+ class TableColumnConfigurationComponent {
9539
+ /** The table config to configure. Deep-cloned internally; never mutated. */
9540
+ config;
9541
+ /** Optional label translator, e.g. an ngx-translate `instant` function. */
9542
+ translate;
9543
+ /** Show the "Visible" legend row. Default true. */
9544
+ showLegend = true;
9545
+ store = inject(TableColumnConfigurationService);
9546
+ ngOnChanges(changes) {
9547
+ if (changes['config'] && this.config) {
9548
+ this.store.loadConfig(this.config);
9549
+ }
9550
+ }
9551
+ /**
9552
+ * Returns a fresh, modified copy of the config with the current visibility
9553
+ * selections applied. Returns null if no config has been loaded.
9554
+ */
9555
+ getUpdatedConfig() {
9556
+ return this.store.buildUpdatedConfig();
9557
+ }
9558
+ onToggleVisible(index) {
9559
+ this.store.toggleColumnVisible(index);
9560
+ }
9561
+ trackByIndex(index) {
9562
+ return index;
9563
+ }
9564
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableColumnConfigurationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9565
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TableColumnConfigurationComponent, isStandalone: false, selector: "lib-table-column-configuration", inputs: { config: "config", translate: "translate", showLegend: "showLegend" }, providers: [TableColumnConfigurationService], usesOnChanges: true, ngImport: i0, template: "<div class=\"tcc-root\">\r\n @if (showLegend) {\r\n <div class=\"tcc-legend\">\r\n <span class=\"tcc-legend__item\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <path d=\"M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z\"></path>\r\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\r\n </svg>\r\n <span>Visible</span>\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"tcc-list\">\r\n @for (column of store.columns(); track trackByIndex($index); let ci = $index) {\r\n <lib-config-column-node\r\n [column]=\"column\"\r\n [translate]=\"translate\"\r\n (toggleVisible)=\"onToggleVisible(ci)\"\r\n />\r\n }\r\n\r\n @if (store.columns().length === 0) {\r\n <div class=\"tcc-empty\">\r\n <p>No columns found in the config.</p>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".tcc-root{display:flex;flex-direction:column;gap:var(--tcc-root-gap, 12px);font-family:var(--tcc-font-family, inherit)}.tcc-legend{display:flex;align-items:center;gap:var(--tcc-legend-gap, 24px);padding:var(--tcc-legend-padding, 4px 2px 8px);border-bottom:1px solid var(--tcc-legend-border, #eef0f2);flex-wrap:wrap}.tcc-legend__item{display:inline-flex;align-items:center;gap:6px;font-size:var(--tcc-legend-size, 13px);color:var(--tcc-legend-color, #52606d)}.tcc-list{display:flex;flex-direction:column;gap:var(--tcc-list-gap, 10px)}.tcc-empty{padding:24px;text-align:center;color:var(--tcc-empty-color, #9aa2ab);font-size:13px}\n"], dependencies: [{ kind: "component", type: ConfigColumnNodeComponent, selector: "lib-config-column-node", inputs: ["column", "translate"], outputs: ["toggleVisible"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9566
+ }
9567
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableColumnConfigurationComponent, decorators: [{
9568
+ type: Component,
9569
+ args: [{ selector: 'lib-table-column-configuration', standalone: false, providers: [TableColumnConfigurationService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"tcc-root\">\r\n @if (showLegend) {\r\n <div class=\"tcc-legend\">\r\n <span class=\"tcc-legend__item\">\r\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <path d=\"M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z\"></path>\r\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\r\n </svg>\r\n <span>Visible</span>\r\n </span>\r\n </div>\r\n }\r\n\r\n <div class=\"tcc-list\">\r\n @for (column of store.columns(); track trackByIndex($index); let ci = $index) {\r\n <lib-config-column-node\r\n [column]=\"column\"\r\n [translate]=\"translate\"\r\n (toggleVisible)=\"onToggleVisible(ci)\"\r\n />\r\n }\r\n\r\n @if (store.columns().length === 0) {\r\n <div class=\"tcc-empty\">\r\n <p>No columns found in the config.</p>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".tcc-root{display:flex;flex-direction:column;gap:var(--tcc-root-gap, 12px);font-family:var(--tcc-font-family, inherit)}.tcc-legend{display:flex;align-items:center;gap:var(--tcc-legend-gap, 24px);padding:var(--tcc-legend-padding, 4px 2px 8px);border-bottom:1px solid var(--tcc-legend-border, #eef0f2);flex-wrap:wrap}.tcc-legend__item{display:inline-flex;align-items:center;gap:6px;font-size:var(--tcc-legend-size, 13px);color:var(--tcc-legend-color, #52606d)}.tcc-list{display:flex;flex-direction:column;gap:var(--tcc-list-gap, 10px)}.tcc-empty{padding:24px;text-align:center;color:var(--tcc-empty-color, #9aa2ab);font-size:13px}\n"] }]
9570
+ }], propDecorators: { config: [{
9571
+ type: Input,
9572
+ args: [{ required: true }]
9573
+ }], translate: [{
9574
+ type: Input
9575
+ }], showLegend: [{
9576
+ type: Input
9577
+ }] } });
9578
+
9579
+ const COMPONENTS = [
9580
+ TableColumnConfigurationComponent,
9581
+ ConfigColumnNodeComponent,
9582
+ ];
9583
+ class TableColumnConfigurationModule {
9584
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableColumnConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
9585
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: TableColumnConfigurationModule, declarations: [TableColumnConfigurationComponent,
9586
+ ConfigColumnNodeComponent], imports: [CommonModule], exports: [TableColumnConfigurationComponent] });
9587
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableColumnConfigurationModule, imports: [CommonModule] });
9588
+ }
9589
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableColumnConfigurationModule, decorators: [{
9590
+ type: NgModule,
9591
+ args: [{
9592
+ declarations: [...COMPONENTS],
9593
+ imports: [
9594
+ CommonModule,
9595
+ ],
9596
+ exports: [
9597
+ TableColumnConfigurationComponent,
9598
+ ],
9599
+ }]
9600
+ }] });
9601
+
9342
9602
  class ConfirmationModalComponent {
9343
9603
  config;
9344
9604
  isOpen = false;
@@ -11130,11 +11390,11 @@ class SideNavComponent {
11130
11390
  return styles;
11131
11391
  }
11132
11392
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SideNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11133
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SideNavComponent, isStandalone: false, selector: "lib-side-nav", inputs: { sections: "sections", userRoles: "userRoles", activeId: "activeId", styleConfig: "styleConfig", collapsed: "collapsed", width: "width", collapsedWidth: "collapsedWidth", showCollapseToggle: "showCollapseToggle", hideIconsWhenExpanded: "hideIconsWhenExpanded", showTooltips: "showTooltips", tooltipPosition: "tooltipPosition", labels: "labels" }, outputs: { itemClicked: "itemClicked", collapsedChange: "collapsedChange" }, host: { properties: { "class.cc-side-nav-host-collapsed": "this.isHostCollapsed" } }, usesOnChanges: true, ngImport: i0, template: "<nav class=\"cc-side-nav\" [class.collapsed]=\"collapsed\" role=\"navigation\" [ngStyle]=\"customStyles\">\r\n\r\n <div class=\"cc-side-nav-section\" *ngFor=\"let section of filteredSections; let i = index\">\r\n\r\n <div class=\"cc-side-nav-heading-row\" *ngIf=\"section.heading && !collapsed\">\r\n <h3 class=\"cc-side-nav-heading\">{{ section.heading }}</h3>\r\n </div>\r\n\r\n <ul class=\"cc-side-nav-list\">\r\n <li *ngFor=\"let item of section.items\" class=\"cc-side-nav-list-item\">\r\n <a (click)=\"onItemClick(item, $event)\" class=\"cc-side-nav-link\" [class.active]=\"item.id === activeId\"\r\n [class.disabled]=\"item.disabled\" [matTooltip]=\"item.tooltip || item.label\"\r\n [matTooltipDisabled]=\"collapsed ? false : !showTooltips\" [matTooltipPosition]=\"tooltipPosition\"\r\n [matTooltipClass]=\"'cc-side-nav-tooltip'\" [attr.aria-current]=\"(item.id === activeId) ? 'page' : null\"\r\n [attr.aria-disabled]=\"item.disabled ? true : null\">\r\n <span *ngIf=\"item.icon && (collapsed || !hideIconsWhenExpanded)\" class=\"cc-side-nav-icon\">\r\n <span *ngIf=\"!item.icon.includes('fa') && !item.icon.includes('bi')\" class=\"material-icons\">\r\n {{ item.icon }}\r\n </span>\r\n <i *ngIf=\"item.icon.includes('fa') || item.icon.includes('bi')\" [class]=\"item.icon\"></i>\r\n </span>\r\n <!-- Label: always in DOM, CSS transitions handle fade on collapse -->\r\n <span class=\"cc-side-nav-label\">{{ item.label }}</span>\r\n <!-- Arrow: rendered for active items regardless of collapse state; CSS hides it -->\r\n <span class=\"cc-side-nav-arrow material-icons\"\r\n *ngIf=\"(item.id === activeId) && item.showArrow !== false\">chevron_right</span>\r\n </a>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n\r\n</nav>\r\n\r\n<!--\r\n Toggle pill \u2014 always straddles the right edge of :host (right: -12px).\r\n Hidden via opacity/scale until :host is hovered; always visible when collapsed.\r\n Single chevron SVG rotates 180\u00B0 via CSS \u2014 no icon swap needed.\r\n-->\r\n<button *ngIf=\"showCollapseToggle\"\r\n class=\"cc-sn-toggle\"\r\n (click)=\"toggleCollapse()\"\r\n type=\"button\"\r\n [attr.aria-label]=\"collapsed ? 'Expand navigation' : 'Collapse navigation'\">\r\n <svg class=\"cc-sn-chevron\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 16 16\"\r\n fill=\"none\"\r\n aria-hidden=\"true\">\r\n <path d=\"M10 3L5 8L10 13\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.75\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"/>\r\n </svg>\r\n</button>\r\n", styles: [":host{display:block;height:100%;overflow:visible;position:relative;width:var(--cc-side-nav-width, 220px);transition:width .3s cubic-bezier(.4,0,.2,1);--cc-side-nav-bg: #ffffff;--cc-side-nav-border-color: rgba(0, 0, 0, .08);--cc-side-nav-width: 220px;--cc-side-nav-collapsed-width: 56px;--cc-side-nav-gap-sections: 24px;--cc-side-nav-padding: 16px;--cc-side-nav-font-family: Poppins, sans-serif;--cc-side-nav-heading-font-weight: 500;--cc-side-nav-heading-font-size: 16px;--cc-side-nav-heading-color: #3C4043;--cc-side-nav-item-gap: 4px;--cc-side-nav-item-padding: 12px 16px;--cc-side-nav-item-border-radius: 8px;--cc-side-nav-item-font-weight: 400;--cc-side-nav-item-font-size: 14px;--cc-side-nav-item-color: #5F6368;--cc-side-nav-item-hover-bg: rgba(30, 30, 45, .08);--cc-side-nav-item-hover-color: #1e1e2d;--cc-side-nav-active-bg: #1e1e2d;--cc-side-nav-active-color: #ffffff;--cc-side-nav-active-font-weight: 500;--cc-side-nav-active-hover-bg: #2a2a3d;--cc-side-nav-disabled-opacity: .5;--cc-side-nav-toggle-bg: #ffffff;--cc-side-nav-toggle-border-color: rgba(0, 0, 0, .1);--cc-side-nav-tooltip-bg: #1e1e2d;--cc-side-nav-tooltip-color: #FFFFFF;--cc-side-nav-tooltip-padding: 8px 14px;--cc-side-nav-tooltip-border-radius: 6px;--cc-side-nav-tooltip-font-size: 12px;--cc-side-nav-tooltip-font-weight: 500;--cc-side-nav-tooltip-letter-spacing: .2px;--cc-side-nav-tooltip-offset: 20px;--cc-side-nav-tooltip-shadow: 0 4px 12px rgba(0, 0, 0, .35)}:host.cc-side-nav-host-collapsed{width:var(--cc-side-nav-collapsed-width, 56px)}:host:after{content:\"\";position:absolute;top:10%;right:0;width:2px;height:80%;background:var(--cc-side-nav-active-bg, #1e1e2d);border-radius:2px;opacity:0;transition:opacity .25s ease;pointer-events:none;z-index:4}:host:hover:after{opacity:.18}:host.cc-side-nav-host-collapsed:after{display:none}.cc-sn-toggle{position:absolute;bottom:20px;right:-12px;width:24px;height:24px;border-radius:50%;border:1.5px solid var(--cc-side-nav-toggle-border-color, rgba(0, 0, 0, .1));background:var(--cc-side-nav-toggle-bg, #ffffff);cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:20;padding:0;color:var(--cc-side-nav-item-color, #5F6368);box-shadow:0 1px 4px #0000001a,0 0 0 1px #0000000a;opacity:1;transform:scale(.65);transition:opacity .2s ease,transform .25s cubic-bezier(.34,1.56,.64,1),background .15s ease,color .15s ease,border-color .15s ease,box-shadow .2s ease}.cc-sn-toggle:focus-visible{outline:2px solid var(--cc-side-nav-active-bg, #E63E30);outline-offset:2px}.cc-sn-toggle .cc-sn-chevron{width:12px;height:12px;flex-shrink:0;display:block;transition:transform .3s cubic-bezier(.4,0,.2,1)}:host:hover .cc-sn-toggle{opacity:1;transform:scale(1)}:host:hover .cc-sn-toggle:hover,:host.cc-side-nav-host-collapsed .cc-sn-toggle:hover{background:var(--cc-side-nav-active-bg, #E63E30);color:var(--cc-side-nav-active-color, #ffffff);border-color:transparent;box-shadow:0 4px 14px #0000001a,0 1px 4px #0000001a;transform:scale(1.12)}:host.cc-side-nav-host-collapsed .cc-sn-toggle{opacity:1;transform:scale(1);box-shadow:0 2px 8px #00000021,0 0 0 1.5px #00000014}:host.cc-side-nav-host-collapsed .cc-sn-chevron{transform:rotate(180deg)}.cc-side-nav{display:flex;flex-direction:column;gap:var(--cc-side-nav-gap-sections, 24px);padding:var(--cc-side-nav-padding, 16px);width:var(--cc-side-nav-width, 220px);min-width:var(--cc-side-nav-width, 220px);box-sizing:border-box;background-color:var(--cc-side-nav-bg, #ffffff);border-right:1px solid var(--cc-side-nav-border-color, rgba(0, 0, 0, .08));height:100%;overflow-y:auto;overflow-x:hidden;transition:width .3s cubic-bezier(.4,0,.2,1),min-width .3s cubic-bezier(.4,0,.2,1),padding .3s cubic-bezier(.4,0,.2,1)}.cc-side-nav::-webkit-scrollbar{width:3px}.cc-side-nav::-webkit-scrollbar-track{background:transparent}.cc-side-nav::-webkit-scrollbar-thumb{background:#00000026;border-radius:2px}.cc-side-nav::-webkit-scrollbar-thumb:hover{background:#0000004d}.cc-side-nav.collapsed{width:var(--cc-side-nav-collapsed-width, 56px);min-width:var(--cc-side-nav-collapsed-width, 56px);padding:var(--cc-side-nav-padding, 16px) 8px}.cc-side-nav.collapsed .cc-side-nav-link{justify-content:center;gap:0;padding:10px}.cc-side-nav.collapsed .cc-side-nav-icon{font-size:20px}.cc-side-nav-section{display:flex;flex-direction:column;gap:12px}.cc-side-nav-heading-row{display:flex;align-items:center;justify-content:space-between;min-height:28px}.cc-side-nav-heading{margin:0;padding:0 16px;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif);font-weight:var(--cc-side-nav-heading-font-weight, 500);font-style:normal;font-size:var(--cc-side-nav-heading-font-size, 16px);text-transform:uppercase;color:var(--cc-side-nav-heading-color, #3C4043);flex:1}.cc-side-nav-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--cc-side-nav-item-gap, 4px)}.cc-side-nav-list-item{margin:0;padding:0}.cc-side-nav-link{display:flex;align-items:center;gap:12px;padding:var(--cc-side-nav-item-padding, 12px 16px);text-decoration:none;cursor:pointer;border-radius:var(--cc-side-nav-item-border-radius, 8px);transition:background-color .2s ease,opacity .2s ease;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif);font-weight:var(--cc-side-nav-item-font-weight, 400);font-style:normal;font-size:var(--cc-side-nav-item-font-size, 14px);color:var(--cc-side-nav-item-color, #5F6368)}.cc-side-nav-link:hover:not(.disabled){background-color:var(--cc-side-nav-item-hover-bg, rgba(30, 30, 45, .08));color:var(--cc-side-nav-item-hover-color, #1e1e2d)}.cc-side-nav-link.active{background:var(--cc-side-nav-active-bg, #1e1e2d);opacity:1;border-radius:var(--cc-side-nav-item-border-radius, 8px);font-weight:var(--cc-side-nav-active-font-weight, 500);color:var(--cc-side-nav-active-color, #ffffff)}.cc-side-nav-link.active:hover{background-color:var(--cc-side-nav-active-hover-bg, #2a2a3d);color:var(--cc-side-nav-active-color, #ffffff)}.cc-side-nav-link.disabled{cursor:not-allowed;opacity:var(--cc-side-nav-disabled-opacity, .5)}.cc-side-nav-icon{display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0}.cc-side-nav-label{flex:1;white-space:nowrap;overflow:hidden;max-width:200px;opacity:1;transition:opacity .15s ease,max-width .3s cubic-bezier(.4,0,.2,1)}.collapsed .cc-side-nav-label{opacity:0;max-width:0}.cc-side-nav-arrow{margin-left:auto;font-size:18px;opacity:.7;overflow:hidden;max-width:30px;flex-shrink:0;white-space:nowrap;transition:opacity .15s ease,max-width .3s cubic-bezier(.4,0,.2,1)}.collapsed .cc-side-nav-arrow{opacity:0;max-width:0}.cc-side-nav-link.active .cc-side-nav-arrow{color:var(--cc-side-nav-active-color, #FFFFFF);opacity:1}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip{margin-left:var(--cc-side-nav-tooltip-offset, 20px)!important;overflow:visible!important}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip .mdc-tooltip__surface{background-color:var(--cc-side-nav-tooltip-bg, #1e1e2d)!important;color:var(--cc-side-nav-tooltip-color, #FFFFFF)!important;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif)!important;font-size:var(--cc-side-nav-tooltip-font-size, 12px)!important;font-weight:var(--cc-side-nav-tooltip-font-weight, 500)!important;padding:var(--cc-side-nav-tooltip-padding, 8px 14px)!important;border-radius:var(--cc-side-nav-tooltip-border-radius, 6px)!important;box-shadow:var(--cc-side-nav-tooltip-shadow, 0 4px 12px rgba(0, 0, 0, .35))!important;letter-spacing:var(--cc-side-nav-tooltip-letter-spacing, .2px)!important;position:relative!important;overflow:visible!important}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip .mdc-tooltip__surface:before{content:\"\";position:absolute;left:-6px;top:50%;transform:translateY(-50%);width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:6px solid var(--cc-side-nav-tooltip-bg, #1e1e2d)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
11393
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SideNavComponent, isStandalone: false, selector: "lib-side-nav", inputs: { sections: "sections", userRoles: "userRoles", activeId: "activeId", styleConfig: "styleConfig", collapsed: "collapsed", width: "width", collapsedWidth: "collapsedWidth", showCollapseToggle: "showCollapseToggle", hideIconsWhenExpanded: "hideIconsWhenExpanded", showTooltips: "showTooltips", tooltipPosition: "tooltipPosition", labels: "labels" }, outputs: { itemClicked: "itemClicked", collapsedChange: "collapsedChange" }, host: { properties: { "class.cc-side-nav-host-collapsed": "this.isHostCollapsed" } }, usesOnChanges: true, ngImport: i0, template: "<nav class=\"cc-side-nav\" [class.collapsed]=\"collapsed\" role=\"navigation\" [ngStyle]=\"customStyles\">\r\n\r\n <div class=\"cc-side-nav-section\" *ngFor=\"let section of filteredSections; let i = index\">\r\n\r\n <div class=\"cc-side-nav-heading-row\" *ngIf=\"section.heading && !collapsed\">\r\n <h3 class=\"cc-side-nav-heading\">{{ section.heading }}</h3>\r\n </div>\r\n\r\n <ul class=\"cc-side-nav-list\">\r\n <li *ngFor=\"let item of section.items\" class=\"cc-side-nav-list-item\">\r\n <a (click)=\"onItemClick(item, $event)\" class=\"cc-side-nav-link\" [class.active]=\"item.id === activeId\"\r\n [class.disabled]=\"item.disabled\" [matTooltip]=\"item.tooltip || item.label\"\r\n [matTooltipPosition]=\"tooltipPosition\"\r\n [matTooltipClass]=\"'cc-side-nav-tooltip'\" [attr.aria-current]=\"(item.id === activeId) ? 'page' : null\"\r\n [attr.aria-disabled]=\"item.disabled ? true : null\">\r\n <span *ngIf=\"item.icon && (collapsed || !hideIconsWhenExpanded)\" class=\"cc-side-nav-icon\">\r\n <span *ngIf=\"!item.icon.includes('fa') && !item.icon.includes('bi')\" class=\"material-icons\">\r\n {{ item.icon }}\r\n </span>\r\n <i *ngIf=\"item.icon.includes('fa') || item.icon.includes('bi')\" [class]=\"item.icon\"></i>\r\n </span>\r\n <!-- Label: always in DOM, CSS transitions handle fade on collapse -->\r\n <span class=\"cc-side-nav-label\">{{ item.label }}</span>\r\n <!-- Arrow: rendered for active items regardless of collapse state; CSS hides it -->\r\n <span class=\"cc-side-nav-arrow material-icons\"\r\n *ngIf=\"(item.id === activeId) && item.showArrow !== false\">chevron_right</span>\r\n </a>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n\r\n</nav>\r\n\r\n<!--\r\n Toggle pill \u2014 always straddles the right edge of :host (right: -12px).\r\n Hidden via opacity/scale until :host is hovered; always visible when collapsed.\r\n Single chevron SVG rotates 180\u00B0 via CSS \u2014 no icon swap needed.\r\n-->\r\n<button *ngIf=\"showCollapseToggle\"\r\n class=\"cc-sn-toggle\"\r\n (click)=\"toggleCollapse()\"\r\n type=\"button\"\r\n [attr.aria-label]=\"collapsed ? 'Expand navigation' : 'Collapse navigation'\">\r\n <svg class=\"cc-sn-chevron\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 16 16\"\r\n fill=\"none\"\r\n aria-hidden=\"true\">\r\n <path d=\"M10 3L5 8L10 13\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.75\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"/>\r\n </svg>\r\n</button>\r\n", styles: [":host{display:block;height:100%;overflow:visible;position:relative;width:var(--cc-side-nav-width, 220px);transition:width .3s cubic-bezier(.4,0,.2,1);--cc-side-nav-bg: #ffffff;--cc-side-nav-border-color: rgba(0, 0, 0, .08);--cc-side-nav-width: 220px;--cc-side-nav-collapsed-width: 56px;--cc-side-nav-gap-sections: 24px;--cc-side-nav-padding: 16px;--cc-side-nav-font-family: Poppins, sans-serif;--cc-side-nav-heading-font-weight: 500;--cc-side-nav-heading-font-size: 16px;--cc-side-nav-heading-color: #3C4043;--cc-side-nav-item-gap: 4px;--cc-side-nav-item-padding: 12px 16px;--cc-side-nav-item-border-radius: 8px;--cc-side-nav-item-font-weight: 400;--cc-side-nav-item-font-size: 14px;--cc-side-nav-item-color: #5F6368;--cc-side-nav-item-hover-bg: rgba(30, 30, 45, .08);--cc-side-nav-item-hover-color: #1e1e2d;--cc-side-nav-active-bg: #1e1e2d;--cc-side-nav-active-color: #ffffff;--cc-side-nav-active-font-weight: 500;--cc-side-nav-active-hover-bg: #2a2a3d;--cc-side-nav-disabled-opacity: .5;--cc-side-nav-toggle-bg: #ffffff;--cc-side-nav-toggle-border-color: rgba(0, 0, 0, .1);--cc-side-nav-tooltip-bg: #1e1e2d;--cc-side-nav-tooltip-color: #FFFFFF;--cc-side-nav-tooltip-padding: 8px 14px;--cc-side-nav-tooltip-border-radius: 6px;--cc-side-nav-tooltip-font-size: 12px;--cc-side-nav-tooltip-font-weight: 500;--cc-side-nav-tooltip-letter-spacing: .2px;--cc-side-nav-tooltip-offset: 20px;--cc-side-nav-tooltip-shadow: 0 4px 12px rgba(0, 0, 0, .35)}:host.cc-side-nav-host-collapsed{width:var(--cc-side-nav-collapsed-width, 56px)}:host:after{content:\"\";position:absolute;top:10%;right:0;width:2px;height:80%;background:var(--cc-side-nav-active-bg, #1e1e2d);border-radius:2px;opacity:0;transition:opacity .25s ease;pointer-events:none;z-index:4}:host:hover:after{opacity:.18}:host.cc-side-nav-host-collapsed:after{display:none}.cc-sn-toggle{position:absolute;bottom:20px;right:-12px;width:30px;height:30px;border-radius:50%;border:1.5px solid var(--cc-side-nav-toggle-border-color, rgba(0, 0, 0, .1));background:var(--cc-side-nav-toggle-bg, #ffffff);cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:20;padding:0;color:var(--cc-side-nav-item-color, #5F6368);box-shadow:0 1px 4px #0000001a,0 0 0 1px #0000000a;opacity:1;transform:scale(.65);transition:opacity .2s ease,transform .25s cubic-bezier(.34,1.56,.64,1),background .15s ease,color .15s ease,border-color .15s ease,box-shadow .2s ease}.cc-sn-toggle:focus-visible{outline:2px solid var(--cc-side-nav-active-bg, #E63E30);outline-offset:2px}.cc-sn-toggle .cc-sn-chevron{width:12px;height:12px;flex-shrink:0;display:block;transition:transform .3s cubic-bezier(.4,0,.2,1)}:host:hover .cc-sn-toggle{opacity:1;transform:scale(1)}:host:hover .cc-sn-toggle:hover,:host.cc-side-nav-host-collapsed .cc-sn-toggle:hover{background:var(--cc-side-nav-active-bg, #E63E30);color:var(--cc-side-nav-active-color, #ffffff);border-color:transparent;box-shadow:0 4px 14px #0000001a,0 1px 4px #0000001a;transform:scale(1.05)}:host.cc-side-nav-host-collapsed .cc-sn-toggle{opacity:1;transform:scale(1);box-shadow:0 2px 8px #00000021,0 0 0 1.5px #00000014}:host.cc-side-nav-host-collapsed .cc-sn-chevron{transform:rotate(180deg)}.cc-side-nav{display:flex;flex-direction:column;gap:var(--cc-side-nav-gap-sections, 24px);padding:var(--cc-side-nav-padding, 16px);width:var(--cc-side-nav-width, 220px);min-width:var(--cc-side-nav-width, 220px);box-sizing:border-box;background-color:var(--cc-side-nav-bg, #ffffff);border-right:1px solid var(--cc-side-nav-border-color, rgba(0, 0, 0, .08));height:100%;overflow-y:auto;overflow-x:hidden;transition:width .3s cubic-bezier(.4,0,.2,1),min-width .3s cubic-bezier(.4,0,.2,1),padding .3s cubic-bezier(.4,0,.2,1)}.cc-side-nav::-webkit-scrollbar{width:3px}.cc-side-nav::-webkit-scrollbar-track{background:transparent}.cc-side-nav::-webkit-scrollbar-thumb{background:#00000026;border-radius:2px}.cc-side-nav::-webkit-scrollbar-thumb:hover{background:#0000004d}.cc-side-nav.collapsed{width:var(--cc-side-nav-collapsed-width, 56px);min-width:var(--cc-side-nav-collapsed-width, 56px);padding:var(--cc-side-nav-padding, 16px) 8px}.cc-side-nav.collapsed .cc-side-nav-link{justify-content:center;gap:0;padding:10px}.cc-side-nav.collapsed .cc-side-nav-icon{font-size:20px}.cc-side-nav-section{display:flex;flex-direction:column;gap:12px}.cc-side-nav-heading-row{display:flex;align-items:center;justify-content:space-between;min-height:28px}.cc-side-nav-heading{margin:0;padding:0 16px;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif);font-weight:var(--cc-side-nav-heading-font-weight, 500);font-style:normal;font-size:var(--cc-side-nav-heading-font-size, 16px);text-transform:uppercase;color:var(--cc-side-nav-heading-color, #3C4043);flex:1}.cc-side-nav-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--cc-side-nav-item-gap, 4px)}.cc-side-nav-list-item{margin:0;padding:0}.cc-side-nav-link{display:flex;align-items:center;gap:12px;padding:var(--cc-side-nav-item-padding, 12px 16px);text-decoration:none;cursor:pointer;border-radius:var(--cc-side-nav-item-border-radius, 8px);transition:background-color .2s ease,opacity .2s ease;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif);font-weight:var(--cc-side-nav-item-font-weight, 400);font-style:normal;font-size:var(--cc-side-nav-item-font-size, 14px);color:var(--cc-side-nav-item-color, #5F6368)}.cc-side-nav-link:hover:not(.disabled){background-color:var(--cc-side-nav-item-hover-bg, rgba(30, 30, 45, .08));color:var(--cc-side-nav-item-hover-color, #1e1e2d)}.cc-side-nav-link.active{background:var(--cc-side-nav-active-bg, #1e1e2d);opacity:1;border-radius:var(--cc-side-nav-item-border-radius, 8px);font-weight:var(--cc-side-nav-active-font-weight, 500);color:var(--cc-side-nav-active-color, #ffffff)}.cc-side-nav-link.active:hover{background-color:var(--cc-side-nav-active-hover-bg, #2a2a3d);color:var(--cc-side-nav-active-color, #ffffff)}.cc-side-nav-link.disabled{cursor:not-allowed;opacity:var(--cc-side-nav-disabled-opacity, .5)}.cc-side-nav-icon{display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0}.cc-side-nav-label{flex:1;white-space:wrap;overflow:hidden;max-width:200px;opacity:1;transition:opacity .15s ease,max-width .3s cubic-bezier(.4,0,.2,1)}.collapsed .cc-side-nav-label{opacity:0;max-width:0}.cc-side-nav-arrow{margin-left:auto;font-size:18px;opacity:.7;overflow:hidden;max-width:30px;flex-shrink:0;white-space:nowrap;transition:opacity .15s ease,max-width .3s cubic-bezier(.4,0,.2,1)}.collapsed .cc-side-nav-arrow{opacity:0;max-width:0}.cc-side-nav-link.active .cc-side-nav-arrow{color:var(--cc-side-nav-active-color, #FFFFFF);opacity:1}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip{margin-left:var(--cc-side-nav-tooltip-offset, 20px)!important;overflow:visible!important}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip .mdc-tooltip__surface{background-color:var(--cc-side-nav-tooltip-bg, #1e1e2d)!important;color:var(--cc-side-nav-tooltip-color, #FFFFFF)!important;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif)!important;font-size:var(--cc-side-nav-tooltip-font-size, 12px)!important;font-weight:var(--cc-side-nav-tooltip-font-weight, 500)!important;padding:var(--cc-side-nav-tooltip-padding, 8px 14px)!important;border-radius:var(--cc-side-nav-tooltip-border-radius, 6px)!important;box-shadow:var(--cc-side-nav-tooltip-shadow, 0 4px 12px rgba(0, 0, 0, .35))!important;letter-spacing:var(--cc-side-nav-tooltip-letter-spacing, .2px)!important;position:relative!important;overflow:visible!important}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip .mdc-tooltip__surface:before{content:\"\";position:absolute;left:-6px;top:50%;transform:translateY(-50%);width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:6px solid var(--cc-side-nav-tooltip-bg, #1e1e2d)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
11134
11394
  }
11135
11395
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SideNavComponent, decorators: [{
11136
11396
  type: Component,
11137
- args: [{ selector: 'lib-side-nav', standalone: false, template: "<nav class=\"cc-side-nav\" [class.collapsed]=\"collapsed\" role=\"navigation\" [ngStyle]=\"customStyles\">\r\n\r\n <div class=\"cc-side-nav-section\" *ngFor=\"let section of filteredSections; let i = index\">\r\n\r\n <div class=\"cc-side-nav-heading-row\" *ngIf=\"section.heading && !collapsed\">\r\n <h3 class=\"cc-side-nav-heading\">{{ section.heading }}</h3>\r\n </div>\r\n\r\n <ul class=\"cc-side-nav-list\">\r\n <li *ngFor=\"let item of section.items\" class=\"cc-side-nav-list-item\">\r\n <a (click)=\"onItemClick(item, $event)\" class=\"cc-side-nav-link\" [class.active]=\"item.id === activeId\"\r\n [class.disabled]=\"item.disabled\" [matTooltip]=\"item.tooltip || item.label\"\r\n [matTooltipDisabled]=\"collapsed ? false : !showTooltips\" [matTooltipPosition]=\"tooltipPosition\"\r\n [matTooltipClass]=\"'cc-side-nav-tooltip'\" [attr.aria-current]=\"(item.id === activeId) ? 'page' : null\"\r\n [attr.aria-disabled]=\"item.disabled ? true : null\">\r\n <span *ngIf=\"item.icon && (collapsed || !hideIconsWhenExpanded)\" class=\"cc-side-nav-icon\">\r\n <span *ngIf=\"!item.icon.includes('fa') && !item.icon.includes('bi')\" class=\"material-icons\">\r\n {{ item.icon }}\r\n </span>\r\n <i *ngIf=\"item.icon.includes('fa') || item.icon.includes('bi')\" [class]=\"item.icon\"></i>\r\n </span>\r\n <!-- Label: always in DOM, CSS transitions handle fade on collapse -->\r\n <span class=\"cc-side-nav-label\">{{ item.label }}</span>\r\n <!-- Arrow: rendered for active items regardless of collapse state; CSS hides it -->\r\n <span class=\"cc-side-nav-arrow material-icons\"\r\n *ngIf=\"(item.id === activeId) && item.showArrow !== false\">chevron_right</span>\r\n </a>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n\r\n</nav>\r\n\r\n<!--\r\n Toggle pill \u2014 always straddles the right edge of :host (right: -12px).\r\n Hidden via opacity/scale until :host is hovered; always visible when collapsed.\r\n Single chevron SVG rotates 180\u00B0 via CSS \u2014 no icon swap needed.\r\n-->\r\n<button *ngIf=\"showCollapseToggle\"\r\n class=\"cc-sn-toggle\"\r\n (click)=\"toggleCollapse()\"\r\n type=\"button\"\r\n [attr.aria-label]=\"collapsed ? 'Expand navigation' : 'Collapse navigation'\">\r\n <svg class=\"cc-sn-chevron\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 16 16\"\r\n fill=\"none\"\r\n aria-hidden=\"true\">\r\n <path d=\"M10 3L5 8L10 13\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.75\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"/>\r\n </svg>\r\n</button>\r\n", styles: [":host{display:block;height:100%;overflow:visible;position:relative;width:var(--cc-side-nav-width, 220px);transition:width .3s cubic-bezier(.4,0,.2,1);--cc-side-nav-bg: #ffffff;--cc-side-nav-border-color: rgba(0, 0, 0, .08);--cc-side-nav-width: 220px;--cc-side-nav-collapsed-width: 56px;--cc-side-nav-gap-sections: 24px;--cc-side-nav-padding: 16px;--cc-side-nav-font-family: Poppins, sans-serif;--cc-side-nav-heading-font-weight: 500;--cc-side-nav-heading-font-size: 16px;--cc-side-nav-heading-color: #3C4043;--cc-side-nav-item-gap: 4px;--cc-side-nav-item-padding: 12px 16px;--cc-side-nav-item-border-radius: 8px;--cc-side-nav-item-font-weight: 400;--cc-side-nav-item-font-size: 14px;--cc-side-nav-item-color: #5F6368;--cc-side-nav-item-hover-bg: rgba(30, 30, 45, .08);--cc-side-nav-item-hover-color: #1e1e2d;--cc-side-nav-active-bg: #1e1e2d;--cc-side-nav-active-color: #ffffff;--cc-side-nav-active-font-weight: 500;--cc-side-nav-active-hover-bg: #2a2a3d;--cc-side-nav-disabled-opacity: .5;--cc-side-nav-toggle-bg: #ffffff;--cc-side-nav-toggle-border-color: rgba(0, 0, 0, .1);--cc-side-nav-tooltip-bg: #1e1e2d;--cc-side-nav-tooltip-color: #FFFFFF;--cc-side-nav-tooltip-padding: 8px 14px;--cc-side-nav-tooltip-border-radius: 6px;--cc-side-nav-tooltip-font-size: 12px;--cc-side-nav-tooltip-font-weight: 500;--cc-side-nav-tooltip-letter-spacing: .2px;--cc-side-nav-tooltip-offset: 20px;--cc-side-nav-tooltip-shadow: 0 4px 12px rgba(0, 0, 0, .35)}:host.cc-side-nav-host-collapsed{width:var(--cc-side-nav-collapsed-width, 56px)}:host:after{content:\"\";position:absolute;top:10%;right:0;width:2px;height:80%;background:var(--cc-side-nav-active-bg, #1e1e2d);border-radius:2px;opacity:0;transition:opacity .25s ease;pointer-events:none;z-index:4}:host:hover:after{opacity:.18}:host.cc-side-nav-host-collapsed:after{display:none}.cc-sn-toggle{position:absolute;bottom:20px;right:-12px;width:24px;height:24px;border-radius:50%;border:1.5px solid var(--cc-side-nav-toggle-border-color, rgba(0, 0, 0, .1));background:var(--cc-side-nav-toggle-bg, #ffffff);cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:20;padding:0;color:var(--cc-side-nav-item-color, #5F6368);box-shadow:0 1px 4px #0000001a,0 0 0 1px #0000000a;opacity:1;transform:scale(.65);transition:opacity .2s ease,transform .25s cubic-bezier(.34,1.56,.64,1),background .15s ease,color .15s ease,border-color .15s ease,box-shadow .2s ease}.cc-sn-toggle:focus-visible{outline:2px solid var(--cc-side-nav-active-bg, #E63E30);outline-offset:2px}.cc-sn-toggle .cc-sn-chevron{width:12px;height:12px;flex-shrink:0;display:block;transition:transform .3s cubic-bezier(.4,0,.2,1)}:host:hover .cc-sn-toggle{opacity:1;transform:scale(1)}:host:hover .cc-sn-toggle:hover,:host.cc-side-nav-host-collapsed .cc-sn-toggle:hover{background:var(--cc-side-nav-active-bg, #E63E30);color:var(--cc-side-nav-active-color, #ffffff);border-color:transparent;box-shadow:0 4px 14px #0000001a,0 1px 4px #0000001a;transform:scale(1.12)}:host.cc-side-nav-host-collapsed .cc-sn-toggle{opacity:1;transform:scale(1);box-shadow:0 2px 8px #00000021,0 0 0 1.5px #00000014}:host.cc-side-nav-host-collapsed .cc-sn-chevron{transform:rotate(180deg)}.cc-side-nav{display:flex;flex-direction:column;gap:var(--cc-side-nav-gap-sections, 24px);padding:var(--cc-side-nav-padding, 16px);width:var(--cc-side-nav-width, 220px);min-width:var(--cc-side-nav-width, 220px);box-sizing:border-box;background-color:var(--cc-side-nav-bg, #ffffff);border-right:1px solid var(--cc-side-nav-border-color, rgba(0, 0, 0, .08));height:100%;overflow-y:auto;overflow-x:hidden;transition:width .3s cubic-bezier(.4,0,.2,1),min-width .3s cubic-bezier(.4,0,.2,1),padding .3s cubic-bezier(.4,0,.2,1)}.cc-side-nav::-webkit-scrollbar{width:3px}.cc-side-nav::-webkit-scrollbar-track{background:transparent}.cc-side-nav::-webkit-scrollbar-thumb{background:#00000026;border-radius:2px}.cc-side-nav::-webkit-scrollbar-thumb:hover{background:#0000004d}.cc-side-nav.collapsed{width:var(--cc-side-nav-collapsed-width, 56px);min-width:var(--cc-side-nav-collapsed-width, 56px);padding:var(--cc-side-nav-padding, 16px) 8px}.cc-side-nav.collapsed .cc-side-nav-link{justify-content:center;gap:0;padding:10px}.cc-side-nav.collapsed .cc-side-nav-icon{font-size:20px}.cc-side-nav-section{display:flex;flex-direction:column;gap:12px}.cc-side-nav-heading-row{display:flex;align-items:center;justify-content:space-between;min-height:28px}.cc-side-nav-heading{margin:0;padding:0 16px;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif);font-weight:var(--cc-side-nav-heading-font-weight, 500);font-style:normal;font-size:var(--cc-side-nav-heading-font-size, 16px);text-transform:uppercase;color:var(--cc-side-nav-heading-color, #3C4043);flex:1}.cc-side-nav-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--cc-side-nav-item-gap, 4px)}.cc-side-nav-list-item{margin:0;padding:0}.cc-side-nav-link{display:flex;align-items:center;gap:12px;padding:var(--cc-side-nav-item-padding, 12px 16px);text-decoration:none;cursor:pointer;border-radius:var(--cc-side-nav-item-border-radius, 8px);transition:background-color .2s ease,opacity .2s ease;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif);font-weight:var(--cc-side-nav-item-font-weight, 400);font-style:normal;font-size:var(--cc-side-nav-item-font-size, 14px);color:var(--cc-side-nav-item-color, #5F6368)}.cc-side-nav-link:hover:not(.disabled){background-color:var(--cc-side-nav-item-hover-bg, rgba(30, 30, 45, .08));color:var(--cc-side-nav-item-hover-color, #1e1e2d)}.cc-side-nav-link.active{background:var(--cc-side-nav-active-bg, #1e1e2d);opacity:1;border-radius:var(--cc-side-nav-item-border-radius, 8px);font-weight:var(--cc-side-nav-active-font-weight, 500);color:var(--cc-side-nav-active-color, #ffffff)}.cc-side-nav-link.active:hover{background-color:var(--cc-side-nav-active-hover-bg, #2a2a3d);color:var(--cc-side-nav-active-color, #ffffff)}.cc-side-nav-link.disabled{cursor:not-allowed;opacity:var(--cc-side-nav-disabled-opacity, .5)}.cc-side-nav-icon{display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0}.cc-side-nav-label{flex:1;white-space:nowrap;overflow:hidden;max-width:200px;opacity:1;transition:opacity .15s ease,max-width .3s cubic-bezier(.4,0,.2,1)}.collapsed .cc-side-nav-label{opacity:0;max-width:0}.cc-side-nav-arrow{margin-left:auto;font-size:18px;opacity:.7;overflow:hidden;max-width:30px;flex-shrink:0;white-space:nowrap;transition:opacity .15s ease,max-width .3s cubic-bezier(.4,0,.2,1)}.collapsed .cc-side-nav-arrow{opacity:0;max-width:0}.cc-side-nav-link.active .cc-side-nav-arrow{color:var(--cc-side-nav-active-color, #FFFFFF);opacity:1}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip{margin-left:var(--cc-side-nav-tooltip-offset, 20px)!important;overflow:visible!important}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip .mdc-tooltip__surface{background-color:var(--cc-side-nav-tooltip-bg, #1e1e2d)!important;color:var(--cc-side-nav-tooltip-color, #FFFFFF)!important;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif)!important;font-size:var(--cc-side-nav-tooltip-font-size, 12px)!important;font-weight:var(--cc-side-nav-tooltip-font-weight, 500)!important;padding:var(--cc-side-nav-tooltip-padding, 8px 14px)!important;border-radius:var(--cc-side-nav-tooltip-border-radius, 6px)!important;box-shadow:var(--cc-side-nav-tooltip-shadow, 0 4px 12px rgba(0, 0, 0, .35))!important;letter-spacing:var(--cc-side-nav-tooltip-letter-spacing, .2px)!important;position:relative!important;overflow:visible!important}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip .mdc-tooltip__surface:before{content:\"\";position:absolute;left:-6px;top:50%;transform:translateY(-50%);width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:6px solid var(--cc-side-nav-tooltip-bg, #1e1e2d)}\n"] }]
11397
+ args: [{ selector: 'lib-side-nav', standalone: false, template: "<nav class=\"cc-side-nav\" [class.collapsed]=\"collapsed\" role=\"navigation\" [ngStyle]=\"customStyles\">\r\n\r\n <div class=\"cc-side-nav-section\" *ngFor=\"let section of filteredSections; let i = index\">\r\n\r\n <div class=\"cc-side-nav-heading-row\" *ngIf=\"section.heading && !collapsed\">\r\n <h3 class=\"cc-side-nav-heading\">{{ section.heading }}</h3>\r\n </div>\r\n\r\n <ul class=\"cc-side-nav-list\">\r\n <li *ngFor=\"let item of section.items\" class=\"cc-side-nav-list-item\">\r\n <a (click)=\"onItemClick(item, $event)\" class=\"cc-side-nav-link\" [class.active]=\"item.id === activeId\"\r\n [class.disabled]=\"item.disabled\" [matTooltip]=\"item.tooltip || item.label\"\r\n [matTooltipPosition]=\"tooltipPosition\"\r\n [matTooltipClass]=\"'cc-side-nav-tooltip'\" [attr.aria-current]=\"(item.id === activeId) ? 'page' : null\"\r\n [attr.aria-disabled]=\"item.disabled ? true : null\">\r\n <span *ngIf=\"item.icon && (collapsed || !hideIconsWhenExpanded)\" class=\"cc-side-nav-icon\">\r\n <span *ngIf=\"!item.icon.includes('fa') && !item.icon.includes('bi')\" class=\"material-icons\">\r\n {{ item.icon }}\r\n </span>\r\n <i *ngIf=\"item.icon.includes('fa') || item.icon.includes('bi')\" [class]=\"item.icon\"></i>\r\n </span>\r\n <!-- Label: always in DOM, CSS transitions handle fade on collapse -->\r\n <span class=\"cc-side-nav-label\">{{ item.label }}</span>\r\n <!-- Arrow: rendered for active items regardless of collapse state; CSS hides it -->\r\n <span class=\"cc-side-nav-arrow material-icons\"\r\n *ngIf=\"(item.id === activeId) && item.showArrow !== false\">chevron_right</span>\r\n </a>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n\r\n</nav>\r\n\r\n<!--\r\n Toggle pill \u2014 always straddles the right edge of :host (right: -12px).\r\n Hidden via opacity/scale until :host is hovered; always visible when collapsed.\r\n Single chevron SVG rotates 180\u00B0 via CSS \u2014 no icon swap needed.\r\n-->\r\n<button *ngIf=\"showCollapseToggle\"\r\n class=\"cc-sn-toggle\"\r\n (click)=\"toggleCollapse()\"\r\n type=\"button\"\r\n [attr.aria-label]=\"collapsed ? 'Expand navigation' : 'Collapse navigation'\">\r\n <svg class=\"cc-sn-chevron\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 16 16\"\r\n fill=\"none\"\r\n aria-hidden=\"true\">\r\n <path d=\"M10 3L5 8L10 13\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.75\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"/>\r\n </svg>\r\n</button>\r\n", styles: [":host{display:block;height:100%;overflow:visible;position:relative;width:var(--cc-side-nav-width, 220px);transition:width .3s cubic-bezier(.4,0,.2,1);--cc-side-nav-bg: #ffffff;--cc-side-nav-border-color: rgba(0, 0, 0, .08);--cc-side-nav-width: 220px;--cc-side-nav-collapsed-width: 56px;--cc-side-nav-gap-sections: 24px;--cc-side-nav-padding: 16px;--cc-side-nav-font-family: Poppins, sans-serif;--cc-side-nav-heading-font-weight: 500;--cc-side-nav-heading-font-size: 16px;--cc-side-nav-heading-color: #3C4043;--cc-side-nav-item-gap: 4px;--cc-side-nav-item-padding: 12px 16px;--cc-side-nav-item-border-radius: 8px;--cc-side-nav-item-font-weight: 400;--cc-side-nav-item-font-size: 14px;--cc-side-nav-item-color: #5F6368;--cc-side-nav-item-hover-bg: rgba(30, 30, 45, .08);--cc-side-nav-item-hover-color: #1e1e2d;--cc-side-nav-active-bg: #1e1e2d;--cc-side-nav-active-color: #ffffff;--cc-side-nav-active-font-weight: 500;--cc-side-nav-active-hover-bg: #2a2a3d;--cc-side-nav-disabled-opacity: .5;--cc-side-nav-toggle-bg: #ffffff;--cc-side-nav-toggle-border-color: rgba(0, 0, 0, .1);--cc-side-nav-tooltip-bg: #1e1e2d;--cc-side-nav-tooltip-color: #FFFFFF;--cc-side-nav-tooltip-padding: 8px 14px;--cc-side-nav-tooltip-border-radius: 6px;--cc-side-nav-tooltip-font-size: 12px;--cc-side-nav-tooltip-font-weight: 500;--cc-side-nav-tooltip-letter-spacing: .2px;--cc-side-nav-tooltip-offset: 20px;--cc-side-nav-tooltip-shadow: 0 4px 12px rgba(0, 0, 0, .35)}:host.cc-side-nav-host-collapsed{width:var(--cc-side-nav-collapsed-width, 56px)}:host:after{content:\"\";position:absolute;top:10%;right:0;width:2px;height:80%;background:var(--cc-side-nav-active-bg, #1e1e2d);border-radius:2px;opacity:0;transition:opacity .25s ease;pointer-events:none;z-index:4}:host:hover:after{opacity:.18}:host.cc-side-nav-host-collapsed:after{display:none}.cc-sn-toggle{position:absolute;bottom:20px;right:-12px;width:30px;height:30px;border-radius:50%;border:1.5px solid var(--cc-side-nav-toggle-border-color, rgba(0, 0, 0, .1));background:var(--cc-side-nav-toggle-bg, #ffffff);cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:20;padding:0;color:var(--cc-side-nav-item-color, #5F6368);box-shadow:0 1px 4px #0000001a,0 0 0 1px #0000000a;opacity:1;transform:scale(.65);transition:opacity .2s ease,transform .25s cubic-bezier(.34,1.56,.64,1),background .15s ease,color .15s ease,border-color .15s ease,box-shadow .2s ease}.cc-sn-toggle:focus-visible{outline:2px solid var(--cc-side-nav-active-bg, #E63E30);outline-offset:2px}.cc-sn-toggle .cc-sn-chevron{width:12px;height:12px;flex-shrink:0;display:block;transition:transform .3s cubic-bezier(.4,0,.2,1)}:host:hover .cc-sn-toggle{opacity:1;transform:scale(1)}:host:hover .cc-sn-toggle:hover,:host.cc-side-nav-host-collapsed .cc-sn-toggle:hover{background:var(--cc-side-nav-active-bg, #E63E30);color:var(--cc-side-nav-active-color, #ffffff);border-color:transparent;box-shadow:0 4px 14px #0000001a,0 1px 4px #0000001a;transform:scale(1.05)}:host.cc-side-nav-host-collapsed .cc-sn-toggle{opacity:1;transform:scale(1);box-shadow:0 2px 8px #00000021,0 0 0 1.5px #00000014}:host.cc-side-nav-host-collapsed .cc-sn-chevron{transform:rotate(180deg)}.cc-side-nav{display:flex;flex-direction:column;gap:var(--cc-side-nav-gap-sections, 24px);padding:var(--cc-side-nav-padding, 16px);width:var(--cc-side-nav-width, 220px);min-width:var(--cc-side-nav-width, 220px);box-sizing:border-box;background-color:var(--cc-side-nav-bg, #ffffff);border-right:1px solid var(--cc-side-nav-border-color, rgba(0, 0, 0, .08));height:100%;overflow-y:auto;overflow-x:hidden;transition:width .3s cubic-bezier(.4,0,.2,1),min-width .3s cubic-bezier(.4,0,.2,1),padding .3s cubic-bezier(.4,0,.2,1)}.cc-side-nav::-webkit-scrollbar{width:3px}.cc-side-nav::-webkit-scrollbar-track{background:transparent}.cc-side-nav::-webkit-scrollbar-thumb{background:#00000026;border-radius:2px}.cc-side-nav::-webkit-scrollbar-thumb:hover{background:#0000004d}.cc-side-nav.collapsed{width:var(--cc-side-nav-collapsed-width, 56px);min-width:var(--cc-side-nav-collapsed-width, 56px);padding:var(--cc-side-nav-padding, 16px) 8px}.cc-side-nav.collapsed .cc-side-nav-link{justify-content:center;gap:0;padding:10px}.cc-side-nav.collapsed .cc-side-nav-icon{font-size:20px}.cc-side-nav-section{display:flex;flex-direction:column;gap:12px}.cc-side-nav-heading-row{display:flex;align-items:center;justify-content:space-between;min-height:28px}.cc-side-nav-heading{margin:0;padding:0 16px;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif);font-weight:var(--cc-side-nav-heading-font-weight, 500);font-style:normal;font-size:var(--cc-side-nav-heading-font-size, 16px);text-transform:uppercase;color:var(--cc-side-nav-heading-color, #3C4043);flex:1}.cc-side-nav-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--cc-side-nav-item-gap, 4px)}.cc-side-nav-list-item{margin:0;padding:0}.cc-side-nav-link{display:flex;align-items:center;gap:12px;padding:var(--cc-side-nav-item-padding, 12px 16px);text-decoration:none;cursor:pointer;border-radius:var(--cc-side-nav-item-border-radius, 8px);transition:background-color .2s ease,opacity .2s ease;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif);font-weight:var(--cc-side-nav-item-font-weight, 400);font-style:normal;font-size:var(--cc-side-nav-item-font-size, 14px);color:var(--cc-side-nav-item-color, #5F6368)}.cc-side-nav-link:hover:not(.disabled){background-color:var(--cc-side-nav-item-hover-bg, rgba(30, 30, 45, .08));color:var(--cc-side-nav-item-hover-color, #1e1e2d)}.cc-side-nav-link.active{background:var(--cc-side-nav-active-bg, #1e1e2d);opacity:1;border-radius:var(--cc-side-nav-item-border-radius, 8px);font-weight:var(--cc-side-nav-active-font-weight, 500);color:var(--cc-side-nav-active-color, #ffffff)}.cc-side-nav-link.active:hover{background-color:var(--cc-side-nav-active-hover-bg, #2a2a3d);color:var(--cc-side-nav-active-color, #ffffff)}.cc-side-nav-link.disabled{cursor:not-allowed;opacity:var(--cc-side-nav-disabled-opacity, .5)}.cc-side-nav-icon{display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0}.cc-side-nav-label{flex:1;white-space:wrap;overflow:hidden;max-width:200px;opacity:1;transition:opacity .15s ease,max-width .3s cubic-bezier(.4,0,.2,1)}.collapsed .cc-side-nav-label{opacity:0;max-width:0}.cc-side-nav-arrow{margin-left:auto;font-size:18px;opacity:.7;overflow:hidden;max-width:30px;flex-shrink:0;white-space:nowrap;transition:opacity .15s ease,max-width .3s cubic-bezier(.4,0,.2,1)}.collapsed .cc-side-nav-arrow{opacity:0;max-width:0}.cc-side-nav-link.active .cc-side-nav-arrow{color:var(--cc-side-nav-active-color, #FFFFFF);opacity:1}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip{margin-left:var(--cc-side-nav-tooltip-offset, 20px)!important;overflow:visible!important}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip .mdc-tooltip__surface{background-color:var(--cc-side-nav-tooltip-bg, #1e1e2d)!important;color:var(--cc-side-nav-tooltip-color, #FFFFFF)!important;font-family:var(--cc-side-nav-font-family, \"Poppins\", sans-serif)!important;font-size:var(--cc-side-nav-tooltip-font-size, 12px)!important;font-weight:var(--cc-side-nav-tooltip-font-weight, 500)!important;padding:var(--cc-side-nav-tooltip-padding, 8px 14px)!important;border-radius:var(--cc-side-nav-tooltip-border-radius, 6px)!important;box-shadow:var(--cc-side-nav-tooltip-shadow, 0 4px 12px rgba(0, 0, 0, .35))!important;letter-spacing:var(--cc-side-nav-tooltip-letter-spacing, .2px)!important;position:relative!important;overflow:visible!important}::ng-deep .mat-mdc-tooltip.cc-side-nav-tooltip .mdc-tooltip__surface:before{content:\"\";position:absolute;left:-6px;top:50%;transform:translateY(-50%);width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:6px solid var(--cc-side-nav-tooltip-bg, #1e1e2d)}\n"] }]
11138
11398
  }], propDecorators: { sections: [{
11139
11399
  type: Input
11140
11400
  }], userRoles: [{
@@ -12748,6 +13008,7 @@ class SharedUiModule {
12748
13008
  SideNavModule,
12749
13009
  FormBuilderModule,
12750
13010
  FormFieldConfigurationModule,
13011
+ TableColumnConfigurationModule,
12751
13012
  FilterTableSelectorModule], exports: [MaterialModule,
12752
13013
  AlertModule, ButtonModule, ButtonDropdownModule, ConfirmationModalModule, FilterSidebarModule, FilterModule,
12753
13014
  SummaryCardModule,
@@ -12757,6 +13018,7 @@ class SharedUiModule {
12757
13018
  SideNavModule,
12758
13019
  FormBuilderModule,
12759
13020
  FormFieldConfigurationModule,
13021
+ TableColumnConfigurationModule,
12760
13022
  FilterTableSelectorModule] });
12761
13023
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SharedUiModule, imports: [CommonModule,
12762
13024
  MaterialModule,
@@ -12768,6 +13030,7 @@ class SharedUiModule {
12768
13030
  SideNavModule,
12769
13031
  FormBuilderModule,
12770
13032
  FormFieldConfigurationModule,
13033
+ TableColumnConfigurationModule,
12771
13034
  FilterTableSelectorModule, MaterialModule,
12772
13035
  AlertModule, ButtonModule, ButtonDropdownModule, ConfirmationModalModule, FilterSidebarModule, FilterModule,
12773
13036
  SummaryCardModule,
@@ -12777,6 +13040,7 @@ class SharedUiModule {
12777
13040
  SideNavModule,
12778
13041
  FormBuilderModule,
12779
13042
  FormFieldConfigurationModule,
13043
+ TableColumnConfigurationModule,
12780
13044
  FilterTableSelectorModule] });
12781
13045
  }
12782
13046
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SharedUiModule, decorators: [{
@@ -12794,6 +13058,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
12794
13058
  SideNavModule,
12795
13059
  FormBuilderModule,
12796
13060
  FormFieldConfigurationModule,
13061
+ TableColumnConfigurationModule,
12797
13062
  FilterTableSelectorModule
12798
13063
  ],
12799
13064
  exports: [
@@ -12806,6 +13071,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
12806
13071
  SideNavModule,
12807
13072
  FormBuilderModule,
12808
13073
  FormFieldConfigurationModule,
13074
+ TableColumnConfigurationModule,
12809
13075
  FilterTableSelectorModule
12810
13076
  ],
12811
13077
  }]
@@ -14553,5 +14819,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
14553
14819
  * Generated bundle index. Do not edit.
14554
14820
  */
14555
14821
 
14556
- export { AlertComponent, AlertModule, ButtonComponent, ButtonDropdownComponent, ButtonDropdownModule, ButtonModule, CheckboxComponent, ConfigFieldNodeComponent, ConfigSchemaTreeService, ConfigSectionNodeComponent, ConfigurableFormComponent, configurableForm_examples as ConfigurableFormExamples, ConfigurableFormModule, ConfirmationModalComponent, ConfirmationModalModule, DEFAULT_ITEMS_PER_PAGE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_SIDE_NAV_TOOLTIP_POSITION, DatepickerComponent, DropdownComponent, ExpressionService, FieldConfigurationService, FieldConfiguratorComponent, FieldSelectionComponent, FilterComponent, FilterModule, FilterSidebarComponent, FilterSidebarModule, FilterTableSelectorComponent, FilterTableSelectorModule, FormBuilderModule, FormComponentsModule, FormFieldConfigurationComponent, FormFieldConfigurationModule, InputComponent, MaterialModule, NAV_ORIENTATION_DEFAULT, NAV_VARIANT_DEFAULT, NavComponent, NavModule, PAGINATION_THEME_DARK, PAGINATION_THEME_DEFAULT, PaginationComponent, PaginationModule, RadioComponent, SearchComponent, SharedUiModule, SideNavComponent, SideNavModule, SmartFormComponent, SmartFormController, smartForm_examples as SmartFormExamples, SmartFormModule, SmartTableComponent, SmartTableModule, SnackbarComponent, SnackbarModule, SnackbarService, StringUtils, SummaryCardComponent, SummaryCardModule, ToggleComponent, ValidationUtils, appendBaseUrlRecursively, clearLocalStorage, clearSessionStorage, getLocalStorageItem, getSessionStorageItem, removeLocalStorageItem, removeSessionStorageItem, setLocalStorageItem, setSessionStorageItem, translateConfig };
14822
+ export { AlertComponent, AlertModule, ButtonComponent, ButtonDropdownComponent, ButtonDropdownModule, ButtonModule, CheckboxComponent, ConfigColumnNodeComponent, ConfigFieldNodeComponent, ConfigSchemaTreeService, ConfigSectionNodeComponent, ConfigurableFormComponent, configurableForm_examples as ConfigurableFormExamples, ConfigurableFormModule, ConfirmationModalComponent, ConfirmationModalModule, DEFAULT_ITEMS_PER_PAGE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_SIDE_NAV_TOOLTIP_POSITION, DatepickerComponent, DropdownComponent, ExpressionService, FieldConfigurationService, FieldConfiguratorComponent, FieldSelectionComponent, FilterComponent, FilterModule, FilterSidebarComponent, FilterSidebarModule, FilterTableSelectorComponent, FilterTableSelectorModule, FormBuilderModule, FormComponentsModule, FormFieldConfigurationComponent, FormFieldConfigurationModule, InputComponent, MaterialModule, NAV_ORIENTATION_DEFAULT, NAV_VARIANT_DEFAULT, NavComponent, NavModule, PAGINATION_THEME_DARK, PAGINATION_THEME_DEFAULT, PaginationComponent, PaginationModule, RadioComponent, SearchComponent, SharedUiModule, SideNavComponent, SideNavModule, SmartFormComponent, SmartFormController, smartForm_examples as SmartFormExamples, SmartFormModule, SmartTableComponent, SmartTableModule, SnackbarComponent, SnackbarModule, SnackbarService, StringUtils, SummaryCardComponent, SummaryCardModule, TableColumnConfigurationComponent, TableColumnConfigurationModule, TableColumnConfigurationService, ToggleComponent, ValidationUtils, appendBaseUrlRecursively, clearLocalStorage, clearSessionStorage, getLocalStorageItem, getSessionStorageItem, removeLocalStorageItem, removeSessionStorageItem, setLocalStorageItem, setSessionStorageItem, translateConfig };
14557
14823
  //# sourceMappingURL=commons-shared-web-ui.mjs.map