fix(console): Implement generic feature toggle (#9516)

This PR implements a component which is used to render the feature
settings in a generic way.
All features besides`loginV2` and `improvedPerformance` are rendered.

Note: The feature flags are not autogenerated as the console needs
descriptions for the respective features and there are multiple types
where additional fields like text input is required

Closes #9090

---------

Co-authored-by: conblem <[email protected]>
This commit is contained in:
Max Peintner
2025-03-19 15:52:09 +00:00
committed by GitHub
co-authored by conblem
parent b418ea75bb
commit 83108d1dc3
27 changed files with 426 additions and 589 deletions
@@ -20,389 +20,13 @@
<cnsl-card *ngIf="toggleStates && featureData">
<div class="features">
<div class="feature-row" *ngIf="toggleStates.loginDefaultOrg">
<span>{{ 'SETTING.FEATURES.LOGINDEFAULTORG' | translate }}</span>
<div class="row">
<mat-button-toggle-group
class="theme-toggle"
class="buttongroup"
[(ngModel)]="toggleStates.loginDefaultOrg.state"
(change)="validateAndSave()"
name="displayview"
aria-label="Display View"
>
<mat-button-toggle [value]="ToggleState.INHERITED">
<div class="toggle-row">
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
<i
class="info-i las la-question-circle"
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
></i>
<div
*ngIf="
!!featureData.loginDefaultOrg?.enabled &&
(featureData.loginDefaultOrg?.source === Source.SOURCE_SYSTEM ||
featureData.loginDefaultOrg?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot enabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
></div>
<div
*ngIf="
!featureData.loginDefaultOrg?.enabled &&
(featureData.loginDefaultOrg?.source === Source.SOURCE_SYSTEM ||
featureData.loginDefaultOrg?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot disabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
></div>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.DISABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.ENABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
</div>
</mat-button-toggle>
</mat-button-toggle-group>
</div>
<cnsl-info-section class="feature-info">{{
'SETTING.FEATURES.LOGINDEFAULTORG_DESCRIPTION' | translate
}}</cnsl-info-section>
</div>
<div class="feature-row" *ngIf="toggleStates.oidcLegacyIntrospection">
<span>{{ 'SETTING.FEATURES.OIDCLEGACYINTROSPECTION' | translate }}</span>
<div class="row">
<mat-button-toggle-group
class="theme-toggle"
class="buttongroup"
[(ngModel)]="toggleStates.oidcLegacyIntrospection.state"
(change)="validateAndSave()"
name="displayview"
aria-label="Display View"
>
<mat-button-toggle [value]="ToggleState.INHERITED">
<div class="toggle-row">
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
<i
class="info-i las la-question-circle"
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
></i>
<div
*ngIf="
!!featureData.oidcLegacyIntrospection?.enabled &&
(featureData.oidcLegacyIntrospection?.source === Source.SOURCE_SYSTEM ||
featureData.oidcLegacyIntrospection?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot enabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
></div>
<div
*ngIf="
!featureData.oidcLegacyIntrospection?.enabled &&
(featureData.oidcLegacyIntrospection?.source === Source.SOURCE_SYSTEM ||
featureData.oidcLegacyIntrospection?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot disabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
></div>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.DISABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.ENABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
</div>
</mat-button-toggle>
</mat-button-toggle-group>
</div>
<cnsl-info-section class="feature-info">{{
'SETTING.FEATURES.OIDCLEGACYINTROSPECTION_DESCRIPTION' | translate
}}</cnsl-info-section>
</div>
<div class="feature-row" *ngIf="toggleStates.oidcTokenExchange">
<span>{{ 'SETTING.FEATURES.OIDCTOKENEXCHANGE' | translate }}</span>
<div class="row">
<mat-button-toggle-group
class="theme-toggle"
class="buttongroup"
[(ngModel)]="toggleStates.oidcTokenExchange.state"
(change)="validateAndSave()"
name="displayview"
aria-label="Display View"
>
<mat-button-toggle [value]="ToggleState.INHERITED">
<div class="toggle-row">
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
<i
class="info-i las la-question-circle"
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
></i>
<div
*ngIf="
!!featureData.oidcTokenExchange?.enabled &&
(featureData.oidcTokenExchange?.source === Source.SOURCE_SYSTEM ||
featureData.oidcTokenExchange?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot enabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
></div>
<div
*ngIf="
!featureData.oidcTokenExchange?.enabled &&
(featureData.oidcTokenExchange?.source === Source.SOURCE_SYSTEM ||
featureData.oidcTokenExchange?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot disabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
></div>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.DISABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.ENABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
</div>
</mat-button-toggle>
</mat-button-toggle-group>
</div>
<cnsl-info-section class="feature-info">{{
'SETTING.FEATURES.OIDCTOKENEXCHANGE_DESCRIPTION' | translate
}}</cnsl-info-section>
</div>
<div class="feature-row" *ngIf="toggleStates.oidcTriggerIntrospectionProjections">
<span>{{ 'SETTING.FEATURES.OIDCTRIGGERINTROSPECTIONPROJECTIONS' | translate }}</span>
<div class="row">
<mat-button-toggle-group
class="theme-toggle"
class="buttongroup"
[(ngModel)]="toggleStates.oidcTriggerIntrospectionProjections.state"
(change)="validateAndSave()"
name="displayview"
aria-label="Display View"
>
<mat-button-toggle [value]="ToggleState.INHERITED">
<div class="toggle-row">
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
<i
class="info-i las la-question-circle"
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
></i>
<div
*ngIf="
!!featureData.oidcTriggerIntrospectionProjections?.enabled &&
(featureData.oidcTriggerIntrospectionProjections?.source === Source.SOURCE_SYSTEM ||
featureData.oidcTriggerIntrospectionProjections?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot enabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
></div>
<div
*ngIf="
!featureData.oidcTriggerIntrospectionProjections?.enabled &&
(featureData.oidcTriggerIntrospectionProjections?.source === Source.SOURCE_SYSTEM ||
featureData.oidcTriggerIntrospectionProjections?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot disabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
></div>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.DISABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.ENABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
</div>
</mat-button-toggle>
</mat-button-toggle-group>
</div>
<cnsl-info-section class="feature-info">{{
'SETTING.FEATURES.OIDCTRIGGERINTROSPECTIONPROJECTIONS_DESCRIPTION' | translate
}}</cnsl-info-section>
</div>
<div class="feature-row" *ngIf="toggleStates.userSchema">
<span>{{ 'SETTING.FEATURES.USERSCHEMA' | translate }}</span>
<div class="row">
<mat-button-toggle-group
class="theme-toggle"
class="buttongroup"
[(ngModel)]="toggleStates.userSchema.state"
(change)="validateAndSave()"
name="displayview"
aria-label="Display View"
>
<mat-button-toggle [value]="ToggleState.INHERITED">
<div class="toggle-row">
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
<i
class="info-i las la-question-circle"
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
></i>
<div
*ngIf="
!!featureData.userSchema?.enabled &&
(featureData.userSchema?.source === Source.SOURCE_SYSTEM ||
featureData.userSchema?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot enabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
></div>
<div
*ngIf="
!featureData.userSchema?.enabled &&
(featureData.userSchema?.source === Source.SOURCE_SYSTEM ||
featureData.userSchema?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot disabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
></div>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.DISABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.ENABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
</div>
</mat-button-toggle>
</mat-button-toggle-group>
</div>
<cnsl-info-section class="feature-info">{{
'SETTING.FEATURES.USERSCHEMA_DESCRIPTION' | translate
}}</cnsl-info-section>
</div>
<div class="feature-row" *ngIf="toggleStates.actions">
<span>{{ 'SETTING.FEATURES.ACTIONS' | translate }}</span>
<div class="row">
<mat-button-toggle-group
class="theme-toggle"
class="buttongroup"
[(ngModel)]="toggleStates.actions.state"
(change)="validateAndSave()"
name="displayview"
aria-label="Display View"
>
<mat-button-toggle [value]="ToggleState.INHERITED">
<div class="toggle-row">
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
<i
class="info-i las la-question-circle"
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
></i>
<div
*ngIf="
!!featureData.actions?.enabled &&
(featureData.actions?.source === Source.SOURCE_SYSTEM ||
featureData.actions?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot enabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
></div>
<div
*ngIf="
!featureData.actions?.enabled &&
(featureData.actions?.source === Source.SOURCE_SYSTEM ||
featureData.actions?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot disabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
></div>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.DISABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.ENABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
</div>
</mat-button-toggle>
</mat-button-toggle-group>
</div>
<cnsl-info-section class="feature-info">{{ 'SETTING.FEATURES.ACTIONS_DESCRIPTION' | translate }}</cnsl-info-section>
</div>
<div class="feature-row" *ngIf="toggleStates.oidcSingleV1SessionTermination">
<span>{{ 'SETTING.FEATURES.OIDCSINGLEV1SESSIONTERMINATION' | translate }}</span>
<div class="row">
<mat-button-toggle-group
class="theme-toggle"
class="buttongroup"
[(ngModel)]="toggleStates.oidcSingleV1SessionTermination.state"
(change)="validateAndSave()"
name="displayview"
aria-label="Display View"
>
<mat-button-toggle [value]="ToggleState.INHERITED">
<div class="toggle-row">
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
<i
class="info-i las la-question-circle"
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
></i>
<div
*ngIf="
!!featureData.oidcSingleV1SessionTermination?.enabled &&
(featureData.oidcSingleV1SessionTermination?.source === Source.SOURCE_SYSTEM ||
featureData.oidcSingleV1SessionTermination?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot enabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
></div>
<div
*ngIf="
!featureData.oidcSingleV1SessionTermination?.enabled &&
(featureData.oidcSingleV1SessionTermination?.source === Source.SOURCE_SYSTEM ||
featureData.oidcSingleV1SessionTermination?.source === Source.SOURCE_UNSPECIFIED)
"
class="current-dot disabled"
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
></div>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.DISABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
</div>
</mat-button-toggle>
<mat-button-toggle [value]="ToggleState.ENABLED">
<div class="toggle-row">
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
</div>
</mat-button-toggle>
</mat-button-toggle-group>
</div>
<cnsl-info-section class="feature-info">{{
'SETTING.FEATURES.OIDCSINGLEV1SESSIONTERMINATION_DESCRIPTION' | translate
}}</cnsl-info-section>
</div>
<cnsl-feature-toggle
*ngFor="let key of toggleStateKeys"
[featureData]="featureData"
[toggleStates]="toggleStates"
[toggleStateKey]="key"
(toggleChange)="validateAndSave()"
></cnsl-feature-toggle>
</div>
</cnsl-card>
</div>