mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-01-10 04:25:08 +00:00
Merge branch 'master' into skeleton
This commit is contained in:
parent
c93cecdddd
commit
0e2dca00c0
|
@ -5,7 +5,6 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
|||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { MatMomentDateModule } from '@angular/material-moment-adapter';
|
||||
import { MatButtonModule, MatIconModule } from '@angular/material';
|
||||
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import 'hammerjs';
|
||||
|
||||
|
@ -15,35 +14,14 @@ import { FuseSidebarModule, FuseThemeOptionsModule } from '@fuse/components';
|
|||
|
||||
import { fuseConfig } from 'app/fuse-config';
|
||||
|
||||
import { FakeDbService } from 'app/fake-db/fake-db.service';
|
||||
import { AppComponent } from 'app/app.component';
|
||||
import { AppStoreModule } from 'app/store/store.module';
|
||||
import { LayoutModule } from 'app/layout/layout.module';
|
||||
import { SampleModule } from 'app/main/sample/sample.module';
|
||||
|
||||
const appRoutes: Routes = [
|
||||
{
|
||||
path : 'apps',
|
||||
loadChildren: './main/apps/apps.module#AppsModule'
|
||||
},
|
||||
{
|
||||
path : 'pages',
|
||||
loadChildren: './main/pages/pages.module#PagesModule'
|
||||
},
|
||||
{
|
||||
path : 'ui',
|
||||
loadChildren: './main/ui/ui.module#UIModule'
|
||||
},
|
||||
{
|
||||
path : 'documentation',
|
||||
loadChildren: './main/documentation/documentation.module#DocumentationModule'
|
||||
},
|
||||
{
|
||||
path : 'angular-material-elements',
|
||||
loadChildren: './main/angular-material-elements/angular-material-elements.module#AngularMaterialElementsModule'
|
||||
},
|
||||
{
|
||||
path : '**',
|
||||
redirectTo: 'apps/dashboards/analytics'
|
||||
redirectTo: 'sample'
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -58,10 +36,6 @@ const appRoutes: Routes = [
|
|||
RouterModule.forRoot(appRoutes),
|
||||
|
||||
TranslateModule.forRoot(),
|
||||
InMemoryWebApiModule.forRoot(FakeDbService, {
|
||||
delay : 0,
|
||||
passThruUnknownUrl: true
|
||||
}),
|
||||
|
||||
// Material moment date module
|
||||
MatMomentDateModule,
|
||||
|
@ -78,7 +52,7 @@ const appRoutes: Routes = [
|
|||
|
||||
// App modules
|
||||
LayoutModule,
|
||||
AppStoreModule
|
||||
SampleModule
|
||||
],
|
||||
bootstrap : [
|
||||
AppComponent
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Component, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'quick-panel',
|
||||
|
@ -9,24 +6,17 @@ import { takeUntil } from 'rxjs/operators';
|
|||
styleUrls : ['./quick-panel.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class QuickPanelComponent implements OnInit, OnDestroy
|
||||
export class QuickPanelComponent
|
||||
{
|
||||
date: Date;
|
||||
events: any[];
|
||||
notes: any[];
|
||||
settings: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {HttpClient} _httpClient
|
||||
*/
|
||||
constructor(
|
||||
private _httpClient: HttpClient
|
||||
)
|
||||
constructor()
|
||||
{
|
||||
// Set the defaults
|
||||
this.date = new Date();
|
||||
|
@ -35,42 +25,5 @@ export class QuickPanelComponent implements OnInit, OnDestroy
|
|||
cloud : false,
|
||||
retro : true
|
||||
};
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the events
|
||||
this._httpClient.get('api/quick-panel-events')
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((response: any) => {
|
||||
this.events = response;
|
||||
});
|
||||
|
||||
// Subscribe to the notes
|
||||
this._httpClient.get('api/quick-panel-notes')
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((response: any) => {
|
||||
this.notes = response;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { COMPONENT_MAP } from 'app/main/angular-material-elements/example-components';
|
||||
|
||||
@Component({
|
||||
selector : 'angular-material',
|
||||
templateUrl: './angular-material-elements.component.html',
|
||||
styleUrls : ['./angular-material-elements.component.scss']
|
||||
})
|
||||
export class AngularMaterialElementsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
id: string;
|
||||
title: string;
|
||||
examples: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ActivatedRoute} _activatedRoute
|
||||
*/
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._activatedRoute.params
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(params => {
|
||||
this.id = params['id'];
|
||||
const _title = this.id.replace('-', ' ');
|
||||
this.title = _title.charAt(0).toUpperCase() + _title.substring(1);
|
||||
this.examples = COMPONENT_MAP[this.id];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
import { FuseHighlightModule } from '@fuse/components/index';
|
||||
import { FuseWidgetModule } from '@fuse/components/widget/widget.module';
|
||||
|
||||
import { MaterialModule } from 'app/main/angular-material-elements/material.module';
|
||||
import { EXAMPLE_LIST } from 'app/main/angular-material-elements/example-components';
|
||||
import { AngularMaterialElementsComponent } from 'app/main/angular-material-elements/angular-material-elements.component';
|
||||
import { ExampleViewerComponent } from 'app/main/angular-material-elements/example-viewer/example-viewer';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : '',
|
||||
children: [
|
||||
{
|
||||
path : ':id',
|
||||
component: AngularMaterialElementsComponent
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations : [
|
||||
[...EXAMPLE_LIST],
|
||||
AngularMaterialElementsComponent,
|
||||
ExampleViewerComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
MaterialModule,
|
||||
|
||||
FuseSharedModule,
|
||||
FuseHighlightModule,
|
||||
FuseWidgetModule
|
||||
],
|
||||
entryComponents: EXAMPLE_LIST,
|
||||
})
|
||||
export class AngularMaterialElementsModule
|
||||
{
|
||||
}
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
import { AfterViewInit, Component, ComponentFactoryResolver, ComponentRef, Input, OnDestroy, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
import 'prismjs/components/prism-scss';
|
||||
import 'prismjs/components/prism-typescript';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations/index';
|
||||
import { FuseCopierService } from '@fuse/services/copier.service';
|
||||
|
||||
import { EXAMPLE_COMPONENTS } from 'app/main/angular-material-elements/example-components';
|
||||
|
||||
export interface LiveExample
|
||||
{
|
||||
title: string;
|
||||
component: any;
|
||||
additionalFiles?: string[];
|
||||
selectorName?: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector : 'example-viewer',
|
||||
templateUrl : './example-viewer.html',
|
||||
styleUrls : ['./example-viewer.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ExampleViewerComponent implements AfterViewInit, OnDestroy
|
||||
{
|
||||
_example: string;
|
||||
exampleData: LiveExample;
|
||||
showSource: boolean;
|
||||
previewRef: ComponentRef<any>;
|
||||
selectedIndex: number;
|
||||
|
||||
@ViewChild('previewContainer', {read: ViewContainerRef})
|
||||
private _previewContainer: ViewContainerRef;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MatSnackBar} _matSnackBar
|
||||
* @param {FuseCopierService} _fuseCopierService
|
||||
* @param {ComponentFactoryResolver} _componentFactoryResolver
|
||||
*/
|
||||
constructor(
|
||||
private _matSnackBar: MatSnackBar,
|
||||
private _fuseCopierService: FuseCopierService,
|
||||
private _componentFactoryResolver: ComponentFactoryResolver
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.selectedIndex = 0;
|
||||
this.showSource = false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Container
|
||||
*
|
||||
* @param {ViewContainerRef} value
|
||||
*/
|
||||
set container(value: ViewContainerRef)
|
||||
{
|
||||
this._previewContainer = value;
|
||||
}
|
||||
|
||||
get container(): ViewContainerRef
|
||||
{
|
||||
return this._previewContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Example
|
||||
*
|
||||
* @param {string} example
|
||||
*/
|
||||
@Input()
|
||||
set example(example: string)
|
||||
{
|
||||
if ( example && EXAMPLE_COMPONENTS[example] )
|
||||
{
|
||||
this._example = example;
|
||||
this.exampleData = EXAMPLE_COMPONENTS[example];
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('MISSING EXAMPLE: ', example);
|
||||
}
|
||||
}
|
||||
|
||||
get example(): string
|
||||
{
|
||||
return this._example;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* After view init
|
||||
*/
|
||||
ngAfterViewInit(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
const cmpFactory = this._componentFactoryResolver.resolveComponentFactory(this.exampleData.component);
|
||||
this.previewRef = this._previewContainer.createComponent(cmpFactory);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
if ( this.previewRef )
|
||||
{
|
||||
this.previewRef.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle source view
|
||||
*/
|
||||
toggleSourceView(): void
|
||||
{
|
||||
this.showSource = !this.showSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the source
|
||||
*
|
||||
* @param {string} text
|
||||
*/
|
||||
copySource(text: string): void
|
||||
{
|
||||
if ( this._fuseCopierService.copyText(text) )
|
||||
{
|
||||
this._matSnackBar.open('Code copied', '', {duration: 2500});
|
||||
}
|
||||
else
|
||||
{
|
||||
this._matSnackBar.open('Copy failed. Please try again!', '', {duration: 2500});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
<div id="academy-course" class="page-layout simple left-sidebar inner-scroll">
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<fuse-sidebar class="sidebar" name="academy-course-left-sidebar-1" position="left" lockedOpen="gt-md">
|
||||
|
||||
<!-- SIDEBAR CONTENT -->
|
||||
<div class="content" fusePerfectScrollbar>
|
||||
|
||||
<div class="steps">
|
||||
|
||||
<div class="step"
|
||||
*ngFor="let step of course.steps; let i = index; let last = last; let first = first"
|
||||
(click)="gotoStep(i)"
|
||||
[ngClass]="{'current': currentStep === i, 'completed': currentStep > i, 'last': last, 'first': first}">
|
||||
<div class="index">
|
||||
<span>{{i + 1}}</span>
|
||||
</div>
|
||||
<div class="title">{{step.title}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / SIDEBAR CONTENT -->
|
||||
|
||||
</fuse-sidebar>
|
||||
<!-- / SIDEBAR -->
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="center">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24" fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<button mat-icon-button class="sidebar-toggle mr-16" fxHide.gt-md
|
||||
(click)="toggleSidebar('academy-course-left-sidebar-1')">
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button class="mr-16" [routerLink]="'/apps/academy/courses'">
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
</button>
|
||||
|
||||
<div>
|
||||
<h2>{{course.title}}</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div id="course-content" class="content">
|
||||
|
||||
<ng-container *ngFor="let step of course.steps; let i = index;">
|
||||
|
||||
<div class="course-step" fusePerfectScrollbar
|
||||
*ngIf="currentStep === i"
|
||||
[@slideIn]="animationDirection">
|
||||
|
||||
<div id="course-step-content" class="course-step-content" [innerHTML]="step.content"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
<div class="step-navigation">
|
||||
|
||||
<button mat-fab class="previous mat-accent white-fg"
|
||||
(click)="gotoPreviousStep()"
|
||||
[disabled]="currentStep === 0"
|
||||
[fxHide]="currentStep === 0">
|
||||
<mat-icon>chevron_left</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-fab class="next mat-accent white-fg"
|
||||
(click)="gotoNextStep()"
|
||||
[disabled]="currentStep === course.totalSteps - 1"
|
||||
[fxHide]="currentStep === course.totalSteps - 1">
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-fab class="done mat-green-600-bg"
|
||||
routerLink="/apps/academy/courses"
|
||||
[disabled]="currentStep !== course.totalSteps - 1"
|
||||
[fxShow]="currentStep === course.totalSteps - 1">
|
||||
<mat-icon>check</mat-icon>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / CENTER -->
|
||||
|
||||
</div>
|
|
@ -1,162 +0,0 @@
|
|||
import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, QueryList, ViewChildren, ViewEncapsulation } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
|
||||
import { AcademyCourseService } from 'app/main/apps/academy/course.service';
|
||||
|
||||
@Component({
|
||||
selector : 'academy-course',
|
||||
templateUrl : './course.component.html',
|
||||
styleUrls : ['./course.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class AcademyCourseComponent implements OnInit, OnDestroy, AfterViewInit
|
||||
{
|
||||
animationDirection: 'left' | 'right' | 'none';
|
||||
course: any;
|
||||
courseStepContent: any;
|
||||
currentStep: number;
|
||||
|
||||
@ViewChildren(FusePerfectScrollbarDirective)
|
||||
fuseScrollbarDirectives: QueryList<FusePerfectScrollbarDirective>;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {AcademyCourseService} _academyCourseService
|
||||
* @param {ChangeDetectorRef} _changeDetectorRef
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
*/
|
||||
constructor(
|
||||
private _academyCourseService: AcademyCourseService,
|
||||
private _changeDetectorRef: ChangeDetectorRef,
|
||||
private _fuseSidebarService: FuseSidebarService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.animationDirection = 'none';
|
||||
this.currentStep = 0;
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to courses
|
||||
this._academyCourseService.onCourseChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(course => {
|
||||
this.course = course;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* After view init
|
||||
*/
|
||||
ngAfterViewInit(): void
|
||||
{
|
||||
this.courseStepContent = this.fuseScrollbarDirectives.find((fuseScrollbarDirective) => {
|
||||
return fuseScrollbarDirective.elementRef.nativeElement.id === 'course-step-content';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Go to step
|
||||
*
|
||||
* @param step
|
||||
*/
|
||||
gotoStep(step): void
|
||||
{
|
||||
// Decide the animation direction
|
||||
this.animationDirection = this.currentStep < step ? 'left' : 'right';
|
||||
|
||||
// Run change detection so the change
|
||||
// in the animation direction registered
|
||||
this._changeDetectorRef.detectChanges();
|
||||
|
||||
// Set the current step
|
||||
this.currentStep = step;
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to next step
|
||||
*/
|
||||
gotoNextStep(): void
|
||||
{
|
||||
if ( this.currentStep === this.course.totalSteps - 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the animation direction
|
||||
this.animationDirection = 'left';
|
||||
|
||||
// Run change detection so the change
|
||||
// in the animation direction registered
|
||||
this._changeDetectorRef.detectChanges();
|
||||
|
||||
// Increase the current step
|
||||
this.currentStep++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to previous step
|
||||
*/
|
||||
gotoPreviousStep(): void
|
||||
{
|
||||
if ( this.currentStep === 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the animation direction
|
||||
this.animationDirection = 'right';
|
||||
|
||||
// Run change detection so the change
|
||||
// in the animation direction registered
|
||||
this._changeDetectorRef.detectChanges();
|
||||
|
||||
// Decrease the current step
|
||||
this.currentStep--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the sidebar
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
toggleSidebar(name): void
|
||||
{
|
||||
this._fuseSidebarService.getSidebar(name).toggleOpen();
|
||||
}
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { AcademyCoursesService } from 'app/main/apps/academy/courses.service';
|
||||
|
||||
@Component({
|
||||
selector : 'academy-courses',
|
||||
templateUrl: './courses.component.html',
|
||||
styleUrls : ['./courses.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class AcademyCoursesComponent implements OnInit, OnDestroy
|
||||
{
|
||||
categories: any[];
|
||||
courses: any[];
|
||||
coursesFilteredByCategory: any[];
|
||||
filteredCourses: any[];
|
||||
currentCategory: string;
|
||||
searchTerm: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {AcademyCoursesService} _academyCoursesService
|
||||
*/
|
||||
constructor(
|
||||
private _academyCoursesService: AcademyCoursesService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.currentCategory = 'all';
|
||||
this.searchTerm = '';
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to categories
|
||||
this._academyCoursesService.onCategoriesChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(categories => {
|
||||
this.categories = categories;
|
||||
});
|
||||
|
||||
// Subscribe to courses
|
||||
this._academyCoursesService.onCoursesChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(courses => {
|
||||
this.filteredCourses = this.coursesFilteredByCategory = this.courses = courses;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Filter courses by category
|
||||
*/
|
||||
filterCoursesByCategory(): void
|
||||
{
|
||||
// Filter
|
||||
if ( this.currentCategory === 'all' )
|
||||
{
|
||||
this.coursesFilteredByCategory = this.courses;
|
||||
this.filteredCourses = this.courses;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.coursesFilteredByCategory = this.courses.filter((course) => {
|
||||
return course.category === this.currentCategory;
|
||||
});
|
||||
|
||||
this.filteredCourses = [...this.coursesFilteredByCategory];
|
||||
|
||||
}
|
||||
|
||||
// Re-filter by search term
|
||||
this.filterCoursesByTerm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter courses by term
|
||||
*/
|
||||
filterCoursesByTerm(): void
|
||||
{
|
||||
const searchTerm = this.searchTerm.toLowerCase();
|
||||
|
||||
// Search
|
||||
if ( searchTerm === '' )
|
||||
{
|
||||
this.filteredCourses = this.coursesFilteredByCategory;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.filteredCourses = this.coursesFilteredByCategory.filter((course) => {
|
||||
return course.title.toLowerCase().includes(searchTerm);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'dashboards/analytics',
|
||||
loadChildren: './dashboards/analytics/analytics.module#AnalyticsDashboardModule'
|
||||
},
|
||||
{
|
||||
path : 'dashboards/project',
|
||||
loadChildren: './dashboards/project/project.module#ProjectDashboardModule'
|
||||
},
|
||||
{
|
||||
path : 'mail',
|
||||
loadChildren: './mail/mail.module#MailModule'
|
||||
},
|
||||
{
|
||||
path : 'mail-ngrx',
|
||||
loadChildren: './mail-ngrx/mail.module#MailNgrxModule'
|
||||
},
|
||||
{
|
||||
path : 'chat',
|
||||
loadChildren: './chat/chat.module#ChatModule'
|
||||
},
|
||||
{
|
||||
path : 'calendar',
|
||||
loadChildren: './calendar/calendar.module#CalendarModule'
|
||||
},
|
||||
{
|
||||
path : 'e-commerce',
|
||||
loadChildren: './e-commerce/e-commerce.module#EcommerceModule'
|
||||
},
|
||||
{
|
||||
path : 'academy',
|
||||
loadChildren: './academy/academy.module#AcademyModule'
|
||||
},
|
||||
{
|
||||
path : 'todo',
|
||||
loadChildren: './todo/todo.module#TodoModule'
|
||||
},
|
||||
{
|
||||
path : 'file-manager',
|
||||
loadChildren: './file-manager/file-manager.module#FileManagerModule'
|
||||
},
|
||||
{
|
||||
path : 'contacts',
|
||||
loadChildren: './contacts/contacts.module#ContactsModule'
|
||||
},
|
||||
{
|
||||
path : 'scrumboard',
|
||||
loadChildren: './scrumboard/scrumboard.module#ScrumboardModule'
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
FuseSharedModule
|
||||
]
|
||||
})
|
||||
export class AppsModule
|
||||
{
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<div fxFlex fxLayout="column" fxLayoutAlign="center center">
|
||||
|
||||
<div class="big-circle mat-elevation-z1 app-logo" fxLayout="column" fxLayoutAlign="center center"
|
||||
[@animate]="{value:'*',params:{delay:'50ms',scale:'0.2'}}">
|
||||
|
||||
<mat-icon class="s-64 s-mat-128 mat-accent">chat</mat-icon>
|
||||
|
||||
</div>
|
||||
|
||||
<span class="app-title my-24" [@animate]="{value:'*',params:{delay:'100ms',y:'25px'}}">Chat App</span>
|
||||
|
||||
<span fxHide fxShow.gt-md class="app-message" [@animate]="{value:'*',params:{delay:'200ms',y:'50px'}}">
|
||||
Select contact to start the chat!..
|
||||
</span>
|
||||
|
||||
<button mat-raised-button fxHide.gt-md fuseMatSidenavToggler="chat-left-sidenav">
|
||||
Select contact to start the chat!..
|
||||
</button>
|
||||
|
||||
</div>
|
|
@ -1,164 +0,0 @@
|
|||
import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild, ViewChildren } from '@angular/core';
|
||||
import { NgForm } from '@angular/forms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-view',
|
||||
templateUrl: './chat-view.component.html',
|
||||
styleUrls : ['./chat-view.component.scss']
|
||||
})
|
||||
export class ChatViewComponent implements OnInit, OnDestroy, AfterViewInit
|
||||
{
|
||||
user: any;
|
||||
chat: any;
|
||||
dialog: any;
|
||||
contact: any;
|
||||
replyInput: any;
|
||||
selectedChat: any;
|
||||
|
||||
@ViewChild(FusePerfectScrollbarDirective)
|
||||
directiveScroll: FusePerfectScrollbarDirective;
|
||||
|
||||
@ViewChildren('replyInput')
|
||||
replyInputField;
|
||||
|
||||
@ViewChild('replyForm')
|
||||
replyForm: NgForm;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.user = this._chatService.user;
|
||||
this._chatService.onChatSelected
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(chatData => {
|
||||
if ( chatData )
|
||||
{
|
||||
this.selectedChat = chatData;
|
||||
this.contact = chatData.contact;
|
||||
this.dialog = chatData.dialog;
|
||||
this.readyToReply();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* After view init
|
||||
*/
|
||||
ngAfterViewInit(): void
|
||||
{
|
||||
this.replyInput = this.replyInputField.first.nativeElement;
|
||||
this.readyToReply();
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Select contact
|
||||
*/
|
||||
selectContact(): void
|
||||
{
|
||||
this._chatService.selectContact(this.contact);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ready to reply
|
||||
*/
|
||||
readyToReply(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.replyForm.reset();
|
||||
this.focusReplyInput();
|
||||
this.scrollToBottom();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus to the reply input
|
||||
*/
|
||||
focusReplyInput(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.replyInput.focus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll to the bottom
|
||||
*
|
||||
* @param {number} speed
|
||||
*/
|
||||
scrollToBottom(speed?: number): void
|
||||
{
|
||||
speed = speed || 400;
|
||||
if ( this.directiveScroll )
|
||||
{
|
||||
this.directiveScroll.update();
|
||||
|
||||
setTimeout(() => {
|
||||
this.directiveScroll.scrollToBottom(0, speed);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reply
|
||||
*/
|
||||
reply(): void
|
||||
{
|
||||
// Message
|
||||
const message = {
|
||||
who : this.user.id,
|
||||
message: this.replyForm.form.value.message,
|
||||
time : new Date().toISOString()
|
||||
};
|
||||
|
||||
// Add the message to the chat
|
||||
this.dialog.push(message);
|
||||
|
||||
// Update the server
|
||||
this._chatService.updateDialog(this.selectedChat.chatId, this.dialog).then(response => {
|
||||
this.readyToReply();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat',
|
||||
templateUrl : './chat.component.html',
|
||||
styleUrls : ['./chat.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ChatComponent implements OnInit, OnDestroy
|
||||
{
|
||||
selectedChat: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._chatService.onChatSelected
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(chatData => {
|
||||
this.selectedChat = chatData;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { MatButtonModule, MatCardModule, MatFormFieldModule, MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatRadioModule, MatSidenavModule, MatToolbarModule } from '@angular/material';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
import { ChatComponent } from 'app/main/apps/chat/chat.component';
|
||||
import { ChatStartComponent } from 'app/main/apps/chat/chat-start/chat-start.component';
|
||||
import { ChatViewComponent } from 'app/main/apps/chat/chat-view/chat-view.component';
|
||||
import { ChatChatsSidenavComponent } from 'app/main/apps/chat/sidenavs/left/chats/chats.component';
|
||||
import { ChatUserSidenavComponent } from 'app/main/apps/chat/sidenavs/left/user/user.component';
|
||||
import { ChatLeftSidenavComponent } from 'app/main/apps/chat/sidenavs/left/left.component';
|
||||
import { ChatRightSidenavComponent } from 'app/main/apps/chat/sidenavs/right/right.component';
|
||||
import { ChatContactSidenavComponent } from 'app/main/apps/chat/sidenavs/right/contact/contact.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : '**',
|
||||
component: ChatComponent,
|
||||
children : [],
|
||||
resolve : {
|
||||
chat: ChatService
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
ChatComponent,
|
||||
ChatViewComponent,
|
||||
ChatStartComponent,
|
||||
ChatChatsSidenavComponent,
|
||||
ChatUserSidenavComponent,
|
||||
ChatLeftSidenavComponent,
|
||||
ChatRightSidenavComponent,
|
||||
ChatContactSidenavComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
MatButtonModule,
|
||||
MatCardModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatListModule,
|
||||
MatMenuModule,
|
||||
MatRadioModule,
|
||||
MatSidenavModule,
|
||||
MatToolbarModule,
|
||||
|
||||
FuseSharedModule
|
||||
],
|
||||
providers : [
|
||||
ChatService
|
||||
]
|
||||
})
|
||||
export class ChatModule
|
||||
{
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ObservableMedia } from '@angular/flex-layout';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseMatSidenavHelperService } from '@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.service';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-chats-sidenav',
|
||||
templateUrl: './chats.component.html',
|
||||
styleUrls : ['./chats.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ChatChatsSidenavComponent implements OnInit, OnDestroy
|
||||
{
|
||||
chats: any[];
|
||||
chatSearch: any;
|
||||
contacts: any[];
|
||||
searchText: string;
|
||||
user: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
* @param {FuseMatSidenavHelperService} _fuseMatSidenavHelperService
|
||||
* @param {ObservableMedia} _observableMedia
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService,
|
||||
private _fuseMatSidenavHelperService: FuseMatSidenavHelperService,
|
||||
public _observableMedia: ObservableMedia
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.chatSearch = {
|
||||
name: ''
|
||||
};
|
||||
this.searchText = '';
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.user = this._chatService.user;
|
||||
this.chats = this._chatService.chats;
|
||||
this.contacts = this._chatService.contacts;
|
||||
|
||||
this._chatService.onChatsUpdated
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(updatedChats => {
|
||||
this.chats = updatedChats;
|
||||
});
|
||||
|
||||
this._chatService.onUserUpdated
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(updatedUser => {
|
||||
this.user = updatedUser;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get chat
|
||||
*
|
||||
* @param contact
|
||||
*/
|
||||
getChat(contact): void
|
||||
{
|
||||
this._chatService.getChat(contact);
|
||||
|
||||
if ( !this._observableMedia.isActive('gt-md') )
|
||||
{
|
||||
this._fuseMatSidenavHelperService.getSidenav('chat-left-sidenav').toggle();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user status
|
||||
*
|
||||
* @param status
|
||||
*/
|
||||
setUserStatus(status): void
|
||||
{
|
||||
this._chatService.setUserStatus(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change left sidenav view
|
||||
*
|
||||
* @param view
|
||||
*/
|
||||
changeLeftSidenavView(view): void
|
||||
{
|
||||
this._chatService.onLeftSidenavViewChanged.next(view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout
|
||||
*/
|
||||
logout(): void
|
||||
{
|
||||
console.log('logout triggered');
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<div [ngSwitch]="view" class="views">
|
||||
<chat-chats-sidenav class="view"
|
||||
*ngSwitchCase="'chats'"
|
||||
[@slideInRight]>
|
||||
</chat-chats-sidenav>
|
||||
|
||||
<chat-user-sidenav class="view"
|
||||
*ngSwitchCase="'user'"
|
||||
[@slideInLeft]
|
||||
fusePerfectScrollbar>
|
||||
</chat-user-sidenav>
|
||||
</div>
|
|
@ -1,63 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-left-sidenav',
|
||||
templateUrl: './left.component.html',
|
||||
styleUrls : ['./left.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ChatLeftSidenavComponent implements OnInit, OnDestroy
|
||||
{
|
||||
view: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.view = 'chats';
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._chatService.onLeftSidenavViewChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(view => {
|
||||
this.view = view;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-user-sidenav',
|
||||
templateUrl: './user.component.html',
|
||||
styleUrls : ['./user.component.scss']
|
||||
})
|
||||
export class ChatUserSidenavComponent implements OnInit, OnDestroy
|
||||
{
|
||||
user: any;
|
||||
userForm: FormGroup;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.user = this._chatService.user;
|
||||
|
||||
this.userForm = new FormGroup({
|
||||
mood : new FormControl(this.user.mood),
|
||||
status: new FormControl(this.user.status)
|
||||
});
|
||||
|
||||
this.userForm.valueChanges
|
||||
.pipe(
|
||||
takeUntil(this._unsubscribeAll),
|
||||
debounceTime(500),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
.subscribe(data => {
|
||||
this.user.mood = data.mood;
|
||||
this.user.status = data.status;
|
||||
this._chatService.updateUserData(this.user);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Change left sidenav view
|
||||
*
|
||||
* @param view
|
||||
*/
|
||||
changeLeftSidenavView(view): void
|
||||
{
|
||||
this._chatService.onLeftSidenavViewChanged.next(view);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-contact-sidenav',
|
||||
templateUrl: './contact.component.html',
|
||||
styleUrls : ['./contact.component.scss']
|
||||
})
|
||||
export class ChatContactSidenavComponent implements OnInit, OnDestroy
|
||||
{
|
||||
contact: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChatService} _chatService
|
||||
*/
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._chatService.onContactSelected
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(contact => {
|
||||
this.contact = contact;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
<div [ngSwitch]="view" class="views">
|
||||
|
||||
<chat-contact-sidenav class="view"
|
||||
*ngSwitchCase="'contact'"
|
||||
[@slideInRight]
|
||||
fusePerfectScrollbar>
|
||||
</chat-contact-sidenav>
|
||||
|
||||
</div>
|
|
@ -1,59 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { ChatService } from 'app/main/apps/chat/chat.service';
|
||||
|
||||
@Component({
|
||||
selector : 'chat-right-sidenav',
|
||||
templateUrl: './right.component.html',
|
||||
styleUrls : ['./right.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ChatRightSidenavComponent implements OnInit, OnDestroy
|
||||
{
|
||||
view: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
constructor(
|
||||
private _chatService: ChatService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.view = 'contact';
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._chatService.onRightSidenavViewChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(view => {
|
||||
this.view = view;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,242 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material';
|
||||
import { DataSource } from '@angular/cdk/collections';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
|
||||
|
||||
import { ContactsService } from 'app/main/apps/contacts/contacts.service';
|
||||
import { ContactsContactFormDialogComponent } from 'app/main/apps/contacts/contact-form/contact-form.component';
|
||||
|
||||
@Component({
|
||||
selector : 'contacts-contact-list',
|
||||
templateUrl : './contact-list.component.html',
|
||||
styleUrls : ['./contact-list.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ContactsContactListComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@ViewChild('dialogContent')
|
||||
dialogContent: TemplateRef<any>;
|
||||
|
||||
contacts: any;
|
||||
user: any;
|
||||
dataSource: FilesDataSource | null;
|
||||
displayedColumns = ['checkbox', 'avatar', 'name', 'email', 'phone', 'jobTitle', 'buttons'];
|
||||
selectedContacts: any[];
|
||||
checkboxes: {};
|
||||
dialogRef: any;
|
||||
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ContactsService} _contactsService
|
||||
* @param {MatDialog} _matDialog
|
||||
*/
|
||||
constructor(
|
||||
private _contactsService: ContactsService,
|
||||
public _matDialog: MatDialog
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.dataSource = new FilesDataSource(this._contactsService);
|
||||
|
||||
this._contactsService.onContactsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(contacts => {
|
||||
this.contacts = contacts;
|
||||
|
||||
this.checkboxes = {};
|
||||
contacts.map(contact => {
|
||||
this.checkboxes[contact.id] = false;
|
||||
});
|
||||
});
|
||||
|
||||
this._contactsService.onSelectedContactsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selectedContacts => {
|
||||
for ( const id in this.checkboxes )
|
||||
{
|
||||
if ( !this.checkboxes.hasOwnProperty(id) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
this.checkboxes[id] = selectedContacts.includes(id);
|
||||
}
|
||||
this.selectedContacts = selectedContacts;
|
||||
});
|
||||
|
||||
this._contactsService.onUserDataChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(user => {
|
||||
this.user = user;
|
||||
});
|
||||
|
||||
this._contactsService.onFilterChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(() => {
|
||||
this._contactsService.deselectContacts();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Edit contact
|
||||
*
|
||||
* @param contact
|
||||
*/
|
||||
editContact(contact): void
|
||||
{
|
||||
this.dialogRef = this._matDialog.open(ContactsContactFormDialogComponent, {
|
||||
panelClass: 'contact-form-dialog',
|
||||
data : {
|
||||
contact: contact,
|
||||
action : 'edit'
|
||||
}
|
||||
});
|
||||
|
||||
this.dialogRef.afterClosed()
|
||||
.subscribe(response => {
|
||||
if ( !response )
|
||||
{
|
||||
return;
|
||||
}
|
||||
const actionType: string = response[0];
|
||||
const formData: FormGroup = response[1];
|
||||
switch ( actionType )
|
||||
{
|
||||
/**
|
||||
* Save
|
||||
*/
|
||||
case 'save':
|
||||
|
||||
this._contactsService.updateContact(formData.getRawValue());
|
||||
|
||||
break;
|
||||
/**
|
||||
* Delete
|
||||
*/
|
||||
case 'delete':
|
||||
|
||||
this.deleteContact(contact);
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Contact
|
||||
*/
|
||||
deleteContact(contact): void
|
||||
{
|
||||
this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, {
|
||||
disableClose: false
|
||||
});
|
||||
|
||||
this.confirmDialogRef.componentInstance.confirmMessage = 'Are you sure you want to delete?';
|
||||
|
||||
this.confirmDialogRef.afterClosed().subscribe(result => {
|
||||
if ( result )
|
||||
{
|
||||
this._contactsService.deleteContact(contact);
|
||||
}
|
||||
this.confirmDialogRef = null;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* On selected change
|
||||
*
|
||||
* @param contactId
|
||||
*/
|
||||
onSelectedChange(contactId): void
|
||||
{
|
||||
this._contactsService.toggleSelectedContact(contactId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle star
|
||||
*
|
||||
* @param contactId
|
||||
*/
|
||||
toggleStar(contactId): void
|
||||
{
|
||||
if ( this.user.starred.includes(contactId) )
|
||||
{
|
||||
this.user.starred.splice(this.user.starred.indexOf(contactId), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.user.starred.push(contactId);
|
||||
}
|
||||
|
||||
this._contactsService.updateUserData(this.user);
|
||||
}
|
||||
}
|
||||
|
||||
export class FilesDataSource extends DataSource<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ContactsService} _contactsService
|
||||
*/
|
||||
constructor(
|
||||
private _contactsService: ContactsService
|
||||
)
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect function called by the table to retrieve one stream containing the data to render.
|
||||
* @returns {Observable<any[]>}
|
||||
*/
|
||||
connect(): Observable<any[]>
|
||||
{
|
||||
return this._contactsService.onContactsChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*/
|
||||
disconnect(): void
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#contacts {
|
||||
|
||||
.content {
|
||||
overflow: hidden;
|
||||
|
||||
.sidebar {
|
||||
|
||||
&:not(.locked-open) {
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { Subject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
|
||||
import { ContactsService } from 'app/main/apps/contacts/contacts.service';
|
||||
import { ContactsContactFormDialogComponent } from 'app/main/apps/contacts/contact-form/contact-form.component';
|
||||
|
||||
@Component({
|
||||
selector : 'contacts',
|
||||
templateUrl : './contacts.component.html',
|
||||
styleUrls : ['./contacts.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ContactsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
dialogRef: any;
|
||||
hasSelectedContacts: boolean;
|
||||
searchInput: FormControl;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ContactsService} _contactsService
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
* @param {MatDialog} _matDialog
|
||||
*/
|
||||
constructor(
|
||||
private _contactsService: ContactsService,
|
||||
private _fuseSidebarService: FuseSidebarService,
|
||||
private _matDialog: MatDialog
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.searchInput = new FormControl('');
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._contactsService.onSelectedContactsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selectedContacts => {
|
||||
this.hasSelectedContacts = selectedContacts.length > 0;
|
||||
});
|
||||
|
||||
this.searchInput.valueChanges
|
||||
.pipe(
|
||||
takeUntil(this._unsubscribeAll),
|
||||
debounceTime(300),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
.subscribe(searchText => {
|
||||
this._contactsService.onSearchTextChanged.next(searchText);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* New contact
|
||||
*/
|
||||
newContact(): void
|
||||
{
|
||||
this.dialogRef = this._matDialog.open(ContactsContactFormDialogComponent, {
|
||||
panelClass: 'contact-form-dialog',
|
||||
data : {
|
||||
action: 'new'
|
||||
}
|
||||
});
|
||||
|
||||
this.dialogRef.afterClosed()
|
||||
.subscribe((response: FormGroup) => {
|
||||
if ( !response )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._contactsService.updateContact(response.getRawValue());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the sidebar
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
toggleSidebar(name): void
|
||||
{
|
||||
this._fuseSidebarService.getSidebar(name).toggleOpen();
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
|
||||
import { MatButtonModule, MatCheckboxModule, MatDatepickerModule, MatFormFieldModule, MatIconModule, MatInputModule, MatMenuModule, MatRippleModule, MatTableModule, MatToolbarModule } from '@angular/material';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
import { FuseConfirmDialogModule, FuseSidebarModule } from '@fuse/components';
|
||||
|
||||
import { ContactsComponent } from 'app/main/apps/contacts/contacts.component';
|
||||
import { ContactsService } from 'app/main/apps/contacts/contacts.service';
|
||||
import { ContactsContactListComponent } from 'app/main/apps/contacts/contact-list/contact-list.component';
|
||||
import { ContactsSelectedBarComponent } from 'app/main/apps/contacts/selected-bar/selected-bar.component';
|
||||
import { ContactsMainSidebarComponent } from 'app/main/apps/contacts/sidebars/main/main.component';
|
||||
import { ContactsContactFormDialogComponent } from 'app/main/apps/contacts/contact-form/contact-form.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : '**',
|
||||
component: ContactsComponent,
|
||||
resolve : {
|
||||
contacts: ContactsService
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations : [
|
||||
ContactsComponent,
|
||||
ContactsContactListComponent,
|
||||
ContactsSelectedBarComponent,
|
||||
ContactsMainSidebarComponent,
|
||||
ContactsContactFormDialogComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
CdkTableModule,
|
||||
|
||||
MatButtonModule,
|
||||
MatCheckboxModule,
|
||||
MatDatepickerModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatMenuModule,
|
||||
MatRippleModule,
|
||||
MatTableModule,
|
||||
MatToolbarModule,
|
||||
|
||||
FuseSharedModule,
|
||||
FuseConfirmDialogModule,
|
||||
FuseSidebarModule
|
||||
],
|
||||
providers : [
|
||||
ContactsService
|
||||
],
|
||||
entryComponents: [
|
||||
ContactsContactFormDialogComponent
|
||||
]
|
||||
})
|
||||
export class ContactsModule
|
||||
{
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
|
||||
|
||||
import { ContactsService } from 'app/main/apps/contacts/contacts.service';
|
||||
|
||||
@Component({
|
||||
selector : 'selected-bar',
|
||||
templateUrl: './selected-bar.component.html',
|
||||
styleUrls : ['./selected-bar.component.scss']
|
||||
})
|
||||
export class ContactsSelectedBarComponent implements OnInit, OnDestroy
|
||||
{
|
||||
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
|
||||
hasSelectedContacts: boolean;
|
||||
isIndeterminate: boolean;
|
||||
selectedContacts: string[];
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ContactsService} _contactsService
|
||||
* @param {MatDialog} _matDialog
|
||||
*/
|
||||
constructor(
|
||||
private _contactsService: ContactsService,
|
||||
public _matDialog: MatDialog
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._contactsService.onSelectedContactsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selectedContacts => {
|
||||
this.selectedContacts = selectedContacts;
|
||||
setTimeout(() => {
|
||||
this.hasSelectedContacts = selectedContacts.length > 0;
|
||||
this.isIndeterminate = (selectedContacts.length !== this._contactsService.contacts.length && selectedContacts.length > 0);
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Select all
|
||||
*/
|
||||
selectAll(): void
|
||||
{
|
||||
this._contactsService.selectContacts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselect all
|
||||
*/
|
||||
deselectAll(): void
|
||||
{
|
||||
this._contactsService.deselectContacts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete selected contacts
|
||||
*/
|
||||
deleteSelectedContacts(): void
|
||||
{
|
||||
this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, {
|
||||
disableClose: false
|
||||
});
|
||||
|
||||
this.confirmDialogRef.componentInstance.confirmMessage = 'Are you sure you want to delete all selected contacts?';
|
||||
|
||||
this.confirmDialogRef.afterClosed()
|
||||
.subscribe(result => {
|
||||
if ( result )
|
||||
{
|
||||
this._contactsService.deleteSelectedContacts();
|
||||
}
|
||||
this.confirmDialogRef = null;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { ContactsService } from 'app/main/apps/contacts/contacts.service';
|
||||
|
||||
@Component({
|
||||
selector : 'contacts-main-sidebar',
|
||||
templateUrl: './main.component.html',
|
||||
styleUrls : ['./main.component.scss']
|
||||
})
|
||||
export class ContactsMainSidebarComponent implements OnInit, OnDestroy
|
||||
{
|
||||
user: any;
|
||||
filterBy: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ContactsService} _contactsService
|
||||
*/
|
||||
constructor(
|
||||
private _contactsService: ContactsService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.filterBy = this._contactsService.filterBy || 'all';
|
||||
|
||||
this._contactsService.onUserDataChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(user => {
|
||||
this.user = user;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy()
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Change the filter
|
||||
*
|
||||
* @param filter
|
||||
*/
|
||||
changeFilter(filter): void
|
||||
{
|
||||
this.filterBy = filter;
|
||||
this._contactsService.onFilterChanged.next(this.filterBy);
|
||||
}
|
||||
}
|
|
@ -1,903 +0,0 @@
|
|||
<div id="dashboard-project" class="page-layout simple right-sidebar" fxLayout="row">
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<fuse-sidebar class="sidebar" name="project-dashboard-right-sidebar-1" position="right" lockedOpen="gt-md">
|
||||
|
||||
<!-- SIDEBAR CONTENT -->
|
||||
<div class="content">
|
||||
|
||||
<!-- WIDGET GROUP -->
|
||||
<div class="widget-group" fxLayout="column" fxFlex="100" [@animateStagger]="{value:'50'}">
|
||||
|
||||
<!-- NOW WIDGET -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="p-0">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front">
|
||||
|
||||
<div class="pl-16 pr-8 py-16" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
|
||||
<div class="h3">{{dateNow | date: 'EEEE, HH:mm:ss'}}</div>
|
||||
|
||||
<div>
|
||||
<button mat-icon-button [matMenuTriggerFor]="moreMenu" aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #moreMenu="matMenu">
|
||||
<button mat-menu-item aria-label="Flip widget">
|
||||
Details
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 pb-24" fxLayout="column" fxLayoutAlign="center center">
|
||||
<div class="h1 secondary-text">
|
||||
<span>{{dateNow | date: 'MMMM'}}</span>
|
||||
</div>
|
||||
|
||||
<div class="font-size-72 line-height-88 secondary-text font-weight-400">
|
||||
{{dateNow | date: 'd'}}
|
||||
</div>
|
||||
|
||||
<div class="h1 secondary-text">
|
||||
<span>{{dateNow | date: 'y'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / NOW WIDGET -->
|
||||
|
||||
<!-- WEATHER WIDGET -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="p-0">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front">
|
||||
|
||||
<div class="pl-16 pr-8 py-16" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
|
||||
<div class="h4" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text mr-8">place</mat-icon>
|
||||
{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].name}}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button mat-icon-button [matMenuTriggerFor]="moreMenu" aria-label="more">
|
||||
<mat-icon class="secondary-text">more_vert</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #moreMenu="matMenu">
|
||||
<button mat-menu-item aria-label="Flip widget">
|
||||
Details
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 pb-32" fxLayout="column" fxLayoutAlign="center center">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="center center">
|
||||
<mat-icon fontSet="meteocons"
|
||||
[fontIcon]="widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].icon"
|
||||
class="icon s-40 secondary-text mr-16"></mat-icon>
|
||||
<span class="mat-display-2 m-0 font-weight-300 secondary-text">
|
||||
{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].temp[widgets.weatherWidget.tempUnit]}}
|
||||
</span>
|
||||
<span class="font-size-48 font-weight-300 hint-text text-super ml-8">°</span>
|
||||
<span class="mat-display-2 mb-0 font-weight-300 hint-text ng-binding">C</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grey-300-bg p-16" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon fontSet="meteocons" fontIcon="icon-windy"
|
||||
class="s-16 secondary-text mr-8"></mat-icon>
|
||||
<span>
|
||||
{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].windSpeed[widgets.weatherWidget.speedUnit]}}
|
||||
</span>
|
||||
<span class="secondary-text ml-5">{{widgets.weatherWidget.speedUnit}}</span>
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon fontSet="meteocons" fontIcon="icon-compass"
|
||||
class="s-16 secondary-text mr-8"></mat-icon>
|
||||
<span>
|
||||
{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].windDirection}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon fontSet="meteocons" fontIcon="icon-rainy"
|
||||
class="s-16 secondary-text mr-8"></mat-icon>
|
||||
<span>
|
||||
{{widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].rainProbability}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="py-16">
|
||||
<div class="py-16 px-24" fxLayout="row" fxLayoutAlign="space-between center"
|
||||
*ngFor="let day of widgets.weatherWidget.locations[widgets.weatherWidget.currentLocation].next3Days">
|
||||
<span class="h4">{{day.name}}</span>
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon fontSet="meteocons" [fontIcon]="day.icon" class="secondary-text mr-16"></mat-icon>
|
||||
<span class="h2">{{day.temp[widgets.weatherWidget.tempUnit]}}</span>
|
||||
<span class="h2 font-weight-300 secondary-text text-super">°</span>
|
||||
<span class="h2 font-weight-300 secondary-text">
|
||||
{{widgets.weatherWidget.tempUnit}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WEATHER WIDGET -->
|
||||
|
||||
</div>
|
||||
<!-- / WIDGET GROUP -->
|
||||
|
||||
</div>
|
||||
<!-- / SIDEBAR CONTENT -->
|
||||
|
||||
</fuse-sidebar>
|
||||
<!-- / SIDEBAR -->
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="center" fusePerfectScrollbar>
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24 pb-0" fxLayout="column" fxLayoutAlign="space-between">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="space-between start">
|
||||
|
||||
<span class="mat-display-1 mb-0 welcome-message"
|
||||
[@animate]="{value:'*',params:{x:'50px'}}">Welcome back, John!
|
||||
</span>
|
||||
|
||||
<button mat-icon-button class="sidebar-toggle mr-8" fxHide.gt-md
|
||||
(click)="toggleSidebar('project-dashboard-right-sidebar-1')">
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div fxLayout="row">
|
||||
|
||||
<div class="selected-project">{{selectedProject.name}}</div>
|
||||
|
||||
<button mat-icon-button class="project-selector" [matMenuTriggerFor]="projectsMenu"
|
||||
aria-label="Select project">
|
||||
<mat-icon>more_horiz</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #projectsMenu="matMenu">
|
||||
<button mat-menu-item *ngFor="let project of projects" (click)="selectedProject = project">
|
||||
<span>{{project.name}}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content">
|
||||
|
||||
<mat-tab-group dynamicHeight>
|
||||
|
||||
<mat-tab label="Home">
|
||||
|
||||
<div class="widget-group grey-100-bg p-12" fxLayout="row wrap" fxFlex="100" *fuseIfOnDom
|
||||
[@animateStagger]="{value:'50'}">
|
||||
|
||||
<!-- WIDGET 1 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<mat-form-field>
|
||||
<mat-select class="simplified font-size-16"
|
||||
[(ngModel)]="widgets.widget1.currentRange"
|
||||
aria-label="Change range">
|
||||
<mat-option *ngFor="let range of widgets.widget1.ranges | keys"
|
||||
[value]="range.key">
|
||||
{{range.value}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<button mat-icon-button fuseWidgetToggle aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
|
||||
<div class="light-blue-fg font-size-72 line-height-72">
|
||||
{{widgets.widget1.data.count[widgets.widget1.currentRange]}}
|
||||
</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget1.data.label}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
|
||||
<span class="h4 secondary-text text-truncate">
|
||||
{{widgets.widget1.data.extra.label}}:
|
||||
</span>
|
||||
<span class="h4 ml-8">
|
||||
{{widgets.widget1.data.extra.count[widgets.widget1.currentRange]}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
<!-- Back -->
|
||||
<div class="fuse-widget-back p-16 pt-32 mat-white-bg mat-elevation-z2">
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="Flip widget">
|
||||
<mat-icon class="s-16">close</mat-icon>
|
||||
</button>
|
||||
|
||||
<div>
|
||||
{{widgets.widget1.detail}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Back -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 1 -->
|
||||
|
||||
<!-- WIDGET 2 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget2.title}}</div>
|
||||
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
|
||||
<div class="red-fg font-size-72 line-height-72">
|
||||
{{widgets.widget2.data.count}}
|
||||
</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget2.data.label}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
|
||||
<span class="h4 secondary-text text-truncate">
|
||||
{{widgets.widget2.data.extra.label}}:
|
||||
</span>
|
||||
<span class="h4 ml-8">{{widgets.widget2.data.extra.count}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
<!-- Back -->
|
||||
<div class="fuse-widget-back p-16 pt-32 mat-white-bg mat-elevation-z2">
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="Flip widget">
|
||||
<mat-icon class="s-16">close</mat-icon>
|
||||
</button>
|
||||
|
||||
<div>
|
||||
{{widgets.widget2.detail}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Back -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 2 -->
|
||||
|
||||
<!-- WIDGET 3 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget3.title}}</div>
|
||||
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
|
||||
<div class="orange-fg font-size-72 line-height-72">
|
||||
{{widgets.widget3.data.count}}
|
||||
</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget3.data.label}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
|
||||
<span class="h4 secondary-text text-truncate">
|
||||
{{widgets.widget3.data.extra.label}}:
|
||||
</span>
|
||||
<span class="h4 ml-8">{{widgets.widget3.data.extra.count}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
<!-- Back -->
|
||||
<div class="fuse-widget-back p-16 pt-32 mat-white-bg mat-elevation-z2">
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="Flip widget">
|
||||
<mat-icon class="s-16">close</mat-icon>
|
||||
</button>
|
||||
|
||||
<div>
|
||||
{{widgets.widget3.detail}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Back -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 3 -->
|
||||
|
||||
<!-- WIDGET 4 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget4.title}}</div>
|
||||
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
|
||||
<div class="blue-grey-fg font-size-72 line-height-72">
|
||||
{{widgets.widget4.data.count}}
|
||||
</div>
|
||||
<div class="h3 secondary-text font-weight-500">{{widgets.widget4.data.label}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
|
||||
<span class="h4 secondary-text text-truncate">
|
||||
{{widgets.widget4.data.extra.label}}:
|
||||
</span>
|
||||
<span class="h4 ml-8">{{widgets.widget4.data.extra.count}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
<!-- Back -->
|
||||
<div class="fuse-widget-back p-16 pt-32 mat-white-bg mat-elevation-z2">
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="Flip widget">
|
||||
<mat-icon class="s-16">close</mat-icon>
|
||||
</button>
|
||||
|
||||
<div>
|
||||
{{widgets.widget4.detail}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Back -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 4 -->
|
||||
|
||||
<!-- WIDGET 5 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" fxLayout="row" fxFlex="100"
|
||||
class="widget widget5">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
|
||||
<div class="px-16 border-bottom" fxLayout="row wrap"
|
||||
fxLayoutAlign="space-between center">
|
||||
|
||||
<div fxFlex class="py-16 h3">{{widgets.widget5.title}}</div>
|
||||
|
||||
<div fxFlex="0 1 auto" class="py-16" fxLayout="row">
|
||||
<button mat-button class="px-16"
|
||||
*ngFor="let range of widgets.widget5.ranges | keys"
|
||||
(click)="widget5.currentRange = range.key"
|
||||
[disabled]="widget5.currentRange == range.key">
|
||||
{{range.value}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutAlign="start start">
|
||||
|
||||
<div class="h-420 my-16" fxLayout="row" fxFlex="100" fxFlex.gt-sm="50">
|
||||
<ngx-charts-bar-vertical-stacked
|
||||
*fuseIfOnDom
|
||||
[scheme]="widget5.scheme"
|
||||
[results]="this.widgets.widget5.mainChart[this.widget5.currentRange]"
|
||||
[gradient]="widget5.gradient"
|
||||
[xAxis]="widget5.xAxis"
|
||||
[yAxis]="widget5.yAxis"
|
||||
[legend]="widget5.legend"
|
||||
[showXAxisLabel]="widget5.showXAxisLabel"
|
||||
[showYAxisLabel]="widget5.showYAxisLabel"
|
||||
[xAxisLabel]="widget5.xAxisLabel"
|
||||
[yAxisLabel]="widget5.yAxisLabel"
|
||||
(select)="widget5.onSelect($event)">
|
||||
</ngx-charts-bar-vertical-stacked>
|
||||
</div>
|
||||
|
||||
<div class="my-16" fxFlex="100" fxLayout="row wrap" fxFlex.gt-sm="50">
|
||||
|
||||
<div fxLayout="column" fxFlex="100" fxFlex.gt-sm="50" fxLayoutAlign="center"
|
||||
*ngFor="let widget of widgets.widget5.supporting | keys"
|
||||
class="mb-24">
|
||||
|
||||
<div class="px-24">
|
||||
<div class="h4 secondary-text">{{widget.value.label}}</div>
|
||||
<div class="mat-display-1 m-0">
|
||||
{{widget.value.count[widget5.currentRange]}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h-64">
|
||||
<ngx-charts-area-chart
|
||||
*fuseIfOnDom
|
||||
[results]="widget.value.chart[widget5.currentRange]"
|
||||
[scheme]="widget5.supporting.scheme"
|
||||
[gradient]="widget5.supporting.gradient"
|
||||
[xAxis]="widget5.supporting.xAxis"
|
||||
[yAxis]="widget5.supporting.yAxis"
|
||||
[legend]="widget5.supporting.legend"
|
||||
[showXAxisLabel]="widget5.supporting.showXAxisLabel"
|
||||
[showYAxisLabel]="widget5.supporting.showYAxisLabel"
|
||||
[xAxisLabel]="widget5.supporting.xAxisLabel"
|
||||
[yAxisLabel]="widget5.supporting.yAxisLabel"
|
||||
[curve]="widget5.supporting.curve">
|
||||
</ngx-charts-area-chart>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 5 -->
|
||||
|
||||
<!-- WIDGET 6 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-sm="50">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
|
||||
<div class="px-16 py-8 border-bottom" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget6.title}}</div>
|
||||
<mat-form-field>
|
||||
<mat-select class="simplified" [(ngModel)]="widget6.currentRange"
|
||||
aria-label="Change range">
|
||||
<mat-option *ngFor="let range of widgets.widget6.ranges | keys"
|
||||
[value]="range.key">
|
||||
{{range.value}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="h-400">
|
||||
<ngx-charts-pie-chart
|
||||
*fuseIfOnDom
|
||||
[scheme]="widget6.scheme"
|
||||
[results]="widgets.widget6.mainChart[widget6.currentRange]"
|
||||
[legend]="widget6.showLegend"
|
||||
[explodeSlices]="widget6.explodeSlices"
|
||||
[labels]="widget6.labels"
|
||||
[doughnut]="widget6.doughnut"
|
||||
[gradient]="widget6.gradient"
|
||||
(select)="widget6.onSelect($event)">
|
||||
</ngx-charts-pie-chart>
|
||||
</div>
|
||||
|
||||
<div class="py-8 mh-16 border-top" fxLayout="row wrap" fxLayoutAlign="start center">
|
||||
|
||||
<div class="py-8 border-right" fxLayout="column" fxLayoutAlign="center center"
|
||||
fxFlex="100" fxFlex.gt-sm="50">
|
||||
<span class="mat-display-1 mb-0">
|
||||
{{widgets.widget6.footerLeft.count[widget6.currentRange]}}
|
||||
</span>
|
||||
<span class="h4">{{widgets.widget6.footerLeft.title}}</span>
|
||||
</div>
|
||||
|
||||
<div class="py-8" fxLayout="column" fxLayoutAlign="center center" fxFlex="100"
|
||||
fxFlex.gt-sm="50">
|
||||
<span class="mat-display-1 mb-0">
|
||||
{{widgets.widget6.footerRight.count[widget6.currentRange]}}
|
||||
</span>
|
||||
<span class="h4">{{widgets.widget6.footerRight.title}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 6 -->
|
||||
|
||||
<!-- WIDGET 7 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-sm="50">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
|
||||
<div class="px-16 py-8 border-bottom" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget7.title}}</div>
|
||||
<mat-form-field>
|
||||
<mat-select class="simplified" [(ngModel)]="widget7.currentRange"
|
||||
aria-label="Change range">
|
||||
<mat-option *ngFor="let range of widgets.widget7.ranges | keys"
|
||||
[value]="range.key">
|
||||
{{range.value}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="p-16" fxLayout="row" fxLayoutAlign="space-between center"
|
||||
*ngFor="let event of widgets.widget7.schedule[widget7.currentRange]">
|
||||
<div>
|
||||
<div class="h3">{{event.title}}</div>
|
||||
<div>
|
||||
<span class="secondary-text">{{event.time}}</span>
|
||||
<span *ngIf="event.location">, {{event.location}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button mat-icon-button aria-label="More information">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 7 -->
|
||||
|
||||
</div>
|
||||
<!-- / WIDGET GROUP -->
|
||||
|
||||
</mat-tab>
|
||||
|
||||
<mat-tab label="Budget Summary">
|
||||
|
||||
<!-- WIDGET GROUP -->
|
||||
<div class="widget-group grey-100-bg" fxLayout="row wrap" fxFlex="100" *fuseIfOnDom
|
||||
[@animateStagger]="{value:'50'}">
|
||||
|
||||
<!-- WIDGET 8 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-sm="50">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="h3 px-16 py-24">
|
||||
{{widgets.widget8.title}}
|
||||
</div>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<div class="h-400">
|
||||
<ngx-charts-pie-chart
|
||||
*fuseIfOnDom
|
||||
[scheme]="widget8.scheme"
|
||||
[results]="widgets.widget8.mainChart"
|
||||
[legend]="widget8.legend"
|
||||
[explodeSlices]="widget8.explodeSlices"
|
||||
[labels]="widget8.labels"
|
||||
[doughnut]="widget8.doughnut"
|
||||
[gradient]="widget8.gradient"
|
||||
(select)="widget8.onSelect($event)">
|
||||
</ngx-charts-pie-chart>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 8 -->
|
||||
|
||||
<!-- WIDGET 9 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column"
|
||||
fxFlex="100" fxFlex.gt-sm="50">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="px-16 py-12 border-bottom" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h3">{{widgets.widget9.title}}</div>
|
||||
<mat-form-field>
|
||||
<mat-select [(ngModel)]="widget9.currentRange" aria-label="Change range">
|
||||
<mat-option *ngFor="let range of widgets.widget9.ranges | keys"
|
||||
[value]="range.key">
|
||||
{{range.value}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="px-16 py-24" fxLayout="column" fxLayoutAlign="center"
|
||||
fxLayout.gt-xs="row"
|
||||
fxLayoutAlign.gt-xs="space-between end">
|
||||
<div fxFlex="0 1 auto">
|
||||
<div class="h4 secondary-text">{{widgets.widget9.weeklySpent.title}}</div>
|
||||
<div class="pt-8 mat-display-1 m-0 font-weight-300 text-nowrap">
|
||||
<span class="secondary-text">$</span>
|
||||
<span>{{widgets.widget9.weeklySpent.count[widget9.currentRange]}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-52" fxFlex>
|
||||
<ngx-charts-area-chart
|
||||
*fuseIfOnDom
|
||||
[results]="widgets.widget9.weeklySpent.chart[widget9.currentRange]"
|
||||
[scheme]="widget9.scheme"
|
||||
[gradient]="widget9.gradient"
|
||||
[xAxis]="widget9.xAxis"
|
||||
[yAxis]="widget9.yAxis"
|
||||
[legend]="widget9.legend"
|
||||
[showXAxisLabel]="widget9.showXAxisLabel"
|
||||
[showYAxisLabel]="widget9.showYAxisLabel"
|
||||
[xAxisLabel]="widget9.xAxisLabel"
|
||||
[yAxisLabel]="widget9.yAxisLabel"
|
||||
[curve]="widget9.curve">
|
||||
</ngx-charts-area-chart>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-16 py-24" fxLayout="column" fxLayoutAlign="center"
|
||||
fxLayout.gt-xs="row"
|
||||
fxLayoutAlign.gt-xs="space-between end">
|
||||
<div fxFlex="0 1 auto">
|
||||
<div class="h4 secondary-text">{{widgets.widget9.totalSpent.title}}</div>
|
||||
<div class="pt-8 mat-display-1 m-0 font-weight-300 text-nowrap">
|
||||
<span class="secondary-text">$</span>
|
||||
<span>{{widgets.widget9.totalSpent.count[widget9.currentRange]}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-52" fxFlex>
|
||||
<ngx-charts-area-chart
|
||||
*fuseIfOnDom
|
||||
[results]="widgets.widget9.totalSpent.chart[widget9.currentRange]"
|
||||
[scheme]="widget9.scheme"
|
||||
[gradient]="widget9.gradient"
|
||||
[xAxis]="widget9.xAxis"
|
||||
[yAxis]="widget9.yAxis"
|
||||
[legend]="widget9.legend"
|
||||
[showXAxisLabel]="widget9.showXAxisLabel"
|
||||
[showYAxisLabel]="widget9.showYAxisLabel"
|
||||
[xAxisLabel]="widget9.xAxisLabel"
|
||||
[yAxisLabel]="widget9.yAxisLabel"
|
||||
[curve]="widget9.curve">
|
||||
</ngx-charts-area-chart>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-16 py-24" fxLayout="column" fxLayoutAlign="center"
|
||||
fxLayout.gt-xs="row"
|
||||
fxLayoutAlign.gt-xs="space-between end">
|
||||
<div fxFlex="0 1 auto">
|
||||
<div class="h4 secondary-text">{{widgets.widget9.remaining.title}}</div>
|
||||
<div class="pt-8 mat-display-1 m-0 font-weight-300 text-nowrap">
|
||||
<span class="secondary-text">$</span>
|
||||
<span>{{widgets.widget9.remaining.count[widget9.currentRange]}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-52" fxFlex>
|
||||
<ngx-charts-area-chart
|
||||
*fuseIfOnDom
|
||||
[results]="widgets.widget9.remaining.chart[widget9.currentRange]"
|
||||
[scheme]="widget9.scheme"
|
||||
[gradient]="widget9.gradient"
|
||||
[xAxis]="widget9.xAxis"
|
||||
[yAxis]="widget9.yAxis"
|
||||
[legend]="widget9.legend"
|
||||
[showXAxisLabel]="widget9.showXAxisLabel"
|
||||
[showYAxisLabel]="widget9.showYAxisLabel"
|
||||
[xAxisLabel]="widget9.xAxisLabel"
|
||||
[yAxisLabel]="widget9.yAxisLabel"
|
||||
[curve]="widget9.curve">
|
||||
</ngx-charts-area-chart>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-16 py-24 border-top">
|
||||
<div class="h4 secondary-text">{{widgets.widget9.totalBudget.title}}</div>
|
||||
<div class="pt-8 mat-display-1 m-0 font-weight-300">
|
||||
<span class="secondary-text">$</span>
|
||||
<span>{{widgets.widget9.totalBudget.count}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 9 -->
|
||||
|
||||
<!-- WIDGET 10 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row"
|
||||
fxFlex="100">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
|
||||
<div class="simple-table-container" ms-responsive-table>
|
||||
<div class=" table-title">
|
||||
{{widgets.widget10.title}}
|
||||
</div>
|
||||
|
||||
<table class="simple">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th *ngFor="let column of widgets.widget10.table.columns">
|
||||
{{column.title}}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr *ngFor="let row of widgets.widget10.table.rows">
|
||||
<td *ngFor="let cell of row">
|
||||
<span class="p-4" [ngClass]="cell.classes">
|
||||
{{cell.value}}
|
||||
</span>
|
||||
<mat-icon *ngIf="cell.icon" class="s-16">{{cell.icon}}
|
||||
</mat-icon>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 10 -->
|
||||
|
||||
</div>
|
||||
<!-- / WIDGET GROUP -->
|
||||
|
||||
</mat-tab>
|
||||
|
||||
<mat-tab label="Team Members">
|
||||
|
||||
<!-- WIDGET GROUP -->
|
||||
<div class="widget-group grey-100-bg" fxLayout="row wrap" fxFlex="100" *fuseIfOnDom
|
||||
[@animateStagger]="{value:'50'}">
|
||||
|
||||
<!-- WIDGET 11 -->
|
||||
<fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row"
|
||||
fxFlex="100">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
|
||||
<div class="p-24 mb-8 border-bottom" fxLayout="row"
|
||||
fxLayoutAlign="space-between center">
|
||||
<div class="h2">{{widgets.widget11.title}}</div>
|
||||
<div class="text-boxed red-bg white-fg m-0">
|
||||
{{widgets.widget11.table.rows.length}}
|
||||
members
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-table #table [dataSource]="widget11.dataSource">
|
||||
|
||||
<!-- Avatar Column -->
|
||||
<ng-container cdkColumnDef="avatar">
|
||||
<mat-header-cell fxFlex="96px" *cdkHeaderCellDef></mat-header-cell>
|
||||
<mat-cell fxFlex="96px" *cdkCellDef="let contact">
|
||||
<img class="avatar" *ngIf="contact.avatar" [alt]="contact.name"
|
||||
[src]="contact.avatar"/>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Name Column -->
|
||||
<ng-container cdkColumnDef="name">
|
||||
<mat-header-cell *cdkHeaderCellDef>Name</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact">
|
||||
<p class="text-truncate font-weight-600">{{contact.name}}
|
||||
{{contact.lastName}}</p>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Position Column -->
|
||||
<ng-container cdkColumnDef="position">
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-sm>Position
|
||||
</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-sm>
|
||||
<p class="position text-truncate">
|
||||
{{contact.position}}
|
||||
</p>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Office Column -->
|
||||
<ng-container cdkColumnDef="office">
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-md>Office
|
||||
</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-md>
|
||||
<p class="office text-truncate">
|
||||
{{contact.office}}
|
||||
</p>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Email Column -->
|
||||
<ng-container cdkColumnDef="email">
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-sm>Email
|
||||
</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-sm>
|
||||
<p class="email text-truncate">
|
||||
{{contact.email}}
|
||||
</p>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Phone Column -->
|
||||
<ng-container cdkColumnDef="phone">
|
||||
<mat-header-cell *cdkHeaderCellDef fxHide fxShow.gt-md>Phone
|
||||
</mat-header-cell>
|
||||
<mat-cell *cdkCellDef="let contact" fxHide fxShow.gt-md>
|
||||
<p class="phone text-truncate">
|
||||
{{contact.phone}}
|
||||
</p>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row
|
||||
*cdkHeaderRowDef="widgets.widget11.table.columns"></mat-header-row>
|
||||
<mat-row *cdkRowDef="let contact; columns: widgets.widget11.table.columns;">
|
||||
</mat-row>
|
||||
</mat-table>
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
</fuse-widget>
|
||||
<!-- / WIDGET 11 -->
|
||||
|
||||
</div>
|
||||
<!-- / WIDGET GROUP -->
|
||||
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
||||
<!-- / CENTER -->
|
||||
|
||||
</div>
|
|
@ -1,62 +0,0 @@
|
|||
#dashboard-project {
|
||||
|
||||
> .sidebar {
|
||||
width: 280px;
|
||||
min-width: 280px;
|
||||
max-width: 280px;
|
||||
}
|
||||
|
||||
> .center {
|
||||
|
||||
> .header {
|
||||
height: 160px;
|
||||
min-height: 160px;
|
||||
max-height: 160px;
|
||||
|
||||
.selected-project {
|
||||
background: rgba(0, 0, 0, 0.12);
|
||||
color: #FFFFFF;
|
||||
padding: 8px 16px;
|
||||
height: 40px;
|
||||
line-height: 24px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.project-selector {
|
||||
margin-left: 1px;
|
||||
border-radius: 0;
|
||||
background: rgba(0, 0, 0, 0.12);
|
||||
|
||||
mat-icon {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .content {
|
||||
flex: 1;
|
||||
|
||||
mat-tab-group {
|
||||
height: 100%;
|
||||
|
||||
.mat-tab-body-wrapper {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-tab-label-container {
|
||||
padding: 0 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.widget {
|
||||
|
||||
&.widget5 {
|
||||
|
||||
.gridline-path.gridline-path-horizontal {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Subject} from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { orderStatuses } from 'app/main/apps/e-commerce/order/order-statuses';
|
||||
import { Order } from 'app/main/apps/e-commerce/order/order.model';
|
||||
import { EcommerceOrderService } from 'app/main/apps/e-commerce/order/order.service';
|
||||
|
||||
@Component({
|
||||
selector : 'e-commerce-order',
|
||||
templateUrl : './order.component.html',
|
||||
styleUrls : ['./order.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class EcommerceOrderComponent implements OnInit, OnDestroy
|
||||
{
|
||||
order: Order;
|
||||
orderStatuses: any;
|
||||
statusForm: FormGroup;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {EcommerceOrderService} _ecommerceOrderService
|
||||
* @param {FormBuilder} _formBuilder
|
||||
*/
|
||||
constructor(
|
||||
private _ecommerceOrderService: EcommerceOrderService,
|
||||
private _formBuilder: FormBuilder
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.order = new Order();
|
||||
this.orderStatuses = orderStatuses;
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to update order on changes
|
||||
this._ecommerceOrderService.onOrderChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(order => {
|
||||
this.order = new Order(order);
|
||||
});
|
||||
|
||||
this.statusForm = this._formBuilder.group({
|
||||
newStatus: ['']
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Update status
|
||||
*/
|
||||
updateStatus(): void
|
||||
{
|
||||
const newStatusId = Number.parseInt(this.statusForm.get('newStatus').value);
|
||||
|
||||
if ( !newStatusId )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const newStatus = this.orderStatuses.find((status) => {
|
||||
return status.id === newStatusId;
|
||||
});
|
||||
|
||||
newStatus['date'] = new Date().toString();
|
||||
|
||||
this.order.status.unshift(newStatus);
|
||||
}
|
||||
}
|
|
@ -1,242 +0,0 @@
|
|||
import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatPaginator, MatSort } from '@angular/material';
|
||||
import { DataSource } from '@angular/cdk/collections';
|
||||
import { merge, Observable, BehaviorSubject, fromEvent, Subject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseUtils } from '@fuse/utils';
|
||||
|
||||
import { EcommerceOrdersService } from 'app/main/apps/e-commerce/orders/orders.service';
|
||||
import { takeUntil } from 'rxjs/internal/operators';
|
||||
|
||||
@Component({
|
||||
selector : 'e-commerce-orders',
|
||||
templateUrl: './orders.component.html',
|
||||
styleUrls : ['./orders.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class EcommerceOrdersComponent implements OnInit, OnDestroy
|
||||
{
|
||||
dataSource: FilesDataSource | null;
|
||||
displayedColumns = ['id', 'reference', 'customer', 'total', 'payment', 'status', 'date'];
|
||||
|
||||
@ViewChild(MatPaginator)
|
||||
paginator: MatPaginator;
|
||||
|
||||
@ViewChild('filter')
|
||||
filter: ElementRef;
|
||||
|
||||
@ViewChild(MatSort)
|
||||
sort: MatSort;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {EcommerceOrdersService} _ecommerceOrdersService
|
||||
*/
|
||||
constructor(
|
||||
private _ecommerceOrdersService: EcommerceOrdersService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.dataSource = new FilesDataSource(this._ecommerceOrdersService, this.paginator, this.sort);
|
||||
|
||||
fromEvent(this.filter.nativeElement, 'keyup')
|
||||
.pipe(
|
||||
takeUntil(this._unsubscribeAll),
|
||||
debounceTime(150),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
.subscribe(() => {
|
||||
if ( !this.dataSource )
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.dataSource.filter = this.filter.nativeElement.value;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
||||
|
||||
export class FilesDataSource extends DataSource<any>
|
||||
{
|
||||
// Private
|
||||
private _filterChange = new BehaviorSubject('');
|
||||
private _filteredDataChange = new BehaviorSubject('');
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {EcommerceOrdersService} _ecommerceOrdersService
|
||||
* @param {MatPaginator} _matPaginator
|
||||
* @param {MatSort} _matSort
|
||||
*/
|
||||
constructor(
|
||||
private _ecommerceOrdersService: EcommerceOrdersService,
|
||||
private _matPaginator: MatPaginator,
|
||||
private _matSort: MatSort
|
||||
)
|
||||
{
|
||||
super();
|
||||
|
||||
this.filteredData = this._ecommerceOrdersService.orders;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// Filtered data
|
||||
get filteredData(): any
|
||||
{
|
||||
return this._filteredDataChange.value;
|
||||
}
|
||||
|
||||
set filteredData(value: any)
|
||||
{
|
||||
this._filteredDataChange.next(value);
|
||||
}
|
||||
|
||||
// Filter
|
||||
get filter(): string
|
||||
{
|
||||
return this._filterChange.value;
|
||||
}
|
||||
|
||||
set filter(filter: string)
|
||||
{
|
||||
this._filterChange.next(filter);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Connect function called by the table to retrieve one stream containing the data to render.
|
||||
*
|
||||
* @returns {Observable<any[]>}
|
||||
*/
|
||||
connect(): Observable<any[]>
|
||||
{
|
||||
const displayDataChanges = [
|
||||
this._ecommerceOrdersService.onOrdersChanged,
|
||||
this._matPaginator.page,
|
||||
this._filterChange,
|
||||
this._matSort.sortChange
|
||||
];
|
||||
|
||||
return merge(...displayDataChanges).pipe(map(() => {
|
||||
|
||||
let data = this._ecommerceOrdersService.orders.slice();
|
||||
|
||||
data = this.filterData(data);
|
||||
|
||||
this.filteredData = [...data];
|
||||
|
||||
data = this.sortData(data);
|
||||
|
||||
// Grab the page's slice of data.
|
||||
const startIndex = this._matPaginator.pageIndex * this._matPaginator.pageSize;
|
||||
return data.splice(startIndex, this._matPaginator.pageSize);
|
||||
})
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter data
|
||||
*
|
||||
* @param data
|
||||
* @returns {any}
|
||||
*/
|
||||
filterData(data): any
|
||||
{
|
||||
if ( !this.filter )
|
||||
{
|
||||
return data;
|
||||
}
|
||||
return FuseUtils.filterArrayByString(data, this.filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort data
|
||||
*
|
||||
* @param data
|
||||
* @returns {any[]}
|
||||
*/
|
||||
sortData(data): any[]
|
||||
{
|
||||
if ( !this._matSort.active || this._matSort.direction === '' )
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
return data.sort((a, b) => {
|
||||
let propertyA: number | string = '';
|
||||
let propertyB: number | string = '';
|
||||
|
||||
switch ( this._matSort.active )
|
||||
{
|
||||
case 'id':
|
||||
[propertyA, propertyB] = [a.id, b.id];
|
||||
break;
|
||||
case 'reference':
|
||||
[propertyA, propertyB] = [a.reference, b.reference];
|
||||
break;
|
||||
case 'customer':
|
||||
[propertyA, propertyB] = [a.customer.firstName, b.customer.firstName];
|
||||
break;
|
||||
case 'total':
|
||||
[propertyA, propertyB] = [a.total, b.total];
|
||||
break;
|
||||
case 'payment':
|
||||
[propertyA, propertyB] = [a.payment.method, b.payment.method];
|
||||
break;
|
||||
case 'status':
|
||||
[propertyA, propertyB] = [a.status[0].name, b.status[0].name];
|
||||
break;
|
||||
case 'date':
|
||||
[propertyA, propertyB] = [a.date, b.date];
|
||||
break;
|
||||
}
|
||||
|
||||
const valueA = isNaN(+propertyA) ? propertyA : +propertyA;
|
||||
const valueB = isNaN(+propertyB) ? propertyB : +propertyB;
|
||||
|
||||
return (valueA < valueB ? -1 : 1) * (this._matSort.direction === 'asc' ? 1 : -1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*/
|
||||
disconnect(): void
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,171 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Location } from '@angular/common';
|
||||
import { MatSnackBar } from '@angular/material';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseUtils } from '@fuse/utils';
|
||||
|
||||
import { Product } from 'app/main/apps/e-commerce/product/product.model';
|
||||
import { EcommerceProductService } from 'app/main/apps/e-commerce/product/product.service';
|
||||
|
||||
@Component({
|
||||
selector : 'e-commerce-product',
|
||||
templateUrl : './product.component.html',
|
||||
styleUrls : ['./product.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class EcommerceProductComponent implements OnInit, OnDestroy
|
||||
{
|
||||
product: Product;
|
||||
pageType: string;
|
||||
productForm: FormGroup;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {EcommerceProductService} _ecommerceProductService
|
||||
* @param {FormBuilder} _formBuilder
|
||||
* @param {Location} _location
|
||||
* @param {MatSnackBar} _matSnackBar
|
||||
*/
|
||||
constructor(
|
||||
private _ecommerceProductService: EcommerceProductService,
|
||||
private _formBuilder: FormBuilder,
|
||||
private _location: Location,
|
||||
private _matSnackBar: MatSnackBar
|
||||
)
|
||||
{
|
||||
// Set the default
|
||||
this.product = new Product();
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to update product on changes
|
||||
this._ecommerceProductService.onProductChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(product => {
|
||||
|
||||
if ( product )
|
||||
{
|
||||
this.product = new Product(product);
|
||||
this.pageType = 'edit';
|
||||
}
|
||||
else
|
||||
{
|
||||
this.pageType = 'new';
|
||||
this.product = new Product();
|
||||
}
|
||||
|
||||
this.productForm = this.createProductForm();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create product form
|
||||
*
|
||||
* @returns {FormGroup}
|
||||
*/
|
||||
createProductForm(): FormGroup
|
||||
{
|
||||
return this._formBuilder.group({
|
||||
id : [this.product.id],
|
||||
name : [this.product.name],
|
||||
handle : [this.product.handle],
|
||||
description : [this.product.description],
|
||||
categories : [this.product.categories],
|
||||
tags : [this.product.tags],
|
||||
images : [this.product.images],
|
||||
priceTaxExcl : [this.product.priceTaxExcl],
|
||||
priceTaxIncl : [this.product.priceTaxIncl],
|
||||
taxRate : [this.product.taxRate],
|
||||
comparedPrice : [this.product.comparedPrice],
|
||||
quantity : [this.product.quantity],
|
||||
sku : [this.product.sku],
|
||||
width : [this.product.width],
|
||||
height : [this.product.height],
|
||||
depth : [this.product.depth],
|
||||
weight : [this.product.weight],
|
||||
extraShippingFee: [this.product.extraShippingFee],
|
||||
active : [this.product.active]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Save product
|
||||
*/
|
||||
saveProduct(): void
|
||||
{
|
||||
const data = this.productForm.getRawValue();
|
||||
data.handle = FuseUtils.handleize(data.name);
|
||||
|
||||
this._ecommerceProductService.saveProduct(data)
|
||||
.then(() => {
|
||||
|
||||
// Trigger the subscription with new data
|
||||
this._ecommerceProductService.onProductChanged.next(data);
|
||||
|
||||
// Show the success message
|
||||
this._matSnackBar.open('Product saved', 'OK', {
|
||||
verticalPosition: 'top',
|
||||
duration : 2000
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add product
|
||||
*/
|
||||
addProduct(): void
|
||||
{
|
||||
const data = this.productForm.getRawValue();
|
||||
data.handle = FuseUtils.handleize(data.name);
|
||||
|
||||
this._ecommerceProductService.addProduct(data)
|
||||
.then(() => {
|
||||
|
||||
// Trigger the subscription with new data
|
||||
this._ecommerceProductService.onProductChanged.next(data);
|
||||
|
||||
// Show the success message
|
||||
this._matSnackBar.open('Product added', 'OK', {
|
||||
verticalPosition: 'top',
|
||||
duration : 2000
|
||||
});
|
||||
|
||||
// Change the location with new one
|
||||
this._location.go('apps/e-commerce/products/' + this.product.id + '/' + this.product.handle);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,224 +0,0 @@
|
|||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatPaginator, MatSort } from '@angular/material';
|
||||
import { DataSource } from '@angular/cdk/collections';
|
||||
import { merge, Observable, BehaviorSubject, fromEvent, Subject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseUtils } from '@fuse/utils';
|
||||
|
||||
import { EcommerceProductsService } from 'app/main/apps/e-commerce/products/products.service';
|
||||
import { takeUntil } from 'rxjs/internal/operators';
|
||||
|
||||
@Component({
|
||||
selector : 'e-commerce-products',
|
||||
templateUrl: './products.component.html',
|
||||
styleUrls : ['./products.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class EcommerceProductsComponent implements OnInit
|
||||
{
|
||||
dataSource: FilesDataSource | null;
|
||||
displayedColumns = ['id', 'image', 'name', 'category', 'price', 'quantity', 'active'];
|
||||
|
||||
@ViewChild(MatPaginator)
|
||||
paginator: MatPaginator;
|
||||
|
||||
@ViewChild(MatSort)
|
||||
sort: MatSort;
|
||||
|
||||
@ViewChild('filter')
|
||||
filter: ElementRef;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
constructor(
|
||||
private _ecommerceProductsService: EcommerceProductsService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.dataSource = new FilesDataSource(this._ecommerceProductsService, this.paginator, this.sort);
|
||||
|
||||
fromEvent(this.filter.nativeElement, 'keyup')
|
||||
.pipe(
|
||||
takeUntil(this._unsubscribeAll),
|
||||
debounceTime(150),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
.subscribe(() => {
|
||||
if ( !this.dataSource )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.dataSource.filter = this.filter.nativeElement.value;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class FilesDataSource extends DataSource<any>
|
||||
{
|
||||
private _filterChange = new BehaviorSubject('');
|
||||
private _filteredDataChange = new BehaviorSubject('');
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {EcommerceProductsService} _ecommerceProductsService
|
||||
* @param {MatPaginator} _matPaginator
|
||||
* @param {MatSort} _matSort
|
||||
*/
|
||||
constructor(
|
||||
private _ecommerceProductsService: EcommerceProductsService,
|
||||
private _matPaginator: MatPaginator,
|
||||
private _matSort: MatSort
|
||||
)
|
||||
{
|
||||
super();
|
||||
|
||||
this.filteredData = this._ecommerceProductsService.products;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect function called by the table to retrieve one stream containing the data to render.
|
||||
*
|
||||
* @returns {Observable<any[]>}
|
||||
*/
|
||||
connect(): Observable<any[]>
|
||||
{
|
||||
const displayDataChanges = [
|
||||
this._ecommerceProductsService.onProductsChanged,
|
||||
this._matPaginator.page,
|
||||
this._filterChange,
|
||||
this._matSort.sortChange
|
||||
];
|
||||
|
||||
return merge(...displayDataChanges)
|
||||
.pipe(
|
||||
map(() => {
|
||||
let data = this._ecommerceProductsService.products.slice();
|
||||
|
||||
data = this.filterData(data);
|
||||
|
||||
this.filteredData = [...data];
|
||||
|
||||
data = this.sortData(data);
|
||||
|
||||
// Grab the page's slice of data.
|
||||
const startIndex = this._matPaginator.pageIndex * this._matPaginator.pageSize;
|
||||
return data.splice(startIndex, this._matPaginator.pageSize);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// Filtered data
|
||||
get filteredData(): any
|
||||
{
|
||||
return this._filteredDataChange.value;
|
||||
}
|
||||
|
||||
set filteredData(value: any)
|
||||
{
|
||||
this._filteredDataChange.next(value);
|
||||
}
|
||||
|
||||
// Filter
|
||||
get filter(): string
|
||||
{
|
||||
return this._filterChange.value;
|
||||
}
|
||||
|
||||
set filter(filter: string)
|
||||
{
|
||||
this._filterChange.next(filter);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Filter data
|
||||
*
|
||||
* @param data
|
||||
* @returns {any}
|
||||
*/
|
||||
filterData(data): any
|
||||
{
|
||||
if ( !this.filter )
|
||||
{
|
||||
return data;
|
||||
}
|
||||
return FuseUtils.filterArrayByString(data, this.filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort data
|
||||
*
|
||||
* @param data
|
||||
* @returns {any[]}
|
||||
*/
|
||||
sortData(data): any[]
|
||||
{
|
||||
if ( !this._matSort.active || this._matSort.direction === '' )
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
return data.sort((a, b) => {
|
||||
let propertyA: number | string = '';
|
||||
let propertyB: number | string = '';
|
||||
|
||||
switch ( this._matSort.active )
|
||||
{
|
||||
case 'id':
|
||||
[propertyA, propertyB] = [a.id, b.id];
|
||||
break;
|
||||
case 'name':
|
||||
[propertyA, propertyB] = [a.name, b.name];
|
||||
break;
|
||||
case 'categories':
|
||||
[propertyA, propertyB] = [a.categories[0], b.categories[0]];
|
||||
break;
|
||||
case 'price':
|
||||
[propertyA, propertyB] = [a.priceTaxIncl, b.priceTaxIncl];
|
||||
break;
|
||||
case 'quantity':
|
||||
[propertyA, propertyB] = [a.quantity, b.quantity];
|
||||
break;
|
||||
case 'active':
|
||||
[propertyA, propertyB] = [a.active, b.active];
|
||||
break;
|
||||
}
|
||||
|
||||
const valueA = isNaN(+propertyA) ? propertyA : +propertyA;
|
||||
const valueB = isNaN(+propertyB) ? propertyB : +propertyB;
|
||||
|
||||
return (valueA < valueB ? -1 : 1) * (this._matSort.direction === 'asc' ? 1 : -1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*/
|
||||
disconnect(): void
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { DataSource } from '@angular/cdk/collections';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
|
||||
import { FileManagerService } from 'app/main/apps/file-manager/file-manager.service';
|
||||
|
||||
@Component({
|
||||
selector : 'file-list',
|
||||
templateUrl: './file-list.component.html',
|
||||
styleUrls : ['./file-list.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FileManagerFileListComponent implements OnInit, OnDestroy
|
||||
{
|
||||
files: any;
|
||||
dataSource: FilesDataSource | null;
|
||||
displayedColumns = ['icon', 'name', 'type', 'owner', 'size', 'modified', 'detail-button'];
|
||||
selected: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FileManagerService} _fileManagerService
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
*/
|
||||
constructor(
|
||||
private _fileManagerService: FileManagerService,
|
||||
private _fuseSidebarService: FuseSidebarService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.dataSource = new FilesDataSource(this._fileManagerService);
|
||||
|
||||
this._fileManagerService.onFilesChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(files => {
|
||||
this.files = files;
|
||||
});
|
||||
|
||||
this._fileManagerService.onFileSelected
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selected => {
|
||||
this.selected = selected;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On select
|
||||
*
|
||||
* @param selected
|
||||
*/
|
||||
onSelect(selected): void
|
||||
{
|
||||
this._fileManagerService.onFileSelected.next(selected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the sidebar
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
toggleSidebar(name): void
|
||||
{
|
||||
this._fuseSidebarService.getSidebar(name).toggleOpen();
|
||||
}
|
||||
}
|
||||
|
||||
export class FilesDataSource extends DataSource<any>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FileManagerService} _fileManagerService
|
||||
*/
|
||||
constructor(
|
||||
private _fileManagerService: FileManagerService
|
||||
)
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect function called by the table to retrieve one stream containing the data to render.
|
||||
*
|
||||
* @returns {Observable<any[]>}
|
||||
*/
|
||||
connect(): Observable<any[]>
|
||||
{
|
||||
return this._fileManagerService.onFilesChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect
|
||||
*/
|
||||
disconnect(): void
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
<div id="file-manager" class="page-layout simple right-sidebar inner-scroll">
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<fuse-sidebar class="sidebar main-sidebar" name="file-manager-main-sidebar" position="left">
|
||||
<file-manager-main-sidebar></file-manager-main-sidebar>
|
||||
</fuse-sidebar>
|
||||
<!-- / SIDEBAR -->
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="center" fxFlex>
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24" fxLayout="column" fxLayoutAlign="space-between start">
|
||||
|
||||
<!-- TOOLBAR -->
|
||||
<div class="toolbar w-100-p" fxFlex fxLayout="row" fxLayoutAlign="space-between start">
|
||||
|
||||
<div class="left-side" fxLayout="row">
|
||||
<button mat-icon-button class="sidebar-toggle"
|
||||
(click)="toggleSidebar('file-manager-main-sidebar')">
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="right-side" fxLayout="row">
|
||||
<button mat-icon-button aria-label="Search" matTooltip="Search">
|
||||
<mat-icon>search</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / TOOLBAR -->
|
||||
|
||||
<!-- BREADCRUMB -->
|
||||
<div class="breadcrumb text-truncate h1 pl-72" fxLayout="row" fxLayoutAlign="start center"
|
||||
[@animate]="{value:'*',params:{x:'50px'}}">
|
||||
<div *ngFor="let path of pathArr; last as isLast" fxLayout="row" fxLayoutAlign="start center">
|
||||
<span>{{path}}</span>
|
||||
<mat-icon *ngIf="!isLast" class="separator">chevron_right</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / BREADCRUMB -->
|
||||
|
||||
<!-- ADD FILE BUTTON -->
|
||||
<div class="file-uploader">
|
||||
<input hidden type="file" #fileInput/>
|
||||
<button mat-fab
|
||||
class="add-file-button mat-warn"
|
||||
(click)="fileInput.click()"
|
||||
aria-label="Add file"
|
||||
[@animate]="{value:'*', params:{delay:'300ms',scale:'0.2'}}">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<!-- / ADD FILE BUTTON -->
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content mat-white-bg" fusePerfectScrollbar>
|
||||
<file-list></file-list>
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
||||
<!-- / CENTER -->
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<fuse-sidebar class="sidebar details-sidebar" name="file-manager-details-sidebar" position="right"
|
||||
lockedOpen="gt-md">
|
||||
<file-manager-details-sidebar></file-manager-details-sidebar>
|
||||
</fuse-sidebar>
|
||||
<!-- / SIDEBAR -->
|
||||
|
||||
</div>
|
|
@ -1,72 +0,0 @@
|
|||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
#file-manager {
|
||||
|
||||
.sidebar {
|
||||
width: 320px !important;
|
||||
min-width: 320px !important;
|
||||
max-width: 320px !important;
|
||||
|
||||
&.main-sidebar {
|
||||
}
|
||||
|
||||
&.details-sidebar {
|
||||
@include media-breakpoint('gt-md') {
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
overflow: hidden;
|
||||
|
||||
.header {
|
||||
position: relative;
|
||||
height: 160px;
|
||||
min-height: 160px;
|
||||
max-height: 160px;
|
||||
|
||||
@include media-breakpoint-down('sm') {
|
||||
height: 120px;
|
||||
min-height: 120px;
|
||||
max-height: 120px;
|
||||
}
|
||||
|
||||
.add-file-button {
|
||||
position: absolute;
|
||||
bottom: -28px;
|
||||
left: 16px;
|
||||
z-index: 999;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.type-icon {
|
||||
|
||||
&.folder {
|
||||
&:before {
|
||||
content: 'folder';
|
||||
color: #FFB300;
|
||||
}
|
||||
}
|
||||
|
||||
&.document {
|
||||
&:before {
|
||||
content: 'insert_drive_file';
|
||||
color: #1565C0;
|
||||
}
|
||||
}
|
||||
|
||||
&.spreadsheet {
|
||||
&:before {
|
||||
content: 'insert_chart';
|
||||
color: #4CAF50;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
|
||||
import { FileManagerService } from 'app/main/apps/file-manager/file-manager.service';
|
||||
|
||||
@Component({
|
||||
selector : 'file-manager',
|
||||
templateUrl : './file-manager.component.html',
|
||||
styleUrls : ['./file-manager.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FileManagerComponent implements OnInit, OnDestroy
|
||||
{
|
||||
selected: any;
|
||||
pathArr: string[];
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FileManagerService} _fileManagerService
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
*/
|
||||
constructor(
|
||||
private _fileManagerService: FileManagerService,
|
||||
private _fuseSidebarService: FuseSidebarService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._fileManagerService.onFileSelected
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selected => {
|
||||
this.selected = selected;
|
||||
this.pathArr = selected.location.split('>');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle the sidebar
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
toggleSidebar(name): void
|
||||
{
|
||||
this._fuseSidebarService.getSidebar(name).toggleOpen();
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
import { MatButtonModule, MatIconModule, MatRippleModule, MatSlideToggleModule, MatTableModule } from '@angular/material';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
import { FuseSidebarModule } from '@fuse/components';
|
||||
|
||||
import { FileManagerService } from 'app/main/apps/file-manager/file-manager.service';
|
||||
import { FileManagerComponent } from 'app/main/apps/file-manager/file-manager.component';
|
||||
import { FileManagerDetailsSidebarComponent } from 'app/main/apps/file-manager/sidebars/details/details.component';
|
||||
import { FileManagerFileListComponent } from 'app/main/apps/file-manager/file-list/file-list.component';
|
||||
import { FileManagerMainSidebarComponent } from 'app/main/apps/file-manager/sidebars/main/main.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : '**',
|
||||
component: FileManagerComponent,
|
||||
children : [],
|
||||
resolve : {
|
||||
files: FileManagerService
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FileManagerComponent,
|
||||
FileManagerFileListComponent,
|
||||
FileManagerMainSidebarComponent,
|
||||
FileManagerDetailsSidebarComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
CdkTableModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatRippleModule,
|
||||
MatSlideToggleModule,
|
||||
MatTableModule,
|
||||
|
||||
FuseSharedModule,
|
||||
FuseSidebarModule
|
||||
],
|
||||
providers : [
|
||||
FileManagerService
|
||||
]
|
||||
})
|
||||
export class FileManagerModule
|
||||
{
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { FileManagerService } from 'app/main/apps/file-manager/file-manager.service';
|
||||
|
||||
@Component({
|
||||
selector : 'file-manager-details-sidebar',
|
||||
templateUrl: './details.component.html',
|
||||
styleUrls : ['./details.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FileManagerDetailsSidebarComponent implements OnInit, OnDestroy
|
||||
{
|
||||
selected: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FileManagerService} _fileManagerService
|
||||
*/
|
||||
constructor(
|
||||
private _fileManagerService: FileManagerService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._fileManagerService.onFileSelected
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selected => {
|
||||
this.selected = selected;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
import { Component, Inject, ViewEncapsulation } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
|
||||
|
||||
@Component({
|
||||
selector : 'mail-ngrx-compose',
|
||||
templateUrl : './compose.component.html',
|
||||
styleUrls : ['./compose.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MailNgrxComposeDialogComponent
|
||||
{
|
||||
composeForm: FormGroup;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MatDialogRef<MailNgrxComposeDialogComponent>} matDialogRef
|
||||
* @param _data
|
||||
* @param {FormBuilder} _formBuilder
|
||||
*/
|
||||
constructor(
|
||||
public matDialogRef: MatDialogRef<MailNgrxComposeDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) private _data: any,
|
||||
private _formBuilder: FormBuilder
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.composeForm = this.createComposeForm();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create compose form
|
||||
*
|
||||
* @returns {FormGroup}
|
||||
*/
|
||||
createComposeForm(): FormGroup
|
||||
{
|
||||
return this._formBuilder.group({
|
||||
from : {
|
||||
value : ['johndoe@creapond.com'],
|
||||
disabled: [true]
|
||||
},
|
||||
to : [''],
|
||||
cc : [''],
|
||||
bcc : [''],
|
||||
subject: [''],
|
||||
message: ['']
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { Mail } from 'app/main/apps/mail-ngrx/mail.model';
|
||||
import * as fromStore from 'app/main/apps/mail-ngrx/store';
|
||||
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
||||
|
||||
@Component({
|
||||
selector : 'mail-ngrx-details',
|
||||
templateUrl : './mail-details.component.html',
|
||||
styleUrls : ['./mail-details.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class MailNgrxDetailsComponent implements OnChanges
|
||||
{
|
||||
@Input('mail')
|
||||
mailInput: Mail;
|
||||
|
||||
labels$: Observable<any>;
|
||||
mail: Mail;
|
||||
showDetails: boolean;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MailNgrxService} _mailNgrxService
|
||||
* @param {Store<MailAppState>} _store
|
||||
*/
|
||||
constructor(
|
||||
private _mailNgrxService: MailNgrxService,
|
||||
private _store: Store<fromStore.MailAppState>
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.labels$ = this._store.select(fromStore.getLabelsArr);
|
||||
this.showDetails = false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On changes
|
||||
*/
|
||||
ngOnChanges(): void
|
||||
{
|
||||
this.updateModel(this.mailInput);
|
||||
this.markAsRead();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Mark as read
|
||||
*/
|
||||
markAsRead(): void
|
||||
{
|
||||
if ( this.mail && !this.mail.read )
|
||||
{
|
||||
this.mail.markRead();
|
||||
this.updateMail();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle star
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
toggleStar(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
this.mail.toggleStar();
|
||||
this.updateMail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle important
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
toggleImportant(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
this.mail.toggleImportant();
|
||||
this.updateMail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update model
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
updateModel(data): void
|
||||
{
|
||||
this.mail = !data ? null : new Mail({...data});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the mail
|
||||
*/
|
||||
updateMail(): void
|
||||
{
|
||||
this._store.dispatch(new fromStore.UpdateMail(this.mail));
|
||||
this.updateModel(this.mail);
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
import { Mail } from 'app/main/apps/mail-ngrx/mail.model';
|
||||
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
||||
|
||||
@Component({
|
||||
selector : 'mail-ngrx-list',
|
||||
templateUrl : './mail-list.component.html',
|
||||
styleUrls : ['./mail-list.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class MailNgrxListComponent
|
||||
{
|
||||
@Input()
|
||||
mails: Mail[];
|
||||
|
||||
@Input()
|
||||
currentMail: Mail[];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ActivatedRoute} _activatedRoute
|
||||
* @param {MailNgrxService} _mailNgrxService
|
||||
* @param {Router} _router
|
||||
*/
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _mailNgrxService: MailNgrxService,
|
||||
private _router: Router
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Read mail
|
||||
*
|
||||
* @param mailId
|
||||
*/
|
||||
readMail(mailId): void
|
||||
{
|
||||
const labelHandle = this._activatedRoute.snapshot.params.labelHandle,
|
||||
filterHandle = this._activatedRoute.snapshot.params.filterHandle,
|
||||
folderHandle = this._activatedRoute.snapshot.params.folderHandle;
|
||||
|
||||
if ( labelHandle )
|
||||
{
|
||||
this._router.navigate(['apps/mail-ngrx/label/' + labelHandle + '/' + mailId]);
|
||||
}
|
||||
else if ( filterHandle )
|
||||
{
|
||||
this._router.navigate(['apps/mail-ngrx/filter/' + filterHandle + '/' + mailId]);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._router.navigate(['apps/mail-ngrx/' + folderHandle + '/' + mailId]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
<div id="mail" class="page-layout carded left-sidebar inner-scroll">
|
||||
|
||||
<!-- TOP BACKGROUND -->
|
||||
<div class="top-bg mat-accent-bg"></div>
|
||||
<!-- / TOP BACKGROUND -->
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<fuse-sidebar class="sidebar" name="mail-ngrx-main-sidebar" position="left" lockedOpen="gt-md">
|
||||
<mail-ngrx-main-sidebar></mail-ngrx-main-sidebar>
|
||||
</fuse-sidebar>
|
||||
<!-- / SIDEBAR -->
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="center">
|
||||
|
||||
<!-- CONTENT HEADER -->
|
||||
<div class="header" fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<div class="search-wrapper" fxFlex fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<button mat-icon-button class="sidebar-toggle" fxHide.gt-md
|
||||
(click)="toggleSidebar('mail-ngrx-main-sidebar')">
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="search mat-white-bg" flex fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon>search</mat-icon>
|
||||
<input [formControl]="searchInput" [placeholder]="'MAIL.SEARCH_PLACEHOLDER' | translate" fxFlex>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / CONTENT HEADER -->
|
||||
|
||||
<!-- CONTENT CARD -->
|
||||
<div class="content-card mat-white-bg" [ngClass]="{'current-mail-selected':currentMail$ | async}">
|
||||
|
||||
<!-- CONTENT TOOLBAR -->
|
||||
<div class="toolbar px-24 py-8">
|
||||
|
||||
<div class="mail-selection" fxFlex="row" fxLayoutAlign="start center">
|
||||
|
||||
<mat-checkbox (click)="toggleSelectAll($event)"
|
||||
[checked]="hasSelectedMails"
|
||||
[indeterminate]="isIndeterminate">
|
||||
</mat-checkbox>
|
||||
|
||||
<button mat-icon-button [matMenuTriggerFor]="selectMenu">
|
||||
<mat-icon>arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
<mat-menu #selectMenu="matMenu">
|
||||
<button mat-menu-item (click)="selectAllMails()">All</button>
|
||||
<button mat-menu-item (click)="deselectAllMails()">None</button>
|
||||
<button mat-menu-item (click)="selectMailsByParameter('read', true)">Read</button>
|
||||
<button mat-menu-item (click)="selectMailsByParameter('read', false)">Unread</button>
|
||||
<button mat-menu-item (click)="selectMailsByParameter('starred', true)">Starred</button>
|
||||
<button mat-menu-item (click)="selectMailsByParameter('starred', false)">Unstarred</button>
|
||||
<button mat-menu-item (click)="selectMailsByParameter('important', true)">Important</button>
|
||||
<button mat-menu-item (click)="selectMailsByParameter('important', false)">Unimportant</button>
|
||||
</mat-menu>
|
||||
|
||||
<div class="toolbar-separator" *ngIf="hasSelectedMails"></div>
|
||||
|
||||
<button mat-icon-button (click)="setFolderOnSelectedMails(4)" *ngIf="hasSelectedMails">
|
||||
<mat-icon class="secondary-text">delete</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button [matMenuTriggerFor]="folderMenu" *ngIf="hasSelectedMails">
|
||||
<mat-icon class="secondary-text">folder</mat-icon>
|
||||
</button>
|
||||
<mat-menu #folderMenu="matMenu">
|
||||
<button mat-menu-item *ngFor="let folder of folders$ | async"
|
||||
(click)="setFolderOnSelectedMails(folder.id)">{{folder.title}}
|
||||
</button>
|
||||
</mat-menu>
|
||||
|
||||
<button mat-icon-button [matMenuTriggerFor]="labelMenu" *ngIf="hasSelectedMails">
|
||||
<mat-icon class="secondary-text">label</mat-icon>
|
||||
</button>
|
||||
<mat-menu #labelMenu="matMenu">
|
||||
<button mat-menu-item *ngFor="let label of labels$ | async"
|
||||
(click)="toggleLabelOnSelectedMails(label.id)">{{label.title}}
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
||||
<div *ngIf="currentMail$ | async" fxHide.gt-xs>
|
||||
<button mat-icon-button (click)="deselectCurrentMail()">
|
||||
<mat-icon class="secondary-text">arrow_back</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / CONTENT TOOLBAR -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content" fxLayout="row">
|
||||
|
||||
<mail-ngrx-list fusePerfectScrollbar fxFlex [mails]="mails$ | async" [currentMail]="currentMail$ | async"></mail-ngrx-list>
|
||||
<mail-ngrx-details [mail]="currentMail$ | async" fusePerfectScrollbar fxFlex></mail-ngrx-details>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT CARD -->
|
||||
|
||||
</div>
|
||||
<!-- / CENTER -->
|
||||
|
||||
</div>
|
|
@ -1,206 +0,0 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
||||
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
import { FuseTranslationLoaderService } from '@fuse/services/translation-loader.service';
|
||||
|
||||
import { Mail } from 'app/main/apps/mail-ngrx/mail.model';
|
||||
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
||||
import * as fromStore from 'app/main/apps/mail-ngrx/store';
|
||||
|
||||
import { locale as english } from 'app/main/apps/mail-ngrx/i18n/en';
|
||||
import { locale as turkish } from 'app/main/apps/mail-ngrx/i18n/tr';
|
||||
|
||||
@Component({
|
||||
selector : 'mail-ngrx',
|
||||
templateUrl : './mail.component.html',
|
||||
styleUrls : ['./mail.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class MailNgrxComponent implements OnInit, OnDestroy
|
||||
{
|
||||
hasSelectedMails: boolean;
|
||||
isIndeterminate: boolean;
|
||||
searchInput: FormControl;
|
||||
mails$: Observable<any>;
|
||||
folders$: Observable<any>;
|
||||
labels$: Observable<any>;
|
||||
currentMail$: Observable<Mail>;
|
||||
selectedMailIds$: Observable<string[]>;
|
||||
searchText$: Observable<string>;
|
||||
mails: Mail[];
|
||||
selectedMailIds: string[];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ChangeDetectorRef} _changeDetectorRef
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
* @param {FuseTranslationLoaderService} _fuseTranslationLoaderService
|
||||
* @param {MailNgrxService} _mailNgrxService
|
||||
* @param {Store<MailAppState>} _store
|
||||
*/
|
||||
constructor(
|
||||
private _changeDetectorRef: ChangeDetectorRef,
|
||||
private _fuseSidebarService: FuseSidebarService,
|
||||
private _fuseTranslationLoaderService: FuseTranslationLoaderService,
|
||||
private _mailNgrxService: MailNgrxService,
|
||||
private _store: Store<fromStore.MailAppState>
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.searchInput = new FormControl('');
|
||||
this._fuseTranslationLoaderService.loadTranslations(english, turkish);
|
||||
this.currentMail$ = this._store.select(fromStore.getCurrentMail);
|
||||
this.mails$ = this._store.select(fromStore.getMailsArr);
|
||||
this.folders$ = this._store.select(fromStore.getFoldersArr);
|
||||
this.labels$ = this._store.select(fromStore.getLabelsArr);
|
||||
this.selectedMailIds$ = this._store.select(fromStore.getSelectedMailIds);
|
||||
this.searchText$ = this._store.select(fromStore.getSearchText);
|
||||
this.mails = [];
|
||||
this.selectedMailIds = [];
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.mails$.subscribe(mails => {
|
||||
this.mails = mails;
|
||||
});
|
||||
|
||||
this.selectedMailIds$
|
||||
.subscribe(selectedMailIds => {
|
||||
this.selectedMailIds = selectedMailIds;
|
||||
this.hasSelectedMails = selectedMailIds.length > 0;
|
||||
this.isIndeterminate = (selectedMailIds.length !== this.mails.length && selectedMailIds.length > 0);
|
||||
this.refresh();
|
||||
});
|
||||
|
||||
this.searchText$.subscribe(searchText => {
|
||||
this.searchInput.setValue(searchText);
|
||||
});
|
||||
|
||||
this.searchInput.valueChanges.pipe(
|
||||
debounceTime(300),
|
||||
distinctUntilChanged()
|
||||
).subscribe(searchText => {
|
||||
this._store.dispatch(new fromStore.SetSearchText(searchText));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
this._changeDetectorRef.detach();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle select all
|
||||
*
|
||||
* @param ev
|
||||
*/
|
||||
toggleSelectAll(ev): void
|
||||
{
|
||||
ev.preventDefault();
|
||||
|
||||
if ( this.selectedMailIds.length && this.selectedMailIds.length > 0 )
|
||||
{
|
||||
this.deselectAllMails();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.selectAllMails();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select all mails
|
||||
*/
|
||||
selectAllMails(): void
|
||||
{
|
||||
this._store.dispatch(new fromStore.SelectAllMails());
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselect all mails
|
||||
*/
|
||||
deselectAllMails(): void
|
||||
{
|
||||
this._store.dispatch(new fromStore.DeselectAllMails());
|
||||
}
|
||||
|
||||
/**
|
||||
* Select mails by parameter
|
||||
*
|
||||
* @param parameter
|
||||
* @param value
|
||||
*/
|
||||
selectMailsByParameter(parameter, value): void
|
||||
{
|
||||
this._store.dispatch(new fromStore.SelectMailsByParameter({
|
||||
parameter,
|
||||
value
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle label on selected mails
|
||||
*
|
||||
* @param labelId
|
||||
*/
|
||||
toggleLabelOnSelectedMails(labelId): void
|
||||
{
|
||||
this._store.dispatch(new fromStore.AddLabelOnSelectedMails(labelId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set folder on selected mails
|
||||
*
|
||||
* @param folderId
|
||||
*/
|
||||
setFolderOnSelectedMails(folderId): void
|
||||
{
|
||||
this._store.dispatch(new fromStore.SetFolderOnSelectedMails(folderId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselect current mail
|
||||
*/
|
||||
deselectCurrentMail(): void
|
||||
{
|
||||
this._store.dispatch(new fromStore.SetCurrentMail(''));
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh
|
||||
*/
|
||||
refresh(): void
|
||||
{
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the sidebar
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
toggleSidebar(name): void
|
||||
{
|
||||
this._fuseSidebarService.getSidebar(name).toggleOpen();
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { MatButtonModule, MatCheckboxModule, MatDialogModule, MatFormFieldModule, MatIconModule, MatInputModule, MatMenuModule, MatRippleModule, MatSelectModule, MatToolbarModule } from '@angular/material';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
import { FuseSidebarModule } from '@fuse/components';
|
||||
|
||||
import * as fromGuards from 'app/main/apps/mail-ngrx/store/guards/index';
|
||||
import { MailNgrxStoreModule } from 'app/main/apps/mail-ngrx/store/store.module';
|
||||
import { MailNgrxComponent } from 'app/main/apps/mail-ngrx/mail.component';
|
||||
import { MailNgrxListComponent } from 'app/main/apps/mail-ngrx/mail-list/mail-list.component';
|
||||
import { MailNgrxListItemComponent } from 'app/main/apps/mail-ngrx/mail-list/mail-list-item/mail-list-item.component';
|
||||
import { MailNgrxDetailsComponent } from 'app/main/apps/mail-ngrx/mail-details/mail-details.component';
|
||||
import { MailNgrxMainSidebarComponent } from 'app/main/apps/mail-ngrx/sidebars/main/main-sidebar.component';
|
||||
import { MailNgrxComposeDialogComponent } from 'app/main/apps/mail-ngrx/dialogs/compose/compose.component';
|
||||
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : 'label/:labelHandle',
|
||||
component : MailNgrxComponent,
|
||||
canActivate: [fromGuards.ResolveGuard]
|
||||
},
|
||||
{
|
||||
path : 'label/:labelHandle/:mailId',
|
||||
component : MailNgrxComponent,
|
||||
canActivate: [fromGuards.ResolveGuard]
|
||||
},
|
||||
{
|
||||
path : 'filter/:filterHandle',
|
||||
component : MailNgrxComponent,
|
||||
canActivate: [fromGuards.ResolveGuard]
|
||||
},
|
||||
{
|
||||
path : 'filter/:filterHandle/:mailId',
|
||||
component : MailNgrxComponent,
|
||||
canActivate: [fromGuards.ResolveGuard]
|
||||
},
|
||||
{
|
||||
path : ':folderHandle',
|
||||
component : MailNgrxComponent,
|
||||
canActivate: [fromGuards.ResolveGuard]
|
||||
},
|
||||
{
|
||||
path : ':folderHandle/:mailId',
|
||||
component : MailNgrxComponent,
|
||||
canActivate: [fromGuards.ResolveGuard]
|
||||
},
|
||||
{
|
||||
path : '**',
|
||||
redirectTo: 'inbox'
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations : [
|
||||
MailNgrxComponent,
|
||||
MailNgrxListComponent,
|
||||
MailNgrxListItemComponent,
|
||||
MailNgrxDetailsComponent,
|
||||
MailNgrxMainSidebarComponent,
|
||||
MailNgrxComposeDialogComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
MatButtonModule,
|
||||
MatCheckboxModule,
|
||||
MatDialogModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatMenuModule,
|
||||
MatRippleModule,
|
||||
MatSelectModule,
|
||||
MatToolbarModule,
|
||||
|
||||
TranslateModule,
|
||||
|
||||
FuseSharedModule,
|
||||
FuseSidebarModule,
|
||||
|
||||
MailNgrxStoreModule
|
||||
],
|
||||
providers : [
|
||||
MailNgrxService,
|
||||
fromGuards.ResolveGuard
|
||||
],
|
||||
entryComponents: [MailNgrxComposeDialogComponent]
|
||||
})
|
||||
export class MailNgrxModule
|
||||
{
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { Mail } from 'app/main/apps/mail-ngrx/mail.model';
|
||||
import { MailAppState } from 'app/main/apps/mail-ngrx/store/reducers';
|
||||
import { getFiltersArr, getFoldersArr, getLabelsArr, getMailsArr } from 'app/main/apps/mail-ngrx/store/selectors';
|
||||
|
||||
@Injectable()
|
||||
export class MailNgrxService
|
||||
{
|
||||
foldersArr: any;
|
||||
filtersArr: any;
|
||||
labelsArr: any;
|
||||
selectedMails: Mail[];
|
||||
mails: Mail[];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {HttpClient} _httpClient
|
||||
* @param {Store<MailAppState>} _store
|
||||
*/
|
||||
constructor(
|
||||
private _httpClient: HttpClient,
|
||||
private _store: Store<MailAppState>
|
||||
)
|
||||
{
|
||||
this._store.select(getFoldersArr).subscribe(folders => {
|
||||
this.foldersArr = folders;
|
||||
});
|
||||
|
||||
this._store.select(getFiltersArr).subscribe(filters => {
|
||||
this.filtersArr = filters;
|
||||
});
|
||||
|
||||
this._store.select(getLabelsArr).subscribe(labels => {
|
||||
this.labelsArr = labels;
|
||||
});
|
||||
|
||||
this._store.select(getMailsArr).subscribe(mails => {
|
||||
this.mails = mails;
|
||||
});
|
||||
|
||||
this.selectedMails = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all mails
|
||||
*
|
||||
* @returns {Observable<Mail[]>}
|
||||
*/
|
||||
getAllMails(): Observable<Mail[]>
|
||||
{
|
||||
return this._httpClient.get<Mail[]>('api/mail-mails');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get folders
|
||||
*
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
getFolders(): Observable<any>
|
||||
{
|
||||
return this._httpClient.get('api/mail-folders');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filters
|
||||
*
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
getFilters(): Observable<any>
|
||||
{
|
||||
return this._httpClient.get('api/mail-filters');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get labels
|
||||
*
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
getLabels(): Observable<any>
|
||||
{
|
||||
return this._httpClient.get('api/mail-labels');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mails
|
||||
*
|
||||
* @param handle
|
||||
* @returns {Observable<Mail[]>}
|
||||
*/
|
||||
getMails(handle): Observable<Mail[]>
|
||||
{
|
||||
if ( handle.id === 'labelHandle' )
|
||||
{
|
||||
const labelId = this.labelsArr.find(label => label.handle === handle.value).id;
|
||||
return this._httpClient.get<Mail[]>('api/mail-mails?labels=' + labelId);
|
||||
}
|
||||
else if ( handle.id === 'filterHandle' )
|
||||
{
|
||||
return this._httpClient.get<Mail[]>('api/mail-mails?' + handle.value + '=true');
|
||||
}
|
||||
else // folderHandle
|
||||
{
|
||||
const folderId = this.foldersArr.find(folder => folder.handle === handle.value).id;
|
||||
return this._httpClient.get<any>('api/mail-mails?folder=' + folderId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the mail
|
||||
*
|
||||
* @param mail
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
updateMail(mail): any
|
||||
{
|
||||
return this._httpClient.post('api/mail-mails/' + mail.id, {...mail});
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
||||
import * as fromStore from 'app/main/apps/mail-ngrx/store';
|
||||
import { MailNgrxComposeDialogComponent } from 'app/main/apps/mail-ngrx/dialogs/compose/compose.component';
|
||||
|
||||
@Component({
|
||||
selector : 'mail-ngrx-main-sidebar',
|
||||
templateUrl : './main-sidebar.component.html',
|
||||
styleUrls : ['./main-sidebar.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class MailNgrxMainSidebarComponent
|
||||
{
|
||||
labels: any[];
|
||||
accounts: object;
|
||||
selectedAccount: string;
|
||||
dialogRef: any;
|
||||
|
||||
folders$: Observable<any>;
|
||||
filters$: Observable<any>;
|
||||
labels$: Observable<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MailNgrxService} _mailNgrxService
|
||||
* @param {MatDialog} _matDialog
|
||||
* @param {Store<MailAppState>} _store
|
||||
*/
|
||||
constructor(
|
||||
private _mailNgrxService: MailNgrxService,
|
||||
private _matDialog: MatDialog,
|
||||
private _store: Store<fromStore.MailAppState>
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.accounts = {
|
||||
'creapond' : 'johndoe@creapond.com',
|
||||
'withinpixels': 'johndoe@withinpixels.com'
|
||||
};
|
||||
this.selectedAccount = 'creapond';
|
||||
this.folders$ = this._store.select(fromStore.getFoldersArr);
|
||||
this.filters$ = this._store.select(fromStore.getFiltersArr);
|
||||
this.labels$ = this._store.select(fromStore.getLabelsArr);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Compose dialog
|
||||
*/
|
||||
composeDialog(): void
|
||||
{
|
||||
this.dialogRef = this._matDialog.open(MailNgrxComposeDialogComponent, {
|
||||
panelClass: 'mail-ngrx-compose-dialog'
|
||||
});
|
||||
|
||||
this.dialogRef.afterClosed()
|
||||
.subscribe(response => {
|
||||
if ( !response )
|
||||
{
|
||||
return;
|
||||
}
|
||||
const actionType: string = response[0];
|
||||
const formData: FormGroup = response[1];
|
||||
switch ( actionType )
|
||||
{
|
||||
/**
|
||||
* Send
|
||||
*/
|
||||
case 'send':
|
||||
console.log('new Mail', formData.getRawValue());
|
||||
break;
|
||||
/**
|
||||
* Delete
|
||||
*/
|
||||
case 'delete':
|
||||
console.log('delete Mail');
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { Mail } from 'app/main/apps/mail/mail.model';
|
||||
import { MailService } from 'app/main/apps/mail/mail.service';
|
||||
|
||||
@Component({
|
||||
selector : 'mail-details',
|
||||
templateUrl: './mail-details.component.html',
|
||||
styleUrls : ['./mail-details.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class MailDetailsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
mail: Mail;
|
||||
labels: any[];
|
||||
showDetails: boolean;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MailService} _mailService
|
||||
*/
|
||||
constructor(
|
||||
private _mailService: MailService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.showDetails = false;
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to update the current mail
|
||||
this._mailService.onCurrentMailChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(currentMail => {
|
||||
this.mail = currentMail;
|
||||
});
|
||||
|
||||
// Subscribe to update on label change
|
||||
this._mailService.onLabelsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(labels => {
|
||||
this.labels = labels;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle star
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
toggleStar(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
|
||||
this.mail.toggleStar();
|
||||
|
||||
this._mailService.updateMail(this.mail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle important
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
toggleImportant(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
|
||||
this.mail.toggleImportant();
|
||||
|
||||
this._mailService.updateMail(this.mail);
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
import { Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { Mail } from 'app/main/apps/mail/mail.model';
|
||||
import { MailService } from 'app/main/apps/mail/mail.service';
|
||||
|
||||
@Component({
|
||||
selector : 'mail-list-item',
|
||||
templateUrl: './mail-list-item.component.html',
|
||||
styleUrls : ['./mail-list-item.component.scss']
|
||||
})
|
||||
export class MailListItemComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@Input() mail: Mail;
|
||||
labels: any[];
|
||||
|
||||
@HostBinding('class.selected')
|
||||
selected: boolean;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MailService} _mailService
|
||||
*/
|
||||
constructor(
|
||||
private _mailService: MailService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Set the initial values
|
||||
this.mail = new Mail(this.mail);
|
||||
|
||||
// Subscribe to update on selected mail change
|
||||
this._mailService.onSelectedMailsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selectedMails => {
|
||||
this.selected = false;
|
||||
|
||||
if ( selectedMails.length > 0 )
|
||||
{
|
||||
for ( const mail of selectedMails )
|
||||
{
|
||||
if ( mail.id === this.mail.id )
|
||||
{
|
||||
this.selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Subscribe to update on label change
|
||||
this._mailService.onLabelsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(labels => {
|
||||
this.labels = labels;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On selected change
|
||||
*/
|
||||
onSelectedChange(): void
|
||||
{
|
||||
this._mailService.toggleSelectedMail(this.mail.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle star
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
toggleStar(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
|
||||
this.mail.toggleStar();
|
||||
|
||||
this._mailService.updateMail(this.mail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle Important
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
toggleImportant(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
|
||||
this.mail.toggleImportant();
|
||||
|
||||
this._mailService.updateMail(this.mail);
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<div *ngIf="mails.length === 0" fxLayout="column" fxLayoutAlign="center center" fxFlexFill>
|
||||
<span class="no-messages-text hint-text">{{ 'MAIL.NO_MESSAGES' | translate }}</span>
|
||||
</div>
|
||||
|
||||
<div class="mail-list" [@animateStagger]="{value:'50'}">
|
||||
<mail-list-item matRipple *ngFor="let mail of mails" [mail]="mail" (click)="readMail(mail.id)"
|
||||
[ngClass]="{'current-mail mat-accent-50-bg':mail?.id == currentMail?.id}"
|
||||
[@animate]="{value:'*',params:{y:'100%'}}">
|
||||
</mail-list-item>
|
||||
</div>
|
|
@ -1,134 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { Mail } from 'app/main/apps/mail/mail.model';
|
||||
import { MailService } from 'app/main/apps/mail/mail.service';
|
||||
|
||||
@Component({
|
||||
selector : 'mail-list',
|
||||
templateUrl: './mail-list.component.html',
|
||||
styleUrls : ['./mail-list.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class MailListComponent implements OnInit, OnDestroy
|
||||
{
|
||||
mails: Mail[];
|
||||
currentMail: Mail;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ActivatedRoute} _activatedRoute
|
||||
* @param {MailService} _mailService
|
||||
* @param {Location} _location
|
||||
*/
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _mailService: MailService,
|
||||
private _location: Location
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to update mails on changes
|
||||
this._mailService.onMailsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(mails => {
|
||||
this.mails = mails;
|
||||
});
|
||||
|
||||
// Subscribe to update current mail on changes
|
||||
this._mailService.onCurrentMailChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(currentMail => {
|
||||
if ( !currentMail )
|
||||
{
|
||||
// Set the current mail id to null to deselect the current mail
|
||||
this.currentMail = null;
|
||||
|
||||
// Handle the location changes
|
||||
const labelHandle = this._activatedRoute.snapshot.params.labelHandle,
|
||||
filterHandle = this._activatedRoute.snapshot.params.filterHandle,
|
||||
folderHandle = this._activatedRoute.snapshot.params.folderHandle;
|
||||
|
||||
if ( labelHandle )
|
||||
{
|
||||
this._location.go('apps/mail/label/' + labelHandle);
|
||||
}
|
||||
else if ( filterHandle )
|
||||
{
|
||||
this._location.go('apps/mail/filter/' + filterHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._location.go('apps/mail/' + folderHandle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.currentMail = currentMail;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Read mail
|
||||
*
|
||||
* @param mailId
|
||||
*/
|
||||
readMail(mailId): void
|
||||
{
|
||||
const labelHandle = this._activatedRoute.snapshot.params.labelHandle,
|
||||
filterHandle = this._activatedRoute.snapshot.params.filterHandle,
|
||||
folderHandle = this._activatedRoute.snapshot.params.folderHandle;
|
||||
|
||||
if ( labelHandle )
|
||||
{
|
||||
this._location.go('apps/mail/label/' + labelHandle + '/' + mailId);
|
||||
}
|
||||
else if ( filterHandle )
|
||||
{
|
||||
this._location.go('apps/mail/filter/' + filterHandle + '/' + mailId);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._location.go('apps/mail/' + folderHandle + '/' + mailId);
|
||||
}
|
||||
|
||||
// Set current mail
|
||||
this._mailService.setCurrentMail(mailId);
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
<div id="mail" class="page-layout carded left-sidebar inner-scroll">
|
||||
|
||||
<!-- TOP BACKGROUND -->
|
||||
<div class="top-bg mat-accent-bg"></div>
|
||||
<!-- / TOP BACKGROUND -->
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<fuse-sidebar class="sidebar" name="mail-main-sidebar" position="left" lockedOpen="gt-md">
|
||||
<mail-main-sidebar></mail-main-sidebar>
|
||||
</fuse-sidebar>
|
||||
<!-- / SIDEBAR -->
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="center">
|
||||
|
||||
<!-- CONTENT HEADER -->
|
||||
<div class="header" fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<div class="search-wrapper" fxFlex fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<button mat-icon-button class="sidebar-toggle" fxHide.gt-md
|
||||
(click)="toggleSidebar('mail-main-sidebar')">
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="search mat-white-bg" flex fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon>search</mat-icon>
|
||||
<input [formControl]="searchInput" [placeholder]="'MAIL.SEARCH_PLACEHOLDER' | translate" fxFlex>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT HEADER -->
|
||||
|
||||
<!-- CONTENT CARD -->
|
||||
<div class="content-card mat-white-bg" [ngClass]="{'current-mail-selected':currentMail}">
|
||||
|
||||
<!-- CONTENT TOOLBAR -->
|
||||
<div class="toolbar px-24 py-8">
|
||||
|
||||
<div class="mail-selection" fxFlex="row" fxLayoutAlign="start center">
|
||||
<mat-checkbox (click)="toggleSelectAll()" [checked]="hasSelectedMails"
|
||||
[indeterminate]="isIndeterminate"></mat-checkbox>
|
||||
|
||||
<button mat-icon-button [matMenuTriggerFor]="selectMenu">
|
||||
<mat-icon>arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
<mat-menu #selectMenu="matMenu">
|
||||
<button mat-menu-item (click)="selectMails()">All</button>
|
||||
<button mat-menu-item (click)="deselectMails()">None</button>
|
||||
<button mat-menu-item (click)="selectMails('read', true)">Read</button>
|
||||
<button mat-menu-item (click)="selectMails('read', false)">Unread</button>
|
||||
<button mat-menu-item (click)="selectMails('starred', true)">Starred</button>
|
||||
<button mat-menu-item (click)="selectMails('starred', false)">Unstarred</button>
|
||||
<button mat-menu-item (click)="selectMails('important', true)">Important</button>
|
||||
<button mat-menu-item (click)="selectMails('important', false)">Unimportant</button>
|
||||
</mat-menu>
|
||||
|
||||
<div class="toolbar-separator" *ngIf="hasSelectedMails"></div>
|
||||
|
||||
<button mat-icon-button (click)="setFolderOnSelectedMails(4)" *ngIf="hasSelectedMails">
|
||||
<mat-icon class="secondary-text">delete</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button [matMenuTriggerFor]="folderMenu" *ngIf="hasSelectedMails">
|
||||
<mat-icon class="secondary-text">folder</mat-icon>
|
||||
</button>
|
||||
<mat-menu #folderMenu="matMenu">
|
||||
<button mat-menu-item *ngFor="let folder of folders"
|
||||
(click)="setFolderOnSelectedMails(folder.id)">{{folder.title}}
|
||||
</button>
|
||||
</mat-menu>
|
||||
|
||||
<button mat-icon-button [matMenuTriggerFor]="labelMenu" *ngIf="hasSelectedMails">
|
||||
<mat-icon class="secondary-text">label</mat-icon>
|
||||
</button>
|
||||
<mat-menu #labelMenu="matMenu">
|
||||
<button mat-menu-item *ngFor="let label of labels"
|
||||
(click)="toggleLabelOnSelectedMails(label.id)">{{label.title}}
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
||||
<div *ngIf="currentMail" fxHide.gt-xs>
|
||||
<button mat-icon-button (click)="deselectCurrentMail()">
|
||||
<mat-icon class="secondary-text">arrow_back</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / CONTENT TOOLBAR -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content" fxLayout="row">
|
||||
|
||||
<mail-list fusePerfectScrollbar fxFlex></mail-list>
|
||||
<mail-details fusePerfectScrollbar fxFlex></mail-details>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT CARD -->
|
||||
|
||||
</div>
|
||||
<!-- / CENTER -->
|
||||
|
||||
</div>
|
|
@ -1,193 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
import { FuseTranslationLoaderService } from '@fuse/services/translation-loader.service';
|
||||
|
||||
import { Mail } from 'app/main/apps/mail/mail.model';
|
||||
import { MailService } from 'app/main/apps/mail/mail.service';
|
||||
|
||||
import { locale as english } from 'app/main/apps/mail//i18n/en';
|
||||
import { locale as turkish } from 'app/main/apps/mail//i18n/tr';
|
||||
|
||||
@Component({
|
||||
selector : 'mail',
|
||||
templateUrl: './mail.component.html',
|
||||
styleUrls : ['./mail.component.scss']
|
||||
})
|
||||
export class MailComponent implements OnInit, OnDestroy
|
||||
{
|
||||
hasSelectedMails: boolean;
|
||||
isIndeterminate: boolean;
|
||||
folders: any[];
|
||||
filters: any[];
|
||||
labels: any[];
|
||||
searchInput: FormControl;
|
||||
currentMail: Mail;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MailService} _mailService
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
* @param {FuseTranslationLoaderService} _fuseTranslationLoaderService
|
||||
*/
|
||||
constructor(
|
||||
private _mailService: MailService,
|
||||
private _fuseSidebarService: FuseSidebarService,
|
||||
private _fuseTranslationLoaderService: FuseTranslationLoaderService
|
||||
)
|
||||
{
|
||||
// Load the translations
|
||||
this._fuseTranslationLoaderService.loadTranslations(english, turkish);
|
||||
|
||||
// Set the defaults
|
||||
this.searchInput = new FormControl('');
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._mailService.onSelectedMailsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selectedMails => {
|
||||
setTimeout(() => {
|
||||
this.hasSelectedMails = selectedMails.length > 0;
|
||||
this.isIndeterminate = (selectedMails.length !== this._mailService.mails.length && selectedMails.length > 0);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
this._mailService.onFoldersChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(folders => {
|
||||
this.folders = this._mailService.folders;
|
||||
});
|
||||
|
||||
this._mailService.onFiltersChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(folders => {
|
||||
this.filters = this._mailService.filters;
|
||||
});
|
||||
|
||||
this._mailService.onLabelsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(labels => {
|
||||
this.labels = this._mailService.labels;
|
||||
});
|
||||
|
||||
this._mailService.onCurrentMailChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(currentMail => {
|
||||
if ( !currentMail )
|
||||
{
|
||||
this.currentMail = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.currentMail = currentMail;
|
||||
}
|
||||
});
|
||||
|
||||
this.searchInput.valueChanges.pipe(
|
||||
takeUntil(this._unsubscribeAll),
|
||||
debounceTime(300),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
.subscribe(searchText => {
|
||||
this._mailService.onSearchTextChanged.next(searchText);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle select all
|
||||
*/
|
||||
toggleSelectAll(): void
|
||||
{
|
||||
this._mailService.toggleSelectAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select mails
|
||||
*
|
||||
* @param filterParameter
|
||||
* @param filterValue
|
||||
*/
|
||||
selectMails(filterParameter?, filterValue?): void
|
||||
{
|
||||
this._mailService.selectMails(filterParameter, filterValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselect mails
|
||||
*/
|
||||
deselectMails(): void
|
||||
{
|
||||
this._mailService.deselectMails();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselect current mail
|
||||
*/
|
||||
deselectCurrentMail(): void
|
||||
{
|
||||
this._mailService.onCurrentMailChanged.next(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle label on selected mails
|
||||
*
|
||||
* @param labelId
|
||||
*/
|
||||
toggleLabelOnSelectedMails(labelId): void
|
||||
{
|
||||
this._mailService.toggleLabelOnSelectedMails(labelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set folder on selected mails
|
||||
*
|
||||
* @param folderId
|
||||
*/
|
||||
setFolderOnSelectedMails(folderId): void
|
||||
{
|
||||
this._mailService.setFolderOnSelectedMails(folderId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the sidebar
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
toggleSidebar(name): void
|
||||
{
|
||||
this._fuseSidebarService.getSidebar(name).toggleOpen();
|
||||
}
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { MailService } from 'app/main/apps/mail/mail.service';
|
||||
import { MailComposeDialogComponent } from 'app/main/apps/mail/dialogs/compose/compose.component';
|
||||
|
||||
@Component({
|
||||
selector : 'mail-main-sidebar',
|
||||
templateUrl: './main-sidebar.component.html',
|
||||
styleUrls : ['./main-sidebar.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class MailMainSidebarComponent implements OnInit, OnDestroy
|
||||
{
|
||||
folders: any[];
|
||||
filters: any[];
|
||||
labels: any[];
|
||||
accounts: object;
|
||||
selectedAccount: string;
|
||||
dialogRef: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {MailService} _mailService
|
||||
* @param {MatDialog} _matDialog
|
||||
*/
|
||||
constructor(
|
||||
private _mailService: MailService,
|
||||
public _matDialog: MatDialog
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.accounts = {
|
||||
'creapond' : 'johndoe@creapond.com',
|
||||
'withinpixels': 'johndoe@withinpixels.com'
|
||||
};
|
||||
this.selectedAccount = 'creapond';
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._mailService.onFoldersChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(folders => {
|
||||
this.folders = folders;
|
||||
});
|
||||
|
||||
this._mailService.onFiltersChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(filters => {
|
||||
this.filters = filters;
|
||||
});
|
||||
|
||||
this._mailService.onLabelsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(labels => {
|
||||
this.labels = labels;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Compose dialog
|
||||
*/
|
||||
composeDialog(): void
|
||||
{
|
||||
this.dialogRef = this._matDialog.open(MailComposeDialogComponent, {
|
||||
panelClass: 'mail-compose-dialog'
|
||||
});
|
||||
this.dialogRef.afterClosed()
|
||||
.subscribe(response => {
|
||||
if ( !response )
|
||||
{
|
||||
return;
|
||||
}
|
||||
const actionType: string = response[0];
|
||||
const formData: FormGroup = response[1];
|
||||
switch ( actionType )
|
||||
{
|
||||
/**
|
||||
* Send
|
||||
*/
|
||||
case 'send':
|
||||
console.log('new Mail', formData.getRawValue());
|
||||
break;
|
||||
/**
|
||||
* Delete
|
||||
*/
|
||||
case 'delete':
|
||||
console.log('delete Mail');
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
import { Component, EventEmitter, Output, ViewChild } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector : 'scrumboard-board-add-list',
|
||||
templateUrl: './add-list.component.html',
|
||||
styleUrls : ['./add-list.component.scss']
|
||||
})
|
||||
export class ScrumboardBoardAddListComponent
|
||||
{
|
||||
formActive: boolean;
|
||||
form: FormGroup;
|
||||
|
||||
@Output()
|
||||
onListAdd: EventEmitter<any>;
|
||||
|
||||
@ViewChild('nameInput')
|
||||
nameInputField;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FormBuilder} _formBuilder
|
||||
*/
|
||||
constructor(
|
||||
private _formBuilder: FormBuilder
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.formActive = false;
|
||||
this.onListAdd = new EventEmitter();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Open form
|
||||
*/
|
||||
openForm(): void
|
||||
{
|
||||
this.form = this._formBuilder.group({
|
||||
name: ['']
|
||||
});
|
||||
this.formActive = true;
|
||||
this.focusNameField();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close form
|
||||
*/
|
||||
closeForm(): void
|
||||
{
|
||||
this.formActive = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus to the name field
|
||||
*/
|
||||
focusNameField(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.nameInputField.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On form submit
|
||||
*/
|
||||
onFormSubmit(): void
|
||||
{
|
||||
if ( this.form.valid )
|
||||
{
|
||||
this.onListAdd.next(this.form.getRawValue().name);
|
||||
this.formActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||
import { List } from 'app/main/apps/scrumboard/list.model';
|
||||
|
||||
@Component({
|
||||
selector : 'scrumboard-board',
|
||||
templateUrl: './board.component.html',
|
||||
styleUrls : ['./board.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ScrumboardBoardComponent implements OnInit, OnDestroy
|
||||
{
|
||||
board: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _location: Location,
|
||||
private _scrumboardService: ScrumboardService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._scrumboardService.onBoardChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(board => {
|
||||
this.board = board;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On list add
|
||||
*
|
||||
* @param newListName
|
||||
*/
|
||||
onListAdd(newListName): void
|
||||
{
|
||||
if ( newListName === '' )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._scrumboardService.addList(new List({name: newListName}));
|
||||
}
|
||||
|
||||
/**
|
||||
* On board name changed
|
||||
*
|
||||
* @param newName
|
||||
*/
|
||||
onBoardNameChanged(newName): void
|
||||
{
|
||||
this._scrumboardService.updateBoard();
|
||||
this._location.go('/apps/scrumboard/boards/' + this.board.id + '/' + this.board.uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* On drop
|
||||
*
|
||||
* @param ev
|
||||
*/
|
||||
onDrop(ev): void
|
||||
{
|
||||
this._scrumboardService.updateBoard();
|
||||
}
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseUtils } from '@fuse/utils';
|
||||
|
||||
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||
|
||||
@Component({
|
||||
selector : 'scrumboard-label-selector',
|
||||
templateUrl : './label-selector.component.html',
|
||||
styleUrls : ['./label-selector.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
|
||||
export class ScrumboardLabelSelectorComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@Input('card')
|
||||
card: any;
|
||||
|
||||
@Output()
|
||||
onCardLabelsChange: EventEmitter<any>;
|
||||
|
||||
board: any;
|
||||
labelsMenuView: string;
|
||||
selectedLabel: any;
|
||||
newLabel: any;
|
||||
toggleInArray: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ScrumboardService} _scrumboardService
|
||||
*/
|
||||
constructor(
|
||||
private _scrumboardService: ScrumboardService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.onCardLabelsChange = new EventEmitter();
|
||||
this.labelsMenuView = 'labels';
|
||||
this.newLabel = {
|
||||
'id' : '',
|
||||
'name' : '',
|
||||
'color': 'mat-blue-400-bg'
|
||||
};
|
||||
this.toggleInArray = FuseUtils.toggleInArray;
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._scrumboardService.onBoardChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(board => {
|
||||
this.board = board;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Card labels changed
|
||||
*/
|
||||
cardLabelsChanged(): void
|
||||
{
|
||||
this.onCardLabelsChange.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* On label change
|
||||
*/
|
||||
onLabelChange(): void
|
||||
{
|
||||
this._scrumboardService.updateBoard();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new label
|
||||
*/
|
||||
addNewLabel(): void
|
||||
{
|
||||
this.newLabel.id = FuseUtils.generateGUID();
|
||||
this.board.labels.push(Object.assign({}, this.newLabel));
|
||||
this.newLabel.name = '';
|
||||
this.labelsMenuView = 'labels';
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
import { Component, EventEmitter, Output, ViewChild } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector : 'scrumboard-board-add-card',
|
||||
templateUrl: './add-card.component.html',
|
||||
styleUrls : ['./add-card.component.scss']
|
||||
})
|
||||
export class ScrumboardBoardAddCardComponent
|
||||
{
|
||||
formActive: boolean;
|
||||
form: FormGroup;
|
||||
|
||||
@Output()
|
||||
onCardAdd: EventEmitter<any>;
|
||||
|
||||
@ViewChild('nameInput')
|
||||
nameInputField;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FormBuilder} _formBuilder
|
||||
*/
|
||||
constructor(
|
||||
private _formBuilder: FormBuilder
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.formActive = false;
|
||||
this.onCardAdd = new EventEmitter();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Open the form
|
||||
*/
|
||||
openForm(): void
|
||||
{
|
||||
this.form = this._formBuilder.group({
|
||||
name: ''
|
||||
});
|
||||
this.formActive = true;
|
||||
this.focusNameField();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the form
|
||||
*/
|
||||
closeForm(): void
|
||||
{
|
||||
this.formActive = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus to the name field
|
||||
*/
|
||||
focusNameField(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.nameInputField.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On form submit
|
||||
*/
|
||||
onFormSubmit(): void
|
||||
{
|
||||
if ( this.form.valid )
|
||||
{
|
||||
const cardName = this.form.getRawValue().name;
|
||||
this.onCardAdd.next(cardName);
|
||||
this.formActive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import * as moment from 'moment';
|
||||
|
||||
@Component({
|
||||
selector : 'scrumboard-board-card',
|
||||
templateUrl : './card.component.html',
|
||||
styleUrls : ['./card.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class ScrumboardBoardCardComponent implements OnInit
|
||||
{
|
||||
@Input()
|
||||
cardId;
|
||||
|
||||
card: any;
|
||||
board: any;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ActivatedRoute} _activatedRoute
|
||||
*/
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.board = this._activatedRoute.snapshot.data.board;
|
||||
this.card = this.board.cards.filter((card) => {
|
||||
return this.cardId === card.id;
|
||||
})[0];
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Is the card overdue?
|
||||
*
|
||||
* @param cardDate
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isOverdue(cardDate): boolean
|
||||
{
|
||||
return moment() > moment(new Date(cardDate));
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector : 'scrumboard-board-edit-list-name',
|
||||
templateUrl: './edit-list-name.component.html',
|
||||
styleUrls : ['./edit-list-name.component.scss']
|
||||
})
|
||||
export class ScrumboardBoardEditListNameComponent
|
||||
{
|
||||
formActive: boolean;
|
||||
form: FormGroup;
|
||||
|
||||
@Input()
|
||||
list;
|
||||
|
||||
@Output()
|
||||
onNameChanged: EventEmitter<any>;
|
||||
|
||||
@ViewChild('nameInput')
|
||||
nameInputField;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FormBuilder} _formBuilder
|
||||
*/
|
||||
constructor(
|
||||
private _formBuilder: FormBuilder
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.formActive = false;
|
||||
this.onNameChanged = new EventEmitter();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Open the form
|
||||
*/
|
||||
openForm(): void
|
||||
{
|
||||
this.form = this._formBuilder.group({
|
||||
name: [this.list.name]
|
||||
});
|
||||
this.formActive = true;
|
||||
this.focusNameField();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the form
|
||||
*/
|
||||
closeForm(): void
|
||||
{
|
||||
this.formActive = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Focus to the name field
|
||||
*/
|
||||
focusNameField(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.nameInputField.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On form submit
|
||||
*/
|
||||
onFormSubmit(): void
|
||||
{
|
||||
if ( this.form.valid )
|
||||
{
|
||||
this.list.name = this.form.getRawValue().name;
|
||||
this.onNameChanged.next(this.list.name);
|
||||
this.formActive = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
import { Component, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
|
||||
import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
||||
|
||||
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||
import { Card } from 'app/main/apps/scrumboard/card.model';
|
||||
import { ScrumboardCardDialogComponent } from 'app/main/apps/scrumboard/board/dialogs/card/card.component';
|
||||
|
||||
@Component({
|
||||
selector : 'scrumboard-board-list',
|
||||
templateUrl : './list.component.html',
|
||||
styleUrls : ['./list.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class ScrumboardBoardListComponent implements OnInit, OnDestroy
|
||||
{
|
||||
board: any;
|
||||
dialogRef: any;
|
||||
|
||||
@Input()
|
||||
list;
|
||||
|
||||
@ViewChild(FusePerfectScrollbarDirective)
|
||||
listScroll: FusePerfectScrollbarDirective;
|
||||
|
||||
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ActivatedRoute} _activatedRoute
|
||||
* @param {ScrumboardService} _scrumboardService
|
||||
* @param {MatDialog} _matDialog
|
||||
*/
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _scrumboardService: ScrumboardService,
|
||||
private _matDialog: MatDialog
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._scrumboardService.onBoardChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(board => {
|
||||
this.board = board;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On list name changed
|
||||
*
|
||||
* @param newListName
|
||||
*/
|
||||
onListNameChanged(newListName): void
|
||||
{
|
||||
this.list.name = newListName;
|
||||
}
|
||||
|
||||
/**
|
||||
* On card added
|
||||
*
|
||||
* @param newCardName
|
||||
*/
|
||||
onCardAdd(newCardName): void
|
||||
{
|
||||
if ( newCardName === '' )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this._scrumboardService.addCard(this.list.id, new Card({name: newCardName}));
|
||||
|
||||
setTimeout(() => {
|
||||
this.listScroll.scrollToBottom(0, 400);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove list
|
||||
*
|
||||
* @param listId
|
||||
*/
|
||||
removeList(listId): void
|
||||
{
|
||||
this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, {
|
||||
disableClose: false
|
||||
});
|
||||
|
||||
this.confirmDialogRef.componentInstance.confirmMessage = 'Are you sure you want to delete the list and it\'s all cards?';
|
||||
|
||||
this.confirmDialogRef.afterClosed().subscribe(result => {
|
||||
if ( result )
|
||||
{
|
||||
this._scrumboardService.removeList(listId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Open card dialog
|
||||
*
|
||||
* @param cardId
|
||||
*/
|
||||
openCardDialog(cardId): void
|
||||
{
|
||||
this.dialogRef = this._matDialog.open(ScrumboardCardDialogComponent, {
|
||||
panelClass: 'scrumboard-card-dialog',
|
||||
data : {
|
||||
cardId: cardId,
|
||||
listId: this.list.id
|
||||
}
|
||||
});
|
||||
this.dialogRef.afterClosed()
|
||||
.subscribe(response => {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On drop
|
||||
*
|
||||
* @param ev
|
||||
*/
|
||||
onDrop(ev): void
|
||||
{
|
||||
this._scrumboardService.updateBoard();
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { MatColors } from '@fuse/mat-colors';
|
||||
|
||||
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||
|
||||
@Component({
|
||||
selector : 'scrumboard-board-color-selector',
|
||||
templateUrl: './board-color-selector.component.html',
|
||||
styleUrls : ['./board-color-selector.component.scss']
|
||||
})
|
||||
export class ScrumboardBoardColorSelectorComponent implements OnInit, OnDestroy
|
||||
{
|
||||
colors: any;
|
||||
board: any;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ScrumboardService} _scrumboardService
|
||||
*/
|
||||
constructor(
|
||||
private _scrumboardService: ScrumboardService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.colors = MatColors.all;
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._scrumboardService.onBoardChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(board => {
|
||||
this.board = board;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the color
|
||||
*
|
||||
* @param color
|
||||
*/
|
||||
setColor(color): void
|
||||
{
|
||||
this.board.settings.color = color;
|
||||
this._scrumboardService.updateBoard();
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector : 'scrumboard-board-settings',
|
||||
templateUrl: './settings.component.html',
|
||||
styleUrls : ['./settings.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ScrumboardBoardSettingsSidenavComponent implements OnInit, OnDestroy
|
||||
{
|
||||
board: any;
|
||||
view: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
constructor(
|
||||
private scrumboardService: ScrumboardService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.view = 'main';
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.scrumboardService.onBoardChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(board => {
|
||||
this.board = board;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle card cover
|
||||
*/
|
||||
toggleCardCover(): void
|
||||
{
|
||||
this.board.settings.cardCoverImages = !this.board.settings.cardCoverImages;
|
||||
this.scrumboardService.updateBoard();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle subscription
|
||||
*/
|
||||
toggleSubscription(): void
|
||||
{
|
||||
this.board.settings.subscribed = !this.board.settings.subscribed;
|
||||
this.scrumboardService.updateBoard();
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||
import { Board } from 'app/main/apps/scrumboard/board.model';
|
||||
|
||||
@Component({
|
||||
selector : 'scrumboard',
|
||||
templateUrl: './scrumboard.component.html',
|
||||
styleUrls : ['./scrumboard.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class ScrumboardComponent implements OnInit, OnDestroy
|
||||
{
|
||||
boards: any[];
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {Router} _router
|
||||
* @param {ScrumboardService} _scrumboardService
|
||||
*/
|
||||
constructor(
|
||||
private _router: Router,
|
||||
private _scrumboardService: ScrumboardService
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._scrumboardService.onBoardsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(boards => {
|
||||
this.boards = boards;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* New board
|
||||
*/
|
||||
newBoard(): void
|
||||
{
|
||||
const newBoard = new Board({});
|
||||
this._scrumboardService.createNewBoard(newBoard).then(() => {
|
||||
this._router.navigate(['/apps/scrumboard/boards/' + newBoard.id + '/' + newBoard.uri]);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { MatButtonModule, MatCheckboxModule, MatChipsModule, MatDatepickerModule, MatDialogModule, MatFormFieldModule, MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatProgressBarModule, MatRippleModule, MatSidenavModule, MatToolbarModule, MatTooltipModule } from '@angular/material';
|
||||
import { NgxDnDModule } from '@swimlane/ngx-dnd';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
import { FuseConfirmDialogModule, FuseMaterialColorPickerModule } from '@fuse/components';
|
||||
|
||||
import { BoardResolve, ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||
import { ScrumboardComponent } from 'app/main/apps/scrumboard/scrumboard.component';
|
||||
import { ScrumboardBoardComponent } from 'app/main/apps/scrumboard/board/board.component';
|
||||
import { ScrumboardBoardListComponent } from 'app/main/apps/scrumboard/board/list/list.component';
|
||||
import { ScrumboardBoardCardComponent } from 'app/main/apps/scrumboard/board/list/card/card.component';
|
||||
import { ScrumboardBoardEditListNameComponent } from 'app/main/apps/scrumboard/board/list/edit-list-name/edit-list-name.component';
|
||||
import { ScrumboardBoardAddCardComponent } from 'app/main/apps/scrumboard/board/list/add-card/add-card.component';
|
||||
import { ScrumboardBoardAddListComponent } from 'app/main/apps/scrumboard/board/add-list/add-list.component';
|
||||
import { ScrumboardCardDialogComponent } from 'app/main/apps/scrumboard/board/dialogs/card/card.component';
|
||||
import { ScrumboardLabelSelectorComponent } from 'app/main/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component';
|
||||
import { ScrumboardEditBoardNameComponent } from 'app/main/apps/scrumboard/board/edit-board-name/edit-board-name.component';
|
||||
import { ScrumboardBoardSettingsSidenavComponent } from 'app/main/apps/scrumboard/board/sidenavs/settings/settings.component';
|
||||
import { ScrumboardBoardColorSelectorComponent } from 'app/main/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path : 'boards',
|
||||
component: ScrumboardComponent,
|
||||
resolve : {
|
||||
scrumboard: ScrumboardService
|
||||
}
|
||||
},
|
||||
{
|
||||
path : 'boards/:boardId/:boardUri',
|
||||
component: ScrumboardBoardComponent,
|
||||
resolve : {
|
||||
board: BoardResolve
|
||||
}
|
||||
},
|
||||
{
|
||||
path : '**',
|
||||
redirectTo: 'boards'
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations : [
|
||||
ScrumboardComponent,
|
||||
ScrumboardBoardComponent,
|
||||
ScrumboardBoardListComponent,
|
||||
ScrumboardBoardCardComponent,
|
||||
ScrumboardBoardEditListNameComponent,
|
||||
ScrumboardBoardAddCardComponent,
|
||||
ScrumboardBoardAddListComponent,
|
||||
ScrumboardCardDialogComponent,
|
||||
ScrumboardLabelSelectorComponent,
|
||||
ScrumboardEditBoardNameComponent,
|
||||
ScrumboardBoardSettingsSidenavComponent,
|
||||
ScrumboardBoardColorSelectorComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
MatButtonModule,
|
||||
MatCheckboxModule,
|
||||
MatChipsModule,
|
||||
MatDatepickerModule,
|
||||
MatDialogModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatListModule,
|
||||
MatMenuModule,
|
||||
MatProgressBarModule,
|
||||
MatRippleModule,
|
||||
MatSidenavModule,
|
||||
MatToolbarModule,
|
||||
MatTooltipModule,
|
||||
|
||||
NgxDnDModule,
|
||||
|
||||
FuseSharedModule,
|
||||
FuseConfirmDialogModule,
|
||||
FuseMaterialColorPickerModule
|
||||
],
|
||||
providers : [
|
||||
ScrumboardService,
|
||||
BoardResolve
|
||||
],
|
||||
entryComponents: [ScrumboardCardDialogComponent]
|
||||
})
|
||||
export class ScrumboardModule
|
||||
{
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { TodoService } from 'app/main/apps/todo/todo.service';
|
||||
|
||||
@Component({
|
||||
selector : 'todo-main-sidebar',
|
||||
templateUrl: './main-sidebar.component.html',
|
||||
styleUrls : ['./main-sidebar.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class TodoMainSidebarComponent implements OnInit, OnDestroy
|
||||
{
|
||||
folders: any[];
|
||||
filters: any[];
|
||||
tags: any[];
|
||||
accounts: object;
|
||||
selectedAccount: string;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {TodoService} _todoService
|
||||
* @param {Router} _router
|
||||
*/
|
||||
constructor(
|
||||
private _todoService: TodoService,
|
||||
private _router: Router
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.accounts = {
|
||||
'creapond' : 'johndoe@creapond.com',
|
||||
'withinpixels': 'johndoe@withinpixels.com'
|
||||
};
|
||||
this.selectedAccount = 'creapond';
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._todoService.onFiltersChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(filters => {
|
||||
this.filters = filters;
|
||||
});
|
||||
|
||||
this._todoService.onTagsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(tags => {
|
||||
this.tags = tags;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* New todo
|
||||
*/
|
||||
newTodo(): void
|
||||
{
|
||||
this._router.navigate(['/apps/todo/all']).then(() => {
|
||||
setTimeout(() => {
|
||||
this._todoService.onNewTodoClicked.next('');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,219 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseUtils } from '@fuse/utils';
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { Todo } from 'app/main/apps/todo/todo.model';
|
||||
import { TodoService } from 'app/main/apps/todo/todo.service';
|
||||
|
||||
@Component({
|
||||
selector : 'todo-details',
|
||||
templateUrl: './todo-details.component.html',
|
||||
styleUrls : ['./todo-details.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class TodoDetailsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
todo: Todo;
|
||||
tags: any[];
|
||||
formType: string;
|
||||
todoForm: FormGroup;
|
||||
|
||||
@ViewChild('titleInput')
|
||||
titleInputField;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {TodoService} _todoService
|
||||
* @param {FormBuilder} _formBuilder
|
||||
*/
|
||||
constructor(
|
||||
private _todoService: TodoService,
|
||||
private _formBuilder: FormBuilder
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to update the current todo
|
||||
this._todoService.onCurrentTodoChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(([todo, formType]) => {
|
||||
|
||||
if ( todo && formType === 'edit' )
|
||||
{
|
||||
this.formType = 'edit';
|
||||
this.todo = todo;
|
||||
this.todoForm = this.createTodoForm();
|
||||
|
||||
this.todoForm.valueChanges
|
||||
.pipe(
|
||||
takeUntil(this._unsubscribeAll),
|
||||
debounceTime(500),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
.subscribe(data => {
|
||||
this._todoService.updateTodo(data);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Subscribe to update on tag change
|
||||
this._todoService.onTagsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(labels => {
|
||||
this.tags = labels;
|
||||
});
|
||||
|
||||
// Subscribe to update on tag change
|
||||
this._todoService.onNewTodoClicked
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(() => {
|
||||
this.todo = new Todo({});
|
||||
this.todo.id = FuseUtils.generateGUID();
|
||||
this.formType = 'new';
|
||||
this.todoForm = this.createTodoForm();
|
||||
this.focusTitleField();
|
||||
this._todoService.onCurrentTodoChanged.next([this.todo, 'new']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Focus title field
|
||||
*/
|
||||
focusTitleField(): void
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.titleInputField.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create todo form
|
||||
*
|
||||
* @returns {FormGroup}
|
||||
*/
|
||||
createTodoForm(): FormGroup
|
||||
{
|
||||
return this._formBuilder.group({
|
||||
'id' : [this.todo.id],
|
||||
'title' : [this.todo.title],
|
||||
'notes' : [this.todo.notes],
|
||||
'startDate': [this.todo.startDate],
|
||||
'dueDate' : [this.todo.dueDate],
|
||||
'completed': [this.todo.completed],
|
||||
'starred' : [this.todo.starred],
|
||||
'important': [this.todo.important],
|
||||
'deleted' : [this.todo.deleted],
|
||||
'tags' : [this.todo.tags]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle star
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
toggleStar(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
this.todo.toggleStar();
|
||||
this._todoService.updateTodo(this.todo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle important
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
toggleImportant(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
this.todo.toggleImportant();
|
||||
this._todoService.updateTodo(this.todo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle Completed
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
toggleCompleted(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
this.todo.toggleCompleted();
|
||||
this._todoService.updateTodo(this.todo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle Deleted
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
toggleDeleted(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
this.todo.toggleDeleted();
|
||||
this._todoService.updateTodo(this.todo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle tag on todo
|
||||
*
|
||||
* @param tagId
|
||||
*/
|
||||
toggleTagOnTodo(tagId): void
|
||||
{
|
||||
this._todoService.toggleTagOnTodo(tagId, this.todo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has tag?
|
||||
*
|
||||
* @param tagId
|
||||
* @returns {any}
|
||||
*/
|
||||
hasTag(tagId): any
|
||||
{
|
||||
return this._todoService.hasTag(tagId, this.todo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add todo
|
||||
*/
|
||||
addTodo(): void
|
||||
{
|
||||
this._todoService.updateTodo(this.todoForm.getRawValue());
|
||||
}
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
import { Component, HostBinding, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
import { Todo } from 'app/main/apps/todo/todo.model';
|
||||
import { TodoService } from 'app/main/apps/todo/todo.service';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector : 'todo-list-item',
|
||||
templateUrl : './todo-list-item.component.html',
|
||||
styleUrls : ['./todo-list-item.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class TodoListItemComponent implements OnInit, OnDestroy
|
||||
{
|
||||
tags: any[];
|
||||
|
||||
@Input()
|
||||
todo: Todo;
|
||||
|
||||
@HostBinding('class.selected')
|
||||
selected: boolean;
|
||||
|
||||
@HostBinding('class.completed')
|
||||
completed: boolean;
|
||||
|
||||
@HostBinding('class.move-disabled')
|
||||
moveDisabled: boolean;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {TodoService} _todoService
|
||||
* @param {ActivatedRoute} _activatedRoute
|
||||
*/
|
||||
constructor(
|
||||
private _todoService: TodoService,
|
||||
private _activatedRoute: ActivatedRoute
|
||||
)
|
||||
{
|
||||
// Disable move if path is not /all
|
||||
if ( _activatedRoute.snapshot.url[0].path !== 'all' )
|
||||
{
|
||||
this.moveDisabled = true;
|
||||
}
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Set the initial values
|
||||
this.todo = new Todo(this.todo);
|
||||
this.completed = this.todo.completed;
|
||||
|
||||
// Subscribe to update on selected todo change
|
||||
this._todoService.onSelectedTodosChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selectedTodos => {
|
||||
this.selected = false;
|
||||
|
||||
if ( selectedTodos.length > 0 )
|
||||
{
|
||||
for ( const todo of selectedTodos )
|
||||
{
|
||||
if ( todo.id === this.todo.id )
|
||||
{
|
||||
this.selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Subscribe to update on tag change
|
||||
this._todoService.onTagsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(tags => {
|
||||
this.tags = tags;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On selected change
|
||||
*/
|
||||
onSelectedChange(): void
|
||||
{
|
||||
this._todoService.toggleSelectedTodo(this.todo.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle star
|
||||
*/
|
||||
toggleStar(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
|
||||
this.todo.toggleStar();
|
||||
this._todoService.updateTodo(this.todo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle Important
|
||||
*/
|
||||
toggleImportant(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
|
||||
this.todo.toggleImportant();
|
||||
this._todoService.updateTodo(this.todo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle Completed
|
||||
*/
|
||||
toggleCompleted(event): void
|
||||
{
|
||||
event.stopPropagation();
|
||||
|
||||
this.todo.toggleCompleted();
|
||||
this._todoService.updateTodo(this.todo);
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
<div *ngIf="todos.length === 0" fxLayout="column" fxLayoutAlign="center center" fxFlexFill>
|
||||
<span class="no-todos-text hint-text">There are no todos!</span>
|
||||
</div>
|
||||
<div class="todo-list" ngxDroppable [model]="todos" (out)="onDrop($event)" [@animateStagger]="{value:'50'}">
|
||||
<todo-list-item class="todo-list-item has-handle"
|
||||
*ngFor="let todo of todos" [todo]="todo"
|
||||
ngxDraggable
|
||||
[model]="todo"
|
||||
(click)="readTodo(todo.id)"
|
||||
[ngClass]="{'current-todo mat-accent-50-bg':todo?.id == currentTodo?.id}"
|
||||
matRipple
|
||||
[@animate]="{value:'*',params:{y:'100%'}}">
|
||||
</todo-list-item>
|
||||
</div>
|
|
@ -1,126 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
import { Todo } from 'app/main/apps/todo/todo.model';
|
||||
import { TodoService } from 'app/main/apps/todo/todo.service';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector : 'todo-list',
|
||||
templateUrl: './todo-list.component.html',
|
||||
styleUrls : ['./todo-list.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class TodoListComponent implements OnInit, OnDestroy
|
||||
{
|
||||
todos: Todo[];
|
||||
currentTodo: Todo;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ActivatedRoute} _activatedRoute
|
||||
* @param {TodoService} _todoService
|
||||
* @param {Location} _location
|
||||
*/
|
||||
constructor(
|
||||
private _activatedRoute: ActivatedRoute,
|
||||
private _todoService: TodoService,
|
||||
private _location: Location
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to update todos on changes
|
||||
this._todoService.onTodosChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(todos => {
|
||||
this.todos = todos;
|
||||
});
|
||||
|
||||
// Subscribe to update current todo on changes
|
||||
this._todoService.onCurrentTodoChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(currentTodo => {
|
||||
if ( !currentTodo )
|
||||
{
|
||||
// Set the current todo id to null to deselect the current todo
|
||||
this.currentTodo = null;
|
||||
|
||||
// Handle the location changes
|
||||
const tagHandle = this._activatedRoute.snapshot.params.tagHandle,
|
||||
filterHandle = this._activatedRoute.snapshot.params.filterHandle;
|
||||
|
||||
if ( tagHandle )
|
||||
{
|
||||
this._location.go('apps/todo/tag/' + tagHandle);
|
||||
}
|
||||
else if ( filterHandle )
|
||||
{
|
||||
this._location.go('apps/todo/filter/' + filterHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._location.go('apps/todo/all');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.currentTodo = currentTodo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Read todo
|
||||
*
|
||||
* @param todoId
|
||||
*/
|
||||
readTodo(todoId): void
|
||||
{
|
||||
// Set current todo
|
||||
this._todoService.setCurrentTodo(todoId);
|
||||
}
|
||||
|
||||
/**
|
||||
* On drop
|
||||
*
|
||||
* @param ev
|
||||
*/
|
||||
onDrop(ev): void
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
<div id="todo" class="page-layout carded left-sidebar inner-scroll">
|
||||
|
||||
<!-- TOP BACKGROUND -->
|
||||
<div class="top-bg mat-accent-bg"></div>
|
||||
<!-- / TOP BACKGROUND -->
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<fuse-sidebar class="sidebar" name="todo-main-sidebar" position="left" lockedOpen="gt-md">
|
||||
<todo-main-sidebar></todo-main-sidebar>
|
||||
</fuse-sidebar>
|
||||
<!-- / SIDEBAR -->
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="center">
|
||||
|
||||
<!-- CONTENT HEADER -->
|
||||
<div class="header" fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<div class="search-wrapper mat-white-bg" fxFlex fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<button mat-icon-button class="sidebar-toggle" fxHide.gt-md
|
||||
(click)="toggleSidebar('todo-main-sidebar')">
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="search" flex fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon>search</mat-icon>
|
||||
<input [formControl]="searchInput" placeholder="Search for a task" fxFlex>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT HEADER -->
|
||||
|
||||
<!-- CONTENT CARD -->
|
||||
<div class="content-card mat-white-bg" [ngClass]="{'current-todo-selected':currentTodo}">
|
||||
|
||||
<!-- CONTENT TOOLBAR -->
|
||||
<div class="toolbar px-24 py-8">
|
||||
|
||||
<div class="todo-selection" fxFlex="row" fxLayoutAlign="start center">
|
||||
<mat-checkbox (click)="toggleSelectAll()" [checked]="hasSelectedTodos"
|
||||
[indeterminate]="isIndeterminate"></mat-checkbox>
|
||||
|
||||
<button mat-icon-button [matMenuTriggerFor]="selectMenu">
|
||||
<mat-icon>arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
<mat-menu #selectMenu="matMenu">
|
||||
<button mat-menu-item (click)="selectTodos()">All</button>
|
||||
<button mat-menu-item (click)="deselectTodos()">None</button>
|
||||
<button mat-menu-item (click)="selectTodos('read', true)">Read</button>
|
||||
<button mat-menu-item (click)="selectTodos('read', false)">Unread</button>
|
||||
<button mat-menu-item (click)="selectTodos('starred', true)">Starred</button>
|
||||
<button mat-menu-item (click)="selectTodos('starred', false)">Unstarred</button>
|
||||
<button mat-menu-item (click)="selectTodos('important', true)">Important</button>
|
||||
<button mat-menu-item (click)="selectTodos('important', false)">Unimportant</button>
|
||||
</mat-menu>
|
||||
|
||||
<div class="toolbar-separator" *ngIf="hasSelectedTodos"></div>
|
||||
|
||||
<button mat-icon-button [matMenuTriggerFor]="labelMenu" *ngIf="hasSelectedTodos">
|
||||
<mat-icon class="secondary-text">label</mat-icon>
|
||||
</button>
|
||||
<mat-menu #labelMenu="matMenu">
|
||||
<button mat-menu-item *ngFor="let tag of tags" (click)="toggleTagOnSelectedTodos(tag.id)">
|
||||
{{tag.title}}
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
||||
<div *ngIf="currentTodo" fxHide.gt-lg>
|
||||
<button mat-icon-button (click)="deselectCurrentTodo()">
|
||||
<mat-icon class="secondary-text">arrow_back</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT TOOLBAR -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content" fxFlexAlign="row">
|
||||
<todo-list fusePerfectScrollbar fxFlex></todo-list>
|
||||
<todo-details fusePerfectScrollbar fxFlex></todo-details>
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT CARD -->
|
||||
|
||||
</div>
|
||||
<!-- / CENTER -->
|
||||
|
||||
</div>
|
|
@ -1,171 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
|
||||
import { Todo } from 'app/main/apps/todo/todo.model';
|
||||
import { TodoService } from 'app/main/apps/todo/todo.service';
|
||||
|
||||
@Component({
|
||||
selector : 'todo',
|
||||
templateUrl: './todo.component.html',
|
||||
styleUrls : ['./todo.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class TodoComponent implements OnInit, OnDestroy
|
||||
{
|
||||
hasSelectedTodos: boolean;
|
||||
isIndeterminate: boolean;
|
||||
filters: any[];
|
||||
tags: any[];
|
||||
searchInput: FormControl;
|
||||
currentTodo: Todo;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
* @param {TodoService} _todoService
|
||||
*/
|
||||
constructor(
|
||||
private _fuseSidebarService: FuseSidebarService,
|
||||
private _todoService: TodoService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.searchInput = new FormControl('');
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._todoService.onSelectedTodosChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(selectedTodos => {
|
||||
|
||||
setTimeout(() => {
|
||||
this.hasSelectedTodos = selectedTodos.length > 0;
|
||||
this.isIndeterminate = (selectedTodos.length !== this._todoService.todos.length && selectedTodos.length > 0);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
this._todoService.onFiltersChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(folders => {
|
||||
this.filters = this._todoService.filters;
|
||||
});
|
||||
|
||||
this._todoService.onTagsChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(tags => {
|
||||
this.tags = this._todoService.tags;
|
||||
});
|
||||
|
||||
this.searchInput.valueChanges
|
||||
.pipe(
|
||||
takeUntil(this._unsubscribeAll),
|
||||
debounceTime(300),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
.subscribe(searchText => {
|
||||
this._todoService.onSearchTextChanged.next(searchText);
|
||||
});
|
||||
|
||||
this._todoService.onCurrentTodoChanged
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(([currentTodo, formType]) => {
|
||||
if ( !currentTodo )
|
||||
{
|
||||
this.currentTodo = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.currentTodo = currentTodo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Deselect current todo
|
||||
*/
|
||||
deselectCurrentTodo(): void
|
||||
{
|
||||
this._todoService.onCurrentTodoChanged.next([null, null]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle select all
|
||||
*/
|
||||
toggleSelectAll(): void
|
||||
{
|
||||
this._todoService.toggleSelectAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select todos
|
||||
*
|
||||
* @param filterParameter
|
||||
* @param filterValue
|
||||
*/
|
||||
selectTodos(filterParameter?, filterValue?): void
|
||||
{
|
||||
this._todoService.selectTodos(filterParameter, filterValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselect todos
|
||||
*/
|
||||
deselectTodos(): void
|
||||
{
|
||||
this._todoService.deselectTodos();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle tag on selected todos
|
||||
*
|
||||
* @param tagId
|
||||
*/
|
||||
toggleTagOnSelectedTodos(tagId): void
|
||||
{
|
||||
this._todoService.toggleTagOnSelectedTodos(tagId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the sidebar
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
toggleSidebar(name): void
|
||||
{
|
||||
this._fuseSidebarService.getSidebar(name).toggleOpen();
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
@Component({
|
||||
selector : 'mail-confirm',
|
||||
templateUrl: './mail-confirm.component.html',
|
||||
styleUrls : ['./mail-confirm.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class MailConfirmComponent
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FuseConfigService} _fuseConfigService
|
||||
*/
|
||||
constructor(
|
||||
private _fuseConfigService: FuseConfigService
|
||||
)
|
||||
{
|
||||
// Configure the layout
|
||||
this._fuseConfigService.config = {
|
||||
layout: {
|
||||
navbar : {
|
||||
hidden: true
|
||||
},
|
||||
toolbar: {
|
||||
hidden: true
|
||||
},
|
||||
footer : {
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
|
||||
@Component({
|
||||
selector : 'mail-confirm',
|
||||
templateUrl: './mail-confirm.component.html',
|
||||
styleUrls : ['./mail-confirm.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class MailConfirmComponent
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FuseConfigService} _fuseConfigService
|
||||
*/
|
||||
constructor(
|
||||
private _fuseConfigService: FuseConfigService
|
||||
)
|
||||
{
|
||||
// Configure the layout
|
||||
this._fuseConfigService.config = {
|
||||
layout: {
|
||||
navbar : {
|
||||
hidden: true
|
||||
},
|
||||
toolbar: {
|
||||
hidden: true
|
||||
},
|
||||
footer : {
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,938 +0,0 @@
|
|||
<div id="changelog" class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24" fxLayout="column" fxLayoutAlign="center start">
|
||||
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
</div>
|
||||
|
||||
<div class="h2 mt-16">Changelog</div>
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<div class="changelog">
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v6.1.0 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v6.1.0</span>
|
||||
<span class="date">(2018-06-xx)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="breaking-changes">
|
||||
<span class="title">Breaking Changes</span>
|
||||
<ul>
|
||||
<li>New layout system and layouts</li>
|
||||
<li>Replaced all mat-sidenav components with fuse-sidebar on apps and pages</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Navigation service for easier modifications and for easier swapping</li>
|
||||
<li>fusePerfectScrollbar now accepts a boolean to control the scrollbar's status</li>
|
||||
<li>fusePerfectScrollbarOptions for Perfect Scrollbar options</li>
|
||||
<li>Added an extra Angular Material color theme to the styles.scss file as an example</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="improved">
|
||||
<span class="title">Improved</span>
|
||||
<ul>
|
||||
<li>Updated Angular and Angular Material</li>
|
||||
<li>Updated various other packages</li>
|
||||
<li>Improved the codebase and added a lot code comments</li>
|
||||
<li>Improved the documentation and moved them into the Demo app</li>
|
||||
<li>Changed the fuse-sidebar "align" input to "position"</li>
|
||||
<li>Improved the page layouts</li>
|
||||
<li>Navbar toggle button and fold button alignment on right navbar</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Set the selected language in toolbar from the translation service</li>
|
||||
<li>Horizontal nav titles are collapsing on IE11</li>
|
||||
<li>Angular Material card images not showing correctly</li>
|
||||
<li>Other small fixes and improvements</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v6.0.1 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v6.0.1</span>
|
||||
<span class="date">(2018-05-10)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated ngRx to 6.0.0-beta.1</li>
|
||||
<li>Updated various other libraries to Angular 6 compatible versions</li>
|
||||
<li>Updated demo code to make it compatible with RxJS 6.0.0</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Fixed: Scrumboard "Add a list" button is draggable and causing an error</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v6.0.0 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v6.0.0</span>
|
||||
<span class="date">(2018-05-06)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular to 6.0.0</li>
|
||||
<li>Updated Angular Material to 6.0.0</li>
|
||||
<li>Updated Angular CLI to 6.0.0</li>
|
||||
<li>Updated various other packages</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Fixed: Material icon button colors are being overwritten by Fuse</li>
|
||||
<li>Fixed: Contacts app edit dialog issues</li>
|
||||
<li>Fixed: Navigation sidebar doesn't scroll on mobile devices</li>
|
||||
<li>Fixed: Horizontal navigation doesn't have 'hidden' and 'custom function' features like
|
||||
the vertical
|
||||
navigation
|
||||
</li>
|
||||
<li>Fixed: Search bar close icon alignment</li>
|
||||
<li>Fixed: Profile page header background image doesn't cover the header</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v5.2.10 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v5.2.10</span>
|
||||
<span class="date">(2018-03-10)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Fixed: Sidebar folded bugs</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v5.2.9 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v5.2.9</span>
|
||||
<span class="date">(2018-03-10)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Fixed: Sidebar folded doesn't work correctly if activated programmatically</li>
|
||||
<li>Fixed: Skeleton AoT building issues</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v5.2.8 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v5.2.8</span>
|
||||
<span class="date">(2018-03-08)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="breaking-changes">
|
||||
<span class="title">Breaking changes</span>
|
||||
<ul>
|
||||
<li>
|
||||
<code>core</code> folder moved into the <code>@fuse</code> allowing project owners to
|
||||
have their own core folder inside the app directory. Also allows for better separation
|
||||
in between your app and core Fuse features.
|
||||
</li>
|
||||
<li>
|
||||
Removed Angular Material module that includes all Material components at once and added
|
||||
imports for all modules separately. From now on, you must include the Material
|
||||
components that you have used in your components manually in that component's module
|
||||
file. This was a required changed as it does increase the development performance as
|
||||
well as decrease the building and the AoT building times.
|
||||
</li>
|
||||
<li>
|
||||
Changed how navigation model works. Now it's just a simple const that being exported
|
||||
from the <code>navigation.ts</code> file. It allows for easier swapping and editing of
|
||||
the navigation.
|
||||
</li>
|
||||
<li>
|
||||
New sidebar component. Allows us to move main navigation sidebar logic out of your way.
|
||||
Check out the Demo app to see the full usage.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular to 5.2.8</li>
|
||||
<li>Updated Angular Material to 5.2.4</li>
|
||||
<li>Updated Angular CLI to 1.7.3</li>
|
||||
<li>Matched the Fuse version number with the Angular</li>
|
||||
<li>No more Fuse2, the package name update to Fuse since the version number matched to
|
||||
Angular's.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Fixed various issues with Fuse Angular Material Color Picker component.</li>
|
||||
<li>Fixed various other small layout and logic bugs.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.3.6 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.3.6</span>
|
||||
<span class="date">(2018-02-06)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular to 5.2.3</li>
|
||||
<li>Updated Angular Material to 5.1.1</li>
|
||||
<li>Updated Angular CLI to 1.6.7</li>
|
||||
<li>New Analytics dashboard design</li>
|
||||
<li>Added Chart.js examples through the new dashboard</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.3.5 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.3.5</span>
|
||||
<span class="date">(2018-01-24)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated ngRx to 5.0.0</li>
|
||||
<li>Updated Angular CLI to 1.6.5 to fix the wrong devkit version issue</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.3.4 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.3.4</span>
|
||||
<span class="date">(2018-01-18)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular to 5.2.1</li>
|
||||
<li>Updated Angular Material to 5.1.0</li>
|
||||
<li>Updated various other packages to latest versions</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Quick Panel is too wide for smaller screens</li>
|
||||
<li>Academy App course step doesn't scroll on mobile</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.3.3 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.3.3</span>
|
||||
<span class="date">(2018-01-11)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular to 5.2.0</li>
|
||||
<li>Updated Angular Material to 5.0.4</li>
|
||||
<li>Updated various other packages to latest versions</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.3.2 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.3.2</span>
|
||||
<span class="date">(2018-01-09)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular to 5.1.3</li>
|
||||
<li>Updated Angular Material to 5.0.3</li>
|
||||
<li>Updated various other packages to latest versions</li>
|
||||
<li>Added new card designs</li>
|
||||
<li>Added new fuse-highlight component</li>
|
||||
<li>Added lazy load to various other demo modules to make the demo project faster</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>BREAKING CHANGE: Cards are moved to custom classes</li>
|
||||
<li>BREAKING CHANGE: Removed fuse-hljs (Use fuse-highlight instead)</li>
|
||||
<li>Various other small fixed and enhancements</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.3.1 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.3.1</span>
|
||||
<span class="date">(2018-01-02)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular to 5.1.2</li>
|
||||
<li>Updated Angular Material to 5.0.2</li>
|
||||
<li>Updated various other packages to latest versions</li>
|
||||
<li>New Academy app</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Mail compose dialog responsive issues</li>
|
||||
<li>Fixed for various other bugs</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.3.0 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.3.0</span>
|
||||
<span class="date">(2017-12-15)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular to 5.1.0</li>
|
||||
<li>Updated Angular Material to 5.0.1</li>
|
||||
<li>Updated various other packages to latest versions</li>
|
||||
<li>New NgRx Sample app (Mail-NgRx app)</li>
|
||||
<li>Form stepper examples</li>
|
||||
<li>Added support for translations in navigation items</li>
|
||||
<li>Moved the navigation.model.ts into its own folder</li>
|
||||
<li>Added badge support for collapsable navigation items</li>
|
||||
<li>Initialize the navigation from app.component rather then navigation.service</li>
|
||||
<li>Trigger expand/collapse of the navigation on ngOnInit to update the active item</li>
|
||||
<li>Replaced Calendar images</li>
|
||||
<li>Added custom validator for password matching in Auth forms</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Custom scrollbars are showing in print</li>
|
||||
<li>Various small issues in Auth pages</li>
|
||||
<li>ngx-color-picker various style issues</li>
|
||||
<li>Make sure the nav item has children before trying to get them</li>
|
||||
<li>Renamed the KnowledgeBase demo module</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.2.3 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.2.3</span>
|
||||
<span class="date">(2017-11-28)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Sidenav helper causes issues in mobile media steps</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.2.2 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.2.2</span>
|
||||
<span class="date">(2017-11-27)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular to 5.0.3</li>
|
||||
<li>Updated Angular Material to 5.0.0-rc.1</li>
|
||||
<li>Updated Flex Layout</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Contacts app various issues</li>
|
||||
<li>Duplicate content in Profile page tabs</li>
|
||||
<li>Folded status of the Navbar shouldn't brake the layout if Horizontal Navbar is active
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.2.1 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.2.1</span>
|
||||
<span class="date">(2017-11-13)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular to 5.0.1</li>
|
||||
<li>Updated Angular Material to 5.0.0-rc0</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Compatibility fixed for Angular Material 5.0.0-rc0</li>
|
||||
<li>Scrumboard label selector not working properly</li>
|
||||
<li>Todo detail style refinements</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.2.0 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.2.0</span>
|
||||
<span class="date">(2017-11-06)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>BREAKING CHANGE: Updated Angular to 5.0.0 (clean installation recommended)</li>
|
||||
<li>Updated Angular Flex Layout to 2.0.0-beta.10</li>
|
||||
<li>E-Commerce App</li>
|
||||
<li>File based translation service and its implementation example</li>
|
||||
<li>Added Material Design cards</li>
|
||||
<li>New 'Knowledge Base' page design</li>
|
||||
<li>Added Tabbed versions of the Carded Sidenav layouts</li>
|
||||
<li>Added an ability to control the folded status of the vertical navigation via
|
||||
FuseConfig
|
||||
</li>
|
||||
<li>
|
||||
Added 'exactMatch' property to the Navigation Model for more control over the active
|
||||
item
|
||||
highlighting
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Angular 5 Compatibility fixed</li>
|
||||
<li>Various iOS10 scrolling issues</li>
|
||||
<li>FAQ page header shrinks on small heights</li>
|
||||
<li>Stagger animation doesn't have 'optional' parameter</li>
|
||||
<li>Toolbar navigation toggle button doesn't actually toggle the navigation bar</li>
|
||||
<li>Nav items cannot be put on the root in Horizontal menu</li>
|
||||
<li>Vertical navbar puts out wrong classes when its toggled</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.1.2 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.1.2</span>
|
||||
<span class="date">(2017-10-16)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>BREAKING CHANGE: Updated Angular Material to 2.0.0-beta.12</li>
|
||||
<li>Updated Angular to 4.4.5</li>
|
||||
<li>New Reset and Forgot password page styles</li>
|
||||
<li>Added 'agm-map', Google Maps component library.</li>
|
||||
<li>New pricing page design</li>
|
||||
<li>New mail confirmation page</li>
|
||||
<li>New FAQ page design</li>
|
||||
<li>Added new methods for accessing and updating specific nav items</li>
|
||||
<li>Added the ability to add custom functions to the nav items</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Print styles and page breaks</li>
|
||||
<li>Inconsistent font sizes across elements</li>
|
||||
<li>Toolbar search bar button collapses on close</li>
|
||||
<li>iOS scrolling issues</li>
|
||||
<li>All 'mat-select' elements wrapped with 'mat-form-field' and fixed related issues</li>
|
||||
<li>Auth page v2 styles iOS height issues</li>
|
||||
<li>Chat view is not scrollable on mobile</li>
|
||||
<li>Terms & Conditions checkbox styling issues on Auth forms</li>
|
||||
<li>Some page layout header heights not correct on small devices</li>
|
||||
<li>Lock page layout issues</li>
|
||||
<li>Calendar & Scrumboard datepicker issues</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.1.1 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.1.1</span>
|
||||
<span class="date">(2017-09-28)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular Material to 2.0.0-beta.11</li>
|
||||
<li>Nested grouping in navigation</li>
|
||||
<li>Added Angular Material elements showcase</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="improved">
|
||||
<span class="title">Improved</span>
|
||||
<ul>
|
||||
<li>Replaced Http module with HttpClient</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.1.0 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.1.0</span>
|
||||
<span class="date">(2017-09-22)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Updated Angular to 4.4.3</li>
|
||||
<li>Added HMR config for starting the ng serve with HMR support</li>
|
||||
<li>Added a way to swap navigation models on the fly</li>
|
||||
<li>Enhanced animations for all apps and some pages</li>
|
||||
<li>Custom perfect scrollbar directive</li>
|
||||
<li>Navigation bar backdrop for closing the navigation easily on mobile</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="improved">
|
||||
<span class="title">Improved</span>
|
||||
<ul>
|
||||
<li>BREAKING CHANGE: Completely re-structured the navigation model</li>
|
||||
<li>Locked dev dependency versions to prevent majority of the npm update errors</li>
|
||||
<li>Updated perfect scrollbar</li>
|
||||
<li>Calendar, Mail, ToDo and Chat app visual and structural Improved</li>
|
||||
<li>Disabled the perfect-scrollbar on mobile completely</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.0.5 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.0.5</span>
|
||||
<span class="date">(2017-09-12)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Horizontal Navigation</li>
|
||||
<li>Boxed Layout</li>
|
||||
<li>New fade-in-out animation to Animations service</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="improved">
|
||||
<span class="title">Improved</span>
|
||||
<ul>
|
||||
<li>Scrumboard & Chat style Improved</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Removed unused md2 library from skeleton</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.0.4 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.0.4</span>
|
||||
<span class="date">(2017-08-31)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Scrumboard App</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="improved">
|
||||
<span class="title">Improved</span>
|
||||
<ul>
|
||||
<li>Responsive Improved, many more will come</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Dashboard sidenav not correctly working on some mobile devices</li>
|
||||
<li>Couple MS Edge issues</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.0.3 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.0.3</span>
|
||||
<span class="date">(2017-08-30)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Reverted to Angular 4.3.5 since animations are not correctly working on 4.3.6</li>
|
||||
<li>Firefox and Edge scroll issues</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.0.2 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.0.2</span>
|
||||
<span class="date">(2017-08-30)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="improved">
|
||||
<span class="title">Improved</span>
|
||||
<ul>
|
||||
<li>Angular Material v2.0.0-beta.10 Compatibility</li>
|
||||
<li>Upgraded to Angular 4.3.6</li>
|
||||
<li>Shortcuts component now stores the shortcuts in cookies</li>
|
||||
<li>Added print styles</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.0.1 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.0.1</span>
|
||||
<span class="date">(2017-08-24)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="improved">
|
||||
<span class="title">Improved</span>
|
||||
<ul>
|
||||
<li>New router animations</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="fixed">
|
||||
<span class="title">Fixed</span>
|
||||
<ul>
|
||||
<li>Fixed AoT compiler issues</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<!-- @ v1.0.0 -->
|
||||
<!-- --------------------------------------------------------------------------------------------- -->
|
||||
<div class="entry">
|
||||
|
||||
<div class="title">
|
||||
<span class="version">v1.0.0</span>
|
||||
<span class="date">(2017-08-23)</span>
|
||||
</div>
|
||||
|
||||
<div class="groups">
|
||||
|
||||
<div class="new">
|
||||
<span class="title">New</span>
|
||||
<ul>
|
||||
<li>Initial Release</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
|
@ -1,6 +0,0 @@
|
|||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
:host {
|
||||
|
||||
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'docs-changelog',
|
||||
templateUrl: './changelog.component.html',
|
||||
styleUrls : ['./changelog.component.scss']
|
||||
})
|
||||
export class DocsChangelogComponent
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector : 'docs-components-third-party-ngx-datatable',
|
||||
templateUrl: './ngx-datatable.component.html',
|
||||
styleUrls : ['./ngx-datatable.component.scss']
|
||||
})
|
||||
export class DocsComponentsThirdPartyNgxDatatableComponent implements OnInit, OnDestroy
|
||||
{
|
||||
rows: any[];
|
||||
loadingIndicator: boolean;
|
||||
reorderable: boolean;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {HttpClient} _httpClient
|
||||
*/
|
||||
constructor(
|
||||
private _httpClient: HttpClient
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.loadingIndicator = true;
|
||||
this.reorderable = true;
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
this._httpClient.get('api/contacts-contacts')
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((contacts: any) => {
|
||||
this.rows = contacts;
|
||||
this.loadingIndicator = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
<div id="countdown" class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24 h-160" fxLayout="column" fxLayoutAlign="center center" fxLayout.gt-xs="row"
|
||||
fxLayoutAlign.gt-xs="space-between center">
|
||||
<div fxLayout="column" fxLayoutAlign="center center" fxLayout.gt-xs="column" fxLayoutAlign.gt-xs="center start">
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">3rd Party Components</span>
|
||||
</div>
|
||||
<div class="h2 mt-16">Google Maps</div>
|
||||
</div>
|
||||
|
||||
<a mat-raised-button class="reference-button mat-white-bg mt-16 mt-sm-0"
|
||||
href="https://angular-maps.com"
|
||||
target="_blank">
|
||||
<mat-icon class="mr-8">link</mat-icon>
|
||||
<span>Reference</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
<p>
|
||||
<code>agm-map</code> is a angular component library for Google Maps.
|
||||
</p>
|
||||
|
||||
<div class="sectiont-title">Sample</div>
|
||||
<p fxLayout="row" fxLayoutAlign="start start">
|
||||
<agm-map [latitude]="lat" [longitude]="lng">
|
||||
<agm-marker [latitude]="lat" [longitude]="lng"></agm-marker>
|
||||
</agm-map>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<agm-map [latitude]="lat" [longitude]="lng">
|
||||
<agm-marker [latitude]="lat" [longitude]="lng"></agm-marker>
|
||||
</agm-map>
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="sectiont-title">Inputs</div>
|
||||
Checkout the component api docs for detail:
|
||||
<a href="https://angular-maps.com/api-docs/agm-core/components/AgmMap.html" target="_blank">AgmMap Api</a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'docs-components-third-party-google-maps',
|
||||
templateUrl: './google-maps.component.html',
|
||||
styleUrls : ['./google-maps.component.scss']
|
||||
})
|
||||
export class DocsComponentsThirdPartyGoogleMapsComponent
|
||||
{
|
||||
lat: number;
|
||||
lng: number;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor()
|
||||
{
|
||||
// Set the defaults
|
||||
this.lat = -34.397;
|
||||
this.lng = 150.644;
|
||||
}
|
||||
}
|
|
@ -1,224 +0,0 @@
|
|||
import { Component } from '@angular/core';
|
||||
import * as shape from 'd3-shape';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations/index';
|
||||
|
||||
@Component({
|
||||
selector : 'docs-components-cards',
|
||||
templateUrl: './cards.component.html',
|
||||
styleUrls : ['./cards.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class DocsComponentsCardsComponent
|
||||
{
|
||||
view: string;
|
||||
card9Expanded: boolean;
|
||||
card10Expanded: boolean;
|
||||
card19: any;
|
||||
card24: any;
|
||||
card25: any;
|
||||
card26: any;
|
||||
|
||||
constructor()
|
||||
{
|
||||
// Set the defaults
|
||||
this.view = 'preview';
|
||||
|
||||
this.card9Expanded = false;
|
||||
this.card10Expanded = false;
|
||||
this.card19 = {
|
||||
scheme: {
|
||||
domain: ['#5c84f1']
|
||||
},
|
||||
data : [
|
||||
{
|
||||
'name' : 'GOOG',
|
||||
'series': [
|
||||
{
|
||||
'name' : 'Jan 1',
|
||||
'value': 540.2
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 2',
|
||||
'value': 539.4
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 3',
|
||||
'value': 538.9
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 4',
|
||||
'value': 539.6
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 5',
|
||||
'value': 540
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 6',
|
||||
'value': 540.2
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 7',
|
||||
'value': 540.48
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
curve : shape.curveBasis
|
||||
};
|
||||
|
||||
this.card24 = {
|
||||
scheme : {
|
||||
domain: ['#4867d2', '#5c84f1', '#89a9f4']
|
||||
},
|
||||
devices: [
|
||||
{
|
||||
'name' : 'Desktop',
|
||||
'value' : 92.8,
|
||||
'change': -0.6
|
||||
},
|
||||
{
|
||||
'name' : 'Mobile',
|
||||
'value' : 6.1,
|
||||
'change': 0.7
|
||||
},
|
||||
{
|
||||
'name' : 'Tablet',
|
||||
'value' : 1.1,
|
||||
'change': 0.1
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
this.card25 = {
|
||||
scheme: {
|
||||
domain: ['#5c84f1']
|
||||
},
|
||||
data : [
|
||||
{
|
||||
'name' : 'Monday',
|
||||
'value': 221
|
||||
},
|
||||
{
|
||||
'name' : 'Tuesday',
|
||||
'value': 428
|
||||
},
|
||||
{
|
||||
'name' : 'Wednesday',
|
||||
'value': 492
|
||||
},
|
||||
{
|
||||
'name' : 'Thursday',
|
||||
'value': 471
|
||||
},
|
||||
{
|
||||
'name' : 'Friday',
|
||||
'value': 413
|
||||
},
|
||||
{
|
||||
'name' : 'Saturday',
|
||||
'value': 344
|
||||
},
|
||||
{
|
||||
'name' : 'Sunday',
|
||||
'value': 294
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
this.card26 = {
|
||||
scheme: {
|
||||
domain: ['#5c84f1']
|
||||
},
|
||||
data : [
|
||||
{
|
||||
'name' : 'Impressions',
|
||||
'series': [
|
||||
{
|
||||
'name' : 'Jan 1',
|
||||
'value': 670000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 2',
|
||||
'value': 540000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 3',
|
||||
'value': 820000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 4',
|
||||
'value': 570000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 5',
|
||||
'value': 720000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 6',
|
||||
'value': 570000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 7',
|
||||
'value': 870000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 8',
|
||||
'value': 720000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 9',
|
||||
'value': 890000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 10',
|
||||
'value': 987000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 11',
|
||||
'value': 1120000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 12',
|
||||
'value': 1360000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 13',
|
||||
'value': 1100000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 14',
|
||||
'value': 1490000
|
||||
},
|
||||
{
|
||||
'name' : 'Jan 15',
|
||||
'value': 980000
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
curve : shape.curveBasis
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle the view
|
||||
*/
|
||||
toggleView(): void
|
||||
{
|
||||
if ( this.view === 'preview' )
|
||||
{
|
||||
this.view = 'source';
|
||||
}
|
||||
else
|
||||
{
|
||||
this.view = 'preview';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { MatButtonModule, MatButtonToggleModule, MatFormFieldModule, MatIconModule, MatListModule, MatMenuModule, MatSelectModule, MatSlideToggleModule, MatTabsModule } from '@angular/material';
|
||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
|
||||
import { FuseCountdownModule, FuseHighlightModule, FuseMaterialColorPickerModule, FuseWidgetModule } from '@fuse/components';
|
||||
import { DocsComponentsCardsComponent } from 'app/main/documentation/components/cards/cards.component';
|
||||
import { DocsComponentsCountdownComponent } from 'app/main/documentation/components/countdown/countdown.component';
|
||||
import { DocsComponentsHighlightComponent } from 'app/main/documentation/components/highlight/highlight.component';
|
||||
import { DocsComponentsMaterialColorPickerComponent } from 'app/main/documentation/components/material-color-picker/material-color-picker.component';
|
||||
import { DocsComponentsNavigationComponent } from 'app/main/documentation/components/navigation/navigation.component';
|
||||
import { DocsComponentsSearchBarComponent } from 'app/main/documentation/components/search-bar/search-bar.component';
|
||||
import { DocsComponentsSidebarComponent } from 'app/main/documentation/components/sidebar/sidebar.component';
|
||||
import { DocsComponentsShortcutsComponent } from 'app/main/documentation/components/shortcuts/shortcuts.component';
|
||||
import { DocsComponentsWidgetComponent } from 'app/main/documentation/components/widget/widget.component';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'cards',
|
||||
component: DocsComponentsCardsComponent
|
||||
},
|
||||
{
|
||||
path : 'countdown',
|
||||
component: DocsComponentsCountdownComponent
|
||||
},
|
||||
{
|
||||
path : 'highlight',
|
||||
component: DocsComponentsHighlightComponent
|
||||
},
|
||||
{
|
||||
path : 'material-color-picker',
|
||||
component: DocsComponentsMaterialColorPickerComponent
|
||||
},
|
||||
{
|
||||
path : 'navigation',
|
||||
component: DocsComponentsNavigationComponent
|
||||
},
|
||||
{
|
||||
path : 'search-bar',
|
||||
component: DocsComponentsSearchBarComponent
|
||||
},
|
||||
{
|
||||
path : 'sidebar',
|
||||
component: DocsComponentsSidebarComponent
|
||||
},
|
||||
{
|
||||
path : 'shortcuts',
|
||||
component: DocsComponentsShortcutsComponent
|
||||
},
|
||||
{
|
||||
path : 'widget',
|
||||
component: DocsComponentsWidgetComponent
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
DocsComponentsCardsComponent,
|
||||
DocsComponentsCountdownComponent,
|
||||
DocsComponentsHighlightComponent,
|
||||
DocsComponentsMaterialColorPickerComponent,
|
||||
DocsComponentsNavigationComponent,
|
||||
DocsComponentsSearchBarComponent,
|
||||
DocsComponentsSidebarComponent,
|
||||
DocsComponentsShortcutsComponent,
|
||||
DocsComponentsWidgetComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
MatButtonModule,
|
||||
MatButtonToggleModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatListModule,
|
||||
MatMenuModule,
|
||||
MatSelectModule,
|
||||
MatSlideToggleModule,
|
||||
MatTabsModule,
|
||||
|
||||
NgxChartsModule,
|
||||
|
||||
FuseSharedModule,
|
||||
|
||||
FuseCountdownModule,
|
||||
FuseHighlightModule,
|
||||
FuseMaterialColorPickerModule,
|
||||
FuseWidgetModule
|
||||
]
|
||||
})
|
||||
export class ComponentsModule
|
||||
{
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
<div id="countdown" class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24 h-160" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div fxLayout="column" fxLayoutAlign="center start">
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Components</span>
|
||||
</div>
|
||||
<div class="h2 mt-16">Countdown</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>fuse-countdown</code> is a custom built Fuse component allows you to create a countdowns.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Sample</div>
|
||||
<p fxLayout="row" fxLayoutAlign="start start">
|
||||
<fuse-countdown eventDate="2019-07-28"></fuse-countdown>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<fuse-countdown eventDate="2019-07-28"></fuse-countdown>
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Inputs</div>
|
||||
<p class="py-8" fxLayout="row" fxLayoutAlign="start center">
|
||||
<code class="mr-16">eventDate</code>
|
||||
<span>
|
||||
The date of the event. Since fuse-countdown uses moment.js to parse the dates, any moment.js
|
||||
compatible date string can be used.
|
||||
</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
<div id="highlight" class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24 h-160" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div fxLayout="column" fxLayoutAlign="center start">
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Components</span>
|
||||
</div>
|
||||
<div class="h2 mt-16">Highlight</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>fuse-highlight</code> is a custom built Fuse component allows to show syntax highlighted codes.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Sample</div>
|
||||
<p fxLayout="row" fxLayoutAlign="start start">
|
||||
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
|
||||
<div class="title">
|
||||
<span>Example Title</span>
|
||||
</div>
|
||||
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
|
||||
</p>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="mat-grey-200-bg py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<div class="title">
|
||||
<span>Example Title</span>
|
||||
</div>
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Inputs</div>
|
||||
<p class="py-8" fxLayout="row" fxLayoutAlign="start center">
|
||||
<code class="mr-16">lang</code>
|
||||
<span>
|
||||
Language of the code to be highlighted.
|
||||
</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
<div id="material-color-picker" class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24 h-160" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div fxLayout="column" fxLayoutAlign="center start">
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Components</span>
|
||||
</div>
|
||||
<div class="h2 mt-16">Material Color Picker</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>fuse-material-color-picker</code> is a custom built Fuse component allows you to add a color picker
|
||||
that allows to choose one of the many Material spec. colors.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Sample</div>
|
||||
<p fxLayout="row" fxLayoutAlign="start start">
|
||||
<fuse-material-color-picker></fuse-material-color-picker>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<fuse-material-color-picker [(selectedClass)]="colorClass"
|
||||
(onValueChange)="onSettingsChange()">
|
||||
</fuse-material-color-picker>
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Two-way bindings</div>
|
||||
<p class="py-8" fxLayout="row" fxLayoutAlign="start center">
|
||||
<code class="mr-16">selectedClass</code>
|
||||
<span>
|
||||
The name of the Fuse color class to select, e.g. <code>mat-red-500-bg</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="py-8 pt-4" fxLayout="row" fxLayoutAlign="start center">
|
||||
<code class="mr-16">selectedBg</code>
|
||||
<span>
|
||||
The hex code of the color to be selected. It will be only selected if the hex code of the color
|
||||
matches one of the material colors.
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Outputs</div>
|
||||
<p class="py-8" fxLayout="row" fxLayoutAlign="start center">
|
||||
<code class="mr-16">onValueChange</code>
|
||||
<span>
|
||||
Event that triggered when a color selected. Returns an object that holds palette, hue, class name,
|
||||
background and foreground colors.
|
||||
</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -1,381 +0,0 @@
|
|||
<div id="navigation" class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24 h-160" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div fxLayout="column" fxLayoutAlign="center start">
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Components</span>
|
||||
</div>
|
||||
<div class="h2 mt-16">Navigation</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>fuse-navigation</code> is a custom built Fuse component allows you to create a multi-level collapsable
|
||||
navigation. It has built-in support for translations using <b>ngx-translate</b> module.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<fuse-navigation [navigation]="navigation" [layout]="'vertical'"></fuse-navigation>
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="my-48">
|
||||
<h2>[navigation]</h2>
|
||||
<p class="py-8">
|
||||
<code><fuse-navigation></fuse-navigation></code> uses a json file to populate
|
||||
the entire navigation. It supports three different navigation items; <b>Group</b>,
|
||||
<b>Collapsable</b> and <b>Item</b>. These items can be mixed and matched to create unique and complex
|
||||
navigation layouts.
|
||||
</p>
|
||||
<p class="py-8">
|
||||
Navigation data can be found in <code>src/app/navigation</code> folder along with its translation
|
||||
files. Navigation data and its translation files are set in <b>app.component.ts</b> file. Check that
|
||||
file for more detailed usage example.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="my-48">
|
||||
<h2>[layout]</h2>
|
||||
<p class="py-8">
|
||||
There are two different layout options for the component; <code>vertical</code> and
|
||||
<code>horizontal</code>. You can set the layout using the <code>[layout]</code> input.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="section-title">Alternative usage (preferred)</div>
|
||||
<p class="py-8">
|
||||
An alternative usage to the above one is to using the <b>Navigation Service</b>. Simply, you get your
|
||||
navigation array, register that as a navigation using the service and then set it as the current
|
||||
navigation. This allows for easier updating and swapping of the navigation:
|
||||
</p>
|
||||
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="ts">
|
||||
<textarea #source>
|
||||
// Get your navigation array from database or file
|
||||
this.navigation = [...]
|
||||
|
||||
// Register the navigation to the service
|
||||
this._fuseNavigationService.register('main', this.navigation);
|
||||
|
||||
// Set the main navigation as our current navigation
|
||||
this._fuseNavigationService.setCurrentNavigation('main');
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<p class="py-8">
|
||||
Once you register your navigation like this, you no longer need to provide the <b>[navigation]</b> input
|
||||
while using the <code>fuse-navigation</code>:
|
||||
</p>
|
||||
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<fuse-navigation [layout]="'vertical'"></fuse-navigation>
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="main-title">Navigation item types</div>
|
||||
|
||||
<div class="section-title">Grouping</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="json">
|
||||
<textarea #source>
|
||||
{
|
||||
'id' : 'components',
|
||||
'title' : 'COMPONENTS',
|
||||
'translate': 'NAV.COMPONENTS',
|
||||
'type' : 'group',
|
||||
'children' : [
|
||||
{
|
||||
'id' : 'ngx-datatable',
|
||||
'title': 'ngx-datatable',
|
||||
'type' : 'item',
|
||||
'url' : '/components/datatables/ngx-datatable'
|
||||
}
|
||||
]
|
||||
}
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Collapsable</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="json">
|
||||
<textarea #source>
|
||||
{
|
||||
'id' : 'datatables',
|
||||
'title' : 'Datatables',
|
||||
'translate': 'NAV.DATATABLES',
|
||||
'type' : 'collapsable',
|
||||
'icon' : 'border_all',
|
||||
'children' : [
|
||||
{
|
||||
'id' : 'ngx-datatable',
|
||||
'title': 'ngx-datatable',
|
||||
'type' : 'item',
|
||||
'url' : '/components/datatables/ngx-datatable'
|
||||
}
|
||||
]
|
||||
},
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Item</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="json">
|
||||
<textarea #source>
|
||||
{
|
||||
'id' : 'countdown',
|
||||
'title' : 'Countdown',
|
||||
'translate': 'NAV.COUNTDOWN',
|
||||
'type' : 'item',
|
||||
'icon' : 'settings_input_component',
|
||||
'url' : '/components/countdown'
|
||||
},
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="main-title">Vertical Navigation Default Folded Status</div>
|
||||
<p>
|
||||
It's possible to change the default folded status of the navigation.
|
||||
</p>
|
||||
<p>
|
||||
Find the layout that you want to edit from <b>app/layout/vertical/</b> directory. Edit the layout's html
|
||||
file and look for the <code>[folded]</code> attribute on <code>fuse-sidebar</code> components.
|
||||
</p>
|
||||
<p>
|
||||
Assigning <code>true</code> to that attribute will make the vertical navigation folded by default.
|
||||
</p>
|
||||
|
||||
<div class="main-title">Updating the navigation</div>
|
||||
|
||||
<p class="message-box warning">
|
||||
In order to make the runtime modifications easier, it's strongly recommended that to give a unique id
|
||||
to all of your navigation items.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Show / Hide certain navigation items</div>
|
||||
|
||||
<div class="my-24">
|
||||
<button mat-button mat-raised-button color="accent" (click)="showHideCalendarMenuItem()">
|
||||
Show / Hide calendar menu item
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="py-8 mb-48">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
hidden = false;
|
||||
|
||||
showHideCalendarMenuItem(): void
|
||||
{
|
||||
// Get the calendar item from the navigation
|
||||
const calendarNavItem = this._fuseNavigationService.getNavigationItem('calendar');
|
||||
|
||||
// Toggle the visibility
|
||||
this.hidden = !this.hidden;
|
||||
calendarNavItem.hidden = this.hidden;
|
||||
}
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Update navigation item on-the-fly</div>
|
||||
|
||||
<div class="my-24">
|
||||
<button mat-button mat-raised-button color="accent" (click)="updateMailBadge()">
|
||||
Update Mail app badge
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="py-8 mb-48">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
updateMailBadge()
|
||||
{
|
||||
// Get the mail nav item
|
||||
const mailNavItem = this._fuseNavigationService.getNavigationItem('mail');
|
||||
|
||||
// Update the badge title
|
||||
mailNavItem.badge.title = 35;
|
||||
}
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Add a subitem to the Calendar nav item</div>
|
||||
|
||||
<div class="my-24">
|
||||
<button mat-button mat-raised-button color="accent" (click)="addSubitemToCalendar()">
|
||||
Add a subitem to the Calendar nav item
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="py-8 mb-48">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
addSubitemToCalendar()
|
||||
{
|
||||
// Prepare the new nav item
|
||||
const newNavItem = {
|
||||
id : 'sub-item',
|
||||
title: 'Sub Item',
|
||||
type : 'item',
|
||||
url : '/apps/calendar'
|
||||
};
|
||||
|
||||
// Get the calendar item from the navigation
|
||||
const calendarNavItem = this._fuseNavigationService.getNavigationItem('calendar');
|
||||
|
||||
// Make the calendar navigation item collapsable
|
||||
calendarNavItem.type = 'collapse';
|
||||
|
||||
// Add the navigation item
|
||||
this._fuseNavigationService.addNavigationItem(newNavItem, 'calendar');
|
||||
}
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Add a nav item with custom function</div>
|
||||
|
||||
<div class="my-24">
|
||||
<button mat-button mat-raised-button color="accent" (click)="addNavItemWithCustomFunction()">
|
||||
Add a nav item with custom function
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="py-8 mb-48">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
addNavItemWithCustomFunction()
|
||||
{
|
||||
// Prepare the new nav item
|
||||
const newNavItem = {
|
||||
id : 'custom-item',
|
||||
title : 'Custom Item',
|
||||
type : 'item',
|
||||
function: () => {
|
||||
alert('Custom function!');
|
||||
}
|
||||
};
|
||||
|
||||
// Add the new nav item at the beginning of the navigation
|
||||
this._fuseNavigationService.addNavigationItem(newNavItem, 'start');
|
||||
}
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Remove the Dashboards menu item</div>
|
||||
|
||||
<div class="my-24">
|
||||
<button mat-button mat-raised-button color="accent" (click)="removeDashboards()">
|
||||
Remove Dashboards menu item
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="py-8 mb-48">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
removeDashboards(): void
|
||||
{
|
||||
this._fuseNavigationService.removeNavigationItem('dashboards');
|
||||
}
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Register a new navigation and toggle to it</div>
|
||||
|
||||
<div class="my-24">
|
||||
<button mat-button mat-raised-button color="accent" (click)="registerNewNavigationAndToggle()">
|
||||
Register a new navigation and toggle to it
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="typescript">
|
||||
<textarea #source>
|
||||
registerNewNavigationAndToggle(): void
|
||||
{
|
||||
const adminNav = [
|
||||
{
|
||||
id : 'admin',
|
||||
title : 'Admin',
|
||||
type : 'group',
|
||||
icon : 'apps',
|
||||
children: [
|
||||
{
|
||||
id : 'users',
|
||||
title: 'Users',
|
||||
type : 'item',
|
||||
icon : 'person',
|
||||
url : '/apps/dashboards/analytics'
|
||||
},
|
||||
{
|
||||
id : 'payments',
|
||||
title: 'Payments',
|
||||
type : 'item',
|
||||
icon : 'attach_money',
|
||||
url : '/apps/academy'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id : 'control-panel',
|
||||
title : 'Control Panel',
|
||||
type : 'group',
|
||||
icon : 'apps',
|
||||
children: [
|
||||
{
|
||||
id : 'cron-jobs',
|
||||
title: 'Cron Jobs',
|
||||
type : 'item',
|
||||
icon : 'settings',
|
||||
url : '/apps/file-manager'
|
||||
},
|
||||
{
|
||||
id : 'maintenance-mode',
|
||||
title: 'Maintenance Mode',
|
||||
type : 'item',
|
||||
icon : 'build',
|
||||
url : '/apps/todo'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
// Register the new navigation
|
||||
this._fuseNavigationService.register('admin-nav', adminNav);
|
||||
|
||||
// Set the current navigation
|
||||
this._fuseNavigationService.setCurrentNavigation('admin-nav');
|
||||
}
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'docs-components-navigation',
|
||||
templateUrl: './navigation.component.html',
|
||||
styleUrls : ['./navigation.component.scss']
|
||||
})
|
||||
export class DocsComponentsNavigationComponent
|
||||
{
|
||||
navigation: any;
|
||||
hidden: boolean;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor(
|
||||
private _fuseNavigationService: FuseNavigationService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.hidden = false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Show/hide calendar menu item
|
||||
*/
|
||||
showHideCalendarMenuItem(): void
|
||||
{
|
||||
// Get the calendar item from the navigation
|
||||
const calendarNavItem = this._fuseNavigationService.getNavigationItem('calendar');
|
||||
|
||||
// Toggle the visibility
|
||||
this.hidden = !this.hidden;
|
||||
calendarNavItem.hidden = this.hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update mail badge
|
||||
*/
|
||||
updateMailBadge(): void
|
||||
{
|
||||
// Get the mail nav item
|
||||
const mailNavItem = this._fuseNavigationService.getNavigationItem('mail');
|
||||
|
||||
// Update the badge title
|
||||
mailNavItem.badge.title = 35;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add subitem to the calendar
|
||||
*/
|
||||
addSubitemToCalendar(): void
|
||||
{
|
||||
// Prepare the new nav item
|
||||
const newNavItem = {
|
||||
id : 'sub-item',
|
||||
title: 'Sub Item',
|
||||
type : 'item',
|
||||
url : '/apps/calendar'
|
||||
};
|
||||
|
||||
// Get the calendar item from the navigation
|
||||
const calendarNavItem = this._fuseNavigationService.getNavigationItem('calendar');
|
||||
|
||||
// Make the calendar navigation item collapsable
|
||||
calendarNavItem.type = 'collapsable';
|
||||
|
||||
// Add the navigation item
|
||||
this._fuseNavigationService.addNavigationItem(newNavItem, 'calendar');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a nav item with custom function
|
||||
*/
|
||||
addNavItemWithCustomFunction(): void
|
||||
{
|
||||
// Prepare the new nav item
|
||||
const newNavItem = {
|
||||
id : 'custom-item',
|
||||
title : 'Custom Item',
|
||||
type : 'item',
|
||||
function: () => {
|
||||
alert('Custom function!');
|
||||
}
|
||||
};
|
||||
|
||||
// Add the new nav item at the beginning of the navigation
|
||||
this._fuseNavigationService.addNavigationItem(newNavItem, 'start');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the dashboard menu item
|
||||
*/
|
||||
removeDashboards(): void
|
||||
{
|
||||
this._fuseNavigationService.removeNavigationItem('dashboards');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new navigation and toggle to it
|
||||
*/
|
||||
registerNewNavigationAndToggle(): void
|
||||
{
|
||||
const adminNav = [
|
||||
{
|
||||
id : 'admin',
|
||||
title : 'Admin',
|
||||
type : 'group',
|
||||
icon : 'apps',
|
||||
children: [
|
||||
{
|
||||
id : 'users',
|
||||
title: 'Users',
|
||||
type : 'item',
|
||||
icon : 'person',
|
||||
url : '/apps/dashboards/analytics'
|
||||
},
|
||||
{
|
||||
id : 'payments',
|
||||
title: 'Payments',
|
||||
type : 'item',
|
||||
icon : 'attach_money',
|
||||
url : '/apps/academy'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id : 'control-panel',
|
||||
title : 'Control Panel',
|
||||
type : 'group',
|
||||
icon : 'apps',
|
||||
children: [
|
||||
{
|
||||
id : 'cron-jobs',
|
||||
title: 'Cron Jobs',
|
||||
type : 'item',
|
||||
icon : 'settings',
|
||||
url : '/apps/file-manager'
|
||||
},
|
||||
{
|
||||
id : 'maintenance-mode',
|
||||
title: 'Maintenance Mode',
|
||||
type : 'item',
|
||||
icon : 'build',
|
||||
url : '/apps/todo'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
// Register the new navigation
|
||||
this._fuseNavigationService.register('admin-nav', adminNav);
|
||||
|
||||
// Set the current navigation
|
||||
this._fuseNavigationService.setCurrentNavigation('admin-nav');
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<div id="search-bar" class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24 h-160" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div fxLayout="column" fxLayoutAlign="center start">
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Components</span>
|
||||
</div>
|
||||
<div class="h2 mt-16">Search Bar</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>fuse-search-bar</code> is a custom built Fuse component allows you to have a search bar that activates
|
||||
on click.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<fuse-search-bar (input)="search($event)"></fuse-search-bar>
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Outputs</div>
|
||||
<p class="py-8" fxLayout="row" fxLayoutAlign="start center">
|
||||
<code class="mr-8">input</code>
|
||||
<span>Triggers every time an input occurs within the search bar. Can be used to trigger the actual
|
||||
search mechanism. The $event is the value from the search input.
|
||||
</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
<div id="shortcuts" class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24 h-160" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div fxLayout="column" fxLayoutAlign="center start">
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Components</span>
|
||||
</div>
|
||||
<div class="h2 mt-16">Shortcuts</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>fuse-shortcuts</code> is a custom built Fuse component allows you to create and save shortcuts from
|
||||
the navigation model.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<fuse-shortcuts></fuse-shortcuts>
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Model</div>
|
||||
<p class="py-8">
|
||||
<code><fuse-shortcuts></fuse-shortcuts></code> uses the same service with navigation
|
||||
component to populate the shortcuts. It can search the navigation items as well as pin and unpin them as
|
||||
shortcuts. It uses browser cookies to store the shortcuts.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
<div id="widget" class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24 h-160" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div fxLayout="column" fxLayoutAlign="center start">
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Components</span>
|
||||
</div>
|
||||
<div class="h2 mt-16">Widget</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>fuse-widget</code> is a custom built Fuse component allows to create flippable widget boxes.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Sample</div>
|
||||
<div>
|
||||
<fuse-widget class="" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div>Widget title</div>
|
||||
|
||||
<button mat-icon-button fuseWidgetToggle aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
|
||||
Widget Content
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
<!-- Back -->
|
||||
<div class="fuse-widget-back p-16 pt-32 mat-white-bg mat-elevation-z2">
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="Flip widget">
|
||||
<mat-icon class="s-16">close</mat-icon>
|
||||
</button>
|
||||
|
||||
<div>
|
||||
More widget info
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Back -->
|
||||
|
||||
</fuse-widget>
|
||||
</div>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="py-8">
|
||||
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
|
||||
<fuse-widget class="" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
|
||||
|
||||
<!-- Front -->
|
||||
<div class="fuse-widget-front mat-white-bg mat-elevation-z2">
|
||||
<div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<div>Widget title</div>
|
||||
|
||||
<button mat-icon-button fuseWidgetToggle aria-label="more">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
|
||||
Widget Content
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Front -->
|
||||
|
||||
<!-- Back -->
|
||||
<div class="fuse-widget-back p-16 pt-32 mat-white-bg mat-elevation-z2">
|
||||
<button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
|
||||
aria-label="Flip widget">
|
||||
<mat-icon class="s-16">close</mat-icon>
|
||||
</button>
|
||||
|
||||
<div>
|
||||
More widget info
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Back -->
|
||||
|
||||
</fuse-widget>
|
||||
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { MatButtonModule, MatIconModule } from '@angular/material';
|
||||
|
||||
import { FuseSharedModule } from '@fuse/shared.module';
|
||||
import { FuseHighlightModule } from '@fuse/components';
|
||||
|
||||
import { DocsDirectivesFuseIfOnDomComponent } from 'app/main/documentation/directives/fuseIfOnDom/fuse-if-on-dom.component';
|
||||
import { DocsDirectivesFuseInnerScrollComponent } from 'app/main/documentation/directives/fuseInnerScroll/fuse-inner-scroll.component';
|
||||
import { DocsDirectivesFuseMatSidenavComponent } from 'app/main/documentation/directives/fuseMatSidenav/fuse-mat-sidenav.component';
|
||||
import { DocsDirectivesFusePerfectScrollbarComponent } from 'app/main/documentation/directives/fusePerfectScrollbar/fuse-perfect-scrollbar.component';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'fuse-if-on-dom',
|
||||
component: DocsDirectivesFuseIfOnDomComponent
|
||||
},
|
||||
{
|
||||
path : 'fuse-inner-scroll',
|
||||
component: DocsDirectivesFuseInnerScrollComponent
|
||||
},
|
||||
{
|
||||
path : 'fuse-mat-sidenav',
|
||||
component: DocsDirectivesFuseMatSidenavComponent
|
||||
},
|
||||
{
|
||||
path : 'fuse-perfect-scrollbar',
|
||||
component: DocsDirectivesFusePerfectScrollbarComponent
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
DocsDirectivesFuseIfOnDomComponent,
|
||||
DocsDirectivesFuseInnerScrollComponent,
|
||||
DocsDirectivesFuseMatSidenavComponent,
|
||||
DocsDirectivesFusePerfectScrollbarComponent
|
||||
],
|
||||
imports : [
|
||||
RouterModule.forChild(routes),
|
||||
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
|
||||
FuseSharedModule,
|
||||
FuseHighlightModule
|
||||
]
|
||||
})
|
||||
export class DirectivesModule
|
||||
{
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<div class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24" fxLayout="column" fxLayoutAlign="center start">
|
||||
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Directives</span>
|
||||
</div>
|
||||
|
||||
<div class="h2 mt-16">fuseIfOnDom</div>
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>*fuseIfOnDom</code> is a helper directive that detaches and re-attaches the given element if it's
|
||||
currently in the DOM. This will help in various cases such as charts that don't resize properly or
|
||||
animations that don't wait to route to be loaded completely.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<div *fuseIfOnDom></div>
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
|
@ -1,13 +0,0 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'docs-directives-fuse-if-on-dom',
|
||||
templateUrl: './fuse-if-on-dom.component.html',
|
||||
styleUrls : ['./fuse-if-on-dom.component.scss']
|
||||
})
|
||||
export class DocsDirectivesFuseIfOnDomComponent
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
<div class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24" fxLayout="column" fxLayoutAlign="center start">
|
||||
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Directives</span>
|
||||
</div>
|
||||
|
||||
<div class="h2 mt-16">fuseInnerScroll</div>
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>fuseInnerScroll</code> is a class directive that can be used in page layouts. It will lock the
|
||||
container's scroll allowing for individual scroll such as sidebar and the content itself.
|
||||
</p>
|
||||
|
||||
<p class="message-box warning">
|
||||
This directive will only work with Fuse's pre-built page layouts and it's a class directive.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<div class="page-layout carded left-sidebar inner-scroll">
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
|
@ -1,5 +0,0 @@
|
|||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
:host {
|
||||
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'docs-directives-fuse-inner-scroll',
|
||||
templateUrl: './fuse-inner-scroll.component.html',
|
||||
styleUrls : ['./fuse-inner-scroll.component.scss']
|
||||
})
|
||||
export class DocsDirectivesFuseInnerScrollComponent
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
<div class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24" fxLayout="column" fxLayoutAlign="center start">
|
||||
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Directives</span>
|
||||
</div>
|
||||
|
||||
<div class="h2 mt-16">fuseMatSidenav</div>
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>fuseMatSidenav</code> is a helper directive that enhances the Angular Material's sidenav. It modifies
|
||||
the sidenav so it will function like the Angular Material 1.x sidenav. It also has a service which you can
|
||||
register a sidenav in order to access and control its status from anywhere.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<mat-sidenav position="start" opened="true" mode="side"
|
||||
fuseMatSidenavHelper="chat-left-sidenav" mat-is-locked-open="gt-md">
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Inputs</div>
|
||||
<p class="py-8" fxLayout="row" fxLayoutAlign="start center">
|
||||
<code class="mr-16">fuseMatSidenavHelper</code>
|
||||
<span>
|
||||
A unique name for the sidenav.
|
||||
</span>
|
||||
</p>
|
||||
<p class="py-8" fxLayout="row" fxLayoutAlign="start center">
|
||||
<code class="mr-16">mat-is-locked-open</code>
|
||||
<span>
|
||||
Adds a locked open functionality just like Angular Material 1.x sidenav. Works with the media step
|
||||
aliases of the FlexLayout library.
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Accessing to the sidebav methods from anywhere</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="ts">
|
||||
<textarea #source>
|
||||
constructor(
|
||||
private _fuseMatSidenavHelperService: FuseMatSidenavHelperService,
|
||||
) {}
|
||||
|
||||
toggleSidenav()
|
||||
{
|
||||
this._fuseMatSidenavHelperService.getSidenav('chat-left-sidenav').toggle();
|
||||
}
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
|
@ -1,8 +0,0 @@
|
|||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
:host {
|
||||
|
||||
code {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'docs-directives-fuse-mat-sidenav',
|
||||
templateUrl: './fuse-mat-sidenav.component.html',
|
||||
styleUrls : ['./fuse-mat-sidenav.component.scss']
|
||||
})
|
||||
export class DocsDirectivesFuseMatSidenavComponent
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
<div class="page-layout simple fullwidth docs">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24" fxLayout="column" fxLayoutAlign="center start">
|
||||
|
||||
<div class="black-fg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-icon class="secondary-text s-18">home</mat-icon>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Documentation</span>
|
||||
<mat-icon class="secondary-text s-16">chevron_right</mat-icon>
|
||||
<span class="secondary-text">Directives</span>
|
||||
</div>
|
||||
|
||||
<div class="h2 mt-16">fusePerfectScrollbar</div>
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<p>
|
||||
<code>fusePerfectScrollbar</code> is an Angular directive for the <a
|
||||
href="https://github.com/utatti/perfect-scrollbar" target="_blank">Perfect Scrollbar</a> library.
|
||||
</p>
|
||||
|
||||
<div class="section-title">Usage</div>
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<div fusePerfectScrollbar>
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<p class="py-8">
|
||||
<fuse-highlight lang="html">
|
||||
<textarea #source>
|
||||
<div [fusePerfectScrollbar]="false" [fusePerfectScrollbarOptions]="{'updateOnRouteChange': true}">
|
||||
</textarea>
|
||||
</fuse-highlight>
|
||||
</p>
|
||||
|
||||
<div class="section-title">Inputs</div>
|
||||
<p class="py-8" fxLayout="row" fxLayoutAlign="start center">
|
||||
<code class="mr-16">fusePerfectScrollbar</code>
|
||||
<span>
|
||||
Accepts an optional boolean which you can control the Perfect Scrollbar. If provided false, Perfect
|
||||
Scrollbar will be destroyed or won't be initialized.
|
||||
</span>
|
||||
</p>
|
||||
<p class="py-8" fxLayout="row" fxLayoutAlign="start center">
|
||||
<code class="mr-16">fusePerfectScrollbarOptions</code>
|
||||
<span>
|
||||
Accepts the <a href="https://github.com/utatti/perfect-scrollbar#options" target="_blank">Perfect
|
||||
Scrollbar options</a>. In addition to those options, there is also a custom <b>updateOnRouteChange</b>
|
||||
option which updates the scrollbar on route changes. That's useful if your scrollbar wraps a
|
||||
<b>router-outlet</b>.
|
||||
</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user