@alfresco/adf-core
Version:
951 lines • 57.2 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, Input, Inject, ChangeDetectionStrategy, ViewEncapsulation, Component, Directive, inject, Injectable, Optional, provideAppInitializer } from '@angular/core';
import * as i1 from '@angular/common';
import { CommonModule, DOCUMENT } from '@angular/common';
import { BehaviorSubject, combineLatest, of } from 'rxjs';
import { tap, map, debounceTime, take, filter, switchMap } from 'rxjs/operators';
import * as i3 from '@angular/material/table';
import { MatTableModule } from '@angular/material/table';
import * as i4 from '@angular/material/slide-toggle';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import * as i5 from '@angular/material/toolbar';
import { MatToolbarModule } from '@angular/material/toolbar';
import * as i6 from '@angular/material/icon';
import { MatIconModule } from '@angular/material/icon';
import * as i7 from '@angular/material/button';
import { MatButtonModule } from '@angular/material/button';
import * as i8 from '@angular/material/input';
import { MatInputModule } from '@angular/material/input';
import * as i2 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import * as i9 from '@angular/material/dialog';
import { MatDialogModule } from '@angular/material/dialog';
import { TranslatePipe } from '@ngx-translate/core';
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const FeaturesServiceConfigToken = new InjectionToken('FeatureServiceConfigToken');
const FeaturesServiceToken = new InjectionToken('FeaturesService');
const WritableFeaturesServiceToken = new InjectionToken('WritableFeaturesServiceToken');
const WritableFeaturesServiceConfigToken = new InjectionToken('WritableFeaturesServiceConfigToken');
const OverridableFeaturesServiceToken = new InjectionToken('OverridableFeaturesServiceToken');
const FlagsOverrideToken = new InjectionToken('FlagsOverrideToken');
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class FlagsOverrideComponent {
constructor(featuresService, changeDetectorRef) {
this.featuresService = featuresService;
this.isEnabled = false;
this.size = 'medium';
if (this.featuresService.isEnabled$) {
this.featuresService
.isEnabled$()
.pipe(takeUntilDestroyed())
.subscribe((isEnabled) => {
this.isEnabled = isEnabled;
changeDetectorRef.markForCheck();
});
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: FlagsOverrideComponent, deps: [{ token: FeaturesServiceToken }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.6", type: FlagsOverrideComponent, isStandalone: true, selector: "adf-feature-flags-override-indicator", inputs: { size: "size" }, ngImport: i0, template: `
<span [ngClass]="['activity-indicator', size]" *ngIf="isEnabled; else inActive">🟢</span>
<ng-template #inActive><span [ngClass]="['activity-indicator', size]">🔴</span></ng-template>
`, isInline: true, styles: [".adf-activity-indicator{font-size:.885rem}\n", ".adf-activity-indicator .small{font-size:.7rem}\n", ".adf-activity-indicator .large{font-size:1.2rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: FlagsOverrideComponent, decorators: [{
type: Component,
args: [{ selector: 'adf-feature-flags-override-indicator', imports: [CommonModule], template: `
<span [ngClass]="['activity-indicator', size]" *ngIf="isEnabled; else inActive">🟢</span>
<ng-template #inActive><span [ngClass]="['activity-indicator', size]">🔴</span></ng-template>
`, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".adf-activity-indicator{font-size:.885rem}\n", ".adf-activity-indicator .small{font-size:.7rem}\n", ".adf-activity-indicator .large{font-size:1.2rem}\n"] }]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [FeaturesServiceToken]
}] }, { type: i0.ChangeDetectorRef }], propDecorators: { size: [{
type: Input
}] } });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class FlagsComponent {
constructor(featuresService, writableFeaturesService) {
this.featuresService = featuresService;
this.writableFeaturesService = writableFeaturesService;
this.displayedColumns = ['icon', 'flag', 'value'];
this.isEnabled = false;
this.inputValue = '';
this.inputValue$ = new BehaviorSubject('');
this.writableFlagChangeset = {};
if (this.featuresService.isEnabled$) {
this.featuresService
.isEnabled$()
.pipe(takeUntilDestroyed())
.subscribe((isEnabled) => {
this.isEnabled = isEnabled;
});
}
const flags$ = this.featuresService.getFlags$().pipe(tap((flags) => (this.writableFlagChangeset = flags)), map((flags) => Object.keys(flags).map((key) => ({
flag: key,
value: flags[key].current,
fictive: flags[key]?.fictive ?? false
}))));
const debouncedInputValue$ = this.inputValue$.pipe(debounceTime(100));
this.flags$ = combineLatest([flags$, debouncedInputValue$]).pipe(map(([flags, inputValue]) => {
if (!inputValue) {
return flags;
}
return flags.filter((flag) => flag.flag.includes(inputValue));
}));
this.showPlusButton$ = this.flags$.pipe(map((filteredFlags) => this.isEnabled && filteredFlags.length === 0 && this.inputValue.trim().length > 0));
}
onChange(flag, value) {
this.writableFeaturesService.setFlag(flag, value);
}
onEnable(value) {
if (value) {
this.writableFeaturesService.mergeFlags(this.writableFlagChangeset);
}
this.featuresService.enable(value);
}
onInputChange(text) {
this.inputValue$.next(text);
}
onClearInput() {
this.inputValue = '';
this.inputValue$.next('');
}
onAdd(event) {
this.showPlusButton$.pipe(take(1)).subscribe((showPlusButton) => {
if (showPlusButton && event.key === 'Enter' && event.shiftKey) {
this.writableFeaturesService.setFlag(this.inputValue, false);
}
});
}
onAddButtonClick() {
this.writableFeaturesService.setFlag(this.inputValue, false);
}
onDelete(flag) {
this.writableFeaturesService.removeFlag(flag);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: FlagsComponent, deps: [{ token: FeaturesServiceToken }, { token: WritableFeaturesServiceToken }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.6", type: FlagsComponent, isStandalone: true, selector: "adf-feature-flags-overrides", ngImport: i0, template: "<mat-toolbar class=\"adf-feature-flags-overrides-header\">\n <div class=\"adf-feature-flags-overrides-header-text\" tabindex=\"0\">\n <adf-feature-flags-override-indicator\n class=\"adf-activity-indicator\"\n size='large' />\n <span>{{ \"CORE.FEATURE-FLAGS.OVERRIDES\" | translate }}</span>\n </div>\n <mat-slide-toggle\n [checked]=\"isEnabled\"\n (change)=\"onEnable($event.checked)\" />\n <button\n class=\"adf-feature-flags-overrides-header-close\"\n mat-icon-button\n mat-dialog-close>\n <mat-icon>close</mat-icon>\n </button>\n</mat-toolbar>\n\n<ng-container *ngIf=\"flags$ | async as flags\">\n <table mat-table [dataSource]=\"flags\" class=\"adf-feature-flags-overrides-table mat-elevation-z0\">\n <ng-container matColumnDef=\"icon\">\n <th mat-header-cell class=\"adf-icon-col adf-header-cell\" *matHeaderCellDef>\n <mat-icon class=\"material-icons-outlined adf-search-icon\">search</mat-icon>\n </th>\n <td mat-cell class=\"adf-icon-col\" *matCellDef=\"let element\">\n <button mat-icon-button *ngIf=\"element.fictive; else flagFromApi\" class=\"adf-fictive-flag-button\" (click)=\"onDelete(element.flag)\">\n <mat-icon class=\"material-icons-outlined adf-custom-flag-icon\" fontIcon=\"memory\" />\n <mat-icon class=\"material-icons-outlined adf-trash-icon\" fontIcon=\"delete\" />\n </button>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"flag\">\n <th mat-header-cell class=\"flag-col header-cell\" *matHeaderCellDef>\n <mat-form-field class=\"adf-flag-form-field\" appearance=\"fill\" floatLabel=\"auto\">\n <input class=\"flag-input\" [placeholder]=\"(isEnabled ? 'CORE.FEATURE-FLAGS.FILTER_OR_ADD_NEW' : 'CORE.FEATURE-FLAGS.FILTER') | translate\" matInput type=\"text\" [(ngModel)]=\"inputValue\" (keyup)=\"onInputChange(inputValue)\" (keypress)=\"onAdd($event)\">\n </mat-form-field>\n </th>\n <td mat-cell class=\"flag-col\" *matCellDef=\"let element\">{{ element.flag }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"value\">\n <th mat-header-cell class=\"adf-val-col header-cell\" *matHeaderCellDef>\n <div class=\"adf-input-field-buttons-container\">\n <button *ngIf=\"showPlusButton$ | async\" mat-icon-button title=\"{{'CORE.FEATURE-FLAGS.ADD_NEW' | translate}}\" color=\"accent\" (click)=\"onAddButtonClick()\">\n <mat-icon class=\"material-icons-outlined\" fontIcon=\"add_circle\" />\n </button>\n <button *ngIf=\"inputValue\" matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"onClearInput()\" class=\"adf-clear-button\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n </th>\n <td mat-cell class=\"adf-val-col\" *matCellDef=\"let element\">\n <mat-slide-toggle\n [checked]=\"element.value\"\n (change)=\"onChange(element.flag, $event.checked)\"\n [disabled]=\"!isEnabled\" />\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n</ng-container>\n\n<ng-template #flagFromApi>\n <mat-icon class=\"material-icons-outlined\">cloud</mat-icon>\n</ng-template>\n\n", styles: [".adf-feature-flags-overrides-header{position:sticky;top:0;height:64px;z-index:101;display:flex}.adf-feature-flags-overrides-header .adf-activity-indicator{margin-right:12px;position:relative;top:-2px}.adf-feature-flags-overrides-header-text{flex:1}.adf-feature-flags-overrides-header-close{margin-left:12px}.adf-feature-flags-overrides-table{width:100%}.adf-feature-flags-overrides-table .adf-search-icon{position:relative;top:4px}.adf-feature-flags-overrides-table .adf-flag-form-field{width:100%;display:flex}.adf-feature-flags-overrides-table .adf-flag-form-field .mat-mdc-form-field-subscript-wrapper,.adf-feature-flags-overrides-table .adf-flag-form-field .mdc-line-ripple{display:none}.adf-feature-flags-overrides-table .adf-input-field-buttons-container{display:flex;justify-content:flex-end}.adf-feature-flags-overrides-table .adf-clear-button{margin-left:-14px}.adf-feature-flags-overrides-table .adf-fictive-flag-button{margin-left:-12px}.adf-feature-flags-overrides-table .adf-fictive-flag-button .adf-custom-flag-icon{display:block}.adf-feature-flags-overrides-table .adf-fictive-flag-button .adf-trash-icon,.adf-feature-flags-overrides-table .adf-fictive-flag-button:hover .adf-custom-flag-icon{display:none}.adf-feature-flags-overrides-table .adf-fictive-flag-button:hover .adf-trash-icon{display:block}.adf-feature-flags-overrides-table .adf-icon-col{width:56px;padding-left:24px}.adf-feature-flags-overrides-table .adf-val-col{width:85px}\n"], dependencies: [{ kind: "component", type: FlagsOverrideComponent, selector: "adf-feature-flags-override-indicator", inputs: ["size"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i3.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i3.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i3.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i3.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i3.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i3.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i3.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i3.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i3.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i3.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i4.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i5.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i7.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i9.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: FlagsComponent, decorators: [{
type: Component,
args: [{ selector: 'adf-feature-flags-overrides', imports: [
FlagsOverrideComponent,
CommonModule,
FormsModule,
MatTableModule,
MatSlideToggleModule,
MatToolbarModule,
MatIconModule,
MatButtonModule,
MatInputModule,
MatDialogModule,
TranslatePipe
], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-toolbar class=\"adf-feature-flags-overrides-header\">\n <div class=\"adf-feature-flags-overrides-header-text\" tabindex=\"0\">\n <adf-feature-flags-override-indicator\n class=\"adf-activity-indicator\"\n size='large' />\n <span>{{ \"CORE.FEATURE-FLAGS.OVERRIDES\" | translate }}</span>\n </div>\n <mat-slide-toggle\n [checked]=\"isEnabled\"\n (change)=\"onEnable($event.checked)\" />\n <button\n class=\"adf-feature-flags-overrides-header-close\"\n mat-icon-button\n mat-dialog-close>\n <mat-icon>close</mat-icon>\n </button>\n</mat-toolbar>\n\n<ng-container *ngIf=\"flags$ | async as flags\">\n <table mat-table [dataSource]=\"flags\" class=\"adf-feature-flags-overrides-table mat-elevation-z0\">\n <ng-container matColumnDef=\"icon\">\n <th mat-header-cell class=\"adf-icon-col adf-header-cell\" *matHeaderCellDef>\n <mat-icon class=\"material-icons-outlined adf-search-icon\">search</mat-icon>\n </th>\n <td mat-cell class=\"adf-icon-col\" *matCellDef=\"let element\">\n <button mat-icon-button *ngIf=\"element.fictive; else flagFromApi\" class=\"adf-fictive-flag-button\" (click)=\"onDelete(element.flag)\">\n <mat-icon class=\"material-icons-outlined adf-custom-flag-icon\" fontIcon=\"memory\" />\n <mat-icon class=\"material-icons-outlined adf-trash-icon\" fontIcon=\"delete\" />\n </button>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"flag\">\n <th mat-header-cell class=\"flag-col header-cell\" *matHeaderCellDef>\n <mat-form-field class=\"adf-flag-form-field\" appearance=\"fill\" floatLabel=\"auto\">\n <input class=\"flag-input\" [placeholder]=\"(isEnabled ? 'CORE.FEATURE-FLAGS.FILTER_OR_ADD_NEW' : 'CORE.FEATURE-FLAGS.FILTER') | translate\" matInput type=\"text\" [(ngModel)]=\"inputValue\" (keyup)=\"onInputChange(inputValue)\" (keypress)=\"onAdd($event)\">\n </mat-form-field>\n </th>\n <td mat-cell class=\"flag-col\" *matCellDef=\"let element\">{{ element.flag }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"value\">\n <th mat-header-cell class=\"adf-val-col header-cell\" *matHeaderCellDef>\n <div class=\"adf-input-field-buttons-container\">\n <button *ngIf=\"showPlusButton$ | async\" mat-icon-button title=\"{{'CORE.FEATURE-FLAGS.ADD_NEW' | translate}}\" color=\"accent\" (click)=\"onAddButtonClick()\">\n <mat-icon class=\"material-icons-outlined\" fontIcon=\"add_circle\" />\n </button>\n <button *ngIf=\"inputValue\" matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"onClearInput()\" class=\"adf-clear-button\">\n <mat-icon>cancel</mat-icon>\n </button>\n </div>\n </th>\n <td mat-cell class=\"adf-val-col\" *matCellDef=\"let element\">\n <mat-slide-toggle\n [checked]=\"element.value\"\n (change)=\"onChange(element.flag, $event.checked)\"\n [disabled]=\"!isEnabled\" />\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n</ng-container>\n\n<ng-template #flagFromApi>\n <mat-icon class=\"material-icons-outlined\">cloud</mat-icon>\n</ng-template>\n\n", styles: [".adf-feature-flags-overrides-header{position:sticky;top:0;height:64px;z-index:101;display:flex}.adf-feature-flags-overrides-header .adf-activity-indicator{margin-right:12px;position:relative;top:-2px}.adf-feature-flags-overrides-header-text{flex:1}.adf-feature-flags-overrides-header-close{margin-left:12px}.adf-feature-flags-overrides-table{width:100%}.adf-feature-flags-overrides-table .adf-search-icon{position:relative;top:4px}.adf-feature-flags-overrides-table .adf-flag-form-field{width:100%;display:flex}.adf-feature-flags-overrides-table .adf-flag-form-field .mat-mdc-form-field-subscript-wrapper,.adf-feature-flags-overrides-table .adf-flag-form-field .mdc-line-ripple{display:none}.adf-feature-flags-overrides-table .adf-input-field-buttons-container{display:flex;justify-content:flex-end}.adf-feature-flags-overrides-table .adf-clear-button{margin-left:-14px}.adf-feature-flags-overrides-table .adf-fictive-flag-button{margin-left:-12px}.adf-feature-flags-overrides-table .adf-fictive-flag-button .adf-custom-flag-icon{display:block}.adf-feature-flags-overrides-table .adf-fictive-flag-button .adf-trash-icon,.adf-feature-flags-overrides-table .adf-fictive-flag-button:hover .adf-custom-flag-icon{display:none}.adf-feature-flags-overrides-table .adf-fictive-flag-button:hover .adf-trash-icon{display:block}.adf-feature-flags-overrides-table .adf-icon-col{width:56px;padding-left:24px}.adf-feature-flags-overrides-table .adf-val-col{width:85px}\n"] }]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [FeaturesServiceToken]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [WritableFeaturesServiceToken]
}] }] });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class FeatureFlagsWrapperComponent {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: FeatureFlagsWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.6", type: FeatureFlagsWrapperComponent, isStandalone: true, selector: "adf-feature-flags-wrapper", ngImport: i0, template: `
<div class="adf-feature-flags-wrapper">
<adf-feature-flags-overrides />
</div>
`, isInline: true, styles: [".adf-feature-flags-wrapper{width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: FlagsComponent, selector: "adf-feature-flags-overrides" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: FeatureFlagsWrapperComponent, decorators: [{
type: Component,
args: [{ selector: 'adf-feature-flags-wrapper', imports: [FlagsComponent], template: `
<div class="adf-feature-flags-wrapper">
<adf-feature-flags-overrides />
</div>
`, styles: [".adf-feature-flags-wrapper{width:100%;height:100%}\n"] }]
}] });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class FeaturesDirective {
set adfForFeatures(feature) {
this.inputUpdate$.next(Array.isArray(feature) ? feature : [feature]);
}
constructor(featuresService, templateRef, viewContainer) {
this.featuresService = featuresService;
this.templateRef = templateRef;
this.viewContainer = viewContainer;
this.hasView = false;
this.inputUpdate$ = new BehaviorSubject([]);
combineLatest([this.featuresService.getFlags$(), this.inputUpdate$])
.pipe(takeUntilDestroyed())
.subscribe(([flags, features]) => this.updateView(flags, features));
}
updateView(flags, features) {
const shouldShow = features.every((feature) => flags[feature]?.current);
if (shouldShow && !this.hasView) {
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
}
else if (!shouldShow && this.hasView) {
this.viewContainer.clear();
this.hasView = false;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: FeaturesDirective, deps: [{ token: FeaturesServiceToken }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.6", type: FeaturesDirective, isStandalone: true, selector: "[adfForFeatures]", inputs: { adfForFeatures: "adfForFeatures" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: FeaturesDirective, decorators: [{
type: Directive,
args: [{
/* eslint-disable-next-line @angular-eslint/directive-selector */
selector: '[adfForFeatures]'
}]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [FeaturesServiceToken]
}] }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }], propDecorators: { adfForFeatures: [{
type: Input
}] } });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class NotFeaturesDirective {
set adfNotForFeatures(feature) {
this.inputUpdate$.next(Array.isArray(feature) ? feature : [feature]);
}
constructor(featuresService, templateRef, viewContainer) {
this.featuresService = featuresService;
this.templateRef = templateRef;
this.viewContainer = viewContainer;
this.hasView = false;
this.inputUpdate$ = new BehaviorSubject([]);
combineLatest([this.featuresService.getFlags$(), this.inputUpdate$])
.pipe(takeUntilDestroyed())
.subscribe(([flags, features]) => this.updateView(flags, features));
}
updateView(flags, features) {
const shouldShow = features.every((feature) => !flags[feature]?.current);
if (shouldShow && !this.hasView) {
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
}
else if (!shouldShow && this.hasView) {
this.viewContainer.clear();
this.hasView = false;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: NotFeaturesDirective, deps: [{ token: FeaturesServiceToken }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.6", type: NotFeaturesDirective, isStandalone: true, selector: "[adfNotForFeatures]", inputs: { adfNotForFeatures: "adfNotForFeatures" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: NotFeaturesDirective, decorators: [{
type: Directive,
args: [{
/* eslint-disable-next-line @angular-eslint/directive-selector */
selector: '[adfNotForFeatures]'
}]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [FeaturesServiceToken]
}] }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }], propDecorators: { adfNotForFeatures: [{
type: Input
}] } });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const isFeatureOn = (flag) => () => inject(FeaturesServiceToken).isOn$(flag);
class IsFeatureOn {
constructor(featuresServiceToken) {
this.featuresServiceToken = featuresServiceToken;
}
canMatch(route) {
return this.featuresServiceToken.isOn$(route?.data?.['feature']);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: IsFeatureOn, deps: [{ token: FeaturesServiceToken }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: IsFeatureOn, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: IsFeatureOn, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [FeaturesServiceToken]
}] }] });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const isFeatureOff = (flag) => () => inject(FeaturesServiceToken).isOff$(flag);
class IsFeatureOff {
constructor(featuresServiceToken) {
this.featuresServiceToken = featuresServiceToken;
}
canMatch(route) {
return this.featuresServiceToken.isOff$(route?.data?.['feature']);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: IsFeatureOff, deps: [{ token: FeaturesServiceToken }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: IsFeatureOff, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: IsFeatureOff, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [FeaturesServiceToken]
}] }] });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const isFlagsOverrideOn = () => () => inject(FlagsOverrideToken) ?? false;
class IsFlagsOverrideOn {
constructor(devToolsToken) {
this.devToolsToken = devToolsToken;
}
canMatch() {
return !!this.devToolsToken;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: IsFlagsOverrideOn, deps: [{ token: FlagsOverrideToken, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: IsFlagsOverrideOn, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: IsFlagsOverrideOn, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [FlagsOverrideToken]
}] }] });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable @typescript-eslint/no-unused-vars */
class DummyFeaturesService {
init() {
return of();
}
isOn$() {
return of(false);
}
isOff$(_key) {
return of(true);
}
getFlags$() {
return of({});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: DummyFeaturesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: DummyFeaturesService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: DummyFeaturesService, decorators: [{
type: Injectable
}] });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Provides the dummy feature flags.
*
* @returns Environment Providers for Feature Flags.
*/
function provideDummyFeatureFlags() {
return [
{ provide: FeaturesServiceToken, useClass: DummyFeaturesService },
{ provide: FlagsOverrideToken, useValue: false },
IsFeatureOn,
IsFeatureOff,
IsFlagsOverrideOn
];
}
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class FlagSetParser {
static serialize(flags) {
return Object.keys(flags).reduce((acc, key) => ({
...acc,
[key]: {
current: flags[key].current,
fictive: flags[key].fictive
}
}), {});
}
static deserialize(serializedFlags) {
return Object.keys(serializedFlags).reduce((acc, key) => ({
...acc,
[key]: {
current: serializedFlags[key].current,
previous: null,
...(serializedFlags[key].fictive ? { fictive: true } : {})
}
}), {});
}
}
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class StorageFeaturesService {
constructor(config) {
this.config = config;
this.currentFlagState = {};
this.flags = new BehaviorSubject({});
this.flags$ = this.flags.asObservable();
this.initSubject = new BehaviorSubject(false);
combineLatest({
flags: this.flags,
init: this.waitForInitializationToFinish()
}).subscribe(({ flags }) => {
this.currentFlagState = flags;
sessionStorage.setItem(this.storageKey, JSON.stringify(FlagSetParser.serialize(flags)));
});
}
get storageKey() {
return this.config?.storageKey || 'feature-flags';
}
init() {
const storedFlags = JSON.parse(sessionStorage.getItem(this.storageKey) || '{}');
const initialFlagChangeSet = FlagSetParser.deserialize(storedFlags);
this.flags.next(initialFlagChangeSet);
this.initSubject.next(true);
return of(initialFlagChangeSet);
}
isOn$(key) {
return this.flags$.pipe(map((flags) => !!flags[key]?.current));
}
isOff$(key) {
return this.flags$.pipe(map((flags) => !flags[key]?.current));
}
getFlags$() {
return this.flags$;
}
setFlag(key, value) {
let fictive = {};
if (!this.currentFlagState[key]) {
fictive = { fictive: true };
}
else {
fictive = this.currentFlagState[key]?.fictive ? { fictive: true } : {};
}
this.flags.next({
...this.currentFlagState,
[key]: {
current: value,
previous: this.currentFlagState[key]?.current ?? null,
...fictive
}
});
}
removeFlag(key) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { [key]: _, ...flags } = this.currentFlagState;
this.flags.next(flags);
}
resetFlags(flags) {
this.flags.next(Object.keys(flags).reduce((acc, key) => ({
...acc,
[key]: {
current: flags[key],
previous: null,
fictive: true
}
}), {}));
}
mergeFlags(flags) {
const mergedFlags = Object.keys(flags).reduce((acc, key) => {
const current = this.currentFlagState[key]?.current;
return {
...acc,
[key]: {
current: current ?? flags[key].current,
previous: current ?? null
}
};
}, {});
Object.keys(this.currentFlagState)
.filter((key) => !flags[key])
.forEach((key) => {
mergedFlags[key] = {
current: this.currentFlagState[key].current,
previous: this.currentFlagState[key].previous,
fictive: true
};
});
this.flags.next(mergedFlags);
}
waitForInitializationToFinish() {
return this.initSubject.pipe(filter((initialized) => !!initialized));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: StorageFeaturesService, deps: [{ token: WritableFeaturesServiceConfigToken, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: StorageFeaturesService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: StorageFeaturesService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [WritableFeaturesServiceConfigToken]
}] }] });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class DebugFeaturesService {
get storageKey() {
return `${this.config?.storageKey || 'feature-flags'}-override`;
}
constructor(overriddenFeaturesService, writableFeaturesService, config) {
this.overriddenFeaturesService = overriddenFeaturesService;
this.writableFeaturesService = writableFeaturesService;
this.config = config;
this.isInDebugModeSubject = new BehaviorSubject(false);
this.isInDebugMode$ = this.isInDebugModeSubject.asObservable();
this.initSubject = new BehaviorSubject(false);
this.init();
combineLatest({
debugMode: this.isInDebugModeSubject,
init: this.waitForInitializationToFinish()
}).subscribe(({ debugMode }) => {
sessionStorage.setItem(this.storageKey, JSON.stringify(debugMode));
});
}
isOn$(key) {
return this.isInDebugMode$.pipe(switchMap((isInDebugMode) => (isInDebugMode ? this.writableFeaturesService : this.overriddenFeaturesService).isOn$(key)));
}
isOff$(key) {
return this.isInDebugMode$.pipe(switchMap((isInDebugMode) => (isInDebugMode ? this.writableFeaturesService : this.overriddenFeaturesService).isOff$(key)));
}
/**
* Gets the flags as an observable.
*
* @returns the observable that emits the flag changeset.
*/
getFlags$() {
return this.isInDebugMode$.pipe(switchMap((isInDebugMode) => (isInDebugMode ? this.writableFeaturesService : this.overriddenFeaturesService).getFlags$()));
}
/**
* Resets the specified flags.
*
* @param flags The flags to reset.
*/
resetFlags(flags) {
this.writableFeaturesService.resetFlags(flags);
}
enable(on) {
this.isInDebugModeSubject.next(on);
}
isEnabled$() {
return this.isInDebugMode$;
}
init() {
const storedOverride = JSON.parse(sessionStorage.getItem(this.storageKey) || 'false');
this.isInDebugModeSubject.next(storedOverride);
this.initSubject.next(true);
}
waitForInitializationToFinish() {
return this.initSubject.pipe(filter((initialized) => !!initialized));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: DebugFeaturesService, deps: [{ token: OverridableFeaturesServiceToken }, { token: WritableFeaturesServiceToken }, { token: WritableFeaturesServiceConfigToken, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: DebugFeaturesService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: DebugFeaturesService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: undefined, decorators: [{
type: Inject,
args: [OverridableFeaturesServiceToken]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [WritableFeaturesServiceToken]
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [WritableFeaturesServiceConfigToken]
}] }] });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class QaFeaturesHelper {
constructor(applicationRef, debugFeaturesService) {
this.applicationRef = applicationRef;
this.debugFeaturesService = debugFeaturesService;
}
isOn(key) {
let isOn = false;
this.debugFeaturesService.isOn$(key).subscribe((on) => {
isOn = on;
});
return isOn;
}
resetFlags(flags) {
this.debugFeaturesService.resetFlags(flags);
this.applicationRef.tick();
}
enable() {
this.debugFeaturesService.enable(true);
this.applicationRef.tick();
}
disable() {
this.debugFeaturesService.enable(false);
this.applicationRef.tick();
}
isEnabled() {
let enabled = false;
this.debugFeaturesService.isEnabled$().subscribe((isEnabled) => {
enabled = isEnabled;
});
return enabled;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: QaFeaturesHelper, deps: [{ token: i0.ApplicationRef }, { token: FeaturesServiceToken }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: QaFeaturesHelper }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: QaFeaturesHelper, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: DebugFeaturesService, decorators: [{
type: Inject,
args: [FeaturesServiceToken]
}] }] });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
* @param config Configuration for the Feature Flags
* @returns Environment Providers for Feature Flags
*/
function provideDebugFeatureFlags(config) {
return [
{ provide: FlagsOverrideToken, useValue: true },
{ provide: FeaturesServiceToken, useClass: DebugFeaturesService },
{ provide: WritableFeaturesServiceConfigToken, useValue: config },
{ provide: WritableFeaturesServiceToken, useClass: StorageFeaturesService },
{ provide: QaFeaturesHelper, useClass: QaFeaturesHelper },
provideAppInitializer(() => {
const initializerFn = ((featuresService) => () => featuresService.init())(inject(WritableFeaturesServiceToken));
return initializerFn();
}),
provideAppInitializer(() => {
const initializerFn = ((qaFeaturesHelper, document) => () => {
document[config.helperExposeKeyOnDocument ?? 'featureOverrides'] = qaFeaturesHelper;
})(inject(QaFeaturesHelper), inject(DOCUMENT));
return initializerFn();
})
];
}
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const assertFeatureFlag = (flagChangeset, key) => {
const flagChangesetValue = flagChangeset[key];
if (flagChangesetValue === undefined) {
throw new Error(`ERROR FEATURE-FLAG\n'${key}' feature is not mocked, please mock '${key}' using '${provideMockFeatureFlags.name}' helper in your test\n`);
}
};
const mockFeaturesService = (flagChangeset) => ({
init: () => of(flagChangeset),
isOn$: (key) => {
assertFeatureFlag(flagChangeset, key);
return of(flagChangeset[key].current);
},
isOff$: (key) => {
assertFeatureFlag(flagChangeset, key);
return of(!flagChangeset[key].current);
},
getFlags$: () => of(flagChangeset)
});
const arrayToFlagChangeset = (featureFlags) => {
const flagChangeset = {};
featureFlags.forEach((featureFlag) => {
flagChangeset[featureFlag] = { current: true, previous: null };
});
return flagChangeset;
};
const mockFeatureFlagsToFlagChangeset = (mockFeatureFlags) => {
const flagChangeset = {};
const featureFlags = Object.keys(mockFeatureFlags);
featureFlags.forEach((featureFlag) => {
flagChangeset[featureFlag] = { current: mockFeatureFlags[featureFlag], previous: null };
});
return flagChangeset;
};
const provideMockFeatureFlags = (featureFlag) => {
if (typeof featureFlag === 'string') {
featureFlag = [featureFlag];
}
const flagChangeset = Array.isArray(featureFlag) ? arrayToFlagChangeset(featureFlag) : mockFeatureFlagsToFlagChangeset(featureFlag);
return {
provide: FeaturesServiceToken,
useValue: mockFeaturesService(flagChangeset)
};
};
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Generated bundle index. Do not edit.
*/
export { FeatureFlagsWrapperComponent, FeaturesDirective, FeaturesServiceConfigToken, FeaturesServiceToken, FlagsComponent, FlagsOverrideComponent, FlagsOverrideToken, IsFeatureOff, IsFeatureOn, IsFlagsOverrideOn, NotFeaturesDirective, OverridableFeaturesServiceToken, WritableFeaturesServiceConfigToken, WritableFeaturesServiceToken, isFeatureOff, isFeatureOn, isFlagsOverrideOn, provideDebugFeatureFlags, provideDummyFeatureFlags, provideMockFeatureFlags };
//# sourceMappingURL=alfresco-adf-core-feature-flags.mjs.map