packages added.

This commit is contained in:
insanity 2018-04-06 20:02:18 +09:00
parent da66377a96
commit 35f82466a0
382 changed files with 10630 additions and 855 deletions

View File

@ -3,7 +3,8 @@ import { Routes, RouterModule, PreloadAllModules } from '@angular/router';
import { AuthGuard } from './commons/guard/auth.guard'; import { AuthGuard } from './commons/guard/auth.guard';
const routes: Routes = [ const routes: Routes = [
{ path: '', loadChildren: './pages/pages.module#PagesModule' }, // { path: '', loadChildren: './pages/pages.module#PagesModule', canActivate: [AuthGuard] },
{ path: '', loadChildren: './pages/pages.module#PagesModule'},
{ path: 'auth', loadChildren: './pages/auth/auth-page.module#AuthPageModule' }, { path: 'auth', loadChildren: './pages/auth/auth-page.module#AuthPageModule' },
// { path: 'errors', loadChildren: './pages/errors/errors-page.module#ErrorsPageModule' }, // { path: 'errors', loadChildren: './pages/errors/errors-page.module#ErrorsPageModule' },
]; ];

View File

@ -1,39 +1 @@
<div *ngIf="isAuthRouteActivated();else layout"> <router-outlet></router-outlet>
<router-outlet></router-outlet>
</div>
<ng-template #layout>
<div class="layout-wrapper" [ngClass]="{'layout-compact':layoutCompact}" (click)="onLayoutClick()">
<div #layoutContainer class="layout-container" [ngClass]="{'menu-layout-static': !isOverlay(),
'menu-layout-overlay': isOverlay(),
'layout-menu-overlay-active': overlayMenuActive,
'menu-layout-horizontal': isHorizontal(),
'menu-layout-slim': isSlim(),
'layout-menu-static-inactive': staticMenuDesktopInactive,
'layout-menu-static-active': staticMenuMobileActive}">
<of-topbar></of-topbar>
<div class="layout-menu" [ngClass]="{'layout-menu-dark':darkMenu}" (click)="onMenuClick($event)">
<p-scrollPanel #scrollPanel [style]="{height: '100%'}">
<of-inline-profile *ngIf="profileMode=='inline'&&!isHorizontal()"></of-inline-profile>
<of-menu [reset]="resetMenu"></of-menu>
</p-scrollPanel>
</div>
<div class="layout-main">
<of-breadcrumb></of-breadcrumb>
<div class="layout-content">
<router-outlet></router-outlet>
<of-footer></of-footer>
</div>
</div>
<of-rightpanel></of-rightpanel>
<div class="layout-mask"></div>
</div>
</div>
</ng-template>

View File

@ -2,321 +2,10 @@ import { Component, AfterViewInit, ElementRef, Renderer, ViewChild, OnDestroy, O
import { ScrollPanel } from 'primeng/primeng'; import { ScrollPanel } from 'primeng/primeng';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
enum MenuOrientation {
STATIC,
OVERLAY,
SLIM,
HORIZONTAL
}
@Component({ @Component({
selector: 'of-root', selector: 'of-root',
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'] styleUrls: ['./app.component.scss']
}) })
export class AppComponent implements AfterViewInit, OnDestroy, OnInit { export class AppComponent {
layoutCompact = true;
layoutMode: MenuOrientation = MenuOrientation.STATIC;
darkMenu = false;
profileMode = 'inline';
rotateMenuButton: boolean;
topbarMenuActive: boolean;
overlayMenuActive: boolean;
staticMenuDesktopInactive: boolean;
staticMenuMobileActive: boolean;
rightPanelActive: boolean;
rightPanelClick: boolean;
layoutContainer: HTMLDivElement;
layoutMenuScroller: HTMLDivElement;
menuClick: boolean;
topbarItemClick: boolean;
activeTopbarItem: any;
resetMenu: boolean;
menuHoverActive: boolean;
@ViewChild('layoutContainer') layourContainerViewChild: ElementRef;
@ViewChild('scrollPanel') layoutMenuScrollerViewChild: ScrollPanel;
rippleInitListener: any;
rippleMouseDownListener: any;
constructor(public renderer: Renderer, public zone: NgZone, private router: Router) { }
ngOnInit() {
if (this.isAuthRouteActivated()) {
console.log('auth?');
return;
}
this.zone.runOutsideAngular(() => { this.bindRipple(); });
}
bindRipple() {
this.rippleInitListener = this.init.bind(this);
document.addEventListener('DOMContentLoaded', this.rippleInitListener);
}
init() {
this.rippleMouseDownListener = this.rippleMouseDown.bind(this);
document.addEventListener('mousedown', this.rippleMouseDownListener, false);
}
rippleMouseDown(e) {
for (let target = e.target; target && target !== this; target = target['parentNode']) {
if (!this.isVisible(target)) {
continue;
}
// Element.matches() -> https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
if (this.selectorMatches(target, '.ripplelink, .ui-button')) {
const element = target;
this.rippleEffect(element, e);
break;
}
}
}
selectorMatches(el, selector) {
const p = Element.prototype;
const f = p['matches'] || p['webkitMatchesSelector'] || p['mozMatchesSelector'] || p['msMatchesSelector'] || function (s) {
return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
};
return f.call(el, selector);
}
isVisible(el) {
return !!(el.offsetWidth || el.offsetHeight);
}
rippleEffect(element, e) {
if (element.querySelector('.ink') === null) {
const inkEl = document.createElement('span');
this.addClass(inkEl, 'ink');
if (this.hasClass(element, 'ripplelink')) {
element.querySelector('span').insertAdjacentHTML('afterend', '<span class=\'ink\'></span>');
} else {
element.appendChild(inkEl);
}
}
const ink = element.querySelector('.ink');
this.removeClass(ink, 'ripple-animate');
if (!ink.offsetHeight && !ink.offsetWidth) {
const d = Math.max(element.offsetWidth, element.offsetHeight);
ink.style.height = d + 'px';
ink.style.width = d + 'px';
}
const x = e.pageX - this.getOffset(element).left - (ink.offsetWidth / 2);
const y = e.pageY - this.getOffset(element).top - (ink.offsetHeight / 2);
ink.style.top = y + 'px';
ink.style.left = x + 'px';
ink.style.pointerEvents = 'none';
this.addClass(ink, 'ripple-animate');
}
hasClass(element, className) {
if (element.classList) {
return element.classList.contains(className);
} else {
return new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className);
}
}
addClass(element, className) {
if (element.classList) {
element.classList.add(className);
} else {
element.className += ' ' + className;
}
}
removeClass(element, className) {
if (element.classList) {
element.classList.remove(className);
} else {
element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
}
getOffset(el) {
const rect = el.getBoundingClientRect();
return {
top: rect.top + (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0),
left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0),
};
}
unbindRipple() {
if (this.rippleInitListener) {
document.removeEventListener('DOMContentLoaded', this.rippleInitListener);
}
if (this.rippleMouseDownListener) {
document.removeEventListener('mousedown', this.rippleMouseDownListener);
}
}
ngAfterViewInit() {
this.layoutContainer = <HTMLDivElement>this.layourContainerViewChild.nativeElement;
setTimeout(() => { this.layoutMenuScrollerViewChild.moveBar(); }, 100);
}
onLayoutClick() {
if (!this.topbarItemClick) {
this.activeTopbarItem = null;
this.topbarMenuActive = false;
}
if (!this.menuClick) {
if (this.isHorizontal() || this.isSlim()) {
this.resetMenu = true;
}
if (this.overlayMenuActive || this.staticMenuMobileActive) {
this.hideOverlayMenu();
}
this.menuHoverActive = false;
}
if (!this.rightPanelClick) {
this.rightPanelActive = false;
}
this.topbarItemClick = false;
this.menuClick = false;
this.rightPanelClick = false;
}
onMenuButtonClick(event) {
this.menuClick = true;
this.rotateMenuButton = !this.rotateMenuButton;
this.topbarMenuActive = false;
if (this.layoutMode === MenuOrientation.OVERLAY) {
this.overlayMenuActive = !this.overlayMenuActive;
} else {
if (this.isDesktop()) {
this.staticMenuDesktopInactive = !this.staticMenuDesktopInactive;
} else {
this.staticMenuMobileActive = !this.staticMenuMobileActive;
}
}
event.preventDefault();
}
onMenuClick($event) {
this.menuClick = true;
this.resetMenu = false;
}
onTopbarMenuButtonClick(event) {
this.topbarItemClick = true;
this.topbarMenuActive = !this.topbarMenuActive;
this.hideOverlayMenu();
event.preventDefault();
}
onTopbarItemClick(event, item) {
this.topbarItemClick = true;
if (this.activeTopbarItem === item) {
this.activeTopbarItem = null;
} else {
this.activeTopbarItem = item;
}
event.preventDefault();
}
onRightPanelButtonClick(event) {
this.rightPanelClick = true;
this.rightPanelActive = !this.rightPanelActive;
event.preventDefault();
}
onRightPanelClick() {
this.rightPanelClick = true;
}
hideOverlayMenu() {
this.rotateMenuButton = false;
this.overlayMenuActive = false;
this.staticMenuMobileActive = false;
}
isTablet() {
const width = window.innerWidth;
return width <= 1024 && width > 640;
}
isDesktop() {
return window.innerWidth > 1024;
}
isMobile() {
return window.innerWidth <= 640;
}
isOverlay() {
return this.layoutMode === MenuOrientation.OVERLAY;
}
isHorizontal() {
return this.layoutMode === MenuOrientation.HORIZONTAL;
}
isSlim() {
return this.layoutMode === MenuOrientation.SLIM;
}
changeToStaticMenu() {
this.layoutMode = MenuOrientation.STATIC;
}
changeToOverlayMenu() {
this.layoutMode = MenuOrientation.OVERLAY;
}
changeToHorizontalMenu() {
this.layoutMode = MenuOrientation.HORIZONTAL;
}
changeToSlimMenu() {
this.layoutMode = MenuOrientation.SLIM;
}
ngOnDestroy() {
this.unbindRipple();
}
isAuthRouteActivated() {
return this.router.url.indexOf('/auth') > -1;
}
} }

View File

@ -1,6 +1,5 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { PrimeNGModules } from '../packages/commons/prime-ng/prime-ng.module';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppStoreModule } from './app-store.module'; import { AppStoreModule } from './app-store.module';
@ -10,23 +9,16 @@ import { AppRESTModule } from './app-rest.module';
import { AppLoggerModule } from './app-logger.module'; import { AppLoggerModule } from './app-logger.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
import { CookieService } from 'ngx-cookie-service'; import { CookieService } from 'ngx-cookie-service';
import { AuthGuard } from './commons/guard/auth.guard'; import { AuthGuard } from './commons/guard/auth.guard';
import { BrowserModule } from '@angular/platform-browser';
import { AppMenuComponent } from 'app/commons/component/layout/menu/app.menu.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppSubMenuComponent } from 'app/commons/component/layout/menu/app.submenu.component';
import { AppTopbarComponent } from 'app/commons/component/layout/topbar/app.topbar.component';
import { AppFooterComponent } from 'app/commons/component/layout/footer/app.footer.component';
import { AppBreadcrumbComponent } from 'app/commons/component/layout/breadcrumb/app.breadcrumb.component';
import { AppRightpanelComponent } from 'app/commons/component/layout/right-panel/app.rightpanel.component';
import { AppInlineProfileComponent } from 'app/commons/component/layout/profile/app.profile.component';
import { BreadcrumbService } from 'app/commons/component/layout/breadcrumb/breadcrumb.service';
@NgModule({ @NgModule({
imports: [ imports: [
PrimeNGModules, BrowserModule,
BrowserAnimationsModule,
HttpClientModule, HttpClientModule,
AppRoutingModule, AppRoutingModule,
AppStoreModule, AppStoreModule,
@ -37,17 +29,8 @@ import { BreadcrumbService } from 'app/commons/component/layout/breadcrumb/bread
], ],
declarations: [ declarations: [
AppComponent, AppComponent,
AppMenuComponent,
AppSubMenuComponent,
AppTopbarComponent,
AppFooterComponent,
AppBreadcrumbComponent,
AppRightpanelComponent,
AppInlineProfileComponent,
], ],
providers: [ providers: [
{ provide: LocationStrategy, useClass: HashLocationStrategy },
BreadcrumbService,
CookieService, CookieService,
AuthGuard, AuthGuard,
], ],

View File

@ -2,6 +2,7 @@ import { Component, Input, OnInit } from '@angular/core';
import { trigger, state, style, transition, animate } from '@angular/animations'; import { trigger, state, style, transition, animate } from '@angular/animations';
import { MenuItem } from 'primeng/primeng'; import { MenuItem } from 'primeng/primeng';
import { AppComponent } from 'app/app.component'; import { AppComponent } from 'app/app.component';
import { PagesComponent } from '../../../../pages/pages.component';
@Component({ @Component({
selector: 'of-menu', selector: 'of-menu',
@ -14,7 +15,7 @@ export class AppMenuComponent implements OnInit {
model: any[]; model: any[];
constructor(public app: AppComponent) { } constructor(public app: PagesComponent) { }
ngOnInit() { ngOnInit() {
this.model = [ this.model = [

View File

@ -2,6 +2,7 @@ import { Component, Input, OnInit } from '@angular/core';
import { trigger, state, style, transition, animate } from '@angular/animations'; import { trigger, state, style, transition, animate } from '@angular/animations';
import { MenuItem } from 'primeng/primeng'; import { MenuItem } from 'primeng/primeng';
import { AppComponent } from 'app/app.component'; import { AppComponent } from 'app/app.component';
import { PagesComponent } from '../../../../pages/pages.component';
@Component({ @Component({
/* tslint:disable:component-selector */ /* tslint:disable:component-selector */
@ -41,7 +42,7 @@ export class AppSubMenuComponent {
activeIndex: number; activeIndex: number;
constructor(public app: AppComponent) { } constructor(public app: PagesComponent) { }
itemClick(event: Event, item: MenuItem, index: number)  { itemClick(event: Event, item: MenuItem, index: number)  {
if (this.root) { if (this.root) {

View File

@ -1,5 +1,6 @@
import {Component, trigger, state, transition, style, animate} from '@angular/core'; import {Component, trigger, state, transition, style, animate} from '@angular/core';
import {AppComponent} from 'app/app.component'; import {AppComponent} from 'app/app.component';
import { PagesComponent } from '../../../../pages/pages.component';
@Component({ @Component({
selector: 'of-inline-profile', selector: 'of-inline-profile',
@ -21,7 +22,7 @@ export class AppInlineProfileComponent {
active: boolean; active: boolean;
constructor(public app: AppComponent) {} constructor(public app: PagesComponent) {}
onClick(event) { onClick(event) {
this.active = !this.active; this.active = !this.active;

View File

@ -1,6 +1,7 @@
import {Component, ViewChild, AfterViewInit} from '@angular/core'; import {Component, ViewChild, AfterViewInit} from '@angular/core';
import {AppComponent} from 'app/app.component'; import {AppComponent} from 'app/app.component';
import {ScrollPanel} from 'primeng/primeng'; import {ScrollPanel} from 'primeng/primeng';
import { PagesComponent } from '../../../../pages/pages.component';
@Component({ @Component({
selector: 'of-rightpanel', selector: 'of-rightpanel',
@ -10,7 +11,7 @@ export class AppRightpanelComponent implements AfterViewInit {
@ViewChild('scrollRightPanel') rightPanelMenuScrollerViewChild: ScrollPanel; @ViewChild('scrollRightPanel') rightPanelMenuScrollerViewChild: ScrollPanel;
constructor(public app: AppComponent) {} constructor(public app: PagesComponent) {}
ngAfterViewInit() { ngAfterViewInit() {
setTimeout(() => {this.rightPanelMenuScrollerViewChild.moveBar(); }, 100); setTimeout(() => {this.rightPanelMenuScrollerViewChild.moveBar(); }, 100);

View File

@ -1,5 +1,6 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {AppComponent} from 'app/app.component'; import {AppComponent} from 'app/app.component';
import { PagesComponent } from '../../../../pages/pages.component';
@Component({ @Component({
selector: 'of-topbar', selector: 'of-topbar',
@ -7,6 +8,6 @@ import {AppComponent} from 'app/app.component';
}) })
export class AppTopbarComponent { export class AppTopbarComponent {
constructor(public app: AppComponent) {} constructor(public app: PagesComponent) {}
} }

View File

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

View File

@ -1 +0,0 @@
<div>header</div>

View File

@ -1,17 +0,0 @@
:host {
z-index: 4;
}
.main-toolbar {
height: 64px;
padding-left: 16px;
}
.more-btn {
height: 100%;
min-width: 70px;
}
.mat-icon-button {
margin-right: 10px;
}

View File

@ -1,34 +0,0 @@
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { ISubscription } from 'rxjs/Subscription';
import { LocaleService, TranslationService } from 'angular-l10n';
@Component({
selector: 'of-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
countryMenuItems: any[] = [
{ text: 'United States', language: 'en', country: 'US', currency: 'USD', numberingSystem: 'latn' },
{ text: 'Korea', language: 'kr', country: 'KR', currency: 'KRW', numberingSystem: 'latn' }
];
@Input() sidenav;
@Input() sidebar;
@Input() drawer;
@Input() matDrawerShow;
searchOpen = false;
constructor(public locale: LocaleService, public translation: TranslationService, public title: Title) { }
ngOnInit() {
}
}

View File

@ -1,29 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FooterComponent } from './footer/footer.component';
import { HeaderComponent } from './header/header.component';
import { LocalizationModule } from 'angular-l10n';
import { RouterModule } from '@angular/router';
import { SidebarComponent } from './sidebar/sidebar.component';
import { SubMenubarComponent } from './sub-menubar/sub-menubar.component';
@NgModule({
imports: [
CommonModule,
LocalizationModule,
RouterModule,
],
declarations: [
FooterComponent,
HeaderComponent,
SidebarComponent,
SubMenubarComponent
],
exports: [
FooterComponent,
HeaderComponent,
SidebarComponent,
SubMenubarComponent
]
})
export class LayoutModule { }

View File

@ -1,83 +0,0 @@
export const menus = [
{
'name': 'App.Home',
'icon': 'home',
'link': '/home',
'open': true,
},
{
'name': 'App.Infra',
'icon': 'widgets',
'link': false,
'open': false,
'sub': [
{
'name': 'App.Map',
'link': '/map',
'icon': 'indeterminate_check_box',
'chip': false,
'open': false,
},
{
'name': 'App.Sensors',
'link': '/sensors',
'icon': 'indeterminate_check_box',
'chip': false,
'open': false,
},
{
'name': 'App.Probes',
'link': '/probes',
'icon': 'indeterminate_check_box',
'chip': false,
'open': false,
},
]
},
{
'name': 'App.Monitor',
'icon': 'widgets',
'link': false,
'open': false,
'sub': [
{
'name': 'App.Overview',
'link': '/overview',
'icon': 'indeterminate_check_box',
'chip': false,
'open': false,
},
{
'name': 'App.Dashboards',
'link': '/dashboard',
'icon': 'indeterminate_check_box',
'chip': { 'value': 3, 'color': 'accent'},
'open': false,
},
]
},
{
'name': 'App.Alert',
'icon': 'warning',
'link': '/alert',
'open': true,
},
{
'name': 'App.Report',
'icon': '',
'link': '',
'open': true,
},
{
'name': 'App.Log',
'icon': '',
'link': '',
'open': true,
},
{
'name': 'App.Setting',
'icon': '',
'link': '/auth/signin',
'open': true,
},
];

View File

@ -1 +0,0 @@
<div>sidebar</div>

View File

@ -1,4 +0,0 @@
@mixin sidemenu($theme) {
}

View File

@ -1,20 +0,0 @@
import { Component, OnInit, Input } from '@angular/core';
import { menus } from './menu-element';
import { Language } from 'angular-l10n';
@Component({
selector: 'of-sidebar',
templateUrl: './sidebar.component.html',
styleUrls: ['./sidebar.component.scss']
})
export class SidebarComponent implements OnInit {
@Language() lang: string;
@Input() iconOnly = false;
public menus = menus;
constructor() { }
ngOnInit() {
}
}

View File

@ -1 +0,0 @@
<div>submenubar</div>

View File

@ -1,20 +0,0 @@
import { Component, OnInit, Input } from '@angular/core';
import { Router } from '@angular/router';
import { Language } from 'angular-l10n';
@Component({
selector: 'of-sub-menubar',
templateUrl: './sub-menubar.component.html',
styleUrls: ['./sub-menubar.component.scss']
})
export class SubMenubarComponent implements OnInit {
@Input() tabs: any;
constructor(public router: Router) { }
ngOnInit() {
}
}

View File

@ -1,3 +1 @@
<p> <p>home works</p>
Home works!
</p>

View File

@ -1,7 +1,6 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { PagesComponent } from './pages.component'; import { PagesComponent } from './pages.component';
import {AuthGuard} from '../commons/guard/auth.guard';
const routes: Routes = [ const routes: Routes = [
{ {

View File

@ -1 +1,34 @@
<router-outlet></router-outlet> <div class="layout-wrapper" [ngClass]="{'layout-compact':layoutCompact}" (click)="onLayoutClick()">
<div #layoutContainer class="layout-container" [ngClass]="{'menu-layout-static': !isOverlay(),
'menu-layout-overlay': isOverlay(),
'layout-menu-overlay-active': overlayMenuActive,
'menu-layout-horizontal': isHorizontal(),
'menu-layout-slim': isSlim(),
'layout-menu-static-inactive': staticMenuDesktopInactive,
'layout-menu-static-active': staticMenuMobileActive}">
<of-topbar></of-topbar>
<div class="layout-menu" [ngClass]="{'layout-menu-dark':darkMenu}" (click)="onMenuClick($event)">
<p-scrollPanel #scrollPanel [style]="{height: '100%'}">
<of-inline-profile *ngIf="profileMode=='inline'&&!isHorizontal()"></of-inline-profile>
<of-menu [reset]="resetMenu"></of-menu>
</p-scrollPanel>
</div>
<div class="layout-main">
<of-breadcrumb></of-breadcrumb>
<div class="layout-content">
<router-outlet></router-outlet>
<of-footer></of-footer>
</div>
</div>
<of-rightpanel></of-rightpanel>
<div class="layout-mask"></div>
</div>
</div>

View File

@ -1,27 +1,319 @@
import { Component, OnInit, Input, OnChanges } from '@angular/core'; import { Component, AfterViewInit, ElementRef, Renderer, ViewChild, OnDestroy, OnInit, NgZone } from '@angular/core';
import { ScrollPanel } from 'primeng/primeng';
import { Router } from '@angular/router';
enum MenuOrientation {
STATIC,
OVERLAY,
SLIM,
HORIZONTAL
}
@Component({ @Component({
selector: 'of-pages', selector: 'of-pages',
templateUrl: './pages.component.html', templateUrl: './pages.component.html',
styleUrls: ['./pages.component.scss'] styleUrls: ['./pages.component.scss']
}) })
export class PagesComponent implements OnInit { export class PagesComponent implements AfterViewInit, OnDestroy, OnInit {
layoutCompact = true;
@Input() isVisible = true; layoutMode: MenuOrientation = MenuOrientation.STATIC;
visibility = 'shown';
sideNavOpened = true; darkMenu = false;
matDrawerOpened = false;
matDrawerShow = true;
sideNavMode = 'side';
constructor() { } profileMode = 'inline';
rotateMenuButton: boolean;
topbarMenuActive: boolean;
overlayMenuActive: boolean;
staticMenuDesktopInactive: boolean;
staticMenuMobileActive: boolean;
rightPanelActive: boolean;
rightPanelClick: boolean;
layoutContainer: HTMLDivElement;
layoutMenuScroller: HTMLDivElement;
menuClick: boolean;
topbarItemClick: boolean;
activeTopbarItem: any;
resetMenu: boolean;
menuHoverActive: boolean;
@ViewChild('layoutContainer') layourContainerViewChild: ElementRef;
@ViewChild('scrollPanel') layoutMenuScrollerViewChild: ScrollPanel;
rippleInitListener: any;
rippleMouseDownListener: any;
constructor(public renderer: Renderer, public zone: NgZone, private router: Router) { }
ngOnInit() { ngOnInit() {
if (this.isAuthRouteActivated()) {
return;
}
this.zone.runOutsideAngular(() => { this.bindRipple(); });
} }
getRouteAnimation(outlet) { bindRipple() {
return outlet.activatedRouteData.animation; this.rippleInitListener = this.init.bind(this);
document.addEventListener('DOMContentLoaded', this.rippleInitListener);
}
init() {
this.rippleMouseDownListener = this.rippleMouseDown.bind(this);
document.addEventListener('mousedown', this.rippleMouseDownListener, false);
}
rippleMouseDown(e) {
for (let target = e.target; target && target !== this; target = target['parentNode']) {
if (!this.isVisible(target)) {
continue;
}
// Element.matches() -> https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
if (this.selectorMatches(target, '.ripplelink, .ui-button')) {
const element = target;
this.rippleEffect(element, e);
break;
}
}
}
selectorMatches(el, selector) {
const p = Element.prototype;
const f = p['matches'] || p['webkitMatchesSelector'] || p['mozMatchesSelector'] || p['msMatchesSelector'] || function (s) {
return [].indexOf.call(document.querySelectorAll(s), this) !== -1;
};
return f.call(el, selector);
}
isVisible(el) {
return !!(el.offsetWidth || el.offsetHeight);
}
rippleEffect(element, e) {
if (element.querySelector('.ink') === null) {
const inkEl = document.createElement('span');
this.addClass(inkEl, 'ink');
if (this.hasClass(element, 'ripplelink')) {
element.querySelector('span').insertAdjacentHTML('afterend', '<span class=\'ink\'></span>');
} else {
element.appendChild(inkEl);
}
}
const ink = element.querySelector('.ink');
this.removeClass(ink, 'ripple-animate');
if (!ink.offsetHeight && !ink.offsetWidth) {
const d = Math.max(element.offsetWidth, element.offsetHeight);
ink.style.height = d + 'px';
ink.style.width = d + 'px';
}
const x = e.pageX - this.getOffset(element).left - (ink.offsetWidth / 2);
const y = e.pageY - this.getOffset(element).top - (ink.offsetHeight / 2);
ink.style.top = y + 'px';
ink.style.left = x + 'px';
ink.style.pointerEvents = 'none';
this.addClass(ink, 'ripple-animate');
}
hasClass(element, className) {
if (element.classList) {
return element.classList.contains(className);
} else {
return new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className);
}
}
addClass(element, className) {
if (element.classList) {
element.classList.add(className);
} else {
element.className += ' ' + className;
}
}
removeClass(element, className) {
if (element.classList) {
element.classList.remove(className);
} else {
element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
}
getOffset(el) {
const rect = el.getBoundingClientRect();
return {
top: rect.top + (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0),
left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0),
};
}
unbindRipple() {
if (this.rippleInitListener) {
document.removeEventListener('DOMContentLoaded', this.rippleInitListener);
}
if (this.rippleMouseDownListener) {
document.removeEventListener('mousedown', this.rippleMouseDownListener);
}
}
ngAfterViewInit() {
this.layoutContainer = <HTMLDivElement>this.layourContainerViewChild.nativeElement;
setTimeout(() => { this.layoutMenuScrollerViewChild.moveBar(); }, 100);
}
onLayoutClick() {
if (!this.topbarItemClick) {
this.activeTopbarItem = null;
this.topbarMenuActive = false;
}
if (!this.menuClick) {
if (this.isHorizontal() || this.isSlim()) {
this.resetMenu = true;
}
if (this.overlayMenuActive || this.staticMenuMobileActive) {
this.hideOverlayMenu();
}
this.menuHoverActive = false;
}
if (!this.rightPanelClick) {
this.rightPanelActive = false;
}
this.topbarItemClick = false;
this.menuClick = false;
this.rightPanelClick = false;
}
onMenuButtonClick(event) {
this.menuClick = true;
this.rotateMenuButton = !this.rotateMenuButton;
this.topbarMenuActive = false;
if (this.layoutMode === MenuOrientation.OVERLAY) {
this.overlayMenuActive = !this.overlayMenuActive;
} else {
if (this.isDesktop()) {
this.staticMenuDesktopInactive = !this.staticMenuDesktopInactive;
} else {
this.staticMenuMobileActive = !this.staticMenuMobileActive;
}
}
event.preventDefault();
}
onMenuClick($event) {
this.menuClick = true;
this.resetMenu = false;
}
onTopbarMenuButtonClick(event) {
this.topbarItemClick = true;
this.topbarMenuActive = !this.topbarMenuActive;
this.hideOverlayMenu();
event.preventDefault();
}
onTopbarItemClick(event, item) {
this.topbarItemClick = true;
if (this.activeTopbarItem === item) {
this.activeTopbarItem = null;
} else {
this.activeTopbarItem = item;
}
event.preventDefault();
}
onRightPanelButtonClick(event) {
this.rightPanelClick = true;
this.rightPanelActive = !this.rightPanelActive;
event.preventDefault();
}
onRightPanelClick() {
this.rightPanelClick = true;
}
hideOverlayMenu() {
this.rotateMenuButton = false;
this.overlayMenuActive = false;
this.staticMenuMobileActive = false;
}
isTablet() {
const width = window.innerWidth;
return width <= 1024 && width > 640;
}
isDesktop() {
return window.innerWidth > 1024;
}
isMobile() {
return window.innerWidth <= 640;
}
isOverlay() {
return this.layoutMode === MenuOrientation.OVERLAY;
}
isHorizontal() {
return this.layoutMode === MenuOrientation.HORIZONTAL;
}
isSlim() {
return this.layoutMode === MenuOrientation.SLIM;
}
changeToStaticMenu() {
this.layoutMode = MenuOrientation.STATIC;
}
changeToOverlayMenu() {
this.layoutMode = MenuOrientation.OVERLAY;
}
changeToHorizontalMenu() {
this.layoutMode = MenuOrientation.HORIZONTAL;
}
changeToSlimMenu() {
this.layoutMode = MenuOrientation.SLIM;
}
ngOnDestroy() {
this.unbindRipple();
}
isAuthRouteActivated() {
return this.router.url.indexOf('/auth') > -1;
} }
} }

View File

@ -1,21 +1,44 @@
import { NgModule, APP_INITIALIZER} from '@angular/core'; import { NgModule, APP_INITIALIZER} from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { AppMenuComponent } from 'app/commons/component/layout/menu/app.menu.component';
import { AppSubMenuComponent } from 'app/commons/component/layout/menu/app.submenu.component';
import { AppTopbarComponent } from 'app/commons/component/layout/topbar/app.topbar.component';
import { AppFooterComponent } from 'app/commons/component/layout/footer/app.footer.component';
import { AppBreadcrumbComponent } from 'app/commons/component/layout/breadcrumb/app.breadcrumb.component';
import { AppRightpanelComponent } from 'app/commons/component/layout/right-panel/app.rightpanel.component';
import { AppInlineProfileComponent } from 'app/commons/component/layout/profile/app.profile.component';
import { BreadcrumbService } from 'app/commons/component/layout/breadcrumb/breadcrumb.service';
import { import {
LocalizationModule, LocalizationModule,
} from 'angular-l10n'; } from 'angular-l10n';
import { PagesComponent } from './pages.component'; import { PagesComponent } from './pages.component';
import { PagesRoutingModule } from './pages-routing.module'; import { PagesRoutingModule } from './pages-routing.module';
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
import { PrimeNGModules } from 'packages/commons/prime-ng/prime-ng.module';
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, CommonModule,
PagesRoutingModule, PagesRoutingModule,
LocalizationModule, LocalizationModule,
PrimeNGModules,
], ],
declarations: [ declarations: [
PagesComponent, PagesComponent,
AppMenuComponent,
AppSubMenuComponent,
AppTopbarComponent,
AppFooterComponent,
AppBreadcrumbComponent,
AppRightpanelComponent,
AppInlineProfileComponent,
], ],
providers: [
{ provide: LocationStrategy, useClass: HashLocationStrategy },
BreadcrumbService,
]
}) })
export class PagesModule { } export class PagesModule { }

View File

@ -1,149 +1,140 @@
import {NgModule} from '@angular/core'; import { NgModule, ModuleWithProviders } from '@angular/core';
import {FormsModule} from '@angular/forms'; import { AccordionModule } from 'primeng/primeng';
import {HttpModule} from '@angular/http'; import { AutoCompleteModule } from 'primeng/primeng';
import {BrowserModule} from '@angular/platform-browser'; import { BreadcrumbModule } from 'primeng/primeng';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; import { ButtonModule } from 'primeng/primeng';
import {LocationStrategy, HashLocationStrategy} from '@angular/common'; import { CalendarModule } from 'primeng/primeng';
import {AccordionModule} from 'primeng/primeng'; import { CarouselModule } from 'primeng/primeng';
import {AutoCompleteModule} from 'primeng/primeng'; import { ColorPickerModule } from 'primeng/primeng';
import {BreadcrumbModule} from 'primeng/primeng'; import { ChartModule } from 'primeng/primeng';
import {ButtonModule} from 'primeng/primeng'; import { CheckboxModule } from 'primeng/primeng';
import {CalendarModule} from 'primeng/primeng'; import { ChipsModule } from 'primeng/primeng';
import {CarouselModule} from 'primeng/primeng'; import { CodeHighlighterModule } from 'primeng/primeng';
import {ColorPickerModule} from 'primeng/primeng'; import { ConfirmDialogModule } from 'primeng/primeng';
import {ChartModule} from 'primeng/primeng'; import { SharedModule } from 'primeng/primeng';
import {CheckboxModule} from 'primeng/primeng'; import { ContextMenuModule } from 'primeng/primeng';
import {ChipsModule} from 'primeng/primeng'; import { DataGridModule } from 'primeng/primeng';
import {CodeHighlighterModule} from 'primeng/primeng'; import { DataListModule } from 'primeng/primeng';
import {ConfirmDialogModule} from 'primeng/primeng'; import { DataScrollerModule } from 'primeng/primeng';
import {SharedModule} from 'primeng/primeng'; import { DataTableModule } from 'primeng/primeng';
import {ContextMenuModule} from 'primeng/primeng'; import { DialogModule } from 'primeng/primeng';
import {DataGridModule} from 'primeng/primeng'; import { DragDropModule } from 'primeng/primeng';
import {DataListModule} from 'primeng/primeng'; import { DropdownModule } from 'primeng/primeng';
import {DataScrollerModule} from 'primeng/primeng'; import { EditorModule } from 'primeng/primeng';
import {DataTableModule} from 'primeng/primeng'; import { FieldsetModule } from 'primeng/primeng';
import {DialogModule} from 'primeng/primeng'; import { FileUploadModule } from 'primeng/primeng';
import {DragDropModule} from 'primeng/primeng'; import { GalleriaModule } from 'primeng/primeng';
import {DropdownModule} from 'primeng/primeng'; import { GMapModule } from 'primeng/primeng';
import {EditorModule} from 'primeng/primeng'; import { GrowlModule } from 'primeng/primeng';
import {FieldsetModule} from 'primeng/primeng'; import { InputMaskModule } from 'primeng/primeng';
import {FileUploadModule} from 'primeng/primeng'; import { InputSwitchModule } from 'primeng/primeng';
import {GalleriaModule} from 'primeng/primeng'; import { InputTextModule } from 'primeng/primeng';
import {GMapModule} from 'primeng/primeng'; import { InputTextareaModule } from 'primeng/primeng';
import {GrowlModule} from 'primeng/primeng'; import { LightboxModule } from 'primeng/primeng';
import {InputMaskModule} from 'primeng/primeng'; import { ListboxModule } from 'primeng/primeng';
import {InputSwitchModule} from 'primeng/primeng'; import { MegaMenuModule } from 'primeng/primeng';
import {InputTextModule} from 'primeng/primeng'; import { MenuModule } from 'primeng/primeng';
import {InputTextareaModule} from 'primeng/primeng'; import { MenubarModule } from 'primeng/primeng';
import {LightboxModule} from 'primeng/primeng'; import { MessagesModule } from 'primeng/primeng';
import {ListboxModule} from 'primeng/primeng'; import { MultiSelectModule } from 'primeng/primeng';
import {MegaMenuModule} from 'primeng/primeng'; import { OrderListModule } from 'primeng/primeng';
import {MenuModule} from 'primeng/primeng'; import { OrganizationChartModule } from 'primeng/primeng';
import {MenubarModule} from 'primeng/primeng'; import { OverlayPanelModule } from 'primeng/primeng';
import {MessagesModule} from 'primeng/primeng'; import { PaginatorModule } from 'primeng/primeng';
import {MultiSelectModule} from 'primeng/primeng'; import { PanelModule } from 'primeng/primeng';
import {OrderListModule} from 'primeng/primeng'; import { PanelMenuModule } from 'primeng/primeng';
import {OrganizationChartModule} from 'primeng/primeng'; import { PasswordModule } from 'primeng/primeng';
import {OverlayPanelModule} from 'primeng/primeng'; import { PickListModule } from 'primeng/primeng';
import {PaginatorModule} from 'primeng/primeng'; import { ProgressBarModule } from 'primeng/primeng';
import {PanelModule} from 'primeng/primeng'; import { RadioButtonModule } from 'primeng/primeng';
import {PanelMenuModule} from 'primeng/primeng'; import { RatingModule } from 'primeng/primeng';
import {PasswordModule} from 'primeng/primeng'; import { ScheduleModule } from 'primeng/primeng';
import {PickListModule} from 'primeng/primeng'; import { ScrollPanelModule } from 'primeng/scrollpanel';
import {ProgressBarModule} from 'primeng/primeng'; import { SelectButtonModule } from 'primeng/primeng';
import {RadioButtonModule} from 'primeng/primeng'; import { SlideMenuModule } from 'primeng/primeng';
import {RatingModule} from 'primeng/primeng'; import { SliderModule } from 'primeng/primeng';
import {ScheduleModule} from 'primeng/primeng'; import { SpinnerModule } from 'primeng/primeng';
import {ScrollPanelModule} from 'primeng/scrollpanel'; import { SplitButtonModule } from 'primeng/primeng';
import {SelectButtonModule} from 'primeng/primeng'; import { StepsModule } from 'primeng/primeng';
import {SlideMenuModule} from 'primeng/primeng'; import { TableModule } from 'primeng/table';
import {SliderModule} from 'primeng/primeng'; import { TabMenuModule } from 'primeng/primeng';
import {SpinnerModule} from 'primeng/primeng'; import { TabViewModule } from 'primeng/primeng';
import {SplitButtonModule} from 'primeng/primeng'; import { TerminalModule } from 'primeng/primeng';
import {StepsModule} from 'primeng/primeng'; import { TieredMenuModule } from 'primeng/primeng';
import {TableModule} from 'primeng/table'; import { ToggleButtonModule } from 'primeng/primeng';
import {TabMenuModule} from 'primeng/primeng'; import { ToolbarModule } from 'primeng/primeng';
import {TabViewModule} from 'primeng/primeng'; import { TooltipModule } from 'primeng/primeng';
import {TerminalModule} from 'primeng/primeng'; import { TreeModule } from 'primeng/primeng';
import {TieredMenuModule} from 'primeng/primeng'; import { TreeTableModule } from 'primeng/primeng';
import {ToggleButtonModule} from 'primeng/primeng';
import {ToolbarModule} from 'primeng/primeng';
import {TooltipModule} from 'primeng/primeng';
import {TreeModule} from 'primeng/primeng';
import {TreeTableModule} from 'primeng/primeng';
const PRIME_NG_MODULES: any[] = [ const PRIME_NG_MODULES: any[] = [
BrowserModule, AccordionModule,
FormsModule, AutoCompleteModule,
HttpModule, BreadcrumbModule,
BrowserAnimationsModule, ButtonModule,
AccordionModule, CalendarModule,
AutoCompleteModule, CarouselModule,
BreadcrumbModule, ColorPickerModule,
ButtonModule, ChartModule,
CalendarModule, CheckboxModule,
CarouselModule, ChipsModule,
ColorPickerModule, CodeHighlighterModule,
ChartModule, ConfirmDialogModule,
CheckboxModule, SharedModule,
ChipsModule, ContextMenuModule,
CodeHighlighterModule, DataGridModule,
ConfirmDialogModule, DataListModule,
SharedModule, DataScrollerModule,
ContextMenuModule, DataTableModule,
DataGridModule, DialogModule,
DataListModule, DragDropModule,
DataScrollerModule, DropdownModule,
DataTableModule, EditorModule,
DialogModule, FieldsetModule,
DragDropModule, FileUploadModule,
DropdownModule, GalleriaModule,
EditorModule, GMapModule,
FieldsetModule, GrowlModule,
FileUploadModule, InputMaskModule,
GalleriaModule, InputSwitchModule,
GMapModule, InputTextModule,
GrowlModule, InputTextareaModule,
InputMaskModule, LightboxModule,
InputSwitchModule, ListboxModule,
InputTextModule, MegaMenuModule,
InputTextareaModule, MenuModule,
LightboxModule, MenubarModule,
ListboxModule, MessagesModule,
MegaMenuModule, MultiSelectModule,
MenuModule, OrderListModule,
MenubarModule, OrganizationChartModule,
MessagesModule, OverlayPanelModule,
MultiSelectModule, PaginatorModule,
OrderListModule, PanelModule,
OrganizationChartModule, PanelMenuModule,
OverlayPanelModule, PasswordModule,
PaginatorModule, PickListModule,
PanelModule, ProgressBarModule,
PanelMenuModule, RadioButtonModule,
PasswordModule, RatingModule,
PickListModule, ScheduleModule,
ProgressBarModule, ScrollPanelModule,
RadioButtonModule, SelectButtonModule,
RatingModule, SlideMenuModule,
ScheduleModule, SliderModule,
ScrollPanelModule, SpinnerModule,
SelectButtonModule, SplitButtonModule,
SlideMenuModule, StepsModule,
SliderModule, TableModule,
SpinnerModule, TabMenuModule,
SplitButtonModule, TabViewModule,
StepsModule, TerminalModule,
TableModule, TieredMenuModule,
TabMenuModule, ToggleButtonModule,
TabViewModule, ToolbarModule,
TerminalModule, TooltipModule,
TieredMenuModule, TreeModule,
ToggleButtonModule, TreeTableModule
ToolbarModule,
TooltipModule,
TreeModule,
TreeTableModule
]; ];
@NgModule({ @NgModule({
@ -154,4 +145,4 @@ const PRIME_NG_MODULES: any[] = [
PRIME_NG_MODULES PRIME_NG_MODULES
], ],
}) })
export class PrimeNGModules { } export class PrimeNGModules {}

View File

@ -0,0 +1,5 @@
// import { SettingComponent } from './setting/setting.component';
// export const COMPONENTS = [
// SettingComponent,
// ];

View File

@ -0,0 +1,85 @@
<div *ngIf="!started">
<h2 mat-dialog-title>Discovery Setting</h2>
<mat-dialog-content>
<mat-card>
<mat-card-header>
<mat-card-title>Zone</mat-card-title>
<mat-card-subtitle>{{cidr}}</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<!-- <form (ngSubmit)="discovery()"> -->
<div>
<div>
<mat-checkbox [checked]="true" [(ngModel)]="hostChecked" (change)="handleHostCheckChange($event)">Host</mat-checkbox>
</div>
<div>
<mat-form-field *ngIf="hostChecked">
<input matInput placeholder="Start IP" type="string" [(ngModel)]="startIP">
</mat-form-field>
<mat-form-field *ngIf="hostChecked">
<input matInput placeholder="End IP" type="string" [(ngModel)]="endIP">
</mat-form-field>
</div>
</div>
<div>
<div>
<mat-checkbox [(ngModel)]="portChecked" (change)="handlePortCheckChange($event)">Port</mat-checkbox>
</div>
<div>
<div *ngIf="portChecked">
<mat-slide-toggle [checked]="true" [(ngModel)]="tcpChecked">TCP</mat-slide-toggle>
<mat-slide-toggle [checked]="true" [(ngModel)]="udpChecked">UDP</mat-slide-toggle>
</div>
<mat-form-field *ngIf="portChecked">
<input matInput placeholder="Start Port" type="number" [(ngModel)]="startPort">
</mat-form-field>
<mat-form-field *ngIf="portChecked">
<input matInput placeholder="End Port" type="number" [(ngModel)]="endPort">
</mat-form-field>
</div>
</div>
<div>
<div>
<mat-checkbox [(ngModel)]="serviceChecked" (change)="handleServiceCheckChange($event)">Service</mat-checkbox>
</div>
<div>
<of-input-chip *ngIf="serviceChecked" [unselectedItems]="serviceItems" (change)="handleServiceChange($event)"></of-input-chip>
</div>
</div>
<!-- </form> -->
</mat-card-content>
</mat-card>
</mat-dialog-content>
<mat-dialog-actions fxLayoutAlign="end">
<button mat-button mat-dialog-close>Cancel</button>
<button mat-button color="primary" (click)="discovery()">Start</button>
<!-- <button mat-raised-button type="submit" color="primary">Start</button> -->
</mat-dialog-actions>
</div>
<div *ngIf="started">
<tree-root id="tree2" [focused]="true" [nodes]="treeNodes">
<ng-template #treeNodeFullTemplate let-node let-index="index" let-templates="templates">
<div class="tree-node">
<input type="checkbox" [checked]="node.isActive" (change)="checkDiscoveryResult(node)" />
<tree-node-expander [node]="node"></tree-node-expander>
<div class="node-content-wrapper" [class.node-content-wrapper-active]="node.isActive" [class.node-content-wrapper-focused]="node.isFocused"
(click)="checkDiscoveryResult(node)">
<span [class]="node.data.className" [class.title]="true">{{ node.data.title }}</span>
</div>
<tree-node-children [node]="node" [templates]="templates"></tree-node-children>
</div>
</ng-template>
</tree-root>
<mat-dialog-actions fxLayoutAlign="end">
<button mat-button mat-dialog-close>Cancel</button>
<button mat-button color="primary" (click)="discoveryResultSave()">Save</button>
<!-- <button mat-raised-button type="submit" color="primary">Start</button> -->
</mat-dialog-actions>
</div>

View File

@ -1,20 +1,20 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SidebarComponent } from './sidebar.component'; import { SettingComponent } from './setting.component';
describe('SidebarComponent', () => { describe('SettingComponent', () => {
let component: SidebarComponent; let component: SettingComponent;
let fixture: ComponentFixture<SidebarComponent>; let fixture: ComponentFixture<SettingComponent>;
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ SidebarComponent ] declarations: [ SettingComponent ]
}) })
.compileComponents(); .compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(SidebarComponent); fixture = TestBed.createComponent(SettingComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

@ -0,0 +1,392 @@
// import { Component, OnInit, AfterContentInit } from '@angular/core';
// import { Store, select } from '@ngrx/store';
// import { RPCClientError } from '@loafer/ng-rpc/protocol';
// import {
// DiscoveryStartInfo,
// DiscoveryZone,
// Zone,
// DiscoveryPort,
// DiscoveryService
// } from '../../model';
// import * as CIDR from 'ip-cidr';
// import * as DiscoveredStore from '../../store/setting';
// // import * as DiscoverStore from '../../store/discover';
// import { SettingSelector, DiscoverSelector } from '../../store';
// import * as DiscoverStore from '../../store/discover';
// import * as RegistStore from '../../store/regist';
// import { Host } from 'packages/discovery/model/Host';
// import { Port } from 'packages/discovery/model/Port';
// import { Service } from 'packages/discovery/model/Service';
// import * as ProbeDetailStore from 'packages/probe/store';
// import { Probe } from 'packages/probe/model';
// import { DetailSelector as ProbeDetailSelector } from 'packages/probe/store';
// @Component({
// selector: 'of-setting',
// templateUrl: './setting.component.html',
// styleUrls: ['./setting.component.scss']
// })
// export class SettingComponent implements OnInit, AfterContentInit {
// probe$ = this.probeDetailStore.pipe(select(ProbeDetailSelector.select('probe')));
// settingSucceed$: any;
// discoveryResult$: any;
// probe: Probe = null;
// started = false;
// cidr;
// startIP;
// endIP;
// startPort;
// endPort;
// // private settingForm: FormGroup;
// hostChecked = true;
// portChecked = true;
// serviceChecked = true;
// tcpChecked = true;
// udpChecked = true;
// includeServices = null;
// serviceItems = [
// { name: 'SSH' },
// { name: 'PostgreSQL' },
// { name: 'DNS' },
// { name: 'WMI'},
// { name: 'SMB' },
// { name: 'ActiveDirectory' },
// { name: 'Cassandra' },
// { name: 'FTP' },
// { name: 'HTTP' },
// { name: 'IMAP' },
// { name: 'LDAP' },
// { name: 'MongoDB' },
// { name: 'MySQL' },
// { name: 'NBSS' },
// ];
// treeNodes = [];
// zones: Map<string, Zone> = null;
// checkedSet = new Set();
// constructor(
// private discoverdstore: Store<DiscoveredStore.State>,
// private discoverstore: Store<DiscoverStore.State>,
// private registStore: Store<RegistStore.State>,
// private probeDetailStore: Store<ProbeDetailStore.State>
// ) {
// this.settingSucceed$ = discoverdstore.pipe(select(SettingSelector.select('isStart')));
// this.discoveryResult$ = this.discoverstore.pipe(select(DiscoverSelector.select('zones')));
// }
// ngOnInit() {
// this.settingSucceed$.subscribe(
// (succeed: boolean) => {
// if (succeed) {
// this.started = true;
// }
// },
// (error: RPCClientError) => {
// console.log(error.response.message);
// }
// );
// this.probe$.subscribe(
// (probe: Probe) => {
// if (probe != null) {
// this.probe = probe;
// }
// },
// (error: RPCClientError) => {
// console.log(error.response.message);
// }
// );
// this.discoveryResult$.subscribe(
// (zones: Map<string, Zone>) => {
// console.log('ZoneZoneZoneZoneZoneZoneZone');
// // console.log(JSON.stringify(zones));
// this.convertTreeViewZone(zones);
// this.zones = zones;
// },
// (error: RPCClientError) => {
// console.log(error.response.message);
// }
// );
// }
// isZone(zone: Zone): boolean {
// for (let i = 0; i < this.treeNodes.length; ++i) {
// if (zone.iface === this.treeNodes[i].iface) {
// return true;
// }
// }
// return false;
// }
// convertTreeViewZone(zones: Map<string, Zone>) {
// if (zones === undefined || zones === null) {
// return;
// }
// // console.log('convertTreeViewZone');
// const treeNodes: any[] = [];
// zones.forEach((value: Zone, key: string, map) => {
// if (this.isZone(value)) {
// return;
// }
// const jZone: any = {
// title: 'Zone - ' + value.iface,
// className: 'cn' + value.ip
// };
// jZone.obj = value;
// jZone.children = this.convertViewHost(value.hosts);
// treeNodes.push(jZone);
// });
// this.treeNodes = treeNodes;
// }
// ngAfterContentInit() {
// this.cidr = '192.168.1.0/24';
// this.hostRange();
// this.portRange();
// }
// hostRange() {
// const cidr = new CIDR(this.cidr);
// if (!cidr.isValid()) {
// alert('Invalid cidr : ' + this.cidr);
// return;
// }
// this.startIP = cidr.addressStart.address;
// this.endIP = cidr.addressEnd.address;
// }
// portRange() {
// this.startPort = '1';
// this.endPort = '1024';
// }
// handleHostCheckChange(e: MatCheckboxChange) {
// this.hostChecked = true;
// e.source.checked = true;
// }
// handlePortCheckChange(e: MatCheckboxChange) {
// this.serviceChecked = false;
// }
// handleServiceCheckChange(e: MatCheckboxChange) {
// if (e.checked) {
// this.portChecked = true;
// }
// }
// handleServiceChange(list: any) {
// this.includeServices = list;
// }
// discovery() {
// let discoveryPort: DiscoveryPort = null;
// let discoveryService: DiscoveryService = null;
// if (this.serviceChecked) {
// const services = new Array();
// for (const service of this.includeServices) {
// services.push(service.name);
// }
// discoveryService = {
// includeServices: services,
// };
// }
// if (this.portChecked) {
// discoveryPort = {
// firstScanRange: this.startPort,
// lastScanRange: this.endPort,
// includeTCP: this.tcpChecked,
// includeUDP: this.udpChecked,
// excludePorts: null,
// discoveryService: discoveryService
// };
// }
// const discoveryZone: DiscoveryZone = {
// discoveryHost: {
// firstScanRange: this.startIP,
// lastScanRange: this.endIP,
// discoveryPort: discoveryPort,
// },
// };
// console.log(discoveryZone);
// console.log('start discovery - ' + this.probe.probeKey);
// this.discoverstore.dispatch(new DiscoverStore.DiscoverZone(
// { probeID: this.probe.probeKey, discoveryZone: discoveryZone }));
// this.started = true;
// }
// checkDiscoveryResult(node) {
// node.toggleActivated(true);
// if (node.isActive) {
// if (node.data.obj !== undefined) {
// node.data.obj.target = true;
// }
// } else {
// if (node.data.obj !== undefined) {
// node.data.obj.target = false;
// }
// }
// console.log(this.zones);
// }
// convertMapToList(map: Map<any, any>): Array<any> {
// if (undefined === map || null === map || map.size < 0) {
// return null;
// }
// const retArr = new Array();
// map.forEach((v: any, k: any) => {
// retArr.push(v);
// });
// return retArr;
// }
// discoveryResultSave() {
// // console.log(this.checkedSet);
// // send discovery save this.zones;
// // this.registStore.dispatch(new DiscoverStore.DiscoverZone(
// // {probeID: '52abd6fd57e511e7ac52080027658d13', discoveryZone: discoveryZone}));
// this.zones.forEach((zone: Zone, key: string) => {
// if (zone.hosts !== undefined && zone.hosts !== null && zone.hosts.size > 0) {
// // FIXME: getHosts
// const hosts: Host[] = [];
// zone.hosts.forEach((h: Host, hKey: string) => {
// // if (h.ports !== undefined && h.ports !== null) {
// // h.portList = [];
// // h.ports.forEach((p: Port, pKey: number) => {
// // if (p.services !== undefined && p.services !== null) {
// // p.serviceList = [];
// // p.services.forEach((s: Service, sKey: string) => {
// // p.serviceList.push(s);
// // });
// // }
// // h.portList.push(p);
// // });
// // }
// hosts.push(h);
// });
// if (hosts.length > 0) {
// const sd: any = { hosts: hosts, probe: { id: 1 } };
// console.log(JSON.stringify(sd));
// console.log('--------');
// this.registStore.dispatch(new RegistStore.DiscoverySaveAllTarget(sd));
// }
// }
// });
// }
// convertViewHost(hosts): any[] {
// if (hosts === undefined || hosts === null) {
// return null;
// }
// const hostNodes: any[] = [];
// hosts.forEach((host, hostKey) => {
// const jHost: any = {
// title: 'Host - ' + host.ip,
// className: 'cn' + host.ip
// };
// jHost.obj = host;
// jHost.children = this.convertViewPort(host.ports);
// hostNodes.push(jHost);
// });
// return hostNodes;
// }
// convertViewPort(ports): any[] {
// if (ports === undefined || ports === null) {
// return null;
// }
// const portChildren: any[] = [];
// ports.forEach((port, portKey) => {
// const jPort: any = {
// title: 'Port - ' + port.portNumber,
// className: 'cn' + port.portNumber,
// };
// jPort.obj = port;
// jPort.children = this.convertViewService(port.services);
// portChildren.push(jPort);
// });
// return portChildren;
// }
// convertViewService(services): any[] {
// if (services === undefined || services === null || services.size <= 0) {
// return null;
// }
// const serviceChildren: any[] = [];
// services.forEach((service, serviceKey) => {
// const jService: any = {
// title: 'Service - ' + service.serviceName,
// className: 'cn' + service.serviceName,
// };
// jService.obj = service;
// serviceChildren.push(jService);
// });
// return serviceChildren;
// }
// }

View File

@ -0,0 +1,10 @@
import { NgModule } from '@angular/core';
import { LoggerModule } from '@loafer/ng-logger';
@NgModule({
imports: [
LoggerModule.forFeature({}),
],
})
export class DiscoveryLoggerModule { }

View File

@ -0,0 +1,13 @@
import { NgModule } from '@angular/core';
import { RPCModule } from '@loafer/ng-rpc';
import {
SUBSCRIBERS,
} from './subscriber';
@NgModule({
imports: [
RPCModule.forFeature({subscribers: SUBSCRIBERS}),
],
})
export class DiscoveryRPCModule { }

View File

@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import {
REDUCERS,
EFFECTS,
} from './store';
import { MODULE } from './discovery.constant';
@NgModule({
imports: [
StoreModule.forFeature(MODULE.name, REDUCERS),
EffectsModule.forFeature(EFFECTS),
],
})
export class DiscoveryStoreModule { }

View File

@ -0,0 +1,3 @@
export const MODULE = {
name: 'discovery'
};

View File

@ -0,0 +1,39 @@
// import { NgModule, Inject } from '@angular/core';
// import { CommonModule } from '@angular/common';
// import { FormsModule } from '@angular/forms';
// import { MaterialModule } from 'packages/commons/material/material.module';
// import { InputChipModule } from 'packages/commons/component/input-chip/input-chip.module';
// import { DiscoveryStoreModule } from './discovery-store.module';
// import { DiscoveryRPCModule } from './discovery-rpc.module';
// import { DiscoveryLoggerModule } from './discovery-logger.module';
// import { COMPONENTS } from './component';
// import { SERVICES } from './service';
// import { TreeModule } from 'angular-tree-component';
// @NgModule({
// imports: [
// CommonModule,
// MaterialModule,
// InputChipModule,
// FormsModule,
// TreeModule,
// DiscoveryStoreModule,
// DiscoveryRPCModule,
// DiscoveryLoggerModule,
// ],
// declarations: [
// COMPONENTS
// ],
// exports: [
// COMPONENTS,
// ],
// providers: [
// SERVICES,
// ],
// })
// export class DiscoveryModule {
// }

View File

@ -0,0 +1,10 @@
import { DiscoveryPort } from './DiscoveryPort';
export interface DiscoveryHost {
firstScanRange?: string;
lastScanRange?: string;
excludeHosts?: string[];
includeHosts?: string[];
discoveryPort?: DiscoveryPort;
}

View File

@ -0,0 +1,11 @@
import { DiscoveryService } from './DiscoveryService';
export interface DiscoveryPort {
firstScanRange: number;
lastScanRange: number;
excludePorts: number[];
includeTCP: boolean;
includeUDP: boolean;
discoveryService?: DiscoveryService;
}

View File

@ -0,0 +1,3 @@
export interface DiscoveryService {
includeServices: string[];
}

View File

@ -0,0 +1,11 @@
export interface DiscoveryStartInfo {
startIp: string;
endIP: string;
excludeIp?: string;
startPort?: string;
endPort?: string;
services?: Array<string>;
}
// export default DiscoveryStartInfo;

View File

@ -0,0 +1,7 @@
import { DiscoveryHost } from './DiscoveryHost';
export interface DiscoveryZone {
excludePatterns?: string[];
discoveryHost?: DiscoveryHost;
}

View File

@ -0,0 +1,15 @@
import { Zone } from './Zone';
import { Port } from './Port';
export interface Host {
id?: number;
ip: string;
mac: number;
os: string;
discoveredDate?: Date;
zone?: Zone;
target?: boolean;
ports: Map<number, Port> | null;
portList: Port[] | null;
}

View File

@ -0,0 +1,15 @@
import { Host } from './Host';
import { PortType } from './PortType';
import { Service } from './Service';
export interface Port {
id?: number;
portType: PortType;
portNumber: number;
discoveredDate?: Date;
host: Host;
isTarget?: boolean;
services: Map<string, Service> | null;
serviceList: Service[] | null;
}

View File

@ -0,0 +1,8 @@
// enum PortType {
// TCP = 1,
// UDP = 2,
// TLS = 3,
// }
export type PortType = 'TCP' | 'UDP' | 'TLS';

View File

@ -0,0 +1,10 @@
import { Port } from './Port';
export interface Service {
id: number;
cryptoType: string;
serviceName: string;
discoveredDate?: Date;
port: Port;
isTarget?: boolean;
}

View File

@ -0,0 +1,12 @@
import { Host } from './Host';
export interface Zone {
id?: number;
network?: string;
ip?: string;
iface?: string;
mac?: string;
discoveredDate?: Date;
hosts: Map<string, Host> | null;
}

View File

@ -0,0 +1,11 @@
export * from './DiscoveryHost';
export * from './DiscoveryPort';
export * from './DiscoveryService';
export * from './DiscoveryZone';
export * from './DiscoveryStartInfo';
export * from './Host';
export * from './Port';
export * from './PortType';
export * from './Service';
export * from './Zone';

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { DiscoveryService } from './discovery.service';
describe('DiscoveryService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [DiscoveryService]
});
});
it('should be created', inject([DiscoveryService], (service: DiscoveryService) => {
expect(service).toBeTruthy();
}));
});

View File

@ -0,0 +1,42 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { RPCService } from '@loafer/ng-rpc/service';
import {
DiscoveryStartInfo,
DiscoveryZone,
DiscoveryHost,
DiscoveryPort,
DiscoveryService as M_DiscoveryService,
Zone,
Host,
Port,
Service,
} from '../model';
@Injectable()
export class DiscoveryService {
public constructor(
private rpcService: RPCService,
) {
}
public start(dsInfo: DiscoveryStartInfo): Observable<DiscoveryStartInfo> {
return this.rpcService.call('DiscoveryService.startDiscovery', dsInfo);
}
public discoverZone(probeID: string, discoveryZone: DiscoveryZone): void {
this.rpcService.send('DiscoveryService.discoverZone', probeID, discoveryZone);
}
public discoverHost(probeID: string, zone: Zone, discoveryHost: DiscoveryHost): void {
this.rpcService.send('DiscoveryService.discoverHost', probeID, zone, discoveryHost);
}
public discoverPort(probeID: string, host: Host, discoveryPort: DiscoveryPort): void {
this.rpcService.send('DiscoveryService.discoverPort', probeID, host, discoveryPort);
}
public discoverService(probeID: string, port: Port, discoveryService: M_DiscoveryService): void {
this.rpcService.send('DiscoveryService.discoverService', probeID, port, discoveryService);
}
}

View File

@ -0,0 +1,7 @@
import { DiscoveryService } from './discovery.service';
import { TargetDiscoveryService } from './target-discovery.service';
export const SERVICES = [
DiscoveryService,
TargetDiscoveryService,
];

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { TargetDiscoveryService } from './target-discovery.service';
describe('TargetDiscoveryService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [TargetDiscoveryService]
});
});
it('should be created', inject([TargetDiscoveryService], (service: TargetDiscoveryService) => {
expect(service).toBeTruthy();
}));
});

View File

@ -0,0 +1,31 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { RPCService } from '@loafer/ng-rpc/service';
import {
DiscoveryStartInfo,
DiscoveryZone,
DiscoveryHost,
DiscoveryPort,
DiscoveryService as M_DiscoveryService,
Zone,
Host,
Port,
Service,
} from '../model';
import { Probe } from 'packages/probe/model';
@Injectable()
export class TargetDiscoveryService {
public constructor(
private rpcService: RPCService,
) {
}
public saveAllTarget(hosts: Host[], probe: Probe): Observable<Boolean> {
return this.rpcService.call('TargetDiscoveryService.saveAllTarget', hosts, probe);
}
}

View File

@ -0,0 +1,82 @@
import { Action } from '@ngrx/store';
import {
Zone,
Host,
Port,
Service,
DiscoveryZone,
DiscoveryHost,
DiscoveryPort,
DiscoveryService as MDiscoveryService,
} from '../../model';
export enum ActionType {
DiscoverZone = '[discovery.discovery] discoverZone',
DiscoverHost = '[discovery.discovery] discoverHost',
DiscoverPort = '[discovery.discovery] discoverPort',
DiscoverService = '[discovery.discovery] discoverService',
DiscoveredZone = '[discovery.discovery] DiscoveryService.discoveredZone',
DiscoveredHost = '[discovery.discovery] DiscoveryService.discoveredHost',
DiscoveredPort = '[discovery.discovery] DiscoveryService.discoveredPort',
DiscoveredService = '[discovery.discovery] DiscoveryService.discoveredService',
}
export class DiscoverZone implements Action {
readonly type = ActionType.DiscoverZone;
constructor(public payload: {probeID: string, discoveryZone: DiscoveryZone}) {}
}
export class DiscoverHost implements Action {
readonly type = ActionType.DiscoverHost;
constructor(public payload: {probeID: string, zone: Zone, discoveryHost: DiscoveryHost}) {}
}
export class DiscoverPort implements Action {
readonly type = ActionType.DiscoverPort;
constructor(public payload: {probeID: string, host: Host, discoveryPort: DiscoveryPort}) {}
}
export class DiscoverService implements Action {
readonly type = ActionType.DiscoverService;
constructor(public payload: {probeID: string, port: Port, discoveryService: MDiscoveryService}) {}
}
export class DiscoveredZone implements Action {
readonly type = ActionType.DiscoveredZone;
constructor(public payload: Zone) {}
}
export class DiscoveredHost implements Action {
readonly type = ActionType.DiscoveredHost;
constructor(public payload: Host) {}
}
export class DiscoveredPort implements Action {
readonly type = ActionType.DiscoveredPort;
constructor(public payload: Port) {}
}
export class DiscoveredService implements Action {
readonly type = ActionType.DiscoveredService;
constructor(public payload: Service) {}
}
export type Actions =
| DiscoverZone
| DiscoverHost
| DiscoverPort
| DiscoverService
| DiscoveredZone
| DiscoveredHost
| DiscoveredPort
| DiscoveredService
;

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { Effects } from './discover.effect';
describe('Discover.Effects', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [Effects]
});
});
it('should be created', inject([Effects], (effects: Effects) => {
expect(effects).toBeTruthy();
}));
});

View File

@ -0,0 +1,66 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { Action } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/exhaustMap';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import {
DiscoverZone,
DiscoverHost,
DiscoverPort,
DiscoverService,
ActionType
} from './discover.action';
import {DiscoveryService} from '../../service/discovery.service';
@Injectable()
export class Effects {
constructor(private actions$: Actions,
private discoveryService: DiscoveryService,
private router: Router) {
}
@Effect({ dispatch: false })
discoveryZone$ = this.actions$
.ofType(ActionType.DiscoverZone)
.map((action: DiscoverZone) => action.payload)
.do(payload => {
this.discoveryService.discoverZone(payload.probeID, payload.discoveryZone);
});
@Effect({ dispatch: false })
discoveryHost$ = this.actions$
.ofType(ActionType.DiscoverHost)
.map((action: DiscoverHost) => action.payload)
.do(payload => {
this.discoveryService.discoverHost(payload.probeID, payload.zone, payload.discoveryHost);
});
@Effect({ dispatch: false })
discoveryPort$ = this.actions$
.ofType(ActionType.DiscoverPort)
.map((action: DiscoverPort) => action.payload)
.do(payload => {
this.discoveryService.discoverPort(payload.probeID, payload.host, payload.discoveryPort);
});
@Effect({ dispatch: false })
discoveryService$ = this.actions$
.ofType(ActionType.DiscoverService)
.map((action: DiscoverService) => action.payload)
.do(payload => {
this.discoveryService.discoverService(payload.probeID, payload.port, payload.discoveryService);
});
}

View File

@ -0,0 +1,205 @@
import {
Actions,
ActionType,
} from './discover.action';
import {
State,
initialState,
} from './discover.state';
import {
Zone,
Host,
Port,
Service,
} from '../../model';
// import * as _ 'lodash';
export function reducer(state = initialState, action: Actions): State {
switch (action.type) {
case ActionType.DiscoveredZone: {
const zone: Zone = <Zone>action.payload;
const zones: Map<string, Zone> = null === state.zones ? new Map() : state.zones;
zones.set(zone.network, zone);
const newZones: Map<string, Zone> = new Map();
zones.forEach(function(value, key) {
newZones.set(key, value);
});
return {
...state,
zones : newZones,
};
}
case ActionType.DiscoveredHost: {
const host: Host = <Host>action.payload;
let zone = null;
let zones: Map<string, Zone> = state.zones;
if (zones === undefined || zones === null) {
zones = new Map();
zone = host.zone;
// zones.set(zone.network, zone);
} else {
zone = zones.get(host.zone.network);
}
if (undefined === zone) {
// console.error(`Discovery.discoveredHost: Zone[${host.zone.network}] is not exist`);
zone = new Map();
}
if (null === zone.hosts || undefined === zone.hosts) {
zone.hosts = new Map();
zone.hosts.set(host.ip, host);
} else {
if (zone.hosts.has(host.ip) === false) {
zone.hosts.set(host.ip, host);
}
}
zones.set(zone.network, zone);
const newZones: Map<string, Zone> = new Map();
zones.forEach(function(value, key) {
newZones.set(key, value);
});
return {
...state,
zones: newZones
};
}
case ActionType.DiscoveredPort: {
const port: Port = <Port>action.payload;
let zone = state.zones.get(port.host.zone.network);
let zones: Map<string, Zone> = state.zones;
if (zones === undefined || zones === null) {
zones = new Map();
}
if (zone === undefined || zone === null) {
zone = port.host.zone;
}
// if (undefined === zone) {
// console.error(`Discovery.DiscoveredPort: Zone[${port.host.zone.network}] is not exist`);
// }
// if (null === zone.hosts || undefined === zone.hosts.get(port.host.ip)) {
// console.error(`Discovery.DiscoveredPort: Host[${port.host.ip}] is not exist`);
// return state;
// }
if (zone.hosts === undefined || zone.hosts === null) {
zone.hosts = new Map();
}
let host: Host = null;
host = zone.hosts.get(port.host.ip);
if (host === undefined || host === null) {
host = port.host;
}
if (null === host.ports || undefined === host.ports) {
host.ports = new Map();
host.ports.set(port.portNumber, port);
} else {
if (host.ports.has(port.portNumber) === false) {
host.ports.set(port.portNumber, port);
}
}
zone.hosts.set(host.ip, host);
zones.set(zone.network, zone);
const newZones: Map<string, Zone> = new Map();
zones.forEach(function(value, key) {
newZones.set(key, value);
});
return {
...state,
zones: newZones
};
}
case ActionType.DiscoveredService: {
const service: Service = <Service>action.payload;
let zone = state.zones.get(service.port.host.zone.network);
let zones: Map<string, Zone> = state.zones;
if (zones === undefined || zones === null) {
zones = new Map();
}
if (zone === undefined || zone === null) {
zone = service.port.host.zone;
}
if (zone.hosts === undefined || zone.hosts === null) {
zone.hosts = new Map();
}
zone.hosts.set(service.port.host.ip, service.port.host);
// if (undefined === zone) {
// console.error(`Discovery.DiscoveredService: Zone[${service.port.host.zone.network}] is not exist`);
// }
// if (null === zone.hosts || undefined === zone.hosts.get(service.port.host.ip)) {
// console.error(`Discovery.DiscoveredPort: Host[${service.port.host.ip}] is not exist`);
// }
const host: Host = zone.hosts.get(service.port.host.ip);
if (null === host.ports || undefined === host.ports) {
host.ports = new Map();
host.ports.set(service.port.portNumber, service.port);
}
const port: Port = host.ports.get(service.port.portNumber);
if (null === port.services || undefined === port.services) {
port.services = new Map();
}
port.services.set(service.serviceName, service);
host.ports.set(service.port.portNumber, port);
zone.hosts.set(host.ip, host);
zones.set(zone.network, zone);
const newZones: Map<string, Zone> = new Map();
zones.forEach(function(value, key) {
newZones.set(key, value);
});
return {
...state,
zones: newZones
};
}
default: {
return state;
}
}
}
// function checkZone(state, pZone: Zone) : {
// }

View File

@ -0,0 +1,16 @@
import { RPCClientError } from '@loafer/ng-rpc/protocol';
import { Zone } from '../../model';
export interface State {
error: RPCClientError | null;
processing: boolean;
zones: Map<string, Zone> | null;
}
export const initialState: State = {
error: null,
processing: false,
zones: null,
};

View File

@ -0,0 +1,4 @@
export * from './discover.action';
export * from './discover.reducer';
export * from './discover.state';
export * from './discover.effect';

View File

@ -0,0 +1,42 @@
import {
createSelector,
createFeatureSelector,
ActionReducerMap,
Selector,
} from '@ngrx/store';
import { StateSelector } from 'packages/core/ngrx/store';
import { MODULE } from '../discovery.constant';
import * as DiscoverStore from './discover';
import * as SettingStore from './setting';
export interface State {
discover: DiscoverStore.State;
setting: SettingStore.State;
}
export const REDUCERS = {
discover: DiscoverStore.reducer,
setting: SettingStore.reducer,
};
export const EFFECTS = [
SettingStore.Effects,
DiscoverStore.Effects,
];
export const selectDiscoveryState = createFeatureSelector<State>(MODULE.name);
export const DiscoverSelector = new StateSelector<DiscoverStore.State>(createSelector(
selectDiscoveryState,
(state: State) => state.discover
));
export const SettingSelector = new StateSelector<SettingStore.State>(createSelector(
selectDiscoveryState,
(state: State) => state.setting
));

View File

@ -0,0 +1,4 @@
export * from './regist.action';
export * from './regist.effect';
export * from './regist.reducer';
export * from './regist.state';

View File

@ -0,0 +1,45 @@
import { Action } from '@ngrx/store';
import { RPCClientError } from '@loafer/ng-rpc/protocol';
import {
Zone,
Host,
Port,
Service,
DiscoveryZone,
DiscoveryHost,
DiscoveryPort,
DiscoveryService as MDiscoveryService,
} from '../../model';
import { Probe } from 'packages/probe/model';
export enum ActionType {
SaveAllTarget = '[@@REGIST] TargetDiscoveryService.saveAllTarget',
SaveAllTargetSuccess = '[@@REGIST] TargetDiscoveryService.SaveAllTargetSuccess',
SaveAllTargetFailure = '[@@REGIST] TargetDiscoveryService.SaveAllTargetFailure',
}
export class DiscoverySaveAllTarget implements Action {
readonly type = ActionType.SaveAllTarget;
constructor(public payload: {hosts: Host[], probe: Probe}) {}
}
export class DiscoverySaveAllTargetSuccess implements Action {
readonly type = ActionType.SaveAllTargetSuccess;
constructor(public payload: Boolean) {}
}
export class DiscoverySaveAllTargetFailure implements Action {
readonly type = ActionType.SaveAllTargetFailure;
constructor(public payload: RPCClientError) {}
}
export type Actions =
| DiscoverySaveAllTarget
| DiscoverySaveAllTargetSuccess
| DiscoverySaveAllTargetFailure
;

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { Effects } from './regist.effect';
describe('Regist.Effects', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [Effects]
});
});
it('should be created', inject([Effects], (effects: Effects) => {
expect(effects).toBeTruthy();
}));
});

View File

@ -0,0 +1,51 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { Action } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/exhaustMap';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import { RPCClientError } from '@loafer/ng-rpc/protocol';
import { DiscoveryStartInfo } from '../../model';
import { TargetDiscoveryService } from '../../service/target-discovery.service';
import {
DiscoverySaveAllTarget,
DiscoverySaveAllTargetSuccess,
DiscoverySaveAllTargetFailure,
ActionType
} from './regist.action';
@Injectable()
export class Effects {
constructor(
private actions$: Actions,
private targetDiscoveryService: TargetDiscoveryService,
private router: Router
) { }
@Effect()
saveAllTargetResult$: Observable<Action> = this.actions$
.ofType(ActionType.SaveAllTarget)
.map((action: DiscoverySaveAllTarget) => action.payload)
.switchMap(payload => this.targetDiscoveryService.saveAllTarget(payload.hosts, payload.probe))
.map(result => {
return new DiscoverySaveAllTargetSuccess(result);
})
.catch((error: RPCClientError) => {
console.log(error.response.message);
return of(new DiscoverySaveAllTargetFailure(error));
});
}

View File

@ -0,0 +1,45 @@
import {
Actions,
ActionType,
} from './regist.action';
import {
State,
initialState,
} from './regist.state';
import { DiscoveryStartInfo } from '../../model';
export function reducer(state = initialState, action: Actions): State {
switch (action.type) {
case ActionType.SaveAllTarget: {
return {
...state,
error: null,
isPending: true,
};
}
case ActionType.SaveAllTargetSuccess: {
return {
...state,
error: null,
isPending: false,
isSuccess: action.payload,
};
}
case ActionType.SaveAllTargetFailure: {
return {
...state,
error: action.payload,
isPending: false,
isSuccess: null,
};
}
default: {
return state;
}
}
}

View File

@ -0,0 +1,18 @@
import { RPCClientError } from '@loafer/ng-rpc/protocol';
import { DiscoveryStartInfo } from '../../model';
export interface State {
error: RPCClientError | null;
isPending: boolean;
isSuccess: Boolean | null;
}
export const initialState: State = {
error: null,
isPending: false,
isSuccess: null,
};
export const getSuccess = (state: State) => state.isSuccess;

View File

@ -0,0 +1,4 @@
export * from './setting.action';
export * from './setting.effect';
export * from './setting.reducer';
export * from './setting.state';

View File

@ -0,0 +1,42 @@
import { Action } from '@ngrx/store';
import { RPCClientError } from '@loafer/ng-rpc/protocol';
import { DiscoveryStartInfo } from '../../model';
export enum ActionType {
Setting = '[discovery.setting] Setting',
SettingSuccess = '[discovery.setting] SettingSuccess',
SettingFailure = '[discovery.setting] SettingFailure',
SettingRedirect = '[discovery.setting] SettingRedirect',
}
export class Setting implements Action {
readonly type = ActionType.Setting;
constructor(public payload: DiscoveryStartInfo) {}
}
export class SettingSuccess implements Action {
readonly type = ActionType.SettingSuccess;
constructor(public payload: DiscoveryStartInfo) {}
}
export class SettingFailure implements Action {
readonly type = ActionType.SettingFailure;
constructor(public payload: RPCClientError) {}
}
export class SettingRedirect implements Action {
readonly type = ActionType.SettingRedirect;
}
export type Actions =
| Setting
| SettingSuccess
| SettingFailure
| SettingRedirect
;

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { Effects } from './setting.effect';
describe('Auth.Effects', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [Effects]
});
});
it('should be created', inject([Effects], (effects: Effects) => {
expect(effects).toBeTruthy();
}));
});

View File

@ -0,0 +1,51 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { Action } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/exhaustMap';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import { RPCClientError } from '@loafer/ng-rpc/protocol';
import { DiscoveryStartInfo } from '../../model';
import { DiscoveryService } from '../../service/discovery.service';
import {
Setting,
SettingSuccess,
SettingFailure,
ActionType,
} from './setting.action';
@Injectable()
export class Effects {
constructor(
private actions$: Actions,
private discoveryService: DiscoveryService,
private router: Router
) { }
@Effect()
startDiscovery$: Observable<Action> = this.actions$
.ofType(ActionType.Setting)
.map((action: Setting) => action.payload)
.switchMap(payload => this.discoveryService.start(payload))
.map(discoveryStartInfo => {
return new SettingSuccess(discoveryStartInfo);
})
.catch((error: RPCClientError) => {
console.log(error.response.message);
return of(new SettingFailure(error));
});
}

View File

@ -0,0 +1,48 @@
import {
Actions,
ActionType,
Setting,
} from './setting.action';
import {
State,
initialState,
} from './setting.state';
import { DiscoveryStartInfo } from '../../model';
export function reducer(state = initialState, action: Actions): State {
switch (action.type) {
case ActionType.Setting: {
return {
...state,
error: null,
isPending: true,
};
}
case ActionType.SettingSuccess: {
return {
...state,
isStart: true,
error: null,
isPending: false,
discoveryStartInfo: action.payload,
};
}
case ActionType.SettingFailure: {
return {
...state,
isStart: false,
error: action.payload,
isPending: false,
discoveryStartInfo: null,
};
}
default: {
return state;
}
}
}

View File

@ -0,0 +1,22 @@
import { RPCClientError } from '@loafer/ng-rpc/protocol';
import { DiscoveryStartInfo } from '../../model';
export interface State {
isStart: boolean;
error: RPCClientError | null;
isPending: boolean;
discoveryStartInfo: DiscoveryStartInfo | null;
}
export const initialState: State = {
isStart: false,
error: null,
isPending: false,
discoveryStartInfo: null,
};
export const isStart = (state: State) => state.isStart;
export const getDiscoveryStartInfo = (state: State) => state.discoveryStartInfo;
export const getError = (state: State) => state.error;
export const isPending = (state: State) => state.isPending;

View File

@ -0,0 +1,47 @@
import { Injectable } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { RPCSubscriber } from '@loafer/ng-rpc/decorator';
import { LoggerService } from '@loafer/ng-logger/service';
import * as DiscoverStore from '../store/discover';
import {
Zone,
Host,
Port,
Service,
} from '../model';
@Injectable()
export class DiscoverySubscriber {
public constructor(
private store: Store<DiscoverStore.State>,
private loggerService: LoggerService,
) {
this.loggerService.debug('dddddd');
}
@RPCSubscriber({method: 'DiscoveryService.discoveredZone'})
public discoveredZone(zone: Zone): void {
this.loggerService.debug('DiscoverySubscriber.discoveredZone zone:', zone);
this.store.dispatch(new DiscoverStore.DiscoveredZone(zone));
}
@RPCSubscriber({method: 'DiscoveryService.discoveredHost'})
public discoveredHost(host: Host): void {
// this.loggerService.debug('DiscoverySubscriber.discoveredHost host:', host);
this.store.dispatch(new DiscoverStore.DiscoveredHost(host));
}
@RPCSubscriber({method: 'DiscoveryService.discoveredPort'})
public discoveredPort(port: Port): void {
this.store.dispatch(new DiscoverStore.DiscoveredPort(port));
}
@RPCSubscriber({method: 'DiscoveryService.discoveredService'})
public discoveredService(service: Service): void {
this.loggerService.debug('DiscoverySubscriber.discoveredService service:', service);
this.store.dispatch(new DiscoverStore.DiscoveredService(service));
}
}

View File

@ -0,0 +1,5 @@
import { DiscoverySubscriber } from './discovery.subscriber';
export const SUBSCRIBERS = [
DiscoverySubscriber,
];

View File

@ -0,0 +1,5 @@
// import { MapComponent } from './map/map.component';
// export const COMPONENTS = [
// MapComponent,
// ];

View File

@ -0,0 +1,55 @@
<div fxLayoutAlign="end" [style.margin]="'10px 10px'">
<form class="form">
<mat-form-field class="full-width">
<input matInput placeholder="Search" [(ngModel)]="searchWord" (ngModelChange)="handleSearch($event)" [ngModelOptions]="{standalone: true}">
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
</form>
</div>
<div fxLayoutAlign="end" [style.margin]="'10px 10px'">
** probe가 설치된 host와 그 probe가 가장 상위에 나와야 함 **
<div class="box up"></div>Up
<div class="box down"></div>Down
<div class="box warn"></div>Warn
<div class="box error"></div>Error
</div>
<div *ngIf="loading" fxLayoutAlign="center">
<mat-spinner></mat-spinner>
</div>
<div *ngIf="!loading" class="search-result" infinite-scroll [infiniteScrollDistance]="2" [infiniteScrollThrottle]="50" (scrolled)="onScroll()" [scrollWindow]="false">
<div class="infra-list mat-elevation-z4 " *ngFor="let infra of hostDataList">
<mat-toolbar>
<mat-toolbar-row>
<span matTooltip="showHostInfo(infra)">IP : {{infra.host.ip}}</span>
<span class="pull-right"></span>
<span style="margin-right: 20px">
<!-- <of-sensor-name-tag [target]="infra.target"></of-sensor-name-tag> -->
</span>
<button mat-raised-button color="primary" fxLayoutAlign="end" (click)="addSensor(infra)">Add Sensor</button>
</mat-toolbar-row>
</mat-toolbar>
<mat-card-content *ngFor="let service of infra.services">
<mat-grid-list cols="6" rowHeight="9:1">
<mat-grid-tile [rowspan]="2" style="background-color: lightcoral">
{{service.vendor.name}}
</mat-grid-tile>
<mat-grid-tile [colspan]="3" style="background-color: lightblue">
<div class="grid-left-align">
Port : {{service.port}} | {{service.portType}} {{service.tlsType ? '| TLS' : ''}}
</div>
</mat-grid-tile>
<mat-grid-tile [rowspan]="2" style="background-color: lightgray">
<span class="pull-right"></span>
<button mat-button fxLayoutAlign="end" (click)="addSensor(infra)">Add Sensor</button>
</mat-grid-tile>
<mat-grid-tile [colspan]="3" style="background-color: lightgreen">
<div class="grid-left-align">
<!-- <of-sensor-name-tag [target]="service.target"></of-sensor-name-tag> -->
</div>
</mat-grid-tile>
</mat-grid-list>
</mat-card-content>
</div>
</div>

View File

@ -0,0 +1,78 @@
@mixin infra-list($theme) {
.infra-list{
margin: 10px 5px;
background: white;
}
.pull-right{
flex: 1 1 auto;
}
mat-list-item:hover {
background: #e8eaf6;
cursor: pointer;
}
.mat-chip {
padding: 1px 13px;
}
}
.nav-item {
transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
cursor: default;
&:hover {
transform: translate(0, -8px);
box-shadow: 0 20px 20px rgba(0, 0, 0, .16)
}
}
.infra-card {
width: 70%;
}
.grid-left-align {
position: absolute;
left: 5px;
}
.add-sensor-button {
position: absolute;
right: 1px;
}
.box{
float: left;
width: 13px;
height: 13px;
margin: 5px;
border: 1px solid rgba(0, 0, 0, .2);
}
.up{
background: green;
}
.down{
background: red;
}
.warn{
background: yellow;
}
.error{
background:red;
}
.form {
min-width: 150px;
max-width: 500px;
width: 100%;
}
.full-width {
width: 100%;
}
.search-result {
height: 80%;
overflow-y: scroll;
}

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MapComponent } from './map.component';
describe('MapComponent', () => {
let component: MapComponent;
let fixture: ComponentFixture<MapComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MapComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MapComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import {
REDUCERS,
EFFECTS,
} from './store';
import { MODULE } from './infra.constant';
@NgModule({
imports: [
StoreModule.forFeature(MODULE.name, REDUCERS),
EffectsModule.forFeature(EFFECTS),
],
})
export class InfraStoreModule { }

View File

@ -0,0 +1,3 @@
export const MODULE = {
name: 'infra'
};

View File

@ -0,0 +1,38 @@
// import { NgModule } from '@angular/core';
// import { CommonModule } from '@angular/common';
// import { MaterialModule } from 'packages/commons/material/material.module';
// import { InfraStoreModule } from './infra-store.module';
// import { COMPONENTS } from './component';
// import { SERVICES } from './service';
// import { SensorSettingPageModule } from 'app/pages/sensor-setting/sensor-setting-page.module';
// import { SensorModule } from '../sensor/sensor.module';
// import { SettingComponent } from '../sensor/component/setting/setting.component';
// import { FormsModule } from '@angular/forms';
// import { InfiniteScrollModule } from 'ngx-infinite-scroll';
// @NgModule({
// imports: [
// CommonModule,
// MaterialModule,
// InfraStoreModule,
// SensorModule,
// FormsModule,
// InfiniteScrollModule
// ],
// declarations: [
// COMPONENTS,
// ],
// exports: [
// COMPONENTS,
// ],
// providers: [
// SERVICES
// ],
// entryComponents: [
// SettingComponent,
// ]
// })
// export class InfraModule { }

View File

@ -0,0 +1,13 @@
import { Probe } from 'packages/probe/model';
import { Target } from 'packages/target/model';
import { MetaInfraType } from '../../meta/infra-type/model/MetaInfraType';
export interface Infra {
id?: number;
infraType?: MetaInfraType;
childId?: number;
createDate?: Date;
probe?: Probe;
target?: Target;
}

View File

@ -0,0 +1,10 @@
import { InfraOS } from './InfraOS';
import { Infra } from './Infra';
export interface InfraHost extends Infra {
// id?: number;
os?: InfraOS;
ip?: number;
mac?: number;
createDate?: Date;
}

View File

@ -0,0 +1,8 @@
import { Infra } from './Infra';
export interface InfraMachine extends Infra {
// id?: number;
meta?: string;
createDate?: Date;
}

View File

@ -0,0 +1,11 @@
import { InfraMachine } from './InfraMachine';
import { Infra } from './Infra';
import { MetaInfraVendor } from '../../meta/infra-vendor/model/MetaInfraVendor';
export interface InfraOS extends Infra {
// id?: number;
machine?: InfraMachine;
meta?: string;
createDate?: Date;
vendor?: MetaInfraVendor;
}

View File

@ -0,0 +1,10 @@
import { InfraOS } from './InfraOS';
import { Infra } from './Infra';
export interface InfraOSApplication extends Infra {
// id?: number;
os?: InfraOS;
name?: string;
createDate?: Date;
}

View File

@ -0,0 +1,9 @@
import { InfraOS } from './InfraOS';
import { Infra } from './Infra';
export interface InfraOSDaemon extends Infra {
// id?: number;
os?: InfraOS;
name?: string;
createDate?: Date;
}

View File

@ -0,0 +1,13 @@
import { InfraOS } from './InfraOS';
import { Infra } from './Infra';
import { MetaInfraVendor } from 'packages/meta/infra-vendor/model/MetaInfraVendor';
export interface InfraOSPort extends Infra {
// id?: number;
os?: InfraOS;
createDate?: Date;
port?: number;
portType?: string;
vendor?: MetaInfraVendor;
tlsType?: boolean;
}

View File

@ -0,0 +1,13 @@
import { InfraHost } from './InfraHost';
import { Infra } from './Infra';
import { MetaInfraVendor } from 'packages/meta/infra-vendor/model/MetaInfraVendor';
export interface InfraService extends Infra {
// id?: number;
host?: InfraHost;
portType?: string;
port?: number;
vendor?: MetaInfraVendor;
createDate?: Date;
tlsType?: boolean;
}

View File

@ -0,0 +1,8 @@
export * from './InfraHost';
export * from './InfraMachine';
export * from './InfraOSApplication';
export * from './InfraOSDaemon';
export * from './InfraOSPort';
export * from './InfraOS';
export * from './InfraService';
export * from './Infra';

View File

@ -0,0 +1,5 @@
import { InfraService } from './infra.service';
export const SERVICES = [
InfraService,
];

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { InfraService } from './infra.service';
describe('InfraService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [InfraService]
});
});
it('should be created', inject([InfraService], (service: InfraService) => {
expect(service).toBeTruthy();
}));
});

View File

@ -0,0 +1,29 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { RPCService } from '@loafer/ng-rpc/service';
import { Infra } from '../model';
import { Page, PageParams } from '../../../app/commons/model';
import { Domain } from '../../domain/model';
import { Probe } from '../../probe/model';
@Injectable()
export class InfraService {
public constructor(
private rpcService: RPCService,
) {
}
public readAllByDomain(domain: Domain, pageParams: PageParams): Observable<Page> {
return this.rpcService.call('InfraService.readAllByDomain', domain, pageParams);
}
public readAllByProbe(probe: Probe, pageParams: PageParams): Observable<Page> {
return this.rpcService.call('InfraService.readAllByProbe', probe, pageParams);
}
}

View File

@ -0,0 +1,31 @@
import {
createSelector,
createFeatureSelector,
ActionReducerMap,
} from '@ngrx/store';
import { MODULE } from '../infra.constant';
import * as ListStore from './list';
import { StateSelector } from '../../core/ngrx/store';
export interface State {
list: ListStore.State;
}
export const REDUCERS = {
list: ListStore.reducer,
};
export const EFFECTS = [
ListStore.Effects,
];
export const selectInfraState = createFeatureSelector<State>(MODULE.name);
export const ListSelector = new StateSelector<ListStore.State>(createSelector(
selectInfraState,
(state: State) => state.list
));

View File

@ -0,0 +1,4 @@
export * from './list.action';
export * from './list.effect';
export * from './list.reducer';
export * from './list.state';

View File

@ -0,0 +1,63 @@
import { Action } from '@ngrx/store';
import { RPCClientError } from '@loafer/ng-rpc/protocol';
import { PageParams, Page } from 'app/commons/model';
import { Domain } from '../../../domain/model';
import { Probe } from '../../../probe/model';
export enum ActionType {
ReadAllByDomain = '[Infra.list] ReadAllByDomain',
ReadAllByDomainSuccess = '[Infra.list] ReadAllByDomainSuccess',
ReadAllByDomainFailure = '[Infra.list] ReadAllByDomainFailure',
ReadAllByProbe = '[Infra.list] ReadAllByProbe',
ReadAllByProbeSuccess = '[Infra.list] ReadAllByProbeSuccess',
ReadAllByProbeFailure = '[Infra.list] ReadAllByProbeFailure',
}
export class ReadAllByDomain implements Action {
readonly type = ActionType.ReadAllByDomain;
constructor(public payload: { domain: Domain, pageParams: PageParams }) { }
}
export class ReadAllByDomainSuccess implements Action {
readonly type = ActionType.ReadAllByDomainSuccess;
constructor(public payload: Page) { }
}
export class ReadAllByDomainFailure implements Action {
readonly type = ActionType.ReadAllByDomainFailure;
constructor(public payload: RPCClientError) { }
}
export class ReadAllByProbe implements Action {
readonly type = ActionType.ReadAllByProbe;
constructor(public payload: { probe: Probe, pageParams: PageParams }) { }
}
export class ReadAllByProbeSuccess implements Action {
readonly type = ActionType.ReadAllByProbeSuccess;
constructor(public payload: Page) { }
}
export class ReadAllByProbeFailure implements Action {
readonly type = ActionType.ReadAllByProbeFailure;
constructor(public payload: RPCClientError) { }
}
export type Actions =
| ReadAllByDomain
| ReadAllByDomainSuccess
| ReadAllByDomainFailure
| ReadAllByProbe
| ReadAllByProbeSuccess
| ReadAllByProbeFailure
;

View File

@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';
import { Effects } from './list.effect';
describe('list.Effects', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [Effects]
});
});
it('should be created', inject([Effects], (effects: Effects) => {
expect(effects).toBeTruthy();
}));
});

View File

@ -0,0 +1,64 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { Action } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/exhaustMap';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import { RPCClientError } from '@loafer/ng-rpc/protocol';
import { Infra } from '../../model';
import { InfraService } from '../../service/infra.service';
import {
ReadAllByDomain,
ReadAllByDomainSuccess,
ReadAllByDomainFailure,
ReadAllByProbe,
ReadAllByProbeSuccess,
ReadAllByProbeFailure,
ActionType,
} from './list.action';
import { Domain } from 'packages/domain/model';
@Injectable()
export class Effects {
constructor(
private actions$: Actions,
private infraService: InfraService,
private router: Router
) { }
@Effect()
readAllByDomain$: Observable<Action> = this.actions$
.ofType(ActionType.ReadAllByDomain)
.map((action: ReadAllByDomain) => action.payload)
.switchMap(payload => this.infraService.readAllByDomain(payload.domain, payload.pageParams))
.map(page => {
return new ReadAllByDomainSuccess(page);
})
.catch((error: RPCClientError) => {
return of(new ReadAllByDomainFailure(error));
});
@Effect()
readAllByProbe$: Observable<Action> = this.actions$
.ofType(ActionType.ReadAllByProbe)
.map((action: ReadAllByProbe) => action.payload)
.switchMap(payload => this.infraService.readAllByProbe(payload.probe, payload.pageParams))
.map(page => {
return new ReadAllByProbeSuccess(page);
})
.catch((error: RPCClientError) => {
return of(new ReadAllByProbeFailure(error));
});
}

View File

@ -0,0 +1,39 @@
import { Actions, ActionType } from './list.action';
import { State, initialState } from './list.state';
import { Infra } from '../../model';
export function reducer(state = initialState, action: Actions): State {
switch (action.type) {
case ActionType.ReadAllByDomain: {
return {
...state,
error: null,
isPending: true,
};
}
case ActionType.ReadAllByDomainSuccess: {
return {
...state,
error: null,
isPending: false,
page: action.payload
};
}
case ActionType.ReadAllByDomainFailure: {
return {
...state,
error: action.payload,
isPending: false,
page: null
};
}
default: {
return state;
}
}
}

View File

@ -0,0 +1,30 @@
import {
createSelector,
MemoizedSelector,
} from '@ngrx/store';
import { RPCClientError } from '@loafer/ng-rpc/protocol';
import { Infra } from '../../model';
import { Page } from '../../../../app/commons/model';
export interface State {
error: RPCClientError | null;
isPending: boolean;
page: Page | null;
}
export const initialState: State = {
error: null,
isPending: false,
page: null,
};
export class StateSelector {
public constructor(private _selector: MemoizedSelector<any, any>) {
}
public getInfraList = createSelector(this._selector, (state: State) => state.page);
public getError = createSelector(this._selector, (state: State) => state.error);
public isPending = createSelector(this._selector, (state: State) => state.isPending);
}

View File

@ -1,65 +1,30 @@
<!DOCTYPE html> <div class="card login-panel ui-fluid">
<html> <div class="ui-g">
<div class="ui-g-12">
<img src="assets/layout/images/logo-ultima.svg">
</div>
<div class="ui-g-12">
<span class="md-inputfield">
<input type="text" autocomplete="off" class="ui-inputtext ui-corner-all ui-state-default ui-widget">
<label>Username</label>
</span>
</div>
<div class="ui-g-12">
<span class="md-inputfield">
<input type="password" autocomplete="off" class="ui-inputtext ui-corner-all ui-state-default ui-widget">
<label>Password</label>
</span>
</div>
<div class="ui-g-12">
<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-left">
<span class="ui-button-icon-left ui-c fa fa-fw ui-icon-person"></span>
<span class="ui-button-text ui-c">Sign In</span>
</button>
<button type="button" class="secondary ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-left">
<span class="ui-button-icon-left ui-c fa fa-fw ui-icon-help"></span>
<span class="ui-button-text ui-c">Sign In</span>
</button>
</div>
</div>
<head> </div>
<script>document.write('<base href="' + document.location + '" />');</script>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<title>overFlow</title>
<!-- Layout CSS -->
<link rel="stylesheet" type="text/css" href="assets/theme/theme-indigo.css">
<link rel="stylesheet" type="text/css" href="assets/layout/css/layout-indigo.css">
<link rel="stylesheet" type="text/css" href="assets/layout/css/primeng.min.css">
<script src="jquery.js"></script>
<script type="text/javascript">
$(function() {
$('input').on('blur', function(e) {
var el = $(this);
if(el.val() != '')
el.addClass('ui-state-filled');
else
el.removeClass('ui-state-filled');
});
});
</script>
</head>
<!-- 3. Display the application -->
<body class="login-body">
<div class="card login-panel ui-fluid">
<div class="ui-g">
<div class="ui-g-12">
<img src="assets/layout/images/logo-ultima.svg">
</div>
<div class="ui-g-12">
<span class="md-inputfield">
<input type="text" autocomplete="off" class="ui-inputtext ui-corner-all ui-state-default ui-widget">
<label>Username</label>
</span>
</div>
<div class="ui-g-12">
<span class="md-inputfield">
<input type="password" autocomplete="off" class="ui-inputtext ui-corner-all ui-state-default ui-widget">
<label>Password</label>
</span>
</div>
<div class="ui-g-12">
<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-left">
<span class="ui-button-icon-left ui-c fa fa-fw ui-icon-person"></span>
<span class="ui-button-text ui-c">Sign In</span>
</button>
<button type="button" class="secondary ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-left">
<span class="ui-button-icon-left ui-c fa fa-fw ui-icon-help"></span>
<span class="ui-button-text ui-c">Sign In</span>
</button>
</div>
</div>
</div>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More