feat(console): apply private labeling settings (#2059)

* fetch org design an calc palette

* distinct theme deriv

* calculate self theme

* background palette, fix styles

* component fixes, warn color

* warn color

* stylelint config, set warn color

* lint

* fallback theme

* lint

* granted, owned proejct grid

* dynamic privacy policy, fix home layout, dismissables, info-section

* lint

* apply theme from settings

* enable cache

* fix: add primary tint
This commit is contained in:
Max Peintner 2021-07-28 14:59:52 +02:00 committed by GitHub
parent fb06aed238
commit 7d3c768d8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 963 additions and 588 deletions

View File

@ -4,6 +4,7 @@
], ],
"extends": "stylelint-config-standard", "extends": "stylelint-config-standard",
"rules": { "rules": {
"value-keyword-case": null,
"at-rule-no-unknown": null, "at-rule-no-unknown": null,
"no-descending-specificity": null, "no-descending-specificity": null,
"at-rule-empty-line-before": [ "at-rule-empty-line-before": [

View File

@ -30,7 +30,9 @@
"styles": [ "styles": [
"src/styles.scss" "src/styles.scss"
], ],
"scripts": [], "scripts": [
"./node_modules/tinycolor2/dist/tinycolor-min.js"
],
"allowedCommonJsDependencies": [ "allowedCommonJsDependencies": [
"@angular/common/locales/de", "@angular/common/locales/de",
"src/app/proto/generated/**", "src/app/proto/generated/**",
@ -132,7 +134,9 @@
"./node_modules/@angular/material/prebuilt-themes/pink-bluegrey.css", "./node_modules/@angular/material/prebuilt-themes/pink-bluegrey.css",
"src/styles.scss" "src/styles.scss"
], ],
"scripts": [] "scripts": [
"./node_modules/tinycolor2/dist/tinycolor-min.js"
]
} }
}, },
"lint": { "lint": {

View File

@ -37,6 +37,7 @@
"ngx-color": "^7.2.0", "ngx-color": "^7.2.0",
"ngx-quicklink": "^0.2.6", "ngx-quicklink": "^0.2.6",
"rxjs": "~6.6.7", "rxjs": "~6.6.7",
"tinycolor2": "^1.4.2",
"ts-protoc-gen": "^0.14.0", "ts-protoc-gen": "^0.14.0",
"tslib": "^2.2.0", "tslib": "^2.2.0",
"uuid": "^8.3.2", "uuid": "^8.3.2",
@ -17359,6 +17360,14 @@
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
"dev": true "dev": true
}, },
"node_modules/tinycolor2": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz",
"integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==",
"engines": {
"node": "*"
}
},
"node_modules/tmp": { "node_modules/tmp": {
"version": "0.0.33", "version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@ -32825,6 +32834,11 @@
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
"dev": true "dev": true
}, },
"tinycolor2": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz",
"integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA=="
},
"tmp": { "tmp": {
"version": "0.0.33", "version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",

View File

@ -38,8 +38,10 @@
"libphonenumber-js": "^1.9.16", "libphonenumber-js": "^1.9.16",
"moment": "^2.29.1", "moment": "^2.29.1",
"ngx-color": "^7.2.0", "ngx-color": "^7.2.0",
"ngx-image-cropper": "^3.3.5",
"ngx-quicklink": "^0.2.6", "ngx-quicklink": "^0.2.6",
"rxjs": "~6.6.7", "rxjs": "~6.6.7",
"tinycolor2": "^1.4.2",
"ts-protoc-gen": "^0.14.0", "ts-protoc-gen": "^0.14.0",
"tslib": "^2.2.0", "tslib": "^2.2.0",
"uuid": "^8.3.2", "uuid": "^8.3.2",

View File

@ -5,6 +5,7 @@
(click)="drawer.toggle()"> (click)="drawer.toggle()">
<i class="icon las la-bars"></i> <i class="icon las la-bars"></i>
</button> </button>
<ng-container *ngIf="labelpolicy && !labelpolicy?.disableWatermark">
<a class="title" [routerLink]="['/']"> <a class="title" [routerLink]="['/']">
<img class="logo" alt="zitadel logo" *ngIf="componentCssClass == 'dark-theme'; else lighttheme" <img class="logo" alt="zitadel logo" *ngIf="componentCssClass == 'dark-theme'; else lighttheme"
src="../assets/images/zitadel-logo-solo-light.svg" /> src="../assets/images/zitadel-logo-solo-light.svg" />
@ -17,6 +18,7 @@
stroke-linecap="round" stroke-linejoin="round" fill="none" shape-rendering="geometricPrecision"> stroke-linecap="round" stroke-linejoin="round" fill="none" shape-rendering="geometricPrecision">
<path d="M16.88 3.549L7.12 20.451"></path> <path d="M16.88 3.549L7.12 20.451"></path>
</svg> </svg>
</ng-container>
<button class="org-button" (click)="loadOrgs()" *ngIf="user && org" mat-button [matMenuTriggerFor]="menu" <button class="org-button" (click)="loadOrgs()" *ngIf="user && org" mat-button [matMenuTriggerFor]="menu"
(menuOpened)="focusFilter()">{{org?.name ? org.name : 'NO NAME'}} (menuOpened)="focusFilter()">{{org?.name ? org.name : 'NO NAME'}}
@ -102,7 +104,7 @@
<ng-template appHasRole [appHasRole]="['org.read']"> <ng-template appHasRole [appHasRole]="['org.read']">
<a @navitem matTooltip="{{'MENU.TOOLTIP.ORG' | translate}}" class="nav-item" <a @navitem matTooltip="{{'MENU.TOOLTIP.ORG' | translate}}" class="nav-item"
[routerLinkActive]="['active']" [routerLink]="[ '/org']"> [routerLinkActive]="['active']" [routerLink]="[ '/org']">
<i class="icon las la-archway"></i> <i class="icon las la-cog"></i>
<span class="label">{{'MENU.ORGANIZATION' | translate}}</span> <span class="label">{{'MENU.ORGANIZATION' | translate}}</span>
</a> </a>
</ng-template> </ng-template>
@ -165,25 +167,25 @@
</div> </div>
<a @navitem matTooltip="{{'MENU.TOOLTIP.IAMPOLICIES' | translate}}" class="nav-item" <a @navitem matTooltip="{{'MENU.TOOLTIP.IAMPOLICIES' | translate}}" class="nav-item"
[routerLinkActive]="['active']" [routerLink]="[ '/iam','policies']"> [routerLinkActive]="['active']" [routerLink]="[ '/iam','policies']">
<i class="icon las la-gem"></i> <i class="icon las la-cog"></i>
<span class="label">{{'MENU.IAMPOLICIES' | translate}}</span> <span class="label">{{'MENU.IAMPOLICIES' | translate}}</span>
</a> </a>
<a @navitem matTooltip="{{'MENU.TOOLTIP.IAMEVENTSTORE' | translate}}" class="nav-item" <a @navitem matTooltip="{{'MENU.TOOLTIP.IAMEVENTSTORE' | translate}}" class="nav-item"
[routerLinkActive]="['active']" [routerLink]="[ '/iam', 'eventstore']"> [routerLinkActive]="['active']" [routerLink]="[ '/iam', 'eventstore']">
<i class="icon las la-gem"></i> <i class="icon las la-database"></i>
<span class="label">{{'MENU.IAMEVENTSTORE' | translate}}</span> <span class="label">{{'MENU.IAMEVENTSTORE' | translate}}</span>
</a> </a>
</ng-container> </ng-container>
<span class="fill-space"></span> <span class="fill-space"></span>
<div class="toc-line"> <div class="toc-line" *ngIf="privacyPolicy">
<a class="toc" [href]="'https://docs.zitadel.ch/docs/legal/terms-of-service'" alt="Terms and Conditions" <a class="toc" [href]="privacyPolicy.tosLink" alt="Terms and Conditions"
target="_blank">{{'MENU.TOS' target="_blank">{{'MENU.TOS'
| translate}}</a> | translate}}</a>
<span class="slash">|</span> <span class="slash">|</span>
<a class="toc" [href]="'https://docs.zitadel.ch/docs/legal/privacy-policy'" alt="Privacy Policy " <a class="toc" [href]="privacyPolicy.privacyLink" alt="Privacy Policy "
target="_blank">{{'MENU.PRIVACY' target="_blank">{{'MENU.PRIVACY'
| translate}}</a> | translate}}</a>
<span>&nbsp;&nbsp;&nbsp;</span> <span>&nbsp;&nbsp;&nbsp;</span>

View File

@ -14,6 +14,7 @@ import { catchError, debounceTime, finalize, map, take } from 'rxjs/operators';
import { accountCard, adminLineAnimation, navAnimations, routeAnimations, toolbarAnimation } from './animations'; import { accountCard, adminLineAnimation, navAnimations, routeAnimations, toolbarAnimation } from './animations';
import { TextQueryMethod } from './proto/generated/zitadel/object_pb'; import { TextQueryMethod } from './proto/generated/zitadel/object_pb';
import { Org, OrgNameQuery, OrgQuery } from './proto/generated/zitadel/org_pb'; import { Org, OrgNameQuery, OrgQuery } from './proto/generated/zitadel/org_pb';
import { LabelPolicy, PrivacyPolicy } from './proto/generated/zitadel/policy_pb';
import { User } from './proto/generated/zitadel/user_pb'; import { User } from './proto/generated/zitadel/user_pb';
import { AuthenticationService } from './services/authentication.service'; import { AuthenticationService } from './services/authentication.service';
import { GrpcAuthService } from './services/grpc-auth.service'; import { GrpcAuthService } from './services/grpc-auth.service';
@ -56,9 +57,11 @@ export class AppComponent implements OnDestroy {
public filterControl: FormControl = new FormControl(''); public filterControl: FormControl = new FormControl('');
private authSub: Subscription = new Subscription(); private authSub: Subscription = new Subscription();
private orgSub: Subscription = new Subscription(); private orgSub: Subscription = new Subscription();
public labelpolicy!: LabelPolicy.AsObject;
public hideAdminWarn: boolean = true; public hideAdminWarn: boolean = true;
public language: string = 'en'; public language: string = 'en';
public privacyPolicy!: PrivacyPolicy.AsObject;
constructor( constructor(
public viewPortScroller: ViewportScroller, public viewPortScroller: ViewportScroller,
@Inject('windowObject') public window: Window, @Inject('windowObject') public window: Window,
@ -171,6 +174,8 @@ export class AppComponent implements OnDestroy {
this.domSanitizer.bypassSecurityTrustResourceUrl('assets/mdi/api.svg'), this.domSanitizer.bypassSecurityTrustResourceUrl('assets/mdi/api.svg'),
); );
this.loadPrivateLabelling();
this.getProjectCount(); this.getProjectCount();
this.orgSub = this.authService.activeOrgChanged.subscribe(org => { this.orgSub = this.authService.activeOrgChanged.subscribe(org => {
@ -193,7 +198,7 @@ export class AppComponent implements OnDestroy {
} }
this.isDarkTheme = this.themeService.isDarkTheme; this.isDarkTheme = this.themeService.isDarkTheme;
this.isDarkTheme.subscribe(thema => this.onSetTheme(thema ? 'dark-theme' : 'light-theme')); this.isDarkTheme.subscribe(dark => this.onSetTheme(dark ? 'dark-theme' : 'light-theme'));
this.translate.onLangChange.subscribe((language: LangChangeEvent) => { this.translate.onLangChange.subscribe((language: LangChangeEvent) => {
this.document.documentElement.lang = language.lang; this.document.documentElement.lang = language.lang;
@ -207,6 +212,8 @@ export class AppComponent implements OnDestroy {
}); });
this.hideAdminWarn = localStorage.getItem('hideAdministratorWarning') === 'true' ? true : false; this.hideAdminWarn = localStorage.getItem('hideAdministratorWarning') === 'true' ? true : false;
this.loadPolicies();
} }
public ngOnDestroy(): void { public ngOnDestroy(): void {
@ -219,6 +226,63 @@ export class AppComponent implements OnDestroy {
localStorage.setItem('hideAdministratorWarning', this.hideAdminWarn.toString()); localStorage.setItem('hideAdministratorWarning', this.hideAdminWarn.toString());
} }
public loadPrivateLabelling(): void {
const setDefaultColors = () => {
const darkPrimary = '#5282c1';
const lightPrimary = '#5282c1';
const darkWarn = '#F44336';
const lightWarn = '#F44336';
const darkBackground = '#212224';
const lightBackground = '#fafafa';
this.themeService.savePrimaryColor(darkPrimary, true);
this.themeService.savePrimaryColor(lightPrimary, false);
this.themeService.saveWarnColor(darkWarn, true);
this.themeService.saveWarnColor(lightWarn, false);
this.themeService.saveBackgroundColor(darkBackground, true);
this.themeService.saveBackgroundColor(lightBackground, false);
};
setDefaultColors();
this.mgmtService.getLabelPolicy().then(labelpolicy => {
if (labelpolicy.policy) {
this.labelpolicy = labelpolicy.policy;
const darkPrimary = this.labelpolicy?.primaryColorDark || '#5282c1';
const lightPrimary = this.labelpolicy?.primaryColor || '#5282c1';
const darkWarn = this.labelpolicy?.warnColorDark || '#F44336';
const lightWarn = this.labelpolicy?.warnColor || '#F44336';
const darkBackground = this.labelpolicy?.backgroundColorDark || '#212224';
const lightBackground = this.labelpolicy?.backgroundColor || '#fafafa';
this.themeService.savePrimaryColor(darkPrimary, true);
this.themeService.savePrimaryColor(lightPrimary, false);
this.themeService.saveWarnColor(darkWarn, true);
this.themeService.saveWarnColor(lightWarn, false);
this.themeService.saveBackgroundColor(darkBackground, true);
this.themeService.saveBackgroundColor(lightBackground, false);
}
});
}
public loadPolicies(): void {
this.mgmtService.getPrivacyPolicy().then(privacypolicy => {
if (privacypolicy.policy) {
this.privacyPolicy = privacypolicy.policy;
}
});
}
public loadOrgs(filter?: string): void { public loadOrgs(filter?: string): void {
let query; let query;
if (filter) { if (filter) {
@ -282,6 +346,7 @@ export class AppComponent implements OnDestroy {
public setActiveOrg(org: Org.AsObject): void { public setActiveOrg(org: Org.AsObject): void {
this.org = org; this.org = org;
this.authService.setActiveOrg(org); this.authService.setActiveOrg(org);
this.loadPrivateLabelling();
this.authService.zitadelPermissionsChanged.pipe(take(1)).subscribe(() => { this.authService.zitadelPermissionsChanged.pipe(take(1)).subscribe(() => {
this.router.navigate(['/']); this.router.navigate(['/']);
}); });

View File

@ -3,10 +3,12 @@
@mixin app-card-theme($theme) { @mixin app-card-theme($theme) {
/* stylelint-disable */ /* stylelint-disable */
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$primary-dark: mat.get-color-from-palette($primary, A900); $background: map-get($theme, background);
$accent: map-get($theme, accent); $accent: map-get($theme, accent);
$is-dark-theme: map-get($theme, is-dark); $is-dark-theme: map-get($theme, is-dark);
$accent-color: mat.get-color-from-palette($primary, 500); $accent-color: mat.get-color-from-palette($primary, 500);
$back: map-get($background, background);
/* stylelint-enable */ /* stylelint-enable */
.cnsl-app-card { .cnsl-app-card {
@ -25,7 +27,7 @@
text-transform: uppercase; text-transform: uppercase;
border-radius: .5rem; border-radius: .5rem;
font-weight: 800; font-weight: 800;
background-color: $primary-dark; background-color: $back;
transition: background-color box-shadow .3s ease-in; transition: background-color box-shadow .3s ease-in;
&.web { &.web {

View File

@ -93,7 +93,7 @@
span { span {
margin: 2rem; margin: 2rem;
font-size: 30px; font-size: 30px;
color: if($is-dark-theme, #21222450, #ffffff50); color: if($is-dark-theme, #00000050, #ffffff50);
} }
} }

View File

@ -50,7 +50,7 @@
span { span {
margin: 2rem; margin: 2rem;
font-size: 30px; font-size: 30px;
color: if($is-dark-theme, #21222450, #ffffff50); color: if($is-dark-theme, #00000050, #ffffff50);
} }
} }

View File

@ -1,4 +1,4 @@
<div class="card"> <div class="card" [ngClass]="{'nomargin': nomargin}">
<div *ngIf="title || description" class="header" [ngClass]="{'bottom-margin': expanded}"> <div *ngIf="title || description" class="header" [ngClass]="{'bottom-margin': expanded}">
<div *ngIf="title" class="row"> <div *ngIf="title" class="row">
<h2 class="title">{{title}}</h2> <h2 class="title">{{title}}</h2>

View File

@ -1,4 +1,3 @@
.card { .card {
margin: 1rem 0; margin: 1rem 0;
padding: 1.5rem; padding: 1.5rem;
@ -6,6 +5,10 @@
padding-top: 1rem; padding-top: 1rem;
min-width: 300px; min-width: 300px;
&.nomargin {
margin: 0;
}
.header { .header {
margin-top: 0; margin-top: 0;

View File

@ -22,4 +22,5 @@ export class CardComponent {
@Input() public title: string = ''; @Input() public title: string = '';
@Input() public description: string = ''; @Input() public description: string = '';
@Input() public animate: boolean = false; @Input() public animate: boolean = false;
@Input() public nomargin?: boolean = false;
} }

View File

@ -1,18 +1,20 @@
@use '~@angular/material' as mat; @use '~@angular/material' as mat;
@mixin card-theme($theme) { @mixin card-theme($theme) {
/* stylelint-disable */ /* stylelint-disable */
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$primary-color: mat.get-color-from-palette($primary, 500); $primary-color: mat.get-color-from-palette($primary, 500);
$primary-dark: mat.get-color-from-palette($primary, A800); $background: map-get($theme, background);
$border-color: mat.get-color-from-palette($primary, A700); $card-background-color: mat.get-color-from-palette($background, card);
$border-selected-color: mat.get-color-from-palette($primary, A600); $is-dark-theme: map-get($theme, is-dark);
/* stylelint-enable */ $border-color: if($is-dark-theme, rgba(#8795a1, .2), rgba(#8795a1, .2));
$border-selected-color: if($is-dark-theme, #ffffff, #000000);
/* stylelint-enable */
.card { .card {
background-color: $primary-dark; background-color: $card-background-color;
transition: background-color .3s cubic-bezier(.645, .045, .355, 1); transition: background-color .3s cubic-bezier(.645, .045, .355, 1);
border: 1px solid rgba($border-color, .2); border: 1px solid $border-color;
box-sizing: border-box; box-sizing: border-box;
border-radius: .5rem; border-radius: .5rem;
outline: none; outline: none;

View File

@ -22,11 +22,12 @@
@mixin changes-theme($theme) { @mixin changes-theme($theme) {
$is-dark-theme: map-get($theme, is-dark); $is-dark-theme: map-get($theme, is-dark);
$foreground: map-get($theme, foreground);
.scroll-container { .scroll-container {
max-height: 50vh; max-height: 50vh;
overflow-y: scroll; overflow-y: scroll;
border-bottom: 1px solid if($is-dark-theme, #303131, #e3e8ee); border-bottom: 1px solid map-get($foreground, divider);
margin-bottom: .5rem; margin-bottom: .5rem;
.date { .date {
@ -114,11 +115,13 @@
/* stylelint-disable */ /* stylelint-disable */
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$primary-dark: mat.get-color-from-palette($primary, A800); $is-dark-theme: map-get($theme, is-dark);
$transparent-color: if($is-dark-theme, rgba(#8795a1, .2), rgba(#8795a1, .2));
/* stylelint-enable */ /* stylelint-enable */
&.change-item-back { &.change-item-back {
background-color: rgba($primary-dark, .93); background-color: rgba($transparent-color, .93);
transition: background-color .3s cubic-bezier(.645, .045, .355, 1); transition: background-color .3s cubic-bezier(.645, .045, .355, 1);
} }
} }

View File

@ -4,7 +4,7 @@
/* stylelint-disable */ /* stylelint-disable */
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$primary-color: mat.get-color-from-palette($primary, 500); $primary-color: mat.get-color-from-palette($primary, 500);
$primary-dark: mat.get-color-from-palette($primary, A800); $is-dark-theme: map-get($theme, is-dark);
/* stylelint-enable */ /* stylelint-enable */
$lighter-color: rgba(mat.get-color-from-palette($primary, 300), .5); $lighter-color: rgba(mat.get-color-from-palette($primary, 300), .5);

View File

@ -35,7 +35,7 @@
<p class="error" *ngIf="(stripeCustomer || stripeCustomer == null) && !customerValid">{{'FEATURES.TIER.CUSTOMERINVALID' | translate}}</p> <p class="error" *ngIf="(stripeCustomer || stripeCustomer == null) && !customerValid">{{'FEATURES.TIER.CUSTOMERINVALID' | translate}}</p>
<div class="current-tier"> <div class="current-tier">
<a [disabled]="!org.id || !customerValid || !stripeURL" mat-raised-button [href]="stripeURL" target="_blank" <a color="primary" [disabled]="!org.id || !customerValid || !stripeURL" mat-raised-button [href]="stripeURL" target="_blank"
alt="change tier">{{'FEATURES.TIER.BTN' | translate}}</a> alt="change tier">{{'FEATURES.TIER.BTN' | translate}}</a>
</div> </div>
</ng-container> </ng-container>

View File

@ -2,6 +2,8 @@
@mixin info-section-theme($theme) { @mixin info-section-theme($theme) {
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$background: map-get($theme, background);
$foreground: map-get($theme, foreground);
$primary-color: mat.get-color-from-palette($primary, 500); $primary-color: mat.get-color-from-palette($primary, 500);
$is-dark-theme: map-get($theme, is-dark); $is-dark-theme: map-get($theme, is-dark);
@ -25,29 +27,29 @@
} }
&.info { &.info {
background-color: if($is-dark-theme, #6d6f7382, #e4e4e4); background-color: map-get($background, infosection);
color: if($is-dark-theme, #f0f0f0, #4a4a4a); color: map-get($foreground, infosection);
.icon { .icon {
color: $primary-color; color: map-get($foreground, infosection);
} }
} }
&.success { &.success {
background-color: if($is-dark-theme, #4f566b, #cbf4c9); background-color: map-get($background, successinfosection);
color: if($is-dark-theme, #cbf4c9, #0e6245); color: map-get($foreground, successinfosection);
.icon { .icon {
color: $primary-color; color: map-get($foreground, successinfosection);
} }
} }
&.warn { &.warn {
background-color: if($is-dark-theme, #4f566b, #ffc1c1); background-color: map-get($background, warninfosection);
color: if($is-dark-theme, #ffc1c1, #620e0e); color: map-get($foreground, warninfosection);
.icon { .icon {
color: if($is-dark-theme, #ffc1c1, #620e0e); color: map-get($foreground, warninfosection);
} }
} }
} }

View File

@ -5,10 +5,12 @@
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$primary-color: mat.get-color-from-palette($primary, 500); $primary-color: mat.get-color-from-palette($primary, 500);
$is-dark-theme: map-get($theme, is-dark); $is-dark-theme: map-get($theme, is-dark);
$foreground: map-get($theme, foreground);
/* stylelint-enable */ /* stylelint-enable */
.onboarding-row { .onboarding-row {
box-shadow: inset 0 -1px if($is-dark-theme, #303131, #e3e8ee); box-shadow: inset 0 -1px map-get($foreground, divider);
.prev { .prev {
background: $primary-color; background: $primary-color;
@ -17,7 +19,7 @@
.goto { .goto {
text-decoration: none; text-decoration: none;
background: white; background: white;
border: 1px solid if($is-dark-theme, #303131, #e3e8ee); border: 1px solid map-get($foreground, divider);
&.docs { &.docs {
background-color: $primary-color; background-color: $primary-color;

View File

@ -8,14 +8,14 @@
</div> </div>
<ng-container *ngIf="serviceType === PolicyComponentServiceType.MGMT"> <ng-container *ngIf="serviceType === PolicyComponentServiceType.MGMT">
<ng-template appHasRole [appHasRole]="['policy.delete']"> <ng-template appHasRole [appHasRole]="['policy.delete']">
<button *ngIf="!isDefault" matTooltip="{{'POLICY.RESET' | translate}}" color="warn" (click)="removePolicy()" <button *ngIf="!isDefault" color="primary" matTooltip="{{'POLICY.RESET' | translate}}" color="warn" (click)="removePolicy()"
mat-stroked-button> mat-stroked-button>
{{'POLICY.RESET' | translate}} {{'POLICY.RESET' | translate}}
</button> </button>
</ng-template> </ng-template>
<ng-template appHasRole [appHasRole]="['policy.write']"> <ng-template appHasRole [appHasRole]="['policy.write']">
<button *ngIf="isDefault" matTooltip="{{'POLICY.CREATECUSTOM' | translate}}" (click)="savePolicy()" <button *ngIf="isDefault" color="primary" matTooltip="{{'POLICY.CREATECUSTOM' | translate}}" (click)="savePolicy()"
mat-raised-button> mat-raised-button>
{{'POLICY.CREATECUSTOM' | translate}} {{'POLICY.CREATECUSTOM' | translate}}
</button> </button>

View File

@ -95,11 +95,6 @@
padding: 2px; padding: 2px;
} }
.meta-info {
font-size: 12px;
color: #fafafa;
}
.rm { .rm {
color: #f44336; color: #f44336;
position: absolute; position: absolute;

View File

@ -19,7 +19,7 @@
.dashed { .dashed {
border: 2px dashed rgba(#697386, .5); border: 2px dashed rgba(#697386, .5);
border-radius: 1rem; border-radius: .5rem;
padding: 100px 20px; padding: 100px 20px;
.login-wrapper { .login-wrapper {
@ -74,16 +74,12 @@
} }
&.light { &.light {
background: #fff;
.login-wrapper *:not(.cnsl-label):not(.mat-button-wrapper) { .login-wrapper *:not(.cnsl-label):not(.mat-button-wrapper) {
color: #000; color: #000;
} }
} }
&.dark { &.dark {
background: #212224;
.login-wrapper *:not(.cnsl-label):not(.mat-button-wrapper) { .login-wrapper *:not(.cnsl-label):not(.mat-button-wrapper) {
color: #fff; color: #fff;
} }

View File

@ -66,7 +66,7 @@
<mat-spinner class="spinner" color="primary" diameter="25" *ngIf="loadingImages"></mat-spinner> <mat-spinner class="spinner" color="primary" diameter="25" *ngIf="loadingImages"></mat-spinner>
<container [ngSwitch]="theme"> <container [ngSwitch]="theme">
<div class="logo-view" *ngSwitchCase="Theme.DARK"> <div class="logo-view" *ngSwitchCase="Theme.DARK">
<div class="img-wrapper" *ngIf="images['previewDarkLogo']" > <div class="img-wrapper mat-elevation-z3" *ngIf="images['previewDarkLogo']" >
<mat-icon matTooltip="{{'ACTIONS.DELETE' | translate}}" color="warn" class="dl-btn" (click)="deleteAsset(AssetType.LOGO, theme)">remove_circle</mat-icon> <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"/> <img matTooltip="Preview" class="prev" [src]="images['previewDarkLogo']" alt="dark logo preview"/>
</div> </div>
@ -90,11 +90,10 @@
(dropped)="onDropLogo(theme, $event)" (dropped)="onDropLogo(theme, $event)"
[class.hovering]="isHoveringOverDarkLogo"> [class.hovering]="isHoveringOverDarkLogo">
<label class="file-label"> <label class="file-label">
<input #selectedFile style="display: none;" class="file-input" type="file" (change)="onDropLogo(theme, $event.target.files)"> <i class="icon las la-image"></i>
<button mat-stroked-button class="btn" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['label_policy.private_label'] | hasFeature | async) == false" mat-raised-button type="button" (click)="selectedFile.click();">{{'POLICY.PRIVATELABELING.BTN' | translate}}</button>
<i class="icon las la-cloud-upload-alt"></i>
<span>{{isHoveringOverDarkLogo ? ('POLICY.PRIVATELABELING.RELEASE' | translate): ('POLICY.PRIVATELABELING.DROP' | translate)}}</span> <span>{{isHoveringOverDarkLogo ? ('POLICY.PRIVATELABELING.RELEASE' | translate): ('POLICY.PRIVATELABELING.DROP' | translate)}}</span>
<input #selectedFile style="display: none;" class="file-input" type="file" (change)="onDropLogo(theme, $event.target.files)">
<a class="btn" *ngIf="serviceType == PolicyComponentServiceType.ADMIN || (serviceType == PolicyComponentServiceType.MGMT && (['label_policy.private_label'] | hasFeature | async))" (click)="selectedFile.click();">{{'POLICY.PRIVATELABELING.BTN' | translate}}</a>
</label> </label>
</div> </div>
</div> </div>
@ -130,11 +129,10 @@
(dropped)="onDropIcon(theme, $event)" (dropped)="onDropIcon(theme, $event)"
[class.hovering]="isHoveringOverDarkIcon"> [class.hovering]="isHoveringOverDarkIcon">
<label class="file-label"> <label class="file-label">
<input #selectedFileIcon style="display: none;" class="file-input" type="file" (change)="onDropIcon(theme, $event.target.files)"> <i class="icon las la-image"></i>
<button mat-stroked-button class="btn" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['label_policy.private_label'] | hasFeature | async) == false" mat-raised-button type="button" (click)="selectedFileIcon.click();">{{'POLICY.PRIVATELABELING.BTN' | translate}}</button>
<i class="icon las la-cloud-upload-alt"></i>
<span>{{isHoveringOverDarkIcon ? ('POLICY.PRIVATELABELING.RELEASE' | translate): ('POLICY.PRIVATELABELING.DROP' | translate)}}</span> <span>{{isHoveringOverDarkIcon ? ('POLICY.PRIVATELABELING.RELEASE' | translate): ('POLICY.PRIVATELABELING.DROP' | translate)}}</span>
<input #selectedFileIcon style="display: none;" class="file-input" type="file" (change)="onDropIcon(theme, $event.target.files)">
<a class="btn" *ngIf="serviceType == PolicyComponentServiceType.ADMIN || (serviceType == PolicyComponentServiceType.MGMT && (['label_policy.private_label'] | hasFeature | async))" (click)="selectedFileIcon.click();">{{'POLICY.PRIVATELABELING.BTN' | translate}}</a>
</label> </label>
</div> </div>
</div> </div>
@ -219,11 +217,10 @@
(dropped)="onDropFont($event)" (dropped)="onDropFont($event)"
[class.hovering]="isHoveringOverFont"> [class.hovering]="isHoveringOverFont">
<label class="file-label"> <label class="file-label">
<input #selectedFontFile style="display: none;" class="file-input" type="file" (change)="onDropFont($event.target.files)"> <i class="icon las la-file"></i>
<button mat-stroked-button class="btn" [disabled]="serviceType == PolicyComponentServiceType.MGMT && (['label_policy.private_label'] | hasFeature | async) == false" mat-raised-button type="button" (click)="selectedFontFile.click();">{{'POLICY.PRIVATELABELING.BTN' | translate}}</button>
<i class="icon las la-cloud-upload-alt"></i>
<span >{{isHoveringOverFont ? ('POLICY.PRIVATELABELING.RELEASEFONT' | translate): ('POLICY.PRIVATELABELING.DROPFONT' | translate)}}</span> <span >{{isHoveringOverFont ? ('POLICY.PRIVATELABELING.RELEASEFONT' | translate): ('POLICY.PRIVATELABELING.DROPFONT' | translate)}}</span>
<input #selectedFontFile style="display: none;" class="file-input" type="file" (change)="onDropFont($event.target.files)">
<a class="btn" *ngIf="serviceType == PolicyComponentServiceType.ADMIN || (serviceType == PolicyComponentServiceType.MGMT && (['label_policy.private_label'] | hasFeature | async))" (click)="selectedFontFile.click()">{{'POLICY.PRIVATELABELING.BTN' | translate}}</a>
</label> </label>
</div> </div>
</div> </div>

View File

@ -6,6 +6,8 @@
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$primary-color: mat.get-color-from-palette($primary, 500); $primary-color: mat.get-color-from-palette($primary, 500);
$is-dark-theme: map-get($theme, is-dark); $is-dark-theme: map-get($theme, is-dark);
$background: map-get($theme, background);
$foreground: map-get($theme, foreground);
.policy { .policy {
.header { .header {
@ -157,8 +159,6 @@
margin-bottom: 2rem; margin-bottom: 2rem;
.expansion { .expansion {
background: if($is-dark-theme, #2d2e30, #fff) !important;
.header { .header {
justify-content: flex-start; justify-content: flex-start;
} }
@ -189,8 +189,7 @@
height: 150px; height: 150px;
width: 100%; width: 100%;
border-radius: .5rem; border-radius: .5rem;
background: if($is-dark-theme, #2d2e30, #fff); border: 1px solid map-get($foreground, divider);
border: 1px solid if($is-dark-theme, #4a4b4b, #ddd);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -202,11 +201,8 @@
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
.btn { a {
margin-bottom: .5rem; margin-bottom: .5rem;
}
.btn:not[disabled] {
cursor: pointer; cursor: pointer;
} }
@ -272,32 +268,29 @@
margin-bottom: 1rem; margin-bottom: 1rem;
.img-wrapper { .img-wrapper {
flex: 1;
position: relative; position: relative;
min-height: 80px; height: 80px;
border: 1px solid if($is-dark-theme, #ffffff20, #00000020); width: 80px;
border-radius: .5rem; border-radius: 50vw;
max-width: 120px; background-color: #00000020;
.dl-btn { .dl-btn {
z-index: 2; z-index: 2;
position: absolute; position: absolute;
top: -12px; top: 0;
left: -12px; left: 0;
cursor: pointer; cursor: pointer;
visibility: hidden; visibility: hidden;
} }
.prev, .prev,
.curr { .curr {
position: absolute; top: 0;
top: 50%;
transform: translateY(-50%);
left: 0; left: 0;
max-height: 80px; width: 80px;
max-width: 120px; height: 80px;
object-fit: contain; object-fit: contain;
border-radius: .5rem; border-radius: 50%;
} }
&:hover { &:hover {
@ -412,7 +405,7 @@
position: absolute; position: absolute;
top: .5rem; top: .5rem;
left: .5rem; left: .5rem;
border-radius: 10px !important; border-radius: 8px !important;
z-index: 1; z-index: 1;
span { span {

View File

@ -22,6 +22,7 @@ import { AssetEndpoint, AssetService, AssetType } from 'src/app/services/asset.s
import { GrpcAuthService } from 'src/app/services/grpc-auth.service'; import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
import { ManagementService } from 'src/app/services/mgmt.service'; import { ManagementService } from 'src/app/services/mgmt.service';
import { StorageService } from 'src/app/services/storage.service'; import { StorageService } from 'src/app/services/storage.service';
import { ThemeService } from 'src/app/services/theme.service';
import { ToastService } from 'src/app/services/toast.service'; import { ToastService } from 'src/app/services/toast.service';
import { GridPolicy, PRIVATELABEL_POLICY } from '../../policy-grid/policies'; import { GridPolicy, PRIVATELABEL_POLICY } from '../../policy-grid/policies';
@ -95,6 +96,7 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
private assetService: AssetService, private assetService: AssetService,
private sanitizer: DomSanitizer, private sanitizer: DomSanitizer,
private storageService: StorageService, private storageService: StorageService,
private themeService: ThemeService,
) { ) {
const org: Org.AsObject | null = (this.storageService.getItem(ORG_STORAGE_KEY)); const org: Org.AsObject | null = (this.storageService.getItem(ORG_STORAGE_KEY));
@ -587,6 +589,7 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
if (data.policy) { if (data.policy) {
this.data = data.policy; this.data = data.policy;
this.applyToConsole(data.policy);
this.loadImages(); this.loadImages();
} }
}); });
@ -603,6 +606,7 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
if (data.policy) { if (data.policy) {
this.data = data.policy; this.data = data.policy;
this.applyToConsole(data.policy);
this.loadImages(); this.loadImages();
} }
}); });
@ -613,6 +617,26 @@ export class PrivateLabelingPolicyComponent implements OnDestroy {
} }
} }
private applyToConsole(labelpolicy: LabelPolicy.AsObject): void {
const darkPrimary = labelpolicy?.primaryColorDark || '#5282c1';
const lightPrimary = labelpolicy?.primaryColor || '#5282c1';
const darkWarn = labelpolicy?.warnColorDark || '#F44336';
const lightWarn = labelpolicy?.warnColor || '#F44336';
const darkBackground = labelpolicy?.backgroundColorDark || '#212224';
const lightBackground = labelpolicy?.backgroundColor || '#fafafa';
this.themeService.savePrimaryColor(darkPrimary, true);
this.themeService.savePrimaryColor(lightPrimary, false);
this.themeService.saveWarnColor(darkWarn, true);
this.themeService.saveWarnColor(lightWarn, false);
this.themeService.saveBackgroundColor(darkBackground, true);
this.themeService.saveBackgroundColor(lightBackground, false);
}
public resetPolicy(): Promise<any> { public resetPolicy(): Promise<any> {
return (this.service as ManagementService).resetLabelPolicyToDefault().then(() => { return (this.service as ManagementService).resetLabelPolicyToDefault().then(() => {
this.toast.showInfo('POLICY.PRIVATELABELING.RESET', true); this.toast.showInfo('POLICY.PRIVATELABELING.RESET', true);

View File

@ -4,7 +4,7 @@
<p class="wlc_stnce">{{'HOME.WELCOMESENTENCE' | translate}}</p> <p class="wlc_stnce">{{'HOME.WELCOMESENTENCE' | translate}}</p>
</div> </div>
<div class="container"> <div class="gridcontainer">
<ng-template appHasRole [appHasRole]="['iam.write']"> <ng-template appHasRole [appHasRole]="['iam.write']">
<a matRipple *ngIf="!firstStepsDismissed" class="onboard" [routerLink]="['/firststeps']"> <a matRipple *ngIf="!firstStepsDismissed" class="onboard" [routerLink]="['/firststeps']">
<p class="first-steps">{{'ONBOARDING.HEADER' | translate}}</p> <p class="first-steps">{{'ONBOARDING.HEADER' | translate}}</p>
@ -17,7 +17,7 @@
</a> </a>
</ng-template> </ng-template>
<a matRipple *ngIf="!firstStepsDismissed" class="quickstart" target="_blank" <a matRipple *ngIf="!quickstartsDismissed" class="quickstart" target="_blank"
href="https://docs.zitadel.ch/docs/quickstarts/introduction"> href="https://docs.zitadel.ch/docs/quickstarts/introduction">
<p class="first-steps">{{'HOME.QUICKSTARTS.LABEL' | translate}}</p> <p class="first-steps">{{'HOME.QUICKSTARTS.LABEL' | translate}}</p>
<h2>{{'HOME.QUICKSTARTS.TITLE' | translate}}</h2> <h2>{{'HOME.QUICKSTARTS.TITLE' | translate}}</h2>
@ -35,7 +35,7 @@
</a> </a>
<ng-template appHasRole [appHasRole]="['iam.write']"> <ng-template appHasRole [appHasRole]="['iam.write']">
<app-card class="item"> <app-card class="griditem" [nomargin]="true">
<div class="top"> <div class="top">
<h2> <h2>
<i class="icon las la-gem"></i> <i class="icon las la-gem"></i>
@ -66,7 +66,7 @@
</app-card> </app-card>
</ng-template> </ng-template>
<app-card class="item"> <app-card class="griditem" [nomargin]="true">
<div class="top"> <div class="top">
<h2> <i class="icon las la-user-circle"></i> <h2> <i class="icon las la-user-circle"></i>
{{'HOME.SECURITYANDPRIVACY'| translate}}</h2> {{'HOME.SECURITYANDPRIVACY'| translate}}</h2>
@ -83,7 +83,7 @@
</app-card> </app-card>
<ng-template appHasRole [appHasRole]="['project.read']"> <ng-template appHasRole [appHasRole]="['project.read']">
<app-card class="item"> <app-card class="griditem" [nomargin]="true">
<div class="top"> <div class="top">
<h2> <h2>
<i class="icon las la-layer-group"></i> <i class="icon las la-layer-group"></i>
@ -104,7 +104,7 @@
</ng-template> </ng-template>
<ng-template appHasRole [appHasRole]="['org.read']"> <ng-template appHasRole [appHasRole]="['org.read']">
<app-card class="item"> <app-card class="griditem" [nomargin]="true">
<div class="top"> <div class="top">
<h2> <i class="icon las la-archway"></i> <h2> <i class="icon las la-archway"></i>
{{'HOME.PROTECTION'| translate}}</h2> {{'HOME.PROTECTION'| translate}}</h2>
@ -132,7 +132,7 @@
</ng-template> </ng-template>
<ng-template appHasRole [appHasRole]="['user.read']"> <ng-template appHasRole [appHasRole]="['user.read']">
<app-card class="item"> <app-card class="griditem" [nomargin]="true">
<div class="top"> <div class="top">
<h2> <h2>
<i class="las la-users"></i> <i class="las la-users"></i>

View File

@ -18,21 +18,23 @@
} }
} }
.container { .gridcontainer {
display: flex; display: grid;
flex-wrap: wrap; grid-template-columns: 1fr 1fr;
margin: -1rem; gap: 1rem;
justify-content: space-evenly; justify-content: space-evenly;
@media only screen and (max-width: 899px) {
grid-template-columns: 1fr;
}
.onboard, .onboard,
.quickstart { .quickstart {
text-decoration: none; text-decoration: none;
cursor: pointer; cursor: pointer;
box-sizing: border-box; box-sizing: border-box;
flex: 1 0 45%;
position: relative; position: relative;
border-radius: .5rem; border-radius: .5rem;
margin: 1rem;
padding: 1.5rem; padding: 1.5rem;
box-shadow: 0 3px 8px 0 rgb(0 0 0 / 6%); box-shadow: 0 3px 8px 0 rgb(0 0 0 / 6%);
@ -96,12 +98,14 @@
} }
} }
.item { .griditem {
flex: 1 0 45%;
margin: 0 1rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.card {
margin: 0 !important;
}
.top { .top {
h2 { h2 {
margin-top: .5rem; margin-top: .5rem;

View File

@ -28,6 +28,6 @@ export class HomeComponent {
dismissQuickstarts(event: Event): void { dismissQuickstarts(event: Event): void {
event.preventDefault(); event.preventDefault();
localStorage.setItem('quickstartsDismissed', 'true'); localStorage.setItem('quickstartsDismissed', 'true');
this.firstStepsDismissed = true; this.quickstartsDismissed = true;
} }
} }

View File

@ -9,7 +9,7 @@
<h1>{{'APP.PAGES.CREATE_OIDC_DESC_TITLE' | translate}}</h1> <h1>{{'APP.PAGES.CREATE_OIDC_DESC_TITLE' | translate}}</h1>
<p class="desc">{{'APP.PAGES.CREATE_OIDC_DESC_SUB' | translate}}</p> <p class="desc">{{'APP.PAGES.CREATE_OIDC_DESC_SUB' | translate}}</p>
<mat-progress-bar class="progress-bar" color="accent" *ngIf="loading" mode="indeterminate"></mat-progress-bar> <mat-progress-bar class="progress-bar" color="primary" *ngIf="loading" mode="indeterminate"></mat-progress-bar>
<mat-checkbox class="proswitch" color="primary" [(ngModel)]="devmode"> <mat-checkbox class="proswitch" color="primary" [(ngModel)]="devmode">
{{'APP.OIDC.PROSWITCH' | translate}} {{'APP.OIDC.PROSWITCH' | translate}}

View File

@ -3,8 +3,8 @@
<i class="show list view las la-th-list"></i> <i class="show list view las la-th-list"></i>
</button> </button>
</div> </div>
<div class="container"> <div class="granted-project-grid-container">
<mat-progress-bar *ngIf="loading" class="spinner" color="accent" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="loading" class="spinner" color="primary" mode="indeterminate"></mat-progress-bar>
<p class="n-items" *ngIf="!loading && selection.selected.length > 0">{{'PROJECT.PAGES.PINNED' | translate}}</p> <p class="n-items" *ngIf="!loading && selection.selected.length > 0">{{'PROJECT.PAGES.PINNED' | translate}}</p>
@ -28,7 +28,7 @@
</div> </div>
</div> </div>
<div class="container"> <div class="granted-project-grid-container">
<p class="n-items" *ngIf="!loading && notPinned.length > 0">{{'PROJECT.PAGES.ALL' | translate}}</p> <p class="n-items" *ngIf="!loading && notPinned.length > 0">{{'PROJECT.PAGES.ALL' | translate}}</p>
<div class="item card" *ngFor="let item of notPinned; index as i" <div class="item card" *ngFor="let item of notPinned; index as i"

View File

@ -1,9 +1,16 @@
@mixin granted-project-grid-theme($theme) {
$foreground: map-get($theme, foreground);
.view-toggle {
border-bottom: 1px solid map-get($foreground, divider);
}
}
.view-toggle { .view-toggle {
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
padding-bottom: .5rem; padding-bottom: .5rem;
border-bottom: 1px solid #2d2e30;
.anim-list { .anim-list {
display: flex; display: flex;
@ -22,7 +29,7 @@
margin: 1rem; margin: 1rem;
} }
.container { .granted-project-grid-container {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
margin: 0 -1rem; margin: 0 -1rem;

View File

@ -4,8 +4,8 @@
</button> </button>
</div> </div>
<div class="container"> <div class="owned-project-grid-container">
<mat-progress-bar *ngIf="loading" class="spinner" color="accent" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="loading" class="spinner" color="primary" mode="indeterminate"></mat-progress-bar>
<p class="n-items" *ngIf="!loading && selection.selected.length > 0">{{'PROJECT.PAGES.PINNED' | translate}}</p> <p class="n-items" *ngIf="!loading && selection.selected.length > 0">{{'PROJECT.PAGES.PINNED' | translate}}</p>
@ -31,7 +31,7 @@
</div> </div>
</div> </div>
<div class="container"> <div class="owned-project-grid-container">
<p class="n-items" *ngIf="!loading && notPinned.length > 0">{{'PROJECT.PAGES.ALL' | translate}}</p> <p class="n-items" *ngIf="!loading && notPinned.length > 0">{{'PROJECT.PAGES.ALL' | translate}}</p>
<div class="item card" *ngFor="let item of notPinned; index as i" (click)="navigateToProject(item.id, $event)" <div class="item card" *ngFor="let item of notPinned; index as i" (click)="navigateToProject(item.id, $event)"

View File

@ -1,9 +1,16 @@
@mixin owned-project-grid-theme($theme) {
$foreground: map-get($theme, foreground);
.view-toggle {
border-bottom: 1px solid map-get($foreground, divider);
}
}
.view-toggle { .view-toggle {
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
padding-bottom: .5rem; padding-bottom: .5rem;
border-bottom: 1px solid #2d2e30;
.anim-list { .anim-list {
display: flex; display: flex;
@ -22,7 +29,7 @@
margin: 1rem; margin: 1rem;
} }
.container { .owned-project-grid-container {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
margin: 0 -1rem; margin: 0 -1rem;

View File

@ -1,6 +1,6 @@
<app-detail-layout [backRouterLink]="[ '/users/list/machines']" title="{{ 'USER.CREATE.TITLE' | translate }}" <app-detail-layout [backRouterLink]="[ '/users/list/machines']" title="{{ 'USER.CREATE.TITLE' | translate }}"
description="{{ 'USER.CREATE.DESCRIPTION' | translate }}"> description="{{ 'USER.CREATE.DESCRIPTION' | translate }}">
<mat-progress-bar *ngIf="loading" color="accent" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
<form *ngIf="userForm" [formGroup]="userForm" (ngSubmit)="createUser()" class="form"> <form *ngIf="userForm" [formGroup]="userForm" (ngSubmit)="createUser()" class="form">
<div class="content"> <div class="content">

View File

@ -1,6 +1,6 @@
<app-detail-layout [backRouterLink]="[ '/users/list/humans']" title="{{ 'USER.CREATE.TITLE' | translate }}" <app-detail-layout [backRouterLink]="[ '/users/list/humans']" title="{{ 'USER.CREATE.TITLE' | translate }}"
description="{{ 'USER.CREATE.DESCRIPTION' | translate }}"> description="{{ 'USER.CREATE.DESCRIPTION' | translate }}">
<mat-progress-bar *ngIf="loading" color="accent" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
<form *ngIf="userForm" [formGroup]="userForm" (ngSubmit)="createUser()" class="form"> <form *ngIf="userForm" [formGroup]="userForm" (ngSubmit)="createUser()" class="form">
<div class="content"> <div class="content">

View File

@ -10,7 +10,7 @@
<app-theme-setting></app-theme-setting> <app-theme-setting></app-theme-setting>
</div> </div>
</div> </div>
<mat-progress-bar *ngIf="loading" color="accent" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
<span *ngIf="!loading && !user">{{ 'USER.PAGES.NOUSER' | translate }}</span> <span *ngIf="!loading && !user">{{ 'USER.PAGES.NOUSER' | translate }}</span>

View File

@ -3,12 +3,14 @@
@mixin theme-card($theme) { @mixin theme-card($theme) {
/* stylelint-disable */ /* stylelint-disable */
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$primary-dark: mat.get-color-from-palette($primary, A900); $background: map-get($theme, background);
$is-dark-theme: map-get($theme, is-dark);
$back: map-get($background, background);
/* stylelint-enable */ /* stylelint-enable */
.theme-conent, .theme-conent,
.crescent { .crescent {
background-color: $primary-dark; background-color: $back;
transition: background-color .3s cubic-bezier(.645, .045, .355, 1); // cubic-bezier(.645, .045, .355, 1); transition: background-color .3s cubic-bezier(.645, .045, .355, 1); // cubic-bezier(.645, .045, .355, 1);
} }
} }

View File

@ -1,6 +1,3 @@
$dark-background: #212224;
$light-background: rgb(220, 220, 220);
:root { :root {
transition: none; transition: none;
} }
@ -31,7 +28,6 @@ $light-background: rgb(220, 220, 220);
right: 0; right: 0;
width: 40px; width: 40px;
height: 40px; height: 40px;
background: $light-background;
transform: scale(0); transform: scale(0);
transform-origin: top right; transform-origin: top right;
transition: transform .2s cubic-bezier(.645, .045, .355, 1); transition: transform .2s cubic-bezier(.645, .045, .355, 1);
@ -57,7 +53,6 @@ label {
.toggle { .toggle {
position: absolute; position: absolute;
background-color: $light-background;
box-shadow: 0 2px 15px rgba(0, 0, 0, .15); box-shadow: 0 2px 15px rgba(0, 0, 0, .15);
} }
@ -82,7 +77,6 @@ label {
[type="checkbox"]:checked { [type="checkbox"]:checked {
.toggle { .toggle {
transform: translateX(100%); transform: translateX(100%);
background-color: $dark-background;
} }
.light { .light {
@ -101,7 +95,6 @@ label {
[type="checkbox"]:checked + .theme-app .crescent { [type="checkbox"]:checked + .theme-app .crescent {
transform: scale(1); transform: scale(1);
background: $dark-background;
} }
[type="checkbox"]:checked + .theme-app .circle { [type="checkbox"]:checked + .theme-app .circle {
@ -111,8 +104,3 @@ label {
[type="checkbox"]:checked + .theme-app .main-circle { [type="checkbox"]:checked + .theme-app .main-circle {
background: linear-gradient(40deg, #8983f7, #a3dafb 70%); background: linear-gradient(40deg, #8983f7, #a3dafb 70%);
} }
[type="checkbox"]:checked + .app .toggle {
transform: translateX(100%);
background-color: #34323d;
}

View File

@ -3,9 +3,8 @@
@mixin membership-theme($theme) { @mixin membership-theme($theme) {
/* stylelint-disable */ /* stylelint-disable */
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$primary-dark: mat.get-color-from-palette($primary, A900); $is-dark-theme: map-get($theme, is-dark);
$accent: map-get($theme, accent); $primary-color: mat.get-color-from-palette($primary, 500);
$accent-color: mat.get-color-from-palette($accent, 500);
/* stylelint-enable */ /* stylelint-enable */
.membership-groups { .membership-groups {
@ -91,7 +90,7 @@
font-size: 8px; font-size: 8px;
border-radius: .5rem; border-radius: .5rem;
transition: background-color .3s cubic-bezier(.645, .045, .355, 1); transition: background-color .3s cubic-bezier(.645, .045, .355, 1);
background-color: $accent-color; background-color: $primary-color;
cursor: pointer; cursor: pointer;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;

View File

@ -24,7 +24,7 @@
</ng-template> </ng-template>
</div> </div>
<mat-progress-bar *ngIf="loading" color="accent" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="loading" color="primary" mode="indeterminate"></mat-progress-bar>
<span *ngIf="!loading && !user">{{ 'USER.PAGES.NOUSER' | translate }}</span> <span *ngIf="!loading && !user">{{ 'USER.PAGES.NOUSER' | translate }}</span>

View File

@ -1,12 +1,80 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs'; import { Observable, Subject } from 'rxjs';
declare const tinycolor: any;
export interface Color {
name: string;
hex: string;
darkContrast: boolean;
}
@Injectable() @Injectable()
export class ThemeService { export class ThemeService {
private _darkTheme: Subject<boolean> = new Subject<boolean>(); private _darkTheme: Subject<boolean> = new Subject<boolean>();
public isDarkTheme: Observable<boolean> = this._darkTheme.asObservable(); public isDarkTheme: Observable<boolean> = this._darkTheme.asObservable();
private primaryColorPalette: Color[] = [];
private warnColorPalette: Color[] = [];
private backgroundColorPalette: Color[] = [];
setDarkTheme(isDarkTheme: boolean): void { setDarkTheme(isDarkTheme: boolean): void {
this._darkTheme.next(isDarkTheme); this._darkTheme.next(isDarkTheme);
} }
public updateTheme(colors: Color[], type: string, theme: string): void {
colors.forEach(color => {
document.documentElement.style.setProperty(
`--theme-${theme}-${type}-${color.name}`,
color.hex,
);
document.documentElement.style.setProperty(
`--theme-${theme}-${type}-contrast-${color.name}`,
color.darkContrast ? 'hsla(0, 0%, 0%, 0.87)' : '#ffffff',
);
});
}
public savePrimaryColor(color: string, isDark: boolean): void {
this.primaryColorPalette = this.computeColors(color);
this.updateTheme(this.primaryColorPalette, 'primary', isDark ? 'dark' : 'light');
}
public saveWarnColor(color: string, isDark: boolean): void {
this.warnColorPalette = this.computeColors(color);
this.updateTheme(this.warnColorPalette, 'warn', isDark ? 'dark' : 'light');
}
public saveBackgroundColor(color: string, isDark: boolean): void {
this.backgroundColorPalette = this.computeColors(color);
this.updateTheme(this.backgroundColorPalette, 'background', isDark ? 'dark' : 'light');
}
private computeColors(hex: string): Color[] {
return [
this.getColorObject(tinycolor(hex).lighten(52), '50'),
this.getColorObject(tinycolor(hex).lighten(37), '100'),
this.getColorObject(tinycolor(hex).lighten(26), '200'),
this.getColorObject(tinycolor(hex).lighten(12), '300'),
this.getColorObject(tinycolor(hex).lighten(6), '400'),
this.getColorObject(tinycolor(hex), '500'),
this.getColorObject(tinycolor(hex).darken(6), '600'),
this.getColorObject(tinycolor(hex).darken(12), '700'),
this.getColorObject(tinycolor(hex).darken(18), '800'),
this.getColorObject(tinycolor(hex).darken(24), '900'),
this.getColorObject(tinycolor(hex).lighten(50).saturate(30), 'A100'),
this.getColorObject(tinycolor(hex).lighten(30).saturate(30), 'A200'),
this.getColorObject(tinycolor(hex).lighten(10).saturate(15), 'A400'),
this.getColorObject(tinycolor(hex).lighten(5).saturate(5), 'A700'),
];
}
private getColorObject(value: any, name: string): Color {
const c = tinycolor(value);
return {
name: name,
hex: c.toHexString(),
darkContrast: c.isLight(),
};
}
} }

View File

@ -670,7 +670,7 @@
"COLORS":"Farben", "COLORS":"Farben",
"FONT":"Schrift", "FONT":"Schrift",
"ADVANCEDBEHAVIOR":"Erweitertes Verhalten", "ADVANCEDBEHAVIOR":"Erweitertes Verhalten",
"DROP":"Bild hier ablegen", "DROP":"Bild hier ablegen oder",
"RELEASE":"Jetzt loslassen", "RELEASE":"Jetzt loslassen",
"DROPFONT":"Fontdatei hier ablegen", "DROPFONT":"Fontdatei hier ablegen",
"RELEASEFONT":"Jetzt loslassen", "RELEASEFONT":"Jetzt loslassen",

View File

@ -670,7 +670,7 @@
"COLORS":"Colors", "COLORS":"Colors",
"FONT":"Font", "FONT":"Font",
"ADVANCEDBEHAVIOR":"Advanced Behavior", "ADVANCEDBEHAVIOR":"Advanced Behavior",
"DROP":"Drop image here", "DROP":"Drop image here or",
"RELEASE":"Release", "RELEASE":"Release",
"DROPFONT":"Drop fontfile here", "DROPFONT":"Drop fontfile here",
"RELEASEFONT":"Release", "RELEASEFONT":"Release",

View File

@ -13,6 +13,8 @@
@import 'src/app/modules/app-card/app-card.component'; @import 'src/app/modules/app-card/app-card.component';
@import 'src/app/pages/users/user-detail/auth-user-detail/theme-setting/theme-card'; @import 'src/app/pages/users/user-detail/auth-user-detail/theme-setting/theme-card';
@import 'src/app/pages/users/user-detail/memberships/memberships.component'; @import 'src/app/pages/users/user-detail/memberships/memberships.component';
@import 'src/app/pages/projects/owned-projects/owned-project-list/owned-project-grid/owned-project-grid.component';
@import 'src/app/pages/projects/granted-projects/granted-project-list/granted-project-grid/granted-project-grid.component';
@import 'src/app/app.component.scss'; @import 'src/app/app.component.scss';
@import 'src/app/modules/form-field/form-field.component.scss'; @import 'src/app/modules/form-field/form-field.component.scss';
@import 'src/app/modules/label/label.component.scss'; @import 'src/app/modules/label/label.component.scss';
@ -44,4 +46,6 @@
@include onboarding-theme($theme); @include onboarding-theme($theme);
@include tier-theme($theme); @include tier-theme($theme);
@include private-label-theme($theme); @include private-label-theme($theme);
@include owned-project-grid-theme($theme);
@include granted-project-grid-theme($theme);
} }

View File

@ -4,6 +4,7 @@
@use '~@angular/material' as mat; @use '~@angular/material' as mat;
@import './component-themes'; @import './component-themes';
@import '~@angular/material/theming';
// Plus imports for other components in your app. // Plus imports for other components in your app.
@ -22,131 +23,311 @@
--table-row-back: #363738; --table-row-back: #363738;
} }
$caos-dark-brand: ( $caos-dark-primary: (
50: #fff, 50 : var(--theme-dark-primary-50),
100: #dde6f3, 100 : var(--theme-dark-primary-100),
200: #b4c9e4, 200 : var(--theme-dark-primary-200),
300: #7fa3d1, 300 : var(--theme-dark-primary-300),
400: #6992c9, 400 : var(--theme-dark-primary-400),
500: #5282c1, 500 : var(--theme-dark-primary-500),
600: #4072b4, 600 : var(--theme-dark-primary-600),
700: #38649d, 700 : var(--theme-dark-primary-700),
800: #305687, 800 : var(--theme-dark-primary-800),
900: #284770, 900 : var(--theme-dark-primary-900),
A100: #fff, A100 : var(--theme-dark-primary-A100),
A200: #dde6f3, A200 : var(--theme-dark-primary-A200),
A300: #6992c9, A400 : var(--theme-dark-primary-A400),
A400: #38649d, A700 : var(--theme-dark-primary-A700),
A500: #666,
A600: #fff,
A700: #8795a1,
A800: #2d2e30,
A900: #212224,
contrast: contrast:
( (
50: rgba(black, .87), 50: var(--theme-dark-primary-contrast-50),
100: rgba(black, .87), 100: var(--theme-dark-primary-contrast-100),
200: rgba(black, .87), 200: var(--theme-dark-primary-contrast-200),
300: rgba(black, .87), 300: var(--theme-dark-primary-contrast-300),
400: rgba(black, .87), 400: var(--theme-dark-primary-contrast-400),
500: white, 500: var(--theme-dark-primary-contrast-500),
600: white, 600: var(--theme-dark-primary-contrast-600),
700: white, 700: var(--theme-dark-primary-contrast-700),
800: white, 800: var(--theme-dark-primary-contrast-800),
900: white, 900: var(--theme-dark-primary-contrast-900),
A100: rgba(black, .87), A100: var(--theme-dark-primary-contrast-A100),
A200: rgba(black, .87), A200: var(--theme-dark-primary-contrast-A200),
A400: rgba(black, .87), A400: var(--theme-dark-primary-contrast-A400),
A700: white A700: var(--theme-dark-primary-contrast-A700)
) )
); );
$caos-light-brand: ( $caos-light-primary: (
50: #eaedfa, 50 : var(--theme-light-primary-50),
100: #ccd2f2, 100 : var(--theme-light-primary-100),
200: #aab4ea, 200 : var(--theme-light-primary-200),
300: #8796e1, 300 : var(--theme-light-primary-300),
400: #6e80da, 400 : var(--theme-light-primary-400),
500: #5469d4, 500 : var(--theme-light-primary-500),
600: #4d61cf, 600 : var(--theme-light-primary-600),
700: #4356c9, 700 : var(--theme-light-primary-700),
800: #3a4cc3, 800 : var(--theme-light-primary-800),
900: #293bb9, 900 : var(--theme-light-primary-900),
A100: #f9faff, A100 : var(--theme-light-primary-A100),
A200: #c6ccff, A200 : var(--theme-light-primary-A200),
A300: #939fff, A400 : var(--theme-light-primary-A400),
A400: #7a88ff, A700 : var(--theme-light-primary-A700),
A500:#333,
A600: #000,
A700: #8795a1,
A800: white,
A900: #fafafa,
contrast: contrast:
( (
50: #3d4852, 50: var(--theme-light-primary-contrast-50),
100: #3d4852, 100: var(--theme-light-primary-contrast-100),
200: #3d4852, 200: var(--theme-light-primary-contrast-200),
300: #3d4852, 300: var(--theme-light-primary-contrast-300),
400: #3d4852, 400: var(--theme-light-primary-contrast-400),
500: white, 500: var(--theme-light-primary-contrast-500),
600: white, 600: var(--theme-light-primary-contrast-600),
700: white, 700: var(--theme-light-primary-contrast-700),
800: white, 800: var(--theme-light-primary-contrast-800),
900: white, 900: var(--theme-light-primary-contrast-900),
A100: #3d4852, A100: var(--theme-light-primary-contrast-A100),
A200: #3d4852, A200: var(--theme-light-primary-contrast-A200),
A400: #3d4852, A400: var(--theme-light-primary-contrast-A400),
A700: white A700: var(--theme-light-primary-contrast-A700)
) )
); );
$caos-accent-color: ( $caos-dark-background: (
50: #ebf4f2, 50 : var(--theme-dark-background-50),
100: #cce3de, 100 : var(--theme-dark-background-100),
200: #abd1c9, 200 : var(--theme-dark-background-200),
300: #89bfb3, 300 : var(--theme-dark-background-300),
400: #6fb1a2, 400 : var(--theme-dark-background-400),
500: #56a392, 500 : var(--theme-dark-background-500),
600: #4f9b8a, 600 : var(--theme-dark-background-600),
700: #45917f, 700 : var(--theme-dark-background-700),
800: #3c8875, 800 : var(--theme-dark-background-800),
900: #2b7763, 900 : var(--theme-dark-background-900),
A100: #beffed, A100 : var(--theme-dark-background-A100),
A200: #8bffde, A200 : var(--theme-dark-background-A200),
A400: #58ffd0, A400 : var(--theme-dark-background-A400),
A700: #3effc9, A700 : var(--theme-dark-background-A700),
contrast: contrast:
( (
50: rgba(black, .87), 50: var(--theme-dark-background-contrast-50),
100: rgba(black, .87), 100: var(--theme-dark-background-contrast-100),
200: rgba(black, .87), 200: var(--theme-dark-background-contrast-200),
300: rgba(black, .87), 300: var(--theme-dark-background-contrast-300),
400: rgba(black, .87), 400: var(--theme-dark-background-contrast-400),
500: white, 500: var(--theme-dark-background-contrast-500),
600: white, 600: var(--theme-dark-background-contrast-600),
700: white, 700: var(--theme-dark-background-contrast-700),
800: white, 800: var(--theme-dark-background-contrast-800),
900: white, 900: var(--theme-dark-background-contrast-900),
A100: rgba(black, .87), A100: var(--theme-dark-background-contrast-A100),
A200: rgba(black, .87), A200: var(--theme-dark-background-contrast-A200),
A400: rgba(black, .87), A400: var(--theme-dark-background-contrast-A400),
A700: white A700: var(--theme-dark-background-contrast-A700)
) )
); );
// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$light-primary: mat.define-palette($caos-light-brand); $caos-light-background: (
$light-accent: mat.define-palette($caos-accent-color); 50 : var(--theme-light-background-50),
$light-warn: mat.define-palette(mat.$red-palette); 100 : var(--theme-light-background-100),
200 : var(--theme-light-background-200),
300 : var(--theme-light-background-300),
400 : var(--theme-light-background-400),
500 : var(--theme-light-background-500),
600 : var(--theme-light-background-600),
700 : var(--theme-light-background-700),
800 : var(--theme-light-background-800),
900 : var(--theme-light-background-900),
A100 : var(--theme-light-background-A100),
A200 : var(--theme-light-background-A200),
A400 : var(--theme-light-background-A400),
A700 : var(--theme-light-background-A700),
contrast:
(
50: var(--theme-light-background-contrast-50),
100: var(--theme-light-background-contrast-100),
200: var(--theme-light-background-contrast-200),
300: var(--theme-light-background-contrast-300),
400: var(--theme-light-background-contrast-400),
500: var(--theme-light-background-contrast-500),
600: var(--theme-light-background-contrast-600),
700: var(--theme-light-background-contrast-700),
800: var(--theme-light-background-contrast-800),
900: var(--theme-light-background-contrast-900),
A100: var(--theme-light-background-contrast-A100),
A200: var(--theme-light-background-contrast-A200),
A400: var(--theme-light-background-contrast-A400),
A700: var(--theme-light-background-contrast-A700)
)
);
$dark-primary: mat.define-palette($caos-dark-brand); $caos-dark-warn: (
$dark-accent: mat.define-palette(mat.$pink-palette); 50 : var(--theme-dark-warn-50),
$dark-warn: mat.define-palette(mat.$red-palette); 100 : var(--theme-dark-warn-100),
200 : var(--theme-dark-warn-200),
300 : var(--theme-dark-warn-300),
400 : var(--theme-dark-warn-400),
500 : var(--theme-dark-warn-500),
600 : var(--theme-dark-warn-600),
700 : var(--theme-dark-warn-700),
800 : var(--theme-dark-warn-800),
900 : var(--theme-dark-warn-900),
A100 : var(--theme-dark-warn-A100),
A200 : var(--theme-dark-warn-A200),
A400 : var(--theme-dark-warn-A400),
A700 : var(--theme-dark-warn-A700),
contrast:
(
50: var(--theme-dark-warn-contrast-50),
100: var(--theme-dark-warn-contrast-100),
200: var(--theme-dark-warn-contrast-200),
300: var(--theme-dark-warn-contrast-300),
400: var(--theme-dark-warn-contrast-400),
500: var(--theme-dark-warn-contrast-500),
600: var(--theme-dark-warn-contrast-600),
700: var(--theme-dark-warn-contrast-700),
800: var(--theme-dark-warn-contrast-800),
900: var(--theme-dark-warn-contrast-900),
A100: var(--theme-dark-warn-contrast-A100),
A200: var(--theme-dark-warn-contrast-A200),
A400: var(--theme-dark-warn-contrast-A400),
A700: var(--theme-dark-warn-contrast-A700)
)
);
$light-theme: mat.define-light-theme($light-primary, $light-accent, $light-warn); $caos-light-warn: (
$dark-theme: mat.define-dark-theme($dark-primary, $dark-accent, $dark-warn); 50 : var(--theme-light-warn-50),
100 : var(--theme-light-warn-100),
200 : var(--theme-light-warn-200),
300 : var(--theme-light-warn-300),
400 : var(--theme-light-warn-400),
500 : var(--theme-light-warn-500),
600 : var(--theme-light-warn-600),
700 : var(--theme-light-warn-700),
800 : var(--theme-light-warn-800),
900 : var(--theme-light-warn-900),
A100 : var(--theme-light-warn-A100),
A200 : var(--theme-light-warn-A200),
A400 : var(--theme-light-warn-A400),
A700 : var(--theme-light-warn-A700),
contrast:
(
50: var(--theme-light-warn-contrast-50),
100: var(--theme-light-warn-contrast-100),
200: var(--theme-light-warn-contrast-200),
300: var(--theme-light-warn-contrast-300),
400: var(--theme-light-warn-contrast-400),
500: var(--theme-light-warn-contrast-500),
600: var(--theme-light-warn-contrast-600),
700: var(--theme-light-warn-contrast-700),
800: var(--theme-light-warn-contrast-800),
900: var(--theme-light-warn-contrast-900),
A100: var(--theme-light-warn-contrast-A100),
A200: var(--theme-light-warn-contrast-A200),
A400: var(--theme-light-warn-contrast-A400),
A700: var(--theme-light-warn-contrast-A700)
)
);
$caos-dark-theme-background: (
status-bar: map_get($caos-dark-background, 300),
app-bar: map_get($caos-dark-background, 500),
background: map_get($caos-dark-background, 500),
hover: rgba(black, .04),
card: map_get($caos-dark-background, 400),
dialog: white,
disabled-button: rgba(black, .12),
raised-button: white,
focused-button: $dark-focused,
selected-button: map_get($caos-dark-background, 300),
selected-disabled-button: map_get($caos-dark-background, 400),
disabled-button-toggle: map_get($caos-dark-background, 200),
unselected-chip: map_get($caos-dark-background, 300),
disabled-list-option: map_get($caos-dark-background, 200),
tooltip: map_get($mat-gray, 700),
infosection: map_get($caos-dark-background, 300),
warninfosection: #4f566b,
successinfosection: #4f566b
);
$caos-light-theme-background: (
status-bar: map_get($caos-light-background, 300),
app-bar: map_get($caos-light-background, 100),
background: map_get($caos-light-background, 500),
hover: rgba(black, .04),
card: map_get($caos-light-background, 400),
dialog: white,
disabled-button: rgba(black, .12),
raised-button: white,
focused-button: $light-focused,
selected-button: map_get($caos-light-background, 300),
selected-disabled-button: map_get($caos-light-background, 400),
disabled-button-toggle: map_get($caos-light-background, 200),
unselected-chip: map_get($caos-light-background, 300),
disabled-list-option: map_get($caos-light-background, 200),
tooltip: map_get($mat-gray, 700),
infosection: #e4e4e4,
warninfosection: #ffc1c1,
successinfosection: #cbf4c9
);
$caos-dark-theme-foreground: (
base: white,
divider: $light-dividers,
dividers: $light-dividers,
disabled: $light-disabled-text,
disabled-button: rgba(white, .26),
disabled-text: $light-disabled-text,
elevation: black,
hint-text: $light-disabled-text,
secondary-text: $light-secondary-text,
icon: rgba(white, .54),
icons: rgba(white, .54),
text: rgba(white, .87),
slider-min: rgba(white, .87),
slider-off: rgba(white, .26),
slider-off-active: rgba(white, .38),
infosection: #f0f0f0,
warninfosection: #ffc1c1,
successinfosection: #cbf4c9
);
$caos-light-theme-foreground: (
base: black,
divider: $dark-dividers,
dividers: $dark-dividers,
disabled: $dark-disabled-text,
disabled-button: rgba(black, .26),
disabled-text: $dark-disabled-text,
elevation: black,
hint-text: $dark-disabled-text,
secondary-text: $dark-secondary-text,
icon: rgba(black, .54),
icons: rgba(black, .54),
text: rgba(black, .87),
slider-min: rgba(black, .87),
slider-off: rgba(black, .26),
slider-off-active: rgba(black, .38),
infosection: #4a4a4a,
warninfosection: #620e0e,
successinfosection: #0e6245
);
$caos-dark-app-theme: (
primary: mat-palette($caos-dark-primary),
accent: mat-palette($caos-dark-primary),
warn: mat-palette($caos-dark-warn),
is-dark: true,
foreground: $caos-dark-theme-foreground,
background: $caos-dark-theme-background
);
$caos-light-app-theme: (
primary: mat-palette($caos-light-primary),
accent: mat-palette($caos-light-primary),
warn: mat-palette($caos-light-warn),
is-dark: false,
foreground: $caos-light-theme-foreground,
background: $caos-light-theme-background
);
$custom-typography: mat.define-typography-config($font-family: 'Lato'); $custom-typography: mat.define-typography-config($font-family: 'Lato');
@ -157,8 +338,8 @@ $custom-typography: mat.define-typography-config($font-family: 'Lato');
// } // }
// default theme // default theme
@include component-themes($dark-theme); @include component-themes($caos-dark-app-theme);
@include mat.all-component-themes($dark-theme); @include mat.all-component-themes($caos-dark-app-theme);
.mat-dialog-container, .mat-dialog-container,
.mat-raised-button, .mat-raised-button,
@ -167,30 +348,31 @@ $custom-typography: mat.define-typography-config($font-family: 'Lato');
} }
.light-theme { .light-theme {
@include component-themes($light-theme); @include component-themes($caos-light-app-theme);
@include mat.all-component-themes($light-theme); @include mat.all-component-themes($caos-light-app-theme);
--grey: #697386; --grey: #697386;
--color-main: #5469d4; --color-main: var(--theme-light-primary-500);
$background: map-get($caos-light-app-theme, background);
.sidenav, .sidenav,
.main-container, .main-container,
.mat-dialog-container { .mat-dialog-container {
background-color: #fafafa; background-color: map-get($background, background);
transition: background-color .3s cubic-bezier(.645, .045, .355, 1); transition: background-color .3s cubic-bezier(.645, .045, .355, 1);
} }
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);
box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);
background-color: #fafafa; background-color: map-get($background, background);
border-radius: 8px; border-radius: 8px;
} }
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 6px; width: 6px;
height: 6px; height: 6px;
background-color: #fafafa; background-color: map-get($background, background);
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
@ -200,27 +382,28 @@ $custom-typography: mat.define-typography-config($font-family: 'Lato');
} }
.root-header { .root-header {
box-shadow: inset 0 -1px #e3e8ee; box-shadow: inset 0 -1px map-get($caos-light-theme-foreground, divider);
} }
} }
.dark-theme { .dark-theme {
@include component-themes($dark-theme); @include component-themes($caos-dark-app-theme);
@include mat.all-component-themes($dark-theme); @include mat.all-component-themes($caos-dark-app-theme);
--color-main: #5282c1; --color-main: var(--theme-dark-primary-500);
$background: map-get($caos-dark-app-theme, background);
.sidenav, .sidenav,
.main-container, .main-container,
.mat-dialog-container { .mat-dialog-container {
background-color: #212224; background-color: map-get($background, background);
transition: background-color .3s cubic-bezier(.645, .045, .355, 1); transition: background-color .3s cubic-bezier(.645, .045, .355, 1);
} }
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3); -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
box-shadow: inset 0 0 6px rgba(0, 0, 0, .3); box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
background-color: #2d2e30; background-color: map-get($background, background);
border-radius: 8px; border-radius: 8px;
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important; transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
} }
@ -228,7 +411,7 @@ $custom-typography: mat.define-typography-config($font-family: 'Lato');
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 6px; width: 6px;
height: 6px; height: 6px;
background-color: #2d2e30; background-color: map-get($background, background);
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important; transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
} }
@ -240,7 +423,7 @@ $custom-typography: mat.define-typography-config($font-family: 'Lato');
} }
.root-header { .root-header {
box-shadow: inset 0 -1px #303131; box-shadow: inset 0 -1px map-get($caos-dark-theme-foreground, divider);
} }
} }
// @include mat.checkbox-theme($candy-app-theme); // @include mat.checkbox-theme($candy-app-theme);

View File

@ -3,9 +3,6 @@
@mixin input-theme($theme) { @mixin input-theme($theme) {
/* stylelint-disable */ /* stylelint-disable */
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$primary-dark: mat.get-color-from-palette($primary, A900);
$secondary-dark: mat.get-color-from-palette($primary, A800);
$inv-color: mat.get-color-from-palette($primary, A600);
$primary-color: mat.get-color-from-palette($primary, 500); $primary-color: mat.get-color-from-palette($primary, 500);
$primary-light-color: mat.get-color-from-palette($primary, 200); $primary-light-color: mat.get-color-from-palette($primary, 200);
$warn: map-get($theme, warn); $warn: map-get($theme, warn);
@ -28,17 +25,18 @@
font-size: 1rem; font-size: 1rem;
border: none; border: none;
border: 1px solid if($is-dark-theme, #403e3e, #00000040); border: 1px solid if($is-dark-theme, #403e3e, #00000040);
background-color:if($is-dark-theme, #00000020, #fafafa50); background-color: if($is-dark-theme, #00000020, #fafafa50);
border-radius: 4px; border-radius: 4px;
height: 40px; height: 40px;
padding: 10px; padding: 10px;
transition: border-color .2s ease-in-out; transition: border-color .2s ease-in-out, background-color .3s cubic-bezier(.645, .045, .355, 1),
color .3s cubic-bezier(.645, .045, .355, 1);
width: 100%; width: 100%;
color: mat.get-color-from-palette($foreground, text); color: mat.get-color-from-palette($foreground, text);
margin-bottom: 2px; margin-bottom: 2px;
&:hover { &:hover {
border-color: if($is-dark-theme,#aeafb1, #1a1b1b); border-color: if($is-dark-theme, #aeafb1, #1a1b1b);
} }
&:active, &:active,
@ -53,11 +51,11 @@
} }
&[disabled] { &[disabled] {
border-color: if($is-dark-theme,#36373850,#cccdce50); border-color: if($is-dark-theme, #36373850, #cccdce50);
color: if($is-dark-theme, #ffffff80 ,#00000061); color: if($is-dark-theme, #ffffff80, #00000061);
&::placeholder { &::placeholder {
color: if($is-dark-theme, #ffffff80 ,#00000061); color: if($is-dark-theme, #ffffff80, #00000061);
} }
} }
} }

View File

@ -3,36 +3,49 @@
@mixin sidenav-list-theme($theme) { @mixin sidenav-list-theme($theme) {
/* stylelint-disable */ /* stylelint-disable */
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$background: map-get($theme, background);
$accent: map-get($theme, accent); $accent: map-get($theme, accent);
$primary-color: mat.get-color-from-palette($primary, 500); $primary-color: mat.get-color-from-palette($primary, 500);
$accent-color: mat.get-color-from-palette($accent, 500); $accent-color: mat.get-color-from-palette($accent, 500);
$primary-dark: mat.get-color-from-palette($primary, A900);
$foreground: map-get($theme, foreground); $foreground: map-get($theme, foreground);
$sec-dark: mat.get-color-from-palette($primary, A800);
$is-dark-theme: map-get($theme, is-dark); $is-dark-theme: map-get($theme, is-dark);
$back: map-get($background, background);
/* stylelint-enable */ /* stylelint-enable */
.meta { .meta {
box-shadow: inset 1px 0 if($is-dark-theme, #303131, #e3e8ee); box-shadow: inset 1px 0 map-get($foreground, divider);
} }
.sidenav { .sidenav {
box-shadow: inset -1px 0 if($is-dark-theme, #303131, #e3e8ee); box-shadow: inset -1px 0 map-get($foreground, divider);
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important; transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
} }
.nav-item { .nav-item {
color: mat.get-color-from-palette($foreground, text) !important; color: mat.get-color-from-palette($foreground, text) !important;
transition: all .2s ease;
i {
opacity: .6;
}
&:hover { &:hover {
background-color: if($is-dark-theme, $sec-dark, rgb(84 105 212 / 6%)); // font-weight: 600;
border-top-right-radius: 1.5rem; border-top-right-radius: 1.5rem;
border-bottom-right-radius: 1.5rem; border-bottom-right-radius: 1.5rem;
i {
opacity: 1;
}
} }
&.active { &.active {
color: $primary-color !important; color: $primary-color !important;
background-color: if($is-dark-theme, rgba($color: $primary-color, $alpha: .1), rgb(84 105 212 / 6%)) !important; // background-color: if($is-dark-theme, rgba($color: $primary-color, $alpha: .1), rgb(84 105 212 / 6%)) !important;
i {
opacity: 1;
}
} }
.c_label { .c_label {
@ -45,7 +58,7 @@
.mat-menu-content, .mat-menu-content,
.mat-menu-panel { .mat-menu-panel {
background-color: $primary-dark; background-color: $back;
border-radius: .5rem; border-radius: .5rem;
@include mat.elevation(5); @include mat.elevation(5);
@ -57,8 +70,7 @@
} }
.root-header { .root-header {
box-shadow: inset 0 -1px #e3e8ee; background-color: $back !important;
background-color: $primary-dark !important;
transition: all .3s cubic-bezier(.645, .045, .355, 1); transition: all .3s cubic-bezier(.645, .045, .355, 1);
.slash { .slash {
@ -66,7 +78,6 @@
} }
.org-button { .org-button {
border: 1px solid if($is-dark-theme, #303131, #e3e8ee);
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important; transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
} }
} }
@ -118,11 +129,11 @@
.divider { .divider {
.span { .span {
border-color: if($is-dark-theme, #303131, #e3e8ee); border-color: map-get($foreground, divider);
} }
.line { .line {
background-color: if($is-dark-theme, #303131, #e3e8ee); background-color: map-get($foreground, divider);
} }
} }
} }

View File

@ -3,14 +3,10 @@
@mixin table-theme($theme) { @mixin table-theme($theme) {
/* stylelint-disable */ /* stylelint-disable */
$primary: map-get($theme, primary); $primary: map-get($theme, primary);
$warn: map-get($theme, warn);
$warn-color: mat.get-color-from-palette($warn, 500);
$primary-color: mat.get-color-from-palette($primary, 500); $primary-color: mat.get-color-from-palette($primary, 500);
$primary-dark: mat.get-color-from-palette($primary, A900);
$secondary-dark: mat.get-color-from-palette($primary, A800);
$inv-color: mat.get-color-from-palette($primary, A600);
$foreground: map-get($theme, foreground);
$is-dark-theme: map-get($theme, is-dark); $is-dark-theme: map-get($theme, is-dark);
$foreground: map-get($theme, foreground);
$background: map-get($theme, background);
.mat-table, .mat-table,
.mat-paginator { .mat-paginator {
@ -58,7 +54,7 @@
&:hover { &:hover {
td { td {
background: if($is-dark-theme, #292a2b, #f4f4f4); // rgba($inv-color, .05); background: map-get($background, hover);
} }
} }
} }