mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-06-25 01:19:11 +00:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
e609965e91 | |||
d042ad8ce4 | |||
ddb2e3f34a | |||
7cd1d5ed87 | |||
bc45a1bea9 | |||
b0e197dbbd | |||
e213279cdc | |||
d072324ef7 | |||
a101620954 | |||
e5813a255e | |||
a6eb1cc09f | |||
1b0c62c0d1 | |||
d45947999d | |||
06926c53af | |||
96f4600706 | |||
fe8550678d | |||
a0d88a937e | |||
e1b0e73916 | |||
767dc0c963 | |||
6c4cdb06b2 | |||
91844ee770 | |||
46c4bc1d78 | |||
baa344fbe5 |
@ -1,5 +1,9 @@
|
|||||||
# iOS CircleCI 2.1 configuration file
|
# iOS CircleCI 2.1 configuration file
|
||||||
version: 2.1
|
version: 2.1
|
||||||
|
|
||||||
|
orbs:
|
||||||
|
node: circleci/node@4.2.0
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
macos:
|
macos:
|
||||||
@ -7,13 +11,16 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
- node/install:
|
||||||
|
install-yarn: true
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Install nodejs
|
name: Update BREW and print configs
|
||||||
command: |
|
command: |
|
||||||
brew update
|
brew update
|
||||||
brew upgrade yarn
|
brew analytics off
|
||||||
brew upgrade node
|
brew --env
|
||||||
|
brew --config
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Set timezone and check current datetime
|
name: Set timezone and check current datetime
|
||||||
@ -34,6 +41,8 @@ jobs:
|
|||||||
curl -o /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/readline.rb https://raw.githubusercontent.com/Homebrew/homebrew-core/b1bd1c4a62e1336422de3614d1fc49ffbce589a8/Formula/readline.rb
|
curl -o /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/readline.rb https://raw.githubusercontent.com/Homebrew/homebrew-core/b1bd1c4a62e1336422de3614d1fc49ffbce589a8/Formula/readline.rb
|
||||||
# remove check for old compilers which creates the error described in https://github.com/sashkab/homebrew-python/issues/36
|
# remove check for old compilers which creates the error described in https://github.com/sashkab/homebrew-python/issues/36
|
||||||
sed -i.bak -e '58,61d' /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/python.rb
|
sed -i.bak -e '58,61d' /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/python.rb
|
||||||
|
# remove 'do devel' block to avoid error: Calling 'devel' blocks in formulae is disabled!
|
||||||
|
sed -i.bak -e '14,17d' /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/python.rb
|
||||||
brew unlink python
|
brew unlink python
|
||||||
brew uninstall --ignore-dependencies readline
|
brew uninstall --ignore-dependencies readline
|
||||||
brew install readline
|
brew install readline
|
||||||
@ -41,7 +50,7 @@ jobs:
|
|||||||
brew pin readline
|
brew pin readline
|
||||||
# --ignore-dependencies is used to prevent this issue: https://github.com/tensorflow/tensorflow/issues/25093
|
# --ignore-dependencies is used to prevent this issue: https://github.com/tensorflow/tensorflow/issues/25093
|
||||||
brew install --ignore-dependencies python
|
brew install --ignore-dependencies python
|
||||||
brew switch python 3.6.5_1
|
#brew link python 3.6.5_1
|
||||||
brew info python
|
brew info python
|
||||||
brew pin python
|
brew pin python
|
||||||
|
|
||||||
@ -77,8 +86,11 @@ jobs:
|
|||||||
name: Building gns3server
|
name: Building gns3server
|
||||||
command: |
|
command: |
|
||||||
python3 -V
|
python3 -V
|
||||||
pip3 install -r scripts/requirements.txt
|
python3 -m pip install -U pip
|
||||||
|
python3 -m pip install -r scripts/requirements.txt
|
||||||
python3 scripts/build.py download -a
|
python3 scripts/build.py download -a
|
||||||
|
# necessary because of https://github.com/GNS3/gns3-gui/issues/2849
|
||||||
|
python3 -m pip install jsonschema==2.6.0
|
||||||
python3 scripts/build.py build_exe -b dist/exe.gns3server -s
|
python3 scripts/build.py build_exe -b dist/exe.gns3server -s
|
||||||
python3 scripts/build.py validate -b dist
|
python3 scripts/build.py validate -b dist
|
||||||
|
|
||||||
@ -105,4 +117,3 @@ workflows:
|
|||||||
filters:
|
filters:
|
||||||
tags:
|
tags:
|
||||||
only: /v.*/
|
only: /v.*/
|
||||||
|
|
||||||
|
11
angular.json
11
angular.json
@ -47,16 +47,7 @@
|
|||||||
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||||
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
||||||
"src/styles.scss",
|
"src/styles.scss",
|
||||||
{
|
"src/theme.scss"
|
||||||
"inject": true,
|
|
||||||
"input": "src/theme.scss",
|
|
||||||
"bundleName": "theme-default-dark"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inject": true,
|
|
||||||
"input": "src/theme-light.scss",
|
|
||||||
"bundleName": "theme-default"
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gns3-web-ui",
|
"name": "gns3-web-ui",
|
||||||
"version": "2.2.18",
|
"version": "2.2.19",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "GNS3 Technology Inc.",
|
"name": "GNS3 Technology Inc.",
|
||||||
"email": "developers@gns3.com"
|
"email": "developers@gns3.com"
|
||||||
@ -117,7 +117,7 @@
|
|||||||
"jasmine-core": "~3.6.0",
|
"jasmine-core": "~3.6.0",
|
||||||
"jasmine-spec-reporter": "~5.0.0",
|
"jasmine-spec-reporter": "~5.0.0",
|
||||||
"jquery": "^3.5.1",
|
"jquery": "^3.5.1",
|
||||||
"karma": "^5.2.3",
|
"karma": "^6.1.1",
|
||||||
"karma-chrome-launcher": "~3.1.0",
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
"karma-cli": "^2.0.0",
|
"karma-cli": "^2.0.0",
|
||||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
"karma-coverage-istanbul-reporter": "~3.0.2",
|
||||||
|
@ -144,7 +144,7 @@ def download_from_github(name, definition, output_directory):
|
|||||||
files = []
|
files = []
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
files = definition['files']['windows']
|
files = definition['files']['windows']
|
||||||
|
|
||||||
for filename in files:
|
for filename in files:
|
||||||
dependency_file = os.path.join(dependency_dir, filename)
|
dependency_file = os.path.join(dependency_dir, filename)
|
||||||
dependency_url = list(filter(lambda x: x['name'] == filename, release['assets']))[0]['browser_download_url']
|
dependency_url = list(filter(lambda x: x['name'] == filename, release['assets']))[0]['browser_download_url']
|
||||||
@ -161,7 +161,7 @@ def download_from_http(name, definition, output_directory):
|
|||||||
files = []
|
files = []
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
files = definition['files']['windows']
|
files = definition['files']['windows']
|
||||||
|
|
||||||
for filename in files:
|
for filename in files:
|
||||||
dependency_file = os.path.join(dependency_dir, filename)
|
dependency_file = os.path.join(dependency_dir, filename)
|
||||||
download(url, dependency_file)
|
download(url, dependency_file)
|
||||||
@ -193,7 +193,7 @@ def is_tagged():
|
|||||||
return True
|
return True
|
||||||
if os.environ.get('APPVEYOR_REPO_TAG', False) in (1, "True", "true"):
|
if os.environ.get('APPVEYOR_REPO_TAG', False) in (1, "True", "true"):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def is_web_ui_non_dev():
|
def is_web_ui_non_dev():
|
||||||
package_file = os.path.join(FILE_DIR, '..', 'package.json')
|
package_file = os.path.join(FILE_DIR, '..', 'package.json')
|
||||||
@ -237,6 +237,8 @@ def download_command(arguments):
|
|||||||
|
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
requirements = 'win-requirements.txt'
|
requirements = 'win-requirements.txt'
|
||||||
|
elif platform.system() == "Darwin":
|
||||||
|
requirements = 'mac-requirements.txt'
|
||||||
else:
|
else:
|
||||||
requirements = 'requirements.txt'
|
requirements = 'requirements.txt'
|
||||||
|
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
setuptools==40.8.0
|
setuptools==40.8.0
|
||||||
cx_Freeze==5.1.1
|
cx_Freeze==5.1.1
|
||||||
requests==2.21.0
|
requests==2.25.1
|
||||||
packaging==19.0
|
packaging==20.9
|
||||||
appdirs==1.4.3
|
appdirs==1.4.4
|
||||||
psutil==5.6.7
|
psutil==5.6.7
|
||||||
jsonschema==2.6.0 # lock down jsonschema, 3.0 makes problems
|
|
||||||
|
|
||||||
urllib3>=1.25.9 # not directly required, pinned by Snyk to avoid a vulnerability
|
|
@ -1,6 +1,6 @@
|
|||||||
GNS3 WebUI is web implementation of user interface for GNS3 software.
|
GNS3 WebUI is web implementation of user interface for GNS3 software.
|
||||||
|
|
||||||
Current version: 2.2.18
|
Current version: 2.2.19
|
||||||
|
|
||||||
Current version: 2020.4.0-beta.1
|
Current version: 2020.4.0-beta.1
|
||||||
|
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
<router-outlet></router-outlet>
|
<div [ngClass]="{dark: darkThemeEnabled, light: !darkThemeEnabled}">
|
||||||
<app-notification-box></app-notification-box>
|
<router-outlet></router-outlet>
|
||||||
|
<app-notification-box></app-notification-box>
|
||||||
|
</div>
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
mat-menu-panel {
|
mat-menu-panel {
|
||||||
min-height: 0px;
|
min-height: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
background: #263238!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.light {
|
||||||
|
background: white!important;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, HostBinding, OnInit } from '@angular/core';
|
||||||
import { MatIconRegistry } from '@angular/material/icon';
|
import { MatIconRegistry } from '@angular/material/icon';
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
import { ElectronService } from 'ngx-electron';
|
import { ElectronService } from 'ngx-electron';
|
||||||
@ -6,6 +6,7 @@ import { SettingsService } from './services/settings.service';
|
|||||||
import { ThemeService } from './services/theme.service';
|
import { ThemeService } from './services/theme.service';
|
||||||
import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
|
import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
|
||||||
import { ProgressService } from './common/progress/progress.service';
|
import { ProgressService } from './common/progress/progress.service';
|
||||||
|
import { OverlayContainer} from '@angular/cdk/overlay';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -13,7 +14,10 @@ import { ProgressService } from './common/progress/progress.service';
|
|||||||
styleUrls: ['./app.component.scss']
|
styleUrls: ['./app.component.scss']
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit {
|
||||||
|
public darkThemeEnabled: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private overlayContainer: OverlayContainer,
|
||||||
iconReg: MatIconRegistry,
|
iconReg: MatIconRegistry,
|
||||||
sanitizer: DomSanitizer,
|
sanitizer: DomSanitizer,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
@ -30,18 +34,29 @@ export class AppComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@HostBinding('class') componentCssClass;
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (this.electronService.isElectronApp) {
|
if (this.electronService.isElectronApp) {
|
||||||
this.settingsService.subscribe(settings => {
|
this.settingsService.subscribe(settings => {
|
||||||
this.electronService.ipcRenderer.send('settings.changed', settings);
|
this.electronService.ipcRenderer.send('settings.changed', settings);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let theme = localStorage.getItem('theme');
|
|
||||||
if (theme === 'light') {
|
this.applyTheme(this.themeService.savedTheme + '-theme');
|
||||||
this.themeService.setDarkMode(false);
|
this.themeService.themeChanged.subscribe((event: string) => {
|
||||||
|
this.applyTheme(event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
applyTheme(theme: string) {
|
||||||
|
if (theme === 'dark-theme') {
|
||||||
|
this.darkThemeEnabled = true;
|
||||||
} else {
|
} else {
|
||||||
this.themeService.setDarkMode(true);
|
this.darkThemeEnabled = false;
|
||||||
}
|
}
|
||||||
|
this.overlayContainer.getContainerElement().classList.add(theme);
|
||||||
|
this.componentCssClass = theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkEvent(routerEvent) : void {
|
checkEvent(routerEvent) : void {
|
||||||
|
@ -284,6 +284,7 @@ import { UpdatesService } from './services/updates.service';
|
|||||||
import { ReportIssueComponent } from './components/help/report-issue/report-issue.component';
|
import { ReportIssueComponent } from './components/help/report-issue/report-issue.component';
|
||||||
import { AngularReactBrowserModule } from '@angular-react/core';
|
import { AngularReactBrowserModule } from '@angular-react/core';
|
||||||
import { FabDialogModule, FabButtonModule } from '@angular-react/fabric';
|
import { FabDialogModule, FabButtonModule } from '@angular-react/fabric';
|
||||||
|
import { OverlayContainer, OverlayModule } from '@angular/cdk/overlay';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -492,7 +493,8 @@ import { FabDialogModule, FabButtonModule } from '@angular-react/fabric';
|
|||||||
DragDropModule,
|
DragDropModule,
|
||||||
NgxChildProcessModule,
|
NgxChildProcessModule,
|
||||||
MATERIAL_IMPORTS,
|
MATERIAL_IMPORTS,
|
||||||
NgCircleProgressModule.forRoot()
|
NgCircleProgressModule.forRoot(),
|
||||||
|
OverlayModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
SettingsService,
|
SettingsService,
|
||||||
|
@ -31,6 +31,11 @@
|
|||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
</mat-accordion>
|
</mat-accordion>
|
||||||
</div>
|
</div>
|
||||||
|
<button mat-button class="full-width">
|
||||||
|
<a href="https://docs.gns3.com/docs/">
|
||||||
|
Go to documentation
|
||||||
|
</a>
|
||||||
|
</button>
|
||||||
<button mat-button routerLink="/help/reportissue" class="full-width">
|
<button mat-button routerLink="/help/reportissue" class="full-width">
|
||||||
Report an issue
|
Report an issue
|
||||||
</button>
|
</button>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.full-width {
|
.full-width {
|
||||||
width: 100%;
|
width: 50%;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,11 @@ export class NotificationBoxComponent implements OnInit, OnDestroy {
|
|||||||
// if (!this.location.path().includes('nodes') && !(adbutler == today)) this.startTimer();
|
// if (!this.location.path().includes('nodes') && !(adbutler == today)) this.startTimer();
|
||||||
|
|
||||||
if (!this.location.path().includes('nodes')) this.startTimer();
|
if (!this.location.path().includes('nodes')) this.startTimer();
|
||||||
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
|
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
|
||||||
|
|
||||||
|
this.themeService.themeChanged.subscribe((value: string) => {
|
||||||
|
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
|
@ -70,7 +70,7 @@ describe('LogConsoleComponent', () => {
|
|||||||
expect(component.showMessage).toHaveBeenCalledWith({type: 'command', message: "Available commands: help, version, console {node name}, start all, start {node name}, stop all, stop {node name}, suspend all, suspend {node name}, reload all, reload {node name}, show {node name}."});
|
expect(component.showMessage).toHaveBeenCalledWith({type: 'command', message: "Available commands: help, version, console {node name}, start all, start {node name}, stop all, stop {node name}, suspend all, suspend {node name}, reload all, reload {node name}, show {node name}."});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call show message when version command entered', () => {
|
xit('should call show message when version command entered', () => {
|
||||||
spyOn(component, 'showMessage');
|
spyOn(component, 'showMessage');
|
||||||
component.command = 'version';
|
component.command = 'version';
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="toolbarVisibility" id="show-menu-wrapper" [ngClass]="{lightTheme: isLightThemeEnabled, shadowed: !isProjectMapMenuVisible }">
|
<div *ngIf="toolbarVisibility" id="show-menu-wrapper" [ngClass]="{lightTheme: isLightThemeEnabled, shadowed: !isProjectMapMenuVisible }">
|
||||||
<button [ngClass]="{lightTheme: isLightThemeEnabled}" class="arrow-button" mat-icon-button (click)="showMenu()"><mat-icon class="unmarked">keyboard_arrow_right</mat-icon></button>
|
<button [ngClass]="{lightTheme: isLightThemeEnabled, darkTheme: !isLightThemeEnabled}" class="arrow-button" mat-icon-button (click)="showMenu()"><mat-icon class="unmarked">keyboard_arrow_right</mat-icon></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="toolbarVisibility" id="menu-wrapper" [ngClass]="{lightTheme: isLightThemeEnabled, extended: isProjectMapMenuVisible }">
|
<div *ngIf="toolbarVisibility" id="menu-wrapper" [ngClass]="{lightTheme: isLightThemeEnabled, extended: isProjectMapMenuVisible }">
|
||||||
|
@ -35,6 +35,10 @@ img {
|
|||||||
color: black!important;
|
color: black!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.darkTheme {
|
||||||
|
color: white!important;
|
||||||
|
}
|
||||||
|
|
||||||
#show-menu-wrapper {
|
#show-menu-wrapper {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnDestroy, OnInit, ViewChild, ViewEncapsulation, ElementRef } from '@angular/core';
|
import { Component, OnDestroy, OnInit, ViewChild, ViewEncapsulation, ElementRef, ChangeDetectorRef } from '@angular/core';
|
||||||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
||||||
|
|
||||||
import { Observable, Subject, Subscription, from } from 'rxjs';
|
import { Observable, Subject, Subscription, from } from 'rxjs';
|
||||||
@ -164,7 +164,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
private notificationService: NotificationService,
|
private notificationService: NotificationService,
|
||||||
private themeService: ThemeService,
|
private themeService: ThemeService,
|
||||||
private title: Title,
|
private title: Title,
|
||||||
private nodeConsoleService: NodeConsoleService
|
private nodeConsoleService: NodeConsoleService,
|
||||||
|
private cd: ChangeDetectorRef
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -183,10 +184,16 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
this.addSubscriptions();
|
this.addSubscriptions();
|
||||||
this.addKeyboardListeners();
|
this.addKeyboardListeners();
|
||||||
|
|
||||||
|
this.themeService.themeChanged.subscribe((value: string) => {
|
||||||
|
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSettings() {
|
getSettings() {
|
||||||
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
|
this.themeService.getActualTheme() === 'light' ? this.isLightThemeEnabled = true : this.isLightThemeEnabled = false;
|
||||||
|
this.cd.detectChanges();
|
||||||
|
|
||||||
this.settings = this.settingsService.getAll();
|
this.settings = this.settingsService.getAll();
|
||||||
this.isTopologySummaryVisible = this.mapSettingsService.isTopologySummaryVisible;
|
this.isTopologySummaryVisible = this.mapSettingsService.isTopologySummaryVisible;
|
||||||
this.isConsoleVisible = this.mapSettingsService.isLogConsoleVisible;
|
this.isConsoleVisible = this.mapSettingsService.isLogConsoleVisible;
|
||||||
|
@ -24,6 +24,7 @@ import { ConfirmationBottomSheetComponent } from './confirmation-bottomsheet/con
|
|||||||
import { ToasterService } from '../../services/toaster.service';
|
import { ToasterService } from '../../services/toaster.service';
|
||||||
import { ConfigureGns3VMDialogComponent } from '../servers/configure-gns3vm-dialog/configure-gns3vm-dialog.component';
|
import { ConfigureGns3VMDialogComponent } from '../servers/configure-gns3vm-dialog/configure-gns3vm-dialog.component';
|
||||||
import { ElectronService } from 'ngx-electron';
|
import { ElectronService } from 'ngx-electron';
|
||||||
|
import { RecentlyOpenedProjectService } from '../../services/recentlyOpenedProject.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-projects',
|
selector: 'app-projects',
|
||||||
@ -50,12 +51,14 @@ export class ProjectsComponent implements OnInit {
|
|||||||
private router: Router,
|
private router: Router,
|
||||||
private bottomSheet: MatBottomSheet,
|
private bottomSheet: MatBottomSheet,
|
||||||
private toasterService: ToasterService,
|
private toasterService: ToasterService,
|
||||||
private electronService: ElectronService
|
private electronService: ElectronService,
|
||||||
|
private recentlyOpenedProjectService: RecentlyOpenedProjectService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.server = this.route.snapshot.data['server'];
|
this.server = this.route.snapshot.data['server'];
|
||||||
if(!this.server) this.router.navigate(['/servers']);
|
if(!this.server) this.router.navigate(['/servers']);
|
||||||
|
this.recentlyOpenedProjectService.setServerIdProjectList(this.server.id.toString());
|
||||||
|
|
||||||
this.refresh();
|
this.refresh();
|
||||||
this.sort.sort(<MatSortable>{
|
this.sort.sort(<MatSortable>{
|
||||||
|
@ -36,17 +36,21 @@
|
|||||||
<ng-container matColumnDef="actions">
|
<ng-container matColumnDef="actions">
|
||||||
<mat-header-cell *matHeaderCellDef> Actions </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef> Actions </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let row" style="text-align: right">
|
<mat-cell *matCellDef="let row" style="text-align: right">
|
||||||
<button mat-icon-button (click)="startServer(row)" *ngIf="row.location === 'local' && getServerStatus(row) === 'stopped'">
|
<button mat-icon-button matTooltip="Go to projects" matTooltipClass="custom-tooltip" (click)="openProjects(row)" *ngIf="getServerStatus(row) === 'running' || row.location === 'remote' || row.location === 'bundled'">
|
||||||
|
<mat-icon aria-label="Go to projects">arrow_forward</mat-icon>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button mat-icon-button matTooltip="Start server" matTooltipClass="custom-tooltip" (click)="startServer(row)" *ngIf="row.location === 'local' && getServerStatus(row) === 'stopped'">
|
||||||
<mat-icon aria-label="Start server">play_arrow</mat-icon>
|
<mat-icon aria-label="Start server">play_arrow</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-icon-button (click)="stopServer(row)" *ngIf="row.location === 'local' && getServerStatus(row) === 'running'">
|
<button mat-icon-button matTooltip="Stop server" matTooltipClass="custom-tooltip" (click)="stopServer(row)" *ngIf="row.location === 'local' && getServerStatus(row) === 'running'">
|
||||||
<mat-icon aria-label="Stop server">stop</mat-icon>
|
<mat-icon aria-label="Stop server">stop</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<mat-spinner [diameter]="24" *ngIf="row.location === 'local' && getServerStatus(row) === 'starting'"></mat-spinner>
|
<mat-spinner [diameter]="24" *ngIf="row.location === 'local' && getServerStatus(row) === 'starting'"></mat-spinner>
|
||||||
|
|
||||||
<button mat-icon-button (click)="deleteServer(row)">
|
<button mat-icon-button matTooltip="Remove server" matTooltipClass="custom-tooltip" (click)="deleteServer(row)">
|
||||||
<mat-icon aria-label="Remove server">delete</mat-icon>
|
<mat-icon aria-label="Remove server">delete</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
|
@ -35,7 +35,8 @@ export class ServersComponent implements OnInit, OnDestroy {
|
|||||||
private electronService: ElectronService,
|
private electronService: ElectronService,
|
||||||
private childProcessService: ChildProcessService,
|
private childProcessService: ChildProcessService,
|
||||||
private bottomSheet: MatBottomSheet,
|
private bottomSheet: MatBottomSheet,
|
||||||
private route : ActivatedRoute
|
private route : ActivatedRoute,
|
||||||
|
private router: Router
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
getServers() {
|
getServers() {
|
||||||
@ -107,6 +108,10 @@ export class ServersComponent implements OnInit, OnDestroy {
|
|||||||
this.startServer(server);
|
this.startServer(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openProjects(server) {
|
||||||
|
this.router.navigate(['/server', server.id, 'projects']);
|
||||||
|
}
|
||||||
|
|
||||||
createModal() {
|
createModal() {
|
||||||
const dialogRef = this.dialog.open(AddServerDialogComponent, {
|
const dialogRef = this.dialog.open(AddServerDialogComponent, {
|
||||||
width: '350px',
|
width: '350px',
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
<button mat-button routerLink="/servers">Servers</button>
|
<button mat-button routerLink="/servers">Servers</button>
|
||||||
|
|
||||||
|
<button *ngIf="!recentlyOpenedProjectId && serverIdProjectList" mat-button (click)="listProjects()">Projects</button>
|
||||||
|
|
||||||
<button *ngIf="recentlyOpenedProjectId && recentlyOpenedServerId" mat-button (click)="backToProject()">Back to project</button>
|
<button *ngIf="recentlyOpenedProjectId && recentlyOpenedServerId" mat-button (click)="backToProject()">Back to project</button>
|
||||||
|
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
|
@ -24,6 +24,7 @@ export class DefaultLayoutComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
recentlyOpenedServerId : string;
|
recentlyOpenedServerId : string;
|
||||||
recentlyOpenedProjectId : string;
|
recentlyOpenedProjectId : string;
|
||||||
|
serverIdProjectList: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private electronService: ElectronService,
|
private electronService: ElectronService,
|
||||||
@ -37,6 +38,7 @@ export class DefaultLayoutComponent implements OnInit, OnDestroy {
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.recentlyOpenedServerId = this.recentlyOpenedProjectService.getServerId();
|
this.recentlyOpenedServerId = this.recentlyOpenedProjectService.getServerId();
|
||||||
this.recentlyOpenedProjectId = this.recentlyOpenedProjectService.getProjectId();
|
this.recentlyOpenedProjectId = this.recentlyOpenedProjectService.getProjectId();
|
||||||
|
this.serverIdProjectList = this.recentlyOpenedProjectService.getServerIdProjectList();
|
||||||
|
|
||||||
this.isInstalledSoftwareAvailable = this.electronService.isElectronApp;
|
this.isInstalledSoftwareAvailable = this.electronService.isElectronApp;
|
||||||
|
|
||||||
@ -56,6 +58,11 @@ export class DefaultLayoutComponent implements OnInit, OnDestroy {
|
|||||||
this.shouldStopServersOnClosing = this.electronService.isElectronApp;
|
this.shouldStopServersOnClosing = this.electronService.isElectronApp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listProjects() {
|
||||||
|
this.router.navigate(['/server', this.serverIdProjectList, 'projects'])
|
||||||
|
.catch(error => this.toasterService.error('Cannot list projects'));
|
||||||
|
}
|
||||||
|
|
||||||
backToProject() {
|
backToProject() {
|
||||||
this.router.navigate(['/server', this.recentlyOpenedServerId, 'project', this.recentlyOpenedProjectId])
|
this.router.navigate(['/server', this.recentlyOpenedServerId, 'project', this.recentlyOpenedProjectId])
|
||||||
.catch(error => this.toasterService.error('Cannot navigate to the last opened project'));
|
.catch(error => this.toasterService.error('Cannot navigate to the last opened project'));
|
||||||
|
@ -11,6 +11,7 @@ import { MockedSettingsService } from './settings.service.spec';
|
|||||||
import { Project } from '../models/project';
|
import { Project } from '../models/project';
|
||||||
import { AppTestingModule } from '../testing/app-testing/app-testing.module';
|
import { AppTestingModule } from '../testing/app-testing/app-testing.module';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
|
import { RecentlyOpenedProjectService } from './recentlyOpenedProject.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mocks ProjectsService so it's not based on settings
|
* Mocks ProjectsService so it's not based on settings
|
||||||
@ -62,7 +63,7 @@ describe('ProjectService', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [HttpClientTestingModule, AppTestingModule],
|
imports: [HttpClientTestingModule, AppTestingModule],
|
||||||
providers: [HttpServer, ProjectService, { provide: SettingsService, useClass: MockedSettingsService }]
|
providers: [HttpServer, ProjectService, RecentlyOpenedProjectService, { provide: SettingsService, useClass: MockedSettingsService }]
|
||||||
});
|
});
|
||||||
|
|
||||||
httpClient = TestBed.get(HttpClient);
|
httpClient = TestBed.get(HttpClient);
|
||||||
|
@ -7,12 +7,17 @@ import { Server } from '../models/server';
|
|||||||
import { HttpServer } from './http-server.service';
|
import { HttpServer } from './http-server.service';
|
||||||
import { Drawing } from '../cartography/models/drawing';
|
import { Drawing } from '../cartography/models/drawing';
|
||||||
import { SettingsService } from './settings.service';
|
import { SettingsService } from './settings.service';
|
||||||
|
import { RecentlyOpenedProjectService } from './recentlyOpenedProject.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ProjectService {
|
export class ProjectService {
|
||||||
public projectListSubject = new Subject<boolean>();
|
public projectListSubject = new Subject<boolean>();
|
||||||
|
|
||||||
constructor(private httpServer: HttpServer, private settingsService: SettingsService) {}
|
constructor(
|
||||||
|
private httpServer: HttpServer,
|
||||||
|
private settingsService: SettingsService,
|
||||||
|
private recentlyOpenedProjectService: RecentlyOpenedProjectService
|
||||||
|
) {}
|
||||||
|
|
||||||
projectListUpdated() {
|
projectListUpdated() {
|
||||||
this.projectListSubject.next(true);
|
this.projectListSubject.next(true);
|
||||||
@ -27,6 +32,7 @@ export class ProjectService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
close(server: Server, project_id: string) {
|
close(server: Server, project_id: string) {
|
||||||
|
this.recentlyOpenedProjectService.removeData();
|
||||||
return this.httpServer.post<Project>(server, `/projects/${project_id}/close`, {});
|
return this.httpServer.post<Project>(server, `/projects/${project_id}/close`, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import { Injectable } from '@angular/core';
|
|||||||
export class RecentlyOpenedProjectService {
|
export class RecentlyOpenedProjectService {
|
||||||
private serverId: string;
|
private serverId: string;
|
||||||
private projectId: string;
|
private projectId: string;
|
||||||
|
|
||||||
|
private serverIdProjectList: string;
|
||||||
|
|
||||||
setServerId(serverId: string) {
|
setServerId(serverId: string) {
|
||||||
this.serverId = serverId;
|
this.serverId = serverId;
|
||||||
@ -13,6 +15,10 @@ export class RecentlyOpenedProjectService {
|
|||||||
this.projectId = projectId;
|
this.projectId = projectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setServerIdProjectList(serverId: string) {
|
||||||
|
this.serverIdProjectList = serverId;
|
||||||
|
}
|
||||||
|
|
||||||
getServerId() : string {
|
getServerId() : string {
|
||||||
return this.serverId;
|
return this.serverId;
|
||||||
}
|
}
|
||||||
@ -20,4 +26,13 @@ export class RecentlyOpenedProjectService {
|
|||||||
getProjectId() : string {
|
getProjectId() : string {
|
||||||
return this.projectId;
|
return this.projectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getServerIdProjectList() : string {
|
||||||
|
return this.serverIdProjectList;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeData() {
|
||||||
|
this.serverId = '',
|
||||||
|
this.projectId = ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,67 +1,33 @@
|
|||||||
import { Injectable, RendererFactory2, Renderer2, Inject, EventEmitter } from '@angular/core';
|
import { Injectable, EventEmitter } from '@angular/core';
|
||||||
import { Observable, BehaviorSubject, combineLatest } from 'rxjs';
|
import { Observable, BehaviorSubject} from 'rxjs';
|
||||||
import { DOCUMENT } from '@angular/common';
|
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class ThemeService {
|
export class ThemeService {
|
||||||
private _mainTheme$: BehaviorSubject<string> = new BehaviorSubject('theme-default');
|
|
||||||
private _darkMode$: BehaviorSubject<boolean> = new BehaviorSubject(false);
|
private _darkMode$: BehaviorSubject<boolean> = new BehaviorSubject(false);
|
||||||
private _renderer: Renderer2;
|
|
||||||
private head: HTMLElement;
|
|
||||||
private themeLinks: HTMLElement[] = [];
|
|
||||||
darkMode$: Observable<boolean> = this._darkMode$.asObservable();
|
darkMode$: Observable<boolean> = this._darkMode$.asObservable();
|
||||||
theme$: Observable<[string, boolean]>;
|
theme$: Observable<[string, boolean]>;
|
||||||
|
|
||||||
public themeChanged = new EventEmitter<string>();
|
public themeChanged = new EventEmitter<string>();
|
||||||
public savedTheme: string = 'dark';
|
public savedTheme: string = 'dark';
|
||||||
|
|
||||||
constructor(
|
constructor() {
|
||||||
rendererFactory: RendererFactory2,
|
if (!localStorage.getItem('theme')) localStorage.setItem('theme', 'dark');
|
||||||
@Inject(DOCUMENT) document: Document
|
this.savedTheme = localStorage.getItem('theme');
|
||||||
) {
|
|
||||||
this.head = document.head;
|
|
||||||
this._renderer = rendererFactory.createRenderer(null, null);
|
|
||||||
this.theme$ = combineLatest(this._mainTheme$, this._darkMode$);
|
|
||||||
this.theme$.subscribe(async ([mainTheme, darkMode]) => {
|
|
||||||
const cssExt = '.css';
|
|
||||||
const cssFilename = darkMode ? mainTheme + '-dark' + cssExt : mainTheme + cssExt;
|
|
||||||
await this.loadCss(cssFilename);
|
|
||||||
if (this.themeLinks.length == 2)
|
|
||||||
this._renderer.removeChild(this.head, this.themeLinks.shift());
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getActualTheme() {
|
getActualTheme() {
|
||||||
return this.savedTheme;
|
return this.savedTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
setMainTheme(name: string) {
|
|
||||||
this._mainTheme$.next(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
setDarkMode(value: boolean) {
|
setDarkMode(value: boolean) {
|
||||||
this._darkMode$.next(value);
|
|
||||||
localStorage.removeItem('theme');
|
|
||||||
if (value) {
|
if (value) {
|
||||||
this.savedTheme = 'dark';
|
this.savedTheme = 'dark';
|
||||||
this.themeChanged.emit(this.savedTheme);
|
this.themeChanged.emit('dark-theme');
|
||||||
localStorage.setItem('theme', 'dark');
|
localStorage.setItem('theme', 'dark');
|
||||||
} else {
|
} else {
|
||||||
this.savedTheme = 'light';
|
this.savedTheme = 'light';
|
||||||
this.themeChanged.emit(this.savedTheme);
|
this.themeChanged.emit('light-theme');
|
||||||
localStorage.setItem('theme', 'light');
|
localStorage.setItem('theme', 'light');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadCss(filename: string) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
const linkEl: HTMLElement = this._renderer.createElement('link');
|
|
||||||
this._renderer.setAttribute(linkEl, 'rel', 'stylesheet');
|
|
||||||
this._renderer.setAttribute(linkEl, 'type', 'text/css');
|
|
||||||
this._renderer.setAttribute(linkEl, 'href', filename);
|
|
||||||
this._renderer.setProperty(linkEl, 'onload', resolve);
|
|
||||||
this._renderer.appendChild(this.head, linkEl);
|
|
||||||
this.themeLinks = [...this.themeLinks, linkEl];
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
@import '~@angular/material/theming';
|
|
||||||
@import '~material-design-icons/iconfont/material-icons.css';
|
|
||||||
@import '~typeface-roboto/index.css';
|
|
||||||
|
|
||||||
// Include non-theme styles for core.
|
|
||||||
@include mat-core();
|
|
||||||
|
|
||||||
// Define a theme.
|
|
||||||
$primary: mat-palette($mat-cyan, 700, 500, 900);
|
|
||||||
$accent: mat-palette($mat-blue, A200, A100, A700);
|
|
||||||
|
|
||||||
$theme: mat-light-theme($primary, $accent);
|
|
||||||
|
|
||||||
$light-palette: mat-palette($mat-blue, 900, A100, A400);
|
|
||||||
$light-background: mat-light-theme($light-palette, $primary);
|
|
||||||
|
|
||||||
$mat-light-theme-background: (
|
|
||||||
status-bar: black,
|
|
||||||
app-bar: map_get($mat-blue, 900),
|
|
||||||
background: white,
|
|
||||||
hover: rgba(white, 0.04),
|
|
||||||
card: white,
|
|
||||||
dialog: white,
|
|
||||||
disabled-button: $white-12-opacity,
|
|
||||||
raised-button: white,
|
|
||||||
focused-button: $white-6-opacity,
|
|
||||||
selected-button: map_get($mat-blue, 900),
|
|
||||||
selected-disabled-button: map_get($mat-blue, 800),
|
|
||||||
disabled-button-toggle: black,
|
|
||||||
unselected-chip: map_get($mat-blue, 700),
|
|
||||||
disabled-list-option: black
|
|
||||||
);
|
|
||||||
|
|
||||||
$theme: map-merge(
|
|
||||||
$theme,
|
|
||||||
(
|
|
||||||
background: $mat-light-theme-background
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
@include mat-core-theme($theme);
|
|
||||||
@include mat-autocomplete-theme($theme);
|
|
||||||
@include mat-button-theme($theme);
|
|
||||||
@include mat-button-toggle-theme($theme);
|
|
||||||
@include mat-card-theme($theme);
|
|
||||||
@include mat-checkbox-theme($theme);
|
|
||||||
@include mat-chips-theme($theme);
|
|
||||||
@include mat-table-theme($theme);
|
|
||||||
@include mat-datepicker-theme($theme);
|
|
||||||
@include mat-dialog-theme($theme);
|
|
||||||
@include mat-expansion-panel-theme($theme);
|
|
||||||
@include mat-form-field-theme($theme);
|
|
||||||
@include mat-grid-list-theme($theme);
|
|
||||||
@include mat-icon-theme($theme);
|
|
||||||
@include mat-input-theme($theme);
|
|
||||||
@include mat-list-theme($theme);
|
|
||||||
@include mat-menu-theme($theme);
|
|
||||||
@include mat-paginator-theme($theme);
|
|
||||||
@include mat-progress-bar-theme($theme);
|
|
||||||
@include mat-progress-spinner-theme($theme);
|
|
||||||
@include mat-radio-theme($theme);
|
|
||||||
@include mat-select-theme($theme);
|
|
||||||
@include mat-sidenav-theme($theme);
|
|
||||||
@include mat-slide-toggle-theme($theme);
|
|
||||||
@include mat-slider-theme($theme);
|
|
||||||
@include mat-stepper-theme($theme);
|
|
||||||
@include mat-tabs-theme($theme);
|
|
||||||
@include mat-toolbar-theme($light-background);
|
|
||||||
@include mat-tooltip-theme($theme);
|
|
||||||
@include mat-snack-bar-theme($theme);
|
|
138
src/theme.scss
138
src/theme.scss
@ -1,16 +1,14 @@
|
|||||||
@import '~@angular/material/theming';
|
@import '~@angular/material/theming';
|
||||||
@import '~material-design-icons/iconfont/material-icons.css';
|
@import '~material-design-icons/iconfont/material-icons.css';
|
||||||
@import '~typeface-roboto/index.css';
|
@import '~typeface-roboto/index.css';
|
||||||
|
|
||||||
// Include non-theme styles for core.
|
|
||||||
@include mat-core();
|
@include mat-core();
|
||||||
|
$mat-theme-ignore-duplication-warnings: true;
|
||||||
|
|
||||||
// Define a theme.
|
|
||||||
$primary: mat-palette($mat-cyan, 700, 500, 900);
|
$primary: mat-palette($mat-cyan, 700, 500, 900);
|
||||||
$accent: mat-palette($mat-blue-grey, A200, A100, A700);
|
$accent: mat-palette($mat-blue-grey, A200, A100, A700);
|
||||||
|
|
||||||
$theme: mat-dark-theme($primary, $accent);
|
// Dark theme
|
||||||
|
$dark-theme: mat-dark-theme($primary, $accent);
|
||||||
$dark-palette: mat-palette($mat-blue-grey, 900, A100, A400);
|
$dark-palette: mat-palette($mat-blue-grey, 900, A100, A400);
|
||||||
$dark-background: mat-dark-theme($dark-palette, $primary);
|
$dark-background: mat-dark-theme($dark-palette, $primary);
|
||||||
|
|
||||||
@ -31,40 +29,106 @@ $mat-dark-theme-background: (
|
|||||||
disabled-list-option: black
|
disabled-list-option: black
|
||||||
);
|
);
|
||||||
|
|
||||||
$theme: map-merge(
|
$dark-theme: map-merge(
|
||||||
$theme,
|
$dark-theme,
|
||||||
(
|
(
|
||||||
background: $mat-dark-theme-background
|
background: $mat-dark-theme-background
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@include mat-core-theme($theme);
|
.dark-theme {
|
||||||
@include mat-autocomplete-theme($theme);
|
@include angular-material-theme($dark-theme);
|
||||||
@include mat-button-theme($theme);
|
@include mat-core-theme($dark-theme);
|
||||||
@include mat-button-toggle-theme($theme);
|
@include mat-autocomplete-theme($dark-theme);
|
||||||
@include mat-card-theme($theme);
|
@include mat-button-theme($dark-theme);
|
||||||
@include mat-checkbox-theme($theme);
|
@include mat-button-toggle-theme($dark-theme);
|
||||||
@include mat-chips-theme($theme);
|
@include mat-card-theme($dark-theme);
|
||||||
@include mat-table-theme($theme);
|
@include mat-checkbox-theme($dark-theme);
|
||||||
@include mat-datepicker-theme($theme);
|
@include mat-chips-theme($dark-theme);
|
||||||
@include mat-dialog-theme($theme);
|
@include mat-table-theme($dark-theme);
|
||||||
@include mat-expansion-panel-theme($theme);
|
@include mat-datepicker-theme($dark-theme);
|
||||||
@include mat-form-field-theme($theme);
|
@include mat-dialog-theme($dark-theme);
|
||||||
@include mat-grid-list-theme($theme);
|
@include mat-expansion-panel-theme($dark-theme);
|
||||||
@include mat-icon-theme($theme);
|
@include mat-form-field-theme($dark-theme);
|
||||||
@include mat-input-theme($theme);
|
@include mat-grid-list-theme($dark-theme);
|
||||||
@include mat-list-theme($theme);
|
@include mat-icon-theme($dark-theme);
|
||||||
@include mat-menu-theme($theme);
|
@include mat-input-theme($dark-theme);
|
||||||
@include mat-paginator-theme($theme);
|
@include mat-list-theme($dark-theme);
|
||||||
@include mat-progress-bar-theme($theme);
|
@include mat-menu-theme($dark-theme);
|
||||||
@include mat-progress-spinner-theme($theme);
|
@include mat-paginator-theme($dark-theme);
|
||||||
@include mat-radio-theme($theme);
|
@include mat-progress-bar-theme($dark-theme);
|
||||||
@include mat-select-theme($theme);
|
@include mat-progress-spinner-theme($dark-theme);
|
||||||
@include mat-sidenav-theme($theme);
|
@include mat-radio-theme($dark-theme);
|
||||||
@include mat-slide-toggle-theme($theme);
|
@include mat-select-theme($dark-theme);
|
||||||
@include mat-slider-theme($theme);
|
@include mat-sidenav-theme($dark-theme);
|
||||||
@include mat-stepper-theme($theme);
|
@include mat-slide-toggle-theme($dark-theme);
|
||||||
@include mat-tabs-theme($theme);
|
@include mat-slider-theme($dark-theme);
|
||||||
@include mat-toolbar-theme($dark-background);
|
@include mat-stepper-theme($dark-theme);
|
||||||
@include mat-tooltip-theme($theme);
|
@include mat-tabs-theme($dark-theme);
|
||||||
@include mat-snack-bar-theme($theme);
|
@include mat-toolbar-theme($dark-background);
|
||||||
|
@include mat-tooltip-theme($dark-theme);
|
||||||
|
@include mat-snack-bar-theme($dark-theme);
|
||||||
|
color: white!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Light theme
|
||||||
|
$light-theme: mat-light-theme($primary, $accent);
|
||||||
|
$light-palette: mat-palette($mat-blue, 900, A100, A400);
|
||||||
|
$light-background: mat-light-theme($light-palette, $primary);
|
||||||
|
|
||||||
|
$mat-light-theme-background: (
|
||||||
|
status-bar: black,
|
||||||
|
app-bar: map_get($mat-blue, 900),
|
||||||
|
background: white,
|
||||||
|
hover: rgba(white, 0.04),
|
||||||
|
card: white,
|
||||||
|
dialog: white,
|
||||||
|
disabled-button: $white-12-opacity,
|
||||||
|
raised-button: white,
|
||||||
|
focused-button: $white-6-opacity,
|
||||||
|
selected-button: map_get($mat-blue, 900),
|
||||||
|
selected-disabled-button: map_get($mat-blue, 800),
|
||||||
|
disabled-button-toggle: black,
|
||||||
|
unselected-chip: map_get($mat-blue, 700),
|
||||||
|
disabled-list-option: black
|
||||||
|
);
|
||||||
|
|
||||||
|
$light-theme: map-merge(
|
||||||
|
$light-theme,
|
||||||
|
(
|
||||||
|
background: $mat-light-theme-background
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
.light-theme {
|
||||||
|
@include mat-core-theme($light-theme);
|
||||||
|
@include mat-autocomplete-theme($light-theme);
|
||||||
|
@include mat-button-theme($light-theme);
|
||||||
|
@include mat-button-toggle-theme($light-theme);
|
||||||
|
@include mat-card-theme($light-theme);
|
||||||
|
@include mat-checkbox-theme($light-theme);
|
||||||
|
@include mat-chips-theme($light-theme);
|
||||||
|
@include mat-table-theme($light-theme);
|
||||||
|
@include mat-datepicker-theme($light-theme);
|
||||||
|
@include mat-dialog-theme($light-theme);
|
||||||
|
@include mat-expansion-panel-theme($light-theme);
|
||||||
|
@include mat-form-field-theme($light-theme);
|
||||||
|
@include mat-grid-list-theme($light-theme);
|
||||||
|
@include mat-icon-theme($light-theme);
|
||||||
|
@include mat-input-theme($light-theme);
|
||||||
|
@include mat-list-theme($light-theme);
|
||||||
|
@include mat-menu-theme($light-theme);
|
||||||
|
@include mat-paginator-theme($light-theme);
|
||||||
|
@include mat-progress-bar-theme($light-theme);
|
||||||
|
@include mat-progress-spinner-theme($light-theme);
|
||||||
|
@include mat-radio-theme($light-theme);
|
||||||
|
@include mat-select-theme($light-theme);
|
||||||
|
@include mat-sidenav-theme($light-theme);
|
||||||
|
@include mat-slide-toggle-theme($light-theme);
|
||||||
|
@include mat-slider-theme($light-theme);
|
||||||
|
@include mat-stepper-theme($light-theme);
|
||||||
|
@include mat-tabs-theme($light-theme);
|
||||||
|
@include mat-toolbar-theme($light-background);
|
||||||
|
@include mat-tooltip-theme($light-theme);
|
||||||
|
@include mat-snack-bar-theme($light-theme);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user