feat: rehauled console (#3525)

* new console

* move npm ci to angular build

* rel path for assets

* local grpc copy

* login policy, rm clear views, features rel path

* lock

Co-authored-by: Livio Amstutz <[email protected]>
This commit is contained in:
Max Peintner
2022-04-28 10:35:02 +00:00
committed by GitHub
co-authored by Livio Amstutz
parent 00f7dbe875
commit 08ae39ae19
668 changed files with 47746 additions and 19117 deletions
@@ -0,0 +1,31 @@
<div class="sidenav-container">
<div class="sidenav-settings-list">
<div class="sidenav-sticky-rel">
<button *ngIf="currentSetting !== undefined" (click)="value = undefined"
class="sidenav-setting-list-element mob-only" [ngClass]="{'active': true}">
<i class="las la-angle-left"></i>
<span>{{'USER.SETTINGS.TITLE' | translate}}</span>
</button>
<ng-container *ngFor="let setting of settingsList">
<ng-template *ngIf="setting.featureRequired, else btn" cnslHasFeature [hasFeature]="setting.featureRequired">
<button (click)="value = setting.id" class="sidenav-setting-list-element hide-on-mobile"
[ngClass]="{'active': currentSetting === setting.id, 'show': currentSetting === undefined}">
<span>{{setting.i18nKey | translate}}</span>
</button>
</ng-template>
<ng-template #btn>
<button (click)="value = setting.id" class="sidenav-setting-list-element hide-on-mobile"
[ngClass]="{'active': currentSetting === setting.id, 'show': currentSetting === undefined}">
<span>{{setting.i18nKey | translate}}</span>
</button>
</ng-template>
</ng-container>
</div>
</div>
<div class="sidenav-content">
<div class="max-width-container">
<ng-content></ng-content>
</div>
</div>
</div>
@@ -0,0 +1,89 @@
@use '@angular/material' as mat;
@mixin sidenav-theme($theme) {
$foreground: map-get($theme, foreground);
$is-dark-theme: map-get($theme, is-dark);
.sidenav-container {
padding-top: 1rem;
display: grid;
position: relative;
grid-template-columns: 1fr;
.sidenav-settings-list {
position: relative;
.sidenav-sticky-rel {
display: flex;
flex-direction: column;
position: sticky;
top: 50px;
padding: 1rem 2rem 1rem 0;
.sidenav-setting-list-element {
border: none;
background: none;
text-align: left;
padding: 0.75rem 0;
opacity: 0.6;
font-size: 15px;
cursor: pointer;
color: map-get($foreground, base);
display: flex;
align-items: center;
i {
font-size: 1.2rem;
height: 1.2rem;
line-height: 1.2rem;
}
&:hover {
opacity: 1;
}
&.mob-only {
display: none;
@media only screen and (max-width: 500px) {
display: flex;
}
}
&.hide-on-mobile {
@media only screen and (max-width: 500px) {
display: none;
}
}
&.show {
display: none;
@media only screen and (max-width: 500px) {
display: flex;
}
}
&.active {
font-weight: 600;
opacity: 1;
}
}
}
}
.sidenav-content {
width: 100%;
overflow-x: auto;
}
@media only screen and (min-width: 824px) {
grid-template-columns: 1fr 1fr 1fr 1fr;
.sidenav-content {
grid-column-start: 2;
grid-column-end: 5;
}
}
}
}
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SidenavComponent } from './sidenav.component';
describe('SidenavComponent', () => {
let component: SidenavComponent;
let fixture: ComponentFixture<SidenavComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SidenavComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(SidenavComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,42 @@
import { Component, forwardRef, Input } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
export interface SidenavSetting {
id: string;
i18nKey: string;
featureRequired: string[] | false;
}
@Component({
selector: 'cnsl-sidenav',
templateUrl: './sidenav.component.html',
styleUrls: ['./sidenav.component.scss'],
providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SidenavComponent), multi: true }],
})
export class SidenavComponent {
@Input() public currentSetting: string | undefined = 'general';
@Input() public settingsList: SidenavSetting[] = [];
constructor() {}
private onChange: any = () => {};
private onTouch: any = () => {};
set value(setting: string | undefined) {
this.currentSetting = setting;
this.onChange(setting);
this.onTouch(setting);
}
public writeValue(value: any) {
this.value = value;
}
public registerOnChange(fn: any) {
this.onChange = fn;
}
public registerOnTouched(fn: any) {
this.onTouch = fn;
}
}
@@ -0,0 +1,13 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatIconModule } from '@angular/material/icon';
import { TranslateModule } from '@ngx-translate/core';
import { SidenavComponent } from './sidenav.component';
@NgModule({
declarations: [SidenavComponent],
imports: [CommonModule, MatIconModule, TranslateModule],
exports: [SidenavComponent],
})
export class SidenavModule {}