You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metron.apache.org by sa...@apache.org on 2019/08/23 15:17:10 UTC
[metron] branch master updated: METRON-2179 [UI] Make navigation in
both UIs consistent (sardell) closes apache/metron#1464
This is an automated email from the ASF dual-hosted git repository.
sardell pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/metron.git
The following commit(s) were added to refs/heads/master by this push:
new 4ab1fdb METRON-2179 [UI] Make navigation in both UIs consistent (sardell) closes apache/metron#1464
4ab1fdb is described below
commit 4ab1fdba2f93cfb90dea55d315fb7f45c63d2fa6
Author: sardell <sh...@gmail.com>
AuthorDate: Fri Aug 23 17:16:48 2019 +0200
METRON-2179 [UI] Make navigation in both UIs consistent (sardell) closes apache/metron#1464
---
.../common-services/METRON/CURRENT/metainfo.xml | 2 +
.../package/templates/alerts-ui-app-config.json.j2 | 4 +-
.../templates/management-ui-app-config.json.j2 | 4 +-
metron-interface/metron-alerts/package-lock.json | 61 +++++++++++++++++-
metron-interface/metron-alerts/package.json | 2 +
.../metron-alerts/src/app/app.component.html | 69 ++++++++++++++-------
.../metron-alerts/src/app/app.component.scss | 31 +++++++--
.../metron-alerts/src/app/app.component.spec.ts | 37 ++++++++++-
.../metron-alerts/src/app/app.component.ts | 37 ++++++++++-
.../metron-alerts/src/app/app.module.ts | 28 +++++++--
.../src/app/service/app-config.service.ts | 14 +++++
.../metron-alerts/src/assets/app-config.json | 4 +-
.../metron-alerts/src/assets/images/logo-name.png | Bin 0 -> 3760 bytes
.../src/assets/images/logo-symbol.png | Bin 0 -> 19063 bytes
metron-interface/metron-alerts/src/styles.scss | 64 +++++++++++++++++++
metron-interface/metron-config/package-lock.json | 55 ++++++++++++++++
metron-interface/metron-config/package.json | 1 +
.../metron-config/src/app/app.component.html | 69 ++++++++++++++++-----
.../metron-config/src/app/app.component.scss | 23 +++++++
.../metron-config/src/app/app.component.ts | 37 ++++++++++-
.../metron-config/src/app/app.module.ts | 21 ++++++-
.../src/app/navbar/navbar.component.scss | 10 +++
.../metron-config/src/app/navbar/navbar.html | 8 +--
.../src/app/service/app-config.service.ts | 14 +++++
.../src/app/service/mock.app-config.service.ts | 9 +++
.../metron-config/src/assets/app-config.json | 4 +-
.../metron-config/src/assets/images/logo-name.png | Bin 0 -> 3760 bytes
.../src/assets/images/logo-symbol.png | Bin 0 -> 19063 bytes
metron-interface/metron-config/src/styles.scss | 66 ++++++++++++++++++++
29 files changed, 611 insertions(+), 63 deletions(-)
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/metainfo.xml b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/metainfo.xml
index cb044c2..417c225 100644
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/metainfo.xml
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/metainfo.xml
@@ -375,6 +375,7 @@
<config-type>metron-security-env</config-type>
<config-type>metron-rest-env</config-type>
<config-type>metron-management-ui-env</config-type>
+ <config-type>metron-alerts-ui-env</config-type>
</configuration-dependencies>
</component>
<component>
@@ -401,6 +402,7 @@
<configuration-dependencies>
<config-type>metron-security-env</config-type>
<config-type>metron-rest-env</config-type>
+ <config-type>metron-management-ui-env</config-type>
<config-type>metron-alerts-ui-env</config-type>
</configuration-dependencies>
</component>
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/templates/alerts-ui-app-config.json.j2 b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/templates/alerts-ui-app-config.json.j2
index cdc064e..192e830 100644
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/templates/alerts-ui-app-config.json.j2
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/templates/alerts-ui-app-config.json.j2
@@ -1,5 +1,7 @@
{
"apiRoot": "{{metron_rest_path}}",
"loginPath": "{{metron_alerts_ui_login_path}}",
- "contextMenuConfigURL": "{{metron_alerts_ui_context_menu_config_url}}"
+ "contextMenuConfigURL": "{{metron_alerts_ui_context_menu_config_url}}",
+ "managementUIHost": "{{metron_management_ui_host}}",
+ "managementUIPort": "{{metron_management_ui_port}}"
}
\ No newline at end of file
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/templates/management-ui-app-config.json.j2 b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/templates/management-ui-app-config.json.j2
index 12c3168..c03a35f 100644
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/templates/management-ui-app-config.json.j2
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/templates/management-ui-app-config.json.j2
@@ -1,4 +1,6 @@
{
"apiRoot": "{{metron_rest_path}}",
- "loginPath": "{{metron_management_ui_login_path}}"
+ "loginPath": "{{metron_management_ui_login_path}}",
+ "alertsUIHost": "{{metron_alerts_ui_host}}",
+ "alertsUIPort": "{{metron_alerts_ui_port}}"
}
\ No newline at end of file
diff --git a/metron-interface/metron-alerts/package-lock.json b/metron-interface/metron-alerts/package-lock.json
index 0860f0e..e97967c 100644
--- a/metron-interface/metron-alerts/package-lock.json
+++ b/metron-interface/metron-alerts/package-lock.json
@@ -719,6 +719,31 @@
}
}
},
+ "@angular/animations": {
+ "version": "7.2.15",
+ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.15.tgz",
+ "integrity": "sha512-8oBt3HLgd2+kyJHUgsd7OzKCCss67t2sch15XNoIWlOLfxclqU+EfFE6t/vCzpT8/+lpZS6LU9ZrTnb+UBj5jg==",
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "@angular/cdk": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-7.3.7.tgz",
+ "integrity": "sha512-xbXxhHHKGkVuW6K7pzPmvpJXIwpl0ykBnvA2g+/7Sgy5Pd35wCC+UtHD9RYczDM/mkygNxMQtagyCErwFnDtQA==",
+ "requires": {
+ "parse5": "^5.0.0",
+ "tslib": "^1.7.1"
+ },
+ "dependencies": {
+ "parse5": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
+ "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
+ "optional": true
+ }
+ }
+ },
"@angular/cli": {
"version": "7.3.9",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.3.9.tgz",
@@ -1399,6 +1424,23 @@
"tslib": "^1.9.0"
}
},
+ "@ant-design/colors": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-3.1.0.tgz",
+ "integrity": "sha512-Td7g1P53sNFyT4Gya6836e70TrhoVZ+HjZs6mpWIHrxl4/VqsjjOyzj/8ktOuw0lCx+BfYu9UO1CiJ0MoYYfhg==",
+ "requires": {
+ "tinycolor2": "^1.4.1"
+ }
+ },
+ "@ant-design/icons-angular": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@ant-design/icons-angular/-/icons-angular-2.1.0.tgz",
+ "integrity": "sha512-FDOtuxPKm2CaxWBWFqP2a5abtrrlVz8HzBdLEJJD68bW9ombWQKH71ZMp1Iw53Koqn1KTUCy0jPqSuSwx5wcrA==",
+ "requires": {
+ "@ant-design/colors": "^3.1.0",
+ "tslib": "^1.9.0"
+ }
+ },
"@babel/code-frame": {
"version": "7.0.0-beta.51",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.51.tgz",
@@ -5897,8 +5939,7 @@
"date-fns": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz",
- "integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw==",
- "dev": true
+ "integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw=="
},
"date-format": {
"version": "1.2.0",
@@ -11964,6 +12005,17 @@
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
"dev": true
},
+ "ng-zorro-antd": {
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/ng-zorro-antd/-/ng-zorro-antd-7.5.1.tgz",
+ "integrity": "sha512-0V/LoARoluFjiPUX4Q7x+G7hVA+k+x4g4OyYaLLUAoPpK3o1kriR3VzjdKsuKl73gBoRHHq4SNDRSiqzfOWDeA==",
+ "requires": {
+ "@angular/cdk": "^7.0.0",
+ "@ant-design/icons-angular": "^2.1.0",
+ "date-fns": "^1.29.0",
+ "tslib": "^1.9.0"
+ }
+ },
"ng2-dragula": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/ng2-dragula/-/ng2-dragula-1.5.0.tgz",
@@ -16108,6 +16160,11 @@
"setimmediate": "^1.0.4"
}
},
+ "tinycolor2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
+ "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g="
+ },
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
diff --git a/metron-interface/metron-alerts/package.json b/metron-interface/metron-alerts/package.json
index 91f43e4..d1e662e 100644
--- a/metron-interface/metron-alerts/package.json
+++ b/metron-interface/metron-alerts/package.json
@@ -18,6 +18,7 @@
},
"private": true,
"dependencies": {
+ "@angular/animations": "^7.2.15",
"@angular/common": "^7.2.15",
"@angular/compiler": "^7.2.15",
"@angular/core": "^7.2.15",
@@ -36,6 +37,7 @@
"font-awesome": "^4.7.0",
"jquery": "^3.3.1",
"moment": "^2.22.2",
+ "ng-zorro-antd": "^7.5.1",
"ng2-dragula": "^1.5.0",
"pikaday-time": "^1.6.1",
"popper.js": "^1.14.7",
diff --git a/metron-interface/metron-alerts/src/app/app.component.html b/metron-interface/metron-alerts/src/app/app.component.html
index a531dc8..ce7e201 100644
--- a/metron-interface/metron-alerts/src/app/app.component.html
+++ b/metron-interface/metron-alerts/src/app/app.component.html
@@ -11,27 +11,54 @@
OR CONDITIONS OF ANY KIND, either express or implied. See the License for
the specific language governing permissions and limitations under the License.
-->
-<div class="container-fluid px-0" [class.notransition]="noTransition">
- <nav class="navbar" *ngIf="loggedIn">
- <a class="" href="#">
- <img alt="" src="assets/images/logo.png" width="135" height="45">
- </a>
- <ul class="nav ml-4 h-100">
- <li class="nav-item" routerLinkActive="active">
- <a class="nav-link " routerLink="/alerts-list" routerLinkActive="active">Alerts</a>
- </li>
- <li class="nav-item" routerLinkActive="active">
- <a class="nav-link" routerLink="/pcap" routerLinkActive="active">PCAP</a>
- </li>
- </ul>
- <div class="logout ml-auto">Logged in as {{authService.currentUser}} - <span class="logout-link" (click)="authService.logout()">Logout</span></div>
- </nav>
- <div class="container-fluid">
- <router-outlet></router-outlet>
- </div>
- <router-outlet name="dialog" ></router-outlet>
- <app-metron-dialog></app-metron-dialog>
-</div>
+
+<nz-layout>
+ <nz-sider *ngIf="loggedIn" nzCollapsible [(nzCollapsed)]="isCollapsed" nzWidth="200px">
+ <div class="logo" style="height: 50px;">
+ <img class="icon logo-symbol h-100" src="assets/images/logo-symbol.png" alt="">
+ <img class="icon logo-name h-100" src="assets/images/logo-name.png" alt="">
+ </div>
+ <nav>
+ <ul nz-menu nzMode="inline" [nzInlineCollapsed]="isCollapsed" nzTheme="dark">
+ <li nz-submenu nzOpen *ngFor="let link of centralNavLinks; let i = index" routerLinkActive="ant-menu-item-selected">
+ <span title><i nz-icon [nzType]="link.iconClass"></i><span class="nav-text">{{ link.linkName }}</span></span>
+ <ng-container *ngIf="link.subLinks">
+ <ul>
+ <li *ngFor="let subLink of link.subLinks"
+ nz-menu-item
+ routerLinkActive="ant-menu-item-selected">
+ <a *ngIf="!subLink.externalLink"
+ [routerLink]="subLink.routerLink"
+ routerLinkActive="active">
+ {{ subLink.linkName }}
+ </a>
+ <a *ngIf="subLink.externalLink"
+ href="http://{{hostname}}{{subLink.routerLink}}">
+ {{ subLink.linkName }}
+ </a>
+ </li>
+ </ul>
+ </ng-container>
+ </li>
+ </ul>
+ </nav>
+ </nz-sider>
+ <nz-layout>
+ <nz-content>
+ <div class="container-fluid px-0" [class.notransition]="noTransition">
+ <div class="page-header" *ngIf="loggedIn">
+ <div class="logout ml-auto">Logged in as {{authService.currentUser}} - <span class="logout-link" (click)="authService.logout()">Logout</span></div>
+ </div>
+ <div class="container-fluid">
+ <router-outlet></router-outlet>
+ </div>
+ <router-outlet name="dialog" ></router-outlet>
+ <app-metron-dialog></app-metron-dialog>
+ </div>
+ </nz-content>
+ </nz-layout>
+
+</nz-layout>
diff --git a/metron-interface/metron-alerts/src/app/app.component.scss b/metron-interface/metron-alerts/src/app/app.component.scss
index 8505ee8..332976f 100644
--- a/metron-interface/metron-alerts/src/app/app.component.scss
+++ b/metron-interface/metron-alerts/src/app/app.component.scss
@@ -17,14 +17,14 @@
*/
@import "../variables";
-.navbar
-{
- flex-direction: row;
+.page-header {
background: $nav-bar-bg;
- padding: 0rem 1rem;
+ display: flex;
+ flex-direction: row;
height: 50px;
line-height: 50px;
max-height: 50px;
+ padding: 0rem 1rem;
}
.nav-link
@@ -53,3 +53,26 @@
color: $all-ports;
cursor: pointer;
}
+
+.ant-layout-sider { background-color: #2E2E2E; }
+.ant-menu { background-color: transparent; }
+.logo {
+ background-color: #3C3C3C;
+ display: flex;
+ justify-content: center;
+ padding: .25rem;
+}
+
+.logo-name {
+ transition: opacity .3s cubic-bezier(.645,.045,.355,1),width .3s cubic-bezier(.645,.045,.355,1);
+ .ant-layout-sider-collapsed & {
+ display: inline-block;
+ max-width: 0;
+ opacity: 0;
+ }
+}
+
+.logo-symbol {
+ padding-left: .5rem;
+ padding-right: .5rem;
+}
diff --git a/metron-interface/metron-alerts/src/app/app.component.spec.ts b/metron-interface/metron-alerts/src/app/app.component.spec.ts
index 1485904..0009f4d 100644
--- a/metron-interface/metron-alerts/src/app/app.component.spec.ts
+++ b/metron-interface/metron-alerts/src/app/app.component.spec.ts
@@ -23,10 +23,38 @@ import { AuthenticationService } from './service/authentication.service';
import { of } from 'rxjs';
import { DialogService } from './service/dialog.service';
import { MetronDialogComponent } from './shared/metron-dialog/metron-dialog.component';
+import { RouterTestingModule } from '@angular/router/testing';
+import {
+ NzLayoutModule,
+ NzMenuModule,
+ NgZorroAntdModule,
+ NZ_ICONS
+} from 'ng-zorro-antd';
+import {
+ ToolOutline,
+ WarningOutline,
+ FileOutline
+} from '@ant-design/icons-angular/icons';
+import { IconDefinition } from '@ant-design/icons-angular';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import {AppConfigService} from "./service/app-config.service";
+
+const icons: IconDefinition[] = [ ToolOutline, WarningOutline, FileOutline ];
@Component({ selector: 'router-outlet', template: '' })
class RouterOutletStubComponent {}
+class FakeAppConfigService {
+
+ getManagementUIHost() {
+ return 'localhost';
+ }
+
+ getManagementUIPort() {
+ return '4200'
+ }
+}
+
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
@@ -35,13 +63,20 @@ describe('AppComponent', () => {
TestBed.configureTestingModule({
providers: [
DialogService,
- { provide: AuthenticationService, useValue: { onLoginEvent: of(true) } }
+ { provide: AuthenticationService, useValue: { onLoginEvent: of(true) } },
+ { provide: AppConfigService, useClass: FakeAppConfigService },
+ { provide: NZ_ICONS, useValue: icons }
],
declarations: [
AppComponent,
MetronDialogComponent,
RouterOutletStubComponent,
],
+ imports: [
+ NzLayoutModule,
+ NzMenuModule,
+ BrowserAnimationsModule,
+ NgZorroAntdModule, RouterTestingModule ]
}).compileComponents();
}));
diff --git a/metron-interface/metron-alerts/src/app/app.component.ts b/metron-interface/metron-alerts/src/app/app.component.ts
index e2fc0f8..7d2fa7c 100644
--- a/metron-interface/metron-alerts/src/app/app.component.ts
+++ b/metron-interface/metron-alerts/src/app/app.component.ts
@@ -18,6 +18,7 @@
import { Component, OnInit } from '@angular/core';
import {AuthenticationService} from './service/authentication.service';
import { environment } from 'environments/environment';
+import {AppConfigService} from './service/app-config.service';
@Component({
selector: 'metron-alerts-root',
@@ -27,8 +28,42 @@ import { environment } from 'environments/environment';
export class AppComponent implements OnInit {
loggedIn = false;
noTransition = false;
+ isCollapsed = false;
+ hostname = this.appConfigService.getManagementUIHost();
+ centralNavLinks = [
+ {
+ linkName: 'Alerts',
+ iconClass: 'warning',
+ subLinks: [
+ {
+ linkName: 'Overview',
+ routerLink: '/alerts-list'
+ },
+ {
+ linkName: 'PCAP',
+ routerLink: '/pcap'
+ }
+ ]
+ },
+ {
+ linkName: 'Management',
+ iconClass: 'tool',
+ subLinks: [
+ {
+ linkName: 'Sensors',
+ routerLink: ':' + this.appConfigService.getManagementUIPort() + '/sensors',
+ externalLink: true
+ },
+ {
+ linkName: 'General Settings',
+ routerLink: ':' + this.appConfigService.getManagementUIPort() + '/general-settings',
+ externalLink: true
+ }
+ ]
+ }
+ ]
- constructor(private authService: AuthenticationService) {
+ constructor(private authService: AuthenticationService, private appConfigService: AppConfigService) {
this.authService.onLoginEvent.subscribe(result => {
this.loggedIn = result;
});
diff --git a/metron-interface/metron-alerts/src/app/app.module.ts b/metron-interface/metron-alerts/src/app/app.module.ts
index 560171e..efba0e3 100644
--- a/metron-interface/metron-alerts/src/app/app.module.ts
+++ b/metron-interface/metron-alerts/src/app/app.module.ts
@@ -21,6 +21,7 @@ import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import {HttpClientModule, HTTP_INTERCEPTORS} from '@angular/common/http';
import { APP_INITIALIZER } from '@angular/core';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import {MetronAlertsRoutingModule} from './app-routing.module';
@@ -41,19 +42,33 @@ import {AuthenticationService} from './service/authentication.service';
import {LoginGuard} from './shared/login-guard';
import {UpdateService} from './service/update.service';
import {MetaAlertService} from './service/meta-alert.service';
-import {MetaAlertsModule} from './alerts/meta-alerts/meta-alerts.module';
-import {SearchService} from './service/search.service';
+import { MetaAlertsModule } from './alerts/meta-alerts/meta-alerts.module';
+import { SearchService } from './service/search.service';
import { GlobalConfigService } from './service/global-config.service';
import { DefaultHeadersInterceptor } from './http-interceptors/default-headers.interceptor';
import { DialogService } from './service/dialog.service';
import { MetronDialogComponent } from './shared/metron-dialog/metron-dialog.component';
-import {PcapModule} from './pcap/pcap.module';
+import { PcapModule } from './pcap/pcap.module';
import { AppConfigService } from './service/app-config.service';
+import {
+ NzLayoutModule,
+ NzMenuModule,
+ NgZorroAntdModule,
+ NZ_ICONS
+} from 'ng-zorro-antd';
+import {
+ ToolOutline,
+ WarningOutline,
+ FileOutline
+} from '@ant-design/icons-angular/icons';
+import { IconDefinition } from '@ant-design/icons-angular';
export function initConfig(appConfigService: AppConfigService) {
return () => appConfigService.loadAppConfig();
}
+const icons: IconDefinition[] = [ ToolOutline, WarningOutline, FileOutline ];
+
@NgModule({
declarations: [
AppComponent,
@@ -72,11 +87,16 @@ export function initConfig(appConfigService: AppConfigService) {
ConfigureRowsModule,
SaveSearchModule,
SavedSearchesModule,
- PcapModule
+ PcapModule,
+ NzLayoutModule,
+ NzMenuModule,
+ BrowserAnimationsModule,
+ NgZorroAntdModule,
],
providers: [{ provide: APP_INITIALIZER, useFactory: initConfig, deps: [AppConfigService], multi: true },
{ provide: DataSource, useClass: ElasticSearchLocalstorageImpl },
{ provide: HTTP_INTERCEPTORS, useClass: DefaultHeadersInterceptor, multi: true },
+ { provide: NZ_ICONS, useValue: icons },
AppConfigService,
AuthenticationService,
AuthGuard,
diff --git a/metron-interface/metron-alerts/src/app/service/app-config.service.ts b/metron-interface/metron-alerts/src/app/service/app-config.service.ts
index 97a18f5..4d5ac22 100644
--- a/metron-interface/metron-alerts/src/app/service/app-config.service.ts
+++ b/metron-interface/metron-alerts/src/app/service/app-config.service.ts
@@ -59,4 +59,18 @@ export class AppConfigService {
}
return AppConfigService.appConfigStatic['contextMenuConfigURL'];
}
+
+ getManagementUIHost() {
+ if (AppConfigService.appConfigStatic['managementUIHost'] === undefined) {
+ console.error('[AppConfigService] managementUIHost entry is missing from /assets/app-config.json');
+ }
+ return AppConfigService.appConfigStatic['managementUIHost'];
+ }
+
+ getManagementUIPort() {
+ if (AppConfigService.appConfigStatic['managementUIPort'] === undefined) {
+ console.error('[AppConfigService] managementUIPort entry is missing from /assets/app-config.json');
+ }
+ return AppConfigService.appConfigStatic['managementUIPort'];
+ }
}
diff --git a/metron-interface/metron-alerts/src/assets/app-config.json b/metron-interface/metron-alerts/src/assets/app-config.json
index 04dbc54..a664dcb 100644
--- a/metron-interface/metron-alerts/src/assets/app-config.json
+++ b/metron-interface/metron-alerts/src/assets/app-config.json
@@ -1,5 +1,7 @@
{
"apiRoot": "/api/v1",
"loginPath": "/login",
- "contextMenuConfigURL": "/assets/context-menu.conf.json"
+ "contextMenuConfigURL": "/assets/context-menu.conf.json",
+ "managementUIHost": "localhost",
+ "managementUIPort": "4200"
}
\ No newline at end of file
diff --git a/metron-interface/metron-alerts/src/assets/images/logo-name.png b/metron-interface/metron-alerts/src/assets/images/logo-name.png
new file mode 100644
index 0000000..f91970d
Binary files /dev/null and b/metron-interface/metron-alerts/src/assets/images/logo-name.png differ
diff --git a/metron-interface/metron-alerts/src/assets/images/logo-symbol.png b/metron-interface/metron-alerts/src/assets/images/logo-symbol.png
new file mode 100644
index 0000000..297f0f1
Binary files /dev/null and b/metron-interface/metron-alerts/src/assets/images/logo-symbol.png differ
diff --git a/metron-interface/metron-alerts/src/styles.scss b/metron-interface/metron-alerts/src/styles.scss
index 4b1ce8a..3aa4a18 100644
--- a/metron-interface/metron-alerts/src/styles.scss
+++ b/metron-interface/metron-alerts/src/styles.scss
@@ -23,6 +23,8 @@
@import "../node_modules/pikaday-time/scss/pikaday.scss";
@import "hexagon";
@import "confirm-popover.scss";
+@import "~ng-zorro-antd/layout/style/index.min.css"; /* Import styles of the component */
+@import "~ng-zorro-antd/menu/style/index.min.css"; /* Import styles of the component */
body,
button {
@@ -358,3 +360,65 @@ $background_color_3: #2196F3;
cursor: not-allowed;
pointer-events: all;
}
+
+.ant-layout {
+ background: transparent;
+ min-height: 100vh;
+}
+
+.ant-layout-sider-trigger { background: #3C3C3C; }
+
+.cdk-overlay-pane {
+ position: absolute;
+ z-index: 1000;
+}
+
+.cdk-overlay-connected-position-bounding-box {
+ display: flex;
+ flex-direction: column;
+ min-height: 1px;
+ min-width: 1px;
+ position: absolute;
+ z-index: 1000;
+}
+
+.cdk-overlay-container {
+ height: 100%;
+ left: 0;
+ pointer-events: none;
+ position: fixed;
+ top: 0;
+ width: 100%;
+ z-index: 1000;
+}
+
+.ant-menu-dark .ant-menu-sub {
+ background: #2e2e2e;
+}
+
+.ant-menu.ant-menu-dark :not(ant-menu-submenu-open) .ant-menu-item-selected,
+.ant-menu.ant-menu-dark .ant-menu-sub .ant-menu-item-selected {
+ background-color: rgba(255, 255, 255, .1);
+}
+
+.ant-menu.ant-menu-dark .ant-menu-item-selected {
+ background-color: transparent;
+}
+
+.ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected {
+ background-color: rgba(255, 255, 255, .1);
+}
+
+.ant-menu-dark .ant-menu-inline.ant-menu-sub {
+ background: #2e2e2e;
+ box-shadow: none;
+}
+
+.ant-menu-submenu-title {
+ color: rgba(255,255,255,.65);
+}
+
+.ant-menu-submenu-arrow::before,
+.ant-menu-submenu-arrow::after {
+ background: rgba(255,255,255,.65);
+}
\ No newline at end of file
diff --git a/metron-interface/metron-config/package-lock.json b/metron-interface/metron-config/package-lock.json
index 7527925..deb333d 100644
--- a/metron-interface/metron-config/package-lock.json
+++ b/metron-interface/metron-config/package-lock.json
@@ -339,6 +339,23 @@
"tslib": "^1.9.0"
}
},
+ "@angular/cdk": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-7.3.7.tgz",
+ "integrity": "sha512-xbXxhHHKGkVuW6K7pzPmvpJXIwpl0ykBnvA2g+/7Sgy5Pd35wCC+UtHD9RYczDM/mkygNxMQtagyCErwFnDtQA==",
+ "requires": {
+ "parse5": "^5.0.0",
+ "tslib": "^1.7.1"
+ },
+ "dependencies": {
+ "parse5": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
+ "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
+ "optional": true
+ }
+ }
+ },
"@angular/cli": {
"version": "7.3.9",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.3.9.tgz",
@@ -1342,6 +1359,23 @@
"tslib": "^1.9.0"
}
},
+ "@ant-design/colors": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-3.1.0.tgz",
+ "integrity": "sha512-Td7g1P53sNFyT4Gya6836e70TrhoVZ+HjZs6mpWIHrxl4/VqsjjOyzj/8ktOuw0lCx+BfYu9UO1CiJ0MoYYfhg==",
+ "requires": {
+ "tinycolor2": "^1.4.1"
+ }
+ },
+ "@ant-design/icons-angular": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@ant-design/icons-angular/-/icons-angular-2.1.0.tgz",
+ "integrity": "sha512-FDOtuxPKm2CaxWBWFqP2a5abtrrlVz8HzBdLEJJD68bW9ombWQKH71ZMp1Iw53Koqn1KTUCy0jPqSuSwx5wcrA==",
+ "requires": {
+ "@ant-design/colors": "^3.1.0",
+ "tslib": "^1.9.0"
+ }
+ },
"@ngtools/webpack": {
"version": "7.3.9",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-7.3.9.tgz",
@@ -3623,6 +3657,11 @@
"assert-plus": "^1.0.0"
}
},
+ "date-fns": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
+ "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw=="
+ },
"date-format": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz",
@@ -7897,6 +7936,17 @@
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
"dev": true
},
+ "ng-zorro-antd": {
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/ng-zorro-antd/-/ng-zorro-antd-7.5.1.tgz",
+ "integrity": "sha512-0V/LoARoluFjiPUX4Q7x+G7hVA+k+x4g4OyYaLLUAoPpK3o1kriR3VzjdKsuKl73gBoRHHq4SNDRSiqzfOWDeA==",
+ "requires": {
+ "@angular/cdk": "^7.0.0",
+ "@ant-design/icons-angular": "^2.1.0",
+ "date-fns": "^1.29.0",
+ "tslib": "^1.9.0"
+ }
+ },
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@@ -11176,6 +11226,11 @@
"setimmediate": "^1.0.4"
}
},
+ "tinycolor2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
+ "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g="
+ },
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
diff --git a/metron-interface/metron-config/package.json b/metron-interface/metron-config/package.json
index 28bd758..633d69c 100644
--- a/metron-interface/metron-config/package.json
+++ b/metron-interface/metron-config/package.json
@@ -46,6 +46,7 @@
"font-awesome": "^4.6.3",
"jquery": "^3.3.1",
"karma-phantomjs-launcher": "^1.0.4",
+ "ng-zorro-antd": "^7.5.1",
"popper.js": "^1.14.4",
"puppeteer": "^1.8.0",
"rxjs": "6.5.2",
diff --git a/metron-interface/metron-config/src/app/app.component.html b/metron-interface/metron-config/src/app/app.component.html
index 6825ddc..18f678c 100644
--- a/metron-interface/metron-config/src/app/app.component.html
+++ b/metron-interface/metron-config/src/app/app.component.html
@@ -1,25 +1,60 @@
<!--
Licensed to the Apache Software
- Foundation (ASF) under one or more contributor license agreements. See the
- NOTICE file distributed with this work for additional information regarding
- copyright ownership. The ASF licenses this file to You under the Apache License,
- Version 2.0 (the "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
+ Foundation (ASF) under one or more contributor license agreements. See the
+ NOTICE file distributed with this work for additional information regarding
+ copyright ownership. The ASF licenses this file to You under the Apache License,
+ Version 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
- under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
- OR CONDITIONS OF ANY KIND, either express or implied. See the License for
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ OR CONDITIONS OF ANY KIND, either express or implied. See the License for
the specific language governing permissions and limitations under the License.
-->
-<div class="container-fluid header" *ngIf="loggedIn">
- <metron-config-navbar></metron-config-navbar>
-</div>
-<div [ngClass]="{'container-fluid body-fill px-0': loggedIn, 'fill': !loggedIn}">
- <div [ngClass]="{'card-group ': loggedIn}" class="fill">
- <div *ngIf="loggedIn" class="fill navigation" ><metron-config-vertical-navbar></metron-config-vertical-navbar></div>
- <div [ngClass]="{'fill content px-0 ' : loggedIn , 'fill': !loggedIn}"><router-outlet></router-outlet></div>
- </div>
-</div>
-<router-outlet name="dialog" ></router-outlet>
+<nz-layout>
+ <nz-sider *ngIf="loggedIn" nzCollapsible [(nzCollapsed)]="isCollapsed" nzWidth="200px">
+ <div class="logo" style="height: 50px;">
+ <img class="icon logo-symbol h-100" src="assets/images/logo-symbol.png" alt="">
+ <img class="icon logo-name h-100" src="assets/images/logo-name.png" alt="">
+ </div>
+ <nav>
+ <ul nz-menu nzMode="inline" [nzInlineCollapsed]="isCollapsed" nzTheme="dark">
+ <li nz-submenu nzOpen *ngFor="let link of centralNavLinks; let i = index" routerLinkActive="ant-menu-item-selected">
+ <span title><i nz-icon [nzType]="link.iconClass"></i><span class="nav-text">{{ link.linkName }}</span></span>
+ <ng-container *ngIf="link.subLinks">
+ <ul>
+ <li *ngFor="let subLink of link.subLinks"
+ nz-menu-item
+ routerLinkActive="ant-menu-item-selected">
+ <a *ngIf="!subLink.externalLink"
+ [routerLink]="subLink.routerLink"
+ routerLinkActive="active">
+ {{ subLink.linkName }}
+ </a>
+ <a *ngIf="subLink.externalLink"
+ href="http://{{hostname}}{{subLink.routerLink}}">
+ {{ subLink.linkName }}
+ </a>
+ </li>
+ </ul>
+ </ng-container>
+ </li>
+ </ul>
+ </nav>
+ </nz-sider>
+ <nz-layout>
+ <nz-content>
+ <div class="header" *ngIf="loggedIn">
+ <metron-config-navbar></metron-config-navbar>
+ </div>
+ <div [ngClass]="{'container-fluid body-fill px-0': loggedIn, 'fill': !loggedIn}">
+ <div [ngClass]="{'card-group ': loggedIn}" class="fill">
+ <div [ngClass]="{'fill content px-0 ' : loggedIn , 'fill': !loggedIn}"><router-outlet></router-outlet></div>
+ </div>
+ </div>
+ <router-outlet name="dialog" ></router-outlet>
+ </nz-content>
+ </nz-layout>
+</nz-layout>
diff --git a/metron-interface/metron-config/src/app/app.component.scss b/metron-interface/metron-config/src/app/app.component.scss
index 6060e89..9f7f672 100644
--- a/metron-interface/metron-config/src/app/app.component.scss
+++ b/metron-interface/metron-config/src/app/app.component.scss
@@ -33,3 +33,26 @@
border: none;
flex: 1;
}
+
+.ant-layout-sider { background-color: #2E2E2E; }
+.ant-menu { background-color: transparent; }
+.logo {
+ background-color: #3C3C3C;
+ display: flex;
+ justify-content: center;
+ padding: .25rem;
+}
+
+ .logo-name {
+ transition: opacity .3s cubic-bezier(.645,.045,.355,1),width .3s cubic-bezier(.645,.045,.355,1);
+ .ant-layout-sider-collapsed & {
+ display: inline-block;
+ max-width: 0;
+ opacity: 0;
+ }
+}
+
+ .logo-symbol {
+ padding-left: .5rem;
+ padding-right: .5rem;
+}
diff --git a/metron-interface/metron-config/src/app/app.component.ts b/metron-interface/metron-config/src/app/app.component.ts
index 591f0b0..61e50a0 100644
--- a/metron-interface/metron-config/src/app/app.component.ts
+++ b/metron-interface/metron-config/src/app/app.component.ts
@@ -17,6 +17,7 @@
*/
import {Component} from '@angular/core';
import {AuthenticationService} from './service/authentication.service';
+import {AppConfigService} from './service/app-config.service';
@Component({
@@ -28,8 +29,42 @@ import {AuthenticationService} from './service/authentication.service';
export class AppComponent {
loggedIn = false;
+ isCollapsed = false;
+ hostname = this.appConfigService.getAlertsUIHost();
+ centralNavLinks = [
+ {
+ linkName: 'Alerts',
+ iconClass: 'warning',
+ subLinks: [
+ {
+ linkName: 'Overview',
+ routerLink: ':' + this.appConfigService.getAlertsUIPort() + '/alerts-list',
+ externalLink: true
+ },
+ {
+ linkName: 'PCAP',
+ routerLink: ':' + this.appConfigService.getAlertsUIPort() + '/pcap',
+ externalLink: true
+ }
+ ]
+ },
+ {
+ linkName: 'Management',
+ iconClass: 'tool',
+ subLinks: [
+ {
+ linkName: 'Sensors',
+ routerLink: '/sensors',
+ },
+ {
+ linkName: 'General Settings',
+ routerLink: '/general-settings'
+ }
+ ]
+ }
+ ];
- constructor(private authService: AuthenticationService) {
+ constructor(private authService: AuthenticationService, private appConfigService: AppConfigService) {
this.authService.onLoginEvent.subscribe(result => {
this.loggedIn = result;
});
diff --git a/metron-interface/metron-config/src/app/app.module.ts b/metron-interface/metron-config/src/app/app.module.ts
index 89aa937..a0e1ea4 100644
--- a/metron-interface/metron-config/src/app/app.module.ts
+++ b/metron-interface/metron-config/src/app/app.module.ts
@@ -20,6 +20,7 @@ import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {BrowserModule} from '@angular/platform-browser';
import {HttpClientModule, HTTP_INTERCEPTORS} from '@angular/common/http';
import { Router } from '@angular/router';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {AppComponent} from './app.component';
import {SensorParserConfigService} from './service/sensor-parser-config.service';
import {KafkaService} from './service/kafka.service';
@@ -46,21 +47,37 @@ import {SensorIndexingConfigService} from './service/sensor-indexing-config.serv
import {HdfsService} from './service/hdfs.service';
import { DefaultHeadersInterceptor } from './http-interceptors/default-headers.interceptor';
import {AppConfigService} from './service/app-config.service';
+import {
+ NzLayoutModule,
+ NzMenuModule,
+ NgZorroAntdModule,
+ NZ_ICONS
+} from 'ng-zorro-antd';
+import {
+ ToolOutline,
+ WarningOutline,
+ FileOutline
+} from '@ant-design/icons-angular/icons';
+import { IconDefinition } from '@ant-design/icons-angular';
export function initConfig(appConfigService: AppConfigService) {
return () => appConfigService.loadAppConfig();
}
+const icons: IconDefinition[] = [ ToolOutline, WarningOutline, FileOutline ];
+
@NgModule({
imports: [ BrowserModule, FormsModule, ReactiveFormsModule, HttpClientModule, SensorParserListModule,
- SensorParserConfigModule, SensorParserConfigReadonlyModule, GeneralSettingsModule, MetronConfigRoutingModule ],
+ SensorParserConfigModule, SensorParserConfigReadonlyModule, GeneralSettingsModule, MetronConfigRoutingModule,NzLayoutModule,
+ NzMenuModule, BrowserAnimationsModule, NgZorroAntdModule ],
declarations: [ AppComponent, NavbarComponent, VerticalNavbarComponent ],
providers: [ AppConfigService, AuthenticationService, AuthGuard, LoginGuard, SensorParserConfigService,
SensorParserConfigHistoryService, SensorEnrichmentConfigService, SensorIndexingConfigService,
StormService, KafkaService, GrokValidationService, StellarService, HdfsService,
GlobalConfigService, MetronAlerts, MetronDialogBox,
{ provide: HTTP_INTERCEPTORS, useClass: DefaultHeadersInterceptor, multi: true },
- { provide: APP_INITIALIZER, useFactory: initConfig, deps: [AppConfigService], multi: true }
+ { provide: APP_INITIALIZER, useFactory: initConfig, deps: [AppConfigService], multi: true },
+ { provide: NZ_ICONS, useValue: icons },
],
bootstrap: [ AppComponent ]
})
diff --git a/metron-interface/metron-config/src/app/navbar/navbar.component.scss b/metron-interface/metron-config/src/app/navbar/navbar.component.scss
index 5a0b0be..d30602d 100644
--- a/metron-interface/metron-config/src/app/navbar/navbar.component.scss
+++ b/metron-interface/metron-config/src/app/navbar/navbar.component.scss
@@ -26,3 +26,13 @@
color: $form-button-border;
cursor: pointer;
}
+
+.page-header {
+ background-color: #2E2E2E;
+ display: flex;
+ flex-direction: row;
+ height: 50px;
+ line-height: 50px;
+ max-height: 50px;
+ padding: 0rem 1rem;
+}
diff --git a/metron-interface/metron-config/src/app/navbar/navbar.html b/metron-interface/metron-config/src/app/navbar/navbar.html
index 49f4a20..3c0cb1b 100644
--- a/metron-interface/metron-config/src/app/navbar/navbar.html
+++ b/metron-interface/metron-config/src/app/navbar/navbar.html
@@ -13,13 +13,9 @@
OR CONDITIONS OF ANY KIND, either express or implied. See the License for
the specific language governing permissions and limitations under the License.
-->
-<nav class="metron-nav navbar navbar-dark justify-content-between">
+<nav class="metron-nav page-header navbar-dark justify-content-between">
- <div class="navbar-toggleable-xs" id="exCollapsingNavbar">
- <a class="navbar-brand" href="#"><img src="assets/images/logo.png" alt="Logo" width=110></a>
- </div>
-
- <div class="form-inline">
+ <div class="form-inline ml-auto">
<i class="fa fa-user " style="padding-left: 11px" aria-hidden="true"></i>
<div *ngIf="currentUser != null" class="fa logout">Logged in as {{currentUser}} - <span class="logout-link" (click)="logout()">Logout</span></div>
</div>
diff --git a/metron-interface/metron-config/src/app/service/app-config.service.ts b/metron-interface/metron-config/src/app/service/app-config.service.ts
index 6081ea2..f3ca4c5 100644
--- a/metron-interface/metron-config/src/app/service/app-config.service.ts
+++ b/metron-interface/metron-config/src/app/service/app-config.service.ts
@@ -43,6 +43,20 @@ export class AppConfigService {
return AppConfigService.appConfigStatic['loginPath'];
}
+ getAlertsUIHost() {
+ if (AppConfigService.appConfigStatic['alertsUIHost'] === undefined) {
+ console.error('[AppConfigService] alertsUIHost entry is missing from /assets/app-config.json');
+ }
+ return AppConfigService.appConfigStatic['alertsUIHost'];
+ }
+
+ getAlertsUIPort() {
+ if (AppConfigService.appConfigStatic['alertsUIPort'] === undefined) {
+ console.error('[AppConfigService] alertsUIPort entry is missing from /assets/app-config.json');
+ }
+ return AppConfigService.appConfigStatic['alertsUIPort'];
+ }
+
static getAppConfigStatic() {
return AppConfigService.appConfigStatic;
}
diff --git a/metron-interface/metron-config/src/app/service/mock.app-config.service.ts b/metron-interface/metron-config/src/app/service/mock.app-config.service.ts
index 66f41e4..683ee25 100644
--- a/metron-interface/metron-config/src/app/service/mock.app-config.service.ts
+++ b/metron-interface/metron-config/src/app/service/mock.app-config.service.ts
@@ -26,4 +26,13 @@ export class MockAppConfigService extends AppConfigService {
getLoginPath() {
return '/login'
}
+
+ getAlertsUIHost() {
+ return 'localhost';
+ }
+
+ getAlertsUIPort() {
+ return '4201'
+ }
+
}
\ No newline at end of file
diff --git a/metron-interface/metron-config/src/assets/app-config.json b/metron-interface/metron-config/src/assets/app-config.json
index e485071..7c9132c 100644
--- a/metron-interface/metron-config/src/assets/app-config.json
+++ b/metron-interface/metron-config/src/assets/app-config.json
@@ -1,4 +1,6 @@
{
"apiRoot": "/api/v1",
- "loginPath": "/login"
+ "loginPath": "/login",
+ "alertsUIHost": "localhost",
+ "alertsUIPort": "4201"
}
\ No newline at end of file
diff --git a/metron-interface/metron-config/src/assets/images/logo-name.png b/metron-interface/metron-config/src/assets/images/logo-name.png
new file mode 100644
index 0000000..f91970d
Binary files /dev/null and b/metron-interface/metron-config/src/assets/images/logo-name.png differ
diff --git a/metron-interface/metron-config/src/assets/images/logo-symbol.png b/metron-interface/metron-config/src/assets/images/logo-symbol.png
new file mode 100644
index 0000000..297f0f1
Binary files /dev/null and b/metron-interface/metron-config/src/assets/images/logo-symbol.png differ
diff --git a/metron-interface/metron-config/src/styles.scss b/metron-interface/metron-config/src/styles.scss
index 26bb57c..8a12d5f 100644
--- a/metron-interface/metron-config/src/styles.scss
+++ b/metron-interface/metron-config/src/styles.scss
@@ -18,6 +18,8 @@
/* You can add global styles to this file, and also import other style files */
@import "app/_variables.scss";
@import "app/_fonts.scss";
+@import "~ng-zorro-antd/layout/style/index.min.css"; /* Import styles of the component */
+@import "~ng-zorro-antd/menu/style/index.min.css"; /* Import styles of the component */
$height: 60px;
@@ -737,3 +739,67 @@ button
color: #999;
}
}
+
+// Ant layout overrides
+
+.ant-layout {
+ background: transparent;
+ min-height: 100vh;
+}
+
+ .ant-layout-sider-trigger { background: #3C3C3C; }
+
+ .cdk-overlay-pane {
+ position: absolute;
+ z-index: 1000;
+}
+
+ .cdk-overlay-connected-position-bounding-box {
+ display: flex;
+ flex-direction: column;
+ min-height: 1px;
+ min-width: 1px;
+ position: absolute;
+ z-index: 1000;
+}
+
+ .cdk-overlay-container {
+ height: 100%;
+ left: 0;
+ pointer-events: none;
+ position: fixed;
+ top: 0;
+ width: 100%;
+ z-index: 1000;
+}
+
+ .ant-menu-dark .ant-menu-sub {
+ background: #2e2e2e;
+}
+
+ .ant-menu.ant-menu-dark :not(ant-menu-submenu-open) .ant-menu-item-selected,
+.ant-menu.ant-menu-dark .ant-menu-sub .ant-menu-item-selected {
+ background-color: rgba(255, 255, 255, .1);
+}
+
+ .ant-menu.ant-menu-dark .ant-menu-item-selected {
+ background-color: transparent;
+}
+
+ .ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected {
+ background-color: rgba(255, 255, 255, .1);
+}
+
+ .ant-menu-dark .ant-menu-inline.ant-menu-sub {
+ background: #2e2e2e;
+ box-shadow: none;
+}
+
+ .ant-menu-submenu-title {
+ color: rgba(255,255,255,.65);
+}
+
+ .ant-menu-submenu-arrow::before,
+.ant-menu-submenu-arrow::after {
+ background: rgba(255,255,255,.65);
+}