init commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<ul class="bar-menu" [hidden]="!data.isExpend" *ngIf="!isLeaf(data)">
|
||||
<li *ngFor="let item of data.children">
|
||||
<a (click)="itemClicked(item);">
|
||||
<i class="fa mr-3" [ngClass]="item.icon"></i> <span>{{item.name}}</span>
|
||||
<i style="margin-top:3px;width:17px" class="fa pull-right" [ngClass]="{'fa-angle-down': !isLeaf(item) && item.isExpend, 'fa-angle-left': !isLeaf(item) && !item.isExpend}"></i>
|
||||
</a>
|
||||
<app-bar-menu [data]="item"></app-bar-menu>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -0,0 +1,58 @@
|
||||
@import "../../theme/scss/variables.scss";
|
||||
|
||||
.bar-menu {
|
||||
list-style: none;
|
||||
font-size: 16px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
a {
|
||||
color: $color-gray-deep;
|
||||
text-decoration: none;
|
||||
border: 0px;
|
||||
}
|
||||
& > li {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
// padding: 0 10px;
|
||||
background: rgb(46, 59, 76);
|
||||
border-top: 2px solid rgb(34, 49, 68);
|
||||
// box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.03);
|
||||
&:hover {
|
||||
& > a {
|
||||
color: $color-gray-deep;
|
||||
border: 0px;
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
& > a {
|
||||
color: $color-gray-deep;
|
||||
border: 0px;
|
||||
}
|
||||
}
|
||||
& > a {
|
||||
padding: 8px 5px 8px 60px;
|
||||
display: block;
|
||||
border-left: 3px solid transparent;
|
||||
color: $color-gray-deep;
|
||||
border: 0px;
|
||||
&:hover {
|
||||
color: $color-white;
|
||||
-webkit-transition: 0.3s;
|
||||
transition: 0.3s;
|
||||
-moz-transition: 0.3s;
|
||||
-webkit-transition: 0.3s;
|
||||
-o-transition: 0.3s;
|
||||
cursor: pointer;
|
||||
filter: alpha(opacity=35);
|
||||
-moz-opacity: 0.35;
|
||||
opacity: 0.35;
|
||||
margin-left: 5px;
|
||||
}
|
||||
& > .fa {
|
||||
&::before {
|
||||
width: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { BarMenuComponent } from './bar-menu.component';
|
||||
|
||||
describe('BarMenuComponent', () => {
|
||||
let component: BarMenuComponent;
|
||||
let fixture: ComponentFixture<BarMenuComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ BarMenuComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BarMenuComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bar-menu',
|
||||
templateUrl: './bar-menu.component.html',
|
||||
styleUrls: ['./bar-menu.component.scss']
|
||||
})
|
||||
export class BarMenuComponent implements OnInit {
|
||||
|
||||
@Input() data: Array<any>;
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否有子节点
|
||||
* @param item
|
||||
*/
|
||||
isLeaf(item: any) {
|
||||
return !item.children || !item.children.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单点击事件
|
||||
* @param item
|
||||
*/
|
||||
itemClicked(item: any) {
|
||||
if (!this.isLeaf(item)) {
|
||||
item.isExpend = !item.isExpend;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { BarMenuModule } from './bar-menu.module';
|
||||
|
||||
describe('BarMenuModule', () => {
|
||||
let barMenuModule: BarMenuModule;
|
||||
|
||||
beforeEach(() => {
|
||||
barMenuModule = new BarMenuModule();
|
||||
});
|
||||
|
||||
it('should create an instance', () => {
|
||||
expect(barMenuModule).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { BarMenuComponent } from './bar-menu.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
declarations: [BarMenuComponent],
|
||||
exports: [BarMenuComponent]
|
||||
})
|
||||
export class BarMenuModule { }
|
||||
@@ -0,0 +1,13 @@
|
||||
import { ComponentsModule } from './components.module';
|
||||
|
||||
describe('ComponentsModule', () => {
|
||||
let componentsModule: ComponentsModule;
|
||||
|
||||
beforeEach(() => {
|
||||
componentsModule = new ComponentsModule();
|
||||
});
|
||||
|
||||
it('should create an instance', () => {
|
||||
expect(componentsModule).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { PageTopModule } from './page-top/page-top.module' //头部
|
||||
import { ToastModule } from './toast/toast.module' //消息提示
|
||||
import { SidebarMenuModule } from './sidebar-menu/sidebar-menu.module'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
PageTopModule,
|
||||
ToastModule,
|
||||
SidebarMenuModule,
|
||||
],
|
||||
declarations: [],
|
||||
exports: [
|
||||
PageTopModule,
|
||||
ToastModule,
|
||||
SidebarMenuModule,
|
||||
]
|
||||
})
|
||||
export class ComponentsModule { }
|
||||
@@ -0,0 +1,50 @@
|
||||
<nav class="navbar navbar-expand navbar-dark bg-dark">
|
||||
<a class="navbar-brand" href="#">广州智能科技发展有限公司</a>
|
||||
|
||||
<div class="collapse navbar-collapse">
|
||||
<ul class="navbar-nav ml-auto mr-4">
|
||||
<li class="nav-item dropdown mr-2">
|
||||
<a class="nav-icon nav-link" data-toggle="dropdown" id="messagesDropdown" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<div class="icon-container">
|
||||
<i class="fa fa-bell-o"></i>
|
||||
<span>7</span>
|
||||
</div>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="messagesDropdown">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown mr-2">
|
||||
<a class="nav-icon nav-link" data-toggle="dropdown" id="alertsDropdown" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<div class="icon-container">
|
||||
<i class="fa fa-envelope-o"></i>
|
||||
<span style="background:#0cc2aa">4</span>
|
||||
</div>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="alertsDropdown">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link user-info" data-toggle="dropdown" id="userDropdown" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<div class="user-container">
|
||||
<span class="mr-2">Chris Wood</span>
|
||||
<img src="/assets/images/Vlad.png" alt="">
|
||||
</div>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -0,0 +1,50 @@
|
||||
@import "../../theme/scss/variables";
|
||||
.navbar {
|
||||
height: 66px;
|
||||
.nav-icon {
|
||||
padding: 0.1rem 0.75rem;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: 1.5rem;
|
||||
transition: color 0.1s ease-in-out, color 0.1s ease-in-out;
|
||||
&:hover {
|
||||
color: $white;
|
||||
.icon-container {
|
||||
> span {
|
||||
top: -7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.icon-container {
|
||||
position: relative;
|
||||
> span {
|
||||
background: $red;
|
||||
box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.05);
|
||||
border-radius: 50%;
|
||||
display: block;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
padding: 1px;
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
right: -8px;
|
||||
text-align: center;
|
||||
transition: top 0.1s ease-out;
|
||||
font-size: 0.675rem;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.user-info {
|
||||
cursor: pointer;
|
||||
.user-container {
|
||||
> img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
margin-top: -15px;
|
||||
margin-bottom: -15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PageTopComponent } from './page-top.component';
|
||||
|
||||
describe('PageTopComponent', () => {
|
||||
let component: PageTopComponent;
|
||||
let fixture: ComponentFixture<PageTopComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ PageTopComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PageTopComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-page-top',
|
||||
templateUrl: './page-top.component.html',
|
||||
styleUrls: ['./page-top.component.scss']
|
||||
})
|
||||
export class PageTopComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { PageTopModule } from './page-top.module';
|
||||
|
||||
describe('PageTopModule', () => {
|
||||
let pageTopModule: PageTopModule;
|
||||
|
||||
beforeEach(() => {
|
||||
pageTopModule = new PageTopModule();
|
||||
});
|
||||
|
||||
it('should create an instance', () => {
|
||||
expect(pageTopModule).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { PageTopComponent } from './page-top.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
declarations: [PageTopComponent],
|
||||
exports: [PageTopComponent]
|
||||
})
|
||||
export class PageTopModule { }
|
||||
@@ -0,0 +1,9 @@
|
||||
<ul class="sidebar-menu">
|
||||
<li *ngFor="let item of data">
|
||||
<a (click)="itemClicked(item);">
|
||||
<i style="margin-top:3px;width:17px" class="fa pull-right" [ngClass]="{'fa-angle-down': !isLeaf(item) && item.isExpend, 'fa-angle-left': !isLeaf(item) && !item.isExpend}"></i>
|
||||
<i class="fa mr-3" [ngClass]="item.icon"></i> <span>{{item.name}}</span>
|
||||
</a>
|
||||
<app-bar-menu [data]="item"></app-bar-menu>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -0,0 +1,58 @@
|
||||
@import "../../theme/scss/variables.scss";
|
||||
|
||||
.sidebar-menu {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 20px;
|
||||
a {
|
||||
color: $color-gray-deep;
|
||||
text-decoration: none;
|
||||
border: 0px;
|
||||
}
|
||||
& > li {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
// padding: 0 10px;
|
||||
background: rgb(50, 65, 84);
|
||||
border-bottom: 2px solid rgb(34, 49, 68);
|
||||
// box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.03);
|
||||
&:hover {
|
||||
& > a {
|
||||
color: $color-gray-deep;
|
||||
border: 0px;
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
& > a {
|
||||
color: $color-gray-deep;
|
||||
border: 0px;
|
||||
}
|
||||
}
|
||||
& > a {
|
||||
padding: 8px 5px 8px 25px;
|
||||
display: block;
|
||||
border-left: 3px solid transparent;
|
||||
color: $color-gray-deep;
|
||||
border: 0px;
|
||||
&:hover {
|
||||
color: $color-white;
|
||||
-webkit-transition: 0.3s;
|
||||
transition: 0.3s;
|
||||
-moz-transition: 0.3s;
|
||||
-webkit-transition: 0.3s;
|
||||
-o-transition: 0.3s;
|
||||
cursor: pointer;
|
||||
filter: alpha(opacity=35);
|
||||
-moz-opacity: 0.35;
|
||||
opacity: 0.35;
|
||||
margin-left: 5px;
|
||||
}
|
||||
& > .fa {
|
||||
&::before{
|
||||
width: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SidebarMenuComponent } from './sidebar-menu.component';
|
||||
|
||||
describe('SidebarMenuComponent', () => {
|
||||
let component: SidebarMenuComponent;
|
||||
let fixture: ComponentFixture<SidebarMenuComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SidebarMenuComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SidebarMenuComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Component, OnInit,Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sidebar-menu',
|
||||
templateUrl: './sidebar-menu.component.html',
|
||||
styleUrls: ['./sidebar-menu.component.scss']
|
||||
})
|
||||
export class SidebarMenuComponent implements OnInit {
|
||||
//输入数据
|
||||
@Input() data: Array<any>;
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否有子节点
|
||||
* @param item
|
||||
*/
|
||||
isLeaf(item: any) {
|
||||
return !item.children || !item.children.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单点击事件
|
||||
* @param item
|
||||
*/
|
||||
itemClicked(item: any) {
|
||||
if (!this.isLeaf(item)) {
|
||||
item.isExpend = !item.isExpend;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { SidebarMenuModule } from './sidebar-menu.module';
|
||||
|
||||
describe('SidebarMenuModule', () => {
|
||||
let sidebarMenuModule: SidebarMenuModule;
|
||||
|
||||
beforeEach(() => {
|
||||
sidebarMenuModule = new SidebarMenuModule();
|
||||
});
|
||||
|
||||
it('should create an instance', () => {
|
||||
expect(sidebarMenuModule).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SidebarMenuComponent } from './sidebar-menu.component';
|
||||
import { BarMenuModule } from '../bar-menu/bar-menu.module'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
BarMenuModule
|
||||
],
|
||||
declarations: [SidebarMenuComponent],
|
||||
exports: [SidebarMenuComponent]
|
||||
})
|
||||
export class SidebarMenuModule { }
|
||||
@@ -0,0 +1,5 @@
|
||||
<div class="toast-container" [ngClass]="toastPosition">
|
||||
<div *ngFor="let toastCfg of getToastConfigs()" [@animation]="toastAnimation">
|
||||
<toast [config]="toastCfg" (dismissed)="remove(toastCfg)"></toast>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
.toast-container {
|
||||
position: absolute;
|
||||
z-index: 22222;
|
||||
margin-top:10px;
|
||||
width:450px;
|
||||
}
|
||||
|
||||
.toast-top-left{
|
||||
left: 10px;
|
||||
top:75px;
|
||||
}
|
||||
|
||||
.toast-top-center{
|
||||
top:75px;
|
||||
left: -moz-calc( 50% - 225px);
|
||||
left: -webkit-calc( 50% - 225px);
|
||||
left: calc( 50% - 225px);
|
||||
}
|
||||
|
||||
.toast-top-right{
|
||||
top:75px;
|
||||
right: 10px
|
||||
}
|
||||
|
||||
|
||||
.toast-bottom-right{
|
||||
right: 75px;
|
||||
bottom:0;
|
||||
}
|
||||
|
||||
.toast-bottom-left{
|
||||
left: 10px;
|
||||
bottom:0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ToastBoxComponent } from './toast-box.component';
|
||||
|
||||
describe('ToastBoxComponent', () => {
|
||||
let component: ToastBoxComponent;
|
||||
let fixture: ComponentFixture<ToastBoxComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ToastBoxComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ToastBoxComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {trigger, transition, style, animate, state} from '@angular/animations'
|
||||
import {ToastService} from './toast.service';
|
||||
import {ToastConfig} from './toast-model';
|
||||
// import { from } from 'rxjs';
|
||||
|
||||
/**
|
||||
* toast外层组件
|
||||
*/
|
||||
@Component({
|
||||
selector: 'toast-box',
|
||||
templateUrl : './toast-box.component.html',
|
||||
styleUrls:['./toast-box.component.scss'],
|
||||
animations: [
|
||||
trigger('animation', [
|
||||
state('none', style({})),
|
||||
state('decent', style([{opacity: 1}, {maxWidth: 450}])),
|
||||
state('fancy', style([{transform: 'translateX(0)'},{transform: 'translateY(0)'}, {opacity: 1}, {maxWidth: 450}])),
|
||||
transition('void => fancy', [
|
||||
style({opacity: 0, maxWidth: 450, transform: 'translateX(100%)'}),
|
||||
animate('300ms ease-in-out')
|
||||
]),
|
||||
transition('fancy => void', [
|
||||
animate('300ms ease-in-out', style({transform: 'translateX(100%)', height: 0, opacity: 0}))
|
||||
]),
|
||||
transition('void => decent', [
|
||||
style({opacity: 0, maxWidth: 0}),
|
||||
animate('300ms ease-in-out')
|
||||
]),
|
||||
transition('decent => void', [
|
||||
animate('300ms ease-in-out', style({width: 0, opacity: 0}))
|
||||
])
|
||||
])
|
||||
]
|
||||
})
|
||||
export class ToastBoxComponent implements OnInit {
|
||||
@Input() toastAnimation: string = 'none';
|
||||
@Input() toastPosition: string = 'toast-top-center';
|
||||
|
||||
private toastConfigs: Array<ToastConfig> = [];
|
||||
|
||||
constructor(private toastService: ToastService) {
|
||||
this.toastService.getToasts().forEach((config: ToastConfig) => {
|
||||
this.toastConfigs.unshift(config);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得所有toast配置
|
||||
*/
|
||||
getToastConfigs(): Array<ToastConfig> {
|
||||
return this.toastConfigs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除
|
||||
* @param toastCfg
|
||||
*/
|
||||
remove(toastCfg: ToastConfig) {
|
||||
if(this.toastConfigs.indexOf(toastCfg) >= 0) {
|
||||
this.toastConfigs.splice(this.toastConfigs.indexOf(toastCfg), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
export enum ToastType {
|
||||
SUCCESS, INFO, WARNING, ERROR
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 配置
|
||||
*/
|
||||
export class ToastConfig {
|
||||
toastType: ToastType;
|
||||
text: string;
|
||||
textStrong: string;
|
||||
autoDismissTime: number;
|
||||
dismissable: boolean;
|
||||
|
||||
|
||||
constructor(toastType: ToastType, textStrong: string = '', text: string = '', autoDismissTime = 0, dismissable = true) {
|
||||
this.toastType = toastType;
|
||||
this.text = text;
|
||||
this.textStrong = textStrong;
|
||||
this.autoDismissTime = autoDismissTime;
|
||||
this.dismissable = dismissable;
|
||||
}
|
||||
|
||||
getToastType(): ToastType {
|
||||
return this.toastType;
|
||||
}
|
||||
|
||||
getText(): string {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
getTextStrong(): string {
|
||||
return this.textStrong;
|
||||
}
|
||||
|
||||
getAutoDismissTime(): number {
|
||||
return this.autoDismissTime;
|
||||
}
|
||||
|
||||
getDismissable(): boolean {
|
||||
return this.dismissable;
|
||||
}
|
||||
|
||||
|
||||
isDismissable() {
|
||||
return this.autoDismissTime === 0 || this.dismissable;
|
||||
}
|
||||
|
||||
isAutoDismissing() {
|
||||
return this.autoDismissTime > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<div class="alert text-white c-toast" [class.bg-success]="isSuccess()" [class.bg-info]="isInfo()" [class.bg-warning]="isWarning()" [class.bg-danger]="isError()">
|
||||
<button *ngIf="isDismissEnabled()" type="button" class="close" data-dismiss="config" aria-label="Close" (click)="dismiss()">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<i class="fa mr-3" [class.fa-check-circle]="isSuccess()" [class.fa-info-circle]="isInfo()" [class.fa-warning]="isWarning()" [class.fa-times-circle]="isError()"></i>
|
||||
<strong>{{config.textStrong}}</strong><span>{{config.text}}</span>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
.toast{
|
||||
border:0px;
|
||||
-webkit-box-shadow: 1px 1px 3px rgba(100, 100, 100, 0.3);
|
||||
box-shadow: 1px 1px 3px rgba(100, 100, 100, 0.3);
|
||||
-moz-box-shadow: 1px 1px 3px rgba(100, 100, 100, 0.3);
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ToastComponent } from './toast.component';
|
||||
|
||||
describe('ToastComponent', () => {
|
||||
let component: ToastComponent;
|
||||
let fixture: ComponentFixture<ToastComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ToastComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ToastComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
import {Component, OnInit, Input, Output, EventEmitter} from '@angular/core';
|
||||
import {ToastConfig,ToastType} from './toast-model';
|
||||
|
||||
/**
|
||||
* toast组件
|
||||
*/
|
||||
@Component({
|
||||
selector: 'toast',
|
||||
templateUrl : './toast.component.html',
|
||||
styleUrls:['./toast.component.scss']
|
||||
})
|
||||
export class ToastComponent implements OnInit {
|
||||
|
||||
@Input() config = new ToastConfig(ToastType.INFO, '', '');
|
||||
|
||||
@Output() dismissed = new EventEmitter();
|
||||
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
//自动关闭
|
||||
if (this.config.isAutoDismissing()) {
|
||||
setTimeout(() => this.dismiss(), this.config.getAutoDismissTime());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是成功
|
||||
*/
|
||||
isSuccess() {
|
||||
return this.config.getToastType() === ToastType.SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是信息
|
||||
*/
|
||||
isInfo() {
|
||||
return this.config.getToastType() === ToastType.INFO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是警告
|
||||
*/
|
||||
isWarning() {
|
||||
return this.config.getToastType() === ToastType.WARNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是错误
|
||||
*/
|
||||
isError() {
|
||||
return this.config.getToastType() === ToastType.ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除
|
||||
*/
|
||||
dismiss() {
|
||||
this.dismissed.emit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
isDismissEnabled() {
|
||||
return this.config.isDismissable();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { ToastBoxComponent } from './toast-box.component';
|
||||
import { ToastComponent } from './toast.component';
|
||||
import { ToastService } from './toast.service'
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
],
|
||||
declarations: [
|
||||
ToastBoxComponent,
|
||||
ToastComponent
|
||||
],
|
||||
providers: [
|
||||
ToastService
|
||||
],
|
||||
exports: [
|
||||
ToastBoxComponent,
|
||||
ToastComponent
|
||||
]
|
||||
})
|
||||
export class ToastModule { }
|
||||
@@ -0,0 +1,15 @@
|
||||
import { TestBed, inject } from '@angular/core/testing';
|
||||
|
||||
import { ToastService } from './toast.service';
|
||||
|
||||
describe('ToastService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [ToastService]
|
||||
});
|
||||
});
|
||||
|
||||
it('should be created', inject([ToastService], (service: ToastService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Observable,Subject} from 'rxjs';
|
||||
import {ToastConfig} from './toast-model';
|
||||
|
||||
/**
|
||||
* toast服务
|
||||
*/
|
||||
@Injectable()
|
||||
export class ToastService {
|
||||
|
||||
private toastSubject = new Subject<ToastConfig>();
|
||||
|
||||
constructor() {}
|
||||
|
||||
getToasts(): Observable<ToastConfig> {
|
||||
return this.toastSubject;
|
||||
}
|
||||
|
||||
|
||||
toast(toastConfig: ToastConfig) {
|
||||
this.toastSubject.next(toastConfig);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user