mirror of
https://github.com/zitadel/zitadel.git
synced 2025-05-02 15:40:50 +00:00
feat(console): project privatelabelling, catch query param to set org context (#2277)
* feat: privatelabeling setting, query param for context * lint * Update console/src/assets/i18n/de.json Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> * Update console/src/assets/i18n/de.json Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> * Update console/src/assets/i18n/en.json Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> * Update console/src/assets/i18n/en.json Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
This commit is contained in:
parent
e8da0e3f4f
commit
c884a11f1b
@ -6,10 +6,10 @@ import { FormControl } from '@angular/forms';
|
||||
import { MatIconRegistry } from '@angular/material/icon';
|
||||
import { MatDrawer } from '@angular/material/sidenav';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { Router, RouterOutlet } from '@angular/router';
|
||||
import { ActivatedRoute, Router, RouterOutlet } from '@angular/router';
|
||||
import { LangChangeEvent, TranslateService } from '@ngx-translate/core';
|
||||
import { BehaviorSubject, from, Observable, of, Subscription } from 'rxjs';
|
||||
import { catchError, debounceTime, finalize, map, take } from 'rxjs/operators';
|
||||
import { BehaviorSubject, from, Observable, of, Subject } from 'rxjs';
|
||||
import { catchError, debounceTime, finalize, map, take, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { accountCard, adminLineAnimation, navAnimations, routeAnimations, toolbarAnimation } from './animations';
|
||||
import { TextQueryMethod } from './proto/generated/zitadel/object_pb';
|
||||
@ -55,8 +55,7 @@ export class AppComponent implements OnDestroy {
|
||||
public showProjectSection: boolean = false;
|
||||
|
||||
public filterControl: FormControl = new FormControl('');
|
||||
private authSub: Subscription = new Subscription();
|
||||
private orgSub: Subscription = new Subscription();
|
||||
private destroy$: Subject<void> = new Subject();
|
||||
public labelpolicy!: LabelPolicy.AsObject;
|
||||
|
||||
public hideAdminWarn: boolean = true;
|
||||
@ -76,6 +75,7 @@ export class AppComponent implements OnDestroy {
|
||||
public domSanitizer: DomSanitizer,
|
||||
private router: Router,
|
||||
update: UpdateService,
|
||||
private activatedRoute: ActivatedRoute,
|
||||
@Inject(DOCUMENT) private document: Document,
|
||||
) {
|
||||
console.log('%cWait!', 'text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; color: #5469D4; font-size: 50px');
|
||||
@ -174,16 +174,27 @@ export class AppComponent implements OnDestroy {
|
||||
this.domSanitizer.bypassSecurityTrustResourceUrl('assets/mdi/api.svg'),
|
||||
);
|
||||
|
||||
this.activatedRoute.queryParams
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(route => {
|
||||
const { org } = route;
|
||||
if (org) {
|
||||
this.authService.getActiveOrg(org).then(queriedOrg => {
|
||||
this.org = queriedOrg;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.loadPrivateLabelling();
|
||||
|
||||
this.getProjectCount();
|
||||
|
||||
this.orgSub = this.authService.activeOrgChanged.subscribe(org => {
|
||||
this.authService.activeOrgChanged.pipe(takeUntil(this.destroy$)).subscribe(org => {
|
||||
this.org = org;
|
||||
this.getProjectCount();
|
||||
});
|
||||
|
||||
this.authSub = this.authenticationService.authenticationChanged.subscribe((authenticated) => {
|
||||
this.authenticationService.authenticationChanged.pipe(takeUntil(this.destroy$)).subscribe((authenticated) => {
|
||||
if (authenticated) {
|
||||
this.authService.getActiveOrg().then(org => {
|
||||
this.org = org;
|
||||
@ -217,8 +228,8 @@ export class AppComponent implements OnDestroy {
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
this.authSub.unsubscribe();
|
||||
this.orgSub.unsubscribe();
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
public toggleAdminHide(): void {
|
||||
|
@ -40,12 +40,5 @@
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<ng-container
|
||||
*ngIf="serviceType == PolicyComponentServiceType.MGMT && (['login_policy.idp'] | hasFeature | async) == false">
|
||||
<cnsl-info-section type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value:
|
||||
'login_policy.idp'})}}
|
||||
</cnsl-info-section>
|
||||
</ng-container>
|
||||
|
||||
<app-policy-grid [currentPolicy]="currentPolicy" [type]="serviceType" tagForFilter="text"></app-policy-grid>
|
||||
</app-detail-layout>
|
||||
|
@ -0,0 +1,22 @@
|
||||
<h1 class="title">{{'PROJECT.PAGES.PRIVATELABEL.DIALOG.TITLE' | translate}} {{data?.number}}</h1>
|
||||
<p class="desc">{{'PROJECT.PAGES.PRIVATELABEL.DIALOG.DESCRIPTION' | translate}}</p>
|
||||
<div mat-dialog-content>
|
||||
<mat-radio-group
|
||||
class="example-radio-group"
|
||||
[(ngModel)]="setting">
|
||||
<mat-radio-button class="radio-button" *ngFor="let selection of settings" [value]="selection">
|
||||
<span class="label">{{'PROJECT.PAGES.PRIVATELABEL.'+selection+'.TITLE' | translate}}</span>
|
||||
</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
<cnsl-info-section class="info">{{'PROJECT.PAGES.PRIVATELABEL.'+setting+'.DESC' | translate}}</cnsl-info-section>
|
||||
</div>
|
||||
<div mat-dialog-actions class="action">
|
||||
<button cdkFocusInitial color="primary" mat-button class="ok-button" (click)="closeDialog()">
|
||||
{{'ACTIONS.CLOSE' | translate}}
|
||||
</button>
|
||||
|
||||
<button [disabled]="setting == undefined" cdkFocusInitial color="primary" mat-raised-button class="ok-button"
|
||||
(click)="closeDialog(setting)">
|
||||
{{'ACTIONS.OK' | translate}}
|
||||
</button>
|
||||
</div>
|
@ -0,0 +1,35 @@
|
||||
.title {
|
||||
font-size: 1.2rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: var(--grey);
|
||||
font-size: .9rem;
|
||||
}
|
||||
|
||||
.radio-button {
|
||||
margin: .5rem 0;
|
||||
|
||||
.label {
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
margin: 1rem 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.action {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
.ok-button {
|
||||
margin-left: .5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ProjectPrivateLabelingDialogComponent } from './project-private-labeling-dialog.component';
|
||||
|
||||
describe('ProjectPrivateLabelingDialogComponent', () => {
|
||||
let component: ProjectPrivateLabelingDialogComponent;
|
||||
let fixture: ComponentFixture<ProjectPrivateLabelingDialogComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ProjectPrivateLabelingDialogComponent],
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ProjectPrivateLabelingDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,26 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { PrivateLabelingSetting } from 'src/app/proto/generated/zitadel/project_pb';
|
||||
|
||||
@Component({
|
||||
selector: 'app-project-private-labeling-dialog',
|
||||
templateUrl: './project-private-labeling-dialog.component.html',
|
||||
styleUrls: ['./project-private-labeling-dialog.component.scss'],
|
||||
})
|
||||
export class ProjectPrivateLabelingDialogComponent {
|
||||
public setting: PrivateLabelingSetting = PrivateLabelingSetting.PRIVATE_LABELING_SETTING_UNSPECIFIED;
|
||||
public settings: PrivateLabelingSetting[] = [
|
||||
PrivateLabelingSetting.PRIVATE_LABELING_SETTING_UNSPECIFIED,
|
||||
PrivateLabelingSetting.PRIVATE_LABELING_SETTING_ENFORCE_PROJECT_RESOURCE_OWNER_POLICY,
|
||||
PrivateLabelingSetting.PRIVATE_LABELING_SETTING_ALLOW_LOGIN_USER_RESOURCE_OWNER_POLICY,
|
||||
];
|
||||
constructor(public dialogRef: MatDialogRef<ProjectPrivateLabelingDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any) {
|
||||
this.setting = data.setting;
|
||||
}
|
||||
|
||||
closeDialog(setting?: PrivateLabelingSetting): void {
|
||||
this.dialogRef.close(setting);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { InfoSectionModule } from '../info-section/info-section.module';
|
||||
import { ProjectPrivateLabelingDialogComponent } from './project-private-labeling-dialog.component';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProjectPrivateLabelingDialogComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
TranslateModule,
|
||||
MatButtonModule,
|
||||
FormsModule,
|
||||
MatRadioModule,
|
||||
InfoSectionModule,
|
||||
],
|
||||
})
|
||||
export class ProjectPrivateLabelingDialogModule { }
|
@ -34,7 +34,7 @@
|
||||
<div class="meta-row">
|
||||
<span class="first">{{'PROJECT.STATE.TITLE' | translate}}:</span>
|
||||
<span *ngIf="project && project.state !== undefined" class="state"
|
||||
[ngClass]="{'active': project.state === ProjectState.PROJECTSTATE_ACTIVE, 'inactive': project.state === ProjectState.PROJECTSTATE_INACTIVE}">{{'PROJECT.STATE.'+project.state | translate}}</span>
|
||||
[ngClass]="{'active': project.state === ProjectGrantState.PROJECT_GRANT_STATE_ACTIVE, 'inactive': project.state === ProjectGrantState.PROJECT_GRANT_STATE_INACTIVE}">{{'PROJECT.STATE.'+project.state | translate}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -9,7 +9,7 @@ import { CreationType, MemberCreateDialogComponent } from 'src/app/modules/add-m
|
||||
import { ChangeType } from 'src/app/modules/changes/changes.component';
|
||||
import { UserGrantContext } from 'src/app/modules/user-grants/user-grants-datasource';
|
||||
import { Member } from 'src/app/proto/generated/zitadel/member_pb';
|
||||
import { GrantedProject, ProjectState } from 'src/app/proto/generated/zitadel/project_pb';
|
||||
import { GrantedProject, ProjectGrantState } from 'src/app/proto/generated/zitadel/project_pb';
|
||||
import { User } from 'src/app/proto/generated/zitadel/user_pb';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
@ -24,7 +24,7 @@ export class GrantedProjectDetailComponent implements OnInit, OnDestroy {
|
||||
public grantId: string = '';
|
||||
public project!: GrantedProject.AsObject;
|
||||
|
||||
public ProjectState: any = ProjectState;
|
||||
public ProjectGrantState: any = ProjectGrantState;
|
||||
public ChangeType: any = ChangeType;
|
||||
|
||||
private subscription?: Subscription;
|
||||
|
@ -53,6 +53,14 @@
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="project">
|
||||
<div class="privatelabel-info">
|
||||
<h2 class="setting-title">{{'PROJECT.PAGES.PRIVATELABEL.TITLE' | translate}}</h2>
|
||||
<p class="setting-desc">
|
||||
<span>{{'PROJECT.PAGES.PRIVATELABEL.'+project.privateLabelingSetting+'.TITLE' | translate}}</span>
|
||||
<button (click)="openPrivateLabelingDialog()" mat-icon-button><i class="las la-edit"></i></button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['project.app.read:' + project.id, 'project.app.read']">
|
||||
<app-application-grid *ngIf="grid" [disabled]="isZitadel" (changeView)="grid = false"
|
||||
[projectId]="projectId"></app-application-grid>
|
||||
|
@ -1,7 +1,7 @@
|
||||
.head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #ffffff20;
|
||||
border-bottom: 1px solid #81868a30;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
@ -41,6 +41,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
.privatelabel-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-bottom: 1px solid #81868a30;
|
||||
padding: .5rem 0 1rem 0;
|
||||
|
||||
.setting-title {
|
||||
font-size: 14px;
|
||||
color: var(--grey);
|
||||
text-transform: uppercase;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.setting-desc {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.icon-button {
|
||||
margin-left: .5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
.formfield {
|
||||
flex: 1;
|
||||
|
@ -8,12 +8,15 @@ import { BehaviorSubject, from, Observable, of, Subscription } from 'rxjs';
|
||||
import { catchError, finalize, map } from 'rxjs/operators';
|
||||
import { CreationType, MemberCreateDialogComponent } from 'src/app/modules/add-member-dialog/member-create-dialog.component';
|
||||
import { ChangeType } from 'src/app/modules/changes/changes.component';
|
||||
import {
|
||||
ProjectPrivateLabelingDialogComponent,
|
||||
} from 'src/app/modules/project-private-labeling-dialog/project-private-labeling-dialog.component';
|
||||
import { UserGrantContext } from 'src/app/modules/user-grants/user-grants-datasource';
|
||||
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
|
||||
import { App } from 'src/app/proto/generated/zitadel/app_pb';
|
||||
import { ListAppsResponse, UpdateProjectRequest } from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { Member } from 'src/app/proto/generated/zitadel/member_pb';
|
||||
import { Project, ProjectState } from 'src/app/proto/generated/zitadel/project_pb';
|
||||
import { PrivateLabelingSetting, Project, ProjectState } from 'src/app/proto/generated/zitadel/project_pb';
|
||||
import { User } from 'src/app/proto/generated/zitadel/user_pb';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
@ -70,6 +73,22 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy {
|
||||
this.subscription?.unsubscribe();
|
||||
}
|
||||
|
||||
public openPrivateLabelingDialog(): void {
|
||||
const dialogRef = this.dialog.open(ProjectPrivateLabelingDialogComponent, {
|
||||
data: {
|
||||
setting: this.project.privateLabelingSetting,
|
||||
},
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((resp: PrivateLabelingSetting) => {
|
||||
if (resp !== undefined) {
|
||||
this.project.privateLabelingSetting = resp;
|
||||
this.saveProject();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async getData({ id }: Params): Promise<void> {
|
||||
this.projectId = id;
|
||||
|
||||
@ -186,6 +205,7 @@ export class OwnedProjectDetailComponent implements OnInit, OnDestroy {
|
||||
req.setProjectRoleAssertion(this.project.projectRoleAssertion);
|
||||
req.setProjectRoleCheck(this.project.projectRoleCheck);
|
||||
req.setHasProjectCheck(this.project.hasProjectCheck);
|
||||
req.setPrivateLabelingSetting(this.project.privateLabelingSetting);
|
||||
|
||||
this.mgmtService.updateProject(req).then(() => {
|
||||
this.toast.showInfo('PROJECT.TOAST.UPDATED', true);
|
||||
|
@ -24,45 +24,49 @@ import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.mod
|
||||
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 {
|
||||
ProjectPrivateLabelingDialogModule,
|
||||
} from '../../../modules/project-private-labeling-dialog/project-private-labeling-dialog.module';
|
||||
import { OwnedProjectGridComponent } from './owned-project-list/owned-project-grid/owned-project-grid.component';
|
||||
import { OwnedProjectListComponent } from './owned-project-list/owned-project-list.component';
|
||||
import { OwnedProjectsRoutingModule } from './owned-projects-routing.module';
|
||||
import { OwnedProjectsComponent } from './owned-projects.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
OwnedProjectsComponent,
|
||||
OwnedProjectListComponent,
|
||||
OwnedProjectGridComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
OwnedProjectsRoutingModule,
|
||||
UserGrantsModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
TranslateModule,
|
||||
AvatarModule,
|
||||
ReactiveFormsModule,
|
||||
HasRoleModule,
|
||||
MatTableModule,
|
||||
PaginatorModule,
|
||||
InputModule,
|
||||
MatChipsModule,
|
||||
MatIconModule,
|
||||
WarnDialogModule,
|
||||
MatButtonModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatProgressBarModule,
|
||||
MatCheckboxModule,
|
||||
CardModule,
|
||||
MatTooltipModule,
|
||||
MatSortModule,
|
||||
HasRolePipeModule,
|
||||
TimestampToDatePipeModule,
|
||||
LocalizedDatePipeModule,
|
||||
SharedModule,
|
||||
RefreshTableModule,
|
||||
],
|
||||
declarations: [
|
||||
OwnedProjectsComponent,
|
||||
OwnedProjectListComponent,
|
||||
OwnedProjectGridComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
OwnedProjectsRoutingModule,
|
||||
UserGrantsModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
TranslateModule,
|
||||
AvatarModule,
|
||||
ReactiveFormsModule,
|
||||
HasRoleModule,
|
||||
MatTableModule,
|
||||
PaginatorModule,
|
||||
ProjectPrivateLabelingDialogModule,
|
||||
InputModule,
|
||||
MatChipsModule,
|
||||
MatIconModule,
|
||||
WarnDialogModule,
|
||||
MatButtonModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatProgressBarModule,
|
||||
MatCheckboxModule,
|
||||
CardModule,
|
||||
MatTooltipModule,
|
||||
MatSortModule,
|
||||
HasRolePipeModule,
|
||||
TimestampToDatePipeModule,
|
||||
LocalizedDatePipeModule,
|
||||
SharedModule,
|
||||
RefreshTableModule,
|
||||
],
|
||||
})
|
||||
export class OwnedProjectsModule { }
|
||||
|
@ -140,11 +140,22 @@ export class GrpcAuthService {
|
||||
|
||||
public async getActiveOrg(id?: string): Promise<Org.AsObject> {
|
||||
if (id) {
|
||||
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization);
|
||||
if (org && this.cachedOrgs.find(tmp => tmp.id === org.id)) {
|
||||
return org;
|
||||
const find = this.cachedOrgs.find(tmp => tmp.id === id);
|
||||
if (find) {
|
||||
this.setActiveOrg(find);
|
||||
return Promise.resolve(find);
|
||||
} else {
|
||||
const orgs = (await this.listMyProjectOrgs(10, 0)).resultList;
|
||||
this.cachedOrgs = orgs;
|
||||
|
||||
const toFind = this.cachedOrgs.find(tmp => tmp.id === id);
|
||||
if (toFind) {
|
||||
this.setActiveOrg(toFind);
|
||||
return Promise.resolve(toFind);
|
||||
} else {
|
||||
return Promise.reject(new Error('requested organization not found'));
|
||||
}
|
||||
}
|
||||
return Promise.reject(new Error('no cached org'));
|
||||
} else {
|
||||
let orgs = this.cachedOrgs;
|
||||
if (orgs.length === 0) {
|
||||
|
@ -910,6 +910,25 @@
|
||||
"OWNED": "Eigene Projekte",
|
||||
"GRANTED": "Berechtigte Projekte"
|
||||
},
|
||||
"PRIVATELABEL": {
|
||||
"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."
|
||||
},
|
||||
"1": {
|
||||
"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."
|
||||
},
|
||||
"DIALOG":{
|
||||
"TITLE":"Privatelabeling Verhalten",
|
||||
"DESCRIPTION":"Bestimmen Sie das Verhalten des Projektes im Bezug auf das Privatelabeling."
|
||||
}
|
||||
},
|
||||
"PINNED": "Angepinnt",
|
||||
"ALL": "Alle",
|
||||
"CREATEDON": "Erstellt am",
|
||||
|
@ -912,6 +912,25 @@
|
||||
"OWNED": "Owned Projects",
|
||||
"GRANTED": "Granted Projects"
|
||||
},
|
||||
"PRIVATELABEL": {
|
||||
"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."
|
||||
},
|
||||
"1": {
|
||||
"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."
|
||||
},
|
||||
"DIALOG":{
|
||||
"TITLE":"Privatelabeling Setting",
|
||||
"DESCRIPTION":"Select the behaviour of the login, when using the project."
|
||||
}
|
||||
},
|
||||
"PINNED": "Pinned",
|
||||
"ALL": "All",
|
||||
"CREATEDON": "Created on",
|
||||
|
Loading…
x
Reference in New Issue
Block a user