add part support for sidenavs

This commit is contained in:
rubikscraft
2022-03-16 15:59:06 +01:00
parent 0dce5fa108
commit ac41a3f9c0
43 changed files with 477 additions and 337 deletions

View File

@@ -1,5 +1,26 @@
<ng-template #content>
<div class="header-spacer"></div>
<div class="grow-full" [class.container]="containerWrap">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
</ng-template>
<!-- Actual page -->
<app-header></app-header>
<div class="grow-full">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
<mat-sidenav-container *ngIf="sidebarPortal !== undefined" class="grow-full">
<mat-sidenav mode="side" [opened]="!isMobile">
<ng-template [cdkPortalOutlet]="sidebarPortal"></ng-template>
</mat-sidenav>
<mat-sidenav-content>
<div class="sidenav-content" [class.container]="containerWrap">
<ng-container *ngTemplateOutlet="content"></ng-container>
</div>
</mat-sidenav-content>
</mat-sidenav-container>
<ng-container *ngIf="sidebarPortal === undefined">
<ng-container *ngTemplateOutlet="content"></ng-container>
</ng-container>

View File

@@ -2,3 +2,19 @@
flex-grow: 1;
}
.header-spacer {
height: 64px;
margin-bottom: 32px;
flex-shrink: 0; // why, what, wtf flexbox
}
.sidebar-mobile {
position: fixed;
z-index: 2;
}
.sidenav-content {
display: flex;
flex-direction: column;
height: 100%;
}

View File

@@ -1,4 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { BreakpointObserver } from '@angular/cdk/layout';
import { ComponentPortal, Portal } from '@angular/cdk/portal';
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
import {
ActivatedRoute,
NavigationEnd,
@@ -6,6 +9,7 @@ import {
Router
} from '@angular/router';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import { PRouteData } from './models/picsur-routes';
@Component({
selector: 'app-root',
@@ -15,24 +19,64 @@ import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
export class AppComponent implements OnInit {
private readonly logger = console;
constructor(private router: Router, private activatedRoute: ActivatedRoute) {}
@ViewChild(MatSidenav) snav: MatSidenav;
containerWrap: boolean = true;
sidebarPortal: Portal<any> | undefined = undefined;
isMobile: boolean = false;
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
private breakPointObserver: BreakpointObserver
) {}
private get routeData(): PRouteData {
return this.activatedRoute.firstChild?.snapshot.data ?? {};
}
ngOnInit() {
this.subscribeRouter();
this.subscribeMobile();
}
@AutoUnsubscribe()
ngOnInit() {
private subscribeRouter() {
return this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd) this.onNavigationEnd(event);
if (event instanceof NavigationError) this.onNavigationError(event);
});
}
onNavigationEnd(event: NavigationEnd) {
const data = this.activatedRoute.snapshot.data;
console.log('New:', data);
@AutoUnsubscribe()
private subscribeMobile() {
return this.breakPointObserver
.observe(['(min-width: 576px)']) // Bootstrap breakpoints
.subscribe((state) => {
this.isMobile = !state.matches;
});
}
onNavigationError(event: NavigationError) {
private onNavigationEnd(event: NavigationEnd) {
this.reset();
const data = this.routeData;
this.containerWrap = !data.noContainer;
if (data.sidebar !== undefined)
this.sidebarPortal = new ComponentPortal(data.sidebar);
console.log(data)
}
private onNavigationError(event: NavigationError) {
const error: Error = event.error;
if (error.message.startsWith('Cannot match any routes'))
this.router.navigate(['/pagenotfound']);
}
private reset() {
this.containerWrap = true;
this.sidebarPortal = undefined;
}
}

View File

@@ -1,4 +1,7 @@
import { PortalModule } from '@angular/cdk/portal';
import { NgModule } from '@angular/core';
import { MatListModule } from '@angular/material/list';
import { MatSidenavModule } from '@angular/material/sidenav';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
@@ -13,6 +16,9 @@ import { routes } from './routes/routes';
imports: [
BrowserModule,
BrowserAnimationsModule,
PortalModule,
MatSidenavModule,
MatListModule,
GuardsModule,
AppRoutingModule,

View File

@@ -1,7 +1,8 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RouterModule } from '@angular/router';
import { PRoutes } from './models/picsur-routes';
const routes: Routes = [];
const routes: PRoutes = [];
@NgModule({
imports: [

View File

@@ -1,6 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import { InfoService } from 'src/app/api/info.service';
import { InfoService } from 'src/app/services/api/info.service';
@Component({
selector: 'app-footer',

View File

@@ -1,6 +1,6 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ApiModule } from 'src/app/api/api.module';
import { ApiModule } from 'src/app/services/api/api.module';
import { FooterComponent } from './footer.component';

View File

@@ -1,4 +1,4 @@
<mat-toolbar color="primary" class="header">
<mat-toolbar color="primary">
<a [routerLink]="['/']" class="svg-logo">
<img src="/assets/image/logo/picsur.svg" alt="Picsur" />
</a>

View File

@@ -29,16 +29,16 @@ h2 {
text-decoration: inherit;
}
.header {
margin-bottom: 32px;
}
.spacer {
flex-grow: 1;
}
mat-toolbar {
height: 64px;
position: fixed;
/* Make sure the toolbar will stay on top of the content as it scrolls past. */
z-index: 2;
box-shadow: 0px 2px 5px -3px rgba(0, 0, 0, 0.2),
0px 5px 8px 0px rgba(0, 0, 0, 0.14), 0px 1px 14px 0px rgba(0, 0, 0, 0.12);
}

View File

@@ -4,9 +4,9 @@ import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import { Permission, Permissions } from 'picsur-shared/dist/dto/permissions';
import { EUser } from 'picsur-shared/dist/entities/user.entity';
import { HasFailed } from 'picsur-shared/dist/types';
import { PermissionService } from 'src/app/api/permission.service';
import { UserService } from 'src/app/api/user.service';
import { SnackBarType } from 'src/app/models/snack-bar-type';
import { PermissionService } from 'src/app/services/api/permission.service';
import { UserService } from 'src/app/services/api/user.service';
import { UtilService } from 'src/app/util/util.service';
@Component({

View File

@@ -5,7 +5,7 @@ import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatToolbarModule } from '@angular/material/toolbar';
import { RouterModule } from '@angular/router';
import { ApiModule } from 'src/app/api/api.module';
import { ApiModule } from 'src/app/services/api/api.module';
import { UtilModule } from 'src/app/util/util.module';
import { HeaderComponent } from './header.component';

View File

@@ -1,6 +1,6 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ApiModule } from '../api/api.module';
import { ApiModule } from '../services/api/api.module';
import { PermissionGuard } from './permission.guard';
@NgModule({

View File

@@ -7,7 +7,7 @@ import {
} from '@angular/router';
import { Permissions } from 'picsur-shared/dist/dto/permissions';
import { isPermissionsArray } from 'picsur-shared/dist/util/permissions';
import { PermissionService } from '../api/permission.service';
import { PermissionService } from '../services/api/permission.service';
@Injectable({
providedIn: 'root',

View File

@@ -0,0 +1,15 @@
import { ComponentType } from '@angular/cdk/portal';
import { Route } from '@angular/router';
import { Permissions } from 'picsur-shared/dist/dto/permissions';
export type PRouteData = {
permissions?: Permissions;
noContainer?: boolean;
sidebar?: ComponentType<unknown>;
};
export type PRoute = Route & {
data?: PRouteData;
};
export type PRoutes = PRoute[];

View File

@@ -0,0 +1 @@
<p>admin-sidebar works!</p>

View File

@@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-admin-sidebar',
templateUrl: './admin-sidebar.component.html',
styleUrls: ['./admin-sidebar.component.scss']
})
export class AdminSidebarComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@@ -1,11 +1,16 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { AdminSidebarComponent } from './admin-sidebar/admin-sidebar.component';
import { AdminRoutingModule } from './admin.routing.module';
import { AdminComponent } from './admin/admin.component';
@NgModule({
declarations: [AdminComponent],
imports: [CommonModule, AdminRoutingModule, MatProgressSpinnerModule],
declarations: [AdminComponent, AdminSidebarComponent],
imports: [
CommonModule,
AdminRoutingModule,
MatProgressSpinnerModule,
],
})
export class AdminRouteModule {}

View File

@@ -1,11 +1,16 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RouterModule } from '@angular/router';
import { PRoutes } from 'src/app/models/picsur-routes';
import { AdminSidebarComponent } from './admin-sidebar/admin-sidebar.component';
import { AdminComponent } from './admin/admin.component';
const routes: Routes = [
const routes: PRoutes = [
{
path: 'admin',
component: AdminComponent,
data: {
sidebar: AdminSidebarComponent,
},
},
];

View File

@@ -1,11 +1,18 @@
import { Component, OnInit } from '@angular/core';
import {
Component,
OnInit
} from '@angular/core';
@Component({
templateUrl: './admin.component.html',
styleUrls: ['./admin.component.scss'],
})
export class AdminComponent implements OnInit {
constructor() {}
ngOnInit(): void {}
constructor(
) {}
ngOnInit(): void {
console.log('AdminComponent');
}
}

View File

@@ -1,8 +1,9 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RouterModule } from '@angular/router';
import { PRoutes } from 'src/app/models/picsur-routes';
import { PageNotFoundComponent } from './pagenotfound.component';
const routes: Routes = [
const routes: PRoutes = [
{
path: 'pagenotfound',
component: PageNotFoundComponent,

View File

@@ -1,8 +1,8 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { HasFailed } from 'picsur-shared/dist/types';
import { ImageService } from 'src/app/api/image.service';
import { ProcessingViewMetadata } from 'src/app/models/processing-view-metadata';
import { ImageService } from 'src/app/services/api/image.service';
import { UtilService } from 'src/app/util/util.service';
@Component({

View File

@@ -1,8 +1,9 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RouterModule } from '@angular/router';
import { PRoutes } from 'src/app/models/picsur-routes';
import { ProcessingComponent } from './processing.component';
const routes: Routes = [
const routes: PRoutes = [
{
path: 'processing',
component: ProcessingComponent,

View File

@@ -3,7 +3,7 @@ import { Router } from '@angular/router';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import { NgxDropzoneChangeEvent } from 'ngx-dropzone';
import { Permission, Permissions } from 'picsur-shared/dist/dto/permissions';
import { PermissionService } from 'src/app/api/permission.service';
import { PermissionService } from 'src/app/services/api/permission.service';
import { UtilService } from 'src/app/util/util.service';
import { ProcessingViewMetadata } from '../../models/processing-view-metadata';

View File

@@ -1,8 +1,9 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RouterModule } from '@angular/router';
import { PRoutes } from 'src/app/models/picsur-routes';
import { UploadComponent } from './upload.component';
const routes: Routes = [
const routes: PRoutes = [
{
path: '',
component: UploadComponent,

View File

@@ -3,9 +3,9 @@ import { Router } from '@angular/router';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import { Permission, Permissions } from 'picsur-shared/dist/dto/permissions';
import { HasFailed } from 'picsur-shared/dist/types';
import { PermissionService } from 'src/app/api/permission.service';
import { UserService } from 'src/app/api/user.service';
import { SnackBarType } from 'src/app/models/snack-bar-type';
import { PermissionService } from 'src/app/services/api/permission.service';
import { UserService } from 'src/app/services/api/user.service';
import { UtilService } from 'src/app/util/util.service';
import { LoginControl } from '../../../models/forms/login.model';
import { UserPassModel } from '../../../models/forms/userpass';

View File

@@ -3,10 +3,10 @@ import { Router } from '@angular/router';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import { Permission, Permissions } from 'picsur-shared/dist/dto/permissions';
import { HasFailed } from 'picsur-shared/dist/types';
import { PermissionService } from 'src/app/api/permission.service';
import { UserService } from 'src/app/api/user.service';
import { UserPassModel } from 'src/app/models/forms/userpass';
import { SnackBarType } from 'src/app/models/snack-bar-type';
import { PermissionService } from 'src/app/services/api/permission.service';
import { UserService } from 'src/app/services/api/user.service';
import { UtilService } from 'src/app/util/util.service';
import { RegisterControl } from '../../../models/forms/register.model';

View File

@@ -1,11 +1,12 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RouterModule } from '@angular/router';
import { Permission } from 'picsur-shared/dist/dto/permissions';
import { PermissionGuard } from 'src/app/guards/permission.guard';
import { PRoutes } from 'src/app/models/picsur-routes';
import { LoginComponent } from './login/login.component';
import { RegisterComponent } from './register/register.component';
const routes: Routes = [
const routes: PRoutes = [
{
path: 'login',
component: LoginComponent,

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { isHash } from 'class-validator';
import { ImageLinks } from 'picsur-shared/dist/dto/imagelinks.dto';
import { HasFailed } from 'picsur-shared/dist/types';
import { ImageService } from 'src/app/api/image.service';
import { ImageService } from 'src/app/services/api/image.service';
import { UtilService } from 'src/app/util/util.service';
@Component({

View File

@@ -1,10 +1,11 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RouterModule } from '@angular/router';
import { Permission } from 'picsur-shared/dist/dto/permissions';
import { PermissionGuard } from 'src/app/guards/permission.guard';
import { PRoutes } from 'src/app/models/picsur-routes';
import { ViewComponent } from './view.component';
const routes: Routes = [
const routes: PRoutes = [
{
path: 'view/:hash',
component: ViewComponent,

View File

@@ -6,7 +6,7 @@ import {
ApiSuccessResponse
} from 'picsur-shared/dist/dto/api';
import { AsyncFailable, Fail, HasFailed } from 'picsur-shared/dist/types';
import { MultiPartRequest } from '../models/multi-part-request';
import { MultiPartRequest } from '../../models/multi-part-request';
import { KeyService } from './key.service';
@Injectable({

View File

@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { ImageMetaResponse } from 'picsur-shared/dist/dto/api/image.dto';
import { EImage } from 'picsur-shared/dist/entities/image.entity';
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types';
import { ImageUploadRequest } from '../models/image-upload-request';
import { ImageUploadRequest } from '../../models/image-upload-request';
import { ApiService } from './api.service';
@Injectable({

View File

@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { InfoResponse } from 'picsur-shared/dist/dto/api/info.dto';
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types';
import { BehaviorSubject } from 'rxjs';
import { ServerInfo } from '../models/server-info';
import { ServerInfo } from '../../models/server-info';
import { ApiService } from './api.service';
@Injectable({

2
frontend/src/scss/bootstrap.scss vendored Normal file
View File

@@ -0,0 +1,2 @@
// Include bootstrap-grid.scss from node_modules
@import "../node_modules/bootstrap/scss/bootstrap-grid.scss";

View File

@@ -1,3 +1,29 @@
html,
body {
height: 100%;
}
app-root {
height: 100%;
display: flex;
flex-direction: column;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
-webkit-transition: 0.2s;
-moz-transition: 0.2s;
-o-transition: 0.2s;
transition: 0.2s;
}
.mat-icon {
// Yes yes, !important is here, deal with it
// If someone wants to properly figure out why icons are escaping their 24px box, feel free to

View File

@@ -1,3 +1,5 @@
@import "./material-theme.scss";
@import "./bootstrap.scss";
@import "./fixes.scss";
@import "./personal.scss";
@import "./snackbar.scss";
@import "./fixes.scss";

View File

@@ -0,0 +1,252 @@
/**
* Generated theme by Material Theme Generator
* https://materialtheme.arcsine.dev
* Fork at: https://materialtheme.arcsine.dev/?c=YHBhbGV0dGU$YHByaW1hcnk$YF48IzI3MjcyNyIsIj9lcjwjYmViZWJlIiwiO2VyPCMxNzE3MTd$LCIlPmBePCM0M2EwNDciLCI~ZXI8I2M3ZTNjOCIsIjtlcjwjMmM4NDJmfiwid2Fybj5gXjwjZjQ1MTFlIiwiP2VyPCNmY2NiYmMiLCI7ZXI8I2VmMzcxMn4sIj9UZXh0PCMwMDAwMDAiLCI~PTwjZmFmYWZhIiwiO1RleHQ8I2ZmZmZmZiIsIjs9PCMxMjEyMTJ$LCJmb250cz5bYEA8KC00fixgQDwoLTN$LGBAPCgtMn4sYEA8KC0xfixgQDxoZWFkbGluZX4sYEA8dGl0bGV$LGBAPHN1YiktMn4sYEA8c3ViKS0xfixgQDxib2R5LTJ$LGBAPGJvZHktMX4sYEA8YnV0dG9ufixgQDxjYXB0aW9ufixgQDxpbnB1dCIsInNpemU$bnVsbH1dLCJpY29uczxSb3VuZGVkIiwiP25lc3M$ZmFsc2UsInZlcnNpb24$MTF9
*/
@import "~@angular/material/theming";
// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Fonts
@import "https://fonts.googleapis.com/icon?family=Material+Icons+Round";
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap");
$fontConfig: (
display-4: mat-typography-level(112px, 112px, 300, "Roboto", -0.0134em),
display-3: mat-typography-level(56px, 56px, 400, "Roboto", -0.0089em),
display-2: mat-typography-level(45px, 48px, 400, "Roboto", 0em),
display-1: mat-typography-level(34px, 40px, 400, "Roboto", 0.0074em),
headline: mat-typography-level(24px, 32px, 400, "Roboto", 0em),
title: mat-typography-level(20px, 32px, 500, "Roboto", 0.0075em),
subheading-2: mat-typography-level(16px, 28px, 400, "Roboto", 0.0094em),
subheading-1: mat-typography-level(15px, 24px, 500, "Roboto", 0.0067em),
body-2: mat-typography-level(14px, 24px, 500, "Roboto", 0.0179em),
body-1: mat-typography-level(14px, 20px, 400, "Roboto", 0.0179em),
button: mat-typography-level(14px, 14px, 500, "Roboto", 0.0893em),
caption: mat-typography-level(12px, 20px, 400, "Roboto", 0.0333em),
input: mat-typography-level(inherit, 1.125, 400, "Roboto", 1.5px),
);
// Foreground Elements
// Light Theme Text
$dark-text: #000000;
$dark-primary-text: rgba($dark-text, 0.87);
$dark-accent-text: rgba($dark-primary-text, 0.54);
$dark-disabled-text: rgba($dark-primary-text, 0.38);
$dark-dividers: rgba($dark-primary-text, 0.12);
$dark-focused: rgba($dark-primary-text, 0.12);
$mat-light-theme-foreground-palette: (
base: black,
divider: $dark-dividers,
dividers: $dark-dividers,
disabled: $dark-disabled-text,
disabled-button: rgba($dark-text, 0.26),
disabled-text: $dark-disabled-text,
elevation: black,
secondary-text: $dark-accent-text,
hint-text: $dark-disabled-text,
accent-text: $dark-accent-text,
icon: $dark-accent-text,
icons: $dark-accent-text,
text: $dark-primary-text,
slider-min: $dark-primary-text,
slider-off: rgba($dark-text, 0.26),
slider-off-active: $dark-disabled-text,
);
// Dark Theme text
$light-text: #ffffff;
$light-primary-text: $light-text;
$light-accent-text: rgba($light-primary-text, 0.7);
$light-disabled-text: rgba($light-primary-text, 0.5);
$light-dividers: rgba($light-primary-text, 0.12);
$light-focused: rgba($light-primary-text, 0.12);
$mat-dark-theme-foreground-palette: (
base: $light-text,
divider: $light-dividers,
dividers: $light-dividers,
disabled: $light-disabled-text,
disabled-button: rgba($light-text, 0.3),
disabled-text: $light-disabled-text,
elevation: black,
hint-text: $light-disabled-text,
secondary-text: $light-accent-text,
accent-text: $light-accent-text,
icon: $light-text,
icons: $light-text,
text: $light-text,
slider-min: $light-text,
slider-off: rgba($light-text, 0.3),
slider-off-active: rgba($light-text, 0.3),
);
// Background config
// Light bg
$light-background: #fafafa;
$light-bg-darker-5: darken($light-background, 5%);
$light-bg-darker-10: darken($light-background, 10%);
$light-bg-darker-20: darken($light-background, 20%);
$light-bg-darker-30: darken($light-background, 30%);
$light-bg-lighter-5: lighten($light-background, 5%);
$dark-bg-tooltip: lighten(#121212, 20%);
$dark-bg-alpha-4: rgba(#121212, 0.04);
$dark-bg-alpha-12: rgba(#121212, 0.12);
$mat-light-theme-background-palette: (
background: $light-background,
status-bar: $light-bg-darker-20,
app-bar: $light-bg-darker-5,
hover: $dark-bg-alpha-4,
card: $light-bg-lighter-5,
dialog: $light-bg-lighter-5,
tooltip: $dark-bg-tooltip,
disabled-button: $dark-bg-alpha-12,
raised-button: $light-bg-lighter-5,
focused-button: $dark-focused,
selected-button: $light-bg-darker-20,
selected-disabled-button: $light-bg-darker-30,
disabled-button-toggle: $light-bg-darker-10,
unselected-chip: $light-bg-darker-10,
disabled-list-option: $light-bg-darker-10,
);
// Dark bg
$dark-background: #121212;
$dark-bg-lighter-5: lighten($dark-background, 5%);
$dark-bg-lighter-10: lighten($dark-background, 10%);
$dark-bg-lighter-20: lighten($dark-background, 20%);
$dark-bg-lighter-30: lighten($dark-background, 30%);
$light-bg-alpha-4: rgba(#fafafa, 0.04);
$light-bg-alpha-12: rgba(#fafafa, 0.12);
// Background palette for dark themes.
$mat-dark-theme-background-palette: (
background: $dark-background,
status-bar: $dark-bg-lighter-20,
app-bar: $dark-bg-lighter-5,
hover: $light-bg-alpha-4,
card: $dark-bg-lighter-5,
dialog: $dark-bg-lighter-5,
tooltip: $dark-bg-lighter-20,
disabled-button: $light-bg-alpha-12,
raised-button: $dark-bg-lighter-5,
focused-button: $light-focused,
selected-button: $dark-bg-lighter-20,
selected-disabled-button: $dark-bg-lighter-30,
disabled-button-toggle: $dark-bg-lighter-10,
unselected-chip: $dark-bg-lighter-20,
disabled-list-option: $dark-bg-lighter-10,
);
// Compute font config
@include mat-core($fontConfig);
// Theme Config
body {
--primary-color: #272727;
--primary-lighter-color: #bebebe;
--primary-darker-color: #171717;
--text-primary-color: #{$light-primary-text};
--text-primary-lighter-color: #{$dark-primary-text};
--text-primary-darker-color: #{$light-primary-text};
}
$mat-primary: (
main: #272727,
lighter: #bebebe,
darker: #171717,
200: #272727,
// For slide toggle,
contrast:
(
main: $light-primary-text,
lighter: $dark-primary-text,
darker: $light-primary-text,
),
);
$theme-primary: mat-palette($mat-primary, main, lighter, darker);
body {
--accent-color: #43a047;
--accent-lighter-color: #c7e3c8;
--accent-darker-color: #2c842f;
--text-accent-color: #{$light-primary-text};
--text-accent-lighter-color: #{$dark-primary-text};
--text-accent-darker-color: #{$light-primary-text};
}
$mat-accent: (
main: #43a047,
lighter: #c7e3c8,
darker: #2c842f,
200: #43a047,
// For slide toggle,
contrast:
(
main: $light-primary-text,
lighter: $dark-primary-text,
darker: $light-primary-text,
),
);
$theme-accent: mat-palette($mat-accent, main, lighter, darker);
body {
--warn-color: #f4511e;
--warn-lighter-color: #fccbbc;
--warn-darker-color: #ef3712;
--text-warn-color: #{$light-primary-text};
--text-warn-lighter-color: #{$dark-primary-text};
--text-warn-darker-color: #{$light-primary-text};
}
$mat-warn: (
main: #f4511e,
lighter: #fccbbc,
darker: #ef3712,
200: #f4511e,
// For slide toggle,
contrast:
(
main: $light-primary-text,
lighter: $dark-primary-text,
darker: $light-primary-text,
),
);
$theme-warn: mat-palette($mat-warn, main, lighter, darker);
$theme: mat-dark-theme($theme-primary, $theme-accent, $theme-warn);
$altTheme: mat-light-theme($theme-primary, $theme-accent, $theme-warn);
// Theme Init
@include angular-material-theme($theme);
.theme-alternate {
@include angular-material-theme($altTheme);
}
// Specific component overrides, pieces that are not in line with the general theming
// Handle buttons appropriately, with respect to line-height
.mat-raised-button,
.mat-stroked-button,
.mat-flat-button {
padding: 0 1.15em;
margin: 0 0.65em;
min-width: 3em;
line-height: 36.4px;
}
.mat-standard-chip {
padding: 0.5em 0.85em;
min-height: 2.5em;
}
.material-icons {
font-size: 24px;
font-family: "Material Icons Round", "Material Icons";
.mat-badge-content {
font-family: "Roboto";
}
}

View File

@@ -1,284 +1 @@
/**
* Generated theme by Material Theme Generator
* https://materialtheme.arcsine.dev
* Fork at: https://materialtheme.arcsine.dev/?c=YHBhbGV0dGU$YHByaW1hcnk$YF48IzI3MjcyNyIsIj9lcjwjYmViZWJlIiwiO2VyPCMxNzE3MTd$LCIlPmBePCM0M2EwNDciLCI~ZXI8I2M3ZTNjOCIsIjtlcjwjMmM4NDJmfiwid2Fybj5gXjwjZjQ1MTFlIiwiP2VyPCNmY2NiYmMiLCI7ZXI8I2VmMzcxMn4sIj9UZXh0PCMwMDAwMDAiLCI~PTwjZmFmYWZhIiwiO1RleHQ8I2ZmZmZmZiIsIjs9PCMxMjEyMTJ$LCJmb250cz5bYEA8KC00fixgQDwoLTN$LGBAPCgtMn4sYEA8KC0xfixgQDxoZWFkbGluZX4sYEA8dGl0bGV$LGBAPHN1YiktMn4sYEA8c3ViKS0xfixgQDxib2R5LTJ$LGBAPGJvZHktMX4sYEA8YnV0dG9ufixgQDxjYXB0aW9ufixgQDxpbnB1dCIsInNpemU$bnVsbH1dLCJpY29uczxSb3VuZGVkIiwiP25lc3M$ZmFsc2UsInZlcnNpb24$MTF9
*/
@import "~@angular/material/theming";
// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Fonts
@import "https://fonts.googleapis.com/icon?family=Material+Icons+Round";
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap");
$fontConfig: (
display-4: mat-typography-level(112px, 112px, 300, "Roboto", -0.0134em),
display-3: mat-typography-level(56px, 56px, 400, "Roboto", -0.0089em),
display-2: mat-typography-level(45px, 48px, 400, "Roboto", 0em),
display-1: mat-typography-level(34px, 40px, 400, "Roboto", 0.0074em),
headline: mat-typography-level(24px, 32px, 400, "Roboto", 0em),
title: mat-typography-level(20px, 32px, 500, "Roboto", 0.0075em),
subheading-2: mat-typography-level(16px, 28px, 400, "Roboto", 0.0094em),
subheading-1: mat-typography-level(15px, 24px, 500, "Roboto", 0.0067em),
body-2: mat-typography-level(14px, 24px, 500, "Roboto", 0.0179em),
body-1: mat-typography-level(14px, 20px, 400, "Roboto", 0.0179em),
button: mat-typography-level(14px, 14px, 500, "Roboto", 0.0893em),
caption: mat-typography-level(12px, 20px, 400, "Roboto", 0.0333em),
input: mat-typography-level(inherit, 1.125, 400, "Roboto", 1.5px),
);
// Foreground Elements
// Light Theme Text
$dark-text: #000000;
$dark-primary-text: rgba($dark-text, 0.87);
$dark-accent-text: rgba($dark-primary-text, 0.54);
$dark-disabled-text: rgba($dark-primary-text, 0.38);
$dark-dividers: rgba($dark-primary-text, 0.12);
$dark-focused: rgba($dark-primary-text, 0.12);
$mat-light-theme-foreground-palette: (
base: black,
divider: $dark-dividers,
dividers: $dark-dividers,
disabled: $dark-disabled-text,
disabled-button: rgba($dark-text, 0.26),
disabled-text: $dark-disabled-text,
elevation: black,
secondary-text: $dark-accent-text,
hint-text: $dark-disabled-text,
accent-text: $dark-accent-text,
icon: $dark-accent-text,
icons: $dark-accent-text,
text: $dark-primary-text,
slider-min: $dark-primary-text,
slider-off: rgba($dark-text, 0.26),
slider-off-active: $dark-disabled-text,
);
// Dark Theme text
$light-text: #ffffff;
$light-primary-text: $light-text;
$light-accent-text: rgba($light-primary-text, 0.7);
$light-disabled-text: rgba($light-primary-text, 0.5);
$light-dividers: rgba($light-primary-text, 0.12);
$light-focused: rgba($light-primary-text, 0.12);
$mat-dark-theme-foreground-palette: (
base: $light-text,
divider: $light-dividers,
dividers: $light-dividers,
disabled: $light-disabled-text,
disabled-button: rgba($light-text, 0.3),
disabled-text: $light-disabled-text,
elevation: black,
hint-text: $light-disabled-text,
secondary-text: $light-accent-text,
accent-text: $light-accent-text,
icon: $light-text,
icons: $light-text,
text: $light-text,
slider-min: $light-text,
slider-off: rgba($light-text, 0.3),
slider-off-active: rgba($light-text, 0.3),
);
// Background config
// Light bg
$light-background: #fafafa;
$light-bg-darker-5: darken($light-background, 5%);
$light-bg-darker-10: darken($light-background, 10%);
$light-bg-darker-20: darken($light-background, 20%);
$light-bg-darker-30: darken($light-background, 30%);
$light-bg-lighter-5: lighten($light-background, 5%);
$dark-bg-tooltip: lighten(#121212, 20%);
$dark-bg-alpha-4: rgba(#121212, 0.04);
$dark-bg-alpha-12: rgba(#121212, 0.12);
$mat-light-theme-background-palette: (
background: $light-background,
status-bar: $light-bg-darker-20,
app-bar: $light-bg-darker-5,
hover: $dark-bg-alpha-4,
card: $light-bg-lighter-5,
dialog: $light-bg-lighter-5,
tooltip: $dark-bg-tooltip,
disabled-button: $dark-bg-alpha-12,
raised-button: $light-bg-lighter-5,
focused-button: $dark-focused,
selected-button: $light-bg-darker-20,
selected-disabled-button: $light-bg-darker-30,
disabled-button-toggle: $light-bg-darker-10,
unselected-chip: $light-bg-darker-10,
disabled-list-option: $light-bg-darker-10,
);
// Dark bg
$dark-background: #121212;
$dark-bg-lighter-5: lighten($dark-background, 5%);
$dark-bg-lighter-10: lighten($dark-background, 10%);
$dark-bg-lighter-20: lighten($dark-background, 20%);
$dark-bg-lighter-30: lighten($dark-background, 30%);
$light-bg-alpha-4: rgba(#fafafa, 0.04);
$light-bg-alpha-12: rgba(#fafafa, 0.12);
// Background palette for dark themes.
$mat-dark-theme-background-palette: (
background: $dark-background,
status-bar: $dark-bg-lighter-20,
app-bar: $dark-bg-lighter-5,
hover: $light-bg-alpha-4,
card: $dark-bg-lighter-5,
dialog: $dark-bg-lighter-5,
tooltip: $dark-bg-lighter-20,
disabled-button: $light-bg-alpha-12,
raised-button: $dark-bg-lighter-5,
focused-button: $light-focused,
selected-button: $dark-bg-lighter-20,
selected-disabled-button: $dark-bg-lighter-30,
disabled-button-toggle: $dark-bg-lighter-10,
unselected-chip: $dark-bg-lighter-20,
disabled-list-option: $dark-bg-lighter-10,
);
// Compute font config
@include mat-core($fontConfig);
// Theme Config
body {
--primary-color: #272727;
--primary-lighter-color: #bebebe;
--primary-darker-color: #171717;
--text-primary-color: #{$light-primary-text};
--text-primary-lighter-color: #{$dark-primary-text};
--text-primary-darker-color: #{$light-primary-text};
}
$mat-primary: (
main: #272727,
lighter: #bebebe,
darker: #171717,
200: #272727,
// For slide toggle,
contrast:
(
main: $light-primary-text,
lighter: $dark-primary-text,
darker: $light-primary-text,
),
);
$theme-primary: mat-palette($mat-primary, main, lighter, darker);
body {
--accent-color: #43a047;
--accent-lighter-color: #c7e3c8;
--accent-darker-color: #2c842f;
--text-accent-color: #{$light-primary-text};
--text-accent-lighter-color: #{$dark-primary-text};
--text-accent-darker-color: #{$light-primary-text};
}
$mat-accent: (
main: #43a047,
lighter: #c7e3c8,
darker: #2c842f,
200: #43a047,
// For slide toggle,
contrast:
(
main: $light-primary-text,
lighter: $dark-primary-text,
darker: $light-primary-text,
),
);
$theme-accent: mat-palette($mat-accent, main, lighter, darker);
body {
--warn-color: #f4511e;
--warn-lighter-color: #fccbbc;
--warn-darker-color: #ef3712;
--text-warn-color: #{$light-primary-text};
--text-warn-lighter-color: #{$dark-primary-text};
--text-warn-darker-color: #{$light-primary-text};
}
$mat-warn: (
main: #f4511e,
lighter: #fccbbc,
darker: #ef3712,
200: #f4511e,
// For slide toggle,
contrast:
(
main: $light-primary-text,
lighter: $dark-primary-text,
darker: $light-primary-text,
),
);
$theme-warn: mat-palette($mat-warn, main, lighter, darker);
$theme: mat-dark-theme($theme-primary, $theme-accent, $theme-warn);
$altTheme: mat-light-theme($theme-primary, $theme-accent, $theme-warn);
// Theme Init
@include angular-material-theme($theme);
.theme-alternate {
@include angular-material-theme($altTheme);
}
// Specific component overrides, pieces that are not in line with the general theming
// Handle buttons appropriately, with respect to line-height
.mat-raised-button,
.mat-stroked-button,
.mat-flat-button {
padding: 0 1.15em;
margin: 0 0.65em;
min-width: 3em;
line-height: 36.4px;
}
.mat-standard-chip {
padding: 0.5em 0.85em;
min-height: 2.5em;
}
.material-icons {
font-size: 24px;
font-family: "Material Icons Round", "Material Icons";
.mat-badge-content {
font-family: "Roboto";
}
}
// Include bootstrap-grid.scss from node_modules
@import "../node_modules/bootstrap/scss/bootstrap-grid.scss";
html,
body {
height: 100%;
}
app-root {
height: 100%;
display: flex;
flex-direction: column;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
-webkit-transition: 0.2s;
-moz-transition: 0.2s;
-o-transition: 0.2s;
transition: 0.2s;
}
@import "./scss";

View File

@@ -19,7 +19,7 @@
"importHelpers": true
},
"files": ["src/main.ts", "src/polyfills.ts"],
"include": ["src/**/*.d.ts", "src/**/*.ts"],
"include": ["src/**/*.d.ts", "src/app/**/*.ts"],
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,