Files
zitadel/console/src/app/modules/features/features.component.html
Max Peintner 06e1af4f78 feat(console): actions and flows (#2559)
* features, page, table, create dialog, i18n

* trigger actions service, add action dialog

* display flows, add flow dialog, duration pipe, i18n

* optim flow layout, action presets

* delete actions, flows, layout

* drag drop list, fix update

* lint

* stylelint

* fix template rest

* actions, drag, fix hasrole

* stylelint

* toast, i18n

* missing italian translations

* it

* fix ActionSearchQueries

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
2021-11-16 08:18:03 +01:00

291 lines
13 KiB
HTML

<cnsl-detail-layout [backRouterLink]="[ serviceType === FeatureServiceType.ADMIN ? '/iam/policies' : '/org']"
[title]="('FEATURES.TITLE' | translate)" [description]="'FEATURES.DESCRIPTION' | translate">
<h2>{{'FEATURES.TIER.TITLE' | translate}}</h2>
<p *ngIf="serviceType === FeatureServiceType.MGMT" class="tier-desc">{{'FEATURES.TIER.DESCRIPTION' | translate}}
{{'FEATURES.TIER.QUESTIONS' | translate}} <a href="mailto:support@zitadel.ch">support@zitadel.ch</a>.</p>
<div class="detail">
<p class="title">{{'FEATURES.TIER.NAME' | translate}}</p>
<p class="center">{{features?.tier?.name}}
<a class="ext" href="https://zitadel.ch/pricing" target="_blank">
<i class="las la-external-link-alt"></i>
</a>
</p>
</div>
<ng-container *ngIf="serviceType === FeatureServiceType.MGMT">
<mat-spinner class="spinner" diameter="20" *ngIf="customerLoading || stripeLoading"></mat-spinner>
<div class="detail" *ngIf="stripeCustomer || stripeCustomer === null">
<p class="title">{{'FEATURES.TIER.DETAILS' | translate}}
<a (click)="setCustomer()">{{'ACTIONS.EDIT' | translate}}</a>
</p>
<p>{{stripeCustomer?.contact}}</p>
<p *ngIf="stripeCustomer?.company">{{stripeCustomer?.company}}</p>
<p>{{stripeCustomer?.address}}</p>
<p *ngIf="stripeCustomer?.postal_code || stripeCustomer?.city || stripeCustomer?.country">
{{stripeCustomer?.postal_code}} {{stripeCustomer?.city}} {{stripeCustomer?.country}}
<img *ngIf="customerCountry" height="20px" width="30px"
style="margin-right: 1rem; border-radius: 2px; vertical-align: middle;"
src="../../../assets/flags/{{customerCountry.isoCode.toLowerCase()}}.png" />
</p>
</div>
<p class="error" *ngIf="(stripeCustomer || stripeCustomer === null) && !customerValid">
{{'FEATURES.TIER.CUSTOMERINVALID' | translate}}</p>
<div class="current-tier">
<a color="primary" [disabled]="!org.id || !customerValid || !stripeURL" mat-raised-button [href]="stripeURL"
target="_blank" alt="change tier">{{'FEATURES.TIER.BTN' | translate}}</a>
</div>
</ng-container>
<ng-template cnslHasRole [hasRole]="['iam.features.delete']">
<button *ngIf="serviceType === FeatureServiceType.MGMT && !isDefault" matTooltip="{{'POLICY.RESET' | translate}}"
color="warn" (click)="resetFeatures()" mat-stroked-button>
{{'POLICY.RESET' | translate}}
</button>
</ng-template>
<div class="divider"></div>
<cnsl-info-section *ngIf="isDefault"> {{'POLICY.DEFAULTLABEL' | translate}}</cnsl-info-section>
<div class="content" *ngIf="features">
<div class="row">
<span class="left-desc">{{'FEATURES.DATA.AUDITLOGRETENTION' | translate}}</span>
<span class="fill-space"></span>
<span>{{features.auditLogRetention | timestampToRetention }} {{'FEATURES.RETENTIONDAYS' |
translate}}</span>
</div>
<p class="feature-section">{{'FEATURES.HEADERS.LOGINPOLICY' | translate}}</p>
<div class="row">
<div class="featureavatar green">
<i class="icon las la-sign-in-alt"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.LOGINPOLICYUSERNAMELOGIN' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.loginPolicyUsernameLogin}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.loginPolicyUsernameLogin" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<div class="row">
<div class="featureavatar green">
<i class="icon las la-sign-in-alt"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.LOGINPOLICYPASSWORDRESET' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.loginPolicyPasswordReset}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.loginPolicyPasswordReset" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<div class="row">
<div class="featureavatar green">
<i class="icon las la-sign-in-alt"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.LOGINPOLICYREGISTRATION' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.loginPolicyRegistration}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.loginPolicyRegistration" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<div class="row">
<div class="featureavatar green">
<i class="icon las la-sign-in-alt"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.LOGINPOLICYIDP' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.loginPolicyIdp}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.loginPolicyIdp" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<div class="row">
<div class="featureavatar green">
<i class="icon las la-sign-in-alt"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.LOGINPOLICYFACTORS' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.loginPolicyFactors}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.loginPolicyFactors" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<div class="row">
<div class="featureavatar green">
<i class="icon las la-sign-in-alt"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.LOGINPOLICYPASSWORDLESS' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.loginPolicyPasswordless}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.loginPolicyPasswordless" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<p class="feature-section">{{'FEATURES.HEADERS.PASSWORD' | translate}}</p>
<div class="row">
<div class="featureavatar yellow">
<mat-icon class="icon smaller" svgIcon="mdi_textbox_password"></mat-icon>
</div>
<span class="left-desc">{{'FEATURES.DATA.LOGINPOLICYCOMPLEXITYPOLICY' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.passwordComplexityPolicy}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.passwordComplexityPolicy" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<div class="row">
<div class="featureavatar yellow">
<mat-icon class="icon smaller" svgIcon="mdi_textbox_password"></mat-icon>
</div>
<span class="left-desc">{{'FEATURES.DATA.LOCKOUTPOLICY' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.lockoutPolicy}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.lockoutPolicy" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<p class="feature-section">{{'FEATURES.HEADERS.LABELPOLICY' | translate}}</p>
<div class="row">
<div class="featureavatar blue">
<i class="icon las la-swatchbook"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.LABELPOLICYPRIVATELABEL' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.labelPolicyPrivateLabel}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.labelPolicyPrivateLabel" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<div class="row">
<div class="featureavatar blue">
<i class="icon las la-swatchbook"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.LABELPOLICYWATERMARK' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.labelPolicyWatermark}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.labelPolicyWatermark" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<p class="feature-section">{{'FEATURES.HEADERS.DOMAIN' | translate}}</p>
<div class="row">
<div class="featureavatar purple">
<i class="icon las la-gem"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.CUSTOMDOMAIN' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{active: features.customDomain}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.customDomain" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<p class="feature-section">{{'FEATURES.HEADERS.TEXTSANDLINKS' | translate}}</p>
<div class="row">
<div class="featureavatar red">
<i class="icon las la-paragraph"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.CUSTOMTEXTMESSAGE' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.customTextMessage}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.customTextMessage" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<div class="row">
<div class="featureavatar red">
<i class="icon las la-paragraph"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.CUSTOMTEXTLOGIN' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.customTextLogin}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.customTextLogin" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<div class="row">
<div class="featureavatar black">
<i class="icon las la-file-contract"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.PRIVACYPOLICY' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef"
[ngTemplateOutletContext]="{active: features.privacyPolicy}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.privacyPolicy" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<p class="feature-section">{{'FEATURES.HEADERS.METADATA' | translate}}</p>
<div class="row">
<div class="featureavatar blue">
<i class="icon las la-tags"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.METADATAUSER' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{active: features.metadataUser}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl
[(ngModel)]="features.metadataUser" *ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
<div class="row">
<div class="featureavatar pink">
<i class="icon las la-exchange-alt"></i>
</div>
<span class="left-desc">{{'FEATURES.DATA.FLOWS' | translate}}</span>
<span class="fill-space"></span>
<template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{active: features.actions}"></template>
<mat-slide-toggle class="toggle" color="primary" name="hasNumber" ngDefaultControl [(ngModel)]="features.actions"
*ngIf="(['iam.features.write'] | hasRole | async)">
</mat-slide-toggle>
</div>
</div>
<div class="btn-container" *ngIf="(['iam.features.write'] | hasRole | async) === true">
<button (click)="savePolicy()" color="primary" type="submit" mat-raised-button>{{ 'ACTIONS.SAVE' | translate
}}</button>
</div>
</cnsl-detail-layout>
<ng-template #templateRef let-active="active">
<span class="state" [ngClass]="{'active': active, 'inactive': !active}">
{{active ? ('FEATURES.AVAILABLE' | translate) : ('FEATURES.UNAVAILABLE' | translate)}}
</span>
</ng-template>