mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 20:07:23 +00:00
fix(console): new colorpicker, remove icons logo font (#1826)
* custom color picker, delete font * delete asset, i18n * escape deep styles * ts, proto * remove fallback img, color clickable, remove font * stylelint * fix spinner * fix deprecated chipinput.input * improve logo on login * fix qr code * always use black on white for qr code * fix header and footer css Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
parent
255139862d
commit
59af02b2f3
48
console/package-lock.json
generated
48
console/package-lock.json
generated
@ -34,6 +34,7 @@
|
||||
"grpc-web": "^1.2.1",
|
||||
"libphonenumber-js": "^1.9.16",
|
||||
"moment": "^2.29.1",
|
||||
"ngx-color": "^7.0.0",
|
||||
"ngx-quicklink": "^0.2.6",
|
||||
"rxjs": "~6.6.7",
|
||||
"ts-protoc-gen": "^0.14.0",
|
||||
@ -2915,6 +2916,14 @@
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ctrl/tinycolor": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz",
|
||||
"integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@discoveryjs/json-ext": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz",
|
||||
@ -10058,6 +10067,11 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/material-colors": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
|
||||
"integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg=="
|
||||
},
|
||||
"node_modules/mathml-tag-names": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
|
||||
@ -10690,6 +10704,20 @@
|
||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ngx-color": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ngx-color/-/ngx-color-7.0.0.tgz",
|
||||
"integrity": "sha512-BiTapBTT/f3sFSEFqet3xe06bpqmBm7hmA24s09ogRYYVGL1J69U13XfLwTQG8PhX4qNBceh7p5nhKA1zczHMg==",
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "^3.4.0",
|
||||
"material-colors": "^1.2.6",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=12.0.0-0",
|
||||
"@angular/core": ">=12.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/ngx-quicklink": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/ngx-quicklink/-/ngx-quicklink-0.2.6.tgz",
|
||||
@ -19366,6 +19394,11 @@
|
||||
"integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==",
|
||||
"dev": true
|
||||
},
|
||||
"@ctrl/tinycolor": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz",
|
||||
"integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ=="
|
||||
},
|
||||
"@discoveryjs/json-ext": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz",
|
||||
@ -25200,6 +25233,11 @@
|
||||
"object-visit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"material-colors": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
|
||||
"integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg=="
|
||||
},
|
||||
"mathml-tag-names": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
|
||||
@ -25710,6 +25748,16 @@
|
||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||
"dev": true
|
||||
},
|
||||
"ngx-color": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ngx-color/-/ngx-color-7.0.0.tgz",
|
||||
"integrity": "sha512-BiTapBTT/f3sFSEFqet3xe06bpqmBm7hmA24s09ogRYYVGL1J69U13XfLwTQG8PhX4qNBceh7p5nhKA1zczHMg==",
|
||||
"requires": {
|
||||
"@ctrl/tinycolor": "^3.4.0",
|
||||
"material-colors": "^1.2.6",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"ngx-quicklink": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/ngx-quicklink/-/ngx-quicklink-0.2.6.tgz",
|
||||
|
@ -37,6 +37,7 @@
|
||||
"grpc-web": "^1.2.1",
|
||||
"libphonenumber-js": "^1.9.16",
|
||||
"moment": "^2.29.1",
|
||||
"ngx-color": "^7.0.0",
|
||||
"ngx-quicklink": "^0.2.6",
|
||||
"rxjs": "~6.6.7",
|
||||
"ts-protoc-gen": "^0.14.0",
|
||||
|
@ -25,8 +25,8 @@ import { QuicklinkModule } from 'ngx-quicklink';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { OnboardingModule } from 'src/app/modules/onboarding/onboarding.module';
|
||||
import { RegExpPipeModule } from 'src/app/pipes/regexp-pipe/regexp-pipe.module';
|
||||
import { AssetService } from 'src/app/services/asset.service';
|
||||
import { SubscriptionService } from 'src/app/services/subscription.service';
|
||||
import { UploadService } from 'src/app/services/upload.service';
|
||||
|
||||
import { environment } from '../environments/environment';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
@ -181,7 +181,7 @@ const authConfig: AuthConfig = {
|
||||
AuthenticationService,
|
||||
GrpcAuthService,
|
||||
SubscriptionService,
|
||||
UploadService,
|
||||
AssetService,
|
||||
{ provide: 'windowObject', useValue: window },
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
|
@ -16,171 +16,171 @@ import { ToastService } from 'src/app/services/toast.service';
|
||||
import { PolicyComponentServiceType } from '../policies/policy-component-types.enum';
|
||||
|
||||
@Component({
|
||||
selector: 'app-idp-create',
|
||||
templateUrl: './idp-create.component.html',
|
||||
styleUrls: ['./idp-create.component.scss'],
|
||||
selector: 'app-idp-create',
|
||||
templateUrl: './idp-create.component.html',
|
||||
styleUrls: ['./idp-create.component.scss'],
|
||||
})
|
||||
export class IdpCreateComponent implements OnInit, OnDestroy {
|
||||
public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT;
|
||||
private service!: ManagementService | AdminService;
|
||||
public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE];
|
||||
public mappingFields: OIDCMappingField[] = [];
|
||||
public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT;
|
||||
private service!: ManagementService | AdminService;
|
||||
public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE];
|
||||
public mappingFields: OIDCMappingField[] = [];
|
||||
|
||||
private subscription?: Subscription;
|
||||
public projectId: string = '';
|
||||
private subscription?: Subscription;
|
||||
public projectId: string = '';
|
||||
|
||||
public formGroup!: FormGroup;
|
||||
public createSteps: number = 1;
|
||||
public currentCreateStep: number = 1;
|
||||
public loading: boolean = false;
|
||||
constructor(
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
private _location: Location,
|
||||
) {
|
||||
this.formGroup = new FormGroup({
|
||||
name: new FormControl('', [Validators.required]),
|
||||
clientId: new FormControl('', [Validators.required]),
|
||||
clientSecret: new FormControl('', [Validators.required]),
|
||||
issuer: new FormControl('', [Validators.required]),
|
||||
scopesList: new FormControl(['openid', 'profile', 'email'], []),
|
||||
idpDisplayNameMapping: new FormControl(0),
|
||||
usernameMapping: new FormControl(0),
|
||||
});
|
||||
public formGroup!: FormGroup;
|
||||
public createSteps: number = 1;
|
||||
public currentCreateStep: number = 1;
|
||||
public loading: boolean = false;
|
||||
constructor(
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
private _location: Location,
|
||||
) {
|
||||
this.formGroup = new FormGroup({
|
||||
name: new FormControl('', [Validators.required]),
|
||||
clientId: new FormControl('', [Validators.required]),
|
||||
clientSecret: new FormControl('', [Validators.required]),
|
||||
issuer: new FormControl('', [Validators.required]),
|
||||
scopesList: new FormControl(['openid', 'profile', 'email'], []),
|
||||
idpDisplayNameMapping: new FormControl(0),
|
||||
usernameMapping: new FormControl(0),
|
||||
});
|
||||
|
||||
this.route.data.pipe(take(1)).subscribe(data => {
|
||||
this.serviceType = data.serviceType;
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
this.service = this.injector.get(ManagementService as Type<ManagementService>);
|
||||
this.mappingFields = [
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_EMAIL];
|
||||
break;
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
this.service = this.injector.get(AdminService as Type<AdminService>);
|
||||
this.mappingFields = [
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_EMAIL];
|
||||
break;
|
||||
}
|
||||
});
|
||||
this.route.data.pipe(take(1)).subscribe(data => {
|
||||
this.serviceType = data.serviceType;
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
this.service = this.injector.get(ManagementService as Type<ManagementService>);
|
||||
this.mappingFields = [
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_EMAIL];
|
||||
break;
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
this.service = this.injector.get(AdminService as Type<AdminService>);
|
||||
this.mappingFields = [
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_EMAIL];
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.subscription = this.route.params.subscribe(params => this.getData(params));
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
this.subscription?.unsubscribe();
|
||||
}
|
||||
|
||||
private getData({ projectid }: Params): void {
|
||||
this.projectId = projectid;
|
||||
}
|
||||
|
||||
public addIdp(): void {
|
||||
if (this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||
const req = new AddOrgOIDCIDPRequest();
|
||||
|
||||
req.setName(this.name?.value);
|
||||
req.setClientId(this.clientId?.value);
|
||||
req.setClientSecret(this.clientSecret?.value);
|
||||
req.setIssuer(this.issuer?.value);
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setDisplayNameMapping(this.idpDisplayNameMapping?.value);
|
||||
req.setUsernameMapping(this.usernameMapping?.value);
|
||||
this.loading = true;
|
||||
(this.service as ManagementService).addOrgOIDCIDP(req).then((idp) => {
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
this.router.navigate([
|
||||
(this.serviceType === PolicyComponentServiceType.MGMT ? 'org' :
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN ? 'iam' : ''),
|
||||
'policy', 'login']);
|
||||
}, 2000);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
} else if (PolicyComponentServiceType.ADMIN) {
|
||||
const req = new AddOIDCIDPRequest();
|
||||
req.setName(this.name?.value);
|
||||
req.setClientId(this.clientId?.value);
|
||||
req.setClientSecret(this.clientSecret?.value);
|
||||
req.setIssuer(this.issuer?.value);
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setDisplayNameMapping(this.idpDisplayNameMapping?.value);
|
||||
req.setUsernameMapping(this.usernameMapping?.value);
|
||||
this.loading = true;
|
||||
(this.service as AdminService).addOIDCIDP(req).then((idp) => {
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
this.router.navigate([
|
||||
(this.serviceType === PolicyComponentServiceType.MGMT ? 'org' :
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN ? 'iam' : ''),
|
||||
'policy', 'login']);
|
||||
}, 2000);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.subscription = this.route.params.subscribe(params => this.getData(params));
|
||||
}
|
||||
public close(): void {
|
||||
this._location.back();
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
this.subscription?.unsubscribe();
|
||||
}
|
||||
public addScope(event: MatChipInputEvent): void {
|
||||
const input = event.chipInput?.inputElement;
|
||||
const value = event.value.trim();
|
||||
|
||||
private getData({ projectid }: Params): void {
|
||||
this.projectId = projectid;
|
||||
}
|
||||
|
||||
public addIdp(): void {
|
||||
if (this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||
const req = new AddOrgOIDCIDPRequest();
|
||||
|
||||
req.setName(this.name?.value);
|
||||
req.setClientId(this.clientId?.value);
|
||||
req.setClientSecret(this.clientSecret?.value);
|
||||
req.setIssuer(this.issuer?.value);
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setDisplayNameMapping(this.idpDisplayNameMapping?.value);
|
||||
req.setUsernameMapping(this.usernameMapping?.value);
|
||||
this.loading = true;
|
||||
(this.service as ManagementService).addOrgOIDCIDP(req).then((idp) => {
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
this.router.navigate([
|
||||
(this.serviceType === PolicyComponentServiceType.MGMT ? 'org' :
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN ? 'iam' : ''),
|
||||
'policy', 'login']);
|
||||
}, 2000);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
} else if (PolicyComponentServiceType.ADMIN) {
|
||||
const req = new AddOIDCIDPRequest();
|
||||
req.setName(this.name?.value);
|
||||
req.setClientId(this.clientId?.value);
|
||||
req.setClientSecret(this.clientSecret?.value);
|
||||
req.setIssuer(this.issuer?.value);
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setDisplayNameMapping(this.idpDisplayNameMapping?.value);
|
||||
req.setUsernameMapping(this.usernameMapping?.value);
|
||||
this.loading = true;
|
||||
(this.service as AdminService).addOIDCIDP(req).then((idp) => {
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
this.router.navigate([
|
||||
(this.serviceType === PolicyComponentServiceType.MGMT ? 'org' :
|
||||
this.serviceType === PolicyComponentServiceType.ADMIN ? 'iam' : ''),
|
||||
'policy', 'login']);
|
||||
}, 2000);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
if (value !== '') {
|
||||
if (this.scopesList?.value) {
|
||||
this.scopesList.value.push(value);
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
this._location.back();
|
||||
public removeScope(uri: string): void {
|
||||
if (this.scopesList?.value) {
|
||||
const index = this.scopesList.value.indexOf(uri);
|
||||
|
||||
if (index !== undefined && index >= 0) {
|
||||
this.scopesList.value.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public addScope(event: MatChipInputEvent): void {
|
||||
const input = event.input;
|
||||
const value = event.value.trim();
|
||||
public get name(): AbstractControl | null {
|
||||
return this.formGroup.get('name');
|
||||
}
|
||||
|
||||
if (value !== '') {
|
||||
if (this.scopesList?.value) {
|
||||
this.scopesList.value.push(value);
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public get clientId(): AbstractControl | null {
|
||||
return this.formGroup.get('clientId');
|
||||
}
|
||||
|
||||
public removeScope(uri: string): void {
|
||||
if (this.scopesList?.value) {
|
||||
const index = this.scopesList.value.indexOf(uri);
|
||||
public get clientSecret(): AbstractControl | null {
|
||||
return this.formGroup.get('clientSecret');
|
||||
}
|
||||
|
||||
if (index !== undefined && index >= 0) {
|
||||
this.scopesList.value.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
public get issuer(): AbstractControl | null {
|
||||
return this.formGroup.get('issuer');
|
||||
}
|
||||
public get scopesList(): AbstractControl | null {
|
||||
return this.formGroup.get('scopesList');
|
||||
}
|
||||
|
||||
public get name(): AbstractControl | null {
|
||||
return this.formGroup.get('name');
|
||||
}
|
||||
public get idpDisplayNameMapping(): AbstractControl | null {
|
||||
return this.formGroup.get('idpDisplayNameMapping');
|
||||
}
|
||||
|
||||
public get clientId(): AbstractControl | null {
|
||||
return this.formGroup.get('clientId');
|
||||
}
|
||||
|
||||
public get clientSecret(): AbstractControl | null {
|
||||
return this.formGroup.get('clientSecret');
|
||||
}
|
||||
|
||||
public get issuer(): AbstractControl | null {
|
||||
return this.formGroup.get('issuer');
|
||||
}
|
||||
public get scopesList(): AbstractControl | null {
|
||||
return this.formGroup.get('scopesList');
|
||||
}
|
||||
|
||||
public get idpDisplayNameMapping(): AbstractControl | null {
|
||||
return this.formGroup.get('idpDisplayNameMapping');
|
||||
}
|
||||
|
||||
public get usernameMapping(): AbstractControl | null {
|
||||
return this.formGroup.get('usernameMapping');
|
||||
}
|
||||
public get usernameMapping(): AbstractControl | null {
|
||||
return this.formGroup.get('usernameMapping');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,245 +16,245 @@ import { ToastService } from 'src/app/services/toast.service';
|
||||
import { PolicyComponentServiceType } from '../policies/policy-component-types.enum';
|
||||
|
||||
@Component({
|
||||
selector: 'app-idp',
|
||||
templateUrl: './idp.component.html',
|
||||
styleUrls: ['./idp.component.scss'],
|
||||
selector: 'app-idp',
|
||||
templateUrl: './idp.component.html',
|
||||
styleUrls: ['./idp.component.scss'],
|
||||
})
|
||||
export class IdpComponent implements OnInit, OnDestroy {
|
||||
public mappingFields: OIDCMappingField[] = [];
|
||||
public styleFields: IDPStylingType[] = [];
|
||||
public mappingFields: OIDCMappingField[] = [];
|
||||
public styleFields: IDPStylingType[] = [];
|
||||
|
||||
public showIdSecretSection: boolean = false;
|
||||
public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT;
|
||||
private service!: ManagementService | AdminService;
|
||||
public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE];
|
||||
public showIdSecretSection: boolean = false;
|
||||
public serviceType: PolicyComponentServiceType = PolicyComponentServiceType.MGMT;
|
||||
private service!: ManagementService | AdminService;
|
||||
public readonly separatorKeysCodes: number[] = [ENTER, COMMA, SPACE];
|
||||
|
||||
private subscription?: Subscription;
|
||||
public projectId: string = '';
|
||||
private subscription?: Subscription;
|
||||
public projectId: string = '';
|
||||
|
||||
public idpForm!: FormGroup;
|
||||
public oidcConfigForm!: FormGroup;
|
||||
public idpForm!: FormGroup;
|
||||
public oidcConfigForm!: FormGroup;
|
||||
|
||||
constructor(
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
private route: ActivatedRoute,
|
||||
private _location: Location,
|
||||
) {
|
||||
this.idpForm = new FormGroup({
|
||||
id: new FormControl({ disabled: true, value: '' }, [Validators.required]),
|
||||
name: new FormControl('', [Validators.required]),
|
||||
stylingType: new FormControl('', [Validators.required]),
|
||||
});
|
||||
constructor(
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
private route: ActivatedRoute,
|
||||
private _location: Location,
|
||||
) {
|
||||
this.idpForm = new FormGroup({
|
||||
id: new FormControl({ disabled: true, value: '' }, [Validators.required]),
|
||||
name: new FormControl('', [Validators.required]),
|
||||
stylingType: new FormControl('', [Validators.required]),
|
||||
});
|
||||
|
||||
this.oidcConfigForm = new FormGroup({
|
||||
clientId: new FormControl('', [Validators.required]),
|
||||
clientSecret: new FormControl(''),
|
||||
issuer: new FormControl('', [Validators.required]),
|
||||
scopesList: new FormControl([], []),
|
||||
idpDisplayNameMapping: new FormControl(0),
|
||||
usernameMapping: new FormControl(0),
|
||||
});
|
||||
this.oidcConfigForm = new FormGroup({
|
||||
clientId: new FormControl('', [Validators.required]),
|
||||
clientSecret: new FormControl(''),
|
||||
issuer: new FormControl('', [Validators.required]),
|
||||
scopesList: new FormControl([], []),
|
||||
idpDisplayNameMapping: new FormControl(0),
|
||||
usernameMapping: new FormControl(0),
|
||||
});
|
||||
|
||||
this.route.data.pipe(switchMap(data => {
|
||||
this.serviceType = data.serviceType;
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
this.service = this.injector.get(ManagementService as Type<ManagementService>);
|
||||
this.route.data.pipe(switchMap(data => {
|
||||
this.serviceType = data.serviceType;
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
this.service = this.injector.get(ManagementService as Type<ManagementService>);
|
||||
|
||||
break;
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
this.service = this.injector.get(AdminService as Type<AdminService>);
|
||||
break;
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
this.service = this.injector.get(AdminService as Type<AdminService>);
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this.mappingFields = [
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_EMAIL];
|
||||
this.styleFields = [
|
||||
IDPStylingType.STYLING_TYPE_UNSPECIFIED,
|
||||
IDPStylingType.STYLING_TYPE_GOOGLE];
|
||||
this.mappingFields = [
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_PREFERRED_USERNAME,
|
||||
OIDCMappingField.OIDC_MAPPING_FIELD_EMAIL];
|
||||
this.styleFields = [
|
||||
IDPStylingType.STYLING_TYPE_UNSPECIFIED,
|
||||
IDPStylingType.STYLING_TYPE_GOOGLE];
|
||||
|
||||
return this.route.params.pipe(take(1));
|
||||
})).subscribe((params) => {
|
||||
const { id } = params;
|
||||
if (id) {
|
||||
if (this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||
(this.service as ManagementService).getOrgIDPByID(id).then(resp => {
|
||||
if (resp.idp) {
|
||||
const idpObject = resp.idp;
|
||||
this.idpForm.patchValue(idpObject);
|
||||
if (idpObject.oidcConfig) {
|
||||
this.oidcConfigForm.patchValue(idpObject.oidcConfig);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (this.serviceType === PolicyComponentServiceType.ADMIN) {
|
||||
(this.service as AdminService).getIDPByID(id).then(resp => {
|
||||
if (resp.idp) {
|
||||
const idpObject = resp.idp;
|
||||
this.idpForm.patchValue(idpObject);
|
||||
if (idpObject.oidcConfig) {
|
||||
this.oidcConfigForm.patchValue(idpObject.oidcConfig);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.subscription = this.route.params.subscribe(params => this.getData(params));
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
this.subscription?.unsubscribe();
|
||||
}
|
||||
|
||||
private getData({ projectid }: Params): void {
|
||||
this.projectId = projectid;
|
||||
}
|
||||
|
||||
public updateIdp(): void {
|
||||
return this.route.params.pipe(take(1));
|
||||
})).subscribe((params) => {
|
||||
const { id } = params;
|
||||
if (id) {
|
||||
if (this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||
const req = new UpdateOrgIDPRequest();
|
||||
|
||||
req.setIdpId(this.id?.value);
|
||||
req.setName(this.name?.value);
|
||||
req.setStylingType(this.stylingType?.value);
|
||||
|
||||
(this.service as ManagementService).updateOrgIDP(req).then(() => {
|
||||
this.toast.showInfo('IDP.TOAST.SAVED', true);
|
||||
// this.router.navigate(['idp', ]);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
} else if (this.serviceType === PolicyComponentServiceType.ADMIN) {
|
||||
const req = new UpdateIDPRequest();
|
||||
|
||||
req.setIdpId(this.id?.value);
|
||||
req.setName(this.name?.value);
|
||||
req.setStylingType(this.stylingType?.value);
|
||||
|
||||
(this.service as AdminService).updateIDP(req).then(() => {
|
||||
this.toast.showInfo('IDP.TOAST.SAVED', true);
|
||||
// this.router.navigate(['idp', ]);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public updateOidcConfig(): void {
|
||||
if (this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||
const req = new UpdateOrgIDPOIDCConfigRequest();
|
||||
|
||||
req.setIdpId(this.id?.value);
|
||||
req.setClientId(this.clientId?.value);
|
||||
req.setClientSecret(this.clientSecret?.value);
|
||||
req.setIssuer(this.issuer?.value);
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setUsernameMapping(this.usernameMapping?.value);
|
||||
req.setDisplayNameMapping(this.idpDisplayNameMapping?.value);
|
||||
|
||||
(this.service as ManagementService).updateOrgIDPOIDCConfig(req).then((oidcConfig) => {
|
||||
this.toast.showInfo('IDP.TOAST.SAVED', true);
|
||||
// this.router.navigate(['idp', ]);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
} else if (this.serviceType === PolicyComponentServiceType.ADMIN) {
|
||||
const req = new UpdateIDPOIDCConfigRequest();
|
||||
|
||||
req.setIdpId(this.id?.value);
|
||||
req.setClientId(this.clientId?.value);
|
||||
req.setClientSecret(this.clientSecret?.value);
|
||||
req.setIssuer(this.issuer?.value);
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setUsernameMapping(this.usernameMapping?.value);
|
||||
req.setDisplayNameMapping(this.idpDisplayNameMapping?.value);
|
||||
|
||||
(this.service as AdminService).updateIDPOIDCConfig(req).then((oidcConfig) => {
|
||||
this.toast.showInfo('IDP.TOAST.SAVED', true);
|
||||
// this.router.navigate(['idp', ]);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
this._location.back();
|
||||
}
|
||||
|
||||
public addScope(event: MatChipInputEvent): void {
|
||||
const input = event.input;
|
||||
const value = event.value.trim();
|
||||
|
||||
if (value !== '') {
|
||||
if (this.scopesList?.value) {
|
||||
this.scopesList.value.push(value);
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
(this.service as ManagementService).getOrgIDPByID(id).then(resp => {
|
||||
if (resp.idp) {
|
||||
const idpObject = resp.idp;
|
||||
this.idpForm.patchValue(idpObject);
|
||||
if (idpObject.oidcConfig) {
|
||||
this.oidcConfigForm.patchValue(idpObject.oidcConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public removeScope(uri: string): void {
|
||||
if (this.scopesList?.value) {
|
||||
const index = this.scopesList?.value.indexOf(uri);
|
||||
|
||||
if (index !== undefined && index >= 0) {
|
||||
this.scopesList?.value.splice(index, 1);
|
||||
});
|
||||
} else if (this.serviceType === PolicyComponentServiceType.ADMIN) {
|
||||
(this.service as AdminService).getIDPByID(id).then(resp => {
|
||||
if (resp.idp) {
|
||||
const idpObject = resp.idp;
|
||||
this.idpForm.patchValue(idpObject);
|
||||
if (idpObject.oidcConfig) {
|
||||
this.oidcConfigForm.patchValue(idpObject.oidcConfig);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public get backroutes(): string[] {
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
return ['/org', 'policy', 'login'];
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
return ['/iam', 'policy', 'login'];
|
||||
public ngOnInit(): void {
|
||||
this.subscription = this.route.params.subscribe(params => this.getData(params));
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
this.subscription?.unsubscribe();
|
||||
}
|
||||
|
||||
private getData({ projectid }: Params): void {
|
||||
this.projectId = projectid;
|
||||
}
|
||||
|
||||
public updateIdp(): void {
|
||||
if (this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||
const req = new UpdateOrgIDPRequest();
|
||||
|
||||
req.setIdpId(this.id?.value);
|
||||
req.setName(this.name?.value);
|
||||
req.setStylingType(this.stylingType?.value);
|
||||
|
||||
(this.service as ManagementService).updateOrgIDP(req).then(() => {
|
||||
this.toast.showInfo('IDP.TOAST.SAVED', true);
|
||||
// this.router.navigate(['idp', ]);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
} else if (this.serviceType === PolicyComponentServiceType.ADMIN) {
|
||||
const req = new UpdateIDPRequest();
|
||||
|
||||
req.setIdpId(this.id?.value);
|
||||
req.setName(this.name?.value);
|
||||
req.setStylingType(this.stylingType?.value);
|
||||
|
||||
(this.service as AdminService).updateIDP(req).then(() => {
|
||||
this.toast.showInfo('IDP.TOAST.SAVED', true);
|
||||
// this.router.navigate(['idp', ]);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public updateOidcConfig(): void {
|
||||
if (this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||
const req = new UpdateOrgIDPOIDCConfigRequest();
|
||||
|
||||
req.setIdpId(this.id?.value);
|
||||
req.setClientId(this.clientId?.value);
|
||||
req.setClientSecret(this.clientSecret?.value);
|
||||
req.setIssuer(this.issuer?.value);
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setUsernameMapping(this.usernameMapping?.value);
|
||||
req.setDisplayNameMapping(this.idpDisplayNameMapping?.value);
|
||||
|
||||
(this.service as ManagementService).updateOrgIDPOIDCConfig(req).then((oidcConfig) => {
|
||||
this.toast.showInfo('IDP.TOAST.SAVED', true);
|
||||
// this.router.navigate(['idp', ]);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
} else if (this.serviceType === PolicyComponentServiceType.ADMIN) {
|
||||
const req = new UpdateIDPOIDCConfigRequest();
|
||||
|
||||
req.setIdpId(this.id?.value);
|
||||
req.setClientId(this.clientId?.value);
|
||||
req.setClientSecret(this.clientSecret?.value);
|
||||
req.setIssuer(this.issuer?.value);
|
||||
req.setScopesList(this.scopesList?.value);
|
||||
req.setUsernameMapping(this.usernameMapping?.value);
|
||||
req.setDisplayNameMapping(this.idpDisplayNameMapping?.value);
|
||||
|
||||
(this.service as AdminService).updateIDPOIDCConfig(req).then((oidcConfig) => {
|
||||
this.toast.showInfo('IDP.TOAST.SAVED', true);
|
||||
// this.router.navigate(['idp', ]);
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
this._location.back();
|
||||
}
|
||||
|
||||
public addScope(event: MatChipInputEvent): void {
|
||||
const input = event.chipInput?.inputElement;
|
||||
const value = event.value.trim();
|
||||
|
||||
if (value !== '') {
|
||||
if (this.scopesList?.value) {
|
||||
this.scopesList.value.push(value);
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public get id(): AbstractControl | null {
|
||||
return this.idpForm.get('id');
|
||||
}
|
||||
public removeScope(uri: string): void {
|
||||
if (this.scopesList?.value) {
|
||||
const index = this.scopesList?.value.indexOf(uri);
|
||||
|
||||
public get name(): AbstractControl | null {
|
||||
return this.idpForm.get('name');
|
||||
if (index !== undefined && index >= 0) {
|
||||
this.scopesList?.value.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public get stylingType(): AbstractControl | null {
|
||||
return this.idpForm.get('stylingType');
|
||||
public get backroutes(): string[] {
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
return ['/org', 'policy', 'login'];
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
return ['/iam', 'policy', 'login'];
|
||||
}
|
||||
}
|
||||
|
||||
public get clientId(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('clientId');
|
||||
}
|
||||
public get id(): AbstractControl | null {
|
||||
return this.idpForm.get('id');
|
||||
}
|
||||
|
||||
public get clientSecret(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('clientSecret');
|
||||
}
|
||||
public get name(): AbstractControl | null {
|
||||
return this.idpForm.get('name');
|
||||
}
|
||||
|
||||
public get issuer(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('issuer');
|
||||
}
|
||||
public get stylingType(): AbstractControl | null {
|
||||
return this.idpForm.get('stylingType');
|
||||
}
|
||||
|
||||
public get scopesList(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('scopesList');
|
||||
}
|
||||
public get clientId(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('clientId');
|
||||
}
|
||||
|
||||
public get idpDisplayNameMapping(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('idpDisplayNameMapping');
|
||||
}
|
||||
public get clientSecret(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('clientSecret');
|
||||
}
|
||||
|
||||
public get usernameMapping(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('usernameMapping');
|
||||
}
|
||||
public get issuer(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('issuer');
|
||||
}
|
||||
|
||||
public get scopesList(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('scopesList');
|
||||
}
|
||||
|
||||
public get idpDisplayNameMapping(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('idpDisplayNameMapping');
|
||||
}
|
||||
|
||||
public get usernameMapping(): AbstractControl | null {
|
||||
return this.oidcConfigForm.get('usernameMapping');
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,19 @@
|
||||
<div class="form-row">
|
||||
<cnsl-form-field class="formfield">
|
||||
<cnsl-label>{{name}} (current {{color}})</cnsl-label>
|
||||
<input cnslInput [(ngModel)]="previewColor" (keydown.enter)="name ? emitPreview(previewColor) : null" />
|
||||
</cnsl-form-field>
|
||||
<button matTooltip="{{'ACTIONS.SET' | translate}}" (click)="emitPreview(previewColor)" mat-icon-button><mat-icon>check</mat-icon></button>
|
||||
</div>
|
||||
<div class="color-selector">
|
||||
<div *ngFor="let c of colors" class="circle mat-elevation-z3"
|
||||
[ngClass]="{'active': color == c.color || previewColor == c.color}"
|
||||
(click)="emitPreview(c.color)" [ngStyle]="{'background-color': c.color}">
|
||||
<span *ngIf="previewColor == c.color">P</span>
|
||||
<span *ngIf="color == c.color">C</span>
|
||||
<p class="name">{{name}} (current {{color}})</p>
|
||||
|
||||
<div class="wrapper">
|
||||
<button class="mat-elevation-z3" [style.background-color]="previewColor" (click)="isOpen = !isOpen" cdkOverlayOrigin #trigger="cdkOverlayOrigin" matTooltip="{{'ACTIONS.SET' | translate}}"> </button>
|
||||
|
||||
<div class="hex-wrapper" (click)="isOpen = !isOpen">
|
||||
<i class="las la-hashtag"></i>
|
||||
<span class="hex">{{previewColorCropped}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template
|
||||
cdkConnectedOverlay
|
||||
[cdkConnectedOverlayOrigin]="trigger"
|
||||
[cdkConnectedOverlayOpen]="isOpen"
|
||||
(overlayOutsideClick)="isOpen = false"
|
||||
>
|
||||
<color-chrome class="picker" [color]="previewColor" (onChangeComplete)="changeComplete($event)"></color-chrome>
|
||||
</ng-template>
|
@ -1,52 +1,52 @@
|
||||
.title {
|
||||
// font-size: 1rem;
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
|
||||
&.border {
|
||||
border-top: 1px solid var(--grey);
|
||||
padding-top: 1.5rem;
|
||||
}
|
||||
.name {
|
||||
font-size: 14px;
|
||||
margin-bottom: 0;
|
||||
color: var(--grey);
|
||||
}
|
||||
|
||||
.form-row {
|
||||
.wrapper {
|
||||
border-radius: .5rem;
|
||||
padding: 0 1rem;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
align-items: center;
|
||||
|
||||
.formfield {
|
||||
flex: 1;
|
||||
.hex-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
color: var(--grey);
|
||||
font-size: 14px;
|
||||
padding: 0 1rem;
|
||||
cursor: pointer;
|
||||
|
||||
.hex {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
margin-bottom: .9rem;
|
||||
}
|
||||
}
|
||||
|
||||
.color-selector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -.25rem;
|
||||
width: 100%;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
.circle {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
background-color: #cd5c5c;
|
||||
border-radius: 50%;
|
||||
margin: .25rem;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
margin: .5rem 0;
|
||||
border-radius: .5rem;
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
span {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
border: 3px solid #ffffff90;
|
||||
}
|
||||
border: none;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.picker {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
// stylelint-disable
|
||||
::ng-deep .chrome-picker {
|
||||
border-radius: .5rem !important;
|
||||
}
|
||||
|
||||
::ng-deep .saturation {
|
||||
border-radius: .5rem .5rem 0 0 !important;
|
||||
}
|
||||
// stylelint-enable
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { ColorEvent } from 'ngx-color';
|
||||
|
||||
import { ColorType } from '../private-labeling-policy.component';
|
||||
|
||||
@ -77,6 +78,7 @@ export class ColorComponent implements OnInit {
|
||||
];
|
||||
|
||||
public colors: Array<{ name: string; color: string; }> = this.PRIMARY;
|
||||
public isOpen: boolean = false;
|
||||
|
||||
@Input() colorType: ColorType = ColorType.PRIMARY;
|
||||
@Input() color: string = '';
|
||||
@ -89,8 +91,7 @@ export class ColorComponent implements OnInit {
|
||||
this.previewChanged.emit(this.previewColor);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
public ngOnInit(): void {
|
||||
switch (this.colorType) {
|
||||
case ColorType.PRIMARY:
|
||||
this.colors = this.PRIMARY;
|
||||
@ -115,4 +116,16 @@ export class ColorComponent implements OnInit {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public changeComplete(event: ColorEvent): void {
|
||||
this.emitPreview(event.color.hex);
|
||||
}
|
||||
|
||||
public get previewColorCropped(): string {
|
||||
let s = this.previewColor;
|
||||
while (s.charAt(0) === '#') {
|
||||
s = s.substring(1);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,8 @@
|
||||
<div class="dashed" [ngClass]="{'dark': theme === Theme.DARK, 'light': theme === Theme.LIGHT}" [style.background]="theme == Theme.DARK ? policy.backgroundColorDark : policy.backgroundColor">
|
||||
<div class="login-wrapper" [style.color]="theme == Theme.DARK ? policy.fontColorDark : policy.fontColor">
|
||||
<img *ngIf="images['previewLogo'] && theme == Theme.LIGHT" [src]="images['previewLogo']" alt="logo-mock" />
|
||||
<img *ngIf="!images['previewLogo'] && theme == Theme.LIGHT" src="../../../../assets/images/zitadel-logo-dark.svg" alt="logo-mock" />
|
||||
|
||||
<img *ngIf="images['previewDarkLogo'] && theme == Theme.DARK" [src]="images['previewDarkLogo']" alt="logo-mock" />
|
||||
<img *ngIf="!images['previewDarkLogo'] && theme == Theme.DARK" src="../../../../assets/images/zitadel-logo-light.svg" alt="logo-mock" />
|
||||
|
||||
<h1>{{'POLICY.PRIVATELABELING.PREVIEW.TITLE' | translate}}</h1>
|
||||
<p class="desc-text">{{'POLICY.PRIVATELABELING.PREVIEW.SECOND' | translate}}</p>
|
||||
|
@ -15,13 +15,6 @@
|
||||
<mat-spinner diameter="30" *ngIf="loading" color="primary"></mat-spinner>
|
||||
</div>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['policy.delete']">
|
||||
<button *ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||
matTooltip="{{'POLICY.RESET' | translate}}" color="warn" (click)="removePolicy()" mat-stroked-button>
|
||||
{{'POLICY.RESET' | translate}}
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
<div class="top-row">
|
||||
<div>
|
||||
<p>{{'POLICY.PRIVATELABELING.THEME' | translate}}</p>
|
||||
@ -35,6 +28,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
|
||||
<ng-template appHasRole [appHasRole]="['policy.delete']">
|
||||
<button class="reset-button" *ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||
matTooltip="{{'POLICY.RESET' | translate}}" color="warn" (click)="removePolicy()" mat-stroked-button>
|
||||
{{'POLICY.RESET' | translate}}
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
<button class="activate-button" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['label_policy.private_label'] | hasFeature | async) == false" mat-raised-button color="primary" (click)="activatePolicy()">
|
||||
{{'POLICY.PRIVATELABELING.ACTIVATEPREVIEW' | translate}}
|
||||
</button>
|
||||
@ -64,14 +66,26 @@
|
||||
<mat-spinner class="spinner" color="primary" diameter="25" *ngIf="loadingImages"></mat-spinner>
|
||||
<container [ngSwitch]="theme">
|
||||
<div class="logo-view" *ngSwitchCase="Theme.DARK">
|
||||
<img matTooltip="Preview" class="prev" *ngIf="images['previewDarkLogo']" [src]="images['previewDarkLogo']" alt="dark logo preview"/>
|
||||
<div class="img-wrapper" *ngIf="images['previewDarkLogo']" >
|
||||
<mat-icon matTooltip="{{'ACTIONS.DELETE' | translate}}" color="warn" class="dl-btn" (click)="deleteAsset(AssetType.LOGO, theme)">remove_circle</mat-icon>
|
||||
<img matTooltip="Preview" class="prev" [src]="images['previewDarkLogo']" alt="dark logo preview"/>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<img matTooltip="Current" class="curr" *ngIf="images['darkLogo']" [src]="images['darkLogo']" alt="dark logo"/>
|
||||
<div class="img-wrapper" *ngIf="images['darkLogo']">
|
||||
<!-- <mat-icon matTooltip="{{'ACTIONS.DELETE' | translate}}" color="warn" class="dl-btn" (click)="deleteAsset(AssetType.LOGO, theme, Preview.PREVIEW)">remove_circle</mat-icon> -->
|
||||
<img matTooltip="Current" class="curr" [src]="images['darkLogo']" alt="dark logo"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="logo-view" *ngSwitchCase="Theme.LIGHT">
|
||||
<img matTooltip="Preview" class="prev" *ngIf="images['previewLogo']" [src]="images['previewLogo']" alt="logo preview"/>
|
||||
<div class="img-wrapper" *ngIf="images['previewLogo']">
|
||||
<mat-icon matTooltip="{{'ACTIONS.DELETE' | translate}}" color="warn" class="dl-btn" (click)="deleteAsset(AssetType.LOGO, theme)">remove_circle</mat-icon>
|
||||
<img matTooltip="Preview" class="prev" [src]="images['previewLogo']" alt="logo preview"/>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<img matTooltip="Current" class="curr" *ngIf="images['logo']" [src]="images['logo']" alt="logo"/>
|
||||
<div class="img-wrapper" *ngIf="images['logo']">
|
||||
<!-- <mat-icon matTooltip="{{'ACTIONS.DELETE' | translate}}" color="warn" class="dl-btn" (click)="deleteAsset(AssetType.LOGO, theme, Preview.PREVIEW)">remove_circle</mat-icon> -->
|
||||
<img matTooltip="Current" class="curr" [src]="images['logo']" alt="logo"/>
|
||||
</div>
|
||||
</div>
|
||||
</container>
|
||||
<div class="dropzone" cnslDropzone (hovered)="toggleHoverLogo(theme, $event)"
|
||||
@ -92,14 +106,26 @@
|
||||
<mat-spinner class="spinner" color="primary" diameter="25" *ngIf="loadingImages"></mat-spinner>
|
||||
<container [ngSwitch]="theme">
|
||||
<div class="logo-view" *ngSwitchCase="Theme.DARK">
|
||||
<img matTooltip="Preview" class="prev" *ngIf="images['previewDarkIcon']" [src]="images['previewDarkIcon']" alt="dark icon preview"/>
|
||||
<div class="img-wrapper" *ngIf="images['previewDarkIcon']">
|
||||
<mat-icon matTooltip="{{'ACTIONS.DELETE' | translate}}" color="warn" class="dl-btn" (click)="deleteAsset(AssetType.ICON, theme)">remove_circle</mat-icon>
|
||||
<img matTooltip="Preview" class="prev" [src]="images['previewDarkIcon']" alt="dark icon preview"/>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<img matTooltip="Current" class="curr" *ngIf="images['darkIcon']" [src]="images['darkIcon']" alt="dark icon"/>
|
||||
<div class="img-wrapper" *ngIf="images['darkIcon']">
|
||||
<!-- <mat-icon matTooltip="{{'ACTIONS.DELETE' | translate}}" color="warn" class="dl-btn" (click)="deleteAsset(AssetType.ICON,theme, Preview.CURRENT)">remove_circle</mat-icon> -->
|
||||
<img matTooltip="Current" class="curr" [src]="images['darkIcon']" alt="dark icon"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="logo-view" *ngSwitchCase="Theme.LIGHT">
|
||||
<img matTooltip="Preview" class="prev" *ngIf="images['previewIcon']" [src]="images['previewIcon']" alt="icon preview"/>
|
||||
<div class="img-wrapper" *ngIf="images['previewIcon']">
|
||||
<mat-icon matTooltip="{{'ACTIONS.DELETE' | translate}}" color="warn" class="dl-btn" (click)="deleteAsset(AssetType.ICON,theme)">remove_circle</mat-icon>
|
||||
<img matTooltip="Preview" class="prev" [src]="images['previewIcon']" alt="icon preview"/>
|
||||
</div>
|
||||
<span class="fill-space"></span>
|
||||
<img matTooltip="Current" class="curr" *ngIf="images['icon']" [src]="images['icon']" alt="icon"/>
|
||||
<div class="img-wrapper" *ngIf="images['icon']" >
|
||||
<!-- <mat-icon matTooltip="{{'ACTIONS.DELETE' | translate}}" color="warn" class="dl-btn" (click)="deleteAsset(AssetType.ICON,theme, Preview.CURRENT)">remove_circle</mat-icon> -->
|
||||
<img matTooltip="Current" class="curr"[src]="images['icon']" alt="icon"/>
|
||||
</div>
|
||||
</div>
|
||||
</container>
|
||||
<div class="dropzone" cnslDropzone (hovered)="toggleHoverIcon(theme, $event)"
|
||||
@ -132,19 +158,19 @@
|
||||
<ng-container *ngIf="theme==Theme.DARK">
|
||||
<div class="colors" *ngIf="data && previewData">
|
||||
<div class="color">
|
||||
<cnsl-color [colorType]="ColorType.BACKGROUNDDARK"(previewChanged)="previewData.backgroundColorDark = $event; savePolicy()" name="Background Color Dark" [color]="data.backgroundColorDark" [previewColor]="previewData.backgroundColorDark"></cnsl-color>
|
||||
<cnsl-color [colorType]="ColorType.BACKGROUNDDARK" (previewChanged)="previewData.backgroundColorDark = $event" name="Background Color Dark" [color]="data.backgroundColorDark" [previewColor]="previewData.backgroundColorDark"></cnsl-color>
|
||||
</div>
|
||||
|
||||
<div class="color">
|
||||
<cnsl-color [colorType]="ColorType.PRIMARY"(previewChanged)="previewData.primaryColorDark = $event; savePolicy()" name="Preview Primary Color Dark" [color]="data.primaryColorDark" [previewColor]="previewData.primaryColorDark"></cnsl-color>
|
||||
<cnsl-color [colorType]="ColorType.PRIMARY"(previewChanged)="previewData.primaryColorDark = $event" name="Preview Primary Color Dark" [color]="data.primaryColorDark" [previewColor]="previewData.primaryColorDark"></cnsl-color>
|
||||
</div>
|
||||
|
||||
<div class="color">
|
||||
<cnsl-color [colorType]="ColorType.WARN" (previewChanged)="previewData.warnColorDark = $event; savePolicy()" name="Preview Warn Color Dark" [color]="data.warnColorDark" [previewColor]="previewData.warnColorDark"></cnsl-color>
|
||||
<cnsl-color [colorType]="ColorType.WARN" (previewChanged)="previewData.warnColorDark = $event" name="Preview Warn Color Dark" [color]="data.warnColorDark" [previewColor]="previewData.warnColorDark"></cnsl-color>
|
||||
</div>
|
||||
|
||||
<div class="color">
|
||||
<cnsl-color [colorType]="ColorType.FONTDARK"(previewChanged)="previewData.fontColorDark = $event; savePolicy()" name="Font Color Dark" [color]="data.fontColorDark" [previewColor]="previewData.fontColorDark"></cnsl-color>
|
||||
<cnsl-color [colorType]="ColorType.FONTDARK"(previewChanged)="previewData.fontColorDark = $event" name="Font Color Dark" [color]="data.fontColorDark" [previewColor]="previewData.fontColorDark"></cnsl-color>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
@ -152,22 +178,26 @@
|
||||
<ng-container *ngIf="theme==Theme.LIGHT">
|
||||
<div class="colors" *ngIf="data && previewData">
|
||||
<div class="color">
|
||||
<cnsl-color [colorType]="ColorType.BACKGROUNDLIGHT" (previewChanged)="previewData.backgroundColor = $event; savePolicy()" name="Background Color Light" [color]="data.backgroundColor" [previewColor]="previewData.backgroundColor"></cnsl-color>
|
||||
<cnsl-color [colorType]="ColorType.BACKGROUNDLIGHT" (previewChanged)="previewData.backgroundColor = $event" name="Background Color Light" [color]="data.backgroundColor" [previewColor]="previewData.backgroundColor"></cnsl-color>
|
||||
</div>
|
||||
|
||||
<div class="color">
|
||||
<cnsl-color [colorType]="ColorType.PRIMARY" (previewChanged)="previewData.primaryColor = $event; savePolicy()" name="Preview Primary Color Light" [color]="data.primaryColor" [previewColor]="previewData.primaryColor"></cnsl-color>
|
||||
<cnsl-color [colorType]="ColorType.PRIMARY" (previewChanged)="previewData.primaryColor = $event" name="Preview Primary Color Light" [color]="data.primaryColor" [previewColor]="previewData.primaryColor"></cnsl-color>
|
||||
</div>
|
||||
|
||||
<div class="color">
|
||||
<cnsl-color [colorType]="ColorType.WARN" name="Preview Warn Color Light" (previewChanged)="previewData.warnColor= $event; savePolicy()" [color]="data.warnColor" [previewColor]="previewData.warnColor"></cnsl-color>
|
||||
<cnsl-color [colorType]="ColorType.WARN" name="Preview Warn Color Light" (previewChanged)="previewData.warnColor= $event" [color]="data.warnColor" [previewColor]="previewData.warnColor"></cnsl-color>
|
||||
</div>
|
||||
|
||||
<div class="color">
|
||||
<cnsl-color [colorType]="ColorType.FONTLIGHT" (previewChanged)="previewData.fontColor = $event; savePolicy()" name="Font Color" [color]="data.fontColor" [previewColor]="previewData.fontColor"></cnsl-color>
|
||||
<cnsl-color [colorType]="ColorType.FONTLIGHT" (previewChanged)="previewData.fontColor = $event" name="Font Color" [color]="data.fontColor" [previewColor]="previewData.fontColor"></cnsl-color>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div class="clr-btn-wrapper">
|
||||
<button color="primary" mat-raised-button (click)="savePolicy()">{{'ACTIONS.SAVE' | translate}}</button>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
|
||||
<mat-expansion-panel class="expansion">
|
||||
@ -179,11 +209,12 @@
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div class="fonts">
|
||||
<div class="font-preview">
|
||||
<mat-icon>text_fields</mat-icon>
|
||||
<div class="font-preview mat-elevation-z3" *ngIf="preview == Preview.PREVIEW && previewData.fontUrl || preview == Preview.CURRENT && data.fontUrl">
|
||||
<mat-icon class="icon">text_fields</mat-icon>
|
||||
<span>ABC • abc • 123</span>
|
||||
<span>_</span>
|
||||
<span>Upload your favorite font for the UI</span>
|
||||
|
||||
<span class="fill-space"></span>
|
||||
<button matTooltip="{{'ACTIONS.REMOVE' | translate}}" mat-icon-button color="warn" (click)="deleteFont()"><mat-icon>remove_circle</mat-icon></button>
|
||||
</div>
|
||||
|
||||
<div class="dropzone" cnslDropzone (hovered)="toggleHoverFont($event)"
|
||||
@ -213,7 +244,7 @@
|
||||
|
||||
<ng-container
|
||||
*ngIf="serviceType == PolicyComponentServiceType.MGMT && (['label_policy.private_label'] | hasFeature | async) == false">
|
||||
<cnsl-info-section class="info" type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value:
|
||||
<cnsl-info-section class="info" type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value:
|
||||
'label_policy.private_label'})}}
|
||||
</cnsl-info-section>
|
||||
</ng-container>
|
||||
|
@ -83,7 +83,15 @@
|
||||
|
||||
.top-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.reset-button {
|
||||
align-self: flex-end;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.activate-button {
|
||||
border-radius: 50%;
|
||||
@ -180,7 +188,7 @@
|
||||
outline: none;
|
||||
height: 150px;
|
||||
width: 100%;
|
||||
border-radius: 16px;
|
||||
border-radius: .5rem;
|
||||
background: if($is-dark-theme, #2d2e30, #fff);
|
||||
border: 1px solid if($is-dark-theme, #4a4b4b, #ddd);
|
||||
display: flex;
|
||||
@ -257,11 +265,39 @@
|
||||
display: flex;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.prev,
|
||||
.curr {
|
||||
height: 50px;
|
||||
object-fit: contain;
|
||||
.img-wrapper {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
min-height: 80px;
|
||||
border: 1px solid if($is-dark-theme, #ffffff20, #00000020);
|
||||
border-radius: .5rem;
|
||||
max-width: 120px;
|
||||
|
||||
.dl-btn {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: -12px;
|
||||
cursor: pointer;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.prev,
|
||||
.curr {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
left: 0;
|
||||
max-height: 80px;
|
||||
max-width: 120px;
|
||||
object-fit: contain;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.dl-btn {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
@ -280,6 +316,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.clr-btn-wrapper {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.fonts {
|
||||
.title {
|
||||
display: block;
|
||||
@ -288,10 +330,19 @@
|
||||
|
||||
.font-preview {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 30px 50px;
|
||||
padding: .5rem;
|
||||
text-align: center;
|
||||
border-radius: .5rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.icon {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.fill-space {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.font-selector {
|
||||
@ -299,7 +350,6 @@
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -.25rem;
|
||||
width: 100%;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
.font {
|
||||
|
@ -17,9 +17,9 @@ import {
|
||||
} from 'src/app/proto/generated/zitadel/management_pb';
|
||||
import { LabelPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
|
||||
import { AdminService } from 'src/app/services/admin.service';
|
||||
import { AssetEndpoint, AssetService, AssetType } from 'src/app/services/asset.service';
|
||||
import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { DownloadEndpoint, UploadEndpoint, UploadService } from 'src/app/services/upload.service';
|
||||
|
||||
import { CnslLinks } from '../../links/links.component';
|
||||
import { IAM_COMPLEXITY_LINK, IAM_LOGIN_POLICY_LINK, IAM_POLICY_LINK } from '../../policy-grid/policy-links';
|
||||
@ -82,6 +82,7 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
|
||||
public Theme: any = Theme;
|
||||
public Preview: any = Preview;
|
||||
public ColorType: any = ColorType;
|
||||
public AssetType: any = AssetType;
|
||||
|
||||
public refreshPreview: EventEmitter<void> = new EventEmitter();
|
||||
public loadingImages: boolean = false;
|
||||
@ -90,7 +91,7 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
|
||||
private route: ActivatedRoute,
|
||||
private toast: ToastService,
|
||||
private injector: Injector,
|
||||
private uploadService: UploadService,
|
||||
private assetService: AssetService,
|
||||
private sanitizer: DomSanitizer,
|
||||
) {
|
||||
this.sub = this.route.data.pipe(switchMap(data => {
|
||||
@ -133,17 +134,17 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
|
||||
if (theme === Theme.DARK) {
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
return this.handleUploadPromise(this.uploadService.upload(UploadEndpoint.MGMTDARKLOGO, formData));
|
||||
return this.handleUploadPromise(this.assetService.upload(AssetEndpoint.MGMTDARKLOGO, formData));
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
return this.handleUploadPromise(this.uploadService.upload(UploadEndpoint.IAMDARKLOGO, formData));
|
||||
return this.handleUploadPromise(this.assetService.upload(AssetEndpoint.IAMDARKLOGO, formData));
|
||||
}
|
||||
}
|
||||
if (theme === Theme.LIGHT) {
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
return this.handleUploadPromise(this.uploadService.upload(UploadEndpoint.MGMTLIGHTLOGO, formData));
|
||||
return this.handleUploadPromise(this.assetService.upload(AssetEndpoint.MGMTLOGO, formData));
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
return this.handleUploadPromise(this.uploadService.upload(UploadEndpoint.IAMLIGHTLOGO, formData));
|
||||
return this.handleUploadPromise(this.assetService.upload(AssetEndpoint.IAMLOGO, formData));
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,13 +158,87 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
|
||||
formData.append('file', file);
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
return this.uploadService.upload(UploadEndpoint.MGMTFONT, formData);
|
||||
return this.handleFontUploadPromise(this.assetService.upload(AssetEndpoint.MGMTFONT, formData));
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
return this.uploadService.upload(UploadEndpoint.IAMFONT, formData);
|
||||
return this.handleFontUploadPromise(this.assetService.upload(AssetEndpoint.IAMFONT, formData));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public deleteFont(): Promise<any> {
|
||||
const handler = (prom: Promise<any>) => prom.then(() => {
|
||||
this.toast.showInfo('POLICY.TOAST.DELETESUCCESS', true);
|
||||
setTimeout(() => {
|
||||
this.loadingImages = true;
|
||||
this.getPreviewData().then(data => {
|
||||
|
||||
if (data.policy) {
|
||||
this.previewData = data.policy;
|
||||
this.loadPreviewImages();
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}).catch(error => this.toast.showError(error));
|
||||
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
return handler((this.service as ManagementService).removeLabelPolicyFont());
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
return handler((this.service as AdminService).removeLabelPolicyFont());
|
||||
}
|
||||
}
|
||||
|
||||
public deleteAsset(type: AssetType, theme: Theme): any {
|
||||
const previewHandler = (prom: Promise<any>) => {
|
||||
return prom.then(() => {
|
||||
this.toast.showInfo('POLICY.TOAST.DELETESUCCESS', true);
|
||||
setTimeout(() => {
|
||||
this.loadingImages = true;
|
||||
this.getPreviewData().then(data => {
|
||||
|
||||
if (data.policy) {
|
||||
this.previewData = data.policy;
|
||||
this.loadPreviewImages();
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}).catch(error => this.toast.showError(error));
|
||||
};
|
||||
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
if (type === AssetType.LOGO) {
|
||||
if (theme === Theme.DARK) {
|
||||
return previewHandler(this.service.removeLabelPolicyLogoDark());
|
||||
} else if (theme === Theme.LIGHT) {
|
||||
return previewHandler(this.service.removeLabelPolicyLogo());
|
||||
}
|
||||
} else if (type === AssetType.ICON) {
|
||||
if (theme === Theme.DARK) {
|
||||
return previewHandler(this.service.removeLabelPolicyIconDark());
|
||||
} else if (theme === Theme.LIGHT) {
|
||||
return previewHandler(this.service.removeLabelPolicyIcon());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
if (type === AssetType.LOGO) {
|
||||
if (theme === Theme.DARK) {
|
||||
return previewHandler(this.service.removeLabelPolicyLogoDark());
|
||||
} else if (theme === Theme.LIGHT) {
|
||||
return previewHandler(this.service.removeLabelPolicyLogo());
|
||||
}
|
||||
} else if (type === AssetType.ICON) {
|
||||
if (theme === Theme.DARK) {
|
||||
return previewHandler(this.service.removeLabelPolicyIconDark());
|
||||
} else if (theme === Theme.LIGHT) {
|
||||
return previewHandler(this.service.removeLabelPolicyIcon());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public toggleHoverIcon(theme: Theme, isHovering: boolean): void {
|
||||
if (theme === Theme.DARK) {
|
||||
this.isHoveringOverDarkIcon = isHovering;
|
||||
@ -182,26 +257,39 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
|
||||
if (theme === Theme.DARK) {
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
this.handleUploadPromise(this.uploadService.upload(UploadEndpoint.MGMTDARKICON, formData));
|
||||
this.handleUploadPromise(this.assetService.upload(AssetEndpoint.MGMTDARKICON, formData));
|
||||
break;
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
this.handleUploadPromise(this.uploadService.upload(UploadEndpoint.IAMDARKICON, formData));
|
||||
this.handleUploadPromise(this.assetService.upload(AssetEndpoint.IAMDARKICON, formData));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (theme === Theme.LIGHT) {
|
||||
switch (this.serviceType) {
|
||||
case PolicyComponentServiceType.MGMT:
|
||||
this.handleUploadPromise(this.uploadService.upload(UploadEndpoint.MGMTLIGHTICON, formData));
|
||||
this.handleUploadPromise(this.assetService.upload(AssetEndpoint.MGMTICON, formData));
|
||||
break;
|
||||
case PolicyComponentServiceType.ADMIN:
|
||||
this.handleUploadPromise(this.uploadService.upload(UploadEndpoint.IAMLIGHTICON, formData));
|
||||
this.handleUploadPromise(this.assetService.upload(AssetEndpoint.IAMICON, formData));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private handleFontUploadPromise(task: Promise<any>): Promise<any> {
|
||||
return task.then(() => {
|
||||
this.toast.showInfo('POLICY.TOAST.UPLOADSUCCESS', true);
|
||||
setTimeout(() => {
|
||||
this.getPreviewData().then(data => {
|
||||
if (data.policy) {
|
||||
this.previewData = data.policy;
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}).catch(error => this.toast.showError(error));
|
||||
}
|
||||
|
||||
private handleUploadPromise(task: Promise<any>): Promise<any> {
|
||||
return task.then(() => {
|
||||
this.toast.showInfo('POLICY.TOAST.UPLOADSUCCESS', true);
|
||||
@ -250,63 +338,86 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
|
||||
}
|
||||
|
||||
private loadImages(): void {
|
||||
const promises: Promise<any>[] = [];
|
||||
if (this.serviceType === PolicyComponentServiceType.ADMIN) {
|
||||
if (this.data.logoUrlDark) {
|
||||
this.loadAsset('darkLogo', DownloadEndpoint.IAMDARKLOGOPREVIEW);
|
||||
promises.push(this.loadAsset('darkLogo', AssetEndpoint.IAMDARKLOGO));
|
||||
}
|
||||
if (this.data.iconUrlDark) {
|
||||
this.loadAsset('darkIcon', DownloadEndpoint.IAMDARKICONPREVIEW);
|
||||
promises.push(this.loadAsset('darkIcon', AssetEndpoint.IAMDARKICON));
|
||||
}
|
||||
if (this.data.logoUrl) {
|
||||
this.loadAsset('logo', DownloadEndpoint.IAMLOGOPREVIEW);
|
||||
promises.push(this.loadAsset('logo', AssetEndpoint.IAMLOGO));
|
||||
}
|
||||
if (this.data.iconUrl) {
|
||||
this.loadAsset('icon', DownloadEndpoint.IAMICONPREVIEW);
|
||||
promises.push(this.loadAsset('icon', AssetEndpoint.IAMICON));
|
||||
}
|
||||
} else if (this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||
if (this.data.logoUrlDark) {
|
||||
this.loadAsset('darkLogo', DownloadEndpoint.MGMTDARKLOGOPREVIEW);
|
||||
promises.push(this.loadAsset('darkLogo', AssetEndpoint.MGMTDARKLOGO));
|
||||
}
|
||||
if (this.data.iconUrlDark) {
|
||||
this.loadAsset('darkIcon', DownloadEndpoint.MGMTDARKICONPREVIEW);
|
||||
promises.push(this.loadAsset('darkIcon', AssetEndpoint.MGMTDARKICON));
|
||||
}
|
||||
if (this.data.logoUrl) {
|
||||
this.loadAsset('logo', DownloadEndpoint.MGMTLOGOPREVIEW);
|
||||
promises.push(this.loadAsset('logo', AssetEndpoint.MGMTLOGO));
|
||||
}
|
||||
if (this.data.iconUrl) {
|
||||
this.loadAsset('icon', DownloadEndpoint.MGMTICONPREVIEW);
|
||||
promises.push(this.loadAsset('icon', AssetEndpoint.MGMTICON));
|
||||
}
|
||||
}
|
||||
|
||||
if (promises.length) {
|
||||
Promise.all(promises).then(() => {
|
||||
this.loadingImages = false;
|
||||
}).catch(error => {
|
||||
this.loadingImages = false;
|
||||
});
|
||||
} else {
|
||||
this.loadingImages = false;
|
||||
}
|
||||
}
|
||||
|
||||
private loadPreviewImages(): void {
|
||||
const promises: Promise<any>[] = [];
|
||||
|
||||
if (this.serviceType === PolicyComponentServiceType.ADMIN) {
|
||||
if (this.previewData.logoUrlDark) {
|
||||
this.loadAsset('previewDarkLogo', DownloadEndpoint.IAMDARKLOGOPREVIEW);
|
||||
promises.push(this.loadAsset('previewDarkLogo', AssetEndpoint.IAMDARKLOGOPREVIEW));
|
||||
}
|
||||
if (this.previewData.iconUrlDark) {
|
||||
this.loadAsset('previewDarkIcon', DownloadEndpoint.IAMDARKICONPREVIEW);
|
||||
promises.push(this.loadAsset('previewDarkIcon', AssetEndpoint.IAMDARKICONPREVIEW));
|
||||
}
|
||||
if (this.previewData.logoUrl) {
|
||||
this.loadAsset('previewLogo', DownloadEndpoint.IAMLOGOPREVIEW);
|
||||
promises.push(this.loadAsset('previewLogo', AssetEndpoint.IAMLOGOPREVIEW));
|
||||
}
|
||||
if (this.previewData.iconUrl) {
|
||||
this.loadAsset('previewIcon', DownloadEndpoint.IAMICONPREVIEW);
|
||||
promises.push(this.loadAsset('previewIcon', AssetEndpoint.IAMICONPREVIEW));
|
||||
}
|
||||
} else if (this.serviceType === PolicyComponentServiceType.MGMT) {
|
||||
if (this.previewData.logoUrlDark) {
|
||||
this.loadAsset('previewDarkLogo', DownloadEndpoint.MGMTDARKLOGOPREVIEW);
|
||||
promises.push(this.loadAsset('previewDarkLogo', AssetEndpoint.MGMTDARKLOGOPREVIEW));
|
||||
}
|
||||
if (this.previewData.iconUrlDark) {
|
||||
this.loadAsset('previewDarkIcon', DownloadEndpoint.MGMTDARKICONPREVIEW);
|
||||
promises.push(this.loadAsset('previewDarkIcon', AssetEndpoint.MGMTDARKICONPREVIEW));
|
||||
}
|
||||
if (this.previewData.logoUrl) {
|
||||
this.loadAsset('previewLogo', DownloadEndpoint.MGMTLOGOPREVIEW);
|
||||
promises.push(this.loadAsset('previewLogo', AssetEndpoint.MGMTLOGOPREVIEW));
|
||||
}
|
||||
if (this.previewData.iconUrl) {
|
||||
this.loadAsset('previewIcon', DownloadEndpoint.MGMTICONPREVIEW);
|
||||
promises.push(this.loadAsset('previewIcon', AssetEndpoint.MGMTICONPREVIEW));
|
||||
}
|
||||
}
|
||||
|
||||
if (promises.length) {
|
||||
Promise.all(promises).then(() => {
|
||||
this.loadingImages = false;
|
||||
}).catch(error => {
|
||||
this.loadingImages = false;
|
||||
});
|
||||
} else {
|
||||
this.loadingImages = false;
|
||||
}
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
@ -340,14 +451,12 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
|
||||
}
|
||||
|
||||
private loadAsset(imagekey: string, url: string): Promise<any> {
|
||||
return this.uploadService.load(`${url}`).then(data => {
|
||||
return this.assetService.load(`${url}`).then(data => {
|
||||
const objectURL = URL.createObjectURL(data);
|
||||
this.images[imagekey] = this.sanitizer.bypassSecurityTrustUrl(objectURL);
|
||||
this.refreshPreview.emit();
|
||||
this.loadingImages = false;
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
this.loadingImages = false;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
@ -8,6 +9,7 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ColorChromeModule } from 'ngx-color/chrome';
|
||||
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { HasFeaturePipeModule } from 'src/app/pipes/has-feature-pipe/has-feature-pipe.module';
|
||||
|
||||
@ -28,12 +30,14 @@ import { PrivateLabelingPolicyComponent } from './private-labeling-policy.compon
|
||||
ColorComponent,
|
||||
],
|
||||
imports: [
|
||||
ColorChromeModule,
|
||||
PrivateLabelingPolicyRoutingModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
InputModule,
|
||||
MatButtonModule,
|
||||
MatSlideToggleModule,
|
||||
OverlayModule,
|
||||
MatIconModule,
|
||||
HasRoleModule,
|
||||
MatTooltipModule,
|
||||
|
@ -12,143 +12,143 @@ import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
|
||||
|
||||
export enum ProjectAutocompleteType {
|
||||
PROJECT_OWNED = 0,
|
||||
PROJECT_GRANTED = 1,
|
||||
PROJECT_OWNED = 0,
|
||||
PROJECT_GRANTED = 1,
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-search-project-autocomplete',
|
||||
templateUrl: './search-project-autocomplete.component.html',
|
||||
styleUrls: ['./search-project-autocomplete.component.scss'],
|
||||
selector: 'app-search-project-autocomplete',
|
||||
templateUrl: './search-project-autocomplete.component.html',
|
||||
styleUrls: ['./search-project-autocomplete.component.scss'],
|
||||
})
|
||||
export class SearchProjectAutocompleteComponent implements OnDestroy {
|
||||
public selectable: boolean = true;
|
||||
public removable: boolean = true;
|
||||
public addOnBlur: boolean = true;
|
||||
public separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
public myControl: FormControl = new FormControl();
|
||||
public names: string[] = [];
|
||||
public projects: Array<GrantedProject.AsObject | Project.AsObject | any> = [];
|
||||
public filteredProjects: Array<GrantedProject.AsObject | Project.AsObject | any> = [];
|
||||
public isLoading: boolean = false;
|
||||
@ViewChild('nameInput') public nameInput!: ElementRef<HTMLInputElement>;
|
||||
@ViewChild('auto') public matAutocomplete!: MatAutocomplete;
|
||||
@Input() public singleOutput: boolean = false;
|
||||
@Input() public autocompleteType!: ProjectAutocompleteType;
|
||||
@Output() public selectionChanged: EventEmitter<
|
||||
GrantedProject.AsObject[]
|
||||
| GrantedProject.AsObject
|
||||
| Project.AsObject
|
||||
| Project.AsObject[]
|
||||
> = new EventEmitter();
|
||||
public selectable: boolean = true;
|
||||
public removable: boolean = true;
|
||||
public addOnBlur: boolean = true;
|
||||
public separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
public myControl: FormControl = new FormControl();
|
||||
public names: string[] = [];
|
||||
public projects: Array<GrantedProject.AsObject | Project.AsObject | any> = [];
|
||||
public filteredProjects: Array<GrantedProject.AsObject | Project.AsObject | any> = [];
|
||||
public isLoading: boolean = false;
|
||||
@ViewChild('nameInput') public nameInput!: ElementRef<HTMLInputElement>;
|
||||
@ViewChild('auto') public matAutocomplete!: MatAutocomplete;
|
||||
@Input() public singleOutput: boolean = false;
|
||||
@Input() public autocompleteType!: ProjectAutocompleteType;
|
||||
@Output() public selectionChanged: EventEmitter<
|
||||
GrantedProject.AsObject[]
|
||||
| GrantedProject.AsObject
|
||||
| Project.AsObject
|
||||
| Project.AsObject[]
|
||||
> = new EventEmitter();
|
||||
|
||||
private unsubscribed$: Subject<void> = new Subject();
|
||||
constructor(private mgmtService: ManagementService) {
|
||||
this.myControl.valueChanges
|
||||
.pipe(
|
||||
takeUntil(this.unsubscribed$),
|
||||
debounceTime(200),
|
||||
tap(() => this.isLoading = true),
|
||||
switchMap(value => {
|
||||
const query = new ProjectQuery();
|
||||
const nameQuery = new ProjectNameQuery();
|
||||
nameQuery.setName(value);
|
||||
nameQuery.setMethod(TextQueryMethod.TEXT_QUERY_METHOD_CONTAINS_IGNORE_CASE);
|
||||
query.setNameQuery(nameQuery);
|
||||
private unsubscribed$: Subject<void> = new Subject();
|
||||
constructor(private mgmtService: ManagementService) {
|
||||
this.myControl.valueChanges
|
||||
.pipe(
|
||||
takeUntil(this.unsubscribed$),
|
||||
debounceTime(200),
|
||||
tap(() => this.isLoading = true),
|
||||
switchMap(value => {
|
||||
const query = new ProjectQuery();
|
||||
const nameQuery = new ProjectNameQuery();
|
||||
nameQuery.setName(value);
|
||||
nameQuery.setMethod(TextQueryMethod.TEXT_QUERY_METHOD_CONTAINS_IGNORE_CASE);
|
||||
query.setNameQuery(nameQuery);
|
||||
|
||||
switch (this.autocompleteType) {
|
||||
case ProjectAutocompleteType.PROJECT_GRANTED:
|
||||
return from(this.mgmtService.listGrantedProjects(10, 0, [query]));
|
||||
case ProjectAutocompleteType.PROJECT_OWNED:
|
||||
return from(this.mgmtService.listProjects(10, 0, [query]));
|
||||
default:
|
||||
return forkJoin([
|
||||
from(this.mgmtService.listGrantedProjects(10, 0, [query])),
|
||||
from(this.mgmtService.listProjects(10, 0, [query])),
|
||||
]);
|
||||
}
|
||||
}),
|
||||
).subscribe((returnValue) => {
|
||||
switch (this.autocompleteType) {
|
||||
case ProjectAutocompleteType.PROJECT_GRANTED:
|
||||
this.isLoading = false;
|
||||
this.filteredProjects = [...(returnValue as ListProjectGrantsResponse.AsObject).resultList];
|
||||
break;
|
||||
case ProjectAutocompleteType.PROJECT_OWNED:
|
||||
this.isLoading = false;
|
||||
this.filteredProjects = [...(returnValue as ListProjectsResponse.AsObject).resultList];
|
||||
break;
|
||||
default:
|
||||
this.isLoading = false;
|
||||
this.filteredProjects = [
|
||||
...(returnValue as (ListProjectsResponse.AsObject | ListProjectGrantsResponse.AsObject)[])[0]
|
||||
.resultList,
|
||||
...(returnValue as (ListProjectsResponse.AsObject | ListProjectGrantsResponse.AsObject)[])[1]
|
||||
.resultList,
|
||||
];
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
this.unsubscribed$.next();
|
||||
}
|
||||
|
||||
public displayFn(project?: any): string | undefined {
|
||||
return (project && project.projectName) ? `${project.projectName}` :
|
||||
(project && project.name) ? `${project.name}` : undefined;
|
||||
}
|
||||
|
||||
public add(event: MatChipInputEvent): void {
|
||||
if (!this.matAutocomplete.isOpen) {
|
||||
const input = event.input;
|
||||
const value = event.value;
|
||||
|
||||
if ((value || '').trim()) {
|
||||
const index = this.filteredProjects.findIndex((project) => {
|
||||
if (project?.projectName) {
|
||||
return project.projectName === value;
|
||||
} else if (project?.name) {
|
||||
return project.name === value;
|
||||
}
|
||||
});
|
||||
if (index > -1) {
|
||||
if (this.projects && this.projects.length > 0) {
|
||||
this.projects.push(this.filteredProjects[index]);
|
||||
} else {
|
||||
this.projects = [this.filteredProjects[index]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
switch (this.autocompleteType) {
|
||||
case ProjectAutocompleteType.PROJECT_GRANTED:
|
||||
return from(this.mgmtService.listGrantedProjects(10, 0, [query]));
|
||||
case ProjectAutocompleteType.PROJECT_OWNED:
|
||||
return from(this.mgmtService.listProjects(10, 0, [query]));
|
||||
default:
|
||||
return forkJoin([
|
||||
from(this.mgmtService.listGrantedProjects(10, 0, [query])),
|
||||
from(this.mgmtService.listProjects(10, 0, [query])),
|
||||
]);
|
||||
}
|
||||
}),
|
||||
).subscribe((returnValue) => {
|
||||
switch (this.autocompleteType) {
|
||||
case ProjectAutocompleteType.PROJECT_GRANTED:
|
||||
this.isLoading = false;
|
||||
this.filteredProjects = [...(returnValue as ListProjectGrantsResponse.AsObject).resultList];
|
||||
break;
|
||||
case ProjectAutocompleteType.PROJECT_OWNED:
|
||||
this.isLoading = false;
|
||||
this.filteredProjects = [...(returnValue as ListProjectsResponse.AsObject).resultList];
|
||||
break;
|
||||
default:
|
||||
this.isLoading = false;
|
||||
this.filteredProjects = [
|
||||
...(returnValue as (ListProjectsResponse.AsObject | ListProjectGrantsResponse.AsObject)[])[0]
|
||||
.resultList,
|
||||
...(returnValue as (ListProjectsResponse.AsObject | ListProjectGrantsResponse.AsObject)[])[1]
|
||||
.resultList,
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public remove(project: GrantedProject.AsObject): void {
|
||||
const index = this.projects.indexOf(project);
|
||||
public ngOnDestroy(): void {
|
||||
this.unsubscribed$.next();
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
this.projects.splice(index, 1);
|
||||
public displayFn(project?: any): string | undefined {
|
||||
return (project && project.projectName) ? `${project.projectName}` :
|
||||
(project && project.name) ? `${project.name}` : undefined;
|
||||
}
|
||||
|
||||
public add(event: MatChipInputEvent): void {
|
||||
if (!this.matAutocomplete.isOpen) {
|
||||
const input = event.chipInput?.inputElement;
|
||||
const value = event.value;
|
||||
|
||||
if ((value || '').trim()) {
|
||||
const index = this.filteredProjects.findIndex((project) => {
|
||||
if (project?.projectName) {
|
||||
return project.projectName === value;
|
||||
} else if (project?.name) {
|
||||
return project.name === value;
|
||||
}
|
||||
});
|
||||
if (index > -1) {
|
||||
if (this.projects && this.projects.length > 0) {
|
||||
this.projects.push(this.filteredProjects[index]);
|
||||
} else {
|
||||
this.projects = [this.filteredProjects[index]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public selected(event: MatAutocompleteSelectedEvent): void {
|
||||
if (this.singleOutput) {
|
||||
this.selectionChanged.emit(event.option.value);
|
||||
} else {
|
||||
if (this.projects && this.projects.length > 0) {
|
||||
this.projects.push(event.option.value);
|
||||
} else {
|
||||
this.projects = [event.option.value];
|
||||
}
|
||||
this.selectionChanged.emit(this.projects);
|
||||
|
||||
this.nameInput.nativeElement.value = '';
|
||||
this.myControl.setValue(null);
|
||||
}
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public remove(project: GrantedProject.AsObject): void {
|
||||
const index = this.projects.indexOf(project);
|
||||
|
||||
if (index >= 0) {
|
||||
this.projects.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public selected(event: MatAutocompleteSelectedEvent): void {
|
||||
if (this.singleOutput) {
|
||||
this.selectionChanged.emit(event.option.value);
|
||||
} else {
|
||||
if (this.projects && this.projects.length > 0) {
|
||||
this.projects.push(event.option.value);
|
||||
} else {
|
||||
this.projects = [event.option.value];
|
||||
}
|
||||
this.selectionChanged.emit(this.projects);
|
||||
|
||||
this.nameInput.nativeElement.value = '';
|
||||
this.myControl.setValue(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,113 +10,113 @@ import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-search-roles-autocomplete',
|
||||
templateUrl: './search-roles-autocomplete.component.html',
|
||||
styleUrls: ['./search-roles-autocomplete.component.scss'],
|
||||
selector: 'app-search-roles-autocomplete',
|
||||
templateUrl: './search-roles-autocomplete.component.html',
|
||||
styleUrls: ['./search-roles-autocomplete.component.scss'],
|
||||
})
|
||||
export class SearchRolesAutocompleteComponent implements OnDestroy {
|
||||
public selectable: boolean = true;
|
||||
public removable: boolean = true;
|
||||
public addOnBlur: boolean = true;
|
||||
public separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
public myControl: FormControl = new FormControl();
|
||||
public names: string[] = [];
|
||||
public roles: Array<Role.AsObject> = [];
|
||||
public filteredRoles: Array<Role.AsObject> = [];
|
||||
public isLoading: boolean = false;
|
||||
@ViewChild('nameInput') public nameInput!: ElementRef<HTMLInputElement>;
|
||||
@ViewChild('auto') public matAutocomplete!: MatAutocomplete;
|
||||
@Input() public projectId: string = '';
|
||||
@Input() public singleOutput: boolean = false;
|
||||
@Output() public selectionChanged: EventEmitter<Role.AsObject[] | Role.AsObject> = new EventEmitter();
|
||||
public selectable: boolean = true;
|
||||
public removable: boolean = true;
|
||||
public addOnBlur: boolean = true;
|
||||
public separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
public myControl: FormControl = new FormControl();
|
||||
public names: string[] = [];
|
||||
public roles: Array<Role.AsObject> = [];
|
||||
public filteredRoles: Array<Role.AsObject> = [];
|
||||
public isLoading: boolean = false;
|
||||
@ViewChild('nameInput') public nameInput!: ElementRef<HTMLInputElement>;
|
||||
@ViewChild('auto') public matAutocomplete!: MatAutocomplete;
|
||||
@Input() public projectId: string = '';
|
||||
@Input() public singleOutput: boolean = false;
|
||||
@Output() public selectionChanged: EventEmitter<Role.AsObject[] | Role.AsObject> = new EventEmitter();
|
||||
|
||||
private unsubscribed$: Subject<void> = new Subject();
|
||||
constructor(private mgmtService: ManagementService) {
|
||||
this.myControl.valueChanges
|
||||
.pipe(
|
||||
takeUntil(this.unsubscribed$),
|
||||
debounceTime(200),
|
||||
tap(() => this.isLoading = true),
|
||||
switchMap(value => {
|
||||
const query = new RoleQuery();
|
||||
private unsubscribed$: Subject<void> = new Subject();
|
||||
constructor(private mgmtService: ManagementService) {
|
||||
this.myControl.valueChanges
|
||||
.pipe(
|
||||
takeUntil(this.unsubscribed$),
|
||||
debounceTime(200),
|
||||
tap(() => this.isLoading = true),
|
||||
switchMap(value => {
|
||||
const query = new RoleQuery();
|
||||
|
||||
// const key = new RoleKeyQuery();
|
||||
// key.setKey(key)
|
||||
// query.setKey(key)
|
||||
// const key = new RoleKeyQuery();
|
||||
// key.setKey(key)
|
||||
// query.setKey(key)
|
||||
|
||||
const dQuery = new RoleDisplayNameQuery();
|
||||
dQuery.setDisplayName(value);
|
||||
query.setDisplayNameQuery(dQuery);
|
||||
const dQuery = new RoleDisplayNameQuery();
|
||||
dQuery.setDisplayName(value);
|
||||
query.setDisplayNameQuery(dQuery);
|
||||
|
||||
return from(this.mgmtService.listProjectRoles(this.projectId, 10, 0, [query]));
|
||||
}),
|
||||
).subscribe((resp) => {
|
||||
this.isLoading = false;
|
||||
this.filteredRoles = resp.resultList;
|
||||
}, error => {
|
||||
this.isLoading = false;
|
||||
});
|
||||
}
|
||||
return from(this.mgmtService.listProjectRoles(this.projectId, 10, 0, [query]));
|
||||
}),
|
||||
).subscribe((resp) => {
|
||||
this.isLoading = false;
|
||||
this.filteredRoles = resp.resultList;
|
||||
}, error => {
|
||||
this.isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
this.unsubscribed$.next();
|
||||
}
|
||||
public ngOnDestroy(): void {
|
||||
this.unsubscribed$.next();
|
||||
}
|
||||
|
||||
public displayFn(project?: Role.AsObject): string | undefined {
|
||||
return project ? `${project.displayName}` : undefined;
|
||||
}
|
||||
public displayFn(project?: Role.AsObject): string | undefined {
|
||||
return project ? `${project.displayName}` : undefined;
|
||||
}
|
||||
|
||||
public add(event: MatChipInputEvent): void {
|
||||
if (!this.matAutocomplete.isOpen) {
|
||||
const input = event.input;
|
||||
const value = event.value;
|
||||
public add(event: MatChipInputEvent): void {
|
||||
if (!this.matAutocomplete.isOpen) {
|
||||
const input = event.chipInput?.inputElement;
|
||||
const value = event.value;
|
||||
|
||||
if ((value || '').trim()) {
|
||||
const index = this.filteredRoles.findIndex((role) => {
|
||||
if (role.key) {
|
||||
return role.key === value;
|
||||
}
|
||||
});
|
||||
if (index > -1) {
|
||||
if (this.roles && this.roles.length > 0) {
|
||||
this.roles.push(this.filteredRoles[index]);
|
||||
} else {
|
||||
this.roles = [this.filteredRoles[index]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
if ((value || '').trim()) {
|
||||
const index = this.filteredRoles.findIndex((role) => {
|
||||
if (role.key) {
|
||||
return role.key === value;
|
||||
}
|
||||
});
|
||||
if (index > -1) {
|
||||
if (this.roles && this.roles.length > 0) {
|
||||
this.roles.push(this.filteredRoles[index]);
|
||||
} else {
|
||||
this.roles = [this.filteredRoles[index]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public remove(role: Role.AsObject): void {
|
||||
const index = this.roles.indexOf(role);
|
||||
|
||||
if (index >= 0) {
|
||||
this.roles.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public selected(event: MatAutocompleteSelectedEvent): void {
|
||||
const index = this.filteredRoles.findIndex((role) => role.key === event.option.value);
|
||||
if (index !== -1) {
|
||||
if (this.singleOutput) {
|
||||
this.selectionChanged.emit(this.filteredRoles[index]);
|
||||
} else {
|
||||
if (this.roles && this.roles.length > 0) {
|
||||
this.roles.push(this.filteredRoles[index]);
|
||||
} else {
|
||||
this.roles = [this.filteredRoles[index]];
|
||||
}
|
||||
this.selectionChanged.emit(this.roles);
|
||||
|
||||
this.nameInput.nativeElement.value = '';
|
||||
this.myControl.setValue(null);
|
||||
}
|
||||
public remove(role: Role.AsObject): void {
|
||||
const index = this.roles.indexOf(role);
|
||||
|
||||
if (index >= 0) {
|
||||
this.roles.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public selected(event: MatAutocompleteSelectedEvent): void {
|
||||
const index = this.filteredRoles.findIndex((role) => role.key === event.option.value);
|
||||
if (index !== -1) {
|
||||
if (this.singleOutput) {
|
||||
this.selectionChanged.emit(this.filteredRoles[index]);
|
||||
} else {
|
||||
if (this.roles && this.roles.length > 0) {
|
||||
this.roles.push(this.filteredRoles[index]);
|
||||
} else {
|
||||
this.roles = [this.filteredRoles[index]];
|
||||
}
|
||||
this.selectionChanged.emit(this.roles);
|
||||
|
||||
this.nameInput.nativeElement.value = '';
|
||||
this.myControl.setValue(null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { COMMA, ENTER } from '@angular/cdk/keycodes';
|
||||
import {
|
||||
AfterContentChecked,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewChild,
|
||||
AfterContentChecked,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { MatAutocomplete, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
|
||||
@ -22,163 +22,163 @@ import { ManagementService } from 'src/app/services/mgmt.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
export enum UserTarget {
|
||||
SELF = 'self',
|
||||
EXTERNAL = 'external',
|
||||
SELF = 'self',
|
||||
EXTERNAL = 'external',
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-search-user-autocomplete',
|
||||
templateUrl: './search-user-autocomplete.component.html',
|
||||
styleUrls: ['./search-user-autocomplete.component.scss'],
|
||||
selector: 'app-search-user-autocomplete',
|
||||
templateUrl: './search-user-autocomplete.component.html',
|
||||
styleUrls: ['./search-user-autocomplete.component.scss'],
|
||||
})
|
||||
export class SearchUserAutocompleteComponent implements OnInit, AfterContentChecked {
|
||||
public selectable: boolean = true;
|
||||
public removable: boolean = true;
|
||||
public addOnBlur: boolean = true;
|
||||
public separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
public selectable: boolean = true;
|
||||
public removable: boolean = true;
|
||||
public addOnBlur: boolean = true;
|
||||
public separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
|
||||
public myControl: FormControl = new FormControl();
|
||||
public globalLoginNameControl: FormControl = new FormControl();
|
||||
public myControl: FormControl = new FormControl();
|
||||
public globalLoginNameControl: FormControl = new FormControl();
|
||||
|
||||
public loginNames: string[] = [];
|
||||
@Input() public users: Array<User.AsObject> = [];
|
||||
public filteredUsers: Array<User.AsObject> = [];
|
||||
public isLoading: boolean = false;
|
||||
@Input() public target: UserTarget = UserTarget.SELF;
|
||||
public hint: string = '';
|
||||
public UserTarget: any = UserTarget;
|
||||
@ViewChild('usernameInput') public usernameInput!: ElementRef<HTMLInputElement>;
|
||||
@ViewChild('auto') public matAutocomplete!: MatAutocomplete;
|
||||
@Output() public selectionChanged: EventEmitter<User.AsObject | User.AsObject[]> = new EventEmitter();
|
||||
@Input() public singleOutput: boolean = false;
|
||||
public loginNames: string[] = [];
|
||||
@Input() public users: Array<User.AsObject> = [];
|
||||
public filteredUsers: Array<User.AsObject> = [];
|
||||
public isLoading: boolean = false;
|
||||
@Input() public target: UserTarget = UserTarget.SELF;
|
||||
public hint: string = '';
|
||||
public UserTarget: any = UserTarget;
|
||||
@ViewChild('usernameInput') public usernameInput!: ElementRef<HTMLInputElement>;
|
||||
@ViewChild('auto') public matAutocomplete!: MatAutocomplete;
|
||||
@Output() public selectionChanged: EventEmitter<User.AsObject | User.AsObject[]> = new EventEmitter();
|
||||
@Input() public singleOutput: boolean = false;
|
||||
|
||||
private unsubscribed$: Subject<void> = new Subject();
|
||||
constructor(private userService: ManagementService, private toast: ToastService, private cdref: ChangeDetectorRef) { }
|
||||
private unsubscribed$: Subject<void> = new Subject();
|
||||
constructor(private userService: ManagementService, private toast: ToastService, private cdref: ChangeDetectorRef) { }
|
||||
|
||||
public ngOnInit(): void {
|
||||
if (this.target === UserTarget.EXTERNAL) {
|
||||
this.filteredUsers = [];
|
||||
this.unsubscribed$.next(); // clear old subscription
|
||||
} else if (this.target === UserTarget.SELF) {
|
||||
this.getFilteredResults(); // new subscription
|
||||
}
|
||||
public ngOnInit(): void {
|
||||
if (this.target === UserTarget.EXTERNAL) {
|
||||
this.filteredUsers = [];
|
||||
this.unsubscribed$.next(); // clear old subscription
|
||||
} else if (this.target === UserTarget.SELF) {
|
||||
this.getFilteredResults(); // new subscription
|
||||
}
|
||||
}
|
||||
|
||||
public ngAfterContentChecked(): void {
|
||||
this.cdref.detectChanges();
|
||||
}
|
||||
public ngAfterContentChecked(): void {
|
||||
this.cdref.detectChanges();
|
||||
}
|
||||
|
||||
private getFilteredResults(): void {
|
||||
this.myControl.valueChanges.pipe(debounceTime(200),
|
||||
takeUntil(this.unsubscribed$),
|
||||
tap(() => this.isLoading = true),
|
||||
switchMap(value => {
|
||||
const query = new SearchQuery();
|
||||
private getFilteredResults(): void {
|
||||
this.myControl.valueChanges.pipe(debounceTime(200),
|
||||
takeUntil(this.unsubscribed$),
|
||||
tap(() => this.isLoading = true),
|
||||
switchMap(value => {
|
||||
const query = new SearchQuery();
|
||||
|
||||
const unQuery = new UserNameQuery();
|
||||
unQuery.setMethod(TextQueryMethod.TEXT_QUERY_METHOD_CONTAINS_IGNORE_CASE);
|
||||
unQuery.setUserName(value);
|
||||
const unQuery = new UserNameQuery();
|
||||
unQuery.setMethod(TextQueryMethod.TEXT_QUERY_METHOD_CONTAINS_IGNORE_CASE);
|
||||
unQuery.setUserName(value);
|
||||
|
||||
query.setUserNameQuery(unQuery);
|
||||
query.setUserNameQuery(unQuery);
|
||||
|
||||
if (this.target === UserTarget.SELF) {
|
||||
return from(this.userService.listUsers(10, 0, [query]));
|
||||
} else {
|
||||
return of();
|
||||
}
|
||||
}),
|
||||
).subscribe((userresp: ListUsersResponse.AsObject | unknown) => {
|
||||
this.isLoading = false;
|
||||
if (this.target === UserTarget.SELF && userresp) {
|
||||
this.filteredUsers = (userresp as ListUsersResponse.AsObject).resultList;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public displayFn(user?: User.AsObject): string | undefined {
|
||||
return user ? `${user.preferredLoginName}` : undefined;
|
||||
}
|
||||
|
||||
public add(event: MatChipInputEvent): void {
|
||||
if (!this.matAutocomplete.isOpen) {
|
||||
const input = event.input;
|
||||
const value = event.value;
|
||||
|
||||
if ((value || '').trim()) {
|
||||
const index = this.filteredUsers.findIndex((user) => {
|
||||
if (user.preferredLoginName) {
|
||||
return user.preferredLoginName === value;
|
||||
}
|
||||
});
|
||||
if (index > -1) {
|
||||
if (this.users && this.users.length > 0) {
|
||||
this.users.push(this.filteredUsers[index]);
|
||||
} else {
|
||||
this.users = [this.filteredUsers[index]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public remove(user: User.AsObject): void {
|
||||
const index = this.users.indexOf(user);
|
||||
|
||||
if (index >= 0) {
|
||||
this.users.splice(index, 1);
|
||||
this.selectionChanged.emit(this.users);
|
||||
}
|
||||
}
|
||||
|
||||
public selected(event: MatAutocompleteSelectedEvent): void {
|
||||
const index = this.filteredUsers.findIndex((user) => user === event.option.value);
|
||||
if (index !== -1) {
|
||||
if (this.singleOutput) {
|
||||
this.selectionChanged.emit(this.filteredUsers[index]);
|
||||
} else {
|
||||
if (this.users && this.users.length > 0) {
|
||||
this.users.push(this.filteredUsers[index]);
|
||||
} else {
|
||||
this.users = [this.filteredUsers[index]];
|
||||
}
|
||||
|
||||
if (this.singleOutput) {
|
||||
this.selectionChanged.emit(this.users[0]);
|
||||
} else {
|
||||
this.selectionChanged.emit(this.users);
|
||||
}
|
||||
this.usernameInput.nativeElement.value = '';
|
||||
this.myControl.setValue(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public changeTarget(): void {
|
||||
if (this.target === UserTarget.SELF) {
|
||||
this.target = UserTarget.EXTERNAL;
|
||||
this.filteredUsers = [];
|
||||
this.unsubscribed$.next(); // clear old subscription
|
||||
} else if (this.target === UserTarget.EXTERNAL) {
|
||||
this.target = UserTarget.SELF;
|
||||
this.getFilteredResults(); // new subscription
|
||||
return from(this.userService.listUsers(10, 0, [query]));
|
||||
} else {
|
||||
return of();
|
||||
}
|
||||
}
|
||||
}),
|
||||
).subscribe((userresp: ListUsersResponse.AsObject | unknown) => {
|
||||
this.isLoading = false;
|
||||
if (this.target === UserTarget.SELF && userresp) {
|
||||
this.filteredUsers = (userresp as ListUsersResponse.AsObject).resultList;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public getGlobalUser(): void {
|
||||
this.userService.getUserByLoginNameGlobal(this.globalLoginNameControl.value).then(resp => {
|
||||
if (this.singleOutput && resp.user) {
|
||||
this.users = [resp.user];
|
||||
this.selectionChanged.emit(this.users[0]);
|
||||
} else if (resp.user) {
|
||||
this.users.push(resp.user);
|
||||
this.selectionChanged.emit(this.users);
|
||||
}
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
public displayFn(user?: User.AsObject): string | undefined {
|
||||
return user ? `${user.preferredLoginName}` : undefined;
|
||||
}
|
||||
|
||||
public add(event: MatChipInputEvent): void {
|
||||
if (!this.matAutocomplete.isOpen) {
|
||||
const input = event.chipInput?.inputElement;
|
||||
const value = event.value;
|
||||
|
||||
if ((value || '').trim()) {
|
||||
const index = this.filteredUsers.findIndex((user) => {
|
||||
if (user.preferredLoginName) {
|
||||
return user.preferredLoginName === value;
|
||||
}
|
||||
});
|
||||
if (index > -1) {
|
||||
if (this.users && this.users.length > 0) {
|
||||
this.users.push(this.filteredUsers[index]);
|
||||
} else {
|
||||
this.users = [this.filteredUsers[index]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public remove(user: User.AsObject): void {
|
||||
const index = this.users.indexOf(user);
|
||||
|
||||
if (index >= 0) {
|
||||
this.users.splice(index, 1);
|
||||
this.selectionChanged.emit(this.users);
|
||||
}
|
||||
}
|
||||
|
||||
public selected(event: MatAutocompleteSelectedEvent): void {
|
||||
const index = this.filteredUsers.findIndex((user) => user === event.option.value);
|
||||
if (index !== -1) {
|
||||
if (this.singleOutput) {
|
||||
this.selectionChanged.emit(this.filteredUsers[index]);
|
||||
} else {
|
||||
if (this.users && this.users.length > 0) {
|
||||
this.users.push(this.filteredUsers[index]);
|
||||
} else {
|
||||
this.users = [this.filteredUsers[index]];
|
||||
}
|
||||
|
||||
if (this.singleOutput) {
|
||||
this.selectionChanged.emit(this.users[0]);
|
||||
} else {
|
||||
this.selectionChanged.emit(this.users);
|
||||
}
|
||||
this.usernameInput.nativeElement.value = '';
|
||||
this.myControl.setValue(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public changeTarget(): void {
|
||||
if (this.target === UserTarget.SELF) {
|
||||
this.target = UserTarget.EXTERNAL;
|
||||
this.filteredUsers = [];
|
||||
this.unsubscribed$.next(); // clear old subscription
|
||||
} else if (this.target === UserTarget.EXTERNAL) {
|
||||
this.target = UserTarget.SELF;
|
||||
this.getFilteredResults(); // new subscription
|
||||
}
|
||||
}
|
||||
|
||||
public getGlobalUser(): void {
|
||||
this.userService.getUserByLoginNameGlobal(this.globalLoginNameControl.value).then(resp => {
|
||||
if (this.singleOutput && resp.user) {
|
||||
this.users = [resp.user];
|
||||
this.selectionChanged.emit(this.users[0]);
|
||||
} else if (resp.user) {
|
||||
this.users.push(resp.user);
|
||||
this.selectionChanged.emit(this.users);
|
||||
}
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { PolicyComponentServiceType } from '../modules/policies/policy-component-types.enum';
|
||||
import { Theme } from '../modules/policies/private-labeling-policy/private-labeling-policy.component';
|
||||
import { Org } from '../proto/generated/zitadel/org_pb';
|
||||
import { StorageService } from './storage.service';
|
||||
|
||||
@ -11,22 +13,12 @@ const orgKey = 'x-zitadel-orgid';
|
||||
const bearerPrefix = 'Bearer';
|
||||
const accessTokenStorageKey = 'access_token';
|
||||
|
||||
export enum UploadEndpoint {
|
||||
IAMFONT = 'iam/policy/label/font',
|
||||
MGMTFONT = 'org/policy/label/font',
|
||||
|
||||
IAMDARKLOGO = 'iam/policy/label/logo/dark',
|
||||
IAMLIGHTLOGO = 'iam/policy/label/logo',
|
||||
IAMDARKICON = 'iam/policy/label/icon/dark',
|
||||
IAMLIGHTICON = 'iam/policy/label/icon',
|
||||
|
||||
MGMTDARKLOGO = 'org/policy/label/logo/dark',
|
||||
MGMTLIGHTLOGO = 'org/policy/label/logo',
|
||||
MGMTDARKICON = 'org/policy/label/icon/dark',
|
||||
MGMTLIGHTICON = 'org/policy/label/icon',
|
||||
export enum AssetType {
|
||||
LOGO,
|
||||
ICON,
|
||||
}
|
||||
|
||||
export enum DownloadEndpoint {
|
||||
export enum AssetEndpoint {
|
||||
IAMFONT = 'iam/policy/label/font',
|
||||
MGMTFONT = 'org/policy/label/font',
|
||||
|
||||
@ -51,10 +43,33 @@ export enum DownloadEndpoint {
|
||||
MGMTICONPREVIEW = 'org/policy/label/icon/_preview',
|
||||
}
|
||||
|
||||
export const ENDPOINT = {
|
||||
[Theme.DARK]: {
|
||||
[PolicyComponentServiceType.ADMIN]: {
|
||||
[AssetType.LOGO]: AssetEndpoint.IAMDARKLOGO,
|
||||
[AssetType.ICON]: AssetEndpoint.IAMDARKICON,
|
||||
},
|
||||
[PolicyComponentServiceType.MGMT]: {
|
||||
[AssetType.LOGO]: AssetEndpoint.MGMTDARKLOGO,
|
||||
[AssetType.ICON]: AssetEndpoint.MGMTDARKICON,
|
||||
},
|
||||
},
|
||||
[Theme.LIGHT]: {
|
||||
[PolicyComponentServiceType.ADMIN]: {
|
||||
[AssetType.LOGO]: AssetEndpoint.IAMLOGO,
|
||||
[AssetType.ICON]: AssetEndpoint.IAMICON,
|
||||
},
|
||||
[PolicyComponentServiceType.MGMT]: {
|
||||
[AssetType.LOGO]: AssetEndpoint.MGMTLOGO,
|
||||
[AssetType.ICON]: AssetEndpoint.MGMTICON,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class UploadService {
|
||||
export class AssetService {
|
||||
private serviceUrl: string = '';
|
||||
private accessToken: string = '';
|
||||
private org!: Org.AsObject;
|
||||
@ -81,7 +96,7 @@ export class UploadService {
|
||||
});
|
||||
}
|
||||
|
||||
public upload(endpoint: UploadEndpoint, body: any): Promise<any> {
|
||||
public upload(endpoint: AssetEndpoint, body: any): Promise<any> {
|
||||
return this.http.post(`${this.serviceUrl}/assets/v1/${endpoint}`,
|
||||
body,
|
||||
{
|
||||
@ -103,4 +118,14 @@ export class UploadService {
|
||||
},
|
||||
}).toPromise();
|
||||
}
|
||||
|
||||
public delete(endpoint: AssetEndpoint): Promise<any> {
|
||||
return this.http.delete(`${this.serviceUrl}/assets/v1/${endpoint}`,
|
||||
{
|
||||
headers: {
|
||||
[authorizationKey]: `${bearerPrefix} ${this.accessToken}`,
|
||||
[orgKey]: `${this.org.id}`,
|
||||
},
|
||||
}).toPromise();
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@ import {
|
||||
RemoveLabelPolicyIconResponse,
|
||||
RemoveLabelPolicyLogoDarkRequest,
|
||||
RemoveLabelPolicyLogoDarkResponse,
|
||||
RemoveLabelPolicyLogoRequest,
|
||||
RemoveLabelPolicyLogoResponse,
|
||||
} from '../proto/generated/zitadel/admin_pb';
|
||||
import { AppQuery } from '../proto/generated/zitadel/app_pb';
|
||||
import { KeyType } from '../proto/generated/zitadel/auth_n_key_pb';
|
||||
@ -212,8 +214,6 @@ import {
|
||||
RemoveAppKeyResponse,
|
||||
RemoveAppRequest,
|
||||
RemoveAppResponse,
|
||||
RemoveCustomLabelPolicyLogoRequest,
|
||||
RemoveCustomLabelPolicyLogoResponse,
|
||||
RemoveHumanAuthFactorOTPRequest,
|
||||
RemoveHumanAuthFactorOTPResponse,
|
||||
RemoveHumanAuthFactorU2FRequest,
|
||||
@ -783,31 +783,31 @@ export class ManagementService {
|
||||
public removeLabelPolicyFont():
|
||||
Promise<RemoveLabelPolicyFontResponse.AsObject> {
|
||||
const req = new RemoveLabelPolicyFontRequest();
|
||||
return this.grpcService.admin.removeLabelPolicyFont(req, null).then(resp => resp.toObject());
|
||||
return this.grpcService.mgmt.removeCustomLabelPolicyFont(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public removeLabelPolicyIcon():
|
||||
Promise<RemoveLabelPolicyIconResponse.AsObject> {
|
||||
const req = new RemoveLabelPolicyIconRequest();
|
||||
return this.grpcService.admin.removeLabelPolicyIcon(req, null).then(resp => resp.toObject());
|
||||
return this.grpcService.mgmt.removeCustomLabelPolicyIcon(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public removeLabelPolicyIconDark():
|
||||
Promise<RemoveLabelPolicyIconDarkResponse.AsObject> {
|
||||
const req = new RemoveLabelPolicyIconDarkRequest();
|
||||
return this.grpcService.admin.removeLabelPolicyIconDark(req, null).then(resp => resp.toObject());
|
||||
return this.grpcService.mgmt.removeCustomLabelPolicyIconDark(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public removeCustomLabelPolicyLogo():
|
||||
Promise<RemoveCustomLabelPolicyLogoResponse.AsObject> {
|
||||
const req = new RemoveCustomLabelPolicyLogoRequest();
|
||||
public removeLabelPolicyLogo():
|
||||
Promise<RemoveLabelPolicyLogoResponse.AsObject> {
|
||||
const req = new RemoveLabelPolicyLogoRequest();
|
||||
return this.grpcService.mgmt.removeCustomLabelPolicyLogo(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public removeLabelPolicyLogoDark():
|
||||
Promise<RemoveLabelPolicyLogoDarkResponse.AsObject> {
|
||||
const req = new RemoveLabelPolicyLogoDarkRequest();
|
||||
return this.grpcService.admin.removeLabelPolicyLogoDark(req, null).then(resp => resp.toObject());
|
||||
return this.grpcService.mgmt.removeCustomLabelPolicyLogoDark(req, null).then(resp => resp.toObject());
|
||||
}
|
||||
|
||||
public getOrgIAMPolicy(): Promise<GetOrgIAMPolicyResponse.AsObject> {
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"authServiceUrl": "https://api.zitadel.io",
|
||||
"mgmtServiceUrl": "https://api.zitadel.io",
|
||||
"adminServiceUrl":"https://api.zitadel.io",
|
||||
"subscriptionServiceUrl":"https://sub.zitadel.io",
|
||||
"uploadServiceUrl":"https://api.zitadel.io",
|
||||
"issuer": "https://issuer.zitadel.io",
|
||||
"clientid": "69234247558357051@zitadel"
|
||||
"authServiceUrl": "https://api.zitadel.dev",
|
||||
"mgmtServiceUrl": "https://api.zitadel.dev",
|
||||
"adminServiceUrl":"https://api.zitadel.dev",
|
||||
"subscriptionServiceUrl":"https://sub.zitadel.dev",
|
||||
"uploadServiceUrl":"https://api.zitadel.dev",
|
||||
"issuer": "https://issuer.zitadel.dev",
|
||||
"clientid": "70669160379706195@zitadel"
|
||||
}
|
||||
|
@ -718,6 +718,7 @@
|
||||
"SET": "Richtline erfolgreich gesetzt!",
|
||||
"RESETSUCCESS": "Richtline zurückgesetzt!",
|
||||
"UPLOADSUCCESS": "Upload erfolgreich",
|
||||
"DELETESUCCESS": "Löschen erfolgreich",
|
||||
"UPLOADFAILED":"Upload fehlgeschlagen!"
|
||||
}
|
||||
},
|
||||
|
@ -720,6 +720,7 @@
|
||||
"SET": "Policy set successfully!",
|
||||
"RESETSUCCESS": "Policy reset successfully!",
|
||||
"UPLOADSUCCESS": "Uploaded successfully!",
|
||||
"DELETESUCCESS": "Deleted successfully!",
|
||||
"UPLOADFAILED":"Upload failed!"
|
||||
}
|
||||
},
|
||||
|
@ -14,7 +14,7 @@ $lgn-stroked-button-border-width: 1px;
|
||||
|
||||
$lgn-icon-button-size: 40px !default;
|
||||
$lgn-icon-button-border-radius: 50% !default;
|
||||
$lgn-icon-button-line-height: 24px !default;
|
||||
$lgn-icon-button-line-height: 40px !default;
|
||||
|
||||
// adds base styles to all button types.
|
||||
@mixin lgn-button-base {
|
||||
|
@ -100,7 +100,8 @@ $lgn-container-bottom-margin: 50px;
|
||||
.lgn-left-action {
|
||||
position: absolute;
|
||||
left: 1rem;
|
||||
top: -40px;
|
||||
top: -75px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.lgn-register-options {
|
||||
|
@ -30,8 +30,6 @@ footer {
|
||||
|
||||
.watermark {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.powered {
|
||||
font-size: 12px;
|
||||
@ -39,9 +37,9 @@ footer {
|
||||
}
|
||||
|
||||
.lgn-logo-watermark {
|
||||
height: 34px;
|
||||
width: 125px;
|
||||
margin: 2px;
|
||||
height: 40px;
|
||||
min-width: 125px;
|
||||
margin: auto 2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,8 @@
|
||||
}
|
||||
|
||||
.lgn-logo-watermark {
|
||||
background: var(--zitadel-logo-powered-by);
|
||||
background-position: auto;
|
||||
background: var(--zitadel-logo-powered-by) no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,22 @@
|
||||
$lgn-header-padding: 0;
|
||||
$lgn-header-margin: 1rem auto .5rem auto;
|
||||
$lgn-header-margin: auto;
|
||||
|
||||
.lgn-header {
|
||||
display: block;
|
||||
display: flex;
|
||||
position: relative;
|
||||
margin: $lgn-header-margin;
|
||||
padding: $lgn-header-padding;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
min-height: 150px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.lgn-logo {
|
||||
display: block;
|
||||
max-height: 100px;
|
||||
height: 100px;
|
||||
margin: 0 auto;
|
||||
max-width: 250px;
|
||||
max-height: 150px;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +91,7 @@
|
||||
--zitadel-color-raised-button-background: var(--zitadel-color-white);
|
||||
|
||||
|
||||
--zitadel-color-white: #ffffff;
|
||||
--zitadel-color-black: #000000;
|
||||
--zitadel-color-grey-50: #fafafa;
|
||||
--zitadel-color-grey-100: #f5f5f5;
|
||||
@ -109,8 +110,8 @@
|
||||
--zitadel-color-google-text: #8b8d8d;
|
||||
--zitadel-color-google-background: #ffffff;
|
||||
|
||||
--zitadel-color-qr: var(--zitadel-color-white);
|
||||
--zitadel-color-qr-background: var(--zitadel-color-black);
|
||||
--zitadel-color-qr: var(--zitadel-color-black);
|
||||
--zitadel-color-qr-background: var(--zitadel-color-white);
|
||||
}
|
||||
|
||||
.lgn-dark-theme {
|
||||
|
@ -77,6 +77,7 @@
|
||||
--zitadel-color-button-selected-background: var(--zitadel-color-grey-900);
|
||||
--zitadel-color-button-disabled-selected-background: var(--zitadel-color-grey-800);
|
||||
--zitadel-color-raised-button-background: var(--zitadel-color-white);
|
||||
--zitadel-color-white: #ffffff;
|
||||
--zitadel-color-black: #000000;
|
||||
--zitadel-color-grey-50: #fafafa;
|
||||
--zitadel-color-grey-100: #f5f5f5;
|
||||
@ -92,8 +93,8 @@
|
||||
--zitadel-logo-powered-by: url("../logo-dark.svg");
|
||||
--zitadel-color-google-text: #8b8d8d;
|
||||
--zitadel-color-google-background: #ffffff;
|
||||
--zitadel-color-qr: var(--zitadel-color-white);
|
||||
--zitadel-color-qr-background: var(--zitadel-color-black);
|
||||
--zitadel-color-qr: var(--zitadel-color-black);
|
||||
--zitadel-color-qr-background: var(--zitadel-color-white);
|
||||
}
|
||||
|
||||
.lgn-dark-theme {
|
||||
@ -221,30 +222,34 @@ footer a {
|
||||
}
|
||||
footer .watermark {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
footer .watermark .powered {
|
||||
font-size: 12px;
|
||||
margin: auto 2px;
|
||||
}
|
||||
footer .watermark .lgn-logo-watermark {
|
||||
height: 34px;
|
||||
width: 125px;
|
||||
margin: 2px;
|
||||
height: 40px;
|
||||
min-width: 125px;
|
||||
margin: auto 2px;
|
||||
}
|
||||
|
||||
.lgn-header {
|
||||
display: block;
|
||||
display: flex;
|
||||
position: relative;
|
||||
margin: 1rem auto 0.5rem auto;
|
||||
margin: auto;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
min-height: 150px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.lgn-header .lgn-logo {
|
||||
display: block;
|
||||
max-height: 100px;
|
||||
height: 100px;
|
||||
margin: 0 auto;
|
||||
max-width: 250px;
|
||||
max-height: 150px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.lgn-button, .lgn-stroked-button, .lgn-icon-button {
|
||||
@ -310,7 +315,7 @@ footer .watermark .lgn-logo-watermark {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.lgn-icon-button i, .lgn-icon-button .mat-icon {
|
||||
line-height: 24px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.lgn-stroked-button {
|
||||
@ -621,7 +626,8 @@ a.block {
|
||||
.content-container .lgn-left-action {
|
||||
position: absolute;
|
||||
left: 1rem;
|
||||
top: -40px;
|
||||
top: -75px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.content-container .lgn-register-options {
|
||||
display: flex;
|
||||
@ -1105,30 +1111,34 @@ footer a {
|
||||
}
|
||||
footer .watermark {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
footer .watermark .powered {
|
||||
font-size: 12px;
|
||||
margin: auto 2px;
|
||||
}
|
||||
footer .watermark .lgn-logo-watermark {
|
||||
height: 34px;
|
||||
width: 125px;
|
||||
margin: 2px;
|
||||
height: 40px;
|
||||
min-width: 125px;
|
||||
margin: auto 2px;
|
||||
}
|
||||
|
||||
.lgn-header {
|
||||
display: block;
|
||||
display: flex;
|
||||
position: relative;
|
||||
margin: 1rem auto 0.5rem auto;
|
||||
margin: auto;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
min-height: 150px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.lgn-header .lgn-logo {
|
||||
display: block;
|
||||
max-height: 100px;
|
||||
height: 100px;
|
||||
margin: 0 auto;
|
||||
max-width: 250px;
|
||||
max-height: 150px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.lgn-button, .lgn-stroked-button, .lgn-icon-button {
|
||||
@ -1194,7 +1204,7 @@ footer .watermark .lgn-logo-watermark {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.lgn-icon-button i, .lgn-icon-button .mat-icon {
|
||||
line-height: 24px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.lgn-stroked-button {
|
||||
@ -1505,7 +1515,8 @@ a.block {
|
||||
.content-container .lgn-left-action {
|
||||
position: absolute;
|
||||
left: 1rem;
|
||||
top: -40px;
|
||||
top: -75px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.content-container .lgn-register-options {
|
||||
display: flex;
|
||||
@ -2307,7 +2318,8 @@ i {
|
||||
.content-container .lgn-left-action {
|
||||
position: absolute;
|
||||
left: 1rem;
|
||||
top: -40px;
|
||||
top: -75px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.content-container .lgn-register-options {
|
||||
display: flex;
|
||||
@ -2342,16 +2354,22 @@ i {
|
||||
}
|
||||
|
||||
.lgn-header {
|
||||
display: block;
|
||||
display: flex;
|
||||
position: relative;
|
||||
margin: 1rem auto 0.5rem auto;
|
||||
margin: auto;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
min-height: 150px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.lgn-header .lgn-logo {
|
||||
display: block;
|
||||
max-height: 100px;
|
||||
height: 100px;
|
||||
margin: 0 auto;
|
||||
max-width: 250px;
|
||||
max-height: 150px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
@ -2705,8 +2723,8 @@ footer a {
|
||||
color: var(--zitadel-color-primary);
|
||||
}
|
||||
footer .lgn-logo-watermark {
|
||||
background: var(--zitadel-logo-powered-by);
|
||||
background-position: auto;
|
||||
background: var(--zitadel-logo-powered-by) no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user