mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 21:57:23 +00:00
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>
This commit is contained in:
parent
b80751d7f7
commit
06e1af4f78
@ -74,6 +74,14 @@ const routes: Routes = [
|
||||
roles: ['org.read'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'actions',
|
||||
loadChildren: () => import('./pages/actions/actions.module').then(m => m.ActionsModule),
|
||||
canActivate: [AuthGuard, RoleGuard],
|
||||
data: {
|
||||
roles: ['org.read'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'grants',
|
||||
loadChildren: () => import('./pages/grants/grants.module').then(m => m.GrantsModule),
|
||||
|
@ -1,211 +1,217 @@
|
||||
<ng-container *ngIf="$any(authService.user | async) || {} as user">
|
||||
<ng-container *ngIf="((['iam.read$','iam.write$'] | hasRole)) as iamuser$">
|
||||
<mat-toolbar class="root-header">
|
||||
<button *ngIf="authenticationService.authenticated" aria-label="Toggle sidenav" mat-icon-button
|
||||
(click)="drawer.toggle()">
|
||||
<i class="icon las la-bars"></i>
|
||||
</button>
|
||||
<ng-container *ngIf="labelpolicy && !labelpolicy?.disableWatermark">
|
||||
<a class="title" [routerLink]="['/']">
|
||||
<img class="logo" alt="zitadel logo" *ngIf="componentCssClass === 'dark-theme'; else lighttheme"
|
||||
src="../assets/images/zitadel-logo-solo-light.svg" />
|
||||
<ng-template #lighttheme>
|
||||
<img alt="zitadel logo" class="logo" src="../assets/images/zitadel-logo-solo-dark.svg" />
|
||||
</ng-template>
|
||||
</a>
|
||||
<ng-container *ngIf="((['iam.read$','iam.write$'] | hasRole)) as iamuser$">
|
||||
<mat-toolbar class="root-header">
|
||||
<button *ngIf="authenticationService.authenticated" aria-label="Toggle sidenav" mat-icon-button
|
||||
(click)="drawer.toggle()">
|
||||
<i class="icon las la-bars"></i>
|
||||
</button>
|
||||
<ng-container *ngIf="labelpolicy && !labelpolicy?.disableWatermark">
|
||||
<a class="title" [routerLink]="['/']">
|
||||
<img class="logo" alt="zitadel logo" *ngIf="componentCssClass === 'dark-theme'; else lighttheme"
|
||||
src="../assets/images/zitadel-logo-solo-light.svg" />
|
||||
<ng-template #lighttheme>
|
||||
<img alt="zitadel logo" class="logo" src="../assets/images/zitadel-logo-solo-dark.svg" />
|
||||
</ng-template>
|
||||
</a>
|
||||
|
||||
<svg class="slash" viewBox="0 0 24 24" width="32" height="32" stroke="currentColor" stroke-width="1"
|
||||
stroke-linecap="round" stroke-linejoin="round" fill="none" shape-rendering="geometricPrecision">
|
||||
<path d="M16.88 3.549L7.12 20.451"></path>
|
||||
</svg>
|
||||
<svg class="slash" viewBox="0 0 24 24" width="32" height="32" stroke="currentColor" stroke-width="1"
|
||||
stroke-linecap="round" stroke-linejoin="round" fill="none" shape-rendering="geometricPrecision">
|
||||
<path d="M16.88 3.549L7.12 20.451"></path>
|
||||
</svg>
|
||||
</ng-container>
|
||||
|
||||
<button class="org-button" (click)="loadOrgs()" *ngIf="user && org" mat-button [matMenuTriggerFor]="menu"
|
||||
(menuOpened)="focusFilter()">{{org?.name ? org.name : 'NO NAME'}}
|
||||
<mat-icon>
|
||||
arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu class="menu" #menu="matMenu">
|
||||
<div class="spinner-w">
|
||||
<mat-spinner diameter="20" *ngIf="orgLoading$ | async" color="accent">
|
||||
</mat-spinner>
|
||||
</div>
|
||||
|
||||
<div class="filter-wrapper">
|
||||
<input cnslInput class="filter-input" [formControl]="filterControl" autocomplete="off"
|
||||
(click)="$event.stopPropagation()" placeholder="{{'ORG.PAGES.FILTERPLACEHOLDER' | translate}}" #input>
|
||||
</div>
|
||||
|
||||
<div class="org-wrapper">
|
||||
<button [ngClass]="{'active': temporg.id === org?.id}" [disabled]="!temporg.id"
|
||||
*ngFor="let temporg of orgs$ | async" mat-menu-item (click)="setActiveOrg(temporg)">
|
||||
{{temporg?.name ? temporg.name : 'NO NAME'}}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button class="show-all" mat-menu-item [routerLink]="[ '/org/overview' ]">{{'MENU.SHOWORGS' |
|
||||
translate}}</button>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['org.create','iam.write']">
|
||||
<button mat-menu-item [routerLink]="[ '/org/create' ]">
|
||||
<mat-icon class="avatar">add</mat-icon>
|
||||
{{'MENU.NEWORG' | translate}}
|
||||
</button>
|
||||
</ng-template>
|
||||
</mat-menu>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<a class="doc-link" href="https://docs.zitadel.ch" mat-stroked-button target="_blank">{{'MENU.DOCUMENTATION'
|
||||
| translate}}</a>
|
||||
<div (clickOutside)="closeAccountCard()" class="icon-container">
|
||||
<cnsl-avatar
|
||||
*ngIf="user && (user.human?.profile?.displayName || (user.human?.profile?.firstName && user.human?.profile?.lastName))"
|
||||
class="avatar dontcloseonclick" (click)="showAccount = !showAccount" [active]="showAccount"
|
||||
[avatarUrl]="user.human?.profile?.avatarUrl || ''" [forColor]="user?.preferredLoginName"
|
||||
[name]="user.human.profile.displayName ? user.human.profile.displayName : (user.human.profile.firstName + ' '+ user.human.profile.lastName)"
|
||||
[size]="38">
|
||||
</cnsl-avatar>
|
||||
<cnsl-accounts-card @accounts class="a_card mat-elevation-z1" *ngIf="showAccount"
|
||||
(closedCard)="showAccount = false" [user]="user" [iamuser]="iamuser$ | async">
|
||||
</cnsl-accounts-card>
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
<mat-drawer-container class="main-container">
|
||||
<mat-drawer #drawer class="sidenav" [mode]="(isHandset$ | async) ? 'over' : 'side'"
|
||||
[opened]="(isHandset$ | async) === false && authenticationService.authenticated">
|
||||
<div class="side-column">
|
||||
<div class="list">
|
||||
<a @navitem class="nav-item" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }"
|
||||
[routerLink]="['/']">
|
||||
<i class="icon las la-home"></i>
|
||||
<span class="label">{{ 'MENU.DASHBOARD' | translate }}</span>
|
||||
</a>
|
||||
|
||||
<ng-container *ngIf="authenticationService.authenticationChanged | async">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.PERSONAL' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }"
|
||||
[routerLink]="['/users/me']">
|
||||
<i class="icon las la-user-circle"></i>
|
||||
<span class="label">{{ 'MENU.PERSONAL_INFO' | translate }}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<button class="org-button" (click)="loadOrgs()" *ngIf="user && org" mat-button [matMenuTriggerFor]="menu"
|
||||
(menuOpened)="focusFilter()">{{org?.name ? org.name : 'NO NAME'}}
|
||||
<mat-icon>
|
||||
arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu class="menu" #menu="matMenu">
|
||||
<div class="spinner-w">
|
||||
<mat-spinner diameter="20" *ngIf="orgLoading$ | async" color="accent">
|
||||
</mat-spinner>
|
||||
<div *ngIf="org" [@navAnimation]="org">
|
||||
<ng-template cnslHasRole [hasRole]="['org.read']">
|
||||
<div @navitem class="divider">
|
||||
<div class="line"></div>
|
||||
<span>{{org?.name ? org.name : ('MENU.ORGSECTION' | translate)}}</span>
|
||||
<div class="hiddenline"></div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<div class="filter-wrapper">
|
||||
<input cnslInput class="filter-input" [formControl]="filterControl" autocomplete="off"
|
||||
(click)="$event.stopPropagation()" placeholder="{{'ORG.PAGES.FILTERPLACEHOLDER' | translate}}"
|
||||
#input>
|
||||
</div>
|
||||
<ng-template cnslHasRole [hasRole]="['org.read']">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.ORG' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/org']">
|
||||
<i class="icon las la-cog"></i>
|
||||
<span class="label">{{'MENU.ORGANIZATION' | translate}}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<div class="org-wrapper">
|
||||
<button [ngClass]="{'active': temporg.id === org?.id}" [disabled]="!temporg.id"
|
||||
*ngFor="let temporg of orgs$ | async" mat-menu-item (click)="setActiveOrg(temporg)">
|
||||
{{temporg?.name ? temporg.name : 'NO NAME'}}
|
||||
</button>
|
||||
</div>
|
||||
<ng-template cnslHasRole [hasRole]="['project.read(:[0-9]*)?']">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.SELFPROJECTS' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/projects']">
|
||||
<i class="icon las la-layer-group"></i>
|
||||
|
||||
<button class="show-all" mat-menu-item [routerLink]="[ '/org/overview' ]">{{'MENU.SHOWORGS' |
|
||||
translate}}</button>
|
||||
<div class="c_label">
|
||||
<span> {{'MENU.PROJECT' | translate}} </span>
|
||||
<span *ngIf="(mgmtService?.ownedProjectsCount | async)"
|
||||
class="count">{{mgmtService?.ownedProjectsCount | async}}</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.GRANTEDPROJECTS' | translate}}"
|
||||
*ngIf="mgmtService?.grantedProjectsCount && (mgmtService?.grantedProjectsCount | async)"
|
||||
class="nav-item" [routerLinkActive]="['active']" [routerLink]="[ '/granted-projects']">
|
||||
<i class="icon las la-layer-group"></i>
|
||||
<div class="c_label">
|
||||
<span>{{ 'MENU.GRANTEDPROJECT' | translate }}</span>
|
||||
<span class="count">{{mgmtService?.grantedProjectsCount | async}}</span>
|
||||
</div>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['user.read(:[0-9]*)?']">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.HUMANUSERS' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/users/list/humans']"
|
||||
[routerLinkActiveOptions]="{ exact: true }">
|
||||
<i class="icon las la-user-friends"></i>
|
||||
<span class="label">{{ 'MENU.HUMANUSERS' | translate }}</span>
|
||||
</a>
|
||||
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.MACHINEUSERS' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/users/list/machines']"
|
||||
[routerLinkActiveOptions]="{ exact: true }">
|
||||
<i class="icon las la-users-cog"></i>
|
||||
<span class="label">{{ 'MENU.MACHINEUSERS' | translate }}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['user.grant.read(:[0-9]*)?']">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.AUTHZ' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/grants']"
|
||||
[routerLinkActiveOptions]="{ exact: true }">
|
||||
<i class="icon las la-shield-alt"></i>
|
||||
<span class="label">{{ 'MENU.GRANTS' | translate }}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<ng-template cnslHasFeature [hasFeature]="['actions']">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.ACTIONS' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/actions']"
|
||||
[routerLinkActiveOptions]="{ exact: true }">
|
||||
<i class="icon las la-exchange-alt"></i>
|
||||
<span class="label">{{ 'MENU.ACTIONS' | translate }}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="iamuser$ | async">
|
||||
<div @navitem class="divider">
|
||||
<div class="line"></div>
|
||||
<span>{{'MENU.ADMINSECTION' | translate}}</span>
|
||||
<div class="hiddenline"></div>
|
||||
</div>
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.IAMPOLICIES' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/iam','policies']">
|
||||
<i class="icon las la-cog"></i>
|
||||
<span class="label">{{'MENU.IAMPOLICIES' | translate}}</span>
|
||||
</a>
|
||||
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.IAMEVENTSTORE' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/iam', 'eventstore']">
|
||||
<i class="icon las la-database"></i>
|
||||
<span class="label">{{'MENU.IAMEVENTSTORE' | translate}}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['org.create','iam.write']">
|
||||
<button mat-menu-item [routerLink]="[ '/org/create' ]">
|
||||
<mat-icon class="avatar">add</mat-icon>
|
||||
{{'MENU.NEWORG' | translate}}
|
||||
</button>
|
||||
</ng-template>
|
||||
</mat-menu>
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<a class="doc-link" href="https://docs.zitadel.ch" mat-stroked-button target="_blank">{{'MENU.DOCUMENTATION'
|
||||
<div class="toc-line" *ngIf="privacyPolicy">
|
||||
<a class="toc" [href]="privacyPolicy.tosLink" alt="Terms and Conditions" target="_blank">{{'MENU.TOS'
|
||||
| translate}}</a>
|
||||
<div (clickOutside)="closeAccountCard()" class="icon-container">
|
||||
<cnsl-avatar
|
||||
*ngIf="user && (user.human?.profile?.displayName || (user.human?.profile?.firstName && user.human?.profile?.lastName))"
|
||||
class="avatar dontcloseonclick" (click)="showAccount = !showAccount" [active]="showAccount" [avatarUrl]="user.human?.profile?.avatarUrl || ''" [forColor]="user?.preferredLoginName"
|
||||
[name]="user.human.profile.displayName ? user.human.profile.displayName : (user.human.profile.firstName + ' '+ user.human.profile.lastName)"
|
||||
[size]="38">
|
||||
</cnsl-avatar>
|
||||
<cnsl-accounts-card @accounts class="a_card mat-elevation-z1" *ngIf="showAccount"
|
||||
(closedCard)="showAccount = false" [user]="user" [iamuser]="iamuser$ | async">
|
||||
</cnsl-accounts-card>
|
||||
<span class="slash">|</span>
|
||||
<a class="toc" [href]="privacyPolicy.privacyLink" alt="Privacy Policy " target="_blank">{{'MENU.PRIVACY'
|
||||
| translate}}</a>
|
||||
<span> </span>
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
<mat-drawer-container class="main-container">
|
||||
<mat-drawer #drawer class="sidenav" [mode]="(isHandset$ | async) ? 'over' : 'side'"
|
||||
[opened]="(isHandset$ | async) === false && authenticationService.authenticated">
|
||||
<div class="side-column">
|
||||
<div class="list">
|
||||
<a @navitem class="nav-item" [routerLinkActive]="['active']"
|
||||
[routerLinkActiveOptions]="{ exact: true }" [routerLink]="['/']">
|
||||
<i class="icon las la-home"></i>
|
||||
<span class="label">{{ 'MENU.DASHBOARD' | translate }}</span>
|
||||
</a>
|
||||
|
||||
<ng-container *ngIf="authenticationService.authenticationChanged | async">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.PERSONAL' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }"
|
||||
[routerLink]="['/users/me']">
|
||||
<i class="icon las la-user-circle"></i>
|
||||
<span class="label">{{ 'MENU.PERSONAL_INFO' | translate }}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<div *ngIf="org" [@navAnimation]="org">
|
||||
<ng-template cnslHasRole [hasRole]="['org.read']">
|
||||
<div @navitem class="divider">
|
||||
<div class="line"></div>
|
||||
<span>{{org?.name ? org.name : ('MENU.ORGSECTION' | translate)}}</span>
|
||||
<div class="hiddenline"></div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['org.read']">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.ORG' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/org']">
|
||||
<i class="icon las la-cog"></i>
|
||||
<span class="label">{{'MENU.ORGANIZATION' | translate}}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['project.read(:[0-9]*)?']">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.SELFPROJECTS' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/projects']">
|
||||
<i class="icon las la-layer-group"></i>
|
||||
|
||||
<div class="c_label">
|
||||
<span> {{'MENU.PROJECT' | translate}} </span>
|
||||
<span *ngIf="(mgmtService?.ownedProjectsCount | async)"
|
||||
class="count">{{mgmtService?.ownedProjectsCount | async}}</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.GRANTEDPROJECTS' | translate}}"
|
||||
*ngIf="mgmtService?.grantedProjectsCount && (mgmtService?.grantedProjectsCount | async)"
|
||||
class="nav-item" [routerLinkActive]="['active']"
|
||||
[routerLink]="[ '/granted-projects']">
|
||||
<i class="icon las la-layer-group"></i>
|
||||
<div class="c_label">
|
||||
<span>{{ 'MENU.GRANTEDPROJECT' | translate }}</span>
|
||||
<span class="count">{{mgmtService?.grantedProjectsCount | async}}</span>
|
||||
</div>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['user.read(:[0-9]*)?']">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.HUMANUSERS' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/users/list/humans']"
|
||||
[routerLinkActiveOptions]="{ exact: true }">
|
||||
<i class="icon las la-user-friends"></i>
|
||||
<span class="label">{{ 'MENU.HUMANUSERS' | translate }}</span>
|
||||
</a>
|
||||
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.MACHINEUSERS' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/users/list/machines']"
|
||||
[routerLinkActiveOptions]="{ exact: true }">
|
||||
<i class="icon las la-users-cog"></i>
|
||||
<span class="label">{{ 'MENU.MACHINEUSERS' | translate }}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="['user.grant.read(:[0-9]*)?']">
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.AUTHZ' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/grants']"
|
||||
[routerLinkActiveOptions]="{ exact: true }">
|
||||
<i class="icon las la-shield-alt"></i>
|
||||
<span class="label">{{ 'MENU.GRANTS' | translate }}</span>
|
||||
</a>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="iamuser$ | async">
|
||||
<div @navitem class="divider">
|
||||
<div class="line"></div>
|
||||
<span>{{'MENU.ADMINSECTION' | translate}}</span>
|
||||
<div class="hiddenline"></div>
|
||||
</div>
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.IAMPOLICIES' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/iam','policies']">
|
||||
<i class="icon las la-cog"></i>
|
||||
<span class="label">{{'MENU.IAMPOLICIES' | translate}}</span>
|
||||
</a>
|
||||
|
||||
<a @navitem matTooltip="{{'MENU.TOOLTIP.IAMEVENTSTORE' | translate}}" class="nav-item"
|
||||
[routerLinkActive]="['active']" [routerLink]="[ '/iam', 'eventstore']">
|
||||
<i class="icon las la-database"></i>
|
||||
<span class="label">{{'MENU.IAMEVENTSTORE' | translate}}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<div class="toc-line" *ngIf="privacyPolicy">
|
||||
<a class="toc" [href]="privacyPolicy.tosLink" alt="Terms and Conditions"
|
||||
target="_blank">{{'MENU.TOS'
|
||||
| translate}}</a>
|
||||
<span class="slash">|</span>
|
||||
<a class="toc" [href]="privacyPolicy.privacyLink" alt="Privacy Policy "
|
||||
target="_blank">{{'MENU.PRIVACY'
|
||||
| translate}}</a>
|
||||
<span> </span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
</div>
|
||||
</mat-drawer>
|
||||
<mat-drawer-content class="content">
|
||||
<div class="router" [@routeAnimations]="prepareRoute(outlet)">
|
||||
<router-outlet #outlet="outlet"></router-outlet>
|
||||
</div>
|
||||
</mat-drawer-content>
|
||||
</mat-drawer-container>
|
||||
<div @adminline *ngIf="iamuser$ | async" class="admin-line" [ngClass]="{'expanded': !hideAdminWarn}"
|
||||
matTooltip="IAM Administrator">
|
||||
<button [matTooltip]="!hideAdminWarn ? 'Unpin': 'Pin'" (click)="toggleAdminHide()" mat-icon-button>
|
||||
<mat-icon *ngIf="!hideAdminWarn" svgIcon="mdi_pin"></mat-icon>
|
||||
<mat-icon *ngIf="hideAdminWarn" svgIcon="mdi_pin_outline"></mat-icon>
|
||||
</button>
|
||||
<span>{{'MENU.IAMADMIN' | translate}}</span>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</mat-drawer>
|
||||
<mat-drawer-content class="content">
|
||||
<div class="router" [@routeAnimations]="prepareRoute(outlet)">
|
||||
<router-outlet #outlet="outlet"></router-outlet>
|
||||
</div>
|
||||
</mat-drawer-content>
|
||||
</mat-drawer-container>
|
||||
<div @adminline *ngIf="iamuser$ | async" class="admin-line" [ngClass]="{'expanded': !hideAdminWarn}"
|
||||
matTooltip="IAM Administrator">
|
||||
<button [matTooltip]="!hideAdminWarn ? 'Unpin': 'Pin'" (click)="toggleAdminHide()" mat-icon-button>
|
||||
<mat-icon *ngIf="!hideAdminWarn" svgIcon="mdi_pin"></mat-icon>
|
||||
<mat-icon *ngIf="hideAdminWarn" svgIcon="mdi_pin_outline"></mat-icon>
|
||||
</button>
|
||||
<span>{{'MENU.IAMADMIN' | translate}}</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
@ -165,6 +165,16 @@ export class AppComponent implements OnDestroy {
|
||||
|
||||
this.matIconRegistry.addSvgIcon('mdi_api', this.domSanitizer.bypassSecurityTrustResourceUrl('assets/mdi/api.svg'));
|
||||
|
||||
this.matIconRegistry.addSvgIcon(
|
||||
'mdi_arrow_right_bottom',
|
||||
this.domSanitizer.bypassSecurityTrustResourceUrl('assets/mdi/arrow-right-bottom.svg'),
|
||||
);
|
||||
|
||||
this.matIconRegistry.addSvgIcon(
|
||||
'mdi_arrow_decision',
|
||||
this.domSanitizer.bypassSecurityTrustResourceUrl('assets/mdi/arrow-decision-outline.svg'),
|
||||
);
|
||||
|
||||
this.activatedRoute.queryParams.pipe(takeUntil(this.destroy$)).subscribe((route) => {
|
||||
const { org } = route;
|
||||
if (org) {
|
||||
|
@ -30,6 +30,7 @@ import { SubscriptionService } from 'src/app/services/subscription.service';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { HasFeatureModule } from './directives/has-feature/has-feature.module';
|
||||
import { HasRoleModule } from './directives/has-role/has-role.module';
|
||||
import { OutsideClickModule } from './directives/outside-click/outside-click.module';
|
||||
import { AccountsCardModule } from './modules/accounts-card/accounts-card.module';
|
||||
@ -118,6 +119,7 @@ const authConfig: AuthConfig = {
|
||||
InputModule,
|
||||
HasRolePipeModule,
|
||||
HasFeaturePipeModule,
|
||||
HasFeatureModule,
|
||||
MatProgressBarModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatToolbarModule,
|
||||
|
@ -14,11 +14,11 @@ export class HasFeatureDirective {
|
||||
if (isAllowed && !this.hasView) {
|
||||
this.viewContainerRef.clear();
|
||||
this.viewContainerRef.createEmbeddedView(this.templateRef);
|
||||
} else if (this.hasView) {
|
||||
} else {
|
||||
this.viewContainerRef.clear();
|
||||
this.hasView = false;
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,18 @@
|
||||
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
|
||||
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||
|
||||
|
||||
@Directive({
|
||||
selector: '[cnslHasRole]',
|
||||
})
|
||||
|
||||
export class HasRoleDirective {
|
||||
private hasView: boolean = false;
|
||||
@Input() public set hasRole(roles: string[] | RegExp[]) {
|
||||
if (roles && roles.length > 0) {
|
||||
this.authService.isAllowed(roles).subscribe(isAllowed => {
|
||||
this.authService.isAllowed(roles).subscribe((isAllowed) => {
|
||||
if (isAllowed && !this.hasView) {
|
||||
this.viewContainerRef.clear();
|
||||
this.viewContainerRef.createEmbeddedView(this.templateRef);
|
||||
} else if (this.hasView) {
|
||||
} else {
|
||||
this.viewContainerRef.clear();
|
||||
this.hasView = false;
|
||||
}
|
||||
@ -26,5 +24,5 @@ export class HasRoleDirective {
|
||||
private authService: GrpcAuthService,
|
||||
protected templateRef: TemplateRef<any>,
|
||||
protected viewContainerRef: ViewContainerRef,
|
||||
) { }
|
||||
) {}
|
||||
}
|
||||
|
@ -1,282 +1,291 @@
|
||||
<cnsl-detail-layout [backRouterLink]="[ serviceType === FeatureServiceType.ADMIN ? '/iam/policies' : '/org']"
|
||||
[title]="('FEATURES.TITLE' | translate)" [description]="'FEATURES.DESCRIPTION' | translate">
|
||||
[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>
|
||||
<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 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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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)">
|
||||
<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.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>
|
||||
|
||||
<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 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>
|
||||
</span>
|
||||
</ng-template>
|
@ -109,6 +109,10 @@
|
||||
background: linear-gradient(40deg, #3b82f6 30%, #4f46e5);
|
||||
}
|
||||
|
||||
&.pink {
|
||||
background: linear-gradient(40deg, #db2777 30%, #be185d);
|
||||
}
|
||||
|
||||
&.yellow {
|
||||
background: linear-gradient(40deg, #f59e0b 30%, #b45309);
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ export class FeaturesComponent implements OnDestroy {
|
||||
req.setPrivacyPolicy(this.features.privacyPolicy);
|
||||
req.setMetadataUser(this.features.metadataUser);
|
||||
req.setLockoutPolicy(this.features.lockoutPolicy);
|
||||
req.setActions(this.features.actions);
|
||||
|
||||
this.adminService.setOrgFeatures(req).then(() => {
|
||||
this.toast.showInfo('POLICY.TOAST.SET', true);
|
||||
@ -191,6 +192,7 @@ export class FeaturesComponent implements OnDestroy {
|
||||
dreq.setCustomTextMessage(this.features.customTextMessage);
|
||||
dreq.setMetadataUser(this.features.metadataUser);
|
||||
dreq.setLockoutPolicy(this.features.lockoutPolicy);
|
||||
dreq.setActions(this.features.actions);
|
||||
|
||||
this.adminService.setDefaultFeatures(dreq).then(() => {
|
||||
this.toast.showInfo('POLICY.TOAST.SET', true);
|
||||
|
@ -0,0 +1,66 @@
|
||||
<cnsl-refresh-table [loading]="loading$ | async" (refreshed)="refreshPage()" [dataSize]="dataSource?.data?.length ?? 0"
|
||||
[timestamp]="actionsResult?.details?.viewTimestamp" [selection]="selection">
|
||||
<div actions>
|
||||
<a color="primary" mat-raised-button (click)="openAddAction()">
|
||||
<mat-icon class="icon">add</mat-icon>{{ 'ACTIONS.NEW' | translate }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="table-wrapper">
|
||||
<table class="table" mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox color="primary" (change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()">
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let key">
|
||||
<mat-checkbox color="primary" (click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(key) : null" [checked]="selection.isSelected(key)">
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'FLOWS.ID' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let action"> {{ action?.id }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'FLOWS.NAME' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let action"> {{ action?.name }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="state">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'FLOWS.STATE' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let action">
|
||||
<span class="state"
|
||||
[ngClass]="{'active': action.state === ActionState.ACTION_STATE_ACTIVE,'inactive': action.state === ActionState.ACTION_STATE_INACTIVE }">
|
||||
{{'FLOWS.STATES.'+action.state | translate}}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="timeout">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'FLOWS.TIMEOUT' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let key">
|
||||
{{key.timeout | durationToSeconds}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="allowedToFail">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'FLOWS.ALLOWEDTOFAIL' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let key">
|
||||
{{key.allowedToFail}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr class="highlight" mat-row *matRowDef="let action; columns: displayedColumns;" (click)="openDialog(action)">
|
||||
</tr>
|
||||
</table>
|
||||
<cnsl-paginator #paginator class="paginator" [timestamp]="actionsResult?.details?.viewTimestamp"
|
||||
[length]="actionsResult?.details?.totalResult || 0" [pageSize]="10" [pageSizeOptions]="[5, 10, 20]"
|
||||
(page)="changePage($event)"></cnsl-paginator>
|
||||
</div>
|
||||
</cnsl-refresh-table>
|
@ -0,0 +1,37 @@
|
||||
|
||||
.table-wrapper {
|
||||
overflow: auto;
|
||||
|
||||
.table,
|
||||
.paginator {
|
||||
width: 100%;
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 0 1rem;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
outline: none;
|
||||
|
||||
button {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
button {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ActionTableComponent } from './action-table.component';
|
||||
|
||||
describe('ActionTableComponent', () => {
|
||||
let component: ActionTableComponent;
|
||||
let fixture: ComponentFixture<ActionTableComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ActionTableComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ActionTableComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,128 @@
|
||||
import { SelectionModel } from '@angular/cdk/collections';
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { PageEvent } from '@angular/material/paginator';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { PaginatorComponent } from 'src/app/modules/paginator/paginator.component';
|
||||
import { Action, ActionState } from 'src/app/proto/generated/zitadel/action_pb';
|
||||
import {
|
||||
CreateActionRequest,
|
||||
ListActionsResponse,
|
||||
UpdateActionRequest,
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
import { AddActionDialogComponent } from '../add-action-dialog/add-action-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-action-table',
|
||||
templateUrl: './action-table.component.html',
|
||||
styleUrls: ['./action-table.component.scss']
|
||||
})
|
||||
export class ActionTableComponent implements OnInit {
|
||||
@ViewChild(PaginatorComponent) public paginator!: PaginatorComponent;
|
||||
public dataSource: MatTableDataSource<Action.AsObject> = new MatTableDataSource<Action.AsObject>();
|
||||
public selection: SelectionModel<Action.AsObject> = new SelectionModel<Action.AsObject>(true, []);
|
||||
public actionsResult!: ListActionsResponse.AsObject;
|
||||
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||
@Input() public displayedColumns: string[] = ['select', 'id', 'name', 'state', 'timeout', 'allowedToFail'];
|
||||
|
||||
@Output() public changedSelection: EventEmitter<Array<Action.AsObject>> = new EventEmitter();
|
||||
|
||||
public ActionState: any = ActionState;
|
||||
constructor(public translate: TranslateService, private mgmtService: ManagementService, private dialog: MatDialog,
|
||||
private toast: ToastService) {
|
||||
this.selection.changed.subscribe(() => {
|
||||
this.changedSelection.emit(this.selection.selected);
|
||||
});
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.getData(10, 0);
|
||||
}
|
||||
|
||||
|
||||
public isAllSelected(): boolean {
|
||||
const numSelected = this.selection.selected.length;
|
||||
const numRows = this.dataSource.data.length;
|
||||
return numSelected === numRows;
|
||||
}
|
||||
|
||||
public masterToggle(): void {
|
||||
this.isAllSelected() ?
|
||||
this.selection.clear() :
|
||||
this.dataSource.data.forEach(row => this.selection.select(row));
|
||||
}
|
||||
|
||||
|
||||
public changePage(event: PageEvent): void {
|
||||
this.getData(event.pageSize, event.pageIndex * event.pageSize);
|
||||
}
|
||||
|
||||
public deleteKey(action: Action.AsObject): void {
|
||||
this.mgmtService.deleteAction(action.id).then(() => {
|
||||
this.selection.clear();
|
||||
this.toast.showInfo('FLOWS.TOAST.SELECTEDKEYSDELETED', true);
|
||||
this.getData(10, 0);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
public openAddAction(): void {
|
||||
const dialogRef = this.dialog.open(AddActionDialogComponent, {
|
||||
data: {},
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((req: CreateActionRequest) => {
|
||||
if (req) {
|
||||
this.mgmtService.createAction(req).then(resp => {
|
||||
this.refreshPage();
|
||||
}).catch((error: any) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public openDialog(action: Action.AsObject): void {
|
||||
const dialogRef = this.dialog.open(AddActionDialogComponent, {
|
||||
data: {
|
||||
action: action,
|
||||
},
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((req: UpdateActionRequest) => {
|
||||
if (req) {
|
||||
this.mgmtService.updateAction(req).then(resp => {
|
||||
this.refreshPage();
|
||||
}).catch((error: any) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async getData(limit: number, offset: number): Promise<void> {
|
||||
this.loadingSubject.next(true);
|
||||
|
||||
this.mgmtService.listActions(limit, offset).then(resp => {
|
||||
this.actionsResult = resp;
|
||||
this.dataSource.data = this.actionsResult.resultList;
|
||||
this.loadingSubject.next(false);
|
||||
}).catch((error: any) => {
|
||||
this.toast.showError(error);
|
||||
this.loadingSubject.next(false);
|
||||
});
|
||||
}
|
||||
|
||||
public refreshPage(): void {
|
||||
this.getData(this.paginator.pageSize, this.paginator.pageIndex * this.paginator.pageSize);
|
||||
}
|
||||
}
|
17
console/src/app/pages/actions/actions-routing.module.ts
Normal file
17
console/src/app/pages/actions/actions-routing.module.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { ActionsComponent } from './actions.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: ActionsComponent,
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class ActionsRoutingModule { }
|
66
console/src/app/pages/actions/actions.component.html
Normal file
66
console/src/app/pages/actions/actions.component.html
Normal file
@ -0,0 +1,66 @@
|
||||
<div class="enlarged-container">
|
||||
<h1>{{ 'FLOWS.TITLE' | translate }}</h1>
|
||||
<p class="desc">{{'FLOWS.DESCRIPTION' | translate }}</p>
|
||||
|
||||
<cnsl-info-section *ngIf="(['actions'] | hasFeature | async) === false" [featureLink]="['/org/features']" class="info"
|
||||
[type]="InfoSectionType.WARN">
|
||||
<span [innerHTML]="'FEATURES.NOTAVAILABLE' | translate: ({value: 'actions'})"></span>
|
||||
</cnsl-info-section>
|
||||
|
||||
<div class="title-section">
|
||||
<h2>{{'FLOWS.ACTIONSTITLE' | translate}}</h2>
|
||||
<i class="las la-code"></i>
|
||||
</div>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="[ 'org.action.read']">
|
||||
<cnsl-action-table (changedSelection)="selection = $event"></cnsl-action-table>
|
||||
</ng-template>
|
||||
|
||||
<div class="title-section">
|
||||
<h2>{{'FLOWS.FLOWSTITLE' | translate}}</h2>
|
||||
<i class="las la-exchange-alt"></i>
|
||||
</div>
|
||||
|
||||
<ng-template cnslHasRole [hasRole]="[ 'org.flow.read']">
|
||||
<div *ngIf="flow" class="flow">
|
||||
<cnsl-form-field class="formfield" appearance="outline">
|
||||
<cnsl-label>{{ 'FLOWS.FLOWTYPE' | translate }}</cnsl-label>
|
||||
<mat-select [formControl]="typeControl">
|
||||
<mat-option *ngFor="let type of typesForSelection" [value]="type">
|
||||
{{ 'FLOWS.TYPES.'+type | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<div class="topelements">
|
||||
<div class="flow-type mat-elevation-z1">
|
||||
<span>{{'FLOWS.TYPES.'+flow.type | translate}}</span>
|
||||
<button (click)="clearFlow()" color="warn" mat-raised-button>{{'ACTIONS.CLEAR' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="trigger-wrapper">
|
||||
<div *ngFor="let trigger of flow.triggerActionsList; index as i" class="trigger mat-elevation-z1">
|
||||
<mat-icon svgIcon="mdi_arrow_right_bottom" class="icon"></mat-icon>
|
||||
<span>{{'FLOWS.TRIGGERTYPES.'+trigger.triggerType | translate}}</span>
|
||||
<span class="fill-space"></span>
|
||||
<div class="action-wrapper" cdkDropList (cdkDropListDropped)="drop(i, trigger.actionsList, $event)">
|
||||
<div cdkDrag cdkDragLockAxis="y" cdkDragBoundary=".action-wrapper" class="action"
|
||||
*ngFor="let action of trigger.actionsList">
|
||||
<i class="las la-code"></i>
|
||||
<span>{{action.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="topbottomline"></div>
|
||||
|
||||
<button class="add-btn" mat-raised-button color="primary" (click)="openAddTrigger()">
|
||||
<span>{{'ACTIONS.NEW' | translate}}</span>
|
||||
<span *ngIf="selection && selection.length"> ({{selection.length}})</span>
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
124
console/src/app/pages/actions/actions.component.scss
Normal file
124
console/src/app/pages/actions/actions.component.scss
Normal file
@ -0,0 +1,124 @@
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: var(--grey);
|
||||
margin-bottom: 2rem;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.title-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 1rem;
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
i {
|
||||
margin-left: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.flow {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 1000px;
|
||||
|
||||
.flow-type {
|
||||
padding: 1rem 1rem;
|
||||
margin: .5rem 0;
|
||||
border-radius: .5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.topelements {
|
||||
border: 3px solid var(--color-main);
|
||||
border-radius: 1rem;
|
||||
padding: 0 .5rem;
|
||||
}
|
||||
|
||||
.trigger-wrapper {
|
||||
padding-left: 100px;
|
||||
position: relative;
|
||||
|
||||
.topbottomline {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 100px;
|
||||
left: 120px;
|
||||
width: 3px;
|
||||
z-index: -1;
|
||||
background-color: var(--color-main);
|
||||
}
|
||||
|
||||
.trigger {
|
||||
padding: .5rem 1rem;
|
||||
border-radius: .5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: var(--color-main);
|
||||
color: white;
|
||||
margin: .5rem 0;
|
||||
min-height: 40px;
|
||||
|
||||
.icon {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.action-wrapper {
|
||||
padding: 0 .5rem;
|
||||
|
||||
.action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
padding: .5rem 0;
|
||||
cursor: move;
|
||||
|
||||
i {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-self: flex-start;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cdk-drag-preview {
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
border-radius: .5rem;
|
||||
padding: 0 .5rem;
|
||||
background-color: var(--color-main);
|
||||
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, .2), 0 8px 10px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12);
|
||||
|
||||
i {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.cdk-drag-placeholder {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.cdk-drag-animating {
|
||||
transition: transform 250ms cubic-bezier(0, 0, .2, 1);
|
||||
}
|
25
console/src/app/pages/actions/actions.component.spec.ts
Normal file
25
console/src/app/pages/actions/actions.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ActionsComponent } from './actions.component';
|
||||
|
||||
describe('ActionsComponent', () => {
|
||||
let component: ActionsComponent;
|
||||
let fixture: ComponentFixture<ActionsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ActionsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ActionsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
109
console/src/app/pages/actions/actions.component.ts
Normal file
109
console/src/app/pages/actions/actions.component.ts
Normal file
@ -0,0 +1,109 @@
|
||||
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
|
||||
import { Component } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { InfoSectionType } from 'src/app/modules/info-section/info-section.component';
|
||||
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||
import { Action, Flow, FlowType, TriggerType } from 'src/app/proto/generated/zitadel/action_pb';
|
||||
import { SetTriggerActionsRequest } from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
import { AddFlowDialogComponent } from './add-flow-dialog/add-flow-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-actions',
|
||||
templateUrl: './actions.component.html',
|
||||
styleUrls: ['./actions.component.scss'],
|
||||
})
|
||||
export class ActionsComponent {
|
||||
public flow!: Flow.AsObject;
|
||||
public flowType: FlowType = FlowType.FLOW_TYPE_EXTERNAL_AUTHENTICATION;
|
||||
|
||||
public typeControl: FormControl = new FormControl(FlowType.FLOW_TYPE_EXTERNAL_AUTHENTICATION);
|
||||
|
||||
public typesForSelection: FlowType[] = [FlowType.FLOW_TYPE_EXTERNAL_AUTHENTICATION];
|
||||
|
||||
public selection: Action.AsObject[] = [];
|
||||
public InfoSectionType: any = InfoSectionType;
|
||||
|
||||
constructor(private mgmtService: ManagementService, private dialog: MatDialog, private toast: ToastService) {
|
||||
this.loadFlow();
|
||||
}
|
||||
|
||||
private loadFlow() {
|
||||
this.mgmtService.getFlow(this.flowType).then((flowResponse) => {
|
||||
if (flowResponse.flow) this.flow = flowResponse.flow;
|
||||
});
|
||||
}
|
||||
|
||||
public clearFlow(): void {
|
||||
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||
data: {
|
||||
confirmKey: 'ACTIONS.CLEAR',
|
||||
cancelKey: 'ACTIONS.CANCEL',
|
||||
titleKey: 'FLOWS.DIALOG.CLEAR.TITLE',
|
||||
descriptionKey: 'FLOWS.DIALOG.CLEAR.DESCRIPTION',
|
||||
},
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((resp) => {
|
||||
if (resp) {
|
||||
this.mgmtService
|
||||
.clearFlow(this.flowType)
|
||||
.then((resp) => {
|
||||
this.loadFlow();
|
||||
})
|
||||
.catch((error: any) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public openAddTrigger(): void {
|
||||
const dialogRef = this.dialog.open(AddFlowDialogComponent, {
|
||||
data: {
|
||||
flowType: this.flowType,
|
||||
triggerType: TriggerType.TRIGGER_TYPE_POST_AUTHENTICATION,
|
||||
actions: this.selection && this.selection.length ? this.selection : [],
|
||||
},
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((req: SetTriggerActionsRequest) => {
|
||||
if (req) {
|
||||
this.mgmtService
|
||||
.setTriggerActions(req.getActionIdsList(), req.getFlowType(), req.getTriggerType())
|
||||
.then((resp) => {
|
||||
this.loadFlow();
|
||||
})
|
||||
.catch((error: any) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
drop(triggerActionsListIndex: number, array: any[], event: CdkDragDrop<Action.AsObject[]>) {
|
||||
moveItemInArray(array, event.previousIndex, event.currentIndex);
|
||||
this.saveFlow(triggerActionsListIndex);
|
||||
}
|
||||
|
||||
saveFlow(index: number) {
|
||||
console.log(this.flow.triggerActionsList[index].actionsList.map((action) => action.id));
|
||||
this.mgmtService
|
||||
.setTriggerActions(
|
||||
this.flow.triggerActionsList[index].actionsList.map((action) => action.id),
|
||||
this.flowType,
|
||||
this.flow.triggerActionsList[index].triggerType,
|
||||
)
|
||||
.then((updateResponse) => {
|
||||
this.toast.showInfo('FLOWS.TOAST.ACTIONSSET', true);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
60
console/src/app/pages/actions/actions.module.ts
Normal file
60
console/src/app/pages/actions/actions.module.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { FormFieldModule } from 'src/app/modules/form-field/form-field.module';
|
||||
import { InfoSectionModule } from 'src/app/modules/info-section/info-section.module';
|
||||
import { InputModule } from 'src/app/modules/input/input.module';
|
||||
import { PaginatorModule } from 'src/app/modules/paginator/paginator.module';
|
||||
import { RefreshTableModule } from 'src/app/modules/refresh-table/refresh-table.module';
|
||||
import { WarnDialogModule } from 'src/app/modules/warn-dialog/warn-dialog.module';
|
||||
import { DurationToSecondsPipeModule } from 'src/app/pipes/duration-to-seconds-pipe/duration-to-seconds-pipe.module';
|
||||
import { HasFeaturePipeModule } from 'src/app/pipes/has-feature-pipe/has-feature-pipe.module';
|
||||
import { LocalizedDatePipeModule } from 'src/app/pipes/localized-date-pipe/localized-date-pipe.module';
|
||||
import { TimestampToDatePipeModule } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date-pipe.module';
|
||||
|
||||
import { ActionTableComponent } from './action-table/action-table.component';
|
||||
import { ActionsRoutingModule } from './actions-routing.module';
|
||||
import { ActionsComponent } from './actions.component';
|
||||
import { AddActionDialogComponent } from './add-action-dialog/add-action-dialog.component';
|
||||
import { AddFlowDialogComponent } from './add-flow-dialog/add-flow-dialog.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ActionsComponent, ActionTableComponent, AddActionDialogComponent, AddFlowDialogComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ActionsRoutingModule,
|
||||
TranslateModule,
|
||||
MatDialogModule,
|
||||
RefreshTableModule,
|
||||
MatTableModule,
|
||||
PaginatorModule,
|
||||
MatButtonModule,
|
||||
ReactiveFormsModule,
|
||||
MatIconModule,
|
||||
DurationToSecondsPipeModule,
|
||||
TimestampToDatePipeModule,
|
||||
LocalizedDatePipeModule,
|
||||
HasRoleModule,
|
||||
MatTooltipModule,
|
||||
MatCheckboxModule,
|
||||
InputModule,
|
||||
FormFieldModule,
|
||||
MatSelectModule,
|
||||
WarnDialogModule,
|
||||
DragDropModule,
|
||||
InfoSectionModule,
|
||||
HasFeaturePipeModule,
|
||||
],
|
||||
})
|
||||
export class ActionsModule {}
|
@ -0,0 +1,39 @@
|
||||
<span *ngIf="!id" class="title" mat-dialog-title>{{'FLOWS.DIALOG.ADD.TITLE' | translate}}</span>
|
||||
<span *ngIf="id" class="title" mat-dialog-title>{{'FLOWS.DIALOG.UPDATE.TITLE' | translate}}</span>
|
||||
|
||||
<div mat-dialog-content>
|
||||
<!-- <p class="desc"> {{'FLOWS.DIALOG.ADD.DESCRIPTION' | translate}}</p> -->
|
||||
|
||||
<cnsl-form-field class="form-field" appearance="outline">
|
||||
<cnsl-label>{{'FLOWS.NAME' | translate}}</cnsl-label>
|
||||
<input cnslInput [(ngModel)]="name">
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="form-field" appearance="outline">
|
||||
<cnsl-label>{{'FLOWS.SCRIPT' | translate}}</cnsl-label>
|
||||
<textarea class="script" cnslInput [(ngModel)]="script"></textarea>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="form-field" appearance="outline">
|
||||
<cnsl-label>{{'FLOWS.TIMEOUTINSEC' | translate}}</cnsl-label>
|
||||
<input type="number" cnslInput [(ngModel)]="durationInSec">
|
||||
</cnsl-form-field>
|
||||
|
||||
<mat-checkbox [(ngModel)]="allowedToFail">{{'FLOWS.ALLOWEDTOFAIL' | translate}}</mat-checkbox>
|
||||
</div>
|
||||
<div mat-dialog-actions class=" action">
|
||||
<button *ngIf="id" mat-stroked-button color="warn" (click)="deleteAndCloseDialog()">
|
||||
{{'ACTIONS.DELETE' | translate}}
|
||||
</button>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<button mat-button (click)="closeDialog()">
|
||||
{{'ACTIONS.CANCEL' | translate}}
|
||||
</button>
|
||||
|
||||
<button color="primary" mat-raised-button class="ok-button" [disabled]="false" (click)="closeDialogWithSuccess()">
|
||||
<span *ngIf="!id">{{'ACTIONS.ADD' | translate}}</span>
|
||||
<span *ngIf="id">{{'ACTIONS.SAVE' | translate}}</span>
|
||||
</button>
|
||||
</div>
|
@ -0,0 +1,27 @@
|
||||
.title {
|
||||
font-size: 1.2rem;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: var(--grey);
|
||||
font-size: .9rem;
|
||||
}
|
||||
|
||||
.script {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 1rem;
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.ok-button {
|
||||
margin-left: .5rem;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { AddKeyDialogComponent } from './add-key-dialog.component';
|
||||
|
||||
describe('AddKeyDialogComponent', () => {
|
||||
let component: AddKeyDialogComponent;
|
||||
let fixture: ComponentFixture<AddKeyDialogComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [AddKeyDialogComponent],
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AddKeyDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,99 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Duration } from 'google-protobuf/google/protobuf/duration_pb';
|
||||
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||
import { Action } from 'src/app/proto/generated/zitadel/action_pb';
|
||||
import { CreateActionRequest, UpdateActionRequest } from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-add-action-dialog',
|
||||
templateUrl: './add-action-dialog.component.html',
|
||||
styleUrls: ['./add-action-dialog.component.scss'],
|
||||
})
|
||||
export class AddActionDialogComponent {
|
||||
public name: string = '';
|
||||
public script: string = '';
|
||||
public durationInSec: number = 10;
|
||||
public allowedToFail: boolean = false;
|
||||
|
||||
public id: string = '';
|
||||
|
||||
constructor(
|
||||
private toast: ToastService,
|
||||
private mgmtService: ManagementService,
|
||||
private dialog: MatDialog,
|
||||
public dialogRef: MatDialogRef<AddActionDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
) {
|
||||
if (data && data.action) {
|
||||
const action: Action.AsObject = data.action;
|
||||
this.name = action.name;
|
||||
this.script = action.script;
|
||||
if (action.timeout?.seconds) {
|
||||
this.durationInSec = action.timeout?.seconds;
|
||||
}
|
||||
this.allowedToFail = action.allowedToFail;
|
||||
this.id = action.id;
|
||||
}
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
|
||||
public closeDialogWithSuccess(): void {
|
||||
if (this.id) {
|
||||
const req = new UpdateActionRequest();
|
||||
req.setId(this.id);
|
||||
req.setName(this.name);
|
||||
req.setScript(this.script);
|
||||
|
||||
const duration = new Duration();
|
||||
duration.setNanos(0);
|
||||
duration.setSeconds(this.durationInSec);
|
||||
|
||||
req.setAllowedToFail(this.allowedToFail);
|
||||
|
||||
req.setTimeout(duration)
|
||||
this.dialogRef.close(req);
|
||||
} else {
|
||||
const req = new CreateActionRequest();
|
||||
req.setName(this.name);
|
||||
req.setScript(this.script);
|
||||
|
||||
const duration = new Duration();
|
||||
duration.setNanos(0);
|
||||
duration.setSeconds(this.durationInSec);
|
||||
|
||||
req.setAllowedToFail(this.allowedToFail);
|
||||
|
||||
req.setTimeout(duration)
|
||||
this.dialogRef.close(req);
|
||||
}
|
||||
}
|
||||
|
||||
public deleteAndCloseDialog(): void {
|
||||
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||
data: {
|
||||
confirmKey: 'ACTIONS.CLEAR',
|
||||
cancelKey: 'ACTIONS.CANCEL',
|
||||
titleKey: 'FLOWS.DIALOG.DELETEACTION.TITLE',
|
||||
descriptionKey: 'FLOWS.DIALOG.DELETEACTION.DESCRIPTION',
|
||||
},
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(resp => {
|
||||
if (resp) {
|
||||
this.mgmtService.deleteAction(this.id).then(resp => {
|
||||
this.dialogRef.close();
|
||||
}).catch((error: any) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
<span class="title" mat-dialog-title>{{'FLOWS.DIALOG.ADD.TITLE' | translate}}</span>
|
||||
|
||||
<div mat-dialog-content>
|
||||
<!-- <p class="desc"> {{'FLOWS.DIALOG.ADD.DESCRIPTION' | translate}}</p> -->
|
||||
<form *ngIf="form" [formGroup]="form">
|
||||
<cnsl-form-field class="form-field" appearance="outline">
|
||||
<cnsl-label>{{'FLOWS.FLOWTYPE' | translate}}</cnsl-label>
|
||||
<mat-select formControlName="flowType">
|
||||
<mat-option *ngFor="let type of typesForSelection" [value]="type">
|
||||
{{ 'FLOWS.TYPES.'+type | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="form-field" appearance="outline">
|
||||
<cnsl-label>{{'FLOWS.TRIGGERTYPE' | translate}}</cnsl-label>
|
||||
<mat-select formControlName="triggerType" name="triggerType">
|
||||
<mat-option *ngFor="let type of triggerTypesForSelection" [value]="type">
|
||||
{{ 'FLOWS.TRIGGERTYPES.'+type | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
|
||||
<cnsl-form-field class="form-field" appearance="outline">
|
||||
<cnsl-label>{{'FLOWS.ACTIONS' | translate}}</cnsl-label>
|
||||
<mat-select formControlName="actionIdsList" name="actionIdsList" multiple>
|
||||
<mat-option *ngFor="let action of actions" [value]="action.id">
|
||||
{{ action.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</cnsl-form-field>
|
||||
</form>
|
||||
</div>
|
||||
<div mat-dialog-actions class=" action">
|
||||
<button mat-button (click)="closeDialog()">
|
||||
{{'ACTIONS.CANCEL' | translate}}
|
||||
</button>
|
||||
|
||||
<button color="primary" mat-raised-button class="ok-button" [disabled]="false" (click)="closeDialogWithSuccess()">
|
||||
<span>{{'ACTIONS.SAVE' | translate}}</span>
|
||||
</button>
|
||||
</div>
|
@ -0,0 +1,23 @@
|
||||
.title {
|
||||
font-size: 1.2rem;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: var(--grey);
|
||||
font-size: .9rem;
|
||||
}
|
||||
|
||||
.script {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.action {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 1rem;
|
||||
|
||||
.ok-button {
|
||||
margin-left: .5rem;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { AddKeyDialogComponent } from './add-key-dialog.component';
|
||||
|
||||
describe('AddKeyDialogComponent', () => {
|
||||
let component: AddKeyDialogComponent;
|
||||
let fixture: ComponentFixture<AddKeyDialogComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [AddKeyDialogComponent],
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AddKeyDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,78 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Action, FlowType, TriggerType } from 'src/app/proto/generated/zitadel/action_pb';
|
||||
import { SetTriggerActionsRequest } from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'cnsl-add-flow-dialog',
|
||||
templateUrl: './add-flow-dialog.component.html',
|
||||
styleUrls: ['./add-flow-dialog.component.scss'],
|
||||
})
|
||||
export class AddFlowDialogComponent {
|
||||
public actions: Action.AsObject[] = [];
|
||||
public typesForSelection: FlowType[] = [
|
||||
FlowType.FLOW_TYPE_EXTERNAL_AUTHENTICATION,
|
||||
];
|
||||
public triggerTypesForSelection: TriggerType[] = [
|
||||
TriggerType.TRIGGER_TYPE_POST_AUTHENTICATION,
|
||||
TriggerType.TRIGGER_TYPE_POST_CREATION,
|
||||
TriggerType.TRIGGER_TYPE_PRE_CREATION,
|
||||
];
|
||||
|
||||
public form!: FormGroup;
|
||||
constructor(
|
||||
private toast: ToastService,
|
||||
private mgmtService: ManagementService,
|
||||
private fb: FormBuilder,
|
||||
public dialogRef: MatDialogRef<AddFlowDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
) {
|
||||
this.form = this.fb.group({
|
||||
flowType: [data.flowType ? data.flowType : '', [Validators.required]],
|
||||
triggerType: [data.triggerType ? data.triggerType : '', [Validators.required]],
|
||||
actionIdsList: [data.actions ? (data.actions as Action.AsObject[]).map(a => a.id) : [], [Validators.required]],
|
||||
});
|
||||
this.getActionIds();
|
||||
}
|
||||
|
||||
private getActionIds(): Promise<void> {
|
||||
return this.mgmtService.listActions().then(resp => {
|
||||
this.actions = resp.resultList;
|
||||
}).catch((error: any) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
|
||||
public closeDialogWithSuccess(): void {
|
||||
// if (this.id) {
|
||||
// const req = new UpdateActionRequest();
|
||||
// req.setId(this.id);
|
||||
// req.setName(this.name);
|
||||
// req.setScript(this.script);
|
||||
|
||||
// const duration = new Duration();
|
||||
// duration.setNanos(0);
|
||||
// duration.setSeconds(this.durationInSec);
|
||||
|
||||
// req.setAllowedToFail(this.allowedToFail);
|
||||
|
||||
// req.setTimeout(duration)
|
||||
// this.dialogRef.close(req);
|
||||
// } else {
|
||||
const req = new SetTriggerActionsRequest();
|
||||
req.setActionIdsList(this.form.get('actionIdsList')?.value);
|
||||
req.setFlowType(this.form.get('flowType')?.value);
|
||||
req.setTriggerType(this.form.get('triggerType')?.value);
|
||||
|
||||
this.dialogRef.close(req);
|
||||
// }
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { DurationToSecondsPipe } from './duration-to-seconds.pipe';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
DurationToSecondsPipe,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
],
|
||||
exports: [
|
||||
DurationToSecondsPipe,
|
||||
],
|
||||
})
|
||||
export class DurationToSecondsPipeModule { }
|
@ -0,0 +1,25 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { Duration } from 'google-protobuf/google/protobuf/duration_pb';
|
||||
|
||||
@Pipe({
|
||||
name: 'durationToSeconds',
|
||||
})
|
||||
export class DurationToSecondsPipe implements PipeTransform {
|
||||
|
||||
transform(value?: Duration.AsObject, ...args: unknown[]): unknown {
|
||||
if (value) {
|
||||
return this.durationToSeconds(value);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
private durationToSeconds(date: Duration.AsObject): any {
|
||||
if (date?.seconds !== undefined && date?.nanos !== undefined) {
|
||||
const ms = (date.seconds * 1000 + date.nanos / 1000 / 1000);
|
||||
const secs = ms / 1000;
|
||||
return `${secs.toFixed(2)} sec`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,13 @@ import { Empty } from 'google-protobuf/google/protobuf/empty_pb';
|
||||
import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
import { FlowType, TriggerType } from '../proto/generated/zitadel/action_pb';
|
||||
import { AppQuery } from '../proto/generated/zitadel/app_pb';
|
||||
import { KeyType } from '../proto/generated/zitadel/auth_n_key_pb';
|
||||
import { ChangeQuery } from '../proto/generated/zitadel/change_pb';
|
||||
import { IDPOwnerType } from '../proto/generated/zitadel/idp_pb';
|
||||
import {
|
||||
ActionQuery,
|
||||
ActivateCustomLabelPolicyRequest,
|
||||
ActivateCustomLabelPolicyResponse,
|
||||
AddAPIAppRequest,
|
||||
@ -68,6 +70,10 @@ import {
|
||||
BulkRemoveUserGrantResponse,
|
||||
BulkSetUserMetadataRequest,
|
||||
BulkSetUserMetadataResponse,
|
||||
ClearFlowRequest,
|
||||
ClearFlowResponse,
|
||||
CreateActionRequest,
|
||||
CreateActionResponse,
|
||||
DeactivateAppRequest,
|
||||
DeactivateAppResponse,
|
||||
DeactivateOrgIDPRequest,
|
||||
@ -80,8 +86,12 @@ import {
|
||||
DeactivateProjectResponse,
|
||||
DeactivateUserRequest,
|
||||
DeactivateUserResponse,
|
||||
DeleteActionRequest,
|
||||
DeleteActionResponse,
|
||||
GenerateOrgDomainValidationRequest,
|
||||
GenerateOrgDomainValidationResponse,
|
||||
GetActionRequest,
|
||||
GetActionResponse,
|
||||
GetAppByIDRequest,
|
||||
GetAppByIDResponse,
|
||||
GetCustomDomainClaimedMessageTextRequest,
|
||||
@ -118,6 +128,8 @@ import {
|
||||
GetDefaultVerifyPhoneMessageTextResponse,
|
||||
GetFeaturesRequest,
|
||||
GetFeaturesResponse,
|
||||
GetFlowRequest,
|
||||
GetFlowResponse,
|
||||
GetGrantedProjectByIDRequest,
|
||||
GetGrantedProjectByIDResponse,
|
||||
GetHumanEmailRequest,
|
||||
@ -167,6 +179,8 @@ import {
|
||||
GetUserMetadataRequest,
|
||||
GetUserMetadataResponse,
|
||||
IDPQuery,
|
||||
ListActionsRequest,
|
||||
ListActionsResponse,
|
||||
ListAppChangesRequest,
|
||||
ListAppChangesResponse,
|
||||
ListAppKeysRequest,
|
||||
@ -344,10 +358,14 @@ import {
|
||||
SetHumanInitialPasswordRequest,
|
||||
SetPrimaryOrgDomainRequest,
|
||||
SetPrimaryOrgDomainResponse,
|
||||
SetTriggerActionsRequest,
|
||||
SetTriggerActionsResponse,
|
||||
SetUserMetadataRequest,
|
||||
SetUserMetadataResponse,
|
||||
UnlockUserRequest,
|
||||
UnlockUserResponse,
|
||||
UpdateActionRequest,
|
||||
UpdateActionResponse,
|
||||
UpdateAPIAppConfigRequest,
|
||||
UpdateAPIAppConfigResponse,
|
||||
UpdateAppRequest,
|
||||
@ -881,6 +899,87 @@ export class ManagementService {
|
||||
return this.grpcService.mgmt.listHumanLinkedIDPs(req, null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
public getAction(
|
||||
id: string,
|
||||
): Promise<GetActionResponse.AsObject> {
|
||||
const req = new GetActionRequest();
|
||||
req.setId(id);
|
||||
return this.grpcService.mgmt.getAction(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public createAction(
|
||||
req: CreateActionRequest,
|
||||
): Promise<CreateActionResponse.AsObject> {
|
||||
return this.grpcService.mgmt.createAction(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public updateAction(
|
||||
req: UpdateActionRequest,
|
||||
): Promise<UpdateActionResponse.AsObject> {
|
||||
return this.grpcService.mgmt.updateAction(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public deleteAction(
|
||||
id: string,
|
||||
): Promise<DeleteActionResponse.AsObject> {
|
||||
const req = new DeleteActionRequest();
|
||||
req.setId(id);
|
||||
return this.grpcService.mgmt.deleteAction(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public listActions(
|
||||
limit?: number,
|
||||
offset?: number,
|
||||
asc?: boolean,
|
||||
queryList?: ActionQuery[],
|
||||
): Promise<ListActionsResponse.AsObject> {
|
||||
const req = new ListActionsRequest();
|
||||
const metadata = new ListQuery();
|
||||
if (queryList) {
|
||||
req.setQueriesList(queryList);
|
||||
}
|
||||
|
||||
if (limit) {
|
||||
metadata.setLimit(limit);
|
||||
}
|
||||
if (offset) {
|
||||
metadata.setOffset(offset);
|
||||
}
|
||||
if (asc) {
|
||||
metadata.setAsc(asc);
|
||||
}
|
||||
req.setQuery(metadata);
|
||||
return this.grpcService.mgmt.listActions(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public getFlow(
|
||||
type: FlowType
|
||||
): Promise<GetFlowResponse.AsObject> {
|
||||
const req = new GetFlowRequest();
|
||||
req.setType(type);
|
||||
return this.grpcService.mgmt.getFlow(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public clearFlow(
|
||||
type: FlowType
|
||||
): Promise<ClearFlowResponse.AsObject> {
|
||||
const req = new ClearFlowRequest();
|
||||
req.setType(type);
|
||||
return this.grpcService.mgmt.clearFlow(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public setTriggerActions(
|
||||
actionIdsList: string[],
|
||||
type: FlowType,
|
||||
triggerType: TriggerType,
|
||||
): Promise<SetTriggerActionsResponse.AsObject> {
|
||||
const req = new SetTriggerActionsRequest();
|
||||
req.setActionIdsList(actionIdsList);
|
||||
req.setFlowType(type);
|
||||
req.setTriggerType(triggerType);
|
||||
return this.grpcService.mgmt.setTriggerActions(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public getIAM(): Promise<GetIAMResponse.AsObject> {
|
||||
const req = new GetIAMRequest();
|
||||
return this.grpcService.mgmt.getIAM(req, null).then((resp) => resp.toObject());
|
||||
|
@ -91,6 +91,7 @@
|
||||
"SHOWORGS": "Alle Organisationen anzeigen",
|
||||
"GRANTSECTION": "Berechtigungssektion",
|
||||
"GRANTS": "Berechtigungen",
|
||||
"ACTIONS": "Aktionen",
|
||||
"PRIVACY": "Datenschutz",
|
||||
"TOS": "AGB",
|
||||
"TOOLTIP": {
|
||||
@ -102,20 +103,21 @@
|
||||
"GRANTEDPROJECTS": "Verwalte die berechtigten Projekte von anderen Organisationen",
|
||||
"HUMANUSERS": "Verwalte die Menschlichen Benutzer deiner Organisation",
|
||||
"MACHINEUSERS": "Verwalte die Service Benutzer deiner Organisation",
|
||||
"AUTHZ": "Verwalte die Berechtigungen deiner Organisationsbenutzer"
|
||||
"AUTHZ": "Verwalte die Berechtigungen deiner Organisationsbenutzer",
|
||||
"ACTIONS": "Hinterlege scripts die bei einem bestimmten Event ausgeführt werden."
|
||||
}
|
||||
},
|
||||
"ACTIONS": {
|
||||
"ACTIONS":"Aktionen",
|
||||
"RENAME":"Umbenennen",
|
||||
"SET":"Übernehmen",
|
||||
"COPY":"In die Zwischenablage kopieren",
|
||||
"COPIED":"In die Zwischenablage kopiert.",
|
||||
"RESETDEFAULT":"Auf Standard zurücksetzen",
|
||||
"RESETTO":"Zurücksetzen auf: ",
|
||||
"RESETCURRENT":"Auf aktuellen Wert zurücksetzen",
|
||||
"SHOW":"Aufklappen",
|
||||
"HIDE":"Zuklappen",
|
||||
"ACTIONS": "Aktionen",
|
||||
"RENAME": "Umbenennen",
|
||||
"SET": "Übernehmen",
|
||||
"COPY": "In die Zwischenablage kopieren",
|
||||
"COPIED": "In die Zwischenablage kopiert.",
|
||||
"RESETDEFAULT": "Auf Standard zurücksetzen",
|
||||
"RESETTO": "Zurücksetzen auf: ",
|
||||
"RESETCURRENT": "Auf aktuellen Wert zurücksetzen",
|
||||
"SHOW": "Aufklappen",
|
||||
"HIDE": "Zuklappen",
|
||||
"SAVE": "Speichern",
|
||||
"SAVENOW": "Speichern",
|
||||
"NEW": "Neu",
|
||||
@ -144,9 +146,9 @@
|
||||
"CONFIGURE": "Konfigurieren",
|
||||
"SEND": "Senden",
|
||||
"NEWVALUE": "Neuer Wert",
|
||||
"RESTORE":"Wiederherstellen",
|
||||
"CONTINUEWITHOUTSAVE":"Ohne speichern fortfahren",
|
||||
"GOTOFEATURES":"Zu den Features"
|
||||
"RESTORE": "Wiederherstellen",
|
||||
"CONTINUEWITHOUTSAVE": "Ohne speichern fortfahren",
|
||||
"GOTOFEATURES": "Zu den Features"
|
||||
},
|
||||
"RESOURCEID": "Ressourcen-ID",
|
||||
"TABLE": {
|
||||
@ -177,14 +179,14 @@
|
||||
"REACTIVATE": "Reaktivieren",
|
||||
"DEACTIVATE": "Deaktivieren",
|
||||
"FILTER": "Filter",
|
||||
"STATE":"Status",
|
||||
"STATE": "Status",
|
||||
"DELETE": "Benutzer löschen",
|
||||
"UNLOCK": "Benutzer entsperren",
|
||||
"LOCKEDDESCRIPTION":"Dieser Benutzer wurde aufgrund der Überschreitung der maximalen Anmeldeversuche gesperrt und muss zur erneuten Verwendung entsperrt werden."
|
||||
"LOCKEDDESCRIPTION": "Dieser Benutzer wurde aufgrund der Überschreitung der maximalen Anmeldeversuche gesperrt und muss zur erneuten Verwendung entsperrt werden."
|
||||
},
|
||||
"DETAILS": {
|
||||
"DATECREATED":"Erstellt",
|
||||
"DATECHANGED":"Geändert"
|
||||
"DATECREATED": "Erstellt",
|
||||
"DATECHANGED": "Geändert"
|
||||
},
|
||||
"DIALOG": {
|
||||
"DELETE_TITLE": "User löschen",
|
||||
@ -211,7 +213,7 @@
|
||||
"EMPTY": "Keine Einträge"
|
||||
},
|
||||
"PASSWORDLESS": {
|
||||
"SEND":"Registrierungslink senden",
|
||||
"SEND": "Registrierungslink senden",
|
||||
"TABLETYPE": "Typ",
|
||||
"TABLESTATE": "Status",
|
||||
"NAME": "Name",
|
||||
@ -239,28 +241,28 @@
|
||||
"DIALOG": {
|
||||
"DELETE_TITLE": "Passwordless entfernen",
|
||||
"DELETE_DESCRIPTION": "Sie sind im Begriff eine Passwortlose Authentifizierungsmethode zu entfernen. Sind sie sicher?",
|
||||
"ADD_TITLE":"Passwortlose Authentifizierung",
|
||||
"ADD_DESCRIPTION":"Wählen Sie eine der verfügbaren Optionen für das Erstellen einer passwordlosen Authentifizierungsmethode.",
|
||||
"SEND_DESCRIPTION":"Senden Sie sich einen Registrierungslink an Ihre email adresse.",
|
||||
"SEND":"Registrierungslink senden",
|
||||
"SENT":"Die email wurde erfolgreich zugestellt. Kontrollieren Sie Ihr Postfach um mit dem Setup forzufahren.",
|
||||
"QRCODE_DESCRIPTION":"QR-Code zum scannen mit einem anderen Gerät generieren.",
|
||||
"QRCODE":"QR-Code generieren",
|
||||
"QRCODE_SCAN":"Scannen Sie diesen QR Code um mit dem Setup auf Ihrem Gerät forzufahren.",
|
||||
"NEW_DESCRIPTION":"Verwenden Sie dieses Gerät um Passwordless aufzusetzen.",
|
||||
"NEW":"Hinzufügen"
|
||||
"ADD_TITLE": "Passwortlose Authentifizierung",
|
||||
"ADD_DESCRIPTION": "Wählen Sie eine der verfügbaren Optionen für das Erstellen einer passwordlosen Authentifizierungsmethode.",
|
||||
"SEND_DESCRIPTION": "Senden Sie sich einen Registrierungslink an Ihre email adresse.",
|
||||
"SEND": "Registrierungslink senden",
|
||||
"SENT": "Die email wurde erfolgreich zugestellt. Kontrollieren Sie Ihr Postfach um mit dem Setup forzufahren.",
|
||||
"QRCODE_DESCRIPTION": "QR-Code zum scannen mit einem anderen Gerät generieren.",
|
||||
"QRCODE": "QR-Code generieren",
|
||||
"QRCODE_SCAN": "Scannen Sie diesen QR Code um mit dem Setup auf Ihrem Gerät forzufahren.",
|
||||
"NEW_DESCRIPTION": "Verwenden Sie dieses Gerät um Passwordless aufzusetzen.",
|
||||
"NEW": "Hinzufügen"
|
||||
}
|
||||
},
|
||||
"METADATA": {
|
||||
"TITLE":"Metadata",
|
||||
"DESCRIPTION":"",
|
||||
"KEY":"Schlüssel",
|
||||
"VALUE":"Wert",
|
||||
"ADD":"Neues Element",
|
||||
"SAVE":"Speichern",
|
||||
"EMPTY":"Keine Metadaten",
|
||||
"SETSUCCESS":"Element erfolgreich gespeichert",
|
||||
"REMOVESUCCESS":"Element erfolgreich gelöscht"
|
||||
"TITLE": "Metadata",
|
||||
"DESCRIPTION": "",
|
||||
"KEY": "Schlüssel",
|
||||
"VALUE": "Wert",
|
||||
"ADD": "Neues Element",
|
||||
"SAVE": "Speichern",
|
||||
"EMPTY": "Keine Metadaten",
|
||||
"SETSUCCESS": "Element erfolgreich gespeichert",
|
||||
"REMOVESUCCESS": "Element erfolgreich gelöscht"
|
||||
},
|
||||
"MFA": {
|
||||
"TABLETYPE": "Typ",
|
||||
@ -339,9 +341,9 @@
|
||||
"EMAIL": "E-Mail",
|
||||
"PHONE": "Telefonnummer",
|
||||
"USERNAME": "Benutzername",
|
||||
"CHANGEUSERNAME":"bearbeiten",
|
||||
"CHANGEUSERNAME_TITLE":"Benutzername ändern",
|
||||
"CHANGEUSERNAME_DESC":"Geben Sie ihren neuen Namen an.",
|
||||
"CHANGEUSERNAME": "bearbeiten",
|
||||
"CHANGEUSERNAME_TITLE": "Benutzername ändern",
|
||||
"CHANGEUSERNAME_DESC": "Geben Sie ihren neuen Namen an.",
|
||||
"FIRSTNAME": "Vorname",
|
||||
"LASTNAME": "Nachname",
|
||||
"NICKNAME": "Spitzname",
|
||||
@ -350,13 +352,13 @@
|
||||
"GENDER": "Geschlecht",
|
||||
"PASSWORD": "Passwort",
|
||||
"AVATAR": {
|
||||
"UPLOADTITLE":"Profilfoto uploaden",
|
||||
"UPLOADBTN":"Datei auswählen",
|
||||
"UPLOAD":"Hochladen",
|
||||
"CURRENT":"Aktuelles Bild",
|
||||
"PREVIEW":"Vorschau",
|
||||
"DELETESUCCESS":"Erfolgreich gelöscht!",
|
||||
"CROPPERERROR":"Ein Fehler beim hochladen Ihrer Datei ist fehlgeschlagen. Versuchen Sie es mit ggf mit einem anderen Format und Grösse."
|
||||
"UPLOADTITLE": "Profilfoto uploaden",
|
||||
"UPLOADBTN": "Datei auswählen",
|
||||
"UPLOAD": "Hochladen",
|
||||
"CURRENT": "Aktuelles Bild",
|
||||
"PREVIEW": "Vorschau",
|
||||
"DELETESUCCESS": "Erfolgreich gelöscht!",
|
||||
"CROPPERERROR": "Ein Fehler beim hochladen Ihrer Datei ist fehlgeschlagen. Versuchen Sie es mit ggf mit einem anderen Format und Grösse."
|
||||
}
|
||||
},
|
||||
"MACHINE": {
|
||||
@ -476,7 +478,7 @@
|
||||
"TOAST": {
|
||||
"CREATED": "Benutzer erfolgreich erstellt.",
|
||||
"SAVED": "Profil gespeichert.",
|
||||
"USERNAMECHANGED":"Username geändert.",
|
||||
"USERNAMECHANGED": "Username geändert.",
|
||||
"EMAILSAVED": "E-Mail gespeichert.",
|
||||
"INITEMAILSENT": "Initialisierung Email gesendet.",
|
||||
"PHONESAVED": "Telefonnummer gespeichert.",
|
||||
@ -498,14 +500,14 @@
|
||||
"KEYADDED": "Schlüssel hinzugefügt!",
|
||||
"MACHINEADDED": "Service User erstellt!",
|
||||
"DELETED": "Benutzer erfolgreich gelöscht!",
|
||||
"UNLOCKED":"Benutzer erfolgreich freigeschaltet!",
|
||||
"PASSWORDLESSREGISTRATIONSENT":"Link via email versendet."
|
||||
"UNLOCKED": "Benutzer erfolgreich freigeschaltet!",
|
||||
"PASSWORDLESSREGISTRATIONSENT": "Link via email versendet."
|
||||
},
|
||||
"MEMBERSHIPS": {
|
||||
"TITLE": "ZITADEL Manager-Rollen",
|
||||
"DESCRIPTION": "Dies sind alle Mitgliedschaften des Benutzers. Du kannst die entsprechenden Rechte auch auf der Organisations-, Projekt-, oder IAM-Detailseite aufrufen und modifizieren.",
|
||||
"ORGCONTEXT":"Sie sehen alle Organisationen und Projekte, die mit der aktuell gewählten Organisation in Verbindung stehen.",
|
||||
"USERCONTEXT":"Sie sehen alle Organisationen und Projekte auf denen Sie berechtigt sind inklusive aller zur Auswahl stehenden Organisationen.",
|
||||
"ORGCONTEXT": "Sie sehen alle Organisationen und Projekte, die mit der aktuell gewählten Organisation in Verbindung stehen.",
|
||||
"USERCONTEXT": "Sie sehen alle Organisationen und Projekte auf denen Sie berechtigt sind inklusive aller zur Auswahl stehenden Organisationen.",
|
||||
"CREATIONDATE": "Erstelldatum",
|
||||
"CHANGEDATE": "Letzte Änderung",
|
||||
"DISPLAYNAME": "Anzeigename",
|
||||
@ -519,6 +521,55 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"FLOWS": {
|
||||
"TITLE": "Aktionen und Abläufe",
|
||||
"DESCRIPTION": "Hinterlege scripts die bei einem bestimmten Event ausgeführt werden.",
|
||||
"ACTIONSTITLE": "Aktionen",
|
||||
"FLOWSTITLE": "Abläufe",
|
||||
"ID": "ID",
|
||||
"NAME": "Name",
|
||||
"STATE": "State",
|
||||
"STATES": {
|
||||
"0": "Kein Status",
|
||||
"1": "inaktiv",
|
||||
"2": "aktiv"
|
||||
},
|
||||
"TYPES": {
|
||||
"0": "Unspezifisch",
|
||||
"1": "Externe Authentifizierung"
|
||||
},
|
||||
"TRIGGERTYPES": {
|
||||
"1": "Post Authentication",
|
||||
"2": "Pre Creation",
|
||||
"3": "Post Creation"
|
||||
},
|
||||
"TIMEOUT": "Timeout",
|
||||
"TIMEOUTINSEC": "Timout in Sekunden",
|
||||
"ALLOWEDTOFAIL": "Allowed To Fail",
|
||||
"SCRIPT": "Script",
|
||||
"FLOWTYPE": "Flow Typ",
|
||||
"TRIGGERTYPE": "Trigger Typ",
|
||||
"ACTIONS": "Aktionen",
|
||||
"DIALOG": {
|
||||
"ADD": {
|
||||
"TITLE": "Aktion erstellen"
|
||||
},
|
||||
"UPDATE": {
|
||||
"TITLE": "Aktion bearbeiten"
|
||||
},
|
||||
"DELETEACTION": {
|
||||
"TITLE": "Aktion löschen?",
|
||||
"DESCRIPTION": "Sie sind im Begriff eine Aktion zu löschen. Dieser Vorgang kann nicht zurückgesetzt werden. Sind Sie sicher?"
|
||||
},
|
||||
"CLEAR": {
|
||||
"TITLE": "Flow zurücksetzen?",
|
||||
"DESCRIPTION": "Sie sind im Begriff den Flow mitsamt seinen Triggern und Aktionen zurückzusetzen. Diese Änderung kann nicht wiederhergestellt werden."
|
||||
}
|
||||
},
|
||||
"TOAST": {
|
||||
"ACTIONSSET": "Aktionen gesetzt"
|
||||
}
|
||||
},
|
||||
"IAM": {
|
||||
"POLICIES": {
|
||||
"TITLE": "IAM Administration",
|
||||
@ -645,8 +696,8 @@
|
||||
"TITLE": "Features",
|
||||
"DESCRIPTION": "Hier können Sie Funktionen von ZITADEL auf Basis von Ihrer Preisstufe einsehen.",
|
||||
"BTN-EDIT": "Featureset anzeigen",
|
||||
"AVAILABLE":"freigeschaltet",
|
||||
"UNAVAILABLE":"nicht freigeschaltet",
|
||||
"AVAILABLE": "freigeschaltet",
|
||||
"UNAVAILABLE": "nicht freigeschaltet",
|
||||
"TIER": {
|
||||
"NAME": "Preisstufe Name",
|
||||
"DETAILS": "Abrechnungsdetails",
|
||||
@ -664,12 +715,13 @@
|
||||
"BTN": "Preisstufe ändern"
|
||||
},
|
||||
"HEADERS": {
|
||||
"LOGINPOLICY":"Login Richtlinie",
|
||||
"PASSWORD":"Passwort",
|
||||
"LABELPOLICY":"Privatelabelling",
|
||||
"DOMAIN":"Organisations Domänen",
|
||||
"TEXTSANDLINKS":"Texte und Links",
|
||||
"METADATA":"Metadata"
|
||||
"LOGINPOLICY": "Login Richtlinie",
|
||||
"PASSWORD": "Passwort",
|
||||
"LABELPOLICY": "Privatelabelling",
|
||||
"DOMAIN": "Organisations Domänen",
|
||||
"TEXTSANDLINKS": "Texte und Links",
|
||||
"METADATA": "Metadata",
|
||||
"FLOWS": "Aktionen und Abläufe"
|
||||
},
|
||||
"DATA": {
|
||||
"AUDITLOGRETENTION": "Audit Log Retention",
|
||||
@ -680,14 +732,15 @@
|
||||
"LOGINPOLICYFACTORS": "Multifaktoren",
|
||||
"LOGINPOLICYPASSWORDLESS": "Passwortlose Authentifizierung",
|
||||
"LOGINPOLICYCOMPLEXITYPOLICY": "Passwortkomplexitäts Richtlinie",
|
||||
"LOCKOUTPOLICY":"Passwortsperre",
|
||||
"LOCKOUTPOLICY": "Passwortsperre",
|
||||
"LABELPOLICYPRIVATELABEL": "Farben, Logo, Icon und Texterscheinungsbild",
|
||||
"LABELPOLICYWATERMARK": "ZITADEL Wasserzeichen entfernen",
|
||||
"CUSTOMDOMAIN": "Domänverifikation",
|
||||
"CUSTOMTEXTLOGIN": "Benutzerdefinierte Logininterface Texte",
|
||||
"CUSTOMTEXTMESSAGE":"Benutzerdefinierte Benachrichtigungstexte",
|
||||
"PRIVACYPOLICY":"Benutzerdefinierte Datenschutzrichtlinie und AGB",
|
||||
"METADATAUSER":"User Metadata"
|
||||
"CUSTOMTEXTMESSAGE": "Benutzerdefinierte Benachrichtigungstexte",
|
||||
"PRIVACYPOLICY": "Benutzerdefinierte Datenschutzrichtlinie und AGB",
|
||||
"METADATAUSER": "User Metadata",
|
||||
"FLOWS": "Aktionen und Abläufe"
|
||||
},
|
||||
"TIERSTATES": {
|
||||
"0": "Aktiv",
|
||||
@ -710,34 +763,34 @@
|
||||
"PATTERNERROR": "Das Passwort erfüllt nicht die vorgeschriebene Richtlinie."
|
||||
},
|
||||
"PRIVATELABELING": {
|
||||
"TITLE":"Private Labeling",
|
||||
"DESCRIPTION":"Verleihe dem Login deinen benutzerdefinierten Style und passe das Verhalten an.",
|
||||
"PREVIEW_DESCRIPTION":"Änderungen dieser Richtlinie werden automatisch in der Preview Umgebung verfügbar.",
|
||||
"BTN":"Datei auswählen",
|
||||
"ACTIVATEPREVIEW":"Konfiguration übernehmen",
|
||||
"DARK":"Dunkler Modus",
|
||||
"LIGHT":"Heller Modus",
|
||||
"CHANGEVIEW":"Ansicht wechseln",
|
||||
"ACTIVATED":"Richtlinie wurde LIVE geschaltet",
|
||||
"THEME":"Modus",
|
||||
"COLORS":"Farben",
|
||||
"FONT":"Schrift",
|
||||
"ADVANCEDBEHAVIOR":"Erweitertes Verhalten",
|
||||
"DROP":"Bild hier ablegen oder",
|
||||
"RELEASE":"Jetzt loslassen",
|
||||
"DROPFONT":"Fontdatei hier ablegen",
|
||||
"RELEASEFONT":"Jetzt loslassen",
|
||||
"USEOFLOGO":"Ihr Logo wird im Login sowie emails verwendet, während das Icon für kleinere UI-Elemente wie den Organisationswechsel in der Konsole verwendet wird",
|
||||
"MAXSIZE":"Die maximale Grösse von Uploads ist mit 524kB begrenzt",
|
||||
"EMAILNOSVG":"Das SVG Dateiformat wird nicht in emails unterstützt. Laden Sie deshalb ihr Logo im PNG oder einem anderen unterstützten Format hoch.",
|
||||
"MAXSIZEEXCEEDED":"Maximale Grösse von 524kB überschritten",
|
||||
"FONTINLOGINONLY":"Die Schriftart wird momentan nur im Login interface angezeigt.",
|
||||
"TITLE": "Private Labeling",
|
||||
"DESCRIPTION": "Verleihe dem Login deinen benutzerdefinierten Style und passe das Verhalten an.",
|
||||
"PREVIEW_DESCRIPTION": "Änderungen dieser Richtlinie werden automatisch in der Preview Umgebung verfügbar.",
|
||||
"BTN": "Datei auswählen",
|
||||
"ACTIVATEPREVIEW": "Konfiguration übernehmen",
|
||||
"DARK": "Dunkler Modus",
|
||||
"LIGHT": "Heller Modus",
|
||||
"CHANGEVIEW": "Ansicht wechseln",
|
||||
"ACTIVATED": "Richtlinie wurde LIVE geschaltet",
|
||||
"THEME": "Modus",
|
||||
"COLORS": "Farben",
|
||||
"FONT": "Schrift",
|
||||
"ADVANCEDBEHAVIOR": "Erweitertes Verhalten",
|
||||
"DROP": "Bild hier ablegen oder",
|
||||
"RELEASE": "Jetzt loslassen",
|
||||
"DROPFONT": "Fontdatei hier ablegen",
|
||||
"RELEASEFONT": "Jetzt loslassen",
|
||||
"USEOFLOGO": "Ihr Logo wird im Login sowie emails verwendet, während das Icon für kleinere UI-Elemente wie den Organisationswechsel in der Konsole verwendet wird",
|
||||
"MAXSIZE": "Die maximale Grösse von Uploads ist mit 524kB begrenzt",
|
||||
"EMAILNOSVG": "Das SVG Dateiformat wird nicht in emails unterstützt. Laden Sie deshalb ihr Logo im PNG oder einem anderen unterstützten Format hoch.",
|
||||
"MAXSIZEEXCEEDED": "Maximale Grösse von 524kB überschritten",
|
||||
"FONTINLOGINONLY": "Die Schriftart wird momentan nur im Login interface angezeigt.",
|
||||
"PREVIEW": {
|
||||
"TITLE":"Anmeldung",
|
||||
"SECOND":"mit ZITADEL-Konto anmelden.",
|
||||
"ERROR":"Benutzer konnte nicht gefunden werden!",
|
||||
"PRIMARYBUTTON":"weiter",
|
||||
"SECONDARYBUTTON":"registrieren"
|
||||
"TITLE": "Anmeldung",
|
||||
"SECOND": "mit ZITADEL-Konto anmelden.",
|
||||
"ERROR": "Benutzer konnte nicht gefunden werden!",
|
||||
"PRIMARYBUTTON": "weiter",
|
||||
"SECONDARYBUTTON": "registrieren"
|
||||
}
|
||||
},
|
||||
"PWD_AGE": {
|
||||
@ -763,104 +816,104 @@
|
||||
"DESCRIPTION": "Definiere die Loginmethoden für Benutzer",
|
||||
"DESCRIPTIONCREATEADMIN": "Nutzer können sich mit den verfügbaren Idps authentifizieren.",
|
||||
"DESCRIPTIONCREATEMGMT": "Nutzer können sich mit den verfügbaren Idps authentifizieren. Achtung: Es kann zwischen System- und organisationsspezifischen Providern gewählt werden.",
|
||||
"ADVANCED":"Erweitert",
|
||||
"ADVANCED": "Erweitert",
|
||||
"SAVED": "Erfolgreich gespeichert."
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Datenschutzbestimmungen und AGB",
|
||||
"DESCRIPTION": "Legen Sie Ihre Datenschutzrichtlinien und Nutzungsbedingungen fest",
|
||||
"TOSLINK":"Link zu den Allgemeinen Geschäftsbedingungen",
|
||||
"POLICYLINK":"Link zur den Datenschutzrichtlinien",
|
||||
"TOSLINK": "Link zu den Allgemeinen Geschäftsbedingungen",
|
||||
"POLICYLINK": "Link zur den Datenschutzrichtlinien",
|
||||
"SAVED": "Saved successfully!",
|
||||
"RESET_TITLE":"Standardwerte wiederherstellen",
|
||||
"RESET_DESCRIPTION":"Sie sind im Begriff die Standardlinks für die AGBs und Datenschutzrichtlinie wiederherzustellen. Wollen Sie fortfahren?"
|
||||
"RESET_TITLE": "Standardwerte wiederherstellen",
|
||||
"RESET_DESCRIPTION": "Sie sind im Begriff die Standardlinks für die AGBs und Datenschutzrichtlinie wiederherzustellen. Wollen Sie fortfahren?"
|
||||
},
|
||||
"LOGIN_TEXTS": {
|
||||
"TITLE":"Login Interface Texte",
|
||||
"TITLE": "Login Interface Texte",
|
||||
"DESCRIPTION": "Definiere die Texte für das Logininterface. Wenn Texte leer sind, wird der als Platzhalter angezeigte Standardwert verwendet.",
|
||||
"DESCRIPTION_SHORT":"Definiere die Texte für das Logininterface.",
|
||||
"NEWERVERSIONEXISTS":"Neuere Version verfügbar",
|
||||
"CURRENTDATE":"Momentaner Stand",
|
||||
"CHANGEDATE":"Neuer Stand vom",
|
||||
"KEYNAME":"Login Screen / Interface",
|
||||
"RESET_TITLE":"Standardwerte wiederherstellen",
|
||||
"RESET_DESCRIPTION":"Sie sind im Begriff alle Standardwerte wiederherzustellen. Alle von Ihnen gesetzen Änderungen werden unwiederruflich gelöscht. Wollen Sie fortfahren?",
|
||||
"UNSAVED_TITLE":"Ohne speichern fortfahren?",
|
||||
"UNSAVED_DESCRIPTION":"Sie haben Änderungen vorgenommen ohne zu speichern. Möchten Sie jetzt speichern?",
|
||||
"LOCALE":"Sprachcode",
|
||||
"DESCRIPTION_SHORT": "Definiere die Texte für das Logininterface.",
|
||||
"NEWERVERSIONEXISTS": "Neuere Version verfügbar",
|
||||
"CURRENTDATE": "Momentaner Stand",
|
||||
"CHANGEDATE": "Neuer Stand vom",
|
||||
"KEYNAME": "Login Screen / Interface",
|
||||
"RESET_TITLE": "Standardwerte wiederherstellen",
|
||||
"RESET_DESCRIPTION": "Sie sind im Begriff alle Standardwerte wiederherzustellen. Alle von Ihnen gesetzen Änderungen werden unwiederruflich gelöscht. Wollen Sie fortfahren?",
|
||||
"UNSAVED_TITLE": "Ohne speichern fortfahren?",
|
||||
"UNSAVED_DESCRIPTION": "Sie haben Änderungen vorgenommen ohne zu speichern. Möchten Sie jetzt speichern?",
|
||||
"LOCALE": "Sprachcode",
|
||||
"LOCALES": {
|
||||
"de":"German",
|
||||
"en":"English",
|
||||
"it":"Italian",
|
||||
"fr":"French"
|
||||
"de": "German",
|
||||
"en": "English",
|
||||
"it": "Italian",
|
||||
"fr": "French"
|
||||
},
|
||||
"KEYS": {
|
||||
"emailVerificationDoneText":"Email Verification erfolgreich",
|
||||
"emailVerificationText":"Email Verification",
|
||||
"externalUserNotFoundText":"Externer Benutzer nicht gefunden",
|
||||
"footerText":"Fusszeile",
|
||||
"initMfaDoneText":"MFA Initialisierung erfolgreich",
|
||||
"initMfaOtpText":"MFA Initialisierung",
|
||||
"initMfaPromptText":"MFA Einrichtungsaufforderung",
|
||||
"initMfaU2fText":"Universeller Zweitfaktor Initialisierung",
|
||||
"initPasswordDoneText":"Passwort Initialisierung erfolgreich",
|
||||
"initPasswordText":"Password Initialisierung",
|
||||
"initializeDoneText":"Benutzereinrichtung erfolgreich",
|
||||
"initializeUserText":"Benutzereinrichtung",
|
||||
"linkingUserDoneText":"Benutzerverlinkung erfolgreich",
|
||||
"loginText":"Anmelden",
|
||||
"logoutText":"Abmelden",
|
||||
"mfaProvidersText":"MFA Provider",
|
||||
"passwordChangeDoneText":"Passwortwechsel erfolgreich",
|
||||
"passwordChangeText":"Passwortwechsel",
|
||||
"passwordResetDoneText":"Passwort zurücksetzen erfolgreich",
|
||||
"passwordText":"Passwort",
|
||||
"registrationOptionText":"Registrierungsoptionen",
|
||||
"registrationOrgText":"Organisation registrieren",
|
||||
"registrationUserText":"Benutzer registrieren",
|
||||
"selectAccountText":"Account wählen",
|
||||
"successLoginText":"Erfolgreiche Anmeldung",
|
||||
"usernameChangeDoneText":"Benutzernamenwechsel erfolgreich",
|
||||
"usernameChangeText":"Benutzernamenwechsel",
|
||||
"verifyMfaOtpText":"OTP Verifikation",
|
||||
"verifyMfaU2fText":"Universeller Zweitfaktor Verifikation",
|
||||
"passwordlessPromptText":"Passwordless Aufforderung",
|
||||
"passwordlessRegistrationDoneText":"Passwordless setzen erfolgreich",
|
||||
"passwordlessRegistrationText":"Passwordless Registrierung",
|
||||
"passwordlessText":"Passwordless",
|
||||
"externalRegistrationUserOverviewText":"Externe Registrierung Benutzer Übersicht"
|
||||
"emailVerificationDoneText": "Email Verification erfolgreich",
|
||||
"emailVerificationText": "Email Verification",
|
||||
"externalUserNotFoundText": "Externer Benutzer nicht gefunden",
|
||||
"footerText": "Fusszeile",
|
||||
"initMfaDoneText": "MFA Initialisierung erfolgreich",
|
||||
"initMfaOtpText": "MFA Initialisierung",
|
||||
"initMfaPromptText": "MFA Einrichtungsaufforderung",
|
||||
"initMfaU2fText": "Universeller Zweitfaktor Initialisierung",
|
||||
"initPasswordDoneText": "Passwort Initialisierung erfolgreich",
|
||||
"initPasswordText": "Password Initialisierung",
|
||||
"initializeDoneText": "Benutzereinrichtung erfolgreich",
|
||||
"initializeUserText": "Benutzereinrichtung",
|
||||
"linkingUserDoneText": "Benutzerverlinkung erfolgreich",
|
||||
"loginText": "Anmelden",
|
||||
"logoutText": "Abmelden",
|
||||
"mfaProvidersText": "MFA Provider",
|
||||
"passwordChangeDoneText": "Passwortwechsel erfolgreich",
|
||||
"passwordChangeText": "Passwortwechsel",
|
||||
"passwordResetDoneText": "Passwort zurücksetzen erfolgreich",
|
||||
"passwordText": "Passwort",
|
||||
"registrationOptionText": "Registrierungsoptionen",
|
||||
"registrationOrgText": "Organisation registrieren",
|
||||
"registrationUserText": "Benutzer registrieren",
|
||||
"selectAccountText": "Account wählen",
|
||||
"successLoginText": "Erfolgreiche Anmeldung",
|
||||
"usernameChangeDoneText": "Benutzernamenwechsel erfolgreich",
|
||||
"usernameChangeText": "Benutzernamenwechsel",
|
||||
"verifyMfaOtpText": "OTP Verifikation",
|
||||
"verifyMfaU2fText": "Universeller Zweitfaktor Verifikation",
|
||||
"passwordlessPromptText": "Passwordless Aufforderung",
|
||||
"passwordlessRegistrationDoneText": "Passwordless setzen erfolgreich",
|
||||
"passwordlessRegistrationText": "Passwordless Registrierung",
|
||||
"passwordlessText": "Passwordless",
|
||||
"externalRegistrationUserOverviewText": "Externe Registrierung Benutzer Übersicht"
|
||||
}
|
||||
},
|
||||
"MESSAGE_TEXTS": {
|
||||
"TITLE":"Email Texte",
|
||||
"TITLE": "Email Texte",
|
||||
"DESCRIPTION": "Definiere die Texte für deine Benachrichtigungsmails",
|
||||
"TYPES": {
|
||||
"INIT":"Initialisierung",
|
||||
"VE":"Emailverifikation",
|
||||
"VP":"Telefonnummerverifikation",
|
||||
"PR":"Password Wiederherstellung",
|
||||
"DC":"Domainbeanspruchung",
|
||||
"PL":"Passwordless"
|
||||
"INIT": "Initialisierung",
|
||||
"VE": "Emailverifikation",
|
||||
"VP": "Telefonnummerverifikation",
|
||||
"PR": "Password Wiederherstellung",
|
||||
"DC": "Domainbeanspruchung",
|
||||
"PL": "Passwordless"
|
||||
},
|
||||
"CHIPS": {
|
||||
"firstname":"Vorname",
|
||||
"lastname":"Nachname",
|
||||
"code":"Code",
|
||||
"preferredLoginName":"Bevorzugter Anmeldename",
|
||||
"displayName":"Anzeigename",
|
||||
"nickName":"Spitzname",
|
||||
"loginnames":"Loginnamen",
|
||||
"domain":"Domain",
|
||||
"lastEmail":"Letzte email",
|
||||
"lastPhone":"Letzte Telefonnummer",
|
||||
"verifiedEmail":"Verifizierte email",
|
||||
"verifiedPhone":"Verifizierte Telefonnummer",
|
||||
"changedate":"Änderungsdatum",
|
||||
"username":"Username",
|
||||
"tempUsername":"Temp. Username"
|
||||
"firstname": "Vorname",
|
||||
"lastname": "Nachname",
|
||||
"code": "Code",
|
||||
"preferredLoginName": "Bevorzugter Anmeldename",
|
||||
"displayName": "Anzeigename",
|
||||
"nickName": "Spitzname",
|
||||
"loginnames": "Loginnamen",
|
||||
"domain": "Domain",
|
||||
"lastEmail": "Letzte email",
|
||||
"lastPhone": "Letzte Telefonnummer",
|
||||
"verifiedEmail": "Verifizierte email",
|
||||
"verifiedPhone": "Verifizierte Telefonnummer",
|
||||
"changedate": "Änderungsdatum",
|
||||
"username": "Username",
|
||||
"tempUsername": "Temp. Username"
|
||||
},
|
||||
"TOAST": {
|
||||
"UPDATED":"Benutzerdefinierte Texte gespeichert."
|
||||
"UPDATED": "Benutzerdefinierte Texte gespeichert."
|
||||
}
|
||||
},
|
||||
"DEFAULTLABEL": "Die aktuelle Richtlinie entspricht der IAM-Standard Einstellung.",
|
||||
@ -888,9 +941,9 @@
|
||||
"FORCEMFA_DESC": "Ist die Option gewählt, müssen Benutzer einen zweiten Faktor für den Login verwenden.",
|
||||
"HIDEPASSWORDRESET": "Passwort vergessen ausblenden",
|
||||
"HIDEPASSWORDRESET_DESC": "Ist die Option gewählt, ist es nicht möglich im Login das Passwort zurück zusetzen via Passwort vergessen Link.",
|
||||
"HIDELOGINNAMESUFFIX":"Loginname Suffix ausblenden",
|
||||
"ERRORMSGPOPUP":"Fehler als Dialog Fenster",
|
||||
"DISABLEWATERMARK":"Wasserzeichen ausblenden"
|
||||
"HIDELOGINNAMESUFFIX": "Loginname Suffix ausblenden",
|
||||
"ERRORMSGPOPUP": "Fehler als Dialog Fenster",
|
||||
"DISABLEWATERMARK": "Wasserzeichen ausblenden"
|
||||
},
|
||||
"RESET": "Richtlinie zurücksetzen",
|
||||
"CREATECUSTOM": "Benutzerdefinierte Richtlinie erstellen",
|
||||
@ -899,7 +952,7 @@
|
||||
"RESETSUCCESS": "Richtline zurückgesetzt!",
|
||||
"UPLOADSUCCESS": "Upload erfolgreich",
|
||||
"DELETESUCCESS": "Löschen erfolgreich",
|
||||
"UPLOADFAILED":"Upload fehlgeschlagen!"
|
||||
"UPLOADFAILED": "Upload fehlgeschlagen!"
|
||||
}
|
||||
},
|
||||
"ORG_DETAIL": {
|
||||
@ -939,7 +992,7 @@
|
||||
"PAGES": {
|
||||
"TITLE": "Projekt",
|
||||
"DESCRIPTION": "Hier kannst Du wichtige Einstellungen prüfen und die Daten einsehen, mit denen das Projekt konfiguriert worden ist.",
|
||||
"DELETE":"Projekt löschen",
|
||||
"DELETE": "Projekt löschen",
|
||||
"LIST": "Projekte",
|
||||
"LISTDESCRIPTION": "Hier findest Du alle Projekte, für die Du Aktionen anzeigen oder ausführen darfst. Wenn Du Dein Projekt nicht finden kannst, wende Dich an einen Projektbesitzer oder an jemanden mit den entsprechenden Rechten, um Projektzugriff zu erhalten.",
|
||||
"DETAIL": "Details",
|
||||
@ -953,22 +1006,22 @@
|
||||
"GRANTED": "Berechtigte Projekte"
|
||||
},
|
||||
"PRIVATELABEL": {
|
||||
"TITLE":"Private Labeling Verhalten",
|
||||
"TITLE": "Private Labeling Verhalten",
|
||||
"0": {
|
||||
"TITLE":"Unspezifiziert",
|
||||
"DESC":"Sobald der Nutzer identifiziert ist, wird das Privatelabeling der von ihm gewählten Organisation angezeigt, davor wird der Default des Systems angezeigt."
|
||||
"TITLE": "Unspezifiziert",
|
||||
"DESC": "Sobald der Nutzer identifiziert ist, wird das Privatelabeling der von ihm gewählten Organisation angezeigt, davor wird der Default des Systems angezeigt."
|
||||
},
|
||||
"1": {
|
||||
"TITLE":"Durchsetzung der Richtlinie des Projekteigentümers",
|
||||
"DESC":"Das Privatelabeling der Organisation, die Eigentümerin des Projekts ist, wird angezeigt"
|
||||
"TITLE": "Durchsetzung der Richtlinie des Projekteigentümers",
|
||||
"DESC": "Das Privatelabeling der Organisation, die Eigentümerin des Projekts ist, wird angezeigt"
|
||||
},
|
||||
"2": {
|
||||
"TITLE":"Durchsetzung der Richtlinie des Benutzereigentümers",
|
||||
"DESC":"Das Privatelabeling der Organisation des Projekts wird angezeigt, sobald der Benutzer identifiziert ist, wird jedoch auf die Einstellung der Organisation des identifizierten Benutzers, gewechselt."
|
||||
"TITLE": "Durchsetzung der Richtlinie des Benutzereigentümers",
|
||||
"DESC": "Das Privatelabeling der Organisation des Projekts wird angezeigt, sobald der Benutzer identifiziert ist, wird jedoch auf die Einstellung der Organisation des identifizierten Benutzers, gewechselt."
|
||||
},
|
||||
"DIALOG":{
|
||||
"TITLE":"Privatelabeling Verhalten",
|
||||
"DESCRIPTION":"Bestimmen Sie das Verhalten des Projektes im Bezug auf das Privatelabeling."
|
||||
"DIALOG": {
|
||||
"TITLE": "Privatelabeling Verhalten",
|
||||
"DESCRIPTION": "Bestimmen Sie das Verhalten des Projektes im Bezug auf das Privatelabeling."
|
||||
}
|
||||
},
|
||||
"PINNED": "Angepinnt",
|
||||
@ -1005,9 +1058,9 @@
|
||||
},
|
||||
"NAME": "Name",
|
||||
"NAMEDIALOG": {
|
||||
"TITLE":"Projekt umbenennen",
|
||||
"DESCRIPTION":"Geben Sie den neuen Namen für Ihr Projekt an!",
|
||||
"NAME":"Projektname"
|
||||
"TITLE": "Projekt umbenennen",
|
||||
"DESCRIPTION": "Geben Sie den neuen Namen für Ihr Projekt an!",
|
||||
"NAME": "Projektname"
|
||||
},
|
||||
"MEMBER": {
|
||||
"TITLE": "Manager",
|
||||
@ -1046,7 +1099,7 @@
|
||||
"MEMBERTITLE": "Berechtigte Manager der Organisation",
|
||||
"MEMBERDESC": "Dies sind die Manager der berechtigten Organisation. Wähle die Benutzer, die Zugriff zum Bearbeiten der jeweiligen Zugänge erhalten sollen.",
|
||||
"PROJECTNAME": "Projektname",
|
||||
"GRANTEDORG":"Berechtigte Organisation",
|
||||
"GRANTEDORG": "Berechtigte Organisation",
|
||||
"RESOURCEOWNER": "Besitzer"
|
||||
},
|
||||
"STATE": "Status",
|
||||
@ -1146,7 +1199,7 @@
|
||||
"LIST": {
|
||||
"TITLE": "Identitäts Provider",
|
||||
"DESCRIPTION": "Definieren Sie hier Ihre zusätzlichen Idps, die sie für die Authentifizierung in Ihren Organisationen verwenden können.",
|
||||
"ACTIVETITLE":"Aktive Identitäts Provider"
|
||||
"ACTIVETITLE": "Aktive Identitäts Provider"
|
||||
},
|
||||
"CREATE": {
|
||||
"TITLE": "Neuer Identitäts Provider",
|
||||
@ -1155,8 +1208,8 @@
|
||||
"DETAIL": {
|
||||
"TITLE": "Identitäts Provider",
|
||||
"DESCRIPTION": "Generelle Konfiguration deines Identitäts Providers",
|
||||
"DATECREATED":"Erstellt",
|
||||
"DATECHANGED":"Geändert"
|
||||
"DATECREATED": "Erstellt",
|
||||
"DATECHANGED": "Geändert"
|
||||
},
|
||||
"OWNERTYPES": {
|
||||
"0": "unknown",
|
||||
@ -1164,8 +1217,8 @@
|
||||
"2": "Organisation"
|
||||
},
|
||||
"TYPES": {
|
||||
"0": "unknown",
|
||||
"1": "OIDC"
|
||||
"0": "unknown",
|
||||
"1": "OIDC"
|
||||
},
|
||||
"STATES": {
|
||||
"1": "aktiv",
|
||||
@ -1180,11 +1233,11 @@
|
||||
"0": "kein Styling",
|
||||
"1": "Google"
|
||||
},
|
||||
"ADD":"Identity Provider hinzufügen",
|
||||
"AUTOREGISTER":"Automatische Registrierung",
|
||||
"AUTOREGISTER_DESC":"Wenn aktiviert und noch kein Account vorhanden ist, wird einer für den entsprechenden Benutzer erstellt.",
|
||||
"ADD": "Identity Provider hinzufügen",
|
||||
"AUTOREGISTER": "Automatische Registrierung",
|
||||
"AUTOREGISTER_DESC": "Wenn aktiviert und noch kein Account vorhanden ist, wird einer für den entsprechenden Benutzer erstellt.",
|
||||
"TYPE": "Typ",
|
||||
"OWNER":"Besitzer",
|
||||
"OWNER": "Besitzer",
|
||||
"ID": "ID",
|
||||
"NAME": "Name",
|
||||
"CONFIG": "Konfiguration",
|
||||
@ -1195,7 +1248,7 @@
|
||||
"CLIENTSECRET": "Client Secret",
|
||||
"IDPDISPLAYNAMMAPPING": "IDP Anzeigename Mapping",
|
||||
"USERNAMEMAPPING": "Username Mapping",
|
||||
"DATES":"Datum",
|
||||
"DATES": "Datum",
|
||||
"CREATIONDATE": "Erstelldatum",
|
||||
"CHANGEDATE": "Letzte Änderung",
|
||||
"DEACTIVATE": "Deaktivieren",
|
||||
@ -1206,15 +1259,15 @@
|
||||
"DELETE_SELECTION_TITLE": "Identity Providers löschen",
|
||||
"DELETE_SELECTION_DESCRIPTION": "Sie sind im Begriff mehrere Identity Provider zu löschen. Die daruch hervorgerufenen Änderungen sind unwiederruflich. Wollen Sie dies wirklich tun?",
|
||||
"OIDC": {
|
||||
"TITLE":"OpenId Connect IDP",
|
||||
"DESCRIPTION":"Geben Sie die Daten OIDC Identity Providers ein."
|
||||
"TITLE": "OpenId Connect IDP",
|
||||
"DESCRIPTION": "Geben Sie die Daten OIDC Identity Providers ein."
|
||||
},
|
||||
"JWT": {
|
||||
"TITLE":"JWT IDP",
|
||||
"DESCRIPTION":"Geben Sie die Daten JWT Identity Providers ein. ",
|
||||
"HEADERNAME":"Header Name",
|
||||
"JWTENDPOINT":"JWT Endpoint",
|
||||
"JWTKEYSENDPOINT":"JWT Keys Endpoint"
|
||||
"TITLE": "JWT IDP",
|
||||
"DESCRIPTION": "Geben Sie die Daten JWT Identity Providers ein. ",
|
||||
"HEADERNAME": "Header Name",
|
||||
"JWTENDPOINT": "JWT Endpoint",
|
||||
"JWTKEYSENDPOINT": "JWT Keys Endpoint"
|
||||
},
|
||||
"TOAST": {
|
||||
"SAVED": "Erfolgreich gespeichert.",
|
||||
@ -1282,11 +1335,11 @@
|
||||
"CREATE_OIDC": "OIDC-Anwendung",
|
||||
"CREATE_OIDC_DESC_TITLE": "Gebe die Daten der Anwendung Schritt für Schritt ein.",
|
||||
"CREATE_OIDC_DESC_SUB": "Es wird automatisch eine empfohlene Konfiguration generiert.",
|
||||
"STATE":"Status",
|
||||
"DATECREATED":"Erstellt",
|
||||
"DATECHANGED":"Geändert",
|
||||
"URLS":"Urls",
|
||||
"DELETE":"App löschen",
|
||||
"STATE": "Status",
|
||||
"DATECREATED": "Erstellt",
|
||||
"DATECHANGED": "Geändert",
|
||||
"URLS": "Urls",
|
||||
"DELETE": "App löschen",
|
||||
"DETAIL": {
|
||||
"TITLE": "Detail",
|
||||
"STATE": {
|
||||
@ -1318,19 +1371,19 @@
|
||||
}
|
||||
},
|
||||
"NAMEDIALOG": {
|
||||
"TITLE":"App umbenennen",
|
||||
"DESCRIPTION":"Geben Sie den neuen Namen für Ihre App an!",
|
||||
"NAME":"Appname"
|
||||
"TITLE": "App umbenennen",
|
||||
"DESCRIPTION": "Geben Sie den neuen Namen für Ihre App an!",
|
||||
"NAME": "Appname"
|
||||
},
|
||||
"NAME": "Name",
|
||||
"TYPE": "Anwendungstyp",
|
||||
"AUTHMETHOD": "Authentifizierungsmethode",
|
||||
"AUTHMETHODSECTION": "Authentifizierungsmethode",
|
||||
"GRANT": "Berechtigungstypen",
|
||||
"ADDITIONALORIGINS":"Zusätzliche Origins",
|
||||
"ADDITIONALORIGINSDESC":"Wenn sie zusätzliche Origins definieren wollen, die nicht den Redirect URIs gleichzusätzen sind, können Sie dies hier tun.",
|
||||
"ORIGINS":"Origins",
|
||||
"NOTANORIGIN":"Der Angegebene Wert ist kein Origin.",
|
||||
"ADDITIONALORIGINS": "Zusätzliche Origins",
|
||||
"ADDITIONALORIGINSDESC": "Wenn sie zusätzliche Origins definieren wollen, die nicht den Redirect URIs gleichzusätzen sind, können Sie dies hier tun.",
|
||||
"ORIGINS": "Origins",
|
||||
"NOTANORIGIN": "Der Angegebene Wert ist kein Origin.",
|
||||
"OIDC": {
|
||||
"INFO": {
|
||||
"ISSUER": "Issuer",
|
||||
@ -1353,7 +1406,7 @@
|
||||
"TITLE": "OIDC-Konfiguration",
|
||||
"CLIENTID": "Client ID",
|
||||
"CLIENTSECRET": "Client Secret",
|
||||
"CLIENTSECRET_NOSECRET":"Bei ihrem gewählten Authentication Flow wird kein Secret benötigt und steht daher nicht zur Verfügung.",
|
||||
"CLIENTSECRET_NOSECRET": "Bei ihrem gewählten Authentication Flow wird kein Secret benötigt und steht daher nicht zur Verfügung.",
|
||||
"CLIENTSECRET_DESCRIPTION": "Verwahre das Client Secret an einem sicheren Ort, da es nicht mehr angezeigt werden kann, sobald der Dialog geschlossen wird.",
|
||||
"REGENERATESECRET": "Client Secret neu generieren",
|
||||
"DEVMODE": "Entwicklermodus",
|
||||
@ -1375,7 +1428,7 @@
|
||||
"1": "ID-Token",
|
||||
"2": "Token-ID-Token"
|
||||
},
|
||||
"REFRESHTOKEN":"Refresh Token",
|
||||
"REFRESHTOKEN": "Refresh Token",
|
||||
"GRANTTYPE": "Berechtigungstypen",
|
||||
"GRANT": {
|
||||
"0": "Authorisation Code",
|
||||
@ -1468,7 +1521,7 @@
|
||||
"REACTIVATED": "Anwendung reaktiviert.",
|
||||
"DEACTIVATED": "Anwendung deaktiviert.",
|
||||
"OIDCUPDATED": "OIDC-Konfiguration geändert.",
|
||||
"APIUPDATED":"API Konfiguration geändert.",
|
||||
"APIUPDATED": "API Konfiguration geändert.",
|
||||
"UPDATED": "App geändert.",
|
||||
"CLIENTSECRETREGENERATED": "Client Secret generiert.",
|
||||
"DELETED": "App gelöscht.",
|
||||
@ -1489,7 +1542,7 @@
|
||||
"MEMBER": {
|
||||
"ADD": "Manager hinzufügen",
|
||||
"CREATIONTYPE": "Erstelltyp",
|
||||
"DOCSINFO":"Weitere Informationen finden Sie in unserer Dokumentation",
|
||||
"DOCSINFO": "Weitere Informationen finden Sie in unserer Dokumentation",
|
||||
"CREATIONTYPES": {
|
||||
"3": "IAM",
|
||||
"2": "Organisation",
|
||||
|
@ -91,6 +91,7 @@
|
||||
"SHOWORGS": "Show All Organisations",
|
||||
"GRANTSECTION": "Authorization Section",
|
||||
"GRANTS": "Authorizations",
|
||||
"ACTIONS": "Actions",
|
||||
"PRIVACY": "Privacy",
|
||||
"TOS": "Terms of Service",
|
||||
"TOOLTIP": {
|
||||
@ -102,20 +103,21 @@
|
||||
"GRANTEDPROJECTS": "Show projects your organisation was granted access",
|
||||
"HUMANUSERS": "Show all registered human users on your organisation",
|
||||
"MACHINEUSERS": "Show service users of your organisation",
|
||||
"AUTHZ": "Show authorizations available to your organisation users"
|
||||
"AUTHZ": "Show authorizations available to your organisation users",
|
||||
"ACTIONS": "Define scripts to execute on a certain event."
|
||||
}
|
||||
},
|
||||
"ACTIONS": {
|
||||
"ACTIONS":"Aktionen",
|
||||
"RENAME":"Rename",
|
||||
"SET":"Set",
|
||||
"COPY":"Copy to Clipboard",
|
||||
"COPIED":"Copied to clipboard.",
|
||||
"RESETDEFAULT":"Reset to Default",
|
||||
"RESETTO":"Reset to: ",
|
||||
"RESETCURRENT":"Reset to current",
|
||||
"SHOW":"Show",
|
||||
"HIDE":"Hide",
|
||||
"ACTIONS": "Aktionen",
|
||||
"RENAME": "Rename",
|
||||
"SET": "Set",
|
||||
"COPY": "Copy to Clipboard",
|
||||
"COPIED": "Copied to clipboard.",
|
||||
"RESETDEFAULT": "Reset to Default",
|
||||
"RESETTO": "Reset to: ",
|
||||
"RESETCURRENT": "Reset to current",
|
||||
"SHOW": "Show",
|
||||
"HIDE": "Hide",
|
||||
"SAVE": "Save",
|
||||
"SAVENOW": "Save now",
|
||||
"NEW": "New",
|
||||
@ -144,9 +146,9 @@
|
||||
"CONFIGURE": "Configure",
|
||||
"SEND": "Send",
|
||||
"NEWVALUE": "New Value",
|
||||
"RESTORE":"Restore",
|
||||
"CONTINUEWITHOUTSAVE":"Continue without saving",
|
||||
"GOTOFEATURES":"Go to features"
|
||||
"RESTORE": "Restore",
|
||||
"CONTINUEWITHOUTSAVE": "Continue without saving",
|
||||
"GOTOFEATURES": "Go to features"
|
||||
},
|
||||
"RESOURCEID": "Resource Id",
|
||||
"TABLE": {
|
||||
@ -177,14 +179,14 @@
|
||||
"REACTIVATE": "Reactivate",
|
||||
"DEACTIVATE": "Deactivate",
|
||||
"FILTER": "Filter",
|
||||
"STATE":"Status",
|
||||
"STATE": "Status",
|
||||
"DELETE": "Delete User",
|
||||
"UNLOCK": "Unlock User",
|
||||
"LOCKEDDESCRIPTION":"This user has been locked out due to exceeding the maximum login attempts and must be unlocked to be used again."
|
||||
"LOCKEDDESCRIPTION": "This user has been locked out due to exceeding the maximum login attempts and must be unlocked to be used again."
|
||||
},
|
||||
"DETAILS": {
|
||||
"DATECREATED":"Created",
|
||||
"DATECHANGED":"Changed"
|
||||
"DATECREATED": "Created",
|
||||
"DATECHANGED": "Changed"
|
||||
},
|
||||
"DIALOG": {
|
||||
"DELETE_TITLE": "Delete User",
|
||||
@ -211,7 +213,7 @@
|
||||
"EMPTY": "No entries"
|
||||
},
|
||||
"PASSWORDLESS": {
|
||||
"SEND":"Send registration link",
|
||||
"SEND": "Send registration link",
|
||||
"TABLETYPE": "Type",
|
||||
"TABLESTATE": "Status",
|
||||
"NAME": "Name",
|
||||
@ -239,28 +241,28 @@
|
||||
"DIALOG": {
|
||||
"DELETE_TITLE": "Remove Passwordless Authentication Method",
|
||||
"DELETE_DESCRIPTION": "You are about to delete a passwordless Authentication method. Are you sure?",
|
||||
"ADD_TITLE":"Passwordless Authentication",
|
||||
"ADD_DESCRIPTION":"Select one of the available options for creating a passwordless authentication method.",
|
||||
"SEND_DESCRIPTION":"Send yourself a registration link to your email address.",
|
||||
"SEND":"Send registration link",
|
||||
"SENT":"The email was successfully delivered. Check your mailbox to continue with the setup.",
|
||||
"QRCODE_DESCRIPTION":"Generate QR code for scanning with another device.",
|
||||
"QRCODE":"Generate QR code",
|
||||
"QRCODE_SCAN":"Scan this QR code to continue with the setup on your device.",
|
||||
"NEW_DESCRIPTION":"Use this device to set up Passwordless.",
|
||||
"NEW":"Add New"
|
||||
"ADD_TITLE": "Passwordless Authentication",
|
||||
"ADD_DESCRIPTION": "Select one of the available options for creating a passwordless authentication method.",
|
||||
"SEND_DESCRIPTION": "Send yourself a registration link to your email address.",
|
||||
"SEND": "Send registration link",
|
||||
"SENT": "The email was successfully delivered. Check your mailbox to continue with the setup.",
|
||||
"QRCODE_DESCRIPTION": "Generate QR code for scanning with another device.",
|
||||
"QRCODE": "Generate QR code",
|
||||
"QRCODE_SCAN": "Scan this QR code to continue with the setup on your device.",
|
||||
"NEW_DESCRIPTION": "Use this device to set up Passwordless.",
|
||||
"NEW": "Add New"
|
||||
}
|
||||
},
|
||||
"METADATA": {
|
||||
"TITLE":"Metadata",
|
||||
"DESCRIPTION":"",
|
||||
"KEY":"Key",
|
||||
"VALUE":"Value",
|
||||
"ADD":"New Entry",
|
||||
"SAVE":"Save",
|
||||
"EMPTY":"Keine Metadaten",
|
||||
"SETSUCCESS":"Element saved successfully",
|
||||
"REMOVESUCCESS":"Element deleted successfully"
|
||||
"TITLE": "Metadata",
|
||||
"DESCRIPTION": "",
|
||||
"KEY": "Key",
|
||||
"VALUE": "Value",
|
||||
"ADD": "New Entry",
|
||||
"SAVE": "Save",
|
||||
"EMPTY": "Keine Metadaten",
|
||||
"SETSUCCESS": "Element saved successfully",
|
||||
"REMOVESUCCESS": "Element deleted successfully"
|
||||
},
|
||||
"MFA": {
|
||||
"TABLETYPE": "Type",
|
||||
@ -339,9 +341,9 @@
|
||||
"EMAIL": "E-mail",
|
||||
"PHONE": "Phonenumber",
|
||||
"USERNAME": "User Name",
|
||||
"CHANGEUSERNAME":"modify",
|
||||
"CHANGEUSERNAME_TITLE":"Change username",
|
||||
"CHANGEUSERNAME_DESC":"Enter the new name in the field below.",
|
||||
"CHANGEUSERNAME": "modify",
|
||||
"CHANGEUSERNAME_TITLE": "Change username",
|
||||
"CHANGEUSERNAME_DESC": "Enter the new name in the field below.",
|
||||
"FIRSTNAME": "First Name",
|
||||
"LASTNAME": "Last Name",
|
||||
"NICKNAME": "Nickname",
|
||||
@ -350,13 +352,13 @@
|
||||
"GENDER": "Gender",
|
||||
"PASSWORD": "Password",
|
||||
"AVATAR": {
|
||||
"UPLOADTITLE":"Upload your Profile Picture",
|
||||
"UPLOADBTN":"Choose file",
|
||||
"UPLOAD":"Upload",
|
||||
"CURRENT":"Current Picture",
|
||||
"PREVIEW":"Preview",
|
||||
"DELETESUCCESS":"Deleted successfully!",
|
||||
"CROPPERERROR":"An error while uploading your file occurred. Try a different format and size if necessary."
|
||||
"UPLOADTITLE": "Upload your Profile Picture",
|
||||
"UPLOADBTN": "Choose file",
|
||||
"UPLOAD": "Upload",
|
||||
"CURRENT": "Current Picture",
|
||||
"PREVIEW": "Preview",
|
||||
"DELETESUCCESS": "Deleted successfully!",
|
||||
"CROPPERERROR": "An error while uploading your file occurred. Try a different format and size if necessary."
|
||||
}
|
||||
},
|
||||
"MACHINE": {
|
||||
@ -476,7 +478,7 @@
|
||||
"TOAST": {
|
||||
"CREATED": "User created successfully.",
|
||||
"SAVED": "Profile saved successfully.",
|
||||
"USERNAMECHANGED":"Username changed.",
|
||||
"USERNAMECHANGED": "Username changed.",
|
||||
"EMAILSAVED": "E-mail saved successfully.",
|
||||
"INITEMAILSENT": "Initializing mail sent.",
|
||||
"PHONESAVED": "Phone saved successfully.",
|
||||
@ -498,14 +500,14 @@
|
||||
"KEYADDED": "Key added!",
|
||||
"MACHINEADDED": "Service User created!",
|
||||
"DELETED": "User deleted successfully!",
|
||||
"UNLOCKED":"User unlocked successfully!",
|
||||
"PASSWORDLESSREGISTRATIONSENT":"Registration Link sent successfully."
|
||||
"UNLOCKED": "User unlocked successfully!",
|
||||
"PASSWORDLESSREGISTRATIONSENT": "Registration Link sent successfully."
|
||||
},
|
||||
"MEMBERSHIPS": {
|
||||
"TITLE": "ZITADEL Manager Roles",
|
||||
"DESCRIPTION": "These are all member grants of the user. You can modify them also on organisation, project, or IAM detail pages.",
|
||||
"ORGCONTEXT":"You see all organizations and projects that are related to the currently selected organization.",
|
||||
"USERCONTEXT":"You see all organizations and projects to which you are authorized. Including other organizations.",
|
||||
"ORGCONTEXT": "You see all organizations and projects that are related to the currently selected organization.",
|
||||
"USERCONTEXT": "You see all organizations and projects to which you are authorized. Including other organizations.",
|
||||
"CREATIONDATE": "Creation Date",
|
||||
"CHANGEDATE": "Last Modified",
|
||||
"DISPLAYNAME": "Display Name",
|
||||
@ -519,6 +521,55 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"FLOWS": {
|
||||
"TITLE": "Actions and Flows",
|
||||
"DESCRIPTION": "Define scripts to execute on a certain event.",
|
||||
"ACTIONSTITLE": "Actions",
|
||||
"FLOWSTITLE": "Flows",
|
||||
"ID": "ID",
|
||||
"NAME": "Name",
|
||||
"STATE": "State",
|
||||
"STATES": {
|
||||
"0": "no status",
|
||||
"1": "inactive",
|
||||
"2": "active"
|
||||
},
|
||||
"TYPES": {
|
||||
"0": "Unspecified Type",
|
||||
"1": "External Authentication"
|
||||
},
|
||||
"TRIGGERTYPES": {
|
||||
"1": "Post Authentication",
|
||||
"2": "Pre Creation",
|
||||
"3": "Post Creation"
|
||||
},
|
||||
"TIMEOUT": "Timeout",
|
||||
"TIMEOUTINSEC": "Timout in seconds",
|
||||
"ALLOWEDTOFAIL": "Allowed To Fail",
|
||||
"SCRIPT": "Script",
|
||||
"FLOWTYPE": "Flow Type",
|
||||
"TRIGGERTYPE": "Trigger Type",
|
||||
"ACTIONS": "Actions",
|
||||
"DIALOG": {
|
||||
"ADD": {
|
||||
"TITLE": "Create an Action"
|
||||
},
|
||||
"UPDATE": {
|
||||
"TITLE": "Update Action"
|
||||
},
|
||||
"DELETEACTION": {
|
||||
"TITLE": "Delete Action?",
|
||||
"DESCRIPTION": "You are about to delete an action. This cannot be reverted. Are you sure?"
|
||||
},
|
||||
"CLEAR": {
|
||||
"TITLE": "Clear flow?",
|
||||
"DESCRIPTION": "You are about to reset the flow along with its triggers and actions. This change cannot be restored. Are you sure?"
|
||||
}
|
||||
},
|
||||
"TOAST": {
|
||||
"ACTIONSSET": "Actions set"
|
||||
}
|
||||
},
|
||||
"IAM": {
|
||||
"POLICIES": {
|
||||
"TITLE": "IAM Policies and Access Settings",
|
||||
@ -645,8 +696,8 @@
|
||||
"TITLE": "Features",
|
||||
"DESCRIPTION": "Here you can see your ZITADEL Features based on your Tier.",
|
||||
"BTN-EDIT": "Display Featureset",
|
||||
"AVAILABLE":"unlocked",
|
||||
"UNAVAILABLE":"locked",
|
||||
"AVAILABLE": "unlocked",
|
||||
"UNAVAILABLE": "locked",
|
||||
"TIER": {
|
||||
"NAME": "Tier Name",
|
||||
"DETAILS": "Billing Details",
|
||||
@ -664,12 +715,13 @@
|
||||
"BTN": "Change Tier"
|
||||
},
|
||||
"HEADERS": {
|
||||
"LOGINPOLICY":"Login Policy",
|
||||
"PASSWORD":"Password",
|
||||
"LABELPOLICY":"Privatelabelling",
|
||||
"DOMAIN":"Organization Domain",
|
||||
"TEXTSANDLINKS":"Texts and Links",
|
||||
"METADATA":"Metadata"
|
||||
"LOGINPOLICY": "Login Policy",
|
||||
"PASSWORD": "Password",
|
||||
"LABELPOLICY": "Privatelabelling",
|
||||
"DOMAIN": "Organization Domain",
|
||||
"TEXTSANDLINKS": "Texts and Links",
|
||||
"METADATA": "Metadata",
|
||||
"FLOWS": "Actions and Flows"
|
||||
},
|
||||
"DATA": {
|
||||
"AUDITLOGRETENTION": "Audit Log Retention",
|
||||
@ -680,14 +732,15 @@
|
||||
"LOGINPOLICYFACTORS": "Multifactors",
|
||||
"LOGINPOLICYPASSWORDLESS": "Passwordless Authentication",
|
||||
"LOGINPOLICYCOMPLEXITYPOLICY": "Password Complexity Policy",
|
||||
"LOCKOUTPOLICY":"Lockout Policy",
|
||||
"LOCKOUTPOLICY": "Lockout Policy",
|
||||
"LABELPOLICYPRIVATELABEL": "Colors, Logo, Icon, Textappearance",
|
||||
"LABELPOLICYWATERMARK": "Remove ZITADEL watermark",
|
||||
"CUSTOMDOMAIN": "Organization domain verification",
|
||||
"CUSTOMTEXTLOGIN": "Custom login interface texts",
|
||||
"CUSTOMTEXTMESSAGE":"Custom notification mail texts",
|
||||
"PRIVACYPOLICY":"Custom Privacy Policy and TOS Links",
|
||||
"METADATAUSER":"User Metadata"
|
||||
"CUSTOMTEXTMESSAGE": "Custom notification mail texts",
|
||||
"PRIVACYPOLICY": "Custom Privacy Policy and TOS Links",
|
||||
"METADATAUSER": "User Metadata",
|
||||
"FLOWS": "Actions and Flows"
|
||||
},
|
||||
"TIERSTATES": {
|
||||
"0": "Active",
|
||||
@ -710,34 +763,34 @@
|
||||
"PATTERNERROR": "The password does not meet the required pattern."
|
||||
},
|
||||
"PRIVATELABELING": {
|
||||
"TITLE":"Private Labeling",
|
||||
"DESCRIPTION":"Give the login your personalized style and modify its behavior.",
|
||||
"PREVIEW_DESCRIPTION":"Changes of the policy will automatically deployed to preview environment.",
|
||||
"BTN":"Select File",
|
||||
"ACTIVATEPREVIEW":"Apply configuration",
|
||||
"DARK":"Dark Mode",
|
||||
"LIGHT":"Light Mode",
|
||||
"CHANGEVIEW":"Change View",
|
||||
"ACTIVATED":"Policy changes are now LIVE",
|
||||
"THEME":"Theme",
|
||||
"COLORS":"Colors",
|
||||
"FONT":"Font",
|
||||
"ADVANCEDBEHAVIOR":"Advanced Behavior",
|
||||
"DROP":"Drop image here or",
|
||||
"RELEASE":"Release",
|
||||
"DROPFONT":"Drop fontfile here",
|
||||
"RELEASEFONT":"Release",
|
||||
"USEOFLOGO":"Your Logo will be used in the Login as well as emails, while the icon is used for smaller UI elements like in the organisation switcher in console",
|
||||
"MAXSIZE":"The maximum size is limited to 524kB",
|
||||
"EMAILNOSVG":"The SVG file format is not supported in emails. Therefore upload your logo in PNG or other supported format.",
|
||||
"MAXSIZEEXCEEDED":"Maximum size of 524kB exceeded.",
|
||||
"FONTINLOGINONLY":"The font is currently only displayed in the login interface.",
|
||||
"TITLE": "Private Labeling",
|
||||
"DESCRIPTION": "Give the login your personalized style and modify its behavior.",
|
||||
"PREVIEW_DESCRIPTION": "Changes of the policy will automatically deployed to preview environment.",
|
||||
"BTN": "Select File",
|
||||
"ACTIVATEPREVIEW": "Apply configuration",
|
||||
"DARK": "Dark Mode",
|
||||
"LIGHT": "Light Mode",
|
||||
"CHANGEVIEW": "Change View",
|
||||
"ACTIVATED": "Policy changes are now LIVE",
|
||||
"THEME": "Theme",
|
||||
"COLORS": "Colors",
|
||||
"FONT": "Font",
|
||||
"ADVANCEDBEHAVIOR": "Advanced Behavior",
|
||||
"DROP": "Drop image here or",
|
||||
"RELEASE": "Release",
|
||||
"DROPFONT": "Drop fontfile here",
|
||||
"RELEASEFONT": "Release",
|
||||
"USEOFLOGO": "Your Logo will be used in the Login as well as emails, while the icon is used for smaller UI elements like in the organisation switcher in console",
|
||||
"MAXSIZE": "The maximum size is limited to 524kB",
|
||||
"EMAILNOSVG": "The SVG file format is not supported in emails. Therefore upload your logo in PNG or other supported format.",
|
||||
"MAXSIZEEXCEEDED": "Maximum size of 524kB exceeded.",
|
||||
"FONTINLOGINONLY": "The font is currently only displayed in the login interface.",
|
||||
"PREVIEW": {
|
||||
"TITLE":"Login",
|
||||
"SECOND":"login with your ZITADEL-Account.",
|
||||
"ERROR":"User could not be found!",
|
||||
"PRIMARYBUTTON":"next",
|
||||
"SECONDARYBUTTON":"register"
|
||||
"TITLE": "Login",
|
||||
"SECOND": "login with your ZITADEL-Account.",
|
||||
"ERROR": "User could not be found!",
|
||||
"PRIMARYBUTTON": "next",
|
||||
"SECONDARYBUTTON": "register"
|
||||
}
|
||||
},
|
||||
"PWD_AGE": {
|
||||
@ -754,113 +807,113 @@
|
||||
},
|
||||
"PRIVATELABELING_POLICY": {
|
||||
"TITLE": "Private Labeling",
|
||||
"BTN":"Select File",
|
||||
"BTN": "Select File",
|
||||
"DESCRIPTION": "Customize the appearance of the Login",
|
||||
"ACTIVATEPREVIEW":"Activate Configuration"
|
||||
"ACTIVATEPREVIEW": "Activate Configuration"
|
||||
},
|
||||
"LOGIN_POLICY": {
|
||||
"TITLE": "Login Policy",
|
||||
"DESCRIPTION": "Define how Users can be authenticated and configure Identity Providers",
|
||||
"DESCRIPTIONCREATEADMIN": "Users can choose from the available identity providers below.",
|
||||
"DESCRIPTIONCREATEMGMT": "Users can choose from the available identity providers below. Note: You can use System-set providers as well as providers set for your organisation only.",
|
||||
"ADVANCED":"Advanced",
|
||||
"ADVANCED": "Advanced",
|
||||
"SAVED": "Saved successfully!"
|
||||
},
|
||||
"PRIVACY_POLICY": {
|
||||
"TITLE": "Privacy Policy and TOS",
|
||||
"DESCRIPTION": "Set your Privacy Policy and Terms of Service Links",
|
||||
"TOSLINK":"Link to Terms of Service",
|
||||
"POLICYLINK":"Link to Privacy Policy",
|
||||
"TOSLINK": "Link to Terms of Service",
|
||||
"POLICYLINK": "Link to Privacy Policy",
|
||||
"SAVED": "Saved successfully!",
|
||||
"RESET_TITLE":"Restore Default Values",
|
||||
"RESET_DESCRIPTION":"You are about to restore the default Links for TOS and Privacy Policy. Do you really want to continue?"
|
||||
"RESET_TITLE": "Restore Default Values",
|
||||
"RESET_DESCRIPTION": "You are about to restore the default Links for TOS and Privacy Policy. Do you really want to continue?"
|
||||
},
|
||||
"LOGIN_TEXTS": {
|
||||
"TITLE":"Login Interface Texts",
|
||||
"TITLE": "Login Interface Texts",
|
||||
"DESCRIPTION": "Define your texts for the login interfaces. If texts are empty, the default Value shown as the placeholder will be used.",
|
||||
"DESCRIPTION_SHORT":"Define your texts for the login interfaces.",
|
||||
"NEWERVERSIONEXISTS":"Newer Version exists",
|
||||
"CURRENTDATE":"Current configuration",
|
||||
"CHANGEDATE":"Newer Version from",
|
||||
"KEYNAME":"Login Screen / Interface",
|
||||
"RESET_TITLE":"Restore Default Values",
|
||||
"RESET_DESCRIPTION":"You are about to restore all default values. All changes you have made will be permanently deleted. Do you really want to continue?",
|
||||
"UNSAVED_TITLE":"Continue without saving?",
|
||||
"UNSAVED_DESCRIPTION":"Your have made changes without saving. Do you want to save now?",
|
||||
"LOCALE":"Locale Code",
|
||||
"DESCRIPTION_SHORT": "Define your texts for the login interfaces.",
|
||||
"NEWERVERSIONEXISTS": "Newer Version exists",
|
||||
"CURRENTDATE": "Current configuration",
|
||||
"CHANGEDATE": "Newer Version from",
|
||||
"KEYNAME": "Login Screen / Interface",
|
||||
"RESET_TITLE": "Restore Default Values",
|
||||
"RESET_DESCRIPTION": "You are about to restore all default values. All changes you have made will be permanently deleted. Do you really want to continue?",
|
||||
"UNSAVED_TITLE": "Continue without saving?",
|
||||
"UNSAVED_DESCRIPTION": "Your have made changes without saving. Do you want to save now?",
|
||||
"LOCALE": "Locale Code",
|
||||
"LOCALES": {
|
||||
"de":"German",
|
||||
"en":"English",
|
||||
"it":"Italian",
|
||||
"fr":"French"
|
||||
"de": "German",
|
||||
"en": "English",
|
||||
"it": "Italian",
|
||||
"fr": "French"
|
||||
},
|
||||
"KEYS": {
|
||||
"emailVerificationDoneText":"Email verification done",
|
||||
"emailVerificationText":"Email verification",
|
||||
"externalUserNotFoundText":"External user not found",
|
||||
"footerText":"Footer",
|
||||
"initMfaDoneText":"Initialize MFA done",
|
||||
"initMfaOtpText":"Initialize MFA",
|
||||
"initMfaPromptText":"Initialize MFA Prompt",
|
||||
"initMfaU2fText":"Initialize Universal Second Factor",
|
||||
"initPasswordDoneText":"Initialize password done",
|
||||
"initPasswordText":"Initialize password",
|
||||
"initializeDoneText":"Initialize user done",
|
||||
"initializeUserText":"Initialize user",
|
||||
"linkingUserDoneText":"Linking user done",
|
||||
"loginText":"Login",
|
||||
"logoutText":"Logout",
|
||||
"mfaProvidersText":"MFA Providers",
|
||||
"passwordChangeDoneText":"Password change done",
|
||||
"passwordChangeText":"Password change",
|
||||
"passwordResetDoneText":"Password reset done",
|
||||
"passwordText":"Password",
|
||||
"registrationOptionText":"Registration Options",
|
||||
"registrationOrgText":"Register Org",
|
||||
"registrationUserText":"Register User",
|
||||
"selectAccountText":"Select Account",
|
||||
"successLoginText":"Login with success",
|
||||
"usernameChangeDoneText":"Username change done",
|
||||
"usernameChangeText":"Username change",
|
||||
"verifyMfaOtpText":"Verify OTP",
|
||||
"verifyMfaU2fText":"Verify Universal Second Factor",
|
||||
"passwordlessPromptText":"Passwordless Prompt",
|
||||
"passwordlessRegistrationDoneText":"Passwordless Registration Done",
|
||||
"passwordlessRegistrationText":"Passwordless Registration",
|
||||
"passwordlessText":"Passwordless",
|
||||
"externalRegistrationUserOverviewText":"External Registration User Overview"
|
||||
"emailVerificationDoneText": "Email verification done",
|
||||
"emailVerificationText": "Email verification",
|
||||
"externalUserNotFoundText": "External user not found",
|
||||
"footerText": "Footer",
|
||||
"initMfaDoneText": "Initialize MFA done",
|
||||
"initMfaOtpText": "Initialize MFA",
|
||||
"initMfaPromptText": "Initialize MFA Prompt",
|
||||
"initMfaU2fText": "Initialize Universal Second Factor",
|
||||
"initPasswordDoneText": "Initialize password done",
|
||||
"initPasswordText": "Initialize password",
|
||||
"initializeDoneText": "Initialize user done",
|
||||
"initializeUserText": "Initialize user",
|
||||
"linkingUserDoneText": "Linking user done",
|
||||
"loginText": "Login",
|
||||
"logoutText": "Logout",
|
||||
"mfaProvidersText": "MFA Providers",
|
||||
"passwordChangeDoneText": "Password change done",
|
||||
"passwordChangeText": "Password change",
|
||||
"passwordResetDoneText": "Password reset done",
|
||||
"passwordText": "Password",
|
||||
"registrationOptionText": "Registration Options",
|
||||
"registrationOrgText": "Register Org",
|
||||
"registrationUserText": "Register User",
|
||||
"selectAccountText": "Select Account",
|
||||
"successLoginText": "Login with success",
|
||||
"usernameChangeDoneText": "Username change done",
|
||||
"usernameChangeText": "Username change",
|
||||
"verifyMfaOtpText": "Verify OTP",
|
||||
"verifyMfaU2fText": "Verify Universal Second Factor",
|
||||
"passwordlessPromptText": "Passwordless Prompt",
|
||||
"passwordlessRegistrationDoneText": "Passwordless Registration Done",
|
||||
"passwordlessRegistrationText": "Passwordless Registration",
|
||||
"passwordlessText": "Passwordless",
|
||||
"externalRegistrationUserOverviewText": "External Registration User Overview"
|
||||
}
|
||||
},
|
||||
"MESSAGE_TEXTS": {
|
||||
"TITLE":"Message Texts",
|
||||
"TITLE": "Message Texts",
|
||||
"DESCRIPTION": "Define your texts for your notication mails.",
|
||||
"TYPES": {
|
||||
"INIT":"Initialization",
|
||||
"VE":"Verify Email",
|
||||
"VP":"Verify Phone",
|
||||
"PR":"Password Reset",
|
||||
"DC":"Domain Claim",
|
||||
"PL":"Passwordless"
|
||||
"INIT": "Initialization",
|
||||
"VE": "Verify Email",
|
||||
"VP": "Verify Phone",
|
||||
"PR": "Password Reset",
|
||||
"DC": "Domain Claim",
|
||||
"PL": "Passwordless"
|
||||
},
|
||||
"CHIPS": {
|
||||
"firstname":"Firstname",
|
||||
"lastname":"Lastname",
|
||||
"code":"Code",
|
||||
"preferredLoginName":"Preferred Login Name",
|
||||
"displayName":"Displayname",
|
||||
"nickName":"Nickname",
|
||||
"loginnames":"Login names",
|
||||
"domain":"Domain",
|
||||
"lastEmail":"Last email",
|
||||
"lastPhone":"Last phone",
|
||||
"verifiedEmail":"Verified email",
|
||||
"verifiedPhone":"Verified phone",
|
||||
"changedate":"Change date",
|
||||
"username":"Username",
|
||||
"tempUsername":"Temp username"
|
||||
"firstname": "Firstname",
|
||||
"lastname": "Lastname",
|
||||
"code": "Code",
|
||||
"preferredLoginName": "Preferred Login Name",
|
||||
"displayName": "Displayname",
|
||||
"nickName": "Nickname",
|
||||
"loginnames": "Login names",
|
||||
"domain": "Domain",
|
||||
"lastEmail": "Last email",
|
||||
"lastPhone": "Last phone",
|
||||
"verifiedEmail": "Verified email",
|
||||
"verifiedPhone": "Verified phone",
|
||||
"changedate": "Change date",
|
||||
"username": "Username",
|
||||
"tempUsername": "Temp username"
|
||||
},
|
||||
"TOAST": {
|
||||
"UPDATED":"Custom Texts saved."
|
||||
"UPDATED": "Custom Texts saved."
|
||||
}
|
||||
},
|
||||
"DEFAULTLABEL": "The currently set guideline corresponds to the standard setting set by the IAM Administrator.",
|
||||
@ -888,9 +941,9 @@
|
||||
"FORCEMFA_DESC": "If the option is selected, users have to configure a second factor for login.",
|
||||
"HIDEPASSWORDRESET": "Hide Password reset",
|
||||
"HIDEPASSWORDRESET_DESC": "If the option is selected, the user can't reset his password in the login process.",
|
||||
"HIDELOGINNAMESUFFIX":"Hide Loginname suffix",
|
||||
"ERRORMSGPOPUP":"Show Error in Dialog",
|
||||
"DISABLEWATERMARK":"Hide Watermark"
|
||||
"HIDELOGINNAMESUFFIX": "Hide Loginname suffix",
|
||||
"ERRORMSGPOPUP": "Show Error in Dialog",
|
||||
"DISABLEWATERMARK": "Hide Watermark"
|
||||
},
|
||||
"RESET": "Reset Policy",
|
||||
"CREATECUSTOM": "Create Custom Policy",
|
||||
@ -899,7 +952,7 @@
|
||||
"RESETSUCCESS": "Policy reset successfully!",
|
||||
"UPLOADSUCCESS": "Uploaded successfully!",
|
||||
"DELETESUCCESS": "Deleted successfully!",
|
||||
"UPLOADFAILED":"Upload failed!"
|
||||
"UPLOADFAILED": "Upload failed!"
|
||||
}
|
||||
},
|
||||
"ORG_DETAIL": {
|
||||
@ -939,7 +992,7 @@
|
||||
"PAGES": {
|
||||
"TITLE": "Project",
|
||||
"DESCRIPTION": "Here you can define applications, manage roles and grant other organisations to use your project.",
|
||||
"DELETE":"Delete Project",
|
||||
"DELETE": "Delete Project",
|
||||
"LIST": "Projects",
|
||||
"LISTDESCRIPTION": "Here you can find all projects you are allowed to view or perform actions on. If you can't find a project, contact a project owner or someone with the corresponding rights to gain project access.",
|
||||
"DETAIL": "Detail",
|
||||
@ -953,22 +1006,22 @@
|
||||
"GRANTED": "Granted Projects"
|
||||
},
|
||||
"PRIVATELABEL": {
|
||||
"TITLE":"Private Labeling Setting",
|
||||
"TITLE": "Private Labeling Setting",
|
||||
"0": {
|
||||
"TITLE":"Unspecified",
|
||||
"DESC":"As soon as the user is identified, the private labeling of the organisation of the identified user will be shown, before the system default is shown."
|
||||
"TITLE": "Unspecified",
|
||||
"DESC": "As soon as the user is identified, the private labeling of the organisation of the identified user will be shown, before the system default is shown."
|
||||
},
|
||||
"1": {
|
||||
"TITLE":"Enforce project resource owner Policy",
|
||||
"DESC":"The private labeling of the organisation which owns the project will be shown"
|
||||
"TITLE": "Enforce project resource owner Policy",
|
||||
"DESC": "The private labeling of the organisation which owns the project will be shown"
|
||||
},
|
||||
"2": {
|
||||
"TITLE":"Allow Login User resource owner policy",
|
||||
"DESC":"The private labeling of the organization of the project will be shown, but as soon as the user is identified, the setting of the organization of the identified user, will be shown."
|
||||
"TITLE": "Allow Login User resource owner policy",
|
||||
"DESC": "The private labeling of the organization of the project will be shown, but as soon as the user is identified, the setting of the organization of the identified user, will be shown."
|
||||
},
|
||||
"DIALOG":{
|
||||
"TITLE":"Privatelabeling Setting",
|
||||
"DESCRIPTION":"Select the behaviour of the login, when using the project."
|
||||
"DIALOG": {
|
||||
"TITLE": "Privatelabeling Setting",
|
||||
"DESCRIPTION": "Select the behaviour of the login, when using the project."
|
||||
}
|
||||
},
|
||||
"PINNED": "Pinned",
|
||||
@ -1005,9 +1058,9 @@
|
||||
},
|
||||
"NAME": "Name",
|
||||
"NAMEDIALOG": {
|
||||
"TITLE":"Rename Project",
|
||||
"DESCRIPTION":"Enter the new name for your project",
|
||||
"NAME":"New Name"
|
||||
"TITLE": "Rename Project",
|
||||
"DESCRIPTION": "Enter the new name for your project",
|
||||
"NAME": "New Name"
|
||||
},
|
||||
"MEMBER": {
|
||||
"TITLE": "Managers",
|
||||
@ -1046,7 +1099,7 @@
|
||||
"MEMBERTITLE": "Managers",
|
||||
"MEMBERDESC": "These are the managers of the granted organisation. Add users here who should gain access to edit the data of the project.",
|
||||
"PROJECTNAME": "Project Name",
|
||||
"GRANTEDORG":"Granted Organisation",
|
||||
"GRANTEDORG": "Granted Organisation",
|
||||
"RESOURCEOWNER": "Resource Owner"
|
||||
},
|
||||
"STATE": "State",
|
||||
@ -1146,7 +1199,7 @@
|
||||
"LIST": {
|
||||
"TITLE": "Identity Providers",
|
||||
"DESCRIPTION": "Manage your Identity Provider configuration, which can then be activated in your Login Policy.",
|
||||
"ACTIVETITLE":"Active Identity Providers"
|
||||
"ACTIVETITLE": "Active Identity Providers"
|
||||
},
|
||||
"CREATE": {
|
||||
"TITLE": "New Identity Provider",
|
||||
@ -1155,8 +1208,8 @@
|
||||
"DETAIL": {
|
||||
"TITLE": "Identity Provider",
|
||||
"DESCRIPTION": "General Configuration of your identity provider.",
|
||||
"DATECREATED":"Created",
|
||||
"DATECHANGED":"Changed"
|
||||
"DATECREATED": "Created",
|
||||
"DATECHANGED": "Changed"
|
||||
},
|
||||
"OWNERTYPES": {
|
||||
"0": "unknown",
|
||||
@ -1164,8 +1217,8 @@
|
||||
"2": "Organisation"
|
||||
},
|
||||
"TYPES": {
|
||||
"0": "unknown",
|
||||
"1": "OIDC"
|
||||
"0": "unknown",
|
||||
"1": "OIDC"
|
||||
},
|
||||
"STATES": {
|
||||
"1": "active",
|
||||
@ -1180,11 +1233,11 @@
|
||||
"0": "No Styling",
|
||||
"1": "Google"
|
||||
},
|
||||
"ADD":"Add Identity Provider",
|
||||
"AUTOREGISTER":"Auto Register",
|
||||
"AUTOREGISTER_DESC":"If selected and no account exists yet, one will be created.",
|
||||
"ADD": "Add Identity Provider",
|
||||
"AUTOREGISTER": "Auto Register",
|
||||
"AUTOREGISTER_DESC": "If selected and no account exists yet, one will be created.",
|
||||
"TYPE": "Type",
|
||||
"OWNER":"Owner",
|
||||
"OWNER": "Owner",
|
||||
"ID": "ID",
|
||||
"NAME": "Name",
|
||||
"CONFIG": "Configuration",
|
||||
@ -1195,7 +1248,7 @@
|
||||
"CLIENTSECRET": "Client Secret",
|
||||
"IDPDISPLAYNAMMAPPING": "IDP Anzeigename Mapping",
|
||||
"USERNAMEMAPPING": "Username Mapping",
|
||||
"DATES":"Dates",
|
||||
"DATES": "Dates",
|
||||
"CREATIONDATE": "Created At",
|
||||
"CHANGEDATE": "Last Modified",
|
||||
"DEACTIVATE": "Deactivate",
|
||||
@ -1206,15 +1259,15 @@
|
||||
"DELETE_SELECTION_TITLE": "Delete Idp",
|
||||
"DELETE_SELECTION_DESCRIPTION": "You are about to delete an identity provider. The resulting changes are irrevocable. Do you really want to do this?",
|
||||
"OIDC": {
|
||||
"TITLE":"OpenId Connect IDP",
|
||||
"DESCRIPTION":"Enter the data for OIDC Identity Provider."
|
||||
"TITLE": "OpenId Connect IDP",
|
||||
"DESCRIPTION": "Enter the data for OIDC Identity Provider."
|
||||
},
|
||||
"JWT": {
|
||||
"TITLE":"JWT IDP",
|
||||
"DESCRIPTION":"Enter the data for JWT Identity Provider.",
|
||||
"HEADERNAME":"Header Name",
|
||||
"JWTENDPOINT":"JWT Endpoint",
|
||||
"JWTKEYSENDPOINT":"JWT Keys Endpoint"
|
||||
"TITLE": "JWT IDP",
|
||||
"DESCRIPTION": "Enter the data for JWT Identity Provider.",
|
||||
"HEADERNAME": "Header Name",
|
||||
"JWTENDPOINT": "JWT Endpoint",
|
||||
"JWTKEYSENDPOINT": "JWT Keys Endpoint"
|
||||
},
|
||||
"TOAST": {
|
||||
"SAVED": "Successfully saved.",
|
||||
@ -1282,11 +1335,11 @@
|
||||
"CREATE_OIDC": "OIDC Application",
|
||||
"CREATE_OIDC_DESC_TITLE": "Enter Your Application Details Step by Step",
|
||||
"CREATE_OIDC_DESC_SUB": "A recommended configuration will be automatically generated.",
|
||||
"STATE":"State",
|
||||
"DATECREATED":"Created",
|
||||
"DATECHANGED":"Changed",
|
||||
"URLS":"Urls",
|
||||
"DELETE":"Delete App",
|
||||
"STATE": "State",
|
||||
"DATECREATED": "Created",
|
||||
"DATECHANGED": "Changed",
|
||||
"URLS": "Urls",
|
||||
"DELETE": "Delete App",
|
||||
"DETAIL": {
|
||||
"TITLE": "Detail",
|
||||
"STATE": {
|
||||
@ -1318,19 +1371,19 @@
|
||||
}
|
||||
},
|
||||
"NAMEDIALOG": {
|
||||
"TITLE":"Rename App",
|
||||
"DESCRIPTION":"Enter the new name for your app",
|
||||
"NAME":"New Name"
|
||||
"TITLE": "Rename App",
|
||||
"DESCRIPTION": "Enter the new name for your app",
|
||||
"NAME": "New Name"
|
||||
},
|
||||
"NAME": "Name",
|
||||
"TYPE": "Application Type",
|
||||
"AUTHMETHOD": "Authentication Method",
|
||||
"AUTHMETHODSECTION": "Authentication Method",
|
||||
"GRANT": "Grant Types",
|
||||
"ADDITIONALORIGINS":"Additional Origins",
|
||||
"ADDITIONALORIGINSDESC":"If you want to add additional Origins to your app which is not used as a redirect you can do that here.",
|
||||
"ORIGINS":"Origins",
|
||||
"NOTANORIGIN":"The entered value is not an origin",
|
||||
"ADDITIONALORIGINS": "Additional Origins",
|
||||
"ADDITIONALORIGINSDESC": "If you want to add additional Origins to your app which is not used as a redirect you can do that here.",
|
||||
"ORIGINS": "Origins",
|
||||
"NOTANORIGIN": "The entered value is not an origin",
|
||||
"OIDC": {
|
||||
"INFO": {
|
||||
"ISSUER": "Issuer",
|
||||
@ -1353,7 +1406,7 @@
|
||||
"TITLE": "OIDC Configuration",
|
||||
"CLIENTID": "Client ID",
|
||||
"CLIENTSECRET": "Client Secret",
|
||||
"CLIENTSECRET_NOSECRET":"With your chosen authentication flow, no secret is required and is therefore not available.",
|
||||
"CLIENTSECRET_NOSECRET": "With your chosen authentication flow, no secret is required and is therefore not available.",
|
||||
"CLIENTSECRET_DESCRIPTION": "Keep your client secret at a safe place as it will disappear once the dialog is closed.",
|
||||
"REGENERATESECRET": "Regenerate Client Secret",
|
||||
"DEVMODE": "Development Mode",
|
||||
@ -1375,7 +1428,7 @@
|
||||
"1": "ID Token",
|
||||
"2": "Token-ID Token"
|
||||
},
|
||||
"REFRESHTOKEN":"Refresh Token",
|
||||
"REFRESHTOKEN": "Refresh Token",
|
||||
"GRANTTYPE": "Grant Types",
|
||||
"GRANT": {
|
||||
"0": "Authorization Code",
|
||||
@ -1468,7 +1521,7 @@
|
||||
"REACTIVATED": "Application reactivated.",
|
||||
"DEACTIVATED": "Application deactivated.",
|
||||
"OIDCUPDATED": "OIDC configuration updated.",
|
||||
"APIUPDATED":"API configuration updated",
|
||||
"APIUPDATED": "API configuration updated",
|
||||
"UPDATED": "App updated.",
|
||||
"CLIENTSECRETREGENERATED": "client secret generated.",
|
||||
"DELETED": "App deleted.",
|
||||
@ -1489,7 +1542,7 @@
|
||||
"MEMBER": {
|
||||
"ADD": "Add a Manager",
|
||||
"CREATIONTYPE": "Creation Type",
|
||||
"DOCSINFO":"For more info consider reading our docs",
|
||||
"DOCSINFO": "For more info consider reading our docs",
|
||||
"CREATIONTYPES": {
|
||||
"3": "IAM",
|
||||
"2": "Organisation",
|
||||
|
@ -91,6 +91,7 @@
|
||||
"SHOWORGS": "Mostra tutte le organizzazioni",
|
||||
"GRANTSECTION": "Sezione di autorizzazione",
|
||||
"GRANTS": "Autorizzazioni",
|
||||
"ACTIONS": "Azioni",
|
||||
"PRIVACY": "Informativa sulla privacy",
|
||||
"TOS": "Termini di servizio",
|
||||
"TOOLTIP": {
|
||||
@ -102,7 +103,8 @@
|
||||
"GRANTEDPROJECTS": "Mostra i progetti a cui la tua organizzazione ha accesso",
|
||||
"HUMANUSERS": "Mostra tutti gli utenti umani registrati nella tua organizzazione",
|
||||
"MACHINEUSERS": "Mostra tutti gli utenti di servizio della tua organizzazione",
|
||||
"AUTHZ": "Mostra le autorizzazioni disponibili per gli utenti della tua organizzazione"
|
||||
"AUTHZ": "Mostra le autorizzazioni disponibili per gli utenti della tua organizzazione",
|
||||
"ACTIONS": "Esegui processi su certi eventi."
|
||||
}
|
||||
},
|
||||
"ACTIONS": {
|
||||
@ -124,7 +126,7 @@
|
||||
"CONTINUE": "Continua",
|
||||
"BACK": "Indietro",
|
||||
"CLOSE": "chiudi",
|
||||
"CLEAR": "Chiaro",
|
||||
"CLEAR": "Resetta",
|
||||
"CANCEL": "cancella",
|
||||
"INFO": "Info",
|
||||
"OK": "OK",
|
||||
@ -519,6 +521,55 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"FLOWS": {
|
||||
"TITLE": "Azioni e Processi",
|
||||
"DESCRIPTION": "Esegui processi su certi eventi.",
|
||||
"ACTIONSTITLE": "Azioni",
|
||||
"FLOWSTITLE": "Processi",
|
||||
"ID": "ID",
|
||||
"NAME": "Nome",
|
||||
"STATE": "Stato",
|
||||
"STATES": {
|
||||
"0": "Nessun stato",
|
||||
"1": "inattivo",
|
||||
"2": "attivo"
|
||||
},
|
||||
"TYPES": {
|
||||
"0": "Non specifico",
|
||||
"1": "Autenticazione esterna"
|
||||
},
|
||||
"TRIGGERTYPES": {
|
||||
"1": "Post autenticazione",
|
||||
"2": "Pre creazione",
|
||||
"3": "Post creazione"
|
||||
},
|
||||
"TIMEOUT": "Timeout",
|
||||
"TIMEOUTINSEC": "Timeout in secondi",
|
||||
"ALLOWEDTOFAIL": "Può fallire",
|
||||
"SCRIPT": "Script",
|
||||
"FLOWTYPE": "Tipo processo",
|
||||
"TRIGGERTYPE": "Tipo trigger",
|
||||
"ACTIONS": "Azioni",
|
||||
"DIALOG": {
|
||||
"ADD": {
|
||||
"TITLE": "Crea azione"
|
||||
},
|
||||
"UPDATE": {
|
||||
"TITLE": "Modifica azione"
|
||||
},
|
||||
"DELETEACTION": {
|
||||
"TITLE": "Elimina azione?",
|
||||
"DESCRIPTION": ""
|
||||
},
|
||||
"CLEAR": {
|
||||
"TITLE": "Flow zurücksetzen?",
|
||||
"DESCRIPTION": "Stai per cancellare un'azione. Questa azione non può essere annullata. Vuoi continuare?"
|
||||
}
|
||||
},
|
||||
"TOAST": {
|
||||
"ACTIONSSET": "Azioni salvate!"
|
||||
}
|
||||
},
|
||||
"IAM": {
|
||||
"POLICIES": {
|
||||
"TITLE": "Impostazioni IAM e impostazioni di accesso",
|
||||
@ -669,7 +720,8 @@
|
||||
"LABELPOLICY": "Privatelabelling",
|
||||
"DOMAIN": "Dominio dell'organizzazione",
|
||||
"TEXTSANDLINKS": "Testi e link",
|
||||
"METADATA": "Metadati"
|
||||
"METADATA": "Metadati",
|
||||
"FLOWS": "Azioni e processi"
|
||||
},
|
||||
"DATA": {
|
||||
"AUDITLOGRETENTION": "Ritenzione Audit Log",
|
||||
@ -687,7 +739,8 @@
|
||||
"CUSTOMTEXTLOGIN": "Testi dell'interfaccia login",
|
||||
"CUSTOMTEXTMESSAGE": "Testi email personalizzati",
|
||||
"PRIVACYPOLICY": "Link personalizzati all'informativa sulla privacy e ai TOS",
|
||||
"METADATAUSER": "Metadati utente"
|
||||
"METADATAUSER": "Metadati utente",
|
||||
"FLOWS": "Azioni e processi"
|
||||
},
|
||||
"TIERSTATES": {
|
||||
"0": "Attivo",
|
||||
|
1
console/src/assets/mdi/arrow-decision-outline.svg
Normal file
1
console/src/assets/mdi/arrow-decision-outline.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M9.64,13.4C8.63,12.5 7.34,12.03 6,12V15L2,11L6,7V10C7.67,10 9.3,10.57 10.63,11.59C10.22,12.15 9.89,12.76 9.64,13.4M18,15V12C17.5,12 13.5,12.16 13.05,16.2C14.61,16.75 15.43,18.47 14.88,20.03C14.33,21.59 12.61,22.41 11.05,21.86C9.5,21.3 8.67,19.59 9.22,18.03C9.5,17.17 10.2,16.5 11.05,16.2C11.34,12.61 14.4,9.88 18,10V7L22,11L18,15M13,19A1,1 0 0,0 12,18A1,1 0 0,0 11,19A1,1 0 0,0 12,20A1,1 0 0,0 13,19M11,11.12C11.58,10.46 12.25,9.89 13,9.43V5H16L12,1L8,5H11V11.12Z" /></svg>
|
After Width: | Height: | Size: 758 B |
1
console/src/assets/mdi/arrow-right-bottom.svg
Normal file
1
console/src/assets/mdi/arrow-right-bottom.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M20 16L14.5 21.5L13.08 20.09L16.17 17H10.5C6.91 17 4 14.09 4 10.5V4H6V10.5C6 13 8 15 10.5 15H16.17L13.09 11.91L14.5 10.5L20 16Z" /></svg>
|
After Width: | Height: | Size: 422 B |
@ -83,7 +83,7 @@ type ActionSearchQueries struct {
|
||||
Queries []SearchQuery
|
||||
}
|
||||
|
||||
func (q *ActionSearchQueries) ToQuery(query sq.SelectBuilder) sq.SelectBuilder {
|
||||
func (q *ActionSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
|
||||
query = q.SearchRequest.toQuery(query)
|
||||
for _, q := range q.Queries {
|
||||
query = q.ToQuery(query)
|
||||
|
Loading…
x
Reference in New Issue
Block a user