mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-01-10 12:35:07 +00:00
Improving the codebase (wip)
This commit is contained in:
parent
0039f44936
commit
742da904da
|
@ -3,6 +3,7 @@ import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { MatMomentDateModule } from '@angular/material-moment-adapter';
|
||||||
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
|
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import 'hammerjs';
|
import 'hammerjs';
|
||||||
|
@ -64,6 +65,9 @@ const appRoutes: Routes = [
|
||||||
passThruUnknownUrl: true
|
passThruUnknownUrl: true
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
// Material moment date module
|
||||||
|
MatMomentDateModule,
|
||||||
|
|
||||||
// Fuse modules
|
// Fuse modules
|
||||||
FuseModule.forRoot(fuseConfig),
|
FuseModule.forRoot(fuseConfig),
|
||||||
FuseSharedModule,
|
FuseSharedModule,
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AcademyCourseService implements Resolve<any>
|
export class AcademyCourseService implements Resolve<any>
|
||||||
{
|
{
|
||||||
onCourseChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
onCourseChanged: BehaviorSubject<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -17,6 +17,8 @@ export class AcademyCourseService implements Resolve<any>
|
||||||
private _httpClient: HttpClient
|
private _httpClient: HttpClient
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onCourseChanged = new BehaviorSubject({});
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -6,8 +6,8 @@ import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AcademyCoursesService implements Resolve<any>
|
export class AcademyCoursesService implements Resolve<any>
|
||||||
{
|
{
|
||||||
onCategoriesChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
onCategoriesChanged: BehaviorSubject<any>;
|
||||||
onCoursesChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
onCoursesChanged: BehaviorSubject<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -18,6 +18,9 @@ export class AcademyCoursesService implements Resolve<any>
|
||||||
private _httpClient: HttpClient
|
private _httpClient: HttpClient
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onCategoriesChanged = new BehaviorSubject({});
|
||||||
|
this.onCoursesChanged = new BehaviorSubject({});
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -14,7 +14,7 @@ const routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'mail',
|
path : 'mail',
|
||||||
loadChildren: './mail/mail.module#FuseMailModule'
|
loadChildren: './mail/mail.module#MailModule'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'mail-ngrx',
|
path : 'mail-ngrx',
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
import { MatButtonModule, MatDatepickerModule, MatFormFieldModule, MatIconModule, MatInputModule, MatSlideToggleModule, MatToolbarModule } from '@angular/material';
|
import { MatButtonModule, MatDatepickerModule, MatDialogModule, MatFormFieldModule, MatIconModule, MatInputModule, MatSlideToggleModule, MatToolbarModule } from '@angular/material';
|
||||||
import { ColorPickerModule } from 'ngx-color-picker';
|
import { ColorPickerModule } from 'ngx-color-picker';
|
||||||
import { CalendarModule as AngularCalendarModule } from 'angular-calendar';
|
import { CalendarModule as AngularCalendarModule } from 'angular-calendar';
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ const routes: Routes = [
|
||||||
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatDatepickerModule,
|
MatDatepickerModule,
|
||||||
|
MatDialogModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Observable, Subject } from 'rxjs';
|
||||||
export class CalendarService implements Resolve<any>
|
export class CalendarService implements Resolve<any>
|
||||||
{
|
{
|
||||||
events: any;
|
events: any;
|
||||||
onEventsUpdated = new Subject<any>();
|
onEventsUpdated: Subject<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -18,7 +18,8 @@ export class CalendarService implements Resolve<any>
|
||||||
private _httpClient: HttpClient
|
private _httpClient: HttpClient
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onEventsUpdated = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<mat-toolbar class="mat-accent m-0">
|
<mat-toolbar class="mat-accent m-0">
|
||||||
<mat-toolbar-row fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
<mat-toolbar-row fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||||
<span class="title dialog-title">{{dialogTitle}}</span>
|
<span class="title dialog-title">{{dialogTitle}}</span>
|
||||||
<button mat-icon-button (click)="dialogRef.close()" aria-label="Close dialog">
|
<button mat-icon-button (click)="_matDialogRef.close()" aria-label="Close dialog">
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-toolbar-row>
|
</mat-toolbar-row>
|
||||||
|
@ -117,7 +117,7 @@
|
||||||
|
|
||||||
<button *ngIf="action !=='edit'"
|
<button *ngIf="action !=='edit'"
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
(click)="dialogRef.close(eventForm)"
|
(click)="_matDialogRef.close(eventForm)"
|
||||||
class="save-button mat-accent"
|
class="save-button mat-accent"
|
||||||
[disabled]="eventForm.invalid"
|
[disabled]="eventForm.invalid"
|
||||||
aria-label="SAVE">
|
aria-label="SAVE">
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
|
|
||||||
<button *ngIf="action ==='edit'"
|
<button *ngIf="action ==='edit'"
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
(click)="dialogRef.close(['save',eventForm])"
|
(click)="_matDialogRef.close(['save',eventForm])"
|
||||||
class="save-button mat-accent"
|
class="save-button mat-accent"
|
||||||
[disabled]="eventForm.invalid"
|
[disabled]="eventForm.invalid"
|
||||||
aria-label="SAVE">
|
aria-label="SAVE">
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
|
|
||||||
<button *ngIf="action ==='edit'"
|
<button *ngIf="action ==='edit'"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="dialogRef.close(['delete',eventForm])"
|
(click)="_matDialogRef.close(['delete',eventForm])"
|
||||||
aria-label="Delete"
|
aria-label="Delete"
|
||||||
matTooltip="Delete">
|
matTooltip="Delete">
|
||||||
<mat-icon>delete</mat-icon>
|
<mat-icon>delete</mat-icon>
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { MatColors } from '@fuse/mat-colors';
|
||||||
import { CalendarEventModel } from 'app/main/apps/calendar/event.model';
|
import { CalendarEventModel } from 'app/main/apps/calendar/event.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-calendar-event-form-dialog',
|
selector : 'calendar-event-form-dialog',
|
||||||
templateUrl : './event-form.component.html',
|
templateUrl : './event-form.component.html',
|
||||||
styleUrls : ['./event-form.component.scss'],
|
styleUrls : ['./event-form.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
|
@ -25,12 +25,12 @@ export class CalendarEventFormDialogComponent
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param {MatDialogRef<CalendarEventFormDialogComponent>} dialogRef
|
* @param {MatDialogRef<CalendarEventFormDialogComponent>} _matDialogRef
|
||||||
* @param _data
|
* @param _data
|
||||||
* @param {FormBuilder} _formBuilder
|
* @param {FormBuilder} _formBuilder
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<CalendarEventFormDialogComponent>,
|
private _matDialogRef: MatDialogRef<CalendarEventFormDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) private _data: any,
|
@Inject(MAT_DIALOG_DATA) private _data: any,
|
||||||
private _formBuilder: FormBuilder
|
private _formBuilder: FormBuilder
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,23 +11,64 @@ export class ChatService implements Resolve<any>
|
||||||
contacts: any[];
|
contacts: any[];
|
||||||
chats: any[];
|
chats: any[];
|
||||||
user: any;
|
user: any;
|
||||||
onChatSelected = new BehaviorSubject<any>(null);
|
onChatSelected: BehaviorSubject<any>;
|
||||||
onContactSelected = new BehaviorSubject<any>(null);
|
onContactSelected: BehaviorSubject<any>;
|
||||||
onChatsUpdated = new Subject<any>();
|
onChatsUpdated: Subject<any>;
|
||||||
onUserUpdated = new Subject<any>();
|
onUserUpdated: Subject<any>;
|
||||||
onLeftSidenavViewChanged = new Subject<any>();
|
onLeftSidenavViewChanged: Subject<any>;
|
||||||
onRightSidenavViewChanged = new Subject<any>();
|
onRightSidenavViewChanged: Subject<any>;
|
||||||
|
|
||||||
constructor(private http: HttpClient)
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {HttpClient} _httpClient
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private _httpClient: HttpClient
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onChatSelected = new BehaviorSubject(null);
|
||||||
|
this.onContactSelected = new BehaviorSubject(null);
|
||||||
|
this.onChatsUpdated = new Subject();
|
||||||
|
this.onUserUpdated = new Subject();
|
||||||
|
this.onLeftSidenavViewChanged = new Subject();
|
||||||
|
this.onRightSidenavViewChanged = new Subject();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolver
|
||||||
|
*
|
||||||
|
* @param {ActivatedRouteSnapshot} route
|
||||||
|
* @param {RouterStateSnapshot} state
|
||||||
|
* @returns {Observable<any> | Promise<any> | any}
|
||||||
|
*/
|
||||||
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
Promise.all([
|
||||||
|
this.getContacts(),
|
||||||
|
this.getChats(),
|
||||||
|
this.getUser()
|
||||||
|
]).then(
|
||||||
|
([contacts, chats, user]) => {
|
||||||
|
this.contacts = contacts;
|
||||||
|
this.chats = chats;
|
||||||
|
this.user = user;
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
reject
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get chat
|
* Get chat
|
||||||
|
*
|
||||||
* @param contactId
|
* @param contactId
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
getChat(contactId)
|
getChat(contactId): Promise<any>
|
||||||
{
|
{
|
||||||
const chatItem = this.user.chatList.find((item) => {
|
const chatItem = this.user.chatList.find((item) => {
|
||||||
return item.contactId === contactId;
|
return item.contactId === contactId;
|
||||||
|
@ -45,7 +86,7 @@ export class ChatService implements Resolve<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/chat-chats/' + chatItem.id)
|
this._httpClient.get('api/chat-chats/' + chatItem.id)
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
const chat = response;
|
const chat = response;
|
||||||
|
|
||||||
|
@ -68,11 +109,12 @@ export class ChatService implements Resolve<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create New Chat
|
* Create new chat
|
||||||
|
*
|
||||||
* @param contactId
|
* @param contactId
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
createNewChat(contactId)
|
createNewChat(contactId): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
@ -103,13 +145,13 @@ export class ChatService implements Resolve<any>
|
||||||
/**
|
/**
|
||||||
* Post the created chat
|
* Post the created chat
|
||||||
*/
|
*/
|
||||||
this.http.post('api/chat-chats', {...chat})
|
this._httpClient.post('api/chat-chats', {...chat})
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post the new the user data
|
* Post the new the user data
|
||||||
*/
|
*/
|
||||||
this.http.post('api/chat-user/' + this.user.id, this.user)
|
this._httpClient.post('api/chat-user/' + this.user.id, this.user)
|
||||||
.subscribe(newUserData => {
|
.subscribe(newUserData => {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,30 +167,33 @@ export class ChatService implements Resolve<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select Contact
|
* Select contact
|
||||||
|
*
|
||||||
* @param contact
|
* @param contact
|
||||||
*/
|
*/
|
||||||
selectContact(contact)
|
selectContact(contact): void
|
||||||
{
|
{
|
||||||
this.onContactSelected.next(contact);
|
this.onContactSelected.next(contact);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set user status
|
* Set user status
|
||||||
|
*
|
||||||
* @param status
|
* @param status
|
||||||
*/
|
*/
|
||||||
setUserStatus(status)
|
setUserStatus(status): void
|
||||||
{
|
{
|
||||||
this.user.status = status;
|
this.user.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update user data
|
* Update user data
|
||||||
|
*
|
||||||
* @param userData
|
* @param userData
|
||||||
*/
|
*/
|
||||||
updateUserData(userData)
|
updateUserData(userData): void
|
||||||
{
|
{
|
||||||
this.http.post('api/chat-user/' + this.user.id, userData)
|
this._httpClient.post('api/chat-user/' + this.user.id, userData)
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
this.user = userData;
|
this.user = userData;
|
||||||
}
|
}
|
||||||
|
@ -157,6 +202,7 @@ export class ChatService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the chat dialog
|
* Update the chat dialog
|
||||||
|
*
|
||||||
* @param chatId
|
* @param chatId
|
||||||
* @param dialog
|
* @param dialog
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
|
@ -170,7 +216,7 @@ export class ChatService implements Resolve<any>
|
||||||
dialog: dialog
|
dialog: dialog
|
||||||
};
|
};
|
||||||
|
|
||||||
this.http.post('api/chat-chats/' + chatId, newData)
|
this._httpClient.post('api/chat-chats/' + chatId, newData)
|
||||||
.subscribe(updatedChat => {
|
.subscribe(updatedChat => {
|
||||||
resolve(updatedChat);
|
resolve(updatedChat);
|
||||||
}, reject);
|
}, reject);
|
||||||
|
@ -178,38 +224,14 @@ export class ChatService implements Resolve<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Chat App Main Resolver
|
* Get contacts
|
||||||
* @param {ActivatedRouteSnapshot} route
|
*
|
||||||
* @param {RouterStateSnapshot} state
|
|
||||||
* @returns {Observable<any> | Promise<any> | any}
|
|
||||||
*/
|
|
||||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
|
|
||||||
{
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
Promise.all([
|
|
||||||
this.getContacts(),
|
|
||||||
this.getChats(),
|
|
||||||
this.getUser()
|
|
||||||
]).then(
|
|
||||||
([contacts, chats, user]) => {
|
|
||||||
this.contacts = contacts;
|
|
||||||
this.chats = chats;
|
|
||||||
this.user = user;
|
|
||||||
resolve();
|
|
||||||
},
|
|
||||||
reject
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Contacts
|
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
getContacts(): Promise<any>
|
getContacts(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/chat-contacts')
|
this._httpClient.get('api/chat-contacts')
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
resolve(response);
|
resolve(response);
|
||||||
}, reject);
|
}, reject);
|
||||||
|
@ -217,13 +239,14 @@ export class ChatService implements Resolve<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Chats
|
* Get chats
|
||||||
|
*
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
getChats(): Promise<any>
|
getChats(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/chat-chats')
|
this._httpClient.get('api/chat-chats')
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
resolve(response);
|
resolve(response);
|
||||||
}, reject);
|
}, reject);
|
||||||
|
@ -231,13 +254,14 @@ export class ChatService implements Resolve<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get User
|
* Get user
|
||||||
|
*
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
getUser(): Promise<any>
|
getUser(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/chat-user')
|
this._httpClient.get('api/chat-user')
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
resolve(response[0]);
|
resolve(response[0]);
|
||||||
}, reject);
|
}, reject);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<mat-toolbar matDialogTitle class="mat-accent m-0">
|
<mat-toolbar matDialogTitle class="mat-accent m-0">
|
||||||
<mat-toolbar-row fxLayout="row" fxLayoutAlign="space-between center">
|
<mat-toolbar-row fxLayout="row" fxLayoutAlign="space-between center">
|
||||||
<span class="title dialog-title">{{dialogTitle}}</span>
|
<span class="title dialog-title">{{dialogTitle}}</span>
|
||||||
<button mat-icon-button (click)="dialogRef.close()" aria-label="Close dialog">
|
<button mat-icon-button (click)="_matDialogRef.close()" aria-label="Close dialog">
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-toolbar-row>
|
</mat-toolbar-row>
|
||||||
|
@ -98,7 +98,7 @@
|
||||||
|
|
||||||
<button *ngIf="action !=='edit'"
|
<button *ngIf="action !=='edit'"
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
(click)="dialogRef.close(contactForm)"
|
(click)="_matDialogRef.close(contactForm)"
|
||||||
class="save-button mat-accent"
|
class="save-button mat-accent"
|
||||||
[disabled]="contactForm.invalid"
|
[disabled]="contactForm.invalid"
|
||||||
aria-label="SAVE">
|
aria-label="SAVE">
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
|
|
||||||
<button *ngIf="action ==='edit'"
|
<button *ngIf="action ==='edit'"
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
(click)="dialogRef.close(['save',contactForm])"
|
(click)="_matDialogRef.close(['save',contactForm])"
|
||||||
class="save-button mat-accent"
|
class="save-button mat-accent"
|
||||||
[disabled]="contactForm.invalid"
|
[disabled]="contactForm.invalid"
|
||||||
aria-label="SAVE">
|
aria-label="SAVE">
|
||||||
|
@ -116,7 +116,7 @@
|
||||||
|
|
||||||
<button *ngIf="action ==='edit'"
|
<button *ngIf="action ==='edit'"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="dialogRef.close(['delete',contactForm])"
|
(click)="_matDialogRef.close(['delete',contactForm])"
|
||||||
aria-label="Delete"
|
aria-label="Delete"
|
||||||
matTooltip="Delete">
|
matTooltip="Delete">
|
||||||
<mat-icon>delete</mat-icon>
|
<mat-icon>delete</mat-icon>
|
||||||
|
|
|
@ -21,16 +21,17 @@ export class ContactsContactFormDialogComponent
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param {MatDialogRef<ContactsContactFormDialogComponent>} _dialogRef
|
* @param {MatDialogRef<ContactsContactFormDialogComponent>} _matDialogRef
|
||||||
* @param _data
|
* @param _data
|
||||||
* @param {FormBuilder} _formBuilder
|
* @param {FormBuilder} _formBuilder
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private _dialogRef: MatDialogRef<ContactsContactFormDialogComponent>,
|
private _matDialogRef: MatDialogRef<ContactsContactFormDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) private _data: any,
|
@Inject(MAT_DIALOG_DATA) private _data: any,
|
||||||
private _formBuilder: FormBuilder
|
private _formBuilder: FormBuilder
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
this.action = _data.action;
|
this.action = _data.action;
|
||||||
|
|
||||||
if ( this.action === 'edit' )
|
if ( this.action === 'edit' )
|
||||||
|
|
|
@ -33,7 +33,7 @@ export class ContactsComponent implements OnInit, OnDestroy
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private _contactsService: ContactsService,
|
private _contactsService: ContactsService,
|
||||||
public _matDialog: MatDialog
|
private _matDialog: MatDialog
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Set the defaults
|
// Set the defaults
|
||||||
|
|
|
@ -10,11 +10,11 @@ import { Contact } from 'app/main/apps/contacts/contact.model';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ContactsService implements Resolve<any>
|
export class ContactsService implements Resolve<any>
|
||||||
{
|
{
|
||||||
onContactsChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onContactsChanged: BehaviorSubject<any>;
|
||||||
onSelectedContactsChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onSelectedContactsChanged: BehaviorSubject<any>;
|
||||||
onUserDataChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onUserDataChanged: BehaviorSubject<any>;
|
||||||
onSearchTextChanged: Subject<any> = new Subject();
|
onSearchTextChanged: Subject<any>;
|
||||||
onFilterChanged: Subject<any> = new Subject();
|
onFilterChanged: Subject<any>;
|
||||||
|
|
||||||
contacts: Contact[];
|
contacts: Contact[];
|
||||||
user: any;
|
user: any;
|
||||||
|
@ -32,6 +32,12 @@ export class ContactsService implements Resolve<any>
|
||||||
private _httpClient: HttpClient
|
private _httpClient: HttpClient
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onContactsChanged = new BehaviorSubject([]);
|
||||||
|
this.onSelectedContactsChanged = new BehaviorSubject([]);
|
||||||
|
this.onUserDataChanged = new BehaviorSubject([]);
|
||||||
|
this.onSearchTextChanged = new Subject();
|
||||||
|
this.onFilterChanged = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { Order } from 'app/main/apps/e-commerce/order/order.model';
|
||||||
import { EcommerceOrderService } from 'app/main/apps/e-commerce/order/order.service';
|
import { EcommerceOrderService } from 'app/main/apps/e-commerce/order/order.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-e-commerce-order',
|
selector : 'e-commerce-order',
|
||||||
templateUrl : './order.component.html',
|
templateUrl : './order.component.html',
|
||||||
styleUrls : ['./order.component.scss'],
|
styleUrls : ['./order.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None,
|
||||||
|
|
|
@ -8,7 +8,7 @@ export class EcommerceOrderService implements Resolve<any>
|
||||||
{
|
{
|
||||||
routeParams: any;
|
routeParams: any;
|
||||||
order: any;
|
order: any;
|
||||||
onOrderChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
onOrderChanged: BehaviorSubject<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -19,6 +19,8 @@ export class EcommerceOrderService implements Resolve<any>
|
||||||
private _httpClient: HttpClient
|
private _httpClient: HttpClient
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onOrderChanged = new BehaviorSubject({});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
export class EcommerceOrdersService implements Resolve<any>
|
export class EcommerceOrdersService implements Resolve<any>
|
||||||
{
|
{
|
||||||
orders: any[];
|
orders: any[];
|
||||||
onOrdersChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
onOrdersChanged: BehaviorSubject<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -18,6 +18,8 @@ export class EcommerceOrdersService implements Resolve<any>
|
||||||
private _httpClient: HttpClient
|
private _httpClient: HttpClient
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onOrdersChanged = new BehaviorSubject({});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,7 +8,7 @@ export class EcommerceProductService implements Resolve<any>
|
||||||
{
|
{
|
||||||
routeParams: any;
|
routeParams: any;
|
||||||
product: any;
|
product: any;
|
||||||
onProductChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
onProductChanged: BehaviorSubject<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -19,6 +19,8 @@ export class EcommerceProductService implements Resolve<any>
|
||||||
private _httpClient: HttpClient
|
private _httpClient: HttpClient
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onProductChanged = new BehaviorSubject({});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
export class EcommerceProductsService implements Resolve<any>
|
export class EcommerceProductsService implements Resolve<any>
|
||||||
{
|
{
|
||||||
products: any[];
|
products: any[];
|
||||||
onProductsChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
onProductsChanged: BehaviorSubject<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -18,6 +18,8 @@ export class EcommerceProductsService implements Resolve<any>
|
||||||
private _httpClient: HttpClient
|
private _httpClient: HttpClient
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onProductsChanged = new BehaviorSubject({});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,8 +6,8 @@ import { Observable, BehaviorSubject } from 'rxjs';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class FileManagerService implements Resolve<any>
|
export class FileManagerService implements Resolve<any>
|
||||||
{
|
{
|
||||||
onFilesChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
onFilesChanged: BehaviorSubject<any>;
|
||||||
onFileSelected: BehaviorSubject<any> = new BehaviorSubject({});
|
onFileSelected: BehaviorSubject<any>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -18,6 +18,9 @@ export class FileManagerService implements Resolve<any>
|
||||||
private _httpClient: HttpClient
|
private _httpClient: HttpClient
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onFilesChanged = new BehaviorSubject({});
|
||||||
|
this.onFileSelected = new BehaviorSubject({});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<mat-toolbar class="mat-accent m-0">
|
<mat-toolbar class="mat-accent m-0">
|
||||||
<mat-toolbar-row fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
<mat-toolbar-row fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||||
<span class="title dialog-title">New Message</span>
|
<span class="title dialog-title">New Message</span>
|
||||||
<button mat-icon-button (click)="dialogRef.close()" aria-label="Close dialog">
|
<button mat-icon-button (click)="_matDialogRef.close()" aria-label="Close dialog">
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-toolbar-row>
|
</mat-toolbar-row>
|
||||||
|
@ -86,7 +86,7 @@
|
||||||
<div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="space-between center">
|
<div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="space-between center">
|
||||||
<div>
|
<div>
|
||||||
<button mat-raised-button
|
<button mat-raised-button
|
||||||
(click)="dialogRef.close(['send',composeForm])"
|
(click)="_matDialogRef.close(['send',composeForm])"
|
||||||
class="save-button mat-accent"
|
class="save-button mat-accent"
|
||||||
[disabled]="composeForm.invalid"
|
[disabled]="composeForm.invalid"
|
||||||
aria-label="SAVE">
|
aria-label="SAVE">
|
||||||
|
@ -98,7 +98,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button mat-icon-button (click)="dialogRef.close(['delete',composeForm])" aria-label="Delete"
|
<button mat-icon-button (click)="_matDialogRef.close(['delete',composeForm])" aria-label="Delete"
|
||||||
matTooltip="Delete">
|
matTooltip="Delete">
|
||||||
<mat-icon>delete</mat-icon>
|
<mat-icon>delete</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -3,27 +3,44 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-compose',
|
selector : 'mail-compose',
|
||||||
templateUrl : './compose.component.html',
|
templateUrl : './compose.component.html',
|
||||||
styleUrls : ['./compose.component.scss'],
|
styleUrls : ['./compose.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class FuseMailNgrxComposeDialogComponent
|
export class MailNgrxComposeDialogComponent
|
||||||
{
|
{
|
||||||
composeForm: FormGroup;
|
composeForm: FormGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {MatDialogRef<MailNgrxComposeDialogComponent>} _matDialogRef
|
||||||
|
* @param _data
|
||||||
|
* @param {FormBuilder} _formBuilder
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<FuseMailNgrxComposeDialogComponent>,
|
private _matDialogRef: MatDialogRef<MailNgrxComposeDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) private data: any,
|
@Inject(MAT_DIALOG_DATA) private _data: any,
|
||||||
private formBuilder: FormBuilder
|
private _formBuilder: FormBuilder
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
this.composeForm = this.createComposeForm();
|
this.composeForm = this.createComposeForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
createComposeForm()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create compose form
|
||||||
|
*
|
||||||
|
* @returns {FormGroup}
|
||||||
|
*/
|
||||||
|
createComposeForm(): FormGroup
|
||||||
{
|
{
|
||||||
return this.formBuilder.group({
|
return this._formBuilder.group({
|
||||||
from : {
|
from : {
|
||||||
value : ['johndoe@creapond.com'],
|
value : ['johndoe@creapond.com'],
|
||||||
disabled: [true]
|
disabled: [true]
|
||||||
|
|
|
@ -2,38 +2,62 @@ import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/c
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
import { Mail } from '../mail.model';
|
import { Mail } from 'app/main/apps/mail-ngrx/mail.model';
|
||||||
import * as fromStore from '../store';
|
import * as fromStore from 'app/main/apps/mail-ngrx/store';
|
||||||
import { MailNgrxService } from '../mail.service';
|
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-details',
|
selector : 'mail-details',
|
||||||
templateUrl : './mail-details.component.html',
|
templateUrl : './mail-details.component.html',
|
||||||
styleUrls : ['./mail-details.component.scss'],
|
styleUrls : ['./mail-details.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class FuseMailNgrxDetailsComponent implements OnChanges
|
export class MailNgrxDetailsComponent implements OnChanges
|
||||||
{
|
{
|
||||||
labels$: Observable<any>;
|
@Input('mail')
|
||||||
@Input('mail') mailInput: Mail;
|
mailInput: Mail;
|
||||||
mail: Mail;
|
|
||||||
showDetails = false;
|
|
||||||
|
|
||||||
|
labels$: Observable<any>;
|
||||||
|
mail: Mail;
|
||||||
|
showDetails: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {MailNgrxService} _mailNgrxService
|
||||||
|
* @param {Store<MailAppState>} _store
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private mailService: MailNgrxService,
|
private _mailNgrxService: MailNgrxService,
|
||||||
private store: Store<fromStore.MailAppState>
|
private _store: Store<fromStore.MailAppState>
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.labels$ = this.store.select(fromStore.getLabelsArr);
|
// Set the defaults
|
||||||
|
this.labels$ = this._store.select(fromStore.getLabelsArr);
|
||||||
|
this.showDetails = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On changes
|
||||||
|
*/
|
||||||
|
ngOnChanges(): void
|
||||||
{
|
{
|
||||||
this.updateModel(this.mailInput);
|
this.updateModel(this.mailInput);
|
||||||
this.markAsRead();
|
this.markAsRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
markAsRead()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark as read
|
||||||
|
*/
|
||||||
|
markAsRead(): void
|
||||||
{
|
{
|
||||||
if ( this.mail && !this.mail.read )
|
if ( this.mail && !this.mail.read )
|
||||||
{
|
{
|
||||||
|
@ -42,28 +66,46 @@ export class FuseMailNgrxDetailsComponent implements OnChanges
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleStar(event)
|
/**
|
||||||
|
* Toggle star
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
toggleStar(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.mail.toggleStar();
|
this.mail.toggleStar();
|
||||||
this.updateMail();
|
this.updateMail();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleImportant(event)
|
/**
|
||||||
|
* Toggle important
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
toggleImportant(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.mail.toggleImportant();
|
this.mail.toggleImportant();
|
||||||
this.updateMail();
|
this.updateMail();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateModel(data)
|
/**
|
||||||
|
* Update model
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
updateModel(data): void
|
||||||
{
|
{
|
||||||
this.mail = !data ? null : new Mail({...data});
|
this.mail = !data ? null : new Mail({...data});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMail()
|
/**
|
||||||
|
* Update the mail
|
||||||
|
*/
|
||||||
|
updateMail(): void
|
||||||
{
|
{
|
||||||
this.store.dispatch(new fromStore.UpdateMail(this.mail));
|
this._store.dispatch(new fromStore.UpdateMail(this.mail));
|
||||||
this.updateModel(this.mail);
|
this.updateModel(this.mail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,12 @@ import { Mail } from '../../mail.model';
|
||||||
import * as fromStore from '../../store';
|
import * as fromStore from '../../store';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-list-item',
|
selector : 'mail-list-item',
|
||||||
templateUrl : './mail-list-item.component.html',
|
templateUrl : './mail-list-item.component.html',
|
||||||
styleUrls : ['./mail-list-item.component.scss'],
|
styleUrls : ['./mail-list-item.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class FuseMailNgrxListItemComponent implements OnInit
|
export class MailNgrxListItemComponent implements OnInit
|
||||||
{
|
{
|
||||||
@Input() mail: Mail;
|
@Input() mail: Mail;
|
||||||
@HostBinding('class.selected') selected: boolean;
|
@HostBinding('class.selected') selected: boolean;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mail-list">
|
<div class="mail-list">
|
||||||
<fuse-mail-list-item matRipple *ngFor="let mail of mails" [mail]="mail" (click)="readMail(mail.id)"
|
<mail-list-item matRipple *ngFor="let mail of mails" [mail]="mail" (click)="readMail(mail.id)"
|
||||||
[ngClass]="{'current-mail':mail?.id == currentMail?.id}">
|
[ngClass]="{'current-mail':mail?.id == currentMail?.id}">
|
||||||
</fuse-mail-list-item>
|
</mail-list-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,49 +1,64 @@
|
||||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
|
||||||
import { Mail } from '../mail.model';
|
import { Mail } from 'app/main/apps/mail-ngrx/mail.model';
|
||||||
import { MailNgrxService } from '../mail.service';
|
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-list',
|
selector : 'mail-list',
|
||||||
templateUrl : './mail-list.component.html',
|
templateUrl : './mail-list.component.html',
|
||||||
styleUrls : ['./mail-list.component.scss'],
|
styleUrls : ['./mail-list.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class FuseMailNgrxListComponent
|
export class MailNgrxListComponent
|
||||||
{
|
{
|
||||||
@Input() mails: Mail[];
|
@Input()
|
||||||
@Input() currentMail: Mail[];
|
mails: Mail[];
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
currentMail: Mail[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {ActivatedRoute} _activatedRoute
|
||||||
|
* @param {MailNgrxService} _mailNgrxService
|
||||||
|
* @param {Router} _router
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private _activatedRoute: ActivatedRoute,
|
||||||
private mailService: MailNgrxService,
|
private _mailNgrxService: MailNgrxService,
|
||||||
private router: Router
|
private _router: Router
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read mail
|
* Read mail
|
||||||
|
*
|
||||||
* @param mailId
|
* @param mailId
|
||||||
*/
|
*/
|
||||||
readMail(mailId)
|
readMail(mailId): void
|
||||||
{
|
{
|
||||||
const labelHandle = this.route.snapshot.params.labelHandle,
|
const labelHandle = this._activatedRoute.snapshot.params.labelHandle,
|
||||||
filterHandle = this.route.snapshot.params.filterHandle,
|
filterHandle = this._activatedRoute.snapshot.params.filterHandle,
|
||||||
folderHandle = this.route.snapshot.params.folderHandle;
|
folderHandle = this._activatedRoute.snapshot.params.folderHandle;
|
||||||
|
|
||||||
if ( labelHandle )
|
if ( labelHandle )
|
||||||
{
|
{
|
||||||
this.router.navigate(['apps/mail-ngrx/label/' + labelHandle + '/' + mailId]);
|
this._router.navigate(['apps/mail-ngrx/label/' + labelHandle + '/' + mailId]);
|
||||||
}
|
}
|
||||||
else if ( filterHandle )
|
else if ( filterHandle )
|
||||||
{
|
{
|
||||||
this.router.navigate(['apps/mail-ngrx/filter/' + filterHandle + '/' + mailId]);
|
this._router.navigate(['apps/mail-ngrx/filter/' + filterHandle + '/' + mailId]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.router.navigate(['apps/mail-ngrx/' + folderHandle + '/' + mailId]);
|
this._router.navigate(['apps/mail-ngrx/' + folderHandle + '/' + mailId]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<!-- SIDENAV -->
|
<!-- SIDENAV -->
|
||||||
<mat-sidenav class="sidenav mat-sidenav-opened" position="start" mode="side" opened="true"
|
<mat-sidenav class="sidenav mat-sidenav-opened" position="start" mode="side" opened="true"
|
||||||
fuseMatSidenavHelper="carded-left-sidenav" mat-is-locked-open="gt-md">
|
fuseMatSidenavHelper="carded-left-sidenav" mat-is-locked-open="gt-md">
|
||||||
<fuse-mail-main-sidenav></fuse-mail-main-sidenav>
|
<mail-main-sidenav></mail-main-sidenav>
|
||||||
</mat-sidenav>
|
</mat-sidenav>
|
||||||
<!-- / SIDENAV -->
|
<!-- / SIDENAV -->
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="currentMail$ | async" fxHide.gt-xs>
|
<div *ngIf="currentMail$ | async" fxHide.gt-xs>
|
||||||
<button mat-icon-button (click)="deSelectCurrentMail()">
|
<button mat-icon-button (click)="deselectCurrentMail()">
|
||||||
<mat-icon>arrow_back</mat-icon>
|
<mat-icon>arrow_back</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -98,8 +98,8 @@
|
||||||
<!-- CONTENT -->
|
<!-- CONTENT -->
|
||||||
<div class="content" fxLayout="row">
|
<div class="content" fxLayout="row">
|
||||||
|
|
||||||
<fuse-mail-list fusePerfectScrollbar fxFlex [mails]="mails$ | async" [currentMail]="currentMail$ | async"></fuse-mail-list>
|
<mail-list fusePerfectScrollbar fxFlex [mails]="mails$ | async" [currentMail]="currentMail$ | async"></mail-list>
|
||||||
<fuse-mail-details [mail]="currentMail$ | async" fusePerfectScrollbar fxFlex></fuse-mail-details>
|
<mail-details [mail]="currentMail$ | async" fusePerfectScrollbar fxFlex></mail-details>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- / CONTENT -->
|
<!-- / CONTENT -->
|
||||||
|
|
|
@ -40,16 +40,16 @@
|
||||||
|
|
||||||
@include media-breakpoint(xs) {
|
@include media-breakpoint(xs) {
|
||||||
|
|
||||||
fuse-mail-list {
|
mail-list {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse-mail-list,
|
mail-list,
|
||||||
fuse-mail-details {
|
mail-details {
|
||||||
flex: 1 0 100%;
|
flex: 1 0 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse-mail-details {
|
mail-details {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,11 +65,11 @@
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
|
||||||
fuse-mail-list {
|
mail-list {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse-mail-details {
|
mail-details {
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,16 +10,17 @@ import { FuseConfigService } from '@fuse/services/config.service';
|
||||||
import { Mail } from 'app/main/apps/mail-ngrx/mail.model';
|
import { Mail } from 'app/main/apps/mail-ngrx/mail.model';
|
||||||
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
||||||
import * as fromStore from 'app/main/apps/mail-ngrx/store';
|
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 english } from 'app/main/apps/mail-ngrx/i18n/en';
|
||||||
import { locale as turkish } from 'app/main/apps/mail-ngrx/i18n/tr';
|
import { locale as turkish } from 'app/main/apps/mail-ngrx/i18n/tr';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail',
|
selector : 'mail-ngrx',
|
||||||
templateUrl : './mail.component.html',
|
templateUrl : './mail.component.html',
|
||||||
styleUrls : ['./mail.component.scss'],
|
styleUrls : ['./mail.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class FuseMailNgrxComponent implements OnInit, OnDestroy
|
export class MailNgrxComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
hasSelectedMails: boolean;
|
hasSelectedMails: boolean;
|
||||||
isIndeterminate: boolean;
|
isIndeterminate: boolean;
|
||||||
|
@ -33,31 +34,49 @@ export class FuseMailNgrxComponent implements OnInit, OnDestroy
|
||||||
mails: Mail[];
|
mails: Mail[];
|
||||||
selectedMailIds: string[];
|
selectedMailIds: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {FuseConfigService} _fuseConfigService
|
||||||
|
* @param {MailNgrxService} _mailNgrxService
|
||||||
|
* @param {FuseTranslationLoaderService} _fuseTranslationLoaderService
|
||||||
|
* @param {Store<MailAppState>} _store
|
||||||
|
* @param {ChangeDetectorRef} _changeDetectorRef
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private configService: FuseConfigService,
|
private _fuseConfigService: FuseConfigService,
|
||||||
private mailService: MailNgrxService,
|
private _mailNgrxService: MailNgrxService,
|
||||||
private translationLoader: FuseTranslationLoaderService,
|
private _fuseTranslationLoaderService: FuseTranslationLoaderService,
|
||||||
private store: Store<fromStore.MailAppState>,
|
private _store: Store<fromStore.MailAppState>,
|
||||||
private cd: ChangeDetectorRef
|
private _changeDetectorRef: ChangeDetectorRef
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.searchInput = new FormControl('');
|
// Configure the layout
|
||||||
this.translationLoader.loadTranslations(english, turkish);
|
this._fuseConfigService.config = {
|
||||||
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 = [];
|
|
||||||
|
|
||||||
this.configService.config = {
|
|
||||||
routerAnimation: 'none'
|
routerAnimation: 'none'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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 = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.mails$.subscribe(mails => {
|
this.mails$.subscribe(mails => {
|
||||||
this.mails = mails;
|
this.mails = mails;
|
||||||
|
@ -79,16 +98,28 @@ export class FuseMailNgrxComponent implements OnInit, OnDestroy
|
||||||
debounceTime(300),
|
debounceTime(300),
|
||||||
distinctUntilChanged()
|
distinctUntilChanged()
|
||||||
).subscribe(searchText => {
|
).subscribe(searchText => {
|
||||||
this.store.dispatch(new fromStore.SetSearchText(searchText));
|
this._store.dispatch(new fromStore.SetSearchText(searchText));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.cd.detach();
|
this._changeDetectorRef.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSelectAll(ev)
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle select all
|
||||||
|
*
|
||||||
|
* @param ev
|
||||||
|
*/
|
||||||
|
toggleSelectAll(ev): void
|
||||||
{
|
{
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
|
||||||
|
@ -102,41 +133,69 @@ export class FuseMailNgrxComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectAllMails()
|
/**
|
||||||
|
* Select all mails
|
||||||
|
*/
|
||||||
|
selectAllMails(): void
|
||||||
{
|
{
|
||||||
this.store.dispatch(new fromStore.SelectAllMails());
|
this._store.dispatch(new fromStore.SelectAllMails());
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectAllMails()
|
/**
|
||||||
|
* Deselect all mails
|
||||||
|
*/
|
||||||
|
deselectAllMails(): void
|
||||||
{
|
{
|
||||||
this.store.dispatch(new fromStore.DeselectAllMails());
|
this._store.dispatch(new fromStore.DeselectAllMails());
|
||||||
}
|
}
|
||||||
|
|
||||||
selectMailsByParameter(parameter, value)
|
/**
|
||||||
|
* Select mails by parameter
|
||||||
|
*
|
||||||
|
* @param parameter
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
selectMailsByParameter(parameter, value): void
|
||||||
{
|
{
|
||||||
this.store.dispatch(new fromStore.SelectMailsByParameter({
|
this._store.dispatch(new fromStore.SelectMailsByParameter({
|
||||||
parameter,
|
parameter,
|
||||||
value
|
value
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleLabelOnSelectedMails(labelId)
|
/**
|
||||||
|
* Toggle label on selected mails
|
||||||
|
*
|
||||||
|
* @param labelId
|
||||||
|
*/
|
||||||
|
toggleLabelOnSelectedMails(labelId): void
|
||||||
{
|
{
|
||||||
this.store.dispatch(new fromStore.AddLabelOnSelectedMails(labelId));
|
this._store.dispatch(new fromStore.AddLabelOnSelectedMails(labelId));
|
||||||
}
|
}
|
||||||
|
|
||||||
setFolderOnSelectedMails(folderId)
|
/**
|
||||||
|
* Set folder on selected mails
|
||||||
|
*
|
||||||
|
* @param folderId
|
||||||
|
*/
|
||||||
|
setFolderOnSelectedMails(folderId): void
|
||||||
{
|
{
|
||||||
this.store.dispatch(new fromStore.SetFolderOnSelectedMails(folderId));
|
this._store.dispatch(new fromStore.SetFolderOnSelectedMails(folderId));
|
||||||
}
|
}
|
||||||
|
|
||||||
deSelectCurrentMail()
|
/**
|
||||||
|
* Deselect current mail
|
||||||
|
*/
|
||||||
|
deselectCurrentMail(): void
|
||||||
{
|
{
|
||||||
this.store.dispatch(new fromStore.SetCurrentMail(''));
|
this._store.dispatch(new fromStore.SetCurrentMail(''));
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh()
|
/**
|
||||||
|
* Refresh
|
||||||
|
*/
|
||||||
|
refresh(): void
|
||||||
{
|
{
|
||||||
this.cd.markForCheck();
|
this._changeDetectorRef.markForCheck();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,11 @@ export class Mail
|
||||||
labels: string[];
|
labels: string[];
|
||||||
folder: string;
|
folder: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param mail
|
||||||
|
*/
|
||||||
constructor(mail)
|
constructor(mail)
|
||||||
{
|
{
|
||||||
this.id = mail.id;
|
this.id = mail.id;
|
||||||
|
@ -44,22 +49,34 @@ export class Mail
|
||||||
this.folder = mail.folder;
|
this.folder = mail.folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleStar()
|
/**
|
||||||
|
* Toggle star
|
||||||
|
*/
|
||||||
|
toggleStar(): void
|
||||||
{
|
{
|
||||||
this.starred = !this.starred;
|
this.starred = !this.starred;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleImportant()
|
/**
|
||||||
|
* Toggle important
|
||||||
|
*/
|
||||||
|
toggleImportant(): void
|
||||||
{
|
{
|
||||||
this.important = !this.important;
|
this.important = !this.important;
|
||||||
}
|
}
|
||||||
|
|
||||||
markRead()
|
/**
|
||||||
|
* Mark as read
|
||||||
|
*/
|
||||||
|
markRead(): void
|
||||||
{
|
{
|
||||||
this.read = true;
|
this.read = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
markUnRead()
|
/**
|
||||||
|
* Mark as unread
|
||||||
|
*/
|
||||||
|
markUnread(): void
|
||||||
{
|
{
|
||||||
this.read = false;
|
this.read = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,45 +5,45 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { FuseSharedModule } from '@fuse/shared.module';
|
import { FuseSharedModule } from '@fuse/shared.module';
|
||||||
|
|
||||||
import { MailAppStoreModule } from 'app/main/apps/mail-ngrx/store/store.module';
|
|
||||||
import * as fromGuards from 'app/main/apps/mail-ngrx/store/guards/index';
|
import * as fromGuards from 'app/main/apps/mail-ngrx/store/guards/index';
|
||||||
import { FuseMailNgrxComponent } from 'app/main/apps/mail-ngrx/mail.component';
|
import { MailNgrxStoreModule } from 'app/main/apps/mail-ngrx/store/store.module';
|
||||||
import { FuseMailNgrxListComponent } from 'app/main/apps/mail-ngrx/mail-list/mail-list.component';
|
import { MailNgrxComponent } from 'app/main/apps/mail-ngrx/mail.component';
|
||||||
import { FuseMailNgrxListItemComponent } from 'app/main/apps/mail-ngrx/mail-list/mail-list-item/mail-list-item.component';
|
import { MailNgrxListComponent } from 'app/main/apps/mail-ngrx/mail-list/mail-list.component';
|
||||||
import { FuseMailNgrxDetailsComponent } from 'app/main/apps/mail-ngrx/mail-details/mail-details.component';
|
import { MailNgrxListItemComponent } from 'app/main/apps/mail-ngrx/mail-list/mail-list-item/mail-list-item.component';
|
||||||
import { FuseMailNgrxMainSidenavComponent } from 'app/main/apps/mail-ngrx/sidenavs/main/main-sidenav.component';
|
import { MailNgrxDetailsComponent } from 'app/main/apps/mail-ngrx/mail-details/mail-details.component';
|
||||||
import { FuseMailNgrxComposeDialogComponent } from 'app/main/apps/mail-ngrx/dialogs/compose/compose.component';
|
import { MailNgrxMainSidenavComponent } from 'app/main/apps/mail-ngrx/sidenavs/main/main-sidenav.component';
|
||||||
|
import { MailNgrxComposeDialogComponent } from 'app/main/apps/mail-ngrx/dialogs/compose/compose.component';
|
||||||
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path : 'label/:labelHandle',
|
path : 'label/:labelHandle',
|
||||||
component : FuseMailNgrxComponent,
|
component : MailNgrxComponent,
|
||||||
canActivate: [fromGuards.ResolveGuard]
|
canActivate: [fromGuards.ResolveGuard]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'label/:labelHandle/:mailId',
|
path : 'label/:labelHandle/:mailId',
|
||||||
component : FuseMailNgrxComponent,
|
component : MailNgrxComponent,
|
||||||
canActivate: [fromGuards.ResolveGuard]
|
canActivate: [fromGuards.ResolveGuard]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'filter/:filterHandle',
|
path : 'filter/:filterHandle',
|
||||||
component: FuseMailNgrxComponent,
|
component : MailNgrxComponent,
|
||||||
canActivate: [fromGuards.ResolveGuard]
|
canActivate: [fromGuards.ResolveGuard]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'filter/:filterHandle/:mailId',
|
path : 'filter/:filterHandle/:mailId',
|
||||||
component: FuseMailNgrxComponent,
|
component : MailNgrxComponent,
|
||||||
canActivate: [fromGuards.ResolveGuard]
|
canActivate: [fromGuards.ResolveGuard]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : ':folderHandle',
|
path : ':folderHandle',
|
||||||
component: FuseMailNgrxComponent,
|
component : MailNgrxComponent,
|
||||||
canActivate: [fromGuards.ResolveGuard]
|
canActivate: [fromGuards.ResolveGuard]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : ':folderHandle/:mailId',
|
path : ':folderHandle/:mailId',
|
||||||
component: FuseMailNgrxComponent,
|
component : MailNgrxComponent,
|
||||||
canActivate: [fromGuards.ResolveGuard]
|
canActivate: [fromGuards.ResolveGuard]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -54,12 +54,12 @@ const routes: Routes = [
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations : [
|
declarations : [
|
||||||
FuseMailNgrxComponent,
|
MailNgrxComponent,
|
||||||
FuseMailNgrxListComponent,
|
MailNgrxListComponent,
|
||||||
FuseMailNgrxListItemComponent,
|
MailNgrxListItemComponent,
|
||||||
FuseMailNgrxDetailsComponent,
|
MailNgrxDetailsComponent,
|
||||||
FuseMailNgrxMainSidenavComponent,
|
MailNgrxMainSidenavComponent,
|
||||||
FuseMailNgrxComposeDialogComponent
|
MailNgrxComposeDialogComponent
|
||||||
],
|
],
|
||||||
imports : [
|
imports : [
|
||||||
RouterModule.forChild(routes),
|
RouterModule.forChild(routes),
|
||||||
|
@ -80,13 +80,13 @@ const routes: Routes = [
|
||||||
|
|
||||||
FuseSharedModule,
|
FuseSharedModule,
|
||||||
|
|
||||||
MailAppStoreModule
|
MailNgrxStoreModule
|
||||||
],
|
],
|
||||||
providers : [
|
providers : [
|
||||||
MailNgrxService,
|
MailNgrxService,
|
||||||
fromGuards.ResolveGuard
|
fromGuards.ResolveGuard
|
||||||
],
|
],
|
||||||
entryComponents: [FuseMailNgrxComposeDialogComponent]
|
entryComponents: [MailNgrxComposeDialogComponent]
|
||||||
})
|
})
|
||||||
export class FuseMailNgrxModule
|
export class FuseMailNgrxModule
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,72 +16,108 @@ export class MailNgrxService
|
||||||
selectedMails: Mail[];
|
selectedMails: Mail[];
|
||||||
mails: Mail[];
|
mails: Mail[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {HttpClient} _httpClient
|
||||||
|
* @param {Store<MailAppState>} _store
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private http: HttpClient,
|
private _httpClient: HttpClient,
|
||||||
private store: Store<MailAppState>
|
private _store: Store<MailAppState>
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.store.select(getFoldersArr).subscribe(folders => {
|
this._store.select(getFoldersArr).subscribe(folders => {
|
||||||
this.foldersArr = folders;
|
this.foldersArr = folders;
|
||||||
});
|
});
|
||||||
this.store.select(getFiltersArr).subscribe(filters => {
|
|
||||||
|
this._store.select(getFiltersArr).subscribe(filters => {
|
||||||
this.filtersArr = filters;
|
this.filtersArr = filters;
|
||||||
});
|
});
|
||||||
this.store.select(getLabelsArr).subscribe(labels => {
|
|
||||||
|
this._store.select(getLabelsArr).subscribe(labels => {
|
||||||
this.labelsArr = labels;
|
this.labelsArr = labels;
|
||||||
});
|
});
|
||||||
this.store.select(getMailsArr).subscribe(mails => {
|
|
||||||
|
this._store.select(getMailsArr).subscribe(mails => {
|
||||||
this.mails = mails;
|
this.mails = mails;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.selectedMails = [];
|
this.selectedMails = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all mails
|
||||||
|
*
|
||||||
|
* @returns {Observable<Mail[]>}
|
||||||
|
*/
|
||||||
getAllMails(): Observable<Mail[]>
|
getAllMails(): Observable<Mail[]>
|
||||||
{
|
{
|
||||||
return this.http.get<Mail[]>('api/mail-mails');
|
return this._httpClient.get<Mail[]>('api/mail-mails');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get folders
|
||||||
|
*
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
getFolders(): Observable<any>
|
getFolders(): Observable<any>
|
||||||
{
|
{
|
||||||
return this.http.get('api/mail-folders');
|
return this._httpClient.get('api/mail-folders');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get filters
|
||||||
|
*
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
getFilters(): Observable<any>
|
getFilters(): Observable<any>
|
||||||
{
|
{
|
||||||
return this.http.get('api/mail-filters');
|
return this._httpClient.get('api/mail-filters');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get labels
|
||||||
|
*
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
getLabels(): Observable<any>
|
getLabels(): Observable<any>
|
||||||
{
|
{
|
||||||
return this.http.get('api/mail-labels');
|
return this._httpClient.get('api/mail-labels');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get mails
|
||||||
|
*
|
||||||
|
* @param handle
|
||||||
|
* @returns {Observable<Mail[]>}
|
||||||
|
*/
|
||||||
getMails(handle): Observable<Mail[]>
|
getMails(handle): Observable<Mail[]>
|
||||||
{
|
{
|
||||||
if ( handle.id === 'labelHandle' )
|
if ( handle.id === 'labelHandle' )
|
||||||
{
|
{
|
||||||
const labelId = this.labelsArr.find(label => label.handle === handle.value).id;
|
const labelId = this.labelsArr.find(label => label.handle === handle.value).id;
|
||||||
return this.http.get<Mail[]>('api/mail-mails?labels=' + labelId);
|
return this._httpClient.get<Mail[]>('api/mail-mails?labels=' + labelId);
|
||||||
}
|
}
|
||||||
else if ( handle.id === 'filterHandle' )
|
else if ( handle.id === 'filterHandle' )
|
||||||
{
|
{
|
||||||
return this.http.get<Mail[]>('api/mail-mails?' + handle.value + '=true');
|
return this._httpClient.get<Mail[]>('api/mail-mails?' + handle.value + '=true');
|
||||||
}
|
}
|
||||||
else // folderHandle
|
else // folderHandle
|
||||||
{
|
{
|
||||||
const folderId = this.foldersArr.find(folder => folder.handle === handle.value).id;
|
const folderId = this.foldersArr.find(folder => folder.handle === handle.value).id;
|
||||||
return this.http.get<any>('api/mail-mails?folder=' + folderId);
|
return this._httpClient.get<any>('api/mail-mails?folder=' + folderId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the mail
|
* Update the mail
|
||||||
|
*
|
||||||
* @param mail
|
* @param mail
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
updateMail(mail)
|
updateMail(mail): any
|
||||||
{
|
{
|
||||||
return this.http.post('api/mail-mails/' + mail.id, {...mail});
|
return this._httpClient.post('api/mail-mails/' + mail.id, {...mail});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,17 @@ import { FormGroup } from '@angular/forms';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
import { MailNgrxService } from '../../mail.service';
|
import { MailNgrxService } from 'app/main/apps/mail-ngrx/mail.service';
|
||||||
import * as fromStore from './../../store';
|
import * as fromStore from 'app/main/apps/mail-ngrx/store';
|
||||||
import { FuseMailNgrxComposeDialogComponent } from '../../dialogs/compose/compose.component';
|
import { MailNgrxComposeDialogComponent } from 'app/main/apps/mail-ngrx/dialogs/compose/compose.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-main-sidenav',
|
selector : 'mail-main-sidenav',
|
||||||
templateUrl : './main-sidenav.component.html',
|
templateUrl : './main-sidenav.component.html',
|
||||||
styleUrls : ['./main-sidenav.component.scss'],
|
styleUrls : ['./main-sidenav.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class FuseMailNgrxMainSidenavComponent
|
export class MailNgrxMainSidenavComponent
|
||||||
{
|
{
|
||||||
labels: any[];
|
labels: any[];
|
||||||
accounts: object;
|
accounts: object;
|
||||||
|
@ -25,30 +25,43 @@ export class FuseMailNgrxMainSidenavComponent
|
||||||
filters$: Observable<any>;
|
filters$: Observable<any>;
|
||||||
labels$: Observable<any>;
|
labels$: Observable<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {MailNgrxService} _mailNgrxService
|
||||||
|
* @param {MatDialog} _matDialog
|
||||||
|
* @param {Store<MailAppState>} _store
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private mailService: MailNgrxService,
|
private _mailNgrxService: MailNgrxService,
|
||||||
public dialog: MatDialog,
|
private _matDialog: MatDialog,
|
||||||
private store: Store<fromStore.MailAppState>
|
private _store: Store<fromStore.MailAppState>
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Data
|
// Set the defaults
|
||||||
this.accounts = {
|
this.accounts = {
|
||||||
'creapond' : 'johndoe@creapond.com',
|
'creapond' : 'johndoe@creapond.com',
|
||||||
'withinpixels': 'johndoe@withinpixels.com'
|
'withinpixels': 'johndoe@withinpixels.com'
|
||||||
};
|
};
|
||||||
|
|
||||||
this.selectedAccount = 'creapond';
|
this.selectedAccount = 'creapond';
|
||||||
|
this.folders$ = this._store.select(fromStore.getFoldersArr);
|
||||||
this.folders$ = this.store.select(fromStore.getFoldersArr);
|
this.filters$ = this._store.select(fromStore.getFiltersArr);
|
||||||
this.filters$ = this.store.select(fromStore.getFiltersArr);
|
this.labels$ = this._store.select(fromStore.getLabelsArr);
|
||||||
this.labels$ = this.store.select(fromStore.getLabelsArr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
composeDialog()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compose dialog
|
||||||
|
*/
|
||||||
|
composeDialog(): void
|
||||||
{
|
{
|
||||||
this.dialogRef = this.dialog.open(FuseMailNgrxComposeDialogComponent, {
|
this.dialogRef = this._matDialog.open(MailNgrxComposeDialogComponent, {
|
||||||
panelClass: 'mail-compose-dialog'
|
panelClass: 'mail-compose-dialog'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.dialogRef.afterClosed()
|
this.dialogRef.afterClosed()
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
if ( !response )
|
if ( !response )
|
||||||
|
|
|
@ -16,11 +16,16 @@ export class ResolveGuard implements CanActivate
|
||||||
{
|
{
|
||||||
routerState: any;
|
routerState: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {Store<MailAppState>} _store
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private store: Store<MailAppState>
|
private _store: Store<MailAppState>
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.store.select(getRouterState).subscribe(routerState => {
|
this._store.select(getRouterState).subscribe(routerState => {
|
||||||
if ( routerState )
|
if ( routerState )
|
||||||
{
|
{
|
||||||
this.routerState = routerState.state;
|
this.routerState = routerState.state;
|
||||||
|
@ -28,6 +33,13 @@ export class ResolveGuard implements CanActivate
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can activate
|
||||||
|
*
|
||||||
|
* @param {ActivatedRouteSnapshot} route
|
||||||
|
* @param {RouterStateSnapshot} state
|
||||||
|
* @returns {Observable<boolean>}
|
||||||
|
*/
|
||||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>
|
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>
|
||||||
{
|
{
|
||||||
return this.checkStore().pipe(
|
return this.checkStore().pipe(
|
||||||
|
@ -36,32 +48,42 @@ export class ResolveGuard implements CanActivate
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check store
|
||||||
|
*
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
checkStore(): Observable<any>
|
checkStore(): Observable<any>
|
||||||
{
|
{
|
||||||
return forkJoin(
|
return forkJoin(
|
||||||
this.getFolders(),
|
this.getFolders(),
|
||||||
this.getFilters(),
|
this.getFilters(),
|
||||||
this.getLabels()
|
this.getLabels()
|
||||||
)
|
)
|
||||||
.pipe(
|
.pipe(
|
||||||
filter(([foldersLoaded, filtersLoaded, labelsLoaded]) => filtersLoaded && foldersLoaded && labelsLoaded),
|
filter(([foldersLoaded, filtersLoaded, labelsLoaded]) => !!(foldersLoaded && filtersLoaded && labelsLoaded)),
|
||||||
take(1),
|
take(1),
|
||||||
switchMap(() =>
|
switchMap(() =>
|
||||||
this.getMails()
|
this.getMails()
|
||||||
),
|
),
|
||||||
take(1),
|
take(1),
|
||||||
map(() => this.store.dispatch(new fromStore.SetCurrentMail(this.routerState.params.mailId)))
|
map(() => this._store.dispatch(new fromStore.SetCurrentMail(this.routerState.params.mailId)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFolders()
|
/**
|
||||||
|
* Get folders
|
||||||
|
*
|
||||||
|
* @returns {Observable<any>}
|
||||||
|
*/
|
||||||
|
getFolders(): any
|
||||||
{
|
{
|
||||||
return this.store.select(getFoldersLoaded)
|
return this._store.select(getFoldersLoaded)
|
||||||
.pipe(
|
.pipe(
|
||||||
tap(loaded => {
|
tap(loaded => {
|
||||||
if ( !loaded )
|
if ( !loaded )
|
||||||
{
|
{
|
||||||
this.store.dispatch(new fromStore.GetFolders([]));
|
this._store.dispatch(new fromStore.GetFolders([]));
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
filter(loaded => loaded),
|
filter(loaded => loaded),
|
||||||
|
@ -71,16 +93,17 @@ export class ResolveGuard implements CanActivate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Filters
|
* Get Filters
|
||||||
|
*
|
||||||
* @returns {Observable<any>}
|
* @returns {Observable<any>}
|
||||||
*/
|
*/
|
||||||
getFilters()
|
getFilters(): any
|
||||||
{
|
{
|
||||||
return this.store.select(getFiltersLoaded)
|
return this._store.select(getFiltersLoaded)
|
||||||
.pipe(
|
.pipe(
|
||||||
tap(loaded => {
|
tap(loaded => {
|
||||||
if ( !loaded )
|
if ( !loaded )
|
||||||
{
|
{
|
||||||
this.store.dispatch(new fromStore.GetFilters([]));
|
this._store.dispatch(new fromStore.GetFilters([]));
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
filter(loaded => loaded),
|
filter(loaded => loaded),
|
||||||
|
@ -92,14 +115,14 @@ export class ResolveGuard implements CanActivate
|
||||||
* Get Labels
|
* Get Labels
|
||||||
* @returns {Observable<any>}
|
* @returns {Observable<any>}
|
||||||
*/
|
*/
|
||||||
getLabels()
|
getLabels(): any
|
||||||
{
|
{
|
||||||
return this.store.select(getLabelsLoaded)
|
return this._store.select(getLabelsLoaded)
|
||||||
.pipe(
|
.pipe(
|
||||||
tap(loaded => {
|
tap(loaded => {
|
||||||
if ( !loaded )
|
if ( !loaded )
|
||||||
{
|
{
|
||||||
this.store.dispatch(new fromStore.GetLabels([]));
|
this._store.dispatch(new fromStore.GetLabels([]));
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
filter(loaded => loaded),
|
filter(loaded => loaded),
|
||||||
|
@ -109,19 +132,20 @@ export class ResolveGuard implements CanActivate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Mails
|
* Get Mails
|
||||||
|
*
|
||||||
* @returns {Observable<any>}
|
* @returns {Observable<any>}
|
||||||
*/
|
*/
|
||||||
getMails()
|
getMails(): any
|
||||||
{
|
{
|
||||||
return this.store.select(getMailsLoaded)
|
return this._store.select(getMailsLoaded)
|
||||||
.pipe(
|
.pipe(
|
||||||
tap((loaded: any) => {
|
tap((loaded: any) => {
|
||||||
|
|
||||||
if ( !this.routerState.params[loaded.id] || this.routerState.params[loaded.id] !== loaded.value )
|
if ( !this.routerState.params[loaded.id] || this.routerState.params[loaded.id] !== loaded.value )
|
||||||
{
|
{
|
||||||
this.store.dispatch(new fromStore.GetMails());
|
this._store.dispatch(new fromStore.GetMails());
|
||||||
this.store.dispatch(new fromStore.SetSearchText(''));
|
this._store.dispatch(new fromStore.SetSearchText(''));
|
||||||
this.store.dispatch(new fromStore.DeselectAllMails());
|
this._store.dispatch(new fromStore.DeselectAllMails());
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
filter((loaded: any) => {
|
filter((loaded: any) => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as FiltersActions from 'app/main/apps/mail-ngrx/store/actions/filters.a
|
||||||
|
|
||||||
export interface FiltersState
|
export interface FiltersState
|
||||||
{
|
{
|
||||||
entities: { [id: number]: any };
|
entities?: { [id: number]: any };
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
loaded: boolean;
|
loaded: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as FoldersActions from 'app/main/apps/mail-ngrx/store/actions/folders.a
|
||||||
|
|
||||||
export interface FoldersState
|
export interface FoldersState
|
||||||
{
|
{
|
||||||
entities: { [id: number]: any };
|
entities?: { [id: number]: any };
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
loaded: boolean;
|
loaded: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as LabelsActions from 'app/main/apps/mail-ngrx/store/actions/labels.act
|
||||||
|
|
||||||
export interface LabelsState
|
export interface LabelsState
|
||||||
{
|
{
|
||||||
entities: { [id: number]: any };
|
entities?: { [id: number]: any };
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
loaded: boolean;
|
loaded: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Mail } from 'app/main/apps/mail-ngrx/mail.model';
|
||||||
|
|
||||||
export interface MailsState
|
export interface MailsState
|
||||||
{
|
{
|
||||||
entities: { [id: number]: Mail };
|
entities?: { [id: number]: Mail };
|
||||||
currentMail: any;
|
currentMail: any;
|
||||||
selectedMailIds: string[];
|
selectedMailIds: string[];
|
||||||
searchText: string;
|
searchText: string;
|
||||||
|
|
|
@ -12,6 +12,6 @@ import { effects } from 'app/main/apps/mail-ngrx/store/effects';
|
||||||
],
|
],
|
||||||
providers: []
|
providers: []
|
||||||
})
|
})
|
||||||
export class MailAppStoreModule
|
export class MailNgrxStoreModule
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<mat-toolbar class="mat-accent m-0">
|
<mat-toolbar class="mat-accent m-0">
|
||||||
<mat-toolbar-row fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
<mat-toolbar-row fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||||
<span class="title dialog-title">New Message</span>
|
<span class="title dialog-title">New Message</span>
|
||||||
<button mat-icon-button (click)="dialogRef.close()" aria-label="Close dialog">
|
<button mat-icon-button (click)="_matDialogRef.close()" aria-label="Close dialog">
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-toolbar-row>
|
</mat-toolbar-row>
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
<div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="space-between center">
|
<div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="space-between center">
|
||||||
<div>
|
<div>
|
||||||
<button mat-raised-button
|
<button mat-raised-button
|
||||||
(click)="dialogRef.close(['send',composeForm])"
|
(click)="_matDialogRef.close(['send',composeForm])"
|
||||||
class="save-button mat-accent"
|
class="save-button mat-accent"
|
||||||
[disabled]="composeForm.invalid"
|
[disabled]="composeForm.invalid"
|
||||||
aria-label="SAVE">
|
aria-label="SAVE">
|
||||||
|
@ -103,7 +103,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button mat-icon-button (click)="dialogRef.close(['delete',composeForm])"
|
<button mat-icon-button (click)="_matDialogRef.close(['delete',composeForm])"
|
||||||
aria-label="Delete"
|
aria-label="Delete"
|
||||||
matTooltip="Delete">
|
matTooltip="Delete">
|
||||||
<mat-icon>delete</mat-icon>
|
<mat-icon>delete</mat-icon>
|
||||||
|
|
|
@ -3,25 +3,42 @@ import { FormControl, FormGroup } from '@angular/forms';
|
||||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-compose',
|
selector : 'mail-compose',
|
||||||
templateUrl : './compose.component.html',
|
templateUrl : './compose.component.html',
|
||||||
styleUrls : ['./compose.component.scss'],
|
styleUrls : ['./compose.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class FuseMailComposeDialogComponent
|
export class MailComposeDialogComponent
|
||||||
{
|
{
|
||||||
showExtraToFields = false;
|
showExtraToFields: boolean;
|
||||||
composeForm: FormGroup;
|
composeForm: FormGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {MatDialogRef<MailComposeDialogComponent>} _matDialogRef
|
||||||
|
* @param _data
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<FuseMailComposeDialogComponent>,
|
private _matDialogRef: MatDialogRef<MailComposeDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) private data: any
|
@Inject(MAT_DIALOG_DATA) private _data: any
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
this.composeForm = this.createComposeForm();
|
this.composeForm = this.createComposeForm();
|
||||||
|
this.showExtraToFields = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
createComposeForm()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create compose form
|
||||||
|
*
|
||||||
|
* @returns {FormGroup}
|
||||||
|
*/
|
||||||
|
createComposeForm(): FormGroup
|
||||||
{
|
{
|
||||||
return new FormGroup({
|
return new FormGroup({
|
||||||
from : new FormControl({
|
from : new FormControl({
|
||||||
|
@ -36,7 +53,10 @@ export class FuseMailComposeDialogComponent
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleExtraToFields()
|
/**
|
||||||
|
* Toggle extra to fields
|
||||||
|
*/
|
||||||
|
toggleExtraToFields(): void
|
||||||
{
|
{
|
||||||
this.showExtraToFields = !this.showExtraToFields;
|
this.showExtraToFields = !this.showExtraToFields;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,70 +1,106 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
|
|
||||||
import { Mail } from '../mail.model';
|
import { Mail } from 'app/main/apps/mail/mail.model';
|
||||||
import { MailService } from '../mail.service';
|
import { MailService } from 'app/main/apps/mail/mail.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-details',
|
selector : 'mail-details',
|
||||||
templateUrl: './mail-details.component.html',
|
templateUrl: './mail-details.component.html',
|
||||||
styleUrls : ['./mail-details.component.scss'],
|
styleUrls : ['./mail-details.component.scss'],
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
export class FuseMailDetailsComponent implements OnInit, OnDestroy
|
export class MailDetailsComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
mail: Mail;
|
mail: Mail;
|
||||||
labels: any[];
|
labels: any[];
|
||||||
showDetails = false;
|
showDetails: boolean;
|
||||||
|
|
||||||
onCurrentMailChanged: Subscription;
|
// Private
|
||||||
onLabelsChanged: Subscription;
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {MailService} _mailService
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private mailService: MailService
|
private _mailService: MailService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.showDetails = false;
|
||||||
|
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
// Subscribe to update the current mail
|
// Subscribe to update the current mail
|
||||||
this.onCurrentMailChanged =
|
this._mailService.onCurrentMailChanged
|
||||||
this.mailService.onCurrentMailChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(currentMail => {
|
.subscribe(currentMail => {
|
||||||
this.mail = currentMail;
|
this.mail = currentMail;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Subscribe to update on label change
|
// Subscribe to update on label change
|
||||||
this.onLabelsChanged =
|
this._mailService.onLabelsChanged
|
||||||
this.mailService.onLabelsChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(labels => {
|
.subscribe(labels => {
|
||||||
this.labels = labels;
|
this.labels = labels;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onCurrentMailChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleStar(event)
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle star
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
toggleStar(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.mail.toggleStar();
|
this.mail.toggleStar();
|
||||||
|
|
||||||
this.mailService.updateMail(this.mail);
|
this._mailService.updateMail(this.mail);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleImportant(event)
|
/**
|
||||||
|
* Toggle important
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
toggleImportant(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.mail.toggleImportant();
|
this.mail.toggleImportant();
|
||||||
|
|
||||||
this.mailService.updateMail(this.mail);
|
this._mailService.updateMail(this.mail);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,94 +1,125 @@
|
||||||
import { Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core';
|
import { Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { Mail } from '../../mail.model';
|
import { Mail } from 'app/main/apps/mail/mail.model';
|
||||||
import { MailService } from '../../mail.service';
|
import { MailService } from 'app/main/apps/mail/mail.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-list-item',
|
selector : 'mail-list-item',
|
||||||
templateUrl: './mail-list-item.component.html',
|
templateUrl: './mail-list-item.component.html',
|
||||||
styleUrls : ['./mail-list-item.component.scss']
|
styleUrls : ['./mail-list-item.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseMailListItemComponent implements OnInit, OnDestroy
|
export class MailListItemComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
@Input() mail: Mail;
|
@Input() mail: Mail;
|
||||||
labels: any[];
|
labels: any[];
|
||||||
@HostBinding('class.selected') selected: boolean;
|
|
||||||
|
|
||||||
onSelectedMailsChanged: Subscription;
|
@HostBinding('class.selected')
|
||||||
onLabelsChanged: Subscription;
|
selected: boolean;
|
||||||
|
|
||||||
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {MailService} _mailService
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private mailService: MailService
|
private _mailService: MailService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
// Set the initial values
|
// Set the initial values
|
||||||
this.mail = new Mail(this.mail);
|
this.mail = new Mail(this.mail);
|
||||||
|
|
||||||
// Subscribe to update on selected mail change
|
// Subscribe to update on selected mail change
|
||||||
this.onSelectedMailsChanged =
|
this._mailService.onSelectedMailsChanged
|
||||||
this.mailService.onSelectedMailsChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(selectedMails => {
|
.subscribe(selectedMails => {
|
||||||
this.selected = false;
|
this.selected = false;
|
||||||
|
|
||||||
if ( selectedMails.length > 0 )
|
if ( selectedMails.length > 0 )
|
||||||
|
{
|
||||||
|
for ( const mail of selectedMails )
|
||||||
{
|
{
|
||||||
for ( const mail of selectedMails )
|
if ( mail.id === this.mail.id )
|
||||||
{
|
{
|
||||||
if ( mail.id === this.mail.id )
|
this.selected = true;
|
||||||
{
|
break;
|
||||||
this.selected = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Subscribe to update on label change
|
// Subscribe to update on label change
|
||||||
this.onLabelsChanged =
|
this._mailService.onLabelsChanged
|
||||||
this.mailService.onLabelsChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(labels => {
|
.subscribe(labels => {
|
||||||
this.labels = labels;
|
this.labels = labels;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onSelectedMailsChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectedChange()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On selected change
|
||||||
|
*/
|
||||||
|
onSelectedChange(): void
|
||||||
{
|
{
|
||||||
this.mailService.toggleSelectedMail(this.mail.id);
|
this._mailService.toggleSelectedMail(this.mail.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle star
|
* Toggle star
|
||||||
|
*
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
toggleStar(event)
|
toggleStar(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.mail.toggleStar();
|
this.mail.toggleStar();
|
||||||
|
|
||||||
this.mailService.updateMail(this.mail);
|
this._mailService.updateMail(this.mail);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle Important
|
* Toggle Important
|
||||||
|
*
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
toggleImportant(event)
|
toggleImportant(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.mail.toggleImportant();
|
this.mail.toggleImportant();
|
||||||
|
|
||||||
this.mailService.updateMail(this.mail);
|
this._mailService.updateMail(this.mail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mail-list" *fuseIfOnDom [@animateStagger]="{value:'50'}">
|
<div class="mail-list" *fuseIfOnDom [@animateStagger]="{value:'50'}">
|
||||||
<fuse-mail-list-item matRipple *ngFor="let mail of mails" [mail]="mail" (click)="readMail(mail.id)"
|
<mail-list-item matRipple *ngFor="let mail of mails" [mail]="mail" (click)="readMail(mail.id)"
|
||||||
[ngClass]="{'current-mail':mail?.id == currentMail?.id}"
|
[ngClass]="{'current-mail':mail?.id == currentMail?.id}"
|
||||||
[@animate]="{value:'*',params:{y:'100%'}}">
|
[@animate]="{value:'*',params:{y:'100%'}}">
|
||||||
</fuse-mail-list-item>
|
</mail-list-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,109 +1,134 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
|
|
||||||
import { Mail } from '../mail.model';
|
import { Mail } from 'app/main/apps/mail/mail.model';
|
||||||
import { MailService } from '../mail.service';
|
import { MailService } from 'app/main/apps/mail/mail.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-list',
|
selector : 'mail-list',
|
||||||
templateUrl: './mail-list.component.html',
|
templateUrl: './mail-list.component.html',
|
||||||
styleUrls : ['./mail-list.component.scss'],
|
styleUrls : ['./mail-list.component.scss'],
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
export class FuseMailListComponent implements OnInit, OnDestroy
|
export class MailListComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
mails: Mail[];
|
mails: Mail[];
|
||||||
currentMail: Mail;
|
currentMail: Mail;
|
||||||
|
|
||||||
onMailsChanged: Subscription;
|
// Private
|
||||||
onCurrentMailChanged: Subscription;
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {ActivatedRoute} _activatedRoute
|
||||||
|
* @param {MailService} _mailService
|
||||||
|
* @param {Location} _location
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private _activatedRoute: ActivatedRoute,
|
||||||
private mailService: MailService,
|
private _mailService: MailService,
|
||||||
private location: Location
|
private _location: Location
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
// Subscribe to update mails on changes
|
// Subscribe to update mails on changes
|
||||||
this.onMailsChanged =
|
this._mailService.onMailsChanged
|
||||||
this.mailService.onMailsChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(mails => {
|
.subscribe(mails => {
|
||||||
this.mails = mails;
|
this.mails = mails;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Subscribe to update current mail on changes
|
// Subscribe to update current mail on changes
|
||||||
this.onCurrentMailChanged =
|
this._mailService.onCurrentMailChanged
|
||||||
this.mailService.onCurrentMailChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(currentMail => {
|
.subscribe(currentMail => {
|
||||||
if ( !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 )
|
||||||
{
|
{
|
||||||
// Set the current mail id to null to deselect the current mail
|
this._location.go('apps/mail/label/' + labelHandle);
|
||||||
this.currentMail = null;
|
}
|
||||||
|
else if ( filterHandle )
|
||||||
// Handle the location changes
|
{
|
||||||
const labelHandle = this.route.snapshot.params.labelHandle,
|
this._location.go('apps/mail/filter/' + filterHandle);
|
||||||
filterHandle = this.route.snapshot.params.filterHandle,
|
|
||||||
folderHandle = this.route.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
|
else
|
||||||
{
|
{
|
||||||
this.currentMail = currentMail;
|
this._location.go('apps/mail/' + folderHandle);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
ngOnDestroy()
|
this.currentMail = currentMail;
|
||||||
{
|
}
|
||||||
this.onMailsChanged.unsubscribe();
|
});
|
||||||
this.onCurrentMailChanged.unsubscribe();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
|
{
|
||||||
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read mail
|
* Read mail
|
||||||
|
*
|
||||||
* @param mailId
|
* @param mailId
|
||||||
*/
|
*/
|
||||||
readMail(mailId)
|
readMail(mailId): void
|
||||||
{
|
{
|
||||||
const labelHandle = this.route.snapshot.params.labelHandle,
|
const labelHandle = this._activatedRoute.snapshot.params.labelHandle,
|
||||||
filterHandle = this.route.snapshot.params.filterHandle,
|
filterHandle = this._activatedRoute.snapshot.params.filterHandle,
|
||||||
folderHandle = this.route.snapshot.params.folderHandle;
|
folderHandle = this._activatedRoute.snapshot.params.folderHandle;
|
||||||
|
|
||||||
if ( labelHandle )
|
if ( labelHandle )
|
||||||
{
|
{
|
||||||
this.location.go('apps/mail/label/' + labelHandle + '/' + mailId);
|
this._location.go('apps/mail/label/' + labelHandle + '/' + mailId);
|
||||||
}
|
}
|
||||||
else if ( filterHandle )
|
else if ( filterHandle )
|
||||||
{
|
{
|
||||||
this.location.go('apps/mail/filter/' + filterHandle + '/' + mailId);
|
this._location.go('apps/mail/filter/' + filterHandle + '/' + mailId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.location.go('apps/mail/' + folderHandle + '/' + mailId);
|
this._location.go('apps/mail/' + folderHandle + '/' + mailId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set current mail
|
// Set current mail
|
||||||
this.mailService.setCurrentMail(mailId);
|
this._mailService.setCurrentMail(mailId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<!-- SIDENAV -->
|
<!-- SIDENAV -->
|
||||||
<mat-sidenav class="sidenav" position="start" mode="side" opened="true"
|
<mat-sidenav class="sidenav" position="start" mode="side" opened="true"
|
||||||
fuseMatSidenavHelper="carded-left-sidenav" mat-is-locked-open="gt-md">
|
fuseMatSidenavHelper="carded-left-sidenav" mat-is-locked-open="gt-md">
|
||||||
<fuse-mail-main-sidenav></fuse-mail-main-sidenav>
|
<mail-main-sidenav></mail-main-sidenav>
|
||||||
</mat-sidenav>
|
</mat-sidenav>
|
||||||
<!-- / SIDENAV -->
|
<!-- / SIDENAV -->
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="currentMail" fxHide.gt-xs>
|
<div *ngIf="currentMail" fxHide.gt-xs>
|
||||||
<button mat-icon-button (click)="deSelectCurrentMail()">
|
<button mat-icon-button (click)="deselectCurrentMail()">
|
||||||
<mat-icon>arrow_back</mat-icon>
|
<mat-icon>arrow_back</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -96,8 +96,8 @@
|
||||||
<!-- CONTENT -->
|
<!-- CONTENT -->
|
||||||
<div class="content" fxLayout="row">
|
<div class="content" fxLayout="row">
|
||||||
|
|
||||||
<fuse-mail-list fusePerfectScrollbar fxFlex></fuse-mail-list>
|
<mail-list fusePerfectScrollbar fxFlex></mail-list>
|
||||||
<fuse-mail-details fusePerfectScrollbar fxFlex></fuse-mail-details>
|
<mail-details fusePerfectScrollbar fxFlex></mail-details>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- / CONTENT -->
|
<!-- / CONTENT -->
|
||||||
|
|
|
@ -40,16 +40,16 @@
|
||||||
|
|
||||||
@include media-breakpoint(xs) {
|
@include media-breakpoint(xs) {
|
||||||
|
|
||||||
fuse-mail-list {
|
mail-list {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse-mail-list,
|
mail-list,
|
||||||
fuse-mail-details {
|
mail-details {
|
||||||
flex: 1 0 100%;
|
flex: 1 0 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse-mail-details {
|
mail-details {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,11 +65,11 @@
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
|
||||||
fuse-mail-list {
|
mail-list {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse-mail-details {
|
mail-details {
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { FormControl } from '@angular/forms';
|
import { FormControl } from '@angular/forms';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
import { Subscription } from 'rxjs';
|
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||||
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { FuseTranslationLoaderService } from '@fuse/services/translation-loader.service';
|
import { FuseTranslationLoaderService } from '@fuse/services/translation-loader.service';
|
||||||
|
|
||||||
import { Mail } from './mail.model';
|
import { Mail } from 'app/main/apps/mail/mail.model';
|
||||||
import { MailService } from './mail.service';
|
import { MailService } from 'app/main/apps/mail/mail.service';
|
||||||
import { locale as english } from './i18n/en';
|
|
||||||
import { locale as turkish } from './i18n/tr';
|
import { locale as english } from 'app/main/apps/mail//i18n/en';
|
||||||
|
import { locale as turkish } from 'app/main/apps/mail//i18n/tr';
|
||||||
|
import { FuseConfigService } from '@fuse/services/config.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail',
|
selector : 'mail',
|
||||||
templateUrl: './mail.component.html',
|
templateUrl: './mail.component.html',
|
||||||
styleUrls : ['./mail.component.scss']
|
styleUrls : ['./mail.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseMailComponent implements OnInit, OnDestroy
|
export class MailComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
hasSelectedMails: boolean;
|
hasSelectedMails: boolean;
|
||||||
isIndeterminate: boolean;
|
isIndeterminate: boolean;
|
||||||
|
@ -26,110 +27,162 @@ export class FuseMailComponent implements OnInit, OnDestroy
|
||||||
searchInput: FormControl;
|
searchInput: FormControl;
|
||||||
currentMail: Mail;
|
currentMail: Mail;
|
||||||
|
|
||||||
onSelectedMailsChanged: Subscription;
|
// Private
|
||||||
onFoldersChanged: Subscription;
|
private _unsubscribeAll: Subject<any>;
|
||||||
onFiltersChanged: Subscription;
|
|
||||||
onLabelsChanged: Subscription;
|
|
||||||
onCurrentMailChanged: Subscription;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {MailService} _mailService
|
||||||
|
* @param {FuseConfigService} _fuseConfigService
|
||||||
|
* @param {FuseTranslationLoaderService} _fuseTranslationLoaderService
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private mailService: MailService,
|
private _mailService: MailService,
|
||||||
private fuseTranslationLoader: FuseTranslationLoaderService
|
private _fuseConfigService: FuseConfigService,
|
||||||
|
private _fuseTranslationLoaderService: FuseTranslationLoaderService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Configure the layout
|
||||||
|
this._fuseConfigService.config = {
|
||||||
|
routerAnimation: 'none'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Load the translations
|
||||||
|
this._fuseTranslationLoaderService.loadTranslations(english, turkish);
|
||||||
|
|
||||||
|
// Set the defaults
|
||||||
this.searchInput = new FormControl('');
|
this.searchInput = new FormControl('');
|
||||||
this.fuseTranslationLoader.loadTranslations(english, turkish);
|
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.onSelectedMailsChanged =
|
this._mailService.onSelectedMailsChanged
|
||||||
this.mailService.onSelectedMailsChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(selectedMails => {
|
.subscribe(selectedMails => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.hasSelectedMails = selectedMails.length > 0;
|
||||||
|
this.isIndeterminate = (selectedMails.length !== this._mailService.mails.length && selectedMails.length > 0);
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
|
||||||
setTimeout(() => {
|
this._mailService.onFoldersChanged
|
||||||
this.hasSelectedMails = selectedMails.length > 0;
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
this.isIndeterminate = (selectedMails.length !== this.mailService.mails.length && selectedMails.length > 0);
|
.subscribe(folders => {
|
||||||
}, 0);
|
this.folders = this._mailService.folders;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onFoldersChanged =
|
this._mailService.onFiltersChanged
|
||||||
this.mailService.onFoldersChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(folders => {
|
.subscribe(folders => {
|
||||||
this.folders = this.mailService.folders;
|
this.filters = this._mailService.filters;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onFiltersChanged =
|
this._mailService.onLabelsChanged
|
||||||
this.mailService.onFiltersChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(folders => {
|
.subscribe(labels => {
|
||||||
this.filters = this.mailService.filters;
|
this.labels = this._mailService.labels;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onLabelsChanged =
|
this._mailService.onCurrentMailChanged
|
||||||
this.mailService.onLabelsChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(labels => {
|
.subscribe(currentMail => {
|
||||||
this.labels = this.mailService.labels;
|
if ( !currentMail )
|
||||||
});
|
{
|
||||||
|
this.currentMail = null;
|
||||||
this.onCurrentMailChanged =
|
}
|
||||||
this.mailService.onCurrentMailChanged
|
else
|
||||||
.subscribe(currentMail => {
|
{
|
||||||
if ( !currentMail )
|
this.currentMail = currentMail;
|
||||||
{
|
}
|
||||||
this.currentMail = null;
|
});
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.currentMail = currentMail;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.searchInput.valueChanges.pipe(
|
this.searchInput.valueChanges.pipe(
|
||||||
|
takeUntil(this._unsubscribeAll),
|
||||||
debounceTime(300),
|
debounceTime(300),
|
||||||
distinctUntilChanged()
|
distinctUntilChanged()
|
||||||
)
|
)
|
||||||
.subscribe(searchText => {
|
.subscribe(searchText => {
|
||||||
this.mailService.onSearchTextChanged.next(searchText);
|
this._mailService.onSearchTextChanged.next(searchText);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onSelectedMailsChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
this.onFoldersChanged.unsubscribe();
|
this._unsubscribeAll.next();
|
||||||
this.onFiltersChanged.unsubscribe();
|
this._unsubscribeAll.complete();
|
||||||
this.onLabelsChanged.unsubscribe();
|
|
||||||
this.onCurrentMailChanged.unsubscribe();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSelectAll()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle select all
|
||||||
|
*/
|
||||||
|
toggleSelectAll(): void
|
||||||
{
|
{
|
||||||
this.mailService.toggleSelectAll();
|
this._mailService.toggleSelectAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
selectMails(filterParameter?, filterValue?)
|
/**
|
||||||
|
* Select mails
|
||||||
|
*
|
||||||
|
* @param filterParameter
|
||||||
|
* @param filterValue
|
||||||
|
*/
|
||||||
|
selectMails(filterParameter?, filterValue?): void
|
||||||
{
|
{
|
||||||
this.mailService.selectMails(filterParameter, filterValue);
|
this._mailService.selectMails(filterParameter, filterValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectMails()
|
/**
|
||||||
|
* Deselect mails
|
||||||
|
*/
|
||||||
|
deselectMails(): void
|
||||||
{
|
{
|
||||||
this.mailService.deselectMails();
|
this._mailService.deselectMails();
|
||||||
}
|
}
|
||||||
|
|
||||||
deSelectCurrentMail()
|
/**
|
||||||
|
* Deselect current mail
|
||||||
|
*/
|
||||||
|
deselectCurrentMail(): void
|
||||||
{
|
{
|
||||||
this.mailService.onCurrentMailChanged.next(null);
|
this._mailService.onCurrentMailChanged.next(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleLabelOnSelectedMails(labelId)
|
/**
|
||||||
|
* Toggle label on selected mails
|
||||||
|
*
|
||||||
|
* @param labelId
|
||||||
|
*/
|
||||||
|
toggleLabelOnSelectedMails(labelId): void
|
||||||
{
|
{
|
||||||
this.mailService.toggleLabelOnSelectedMails(labelId);
|
this._mailService.toggleLabelOnSelectedMails(labelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
setFolderOnSelectedMails(folderId)
|
/**
|
||||||
|
* Set folder on selected mails
|
||||||
|
*
|
||||||
|
* @param folderId
|
||||||
|
*/
|
||||||
|
setFolderOnSelectedMails(folderId): void
|
||||||
{
|
{
|
||||||
this.mailService.setFolderOnSelectedMails(folderId);
|
this._mailService.setFolderOnSelectedMails(folderId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,11 @@ export class Mail
|
||||||
labels: string[];
|
labels: string[];
|
||||||
folder: string;
|
folder: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param mail
|
||||||
|
*/
|
||||||
constructor(mail)
|
constructor(mail)
|
||||||
{
|
{
|
||||||
this.id = mail.id;
|
this.id = mail.id;
|
||||||
|
|
|
@ -1,59 +1,57 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
import { MatButtonModule, MatCheckboxModule, MatDialogModule, MatFormFieldModule, MatIconModule, MatInputModule, MatMenuModule, MatRippleModule, MatSelectModule, MatSidenavModule, MatToolbarModule } from '@angular/material';
|
import { MatButtonModule, MatCheckboxModule, MatDialogModule, MatFormFieldModule, MatIconModule, MatInputModule, MatMenuModule, MatRippleModule, MatSelectModule, MatSidenavModule, MatToolbarModule } from '@angular/material';
|
||||||
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { FuseSharedModule } from '@fuse/shared.module';
|
import { FuseSharedModule } from '@fuse/shared.module';
|
||||||
|
|
||||||
import { MailService } from './mail.service';
|
import { MailService } from 'app/main/apps/mail/mail.service';
|
||||||
import { FuseMailComponent } from './mail.component';
|
import { MailComponent } from 'app/main/apps/mail/mail.component';
|
||||||
import { FuseMailMainSidenavComponent } from './sidenavs/main/main-sidenav.component';
|
import { MailListComponent } from 'app/main/apps/mail/mail-list/mail-list.component';
|
||||||
import { FuseMailListItemComponent } from './mail-list/mail-list-item/mail-list-item.component';
|
import { MailListItemComponent } from 'app/main/apps/mail/mail-list/mail-list-item/mail-list-item.component';
|
||||||
import { FuseMailListComponent } from './mail-list/mail-list.component';
|
import { MailDetailsComponent } from 'app/main/apps/mail/mail-details/mail-details.component';
|
||||||
import { FuseMailDetailsComponent } from './mail-details/mail-details.component';
|
import { MailMainSidenavComponent } from 'app/main/apps/mail/sidenavs/main/main-sidenav.component';
|
||||||
import { FuseMailComposeDialogComponent } from './dialogs/compose/compose.component';
|
import { MailComposeDialogComponent } from 'app/main/apps/mail/dialogs/compose/compose.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path : 'label/:labelHandle',
|
path : 'label/:labelHandle',
|
||||||
component: FuseMailComponent,
|
component: MailComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
mail: MailService
|
mail: MailService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'label/:labelHandle/:mailId',
|
path : 'label/:labelHandle/:mailId',
|
||||||
component: FuseMailComponent,
|
component: MailComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
mail: MailService
|
mail: MailService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'filter/:filterHandle',
|
path : 'filter/:filterHandle',
|
||||||
component: FuseMailComponent,
|
component: MailComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
mail: MailService
|
mail: MailService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'filter/:filterHandle/:mailId',
|
path : 'filter/:filterHandle/:mailId',
|
||||||
component: FuseMailComponent,
|
component: MailComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
mail: MailService
|
mail: MailService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : ':folderHandle',
|
path : ':folderHandle',
|
||||||
component: FuseMailComponent,
|
component: MailComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
mail: MailService
|
mail: MailService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : ':folderHandle/:mailId',
|
path : ':folderHandle/:mailId',
|
||||||
component: FuseMailComponent,
|
component: MailComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
mail: MailService
|
mail: MailService
|
||||||
}
|
}
|
||||||
|
@ -66,12 +64,12 @@ const routes: Routes = [
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations : [
|
declarations : [
|
||||||
FuseMailComponent,
|
MailComponent,
|
||||||
FuseMailListComponent,
|
MailListComponent,
|
||||||
FuseMailListItemComponent,
|
MailListItemComponent,
|
||||||
FuseMailDetailsComponent,
|
MailDetailsComponent,
|
||||||
FuseMailMainSidenavComponent,
|
MailMainSidenavComponent,
|
||||||
FuseMailComposeDialogComponent
|
MailComposeDialogComponent
|
||||||
],
|
],
|
||||||
imports : [
|
imports : [
|
||||||
RouterModule.forChild(routes),
|
RouterModule.forChild(routes),
|
||||||
|
@ -95,8 +93,10 @@ const routes: Routes = [
|
||||||
providers : [
|
providers : [
|
||||||
MailService
|
MailService
|
||||||
],
|
],
|
||||||
entryComponents: [FuseMailComposeDialogComponent]
|
entryComponents: [
|
||||||
|
MailComposeDialogComponent
|
||||||
|
]
|
||||||
})
|
})
|
||||||
export class FuseMailModule
|
export class MailModule
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
|
|
||||||
import { FuseUtils } from '@fuse/utils';
|
import { FuseUtils } from '@fuse/utils';
|
||||||
|
|
||||||
import { Mail } from './mail.model';
|
import { Mail } from 'app/main/apps/mail/mail.model';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MailService implements Resolve<any>
|
export class MailService implements Resolve<any>
|
||||||
|
@ -20,22 +20,37 @@ export class MailService implements Resolve<any>
|
||||||
labels: any[];
|
labels: any[];
|
||||||
routeParams: any;
|
routeParams: any;
|
||||||
|
|
||||||
onMailsChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onMailsChanged: BehaviorSubject<any>;
|
||||||
onSelectedMailsChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onSelectedMailsChanged: BehaviorSubject<any>;
|
||||||
onCurrentMailChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onCurrentMailChanged: BehaviorSubject<any>;
|
||||||
|
onFoldersChanged: BehaviorSubject<any>;
|
||||||
|
onFiltersChanged: BehaviorSubject<any>;
|
||||||
|
onLabelsChanged: BehaviorSubject<any>;
|
||||||
|
onSearchTextChanged: BehaviorSubject<any>;
|
||||||
|
|
||||||
onFoldersChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
/**
|
||||||
onFiltersChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
* Constructor
|
||||||
onLabelsChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
*
|
||||||
onSearchTextChanged: BehaviorSubject<any> = new BehaviorSubject('');
|
* @param {HttpClient} _httpClient
|
||||||
|
*/
|
||||||
constructor(private http: HttpClient)
|
constructor(
|
||||||
|
private _httpClient: HttpClient
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
this.selectedMails = [];
|
this.selectedMails = [];
|
||||||
|
this.onMailsChanged = new BehaviorSubject([]);
|
||||||
|
this.onSelectedMailsChanged = new BehaviorSubject([]);
|
||||||
|
this.onCurrentMailChanged = new BehaviorSubject([]);
|
||||||
|
this.onFoldersChanged = new BehaviorSubject([]);
|
||||||
|
this.onFiltersChanged = new BehaviorSubject([]);
|
||||||
|
this.onLabelsChanged = new BehaviorSubject([]);
|
||||||
|
this.onSearchTextChanged = new BehaviorSubject('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve
|
* Resolver
|
||||||
|
*
|
||||||
* @param {ActivatedRouteSnapshot} route
|
* @param {ActivatedRouteSnapshot} route
|
||||||
* @param {RouterStateSnapshot} state
|
* @param {RouterStateSnapshot} state
|
||||||
* @returns {Observable<any> | Promise<any> | any}
|
* @returns {Observable<any> | Promise<any> | any}
|
||||||
|
@ -83,12 +98,13 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all folders
|
* Get all folders
|
||||||
|
*
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
getFolders(): Promise<any>
|
getFolders(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/mail-folders')
|
this._httpClient.get('api/mail-folders')
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
this.folders = response;
|
this.folders = response;
|
||||||
this.onFoldersChanged.next(this.folders);
|
this.onFoldersChanged.next(this.folders);
|
||||||
|
@ -99,12 +115,13 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all filters
|
* Get all filters
|
||||||
|
*
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
getFilters(): Promise<any>
|
getFilters(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/mail-filters')
|
this._httpClient.get('api/mail-filters')
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
this.filters = response;
|
this.filters = response;
|
||||||
this.onFiltersChanged.next(this.filters);
|
this.onFiltersChanged.next(this.filters);
|
||||||
|
@ -115,12 +132,13 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all labels
|
* Get all labels
|
||||||
|
*
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
getLabels(): Promise<any>
|
getLabels(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/mail-labels')
|
this._httpClient.get('api/mail-labels')
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
this.labels = response;
|
this.labels = response;
|
||||||
this.onLabelsChanged.next(this.labels);
|
this.onLabelsChanged.next(this.labels);
|
||||||
|
@ -131,6 +149,7 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all mails
|
* Get all mails
|
||||||
|
*
|
||||||
* @returns {Promise<Mail[]>}
|
* @returns {Promise<Mail[]>}
|
||||||
*/
|
*/
|
||||||
getMails(): Promise<Mail[]>
|
getMails(): Promise<Mail[]>
|
||||||
|
@ -150,6 +169,7 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get mails by folder
|
* Get mails by folder
|
||||||
|
*
|
||||||
* @param handle
|
* @param handle
|
||||||
* @returns {Promise<Mail[]>}
|
* @returns {Promise<Mail[]>}
|
||||||
*/
|
*/
|
||||||
|
@ -157,12 +177,12 @@ export class MailService implements Resolve<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
this.http.get('api/mail-folders?handle=' + handle)
|
this._httpClient.get('api/mail-folders?handle=' + handle)
|
||||||
.subscribe((folders: any) => {
|
.subscribe((folders: any) => {
|
||||||
|
|
||||||
const folderId = folders[0].id;
|
const folderId = folders[0].id;
|
||||||
|
|
||||||
this.http.get('api/mail-mails?folder=' + folderId)
|
this._httpClient.get('api/mail-mails?folder=' + folderId)
|
||||||
.subscribe((mails: any) => {
|
.subscribe((mails: any) => {
|
||||||
|
|
||||||
this.mails = mails.map(mail => {
|
this.mails = mails.map(mail => {
|
||||||
|
@ -182,6 +202,7 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get mails by filter
|
* Get mails by filter
|
||||||
|
*
|
||||||
* @param handle
|
* @param handle
|
||||||
* @returns {Promise<Mail[]>}
|
* @returns {Promise<Mail[]>}
|
||||||
*/
|
*/
|
||||||
|
@ -189,7 +210,7 @@ export class MailService implements Resolve<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
this.http.get('api/mail-mails?' + handle + '=true')
|
this._httpClient.get('api/mail-mails?' + handle + '=true')
|
||||||
.subscribe((mails: any) => {
|
.subscribe((mails: any) => {
|
||||||
|
|
||||||
this.mails = mails.map(mail => {
|
this.mails = mails.map(mail => {
|
||||||
|
@ -208,18 +229,19 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get mails by label
|
* Get mails by label
|
||||||
|
*
|
||||||
* @param handle
|
* @param handle
|
||||||
* @returns {Promise<Mail[]>}
|
* @returns {Promise<Mail[]>}
|
||||||
*/
|
*/
|
||||||
getMailsByLabel(handle): Promise<Mail[]>
|
getMailsByLabel(handle): Promise<Mail[]>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/mail-labels?handle=' + handle)
|
this._httpClient.get('api/mail-labels?handle=' + handle)
|
||||||
.subscribe((labels: any) => {
|
.subscribe((labels: any) => {
|
||||||
|
|
||||||
const labelId = labels[0].id;
|
const labelId = labels[0].id;
|
||||||
|
|
||||||
this.http.get('api/mail-mails?labels=' + labelId)
|
this._httpClient.get('api/mail-mails?labels=' + labelId)
|
||||||
.subscribe((mails: any) => {
|
.subscribe((mails: any) => {
|
||||||
|
|
||||||
this.mails = mails.map(mail => {
|
this.mails = mails.map(mail => {
|
||||||
|
@ -239,9 +261,10 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle selected mail by id
|
* Toggle selected mail by id
|
||||||
|
*
|
||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
toggleSelectedMail(id)
|
toggleSelectedMail(id): void
|
||||||
{
|
{
|
||||||
// First, check if we already have that mail as selected...
|
// First, check if we already have that mail as selected...
|
||||||
if ( this.selectedMails.length > 0 )
|
if ( this.selectedMails.length > 0 )
|
||||||
|
@ -281,7 +304,7 @@ export class MailService implements Resolve<any>
|
||||||
/**
|
/**
|
||||||
* Toggle select all
|
* Toggle select all
|
||||||
*/
|
*/
|
||||||
toggleSelectAll()
|
toggleSelectAll(): void
|
||||||
{
|
{
|
||||||
if ( this.selectedMails.length > 0 )
|
if ( this.selectedMails.length > 0 )
|
||||||
{
|
{
|
||||||
|
@ -294,7 +317,13 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
selectMails(filterParameter?, filterValue?)
|
/**
|
||||||
|
* Select mails
|
||||||
|
*
|
||||||
|
* @param filterParameter
|
||||||
|
* @param filterValue
|
||||||
|
*/
|
||||||
|
selectMails(filterParameter?, filterValue?): void
|
||||||
{
|
{
|
||||||
this.selectedMails = [];
|
this.selectedMails = [];
|
||||||
|
|
||||||
|
@ -316,7 +345,10 @@ export class MailService implements Resolve<any>
|
||||||
this.onSelectedMailsChanged.next(this.selectedMails);
|
this.onSelectedMailsChanged.next(this.selectedMails);
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectMails()
|
/**
|
||||||
|
* Deselect mails
|
||||||
|
*/
|
||||||
|
deselectMails(): void
|
||||||
{
|
{
|
||||||
this.selectedMails = [];
|
this.selectedMails = [];
|
||||||
|
|
||||||
|
@ -326,9 +358,10 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set current mail by id
|
* Set current mail by id
|
||||||
|
*
|
||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
setCurrentMail(id)
|
setCurrentMail(id): void
|
||||||
{
|
{
|
||||||
this.currentMail = this.mails.find(mail => {
|
this.currentMail = this.mails.find(mail => {
|
||||||
return mail.id === id;
|
return mail.id === id;
|
||||||
|
@ -339,9 +372,10 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle label on selected mails
|
* Toggle label on selected mails
|
||||||
|
*
|
||||||
* @param labelId
|
* @param labelId
|
||||||
*/
|
*/
|
||||||
toggleLabelOnSelectedMails(labelId)
|
toggleLabelOnSelectedMails(labelId): void
|
||||||
{
|
{
|
||||||
this.selectedMails.map(mail => {
|
this.selectedMails.map(mail => {
|
||||||
|
|
||||||
|
@ -362,9 +396,10 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set folder on selected mails
|
* Set folder on selected mails
|
||||||
|
*
|
||||||
* @param folderId
|
* @param folderId
|
||||||
*/
|
*/
|
||||||
setFolderOnSelectedMails(folderId)
|
setFolderOnSelectedMails(folderId): void
|
||||||
{
|
{
|
||||||
this.selectedMails.map(mail => {
|
this.selectedMails.map(mail => {
|
||||||
mail.folder = folderId;
|
mail.folder = folderId;
|
||||||
|
@ -377,14 +412,15 @@ export class MailService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the mail
|
* Update the mail
|
||||||
|
*
|
||||||
* @param mail
|
* @param mail
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
updateMail(mail)
|
updateMail(mail): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
this.http.post('api/mail-mails/' + mail.id, {...mail})
|
this._httpClient.post('api/mail-mails/' + mail.id, {...mail})
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
|
|
||||||
this.getMails().then(mails => {
|
this.getMails().then(mails => {
|
||||||
|
@ -400,5 +436,4 @@ export class MailService implements Resolve<any>
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { FormGroup } from '@angular/forms';
|
import { FormGroup } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material';
|
import { MatDialog } from '@angular/material';
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
|
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
|
|
||||||
import { MailService } from '../../mail.service';
|
import { MailService } from 'app/main/apps/mail/mail.service';
|
||||||
import { FuseMailComposeDialogComponent } from '../../dialogs/compose/compose.component';
|
import { MailComposeDialogComponent } from 'app/main/apps/mail/dialogs/compose/compose.component';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-mail-main-sidenav',
|
selector : 'mail-main-sidenav',
|
||||||
templateUrl: './main-sidenav.component.html',
|
templateUrl: './main-sidenav.component.html',
|
||||||
styleUrls : ['./main-sidenav.component.scss'],
|
styleUrls : ['./main-sidenav.component.scss'],
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
export class FuseMailMainSidenavComponent implements OnInit, OnDestroy
|
export class MailMainSidenavComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
folders: any[];
|
folders: any[];
|
||||||
filters: any[];
|
filters: any[];
|
||||||
|
@ -23,55 +24,79 @@ export class FuseMailMainSidenavComponent implements OnInit, OnDestroy
|
||||||
selectedAccount: string;
|
selectedAccount: string;
|
||||||
dialogRef: any;
|
dialogRef: any;
|
||||||
|
|
||||||
onFoldersChanged: Subscription;
|
// Private
|
||||||
onFiltersChanged: Subscription;
|
private _unsubscribeAll: Subject<any>;
|
||||||
onLabelsChanged: Subscription;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {MailService} _mailService
|
||||||
|
* @param {MatDialog} _matDialog
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private mailService: MailService,
|
private _mailService: MailService,
|
||||||
public dialog: MatDialog
|
public _matDialog: MatDialog
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Data
|
// Set the defaults
|
||||||
this.accounts = {
|
this.accounts = {
|
||||||
'creapond' : 'johndoe@creapond.com',
|
'creapond' : 'johndoe@creapond.com',
|
||||||
'withinpixels': 'johndoe@withinpixels.com'
|
'withinpixels': 'johndoe@withinpixels.com'
|
||||||
};
|
};
|
||||||
|
|
||||||
this.selectedAccount = 'creapond';
|
this.selectedAccount = 'creapond';
|
||||||
|
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.onFoldersChanged =
|
this._mailService.onFoldersChanged
|
||||||
this.mailService.onFoldersChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(folders => {
|
.subscribe(folders => {
|
||||||
this.folders = folders;
|
this.folders = folders;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onFiltersChanged =
|
this._mailService.onFiltersChanged
|
||||||
this.mailService.onFiltersChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(filters => {
|
.subscribe(filters => {
|
||||||
this.filters = filters;
|
this.filters = filters;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onLabelsChanged =
|
this._mailService.onLabelsChanged
|
||||||
this.mailService.onLabelsChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(labels => {
|
.subscribe(labels => {
|
||||||
this.labels = labels;
|
this.labels = labels;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onFoldersChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
this.onFiltersChanged.unsubscribe();
|
this._unsubscribeAll.next();
|
||||||
this.onLabelsChanged.unsubscribe();
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
composeDialog()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compose dialog
|
||||||
|
*/
|
||||||
|
composeDialog(): void
|
||||||
{
|
{
|
||||||
this.dialogRef = this.dialog.open(FuseMailComposeDialogComponent, {
|
this.dialogRef = this._matDialog.open(MailComposeDialogComponent, {
|
||||||
panelClass: 'mail-compose-dialog'
|
panelClass: 'mail-compose-dialog'
|
||||||
});
|
});
|
||||||
this.dialogRef.afterClosed()
|
this.dialogRef.afterClosed()
|
||||||
|
|
|
@ -67,6 +67,11 @@ export class Board
|
||||||
color: string
|
color: string
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param board
|
||||||
|
*/
|
||||||
constructor(board)
|
constructor(board)
|
||||||
{
|
{
|
||||||
this.name = board.name || 'Untitled Board';
|
this.name = board.name || 'Untitled Board';
|
||||||
|
|
|
@ -2,49 +2,77 @@ import { Component, EventEmitter, Output, ViewChild } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard-board-add-list',
|
selector : 'scrumboard-board-add-list',
|
||||||
templateUrl: './add-list.component.html',
|
templateUrl: './add-list.component.html',
|
||||||
styleUrls : ['./add-list.component.scss']
|
styleUrls : ['./add-list.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseScrumboardBoardAddListComponent
|
export class ScrumboardBoardAddListComponent
|
||||||
{
|
{
|
||||||
formActive = false;
|
formActive: boolean;
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
@Output() onlistAdd = new EventEmitter();
|
|
||||||
@ViewChild('nameInput') nameInputField;
|
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
onListAdd: EventEmitter<any>;
|
||||||
|
|
||||||
|
@ViewChild('nameInput')
|
||||||
|
nameInputField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {FormBuilder} _formBuilder
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder
|
private _formBuilder: FormBuilder
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.formActive = false;
|
||||||
|
this.onListAdd = new EventEmitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
openForm()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open form
|
||||||
|
*/
|
||||||
|
openForm(): void
|
||||||
{
|
{
|
||||||
this.form = this.formBuilder.group({
|
this.form = this._formBuilder.group({
|
||||||
name: ['']
|
name: ['']
|
||||||
});
|
});
|
||||||
this.formActive = true;
|
this.formActive = true;
|
||||||
this.focusNameField();
|
this.focusNameField();
|
||||||
}
|
}
|
||||||
|
|
||||||
closeForm()
|
/**
|
||||||
|
* Close form
|
||||||
|
*/
|
||||||
|
closeForm(): void
|
||||||
{
|
{
|
||||||
this.formActive = false;
|
this.formActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
focusNameField()
|
/**
|
||||||
|
* Focus to the name field
|
||||||
|
*/
|
||||||
|
focusNameField(): void
|
||||||
{
|
{
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.nameInputField.nativeElement.focus();
|
this.nameInputField.nativeElement.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onFormSubmit()
|
/**
|
||||||
|
* On form submit
|
||||||
|
*/
|
||||||
|
onFormSubmit(): void
|
||||||
{
|
{
|
||||||
if ( this.form.valid )
|
if ( this.form.valid )
|
||||||
{
|
{
|
||||||
this.onlistAdd.next(this.form.getRawValue().name);
|
this.onListAdd.next(this.form.getRawValue().name);
|
||||||
this.formActive = false;
|
this.formActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
fxFlex="1 0 100%" fxFlex.gt-xs="1 0 auto"
|
fxFlex="1 0 100%" fxFlex.gt-xs="1 0 auto"
|
||||||
fxFlexOrder="1" fxFlexOrder.gt-xs="2">
|
fxFlexOrder="1" fxFlexOrder.gt-xs="2">
|
||||||
<mat-icon *ngIf="board.settings.subscribed" class="board-subscribe s-16">remove_red_eye</mat-icon>
|
<mat-icon *ngIf="board.settings.subscribed" class="board-subscribe s-16">remove_red_eye</mat-icon>
|
||||||
<fuse-scrumboard-edit-board-name
|
<scrumboard-edit-board-name
|
||||||
[board]="board"
|
[board]="board"
|
||||||
(onNameChanged)="onBoardNameChanged($event)">
|
(onNameChanged)="onBoardNameChanged($event)">
|
||||||
</fuse-scrumboard-edit-board-name>
|
</scrumboard-edit-board-name>
|
||||||
</div>
|
</div>
|
||||||
<!-- / BOARD NAME -->
|
<!-- / BOARD NAME -->
|
||||||
|
|
||||||
|
@ -58,21 +58,21 @@
|
||||||
*fuseIfOnDom [@animateStagger]="{value:'50'}">
|
*fuseIfOnDom [@animateStagger]="{value:'50'}">
|
||||||
|
|
||||||
<!-- LIST -->
|
<!-- LIST -->
|
||||||
<fuse-scrumboard-board-list
|
<scrumboard-board-list
|
||||||
class="scrumboard-board-list list-wrapper ngx-dnd-item"
|
class="scrumboard-board-list list-wrapper ngx-dnd-item"
|
||||||
ngxDraggable
|
ngxDraggable
|
||||||
*ngFor="let list of board.lists"
|
*ngFor="let list of board.lists"
|
||||||
[model]="list"
|
[model]="list"
|
||||||
[list]="list"
|
[list]="list"
|
||||||
[@animate]="{value:'*',params:{duration:'350ms',x:'100%'}}">
|
[@animate]="{value:'*',params:{duration:'350ms',x:'100%'}}">
|
||||||
</fuse-scrumboard-board-list>
|
</scrumboard-board-list>
|
||||||
<!-- / LIST -->
|
<!-- / LIST -->
|
||||||
|
|
||||||
<!-- NEW LIST BUTTON-->
|
<!-- NEW LIST BUTTON-->
|
||||||
<fuse-scrumboard-board-add-list class="new-list-wrapper" (onlistAdd)="onListAdd($event)"
|
<scrumboard-board-add-list class="new-list-wrapper" (onListAdd)="onListAdd($event)"
|
||||||
ngxDraggable [moves]="false"
|
ngxDraggable [moves]="false"
|
||||||
[@animate]="{value:'*',params:{duration:'350ms',x:'100%'}}">
|
[@animate]="{value:'*',params:{duration:'350ms',x:'100%'}}">
|
||||||
</fuse-scrumboard-board-add-list>
|
</scrumboard-board-add-list>
|
||||||
<!-- / NEW LIST BUTTON-->
|
<!-- / NEW LIST BUTTON-->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mat-sidenav #settingsSidenav position="end">
|
<mat-sidenav #settingsSidenav position="end">
|
||||||
<fuse-scrumboard-board-settings></fuse-scrumboard-board-settings>
|
<scrumboard-board-settings></scrumboard-board-settings>
|
||||||
</mat-sidenav>
|
</mat-sidenav>
|
||||||
|
|
||||||
</mat-sidenav-container>
|
</mat-sidenav-container>
|
||||||
|
|
|
@ -1,65 +1,100 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
import { Subscription } from 'rxjs';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
|
|
||||||
import { List } from '../list.model';
|
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||||
import { ScrumboardService } from '../scrumboard.service';
|
import { List } from 'app/main/apps/scrumboard/list.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard-board',
|
selector : 'scrumboard-board',
|
||||||
templateUrl: './board.component.html',
|
templateUrl: './board.component.html',
|
||||||
styleUrls : ['./board.component.scss'],
|
styleUrls : ['./board.component.scss'],
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
export class FuseScrumboardBoardComponent implements OnInit, OnDestroy
|
export class ScrumboardBoardComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
board: any;
|
board: any;
|
||||||
onBoardChanged: Subscription;
|
|
||||||
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private _activatedRoute: ActivatedRoute,
|
||||||
private location: Location,
|
private _location: Location,
|
||||||
private scrumboardService: ScrumboardService
|
private _scrumboardService: ScrumboardService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.onBoardChanged =
|
this._scrumboardService.onBoardChanged
|
||||||
this.scrumboardService.onBoardChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(board => {
|
.subscribe(board => {
|
||||||
this.board = board;
|
this.board = board;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onBoardChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
onListAdd(newListName)
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On list add
|
||||||
|
*
|
||||||
|
* @param newListName
|
||||||
|
*/
|
||||||
|
onListAdd(newListName): void
|
||||||
{
|
{
|
||||||
if ( newListName === '' )
|
if ( newListName === '' )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scrumboardService.addList(new List({name: newListName}));
|
this._scrumboardService.addList(new List({name: newListName}));
|
||||||
}
|
}
|
||||||
|
|
||||||
onBoardNameChanged(newName)
|
/**
|
||||||
|
* On board name changed
|
||||||
|
*
|
||||||
|
* @param newName
|
||||||
|
*/
|
||||||
|
onBoardNameChanged(newName): void
|
||||||
{
|
{
|
||||||
this.scrumboardService.updateBoard();
|
this._scrumboardService.updateBoard();
|
||||||
this.location.go('/apps/scrumboard/boards/' + this.board.id + '/' + this.board.uri);
|
this._location.go('/apps/scrumboard/boards/' + this.board.id + '/' + this.board.uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDrop(ev)
|
/**
|
||||||
|
* On drop
|
||||||
|
*
|
||||||
|
* @param ev
|
||||||
|
*/
|
||||||
|
onDrop(ev): void
|
||||||
{
|
{
|
||||||
this.scrumboardService.updateBoard();
|
this._scrumboardService.updateBoard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,8 @@
|
||||||
|
|
||||||
<mat-menu #labelsMenu="matMenu" [overlapTrigger]="false" class="scrumboard-labels-menu">
|
<mat-menu #labelsMenu="matMenu" [overlapTrigger]="false" class="scrumboard-labels-menu">
|
||||||
|
|
||||||
<fuse-scrumboard-label-selector [card]="card"
|
<scrumboard-label-selector [card]="card"
|
||||||
(onCardLabelsChange)="updateCard()"></fuse-scrumboard-label-selector>
|
(onCardLabelsChange)="updateCard()"></scrumboard-label-selector>
|
||||||
|
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</div>
|
</div>
|
||||||
|
@ -130,7 +130,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- CLOSE DIALOG BUTTON -->
|
<!-- CLOSE DIALOG BUTTON -->
|
||||||
<button mat-icon-button (click)="dialogRef.close()" aria-label="Close Dialog">
|
<button mat-icon-button (click)="_matDialogRef.close()" aria-label="Close Dialog">
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<!-- / CLOSE DIALOG BUTTON -->
|
<!-- / CLOSE DIALOG BUTTON -->
|
||||||
|
|
|
@ -1,74 +1,108 @@
|
||||||
import { Component, Inject, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
import { Component, Inject, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||||
import { NgForm } from '@angular/forms/src/forms';
|
import { NgForm } from '@angular/forms/src/forms';
|
||||||
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef, MatMenuTrigger } from '@angular/material';
|
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef, MatMenuTrigger } from '@angular/material';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
|
|
||||||
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
|
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
|
||||||
import { FuseUtils } from '@fuse/utils';
|
import { FuseUtils } from '@fuse/utils';
|
||||||
|
|
||||||
import { ScrumboardService } from '../../../scrumboard.service';
|
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard-board-card-dialog',
|
selector : 'scrumboard-board-card-dialog',
|
||||||
templateUrl : './card.component.html',
|
templateUrl : './card.component.html',
|
||||||
styleUrls : ['./card.component.scss'],
|
styleUrls : ['./card.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
export class ScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
card: any;
|
card: any;
|
||||||
board: any;
|
board: any;
|
||||||
list: any;
|
list: any;
|
||||||
|
|
||||||
onBoardChanged: Subscription;
|
|
||||||
toggleInArray = FuseUtils.toggleInArray;
|
toggleInArray = FuseUtils.toggleInArray;
|
||||||
|
|
||||||
@ViewChild('checklistMenuTrigger') checklistMenu: MatMenuTrigger;
|
|
||||||
@ViewChild('newCheckListTitleField') newCheckListTitleField;
|
|
||||||
|
|
||||||
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
|
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
|
||||||
|
|
||||||
|
@ViewChild('checklistMenuTrigger')
|
||||||
|
checklistMenu: MatMenuTrigger;
|
||||||
|
|
||||||
|
@ViewChild('newCheckListTitleField')
|
||||||
|
newCheckListTitleField;
|
||||||
|
|
||||||
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {MatDialogRef<ScrumboardCardDialogComponent>} _matDialogRef
|
||||||
|
* @param _data
|
||||||
|
* @param {MatDialog} _matDialog
|
||||||
|
* @param {ScrumboardService} _scrumboardService
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<FuseScrumboardCardDialogComponent>,
|
private _matDialogRef: MatDialogRef<ScrumboardCardDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) private data: any,
|
@Inject(MAT_DIALOG_DATA) private _data: any,
|
||||||
public dialog: MatDialog,
|
private _matDialog: MatDialog,
|
||||||
private scrumboardService: ScrumboardService
|
private _scrumboardService: ScrumboardService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.onBoardChanged =
|
this._scrumboardService.onBoardChanged
|
||||||
this.scrumboardService.onBoardChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(board => {
|
.subscribe(board => {
|
||||||
this.board = board;
|
this.board = board;
|
||||||
|
|
||||||
this.card = this.board.cards.find((_card) => {
|
this.card = this.board.cards.find((_card) => {
|
||||||
return this.data.cardId === _card.id;
|
return this._data.cardId === _card.id;
|
||||||
});
|
|
||||||
|
|
||||||
this.list = this.board.lists.find((_list) => {
|
|
||||||
return this.data.listId === _list.id;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.list = this.board.lists.find((_list) => {
|
||||||
|
return this._data.listId === _list.id;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove Due date
|
* On destroy
|
||||||
*/
|
*/
|
||||||
removeDueDate()
|
ngOnDestroy(): void
|
||||||
|
{
|
||||||
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove due date
|
||||||
|
*/
|
||||||
|
removeDueDate(): void
|
||||||
{
|
{
|
||||||
this.card.due = '';
|
this.card.due = '';
|
||||||
this.updateCard();
|
this.updateCard();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle Subscribe
|
* Toggle subscribe
|
||||||
*/
|
*/
|
||||||
toggleSubscribe()
|
toggleSubscribe(): void
|
||||||
{
|
{
|
||||||
this.card.subscribed = !this.card.subscribed;
|
this.card.subscribed = !this.card.subscribed;
|
||||||
|
|
||||||
|
@ -76,10 +110,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle Cover Image
|
* Toggle cover image
|
||||||
|
*
|
||||||
* @param attachmentId
|
* @param attachmentId
|
||||||
*/
|
*/
|
||||||
toggleCoverImage(attachmentId)
|
toggleCoverImage(attachmentId): void
|
||||||
{
|
{
|
||||||
if ( this.card.idAttachmentCover === attachmentId )
|
if ( this.card.idAttachmentCover === attachmentId )
|
||||||
{
|
{
|
||||||
|
@ -94,10 +129,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove Attachment
|
* Remove attachment
|
||||||
|
*
|
||||||
* @param attachment
|
* @param attachment
|
||||||
*/
|
*/
|
||||||
removeAttachment(attachment)
|
removeAttachment(attachment): void
|
||||||
{
|
{
|
||||||
if ( attachment.id === this.card.idAttachmentCover )
|
if ( attachment.id === this.card.idAttachmentCover )
|
||||||
{
|
{
|
||||||
|
@ -110,10 +146,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove Checklist
|
* Remove checklist
|
||||||
|
*
|
||||||
* @param checklist
|
* @param checklist
|
||||||
*/
|
*/
|
||||||
removeChecklist(checklist)
|
removeChecklist(checklist): void
|
||||||
{
|
{
|
||||||
this.card.checklists.splice(this.card.checklists.indexOf(checklist), 1);
|
this.card.checklists.splice(this.card.checklists.indexOf(checklist), 1);
|
||||||
|
|
||||||
|
@ -121,10 +158,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update Checked Count
|
* Update checked count
|
||||||
|
*
|
||||||
* @param list
|
* @param list
|
||||||
*/
|
*/
|
||||||
updateCheckedCount(list)
|
updateCheckedCount(list): void
|
||||||
{
|
{
|
||||||
const checkItems = list.checkItems;
|
const checkItems = list.checkItems;
|
||||||
let checkedItems = 0;
|
let checkedItems = 0;
|
||||||
|
@ -154,11 +192,12 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove Checklist Item
|
* Remove checklist item
|
||||||
|
*
|
||||||
* @param checkItem
|
* @param checkItem
|
||||||
* @param checklist
|
* @param checklist
|
||||||
*/
|
*/
|
||||||
removeChecklistItem(checkItem, checklist)
|
removeChecklistItem(checkItem, checklist): void
|
||||||
{
|
{
|
||||||
checklist.checkItems.splice(checklist.checkItems.indexOf(checkItem), 1);
|
checklist.checkItems.splice(checklist.checkItems.indexOf(checkItem), 1);
|
||||||
|
|
||||||
|
@ -168,11 +207,12 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add Check Item
|
* Add check item
|
||||||
|
*
|
||||||
* @param {NgForm} form
|
* @param {NgForm} form
|
||||||
* @param checkList
|
* @param checkList
|
||||||
*/
|
*/
|
||||||
addCheckItem(form: NgForm, checkList)
|
addCheckItem(form: NgForm, checkList): void
|
||||||
{
|
{
|
||||||
const checkItemVal = form.value.checkItem;
|
const checkItemVal = form.value.checkItem;
|
||||||
|
|
||||||
|
@ -196,10 +236,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add Checklist
|
* Add checklist
|
||||||
|
*
|
||||||
* @param {NgForm} form
|
* @param {NgForm} form
|
||||||
*/
|
*/
|
||||||
addChecklist(form: NgForm)
|
addChecklist(form: NgForm): void
|
||||||
{
|
{
|
||||||
this.card.checklists.push({
|
this.card.checklists.push({
|
||||||
id : FuseUtils.generateGUID(),
|
id : FuseUtils.generateGUID(),
|
||||||
|
@ -215,9 +256,9 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On Checklist Menu Open
|
* On checklist menu open
|
||||||
*/
|
*/
|
||||||
onChecklistMenuOpen()
|
onChecklistMenuOpen(): void
|
||||||
{
|
{
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.newCheckListTitleField.nativeElement.focus();
|
this.newCheckListTitleField.nativeElement.focus();
|
||||||
|
@ -225,10 +266,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add New Comment
|
* Add new comment
|
||||||
|
*
|
||||||
* @param {NgForm} form
|
* @param {NgForm} form
|
||||||
*/
|
*/
|
||||||
addNewComment(form: NgForm)
|
addNewComment(form: NgForm): void
|
||||||
{
|
{
|
||||||
const newCommentText = form.value.newComment;
|
const newCommentText = form.value.newComment;
|
||||||
|
|
||||||
|
@ -246,11 +288,11 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove Card
|
* Remove card
|
||||||
*/
|
*/
|
||||||
removeCard()
|
removeCard(): void
|
||||||
{
|
{
|
||||||
this.confirmDialogRef = this.dialog.open(FuseConfirmDialogComponent, {
|
this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, {
|
||||||
disableClose: false
|
disableClose: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -259,22 +301,17 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy
|
||||||
this.confirmDialogRef.afterClosed().subscribe(result => {
|
this.confirmDialogRef.afterClosed().subscribe(result => {
|
||||||
if ( result )
|
if ( result )
|
||||||
{
|
{
|
||||||
this.dialogRef.close();
|
this._matDialogRef.close();
|
||||||
this.scrumboardService.removeCard(this.card.id, this.list.id);
|
this._scrumboardService.removeCard(this.card.id, this.list.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update Card
|
* Update card
|
||||||
*/
|
*/
|
||||||
updateCard()
|
updateCard(): void
|
||||||
{
|
{
|
||||||
this.scrumboardService.updateCard(this.card);
|
this._scrumboardService.updateCard(this.card);
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy()
|
|
||||||
{
|
|
||||||
this.onBoardChanged.unsubscribe();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,68 +1,110 @@
|
||||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
import { Subscription } from 'rxjs';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
import { FuseUtils } from '@fuse/utils';
|
import { FuseUtils } from '@fuse/utils';
|
||||||
|
|
||||||
import { ScrumboardService } from '../../../../scrumboard.service';
|
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard-label-selector',
|
selector : 'scrumboard-label-selector',
|
||||||
templateUrl : './label-selector.component.html',
|
templateUrl : './label-selector.component.html',
|
||||||
styleUrls : ['./label-selector.component.scss'],
|
styleUrls : ['./label-selector.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None,
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
|
|
||||||
export class FuseScrumboardLabelSelectorComponent implements OnInit, OnDestroy
|
export class ScrumboardLabelSelectorComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
|
@Input('card')
|
||||||
|
card: any;
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
onCardLabelsChange: EventEmitter<any>;
|
||||||
|
|
||||||
board: any;
|
board: any;
|
||||||
@Input('card') card: any;
|
labelsMenuView: string;
|
||||||
@Output() onCardLabelsChange = new EventEmitter();
|
|
||||||
|
|
||||||
labelsMenuView = 'labels';
|
|
||||||
selectedLabel: any;
|
selectedLabel: any;
|
||||||
newLabel = {
|
newLabel: any;
|
||||||
'id' : '',
|
toggleInArray: any;
|
||||||
'name' : '',
|
|
||||||
'color': 'mat-blue-400-bg'
|
|
||||||
};
|
|
||||||
toggleInArray = FuseUtils.toggleInArray;
|
|
||||||
|
|
||||||
onBoardChanged: Subscription;
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {ScrumboardService} _scrumboardService
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private scrumboardService: ScrumboardService
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.onBoardChanged =
|
this._scrumboardService.onBoardChanged
|
||||||
this.scrumboardService.onBoardChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(board => {
|
.subscribe(board => {
|
||||||
this.board = board;
|
this.board = board;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onBoardChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
cardLabelsChanged()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Card labels changed
|
||||||
|
*/
|
||||||
|
cardLabelsChanged(): void
|
||||||
{
|
{
|
||||||
this.onCardLabelsChange.next();
|
this.onCardLabelsChange.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
onLabelChange()
|
/**
|
||||||
|
* On label change
|
||||||
|
*/
|
||||||
|
onLabelChange(): void
|
||||||
{
|
{
|
||||||
this.scrumboardService.updateBoard();
|
this._scrumboardService.updateBoard();
|
||||||
}
|
}
|
||||||
|
|
||||||
addNewLabel()
|
/**
|
||||||
|
* Add new label
|
||||||
|
*/
|
||||||
|
addNewLabel(): void
|
||||||
{
|
{
|
||||||
this.newLabel.id = FuseUtils.generateGUID();
|
this.newLabel.id = FuseUtils.generateGUID();
|
||||||
this.board.labels.push(Object.assign({}, this.newLabel));
|
this.board.labels.push(Object.assign({}, this.newLabel));
|
||||||
|
|
|
@ -2,25 +2,41 @@ import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard-edit-board-name',
|
selector : 'scrumboard-edit-board-name',
|
||||||
templateUrl: './edit-board-name.component.html',
|
templateUrl: './edit-board-name.component.html',
|
||||||
styleUrls : ['./edit-board-name.component.scss']
|
styleUrls : ['./edit-board-name.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseScrumboardEditBoardNameComponent
|
export class ScrumboardEditBoardNameComponent
|
||||||
{
|
{
|
||||||
formActive = false;
|
formActive: boolean;
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
@Input() board;
|
|
||||||
@Output() onNameChanged = new EventEmitter();
|
@Input()
|
||||||
@ViewChild('nameInput') nameInputField;
|
board;
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
onNameChanged: EventEmitter<any>;
|
||||||
|
|
||||||
|
@ViewChild('nameInput')
|
||||||
|
nameInputField;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder
|
private formBuilder: FormBuilder
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.formActive = false;
|
||||||
|
this.onNameChanged = new EventEmitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
openForm()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open form
|
||||||
|
*/
|
||||||
|
openForm(): void
|
||||||
{
|
{
|
||||||
this.form = this.formBuilder.group({
|
this.form = this.formBuilder.group({
|
||||||
name: [this.board.name]
|
name: [this.board.name]
|
||||||
|
@ -29,19 +45,28 @@ export class FuseScrumboardEditBoardNameComponent
|
||||||
this.focusNameField();
|
this.focusNameField();
|
||||||
}
|
}
|
||||||
|
|
||||||
closeForm()
|
/**
|
||||||
|
* Close form
|
||||||
|
*/
|
||||||
|
closeForm(): void
|
||||||
{
|
{
|
||||||
this.formActive = false;
|
this.formActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
focusNameField()
|
/**
|
||||||
|
* Focus to the name field
|
||||||
|
*/
|
||||||
|
focusNameField(): void
|
||||||
{
|
{
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.nameInputField.nativeElement.focus();
|
this.nameInputField.nativeElement.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onFormSubmit()
|
/**
|
||||||
|
* On form submit
|
||||||
|
*/
|
||||||
|
onFormSubmit(): void
|
||||||
{
|
{
|
||||||
if ( this.form.valid )
|
if ( this.form.valid )
|
||||||
{
|
{
|
||||||
|
@ -52,5 +77,4 @@ export class FuseScrumboardEditBoardNameComponent
|
||||||
this.formActive = false;
|
this.formActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,45 +2,73 @@ import { Component, EventEmitter, Output, ViewChild } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard-board-add-card',
|
selector : 'scrumboard-board-add-card',
|
||||||
templateUrl: './add-card.component.html',
|
templateUrl: './add-card.component.html',
|
||||||
styleUrls : ['./add-card.component.scss']
|
styleUrls : ['./add-card.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseScrumboardBoardAddCardComponent
|
export class ScrumboardBoardAddCardComponent
|
||||||
{
|
{
|
||||||
formActive = false;
|
formActive: boolean;
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
@Output() onCardAdd = new EventEmitter();
|
|
||||||
@ViewChild('nameInput') nameInputField;
|
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
onCardAdd: EventEmitter<any>;
|
||||||
|
|
||||||
|
@ViewChild('nameInput')
|
||||||
|
nameInputField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {FormBuilder} _formBuilder
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder
|
private _formBuilder: FormBuilder
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.formActive = false;
|
||||||
|
this.onCardAdd = new EventEmitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
openForm()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the form
|
||||||
|
*/
|
||||||
|
openForm(): void
|
||||||
{
|
{
|
||||||
this.form = this.formBuilder.group({
|
this.form = this._formBuilder.group({
|
||||||
name: ''
|
name: ''
|
||||||
});
|
});
|
||||||
this.formActive = true;
|
this.formActive = true;
|
||||||
this.focusNameField();
|
this.focusNameField();
|
||||||
}
|
}
|
||||||
|
|
||||||
closeForm()
|
/**
|
||||||
|
* Close the form
|
||||||
|
*/
|
||||||
|
closeForm(): void
|
||||||
{
|
{
|
||||||
this.formActive = false;
|
this.formActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
focusNameField()
|
/**
|
||||||
|
* Focus to the name field
|
||||||
|
*/
|
||||||
|
focusNameField(): void
|
||||||
{
|
{
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.nameInputField.nativeElement.focus();
|
this.nameInputField.nativeElement.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onFormSubmit()
|
/**
|
||||||
|
* On form submit
|
||||||
|
*/
|
||||||
|
onFormSubmit(): void
|
||||||
{
|
{
|
||||||
if ( this.form.valid )
|
if ( this.form.valid )
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,40 +3,57 @@ import { ActivatedRoute } from '@angular/router';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard-board-card',
|
selector : 'scrumboard-board-card',
|
||||||
templateUrl : './card.component.html',
|
templateUrl : './card.component.html',
|
||||||
styleUrls : ['./card.component.scss'],
|
styleUrls : ['./card.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class FuseScrumboardBoardCardComponent implements OnInit
|
export class ScrumboardBoardCardComponent implements OnInit
|
||||||
{
|
{
|
||||||
@Input() cardId;
|
@Input()
|
||||||
|
cardId;
|
||||||
|
|
||||||
card: any;
|
card: any;
|
||||||
board: any;
|
board: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {ActivatedRoute} _activatedRoute
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private _activatedRoute: ActivatedRoute
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.board = this.route.snapshot.data.board;
|
this.board = this._activatedRoute.snapshot.data.board;
|
||||||
this.card = this.board.cards.filter((card) => {
|
this.card = this.board.cards.filter((card) => {
|
||||||
return this.cardId === card.id;
|
return this.cardId === card.id;
|
||||||
})[0];
|
})[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the card overdue?
|
* Is the card overdue?
|
||||||
*
|
*
|
||||||
* @param cardDate
|
* @param cardDate
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
isOverdue(cardDate)
|
isOverdue(cardDate): boolean
|
||||||
{
|
{
|
||||||
return moment() > moment(new Date(cardDate));
|
return moment() > moment(new Date(cardDate));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,46 +2,76 @@ import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard-board-edit-list-name',
|
selector : 'scrumboard-board-edit-list-name',
|
||||||
templateUrl: './edit-list-name.component.html',
|
templateUrl: './edit-list-name.component.html',
|
||||||
styleUrls : ['./edit-list-name.component.scss']
|
styleUrls : ['./edit-list-name.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseScrumboardBoardEditListNameComponent
|
export class ScrumboardBoardEditListNameComponent
|
||||||
{
|
{
|
||||||
formActive = false;
|
formActive: boolean;
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
@Input() list;
|
|
||||||
@Output() onNameChanged = new EventEmitter();
|
|
||||||
@ViewChild('nameInput') nameInputField;
|
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
list;
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
onNameChanged: EventEmitter<any>;
|
||||||
|
|
||||||
|
@ViewChild('nameInput')
|
||||||
|
nameInputField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {FormBuilder} _formBuilder
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder
|
private _formBuilder: FormBuilder
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.formActive = false;
|
||||||
|
this.onNameChanged = new EventEmitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
openForm()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the form
|
||||||
|
*/
|
||||||
|
openForm(): void
|
||||||
{
|
{
|
||||||
this.form = this.formBuilder.group({
|
this.form = this._formBuilder.group({
|
||||||
name: [this.list.name]
|
name: [this.list.name]
|
||||||
});
|
});
|
||||||
this.formActive = true;
|
this.formActive = true;
|
||||||
this.focusNameField();
|
this.focusNameField();
|
||||||
}
|
}
|
||||||
|
|
||||||
closeForm()
|
/**
|
||||||
|
* Close the form
|
||||||
|
*/
|
||||||
|
closeForm(): void
|
||||||
{
|
{
|
||||||
this.formActive = false;
|
this.formActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
focusNameField()
|
/**
|
||||||
|
* Focus to the name field
|
||||||
|
*/
|
||||||
|
focusNameField(): void
|
||||||
{
|
{
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.nameInputField.nativeElement.focus();
|
this.nameInputField.nativeElement.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onFormSubmit()
|
/**
|
||||||
|
* On form submit
|
||||||
|
*/
|
||||||
|
onFormSubmit(): void
|
||||||
{
|
{
|
||||||
if ( this.form.valid )
|
if ( this.form.valid )
|
||||||
{
|
{
|
||||||
|
@ -50,5 +80,4 @@ export class FuseScrumboardBoardEditListNameComponent
|
||||||
this.formActive = false;
|
this.formActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
<!-- LIST HEADER -->
|
<!-- LIST HEADER -->
|
||||||
<div class="list-header" fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
<div class="list-header" fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||||
|
|
||||||
<fuse-scrumboard-board-edit-list-name
|
<scrumboard-board-edit-list-name
|
||||||
fxFlex="1 0 auto"
|
fxFlex="1 0 auto"
|
||||||
[list]="list"
|
[list]="list"
|
||||||
(onNameChanged)="onListNameChanged($event)">
|
(onNameChanged)="onListNameChanged($event)">
|
||||||
</fuse-scrumboard-board-edit-list-name>
|
</scrumboard-board-edit-list-name>
|
||||||
|
|
||||||
<div fxFlex="0 1 auto">
|
<div fxFlex="0 1 auto">
|
||||||
<button mat-icon-button class="list-header-option-button" [matMenuTriggerFor]="listMenu">
|
<button mat-icon-button class="list-header-option-button" [matMenuTriggerFor]="listMenu">
|
||||||
|
@ -27,21 +27,21 @@
|
||||||
<div class="list-cards ngx-dnd-container"
|
<div class="list-cards ngx-dnd-container"
|
||||||
[model]="list.idCards" ngxDroppable="card" (out)="onDrop($event)"
|
[model]="list.idCards" ngxDroppable="card" (out)="onDrop($event)"
|
||||||
fusePerfectScrollbar #listScroll>
|
fusePerfectScrollbar #listScroll>
|
||||||
<fuse-scrumboard-board-card ngxDraggable
|
<scrumboard-board-card ngxDraggable
|
||||||
(click)="openCardDialog(cardId)"
|
(click)="openCardDialog(cardId)"
|
||||||
class="scrumboard-board-card mat-elevation-z2 ngx-dnd-item"
|
class="scrumboard-board-card mat-elevation-z2 ngx-dnd-item"
|
||||||
*ngFor="let cardId of list.idCards"
|
*ngFor="let cardId of list.idCards"
|
||||||
[model]="cardId"
|
[model]="cardId"
|
||||||
[cardId]="cardId">
|
[cardId]="cardId">
|
||||||
</fuse-scrumboard-board-card>
|
</scrumboard-board-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- / LIST CONTENT -->
|
<!-- / LIST CONTENT -->
|
||||||
|
|
||||||
<!-- NEW CARD BUTTON-->
|
<!-- NEW CARD BUTTON-->
|
||||||
<div class="list-footer">
|
<div class="list-footer">
|
||||||
<fuse-scrumboard-board-add-card (onCardAdd)="onCardAdd($event)">
|
<scrumboard-board-add-card (onCardAdd)="onCardAdd($event)">
|
||||||
</fuse-scrumboard-board-add-card>
|
</scrumboard-board-add-card>
|
||||||
</div>
|
</div>
|
||||||
<!-- / NEW CARD BUTTON-->
|
<!-- / NEW CARD BUTTON-->
|
||||||
|
|
||||||
|
|
|
@ -1,78 +1,122 @@
|
||||||
import { Component, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
import { Component, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { MatDialog, MatDialogRef } from '@angular/material';
|
import { MatDialog, MatDialogRef } from '@angular/material';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
import { Subscription } from 'rxjs';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
|
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
|
||||||
import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
||||||
|
|
||||||
import { Card } from '../../card.model';
|
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||||
import { ScrumboardService } from '../../scrumboard.service';
|
import { Card } from 'app/main/apps/scrumboard/card.model';
|
||||||
import { FuseScrumboardCardDialogComponent } from '../dialogs/card/card.component';
|
import { ScrumboardCardDialogComponent } from 'app/main/apps/scrumboard/board/dialogs/card/card.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard-board-list',
|
selector : 'scrumboard-board-list',
|
||||||
templateUrl : './list.component.html',
|
templateUrl : './list.component.html',
|
||||||
styleUrls : ['./list.component.scss'],
|
styleUrls : ['./list.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class FuseScrumboardBoardListComponent implements OnInit, OnDestroy
|
export class ScrumboardBoardListComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
board: any;
|
board: any;
|
||||||
dialogRef: any;
|
dialogRef: any;
|
||||||
|
|
||||||
@Input() list;
|
@Input()
|
||||||
@ViewChild(FusePerfectScrollbarDirective) listScroll: FusePerfectScrollbarDirective;
|
list;
|
||||||
|
|
||||||
|
@ViewChild(FusePerfectScrollbarDirective)
|
||||||
|
listScroll: FusePerfectScrollbarDirective;
|
||||||
|
|
||||||
onBoardChanged: Subscription;
|
|
||||||
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
|
confirmDialogRef: MatDialogRef<FuseConfirmDialogComponent>;
|
||||||
|
|
||||||
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {ActivatedRoute} _activatedRoute
|
||||||
|
* @param {ScrumboardService} _scrumboardService
|
||||||
|
* @param {MatDialog} _matDialog
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private _activatedRoute: ActivatedRoute,
|
||||||
private scrumboardService: ScrumboardService,
|
private _scrumboardService: ScrumboardService,
|
||||||
public dialog: MatDialog
|
private _matDialog: MatDialog
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.onBoardChanged =
|
this._scrumboardService.onBoardChanged
|
||||||
this.scrumboardService.onBoardChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(board => {
|
.subscribe(board => {
|
||||||
this.board = board;
|
this.board = board;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onBoardChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
onListNameChanged(newListName)
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On list name changed
|
||||||
|
*
|
||||||
|
* @param newListName
|
||||||
|
*/
|
||||||
|
onListNameChanged(newListName): void
|
||||||
{
|
{
|
||||||
this.list.name = newListName;
|
this.list.name = newListName;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCardAdd(newCardName)
|
/**
|
||||||
|
* On card added
|
||||||
|
*
|
||||||
|
* @param newCardName
|
||||||
|
*/
|
||||||
|
onCardAdd(newCardName): void
|
||||||
{
|
{
|
||||||
if ( newCardName === '' )
|
if ( newCardName === '' )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scrumboardService.addCard(this.list.id, new Card({name: newCardName}));
|
this._scrumboardService.addCard(this.list.id, new Card({name: newCardName}));
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.listScroll.scrollToBottom(0, 400);
|
this.listScroll.scrollToBottom(0, 400);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeList(listId)
|
/**
|
||||||
|
* Remove list
|
||||||
|
*
|
||||||
|
* @param listId
|
||||||
|
*/
|
||||||
|
removeList(listId): void
|
||||||
{
|
{
|
||||||
this.confirmDialogRef = this.dialog.open(FuseConfirmDialogComponent, {
|
this.confirmDialogRef = this._matDialog.open(FuseConfirmDialogComponent, {
|
||||||
disableClose: false
|
disableClose: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -81,14 +125,19 @@ export class FuseScrumboardBoardListComponent implements OnInit, OnDestroy
|
||||||
this.confirmDialogRef.afterClosed().subscribe(result => {
|
this.confirmDialogRef.afterClosed().subscribe(result => {
|
||||||
if ( result )
|
if ( result )
|
||||||
{
|
{
|
||||||
this.scrumboardService.removeList(listId);
|
this._scrumboardService.removeList(listId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openCardDialog(cardId)
|
/**
|
||||||
|
* Open card dialog
|
||||||
|
*
|
||||||
|
* @param cardId
|
||||||
|
*/
|
||||||
|
openCardDialog(cardId): void
|
||||||
{
|
{
|
||||||
this.dialogRef = this.dialog.open(FuseScrumboardCardDialogComponent, {
|
this.dialogRef = this._matDialog.open(ScrumboardCardDialogComponent, {
|
||||||
panelClass: 'scrumboard-card-dialog',
|
panelClass: 'scrumboard-card-dialog',
|
||||||
data : {
|
data : {
|
||||||
cardId: cardId,
|
cardId: cardId,
|
||||||
|
@ -101,8 +150,13 @@ export class FuseScrumboardBoardListComponent implements OnInit, OnDestroy
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onDrop(ev)
|
/**
|
||||||
|
* On drop
|
||||||
|
*
|
||||||
|
* @param ev
|
||||||
|
*/
|
||||||
|
onDrop(ev): void
|
||||||
{
|
{
|
||||||
this.scrumboardService.updateBoard();
|
this._scrumboardService.updateBoard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +1,78 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
import { Subscription } from 'rxjs';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { MatColors } from '@fuse/mat-colors';
|
import { MatColors } from '@fuse/mat-colors';
|
||||||
|
|
||||||
import { ScrumboardService } from '../../../../scrumboard.service';
|
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard-board-color-selector',
|
selector : 'scrumboard-board-color-selector',
|
||||||
templateUrl: './board-color-selector.component.html',
|
templateUrl: './board-color-selector.component.html',
|
||||||
styleUrls : ['./board-color-selector.component.scss']
|
styleUrls : ['./board-color-selector.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseScrumboardBoardColorSelectorComponent implements OnInit, OnDestroy
|
export class ScrumboardBoardColorSelectorComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
colors: any;
|
colors: any;
|
||||||
board: any;
|
board: any;
|
||||||
onBoardChanged: Subscription;
|
|
||||||
|
|
||||||
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {ScrumboardService} _scrumboardService
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private scrumboardService: ScrumboardService
|
private _scrumboardService: ScrumboardService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
this.colors = MatColors.all;
|
this.colors = MatColors.all;
|
||||||
|
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.onBoardChanged =
|
this._scrumboardService.onBoardChanged
|
||||||
this.scrumboardService.onBoardChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(board => {
|
.subscribe(board => {
|
||||||
this.board = board;
|
this.board = board;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onBoardChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
setColor(color)
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color
|
||||||
|
*
|
||||||
|
* @param color
|
||||||
|
*/
|
||||||
|
setColor(color): void
|
||||||
{
|
{
|
||||||
this.board.settings.color = color;
|
this.board.settings.color = color;
|
||||||
this.scrumboardService.updateBoard();
|
this._scrumboardService.updateBoard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="nav-item">
|
<div class="nav-item">
|
||||||
<div class="nav-link" matRipple (click)="toggleSubcription()">
|
<div class="nav-link" matRipple (click)="toggleSubscription()">
|
||||||
<mat-icon class="nav-link-icon">remove_red_eye</mat-icon>
|
<mat-icon class="nav-link-icon">remove_red_eye</mat-icon>
|
||||||
<p fxFlex class="title">Subscribe</p>
|
<p fxFlex class="title">Subscribe</p>
|
||||||
<mat-icon *ngIf="board.settings.subscribed" class="s-18">check</mat-icon>
|
<mat-icon *ngIf="board.settings.subscribed" class="s-18">check</mat-icon>
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
|
|
||||||
<!-- SIDENAV CONTENT -->
|
<!-- SIDENAV CONTENT -->
|
||||||
<div class="content p-8" fusePerfectScrollbar>
|
<div class="content p-8" fusePerfectScrollbar>
|
||||||
<fuse-scrumboard-board-color-selector></fuse-scrumboard-board-color-selector>
|
<scrumboard-board-color-selector></scrumboard-board-color-selector>
|
||||||
</div>
|
</div>
|
||||||
<!-- / SIDENAV CONTENT -->
|
<!-- / SIDENAV CONTENT -->
|
||||||
|
|
||||||
|
|
|
@ -1,50 +1,78 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
|
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
|
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||||
import { ScrumboardService } from '../../../scrumboard.service';
|
import { Subject } from 'rxjs';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard-board-settings',
|
selector : 'scrumboard-board-settings',
|
||||||
templateUrl: './settings.component.html',
|
templateUrl: './settings.component.html',
|
||||||
styleUrls : ['./settings.component.scss'],
|
styleUrls : ['./settings.component.scss'],
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
export class FuseScrumboardBoardSettingsSidenavComponent implements OnInit, OnDestroy
|
export class ScrumboardBoardSettingsSidenavComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
board: any;
|
board: any;
|
||||||
view = 'main';
|
view: string;
|
||||||
onBoardChanged: Subscription;
|
|
||||||
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private scrumboardService: ScrumboardService
|
private scrumboardService: ScrumboardService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.view = 'main';
|
||||||
|
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.onBoardChanged =
|
this.scrumboardService.onBoardChanged
|
||||||
this.scrumboardService.onBoardChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(board => {
|
.subscribe(board => {
|
||||||
this.board = board;
|
this.board = board;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onBoardChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleCardCover()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle card cover
|
||||||
|
*/
|
||||||
|
toggleCardCover(): void
|
||||||
{
|
{
|
||||||
this.board.settings.cardCoverImages = !this.board.settings.cardCoverImages;
|
this.board.settings.cardCoverImages = !this.board.settings.cardCoverImages;
|
||||||
this.scrumboardService.updateBoard();
|
this.scrumboardService.updateBoard();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSubcription()
|
/**
|
||||||
|
* Toggle subscription
|
||||||
|
*/
|
||||||
|
toggleSubscription(): void
|
||||||
{
|
{
|
||||||
this.board.settings.subscribed = !this.board.settings.subscribed;
|
this.board.settings.subscribed = !this.board.settings.subscribed;
|
||||||
this.scrumboardService.updateBoard();
|
this.scrumboardService.updateBoard();
|
||||||
|
|
|
@ -17,6 +17,11 @@ export class Card
|
||||||
activities: any[];
|
activities: any[];
|
||||||
due: string;
|
due: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param card
|
||||||
|
*/
|
||||||
constructor(card)
|
constructor(card)
|
||||||
{
|
{
|
||||||
this.id = card.id || FuseUtils.generateGUID();
|
this.id = card.id || FuseUtils.generateGUID();
|
||||||
|
|
|
@ -6,6 +6,11 @@ export class List
|
||||||
name: string;
|
name: string;
|
||||||
idCards: string[];
|
idCards: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
*/
|
||||||
constructor(list)
|
constructor(list)
|
||||||
{
|
{
|
||||||
this.id = list.id || FuseUtils.generateGUID();
|
this.id = list.id || FuseUtils.generateGUID();
|
||||||
|
|
|
@ -1,50 +1,79 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
import { Subscription } from 'rxjs';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
|
|
||||||
import { Board } from './board.model';
|
import { ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||||
import { ScrumboardService } from './scrumboard.service';
|
import { Board } from 'app/main/apps/scrumboard/board.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-scrumboard',
|
selector : 'scrumboard',
|
||||||
templateUrl: './scrumboard.component.html',
|
templateUrl: './scrumboard.component.html',
|
||||||
styleUrls : ['./scrumboard.component.scss'],
|
styleUrls : ['./scrumboard.component.scss'],
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
export class FuseScrumboardComponent implements OnInit, OnDestroy
|
export class ScrumboardComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
boards: any[];
|
boards: any[];
|
||||||
onBoardsChanged: Subscription;
|
|
||||||
|
|
||||||
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {Router} _router
|
||||||
|
* @param {ScrumboardService} _scrumboardService
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private _router: Router,
|
||||||
private scrumboardService: ScrumboardService
|
private _scrumboardService: ScrumboardService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.onBoardsChanged =
|
this._scrumboardService.onBoardsChanged
|
||||||
this.scrumboardService.onBoardsChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(boards => {
|
.subscribe(boards => {
|
||||||
this.boards = boards;
|
this.boards = boards;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onBoardsChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
newBoard()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New board
|
||||||
|
*/
|
||||||
|
newBoard(): void
|
||||||
{
|
{
|
||||||
const newBoard = new Board({});
|
const newBoard = new Board({});
|
||||||
this.scrumboardService.createNewBoard(newBoard).then(() => {
|
this._scrumboardService.createNewBoard(newBoard).then(() => {
|
||||||
this.router.navigate(['/apps/scrumboard/boards/' + newBoard.id + '/' + newBoard.uri]);
|
this._router.navigate(['/apps/scrumboard/boards/' + newBoard.id + '/' + newBoard.uri]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,36 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
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 { 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 { FuseSharedModule } from '@fuse/shared.module';
|
||||||
import { FuseConfirmDialogModule, FuseMaterialColorPickerModule } from '@fuse/components';
|
import { FuseConfirmDialogModule, FuseMaterialColorPickerModule } from '@fuse/components';
|
||||||
|
|
||||||
import { BoardResolve, ScrumboardService } from './scrumboard.service';
|
import { BoardResolve, ScrumboardService } from 'app/main/apps/scrumboard/scrumboard.service';
|
||||||
import { FuseScrumboardComponent } from './scrumboard.component';
|
import { ScrumboardComponent } from 'app/main/apps/scrumboard/scrumboard.component';
|
||||||
import { FuseScrumboardBoardComponent } from './board/board.component';
|
import { ScrumboardBoardComponent } from 'app/main/apps/scrumboard/board/board.component';
|
||||||
import { FuseScrumboardBoardListComponent } from './board/list/list.component';
|
import { ScrumboardBoardListComponent } from 'app/main/apps/scrumboard/board/list/list.component';
|
||||||
import { FuseScrumboardBoardCardComponent } from './board/list/card/card.component';
|
import { ScrumboardBoardCardComponent } from 'app/main/apps/scrumboard/board/list/card/card.component';
|
||||||
import { FuseScrumboardBoardEditListNameComponent } from './board/list/edit-list-name/edit-list-name.component';
|
import { ScrumboardBoardEditListNameComponent } from 'app/main/apps/scrumboard/board/list/edit-list-name/edit-list-name.component';
|
||||||
import { FuseScrumboardBoardAddCardComponent } from './board/list/add-card/add-card.component';
|
import { ScrumboardBoardAddCardComponent } from 'app/main/apps/scrumboard/board/list/add-card/add-card.component';
|
||||||
import { FuseScrumboardBoardAddListComponent } from './board/add-list/add-list.component';
|
import { ScrumboardBoardAddListComponent } from 'app/main/apps/scrumboard/board/add-list/add-list.component';
|
||||||
import { FuseScrumboardCardDialogComponent } from './board/dialogs/card/card.component';
|
import { ScrumboardCardDialogComponent } from 'app/main/apps/scrumboard/board/dialogs/card/card.component';
|
||||||
import { FuseScrumboardLabelSelectorComponent } from './board/dialogs/card/label-selector/label-selector.component';
|
import { ScrumboardLabelSelectorComponent } from 'app/main/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component';
|
||||||
import { FuseScrumboardEditBoardNameComponent } from './board/edit-board-name/edit-board-name.component';
|
import { ScrumboardEditBoardNameComponent } from 'app/main/apps/scrumboard/board/edit-board-name/edit-board-name.component';
|
||||||
import { FuseScrumboardBoardSettingsSidenavComponent } from './board/sidenavs/settings/settings.component';
|
import { ScrumboardBoardSettingsSidenavComponent } from 'app/main/apps/scrumboard/board/sidenavs/settings/settings.component';
|
||||||
import { FuseScrumboardBoardColorSelectorComponent } from './board/sidenavs/settings/board-color-selector/board-color-selector.component';
|
import { ScrumboardBoardColorSelectorComponent } from 'app/main/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component';
|
||||||
import { NgxDnDModule } from '@swimlane/ngx-dnd';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path : 'boards',
|
path : 'boards',
|
||||||
component: FuseScrumboardComponent,
|
component: ScrumboardComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
scrumboard: ScrumboardService
|
scrumboard: ScrumboardService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'boards/:boardId/:boardUri',
|
path : 'boards/:boardId/:boardUri',
|
||||||
component: FuseScrumboardBoardComponent,
|
component: ScrumboardBoardComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
board: BoardResolve
|
board: BoardResolve
|
||||||
}
|
}
|
||||||
|
@ -44,18 +43,18 @@ const routes: Routes = [
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations : [
|
declarations : [
|
||||||
FuseScrumboardComponent,
|
ScrumboardComponent,
|
||||||
FuseScrumboardBoardComponent,
|
ScrumboardBoardComponent,
|
||||||
FuseScrumboardBoardListComponent,
|
ScrumboardBoardListComponent,
|
||||||
FuseScrumboardBoardCardComponent,
|
ScrumboardBoardCardComponent,
|
||||||
FuseScrumboardBoardEditListNameComponent,
|
ScrumboardBoardEditListNameComponent,
|
||||||
FuseScrumboardBoardAddCardComponent,
|
ScrumboardBoardAddCardComponent,
|
||||||
FuseScrumboardBoardAddListComponent,
|
ScrumboardBoardAddListComponent,
|
||||||
FuseScrumboardCardDialogComponent,
|
ScrumboardCardDialogComponent,
|
||||||
FuseScrumboardLabelSelectorComponent,
|
ScrumboardLabelSelectorComponent,
|
||||||
FuseScrumboardEditBoardNameComponent,
|
ScrumboardEditBoardNameComponent,
|
||||||
FuseScrumboardBoardSettingsSidenavComponent,
|
ScrumboardBoardSettingsSidenavComponent,
|
||||||
FuseScrumboardBoardColorSelectorComponent
|
ScrumboardBoardColorSelectorComponent
|
||||||
],
|
],
|
||||||
imports : [
|
imports : [
|
||||||
RouterModule.forChild(routes),
|
RouterModule.forChild(routes),
|
||||||
|
@ -86,7 +85,7 @@ const routes: Routes = [
|
||||||
ScrumboardService,
|
ScrumboardService,
|
||||||
BoardResolve
|
BoardResolve
|
||||||
],
|
],
|
||||||
entryComponents: [FuseScrumboardCardDialogComponent]
|
entryComponents: [ScrumboardCardDialogComponent]
|
||||||
})
|
})
|
||||||
export class FuseScrumboardModule
|
export class FuseScrumboardModule
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||||
|
|
||||||
import { Observable, BehaviorSubject } from 'rxjs';
|
import { Observable, BehaviorSubject } from 'rxjs';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -11,15 +10,26 @@ export class ScrumboardService implements Resolve<any>
|
||||||
routeParams: any;
|
routeParams: any;
|
||||||
board: any;
|
board: any;
|
||||||
|
|
||||||
onBoardsChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onBoardsChanged: BehaviorSubject<any>;
|
||||||
onBoardChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onBoardChanged: BehaviorSubject<any>;
|
||||||
|
|
||||||
constructor(private http: HttpClient)
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {HttpClient} _httpClient
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private _httpClient: HttpClient
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onBoardsChanged = new BehaviorSubject([]);
|
||||||
|
this.onBoardChanged = new BehaviorSubject([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve
|
* Resolver
|
||||||
|
*
|
||||||
* @param {ActivatedRouteSnapshot} route
|
* @param {ActivatedRouteSnapshot} route
|
||||||
* @param {RouterStateSnapshot} state
|
* @param {RouterStateSnapshot} state
|
||||||
* @returns {Observable<any> | Promise<any> | any}
|
* @returns {Observable<any> | Promise<any> | any}
|
||||||
|
@ -40,10 +50,15 @@ export class ScrumboardService implements Resolve<any>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get boards
|
||||||
|
*
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
getBoards(): Promise<any>
|
getBoards(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/scrumboard-boards')
|
this._httpClient.get('api/scrumboard-boards')
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
this.boards = response;
|
this.boards = response;
|
||||||
this.onBoardsChanged.next(this.boards);
|
this.onBoardsChanged.next(this.boards);
|
||||||
|
@ -52,10 +67,16 @@ export class ScrumboardService implements Resolve<any>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get board
|
||||||
|
*
|
||||||
|
* @param boardId
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
getBoard(boardId): Promise<any>
|
getBoard(boardId): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/scrumboard-boards/' + boardId)
|
this._httpClient.get('api/scrumboard-boards/' + boardId)
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
this.board = response;
|
this.board = response;
|
||||||
this.onBoardChanged.next(this.board);
|
this.onBoardChanged.next(this.board);
|
||||||
|
@ -64,7 +85,14 @@ export class ScrumboardService implements Resolve<any>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addCard(listId, newCard)
|
/**
|
||||||
|
* Add card
|
||||||
|
*
|
||||||
|
* @param listId
|
||||||
|
* @param newCard
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
addCard(listId, newCard): Promise<any>
|
||||||
{
|
{
|
||||||
this.board.lists.map((list) => {
|
this.board.lists.map((list) => {
|
||||||
if ( list.id === listId )
|
if ( list.id === listId )
|
||||||
|
@ -78,16 +106,26 @@ export class ScrumboardService implements Resolve<any>
|
||||||
return this.updateBoard();
|
return this.updateBoard();
|
||||||
}
|
}
|
||||||
|
|
||||||
addList(newList)
|
/**
|
||||||
|
* Add list
|
||||||
|
*
|
||||||
|
* @param newList
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
addList(newList): Promise<any>
|
||||||
{
|
{
|
||||||
|
|
||||||
this.board.lists.push(newList);
|
this.board.lists.push(newList);
|
||||||
|
|
||||||
return this.updateBoard();
|
return this.updateBoard();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeList(listId)
|
/**
|
||||||
|
* Remove list
|
||||||
|
*
|
||||||
|
* @param listId
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
removeList(listId): Promise<any>
|
||||||
{
|
{
|
||||||
const list = this.board.lists.find((_list) => {
|
const list = this.board.lists.find((_list) => {
|
||||||
return _list.id === listId;
|
return _list.id === listId;
|
||||||
|
@ -105,9 +143,14 @@ export class ScrumboardService implements Resolve<any>
|
||||||
return this.updateBoard();
|
return this.updateBoard();
|
||||||
}
|
}
|
||||||
|
|
||||||
removeCard(cardId, listId?)
|
/**
|
||||||
|
* Remove card
|
||||||
|
*
|
||||||
|
* @param cardId
|
||||||
|
* @param listId
|
||||||
|
*/
|
||||||
|
removeCard(cardId, listId?): void
|
||||||
{
|
{
|
||||||
|
|
||||||
const card = this.board.cards.find((_card) => {
|
const card = this.board.cards.find((_card) => {
|
||||||
return _card.id === cardId;
|
return _card.id === cardId;
|
||||||
});
|
});
|
||||||
|
@ -125,10 +168,15 @@ export class ScrumboardService implements Resolve<any>
|
||||||
this.updateBoard();
|
this.updateBoard();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBoard()
|
/**
|
||||||
|
* Update board
|
||||||
|
*
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
updateBoard(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.post('api/scrumboard-boards/' + this.board.id, this.board)
|
this._httpClient.post('api/scrumboard-boards/' + this.board.id, this.board)
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
this.onBoardChanged.next(this.board);
|
this.onBoardChanged.next(this.board);
|
||||||
resolve(this.board);
|
resolve(this.board);
|
||||||
|
@ -136,7 +184,12 @@ export class ScrumboardService implements Resolve<any>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCard(newCard)
|
/**
|
||||||
|
* Update card
|
||||||
|
*
|
||||||
|
* @param newCard
|
||||||
|
*/
|
||||||
|
updateCard(newCard): void
|
||||||
{
|
{
|
||||||
this.board.cards.map((_card) => {
|
this.board.cards.map((_card) => {
|
||||||
if ( _card.id === newCard.id )
|
if ( _card.id === newCard.id )
|
||||||
|
@ -148,10 +201,16 @@ export class ScrumboardService implements Resolve<any>
|
||||||
this.updateBoard();
|
this.updateBoard();
|
||||||
}
|
}
|
||||||
|
|
||||||
createNewBoard(board)
|
/**
|
||||||
|
* Create new board
|
||||||
|
*
|
||||||
|
* @param board
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
createNewBoard(board): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.post('api/scrumboard-boards/' + board.id, board)
|
this._httpClient.post('api/scrumboard-boards/' + board.id, board)
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
resolve(board);
|
resolve(board);
|
||||||
}, reject);
|
}, reject);
|
||||||
|
@ -162,12 +221,25 @@ export class ScrumboardService implements Resolve<any>
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class BoardResolve implements Resolve<any>
|
export class BoardResolve implements Resolve<any>
|
||||||
{
|
{
|
||||||
constructor(private scrumboardService: ScrumboardService)
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {ScrumboardService} _scrumboardService
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private _scrumboardService: ScrumboardService
|
||||||
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(route: ActivatedRouteSnapshot)
|
/**
|
||||||
|
* Resolver
|
||||||
|
*
|
||||||
|
* @param {ActivatedRouteSnapshot} route
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
resolve(route: ActivatedRouteSnapshot): Promise<any>
|
||||||
{
|
{
|
||||||
return this.scrumboardService.getBoard(route.paramMap.get('boardId'));
|
return this._scrumboardService.getBoard(route.paramMap.get('boardId'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
|
|
||||||
import { TodoService } from '../../todo.service';
|
import { TodoService } from 'app/main/apps/todo/todo.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-todo-main-sidenav',
|
selector : 'todo-main-sidenav',
|
||||||
templateUrl: './main-sidenav.component.html',
|
templateUrl: './main-sidenav.component.html',
|
||||||
styleUrls : ['./main-sidenav.component.scss'],
|
styleUrls : ['./main-sidenav.component.scss'],
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
export class FuseTodoMainSidenavComponent implements OnInit, OnDestroy
|
export class TodoMainSidenavComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
folders: any[];
|
folders: any[];
|
||||||
filters: any[];
|
filters: any[];
|
||||||
|
@ -20,46 +21,75 @@ export class FuseTodoMainSidenavComponent implements OnInit, OnDestroy
|
||||||
accounts: object;
|
accounts: object;
|
||||||
selectedAccount: string;
|
selectedAccount: string;
|
||||||
|
|
||||||
onFiltersChanged: Subscription;
|
// Private
|
||||||
onTagsChanged: Subscription;
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
constructor(private todoService: TodoService, private router: Router)
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {TodoService} _todoService
|
||||||
|
* @param {Router} _router
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private _todoService: TodoService,
|
||||||
|
private _router: Router
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// Data
|
// Set the defaults
|
||||||
this.accounts = {
|
this.accounts = {
|
||||||
'creapond' : 'johndoe@creapond.com',
|
'creapond' : 'johndoe@creapond.com',
|
||||||
'withinpixels': 'johndoe@withinpixels.com'
|
'withinpixels': 'johndoe@withinpixels.com'
|
||||||
};
|
};
|
||||||
|
|
||||||
this.selectedAccount = 'creapond';
|
this.selectedAccount = 'creapond';
|
||||||
|
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
{
|
// @ Lifecycle hooks
|
||||||
this.onFiltersChanged =
|
// -----------------------------------------------------------------------------------------------------
|
||||||
this.todoService.onFiltersChanged
|
|
||||||
.subscribe(filters => {
|
|
||||||
this.filters = filters;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.onTagsChanged =
|
/**
|
||||||
this.todoService.onTagsChanged
|
* On init
|
||||||
.subscribe(tags => {
|
*/
|
||||||
this.tags = tags;
|
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;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onFiltersChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
this.onTagsChanged.unsubscribe();
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
newTodo()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New todo
|
||||||
|
*/
|
||||||
|
newTodo(): void
|
||||||
{
|
{
|
||||||
this.router.navigate(['/apps/todo/all']).then(() => {
|
this._router.navigate(['/apps/todo/all']).then(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.todoService.onNewTodoClicked.next('');
|
this._todoService.onNewTodoClicked.next('');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,108 +1,132 @@
|
||||||
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
import { Subscription } from 'rxjs';
|
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||||
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { FuseUtils } from '@fuse/utils';
|
import { FuseUtils } from '@fuse/utils';
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
|
|
||||||
import { Todo } from '../todo.model';
|
import { Todo } from 'app/main/apps/todo/todo.model';
|
||||||
import { TodoService } from '../todo.service';
|
import { TodoService } from 'app/main/apps/todo/todo.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-todo-details',
|
selector : 'todo-details',
|
||||||
templateUrl: './todo-details.component.html',
|
templateUrl: './todo-details.component.html',
|
||||||
styleUrls : ['./todo-details.component.scss'],
|
styleUrls : ['./todo-details.component.scss'],
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
export class FuseTodoDetailsComponent implements OnInit, OnDestroy
|
export class TodoDetailsComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
todo: Todo;
|
todo: Todo;
|
||||||
tags: any[];
|
tags: any[];
|
||||||
formType: string;
|
formType: string;
|
||||||
todoForm: FormGroup;
|
todoForm: FormGroup;
|
||||||
@ViewChild('titleInput') titleInputField;
|
|
||||||
|
|
||||||
onFormChange: any;
|
@ViewChild('titleInput')
|
||||||
onCurrentTodoChanged: Subscription;
|
titleInputField;
|
||||||
onTagsChanged: Subscription;
|
|
||||||
onNewTodoClicked: Subscription;
|
|
||||||
|
|
||||||
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {TodoService} _todoService
|
||||||
|
* @param {FormBuilder} _formBuilder
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private todoService: TodoService,
|
private _todoService: TodoService,
|
||||||
private formBuilder: FormBuilder
|
private _formBuilder: FormBuilder
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
// Subscribe to update the current todo
|
// Subscribe to update the current todo
|
||||||
this.onCurrentTodoChanged =
|
this._todoService.onCurrentTodoChanged
|
||||||
this.todoService.onCurrentTodoChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(([todo, formType]) => {
|
.subscribe(([todo, formType]) => {
|
||||||
|
|
||||||
if ( todo && formType === 'edit' )
|
if ( todo && formType === 'edit' )
|
||||||
{
|
{
|
||||||
this.formType = 'edit';
|
this.formType = 'edit';
|
||||||
|
this.todo = todo;
|
||||||
this.todo = todo;
|
|
||||||
|
|
||||||
this.todoForm = this.createTodoForm();
|
|
||||||
|
|
||||||
this.onFormChange =
|
|
||||||
this.todoForm.valueChanges.pipe(
|
|
||||||
debounceTime(500),
|
|
||||||
distinctUntilChanged()
|
|
||||||
).subscribe(data => {
|
|
||||||
this.todoService.updateTodo(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Subscribe to update on tag change
|
|
||||||
this.onTagsChanged =
|
|
||||||
this.todoService.onTagsChanged
|
|
||||||
.subscribe(labels => {
|
|
||||||
this.tags = labels;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Subscribe to update on tag change
|
|
||||||
this.onNewTodoClicked =
|
|
||||||
this.todoService.onNewTodoClicked
|
|
||||||
.subscribe(() => {
|
|
||||||
this.todo = new Todo({});
|
|
||||||
this.todo.id = FuseUtils.generateGUID();
|
|
||||||
this.formType = 'new';
|
|
||||||
this.todoForm = this.createTodoForm();
|
this.todoForm = this.createTodoForm();
|
||||||
this.focusTitleField();
|
|
||||||
this.todoService.onCurrentTodoChanged.next([this.todo, 'new']);
|
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']);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
if ( this.onFormChange )
|
// Unsubscribe from all subscriptions
|
||||||
{
|
this._unsubscribeAll.next();
|
||||||
this.onFormChange.unsubscribe();
|
this._unsubscribeAll.complete();
|
||||||
}
|
|
||||||
|
|
||||||
this.onCurrentTodoChanged.unsubscribe();
|
|
||||||
this.onNewTodoClicked.unsubscribe();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
focusTitleField()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Focus title field
|
||||||
|
*/
|
||||||
|
focusTitleField(): void
|
||||||
{
|
{
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.titleInputField.nativeElement.focus();
|
this.titleInputField.nativeElement.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createTodoForm()
|
/**
|
||||||
|
* Create todo form
|
||||||
|
*
|
||||||
|
* @returns {FormGroup}
|
||||||
|
*/
|
||||||
|
createTodoForm(): FormGroup
|
||||||
{
|
{
|
||||||
return this.formBuilder.group({
|
return this._formBuilder.group({
|
||||||
'id' : [this.todo.id],
|
'id' : [this.todo.id],
|
||||||
'title' : [this.todo.title],
|
'title' : [this.todo.title],
|
||||||
'notes' : [this.todo.notes],
|
'notes' : [this.todo.notes],
|
||||||
|
@ -116,54 +140,80 @@ export class FuseTodoDetailsComponent implements OnInit, OnDestroy
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleStar(event)
|
/**
|
||||||
|
* Toggle star
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
toggleStar(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.todo.toggleStar();
|
this.todo.toggleStar();
|
||||||
this.todoService.updateTodo(this.todo);
|
this._todoService.updateTodo(this.todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleImportant(event)
|
/**
|
||||||
|
* Toggle important
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
toggleImportant(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.todo.toggleImportant();
|
this.todo.toggleImportant();
|
||||||
this.todoService.updateTodo(this.todo);
|
this._todoService.updateTodo(this.todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle Completed
|
* Toggle Completed
|
||||||
|
*
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
toggleCompleted(event)
|
toggleCompleted(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.todo.toggleCompleted();
|
this.todo.toggleCompleted();
|
||||||
this.todoService.updateTodo(this.todo);
|
this._todoService.updateTodo(this.todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle Deleted
|
* Toggle Deleted
|
||||||
|
*
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
toggleDeleted(event)
|
toggleDeleted(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.todo.toggleDeleted();
|
this.todo.toggleDeleted();
|
||||||
this.todoService.updateTodo(this.todo);
|
this._todoService.updateTodo(this.todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleTagOnTodo(tagId)
|
/**
|
||||||
|
* Toggle tag on todo
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
*/
|
||||||
|
toggleTagOnTodo(tagId): void
|
||||||
{
|
{
|
||||||
this.todoService.toggleTagOnTodo(tagId, this.todo);
|
this._todoService.toggleTagOnTodo(tagId, this.todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasTag(tagId)
|
/**
|
||||||
|
* Has tag?
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* @returns {any}
|
||||||
|
*/
|
||||||
|
hasTag(tagId): any
|
||||||
{
|
{
|
||||||
return this.todoService.hasTag(tagId, this.todo);
|
return this._todoService.hasTag(tagId, this.todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
addTodo()
|
/**
|
||||||
|
* Add todo
|
||||||
|
*/
|
||||||
|
addTodo(): void
|
||||||
{
|
{
|
||||||
this.todoService.updateTodo(this.todoForm.getRawValue());
|
this._todoService.updateTodo(this.todoForm.getRawValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,112 +1,148 @@
|
||||||
import { Component, HostBinding, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
import { Component, HostBinding, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subject, Subscription } from 'rxjs';
|
||||||
|
import { Todo } from 'app/main/apps/todo/todo.model';
|
||||||
import { Todo } from '../../todo.model';
|
import { TodoService } from 'app/main/apps/todo/todo.service';
|
||||||
import { TodoService } from '../../todo.service';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-todo-list-item',
|
selector : 'todo-list-item',
|
||||||
templateUrl : './todo-list-item.component.html',
|
templateUrl : './todo-list-item.component.html',
|
||||||
styleUrls : ['./todo-list-item.component.scss'],
|
styleUrls : ['./todo-list-item.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class FuseTodoListItemComponent implements OnInit, OnDestroy
|
export class TodoListItemComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
@Input() todo: Todo;
|
|
||||||
tags: any[];
|
tags: any[];
|
||||||
@HostBinding('class.selected') selected: boolean;
|
|
||||||
@HostBinding('class.completed') completed: boolean;
|
|
||||||
@HostBinding('class.move-disabled') moveDisabled: boolean;
|
|
||||||
|
|
||||||
onSelectedTodosChanged: Subscription;
|
@Input()
|
||||||
onTagsChanged: Subscription;
|
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(
|
constructor(
|
||||||
private todoService: TodoService,
|
private _todoService: TodoService,
|
||||||
private route: ActivatedRoute
|
private _activatedRoute: ActivatedRoute
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Disable move if path is not /all
|
// Disable move if path is not /all
|
||||||
if ( route.snapshot.url[0].path !== 'all' )
|
if ( _activatedRoute.snapshot.url[0].path !== 'all' )
|
||||||
{
|
{
|
||||||
this.moveDisabled = true;
|
this.moveDisabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
// Set the initial values
|
// Set the initial values
|
||||||
this.todo = new Todo(this.todo);
|
this.todo = new Todo(this.todo);
|
||||||
this.completed = this.todo.completed;
|
this.completed = this.todo.completed;
|
||||||
|
|
||||||
// Subscribe to update on selected todo change
|
// Subscribe to update on selected todo change
|
||||||
this.onSelectedTodosChanged =
|
this._todoService.onSelectedTodosChanged
|
||||||
this.todoService.onSelectedTodosChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(selectedTodos => {
|
.subscribe(selectedTodos => {
|
||||||
this.selected = false;
|
this.selected = false;
|
||||||
|
|
||||||
if ( selectedTodos.length > 0 )
|
if ( selectedTodos.length > 0 )
|
||||||
|
{
|
||||||
|
for ( const todo of selectedTodos )
|
||||||
{
|
{
|
||||||
for ( const todo of selectedTodos )
|
if ( todo.id === this.todo.id )
|
||||||
{
|
{
|
||||||
if ( todo.id === this.todo.id )
|
this.selected = true;
|
||||||
{
|
break;
|
||||||
this.selected = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Subscribe to update on tag change
|
// Subscribe to update on tag change
|
||||||
this.onTagsChanged =
|
this._todoService.onTagsChanged
|
||||||
this.todoService.onTagsChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(tags => {
|
.subscribe(tags => {
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onSelectedTodosChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectedChange()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On selected change
|
||||||
|
*/
|
||||||
|
onSelectedChange(): void
|
||||||
{
|
{
|
||||||
this.todoService.toggleSelectedTodo(this.todo.id);
|
this._todoService.toggleSelectedTodo(this.todo.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle star
|
* Toggle star
|
||||||
*/
|
*/
|
||||||
toggleStar(event)
|
toggleStar(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.todo.toggleStar();
|
this.todo.toggleStar();
|
||||||
this.todoService.updateTodo(this.todo);
|
this._todoService.updateTodo(this.todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle Important
|
* Toggle Important
|
||||||
*/
|
*/
|
||||||
toggleImportant(event)
|
toggleImportant(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.todo.toggleImportant();
|
this.todo.toggleImportant();
|
||||||
this.todoService.updateTodo(this.todo);
|
this._todoService.updateTodo(this.todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle Completed
|
* Toggle Completed
|
||||||
*/
|
*/
|
||||||
toggleCompleted(event)
|
toggleCompleted(event): void
|
||||||
{
|
{
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.todo.toggleCompleted();
|
this.todo.toggleCompleted();
|
||||||
this.todoService.updateTodo(this.todo);
|
this._todoService.updateTodo(this.todo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
<span class="no-todos-text hint-text">There are no todos!</span>
|
<span class="no-todos-text hint-text">There are no todos!</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="todo-list" ngxDroppable [model]="todos" (out)="onDrop($event)" *fuseIfOnDom [@animateStagger]="{value:'50'}">
|
<div class="todo-list" ngxDroppable [model]="todos" (out)="onDrop($event)" *fuseIfOnDom [@animateStagger]="{value:'50'}">
|
||||||
<fuse-todo-list-item class="todo-list-item has-handle"
|
<todo-list-item class="todo-list-item has-handle"
|
||||||
*ngFor="let todo of todos" [todo]="todo"
|
*ngFor="let todo of todos" [todo]="todo"
|
||||||
ngxDraggable
|
ngxDraggable
|
||||||
[model]="todo"
|
[model]="todo"
|
||||||
(click)="readTodo(todo.id)"
|
(click)="readTodo(todo.id)"
|
||||||
[ngClass]="{'current-todo':todo?.id == currentTodo?.id}"
|
[ngClass]="{'current-todo':todo?.id == currentTodo?.id}"
|
||||||
matRipple
|
matRipple
|
||||||
[@animate]="{value:'*',params:{y:'100%'}}">
|
[@animate]="{value:'*',params:{y:'100%'}}">
|
||||||
</fuse-todo-list-item>
|
</todo-list-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,94 +1,125 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
|
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
|
|
||||||
import { Todo } from '../todo.model';
|
import { Todo } from 'app/main/apps/todo/todo.model';
|
||||||
import { TodoService } from '../todo.service';
|
import { TodoService } from 'app/main/apps/todo/todo.service';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-todo-list',
|
selector : 'todo-list',
|
||||||
templateUrl: './todo-list.component.html',
|
templateUrl: './todo-list.component.html',
|
||||||
styleUrls : ['./todo-list.component.scss'],
|
styleUrls : ['./todo-list.component.scss'],
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
export class FuseTodoListComponent implements OnInit, OnDestroy
|
export class TodoListComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
todos: Todo[];
|
todos: Todo[];
|
||||||
currentTodo: Todo;
|
currentTodo: Todo;
|
||||||
|
|
||||||
onTodosChanged: Subscription;
|
// Private
|
||||||
onCurrentTodoChanged: Subscription;
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {ActivatedRoute} _activatedRoute
|
||||||
|
* @param {TodoService} _todoService
|
||||||
|
* @param {Location} _location
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private _activatedRoute: ActivatedRoute,
|
||||||
private todoService: TodoService,
|
private _todoService: TodoService,
|
||||||
private location: Location
|
private _location: Location
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
// Subscribe to update todos on changes
|
// Subscribe to update todos on changes
|
||||||
this.onTodosChanged =
|
this._todoService.onTodosChanged
|
||||||
this.todoService.onTodosChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(todos => {
|
.subscribe(todos => {
|
||||||
this.todos = todos;
|
this.todos = todos;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Subscribe to update current todo on changes
|
// Subscribe to update current todo on changes
|
||||||
this.onCurrentTodoChanged =
|
this._todoService.onCurrentTodoChanged
|
||||||
this.todoService.onCurrentTodoChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(currentTodo => {
|
.subscribe(currentTodo => {
|
||||||
if ( !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 )
|
||||||
{
|
{
|
||||||
// Set the current todo id to null to deselect the current todo
|
this._location.go('apps/todo/tag/' + tagHandle);
|
||||||
this.currentTodo = null;
|
}
|
||||||
|
else if ( filterHandle )
|
||||||
// Handle the location changes
|
{
|
||||||
const tagHandle = this.route.snapshot.params.tagHandle,
|
this._location.go('apps/todo/filter/' + filterHandle);
|
||||||
filterHandle = this.route.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
|
else
|
||||||
{
|
{
|
||||||
this.currentTodo = currentTodo;
|
this._location.go('apps/todo/all');
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
ngOnDestroy()
|
this.currentTodo = currentTodo;
|
||||||
{
|
}
|
||||||
this.onTodosChanged.unsubscribe();
|
});
|
||||||
this.onCurrentTodoChanged.unsubscribe();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read todo
|
* On destroy
|
||||||
* @param todoId
|
|
||||||
*/
|
*/
|
||||||
readTodo(todoId)
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
// Set current todo
|
// Unsubscribe from all subscriptions
|
||||||
this.todoService.setCurrentTodo(todoId);
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
onDrop(ev)
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read todo
|
||||||
|
*
|
||||||
|
* @param todoId
|
||||||
|
*/
|
||||||
|
readTodo(todoId): void
|
||||||
|
{
|
||||||
|
// Set current todo
|
||||||
|
this._todoService.setCurrentTodo(todoId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On drop
|
||||||
|
*
|
||||||
|
* @param ev
|
||||||
|
*/
|
||||||
|
onDrop(ev): void
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<!-- SIDENAV -->
|
<!-- SIDENAV -->
|
||||||
<mat-sidenav class="sidenav" position="start" opened="true" mode="side"
|
<mat-sidenav class="sidenav" position="start" opened="true" mode="side"
|
||||||
fuseMatSidenavHelper="carded-left-sidenav" mat-is-locked-open="gt-md">
|
fuseMatSidenavHelper="carded-left-sidenav" mat-is-locked-open="gt-md">
|
||||||
<fuse-todo-main-sidenav></fuse-todo-main-sidenav>
|
<todo-main-sidenav></todo-main-sidenav>
|
||||||
</mat-sidenav>
|
</mat-sidenav>
|
||||||
<!-- / SIDENAV -->
|
<!-- / SIDENAV -->
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="currentTodo" fxHide.gt-lg>
|
<div *ngIf="currentTodo" fxHide.gt-lg>
|
||||||
<button mat-icon-button (click)="deSelectCurrentTodo()">
|
<button mat-icon-button (click)="deselectCurrentTodo()">
|
||||||
<mat-icon>arrow_back</mat-icon>
|
<mat-icon>arrow_back</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -84,9 +84,9 @@
|
||||||
<!-- CONTENT -->
|
<!-- CONTENT -->
|
||||||
<div class="content" fxFlexAlign="row">
|
<div class="content" fxFlexAlign="row">
|
||||||
|
|
||||||
<fuse-todo-list fusePerfectScrollbar fxFlex></fuse-todo-list>
|
<todo-list fusePerfectScrollbar fxFlex></todo-list>
|
||||||
|
|
||||||
<fuse-todo-details fusePerfectScrollbar fxFlex></fuse-todo-details>
|
<todo-details fusePerfectScrollbar fxFlex></todo-details>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- / CONTENT -->
|
<!-- / CONTENT -->
|
||||||
|
|
|
@ -39,16 +39,16 @@
|
||||||
|
|
||||||
@include media-breakpoint-down(lg) {
|
@include media-breakpoint-down(lg) {
|
||||||
|
|
||||||
fuse-todo-list {
|
todo-list {
|
||||||
border-right: 0;
|
border-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse-todo-list,
|
todo-list,
|
||||||
fuse-todo-details {
|
todo-details {
|
||||||
flex: 1 0 100%;
|
flex: 1 0 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse-todo-details {
|
todo-details {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,11 +64,11 @@
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
|
||||||
fuse-todo-list {
|
todo-list {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse-todo-details {
|
todo-details {
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { FormControl } from '@angular/forms';
|
import { FormControl } from '@angular/forms';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
import { Subscription } from 'rxjs';
|
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||||
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
|
|
||||||
import { Todo } from './todo.model';
|
import { Todo } from 'app/main/apps/todo/todo.model';
|
||||||
import { TodoService } from './todo.service';
|
import { TodoService } from 'app/main/apps/todo/todo.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-todo',
|
selector : 'todo',
|
||||||
templateUrl: './todo.component.html',
|
templateUrl: './todo.component.html',
|
||||||
styleUrls : ['./todo.component.scss'],
|
styleUrls : ['./todo.component.scss'],
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
export class FuseTodoComponent implements OnInit, OnDestroy
|
export class TodoComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
hasSelectedTodos: boolean;
|
hasSelectedTodos: boolean;
|
||||||
isIndeterminate: boolean;
|
isIndeterminate: boolean;
|
||||||
|
@ -24,91 +23,136 @@ export class FuseTodoComponent implements OnInit, OnDestroy
|
||||||
searchInput: FormControl;
|
searchInput: FormControl;
|
||||||
currentTodo: Todo;
|
currentTodo: Todo;
|
||||||
|
|
||||||
onSelectedTodosChanged: Subscription;
|
// Private
|
||||||
onFiltersChanged: Subscription;
|
private _unsubscribeAll: Subject<any>;
|
||||||
onTagsChanged: Subscription;
|
|
||||||
onCurrentTodoChanged: Subscription;
|
|
||||||
|
|
||||||
constructor(private todoService: TodoService)
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {TodoService} _todoService
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private _todoService: TodoService
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
this.searchInput = new FormControl('');
|
this.searchInput = new FormControl('');
|
||||||
|
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.onSelectedTodosChanged =
|
this._todoService.onSelectedTodosChanged
|
||||||
this.todoService.onSelectedTodosChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(selectedTodos => {
|
.subscribe(selectedTodos => {
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.hasSelectedTodos = selectedTodos.length > 0;
|
this.hasSelectedTodos = selectedTodos.length > 0;
|
||||||
this.isIndeterminate = (selectedTodos.length !== this.todoService.todos.length && selectedTodos.length > 0);
|
this.isIndeterminate = (selectedTodos.length !== this._todoService.todos.length && selectedTodos.length > 0);
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onFiltersChanged =
|
this._todoService.onFiltersChanged
|
||||||
this.todoService.onFiltersChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(folders => {
|
.subscribe(folders => {
|
||||||
this.filters = this.todoService.filters;
|
this.filters = this._todoService.filters;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onTagsChanged =
|
this._todoService.onTagsChanged
|
||||||
this.todoService.onTagsChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(tags => {
|
.subscribe(tags => {
|
||||||
this.tags = this.todoService.tags;
|
this.tags = this._todoService.tags;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.searchInput.valueChanges.pipe(
|
this.searchInput.valueChanges
|
||||||
debounceTime(300),
|
.pipe(
|
||||||
distinctUntilChanged()
|
takeUntil(this._unsubscribeAll),
|
||||||
).subscribe(searchText => {
|
debounceTime(300),
|
||||||
this.todoService.onSearchTextChanged.next(searchText);
|
distinctUntilChanged()
|
||||||
});
|
)
|
||||||
|
.subscribe(searchText => {
|
||||||
|
this._todoService.onSearchTextChanged.next(searchText);
|
||||||
|
});
|
||||||
|
|
||||||
this.onCurrentTodoChanged =
|
this._todoService.onCurrentTodoChanged
|
||||||
this.todoService.onCurrentTodoChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(([currentTodo, formType]) => {
|
.subscribe(([currentTodo, formType]) => {
|
||||||
if ( !currentTodo )
|
if ( !currentTodo )
|
||||||
{
|
{
|
||||||
this.currentTodo = null;
|
this.currentTodo = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.currentTodo = currentTodo;
|
this.currentTodo = currentTodo;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onSelectedTodosChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
this.onFiltersChanged.unsubscribe();
|
this._unsubscribeAll.next();
|
||||||
this.onTagsChanged.unsubscribe();
|
this._unsubscribeAll.complete();
|
||||||
this.onCurrentTodoChanged.unsubscribe();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deSelectCurrentTodo()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deselect current todo
|
||||||
|
*/
|
||||||
|
deselectCurrentTodo(): void
|
||||||
{
|
{
|
||||||
this.todoService.onCurrentTodoChanged.next([null, null]);
|
this._todoService.onCurrentTodoChanged.next([null, null]);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSelectAll()
|
/**
|
||||||
|
* Toggle select all
|
||||||
|
*/
|
||||||
|
toggleSelectAll(): void
|
||||||
{
|
{
|
||||||
this.todoService.toggleSelectAll();
|
this._todoService.toggleSelectAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
selectTodos(filterParameter?, filterValue?)
|
/**
|
||||||
|
* Select todos
|
||||||
|
*
|
||||||
|
* @param filterParameter
|
||||||
|
* @param filterValue
|
||||||
|
*/
|
||||||
|
selectTodos(filterParameter?, filterValue?): void
|
||||||
{
|
{
|
||||||
this.todoService.selectTodos(filterParameter, filterValue);
|
this._todoService.selectTodos(filterParameter, filterValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectTodos()
|
/**
|
||||||
|
* Deselect todos
|
||||||
|
*/
|
||||||
|
deselectTodos(): void
|
||||||
{
|
{
|
||||||
this.todoService.deselectTodos();
|
this._todoService.deselectTodos();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleTagOnSelectedTodos(tagId)
|
/**
|
||||||
|
* Toggle tag on selected todos
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
*/
|
||||||
|
toggleTagOnSelectedTodos(tagId): void
|
||||||
{
|
{
|
||||||
this.todoService.toggleTagOnSelectedTodos(tagId);
|
this._todoService.toggleTagOnSelectedTodos(tagId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,11 @@ export class Todo
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param todo
|
||||||
|
*/
|
||||||
constructor(todo)
|
constructor(todo)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -34,22 +39,34 @@ export class Todo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleStar()
|
/**
|
||||||
|
* Toggle star
|
||||||
|
*/
|
||||||
|
toggleStar(): void
|
||||||
{
|
{
|
||||||
this.starred = !this.starred;
|
this.starred = !this.starred;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleImportant()
|
/**
|
||||||
|
* Toggle important
|
||||||
|
*/
|
||||||
|
toggleImportant(): void
|
||||||
{
|
{
|
||||||
this.important = !this.important;
|
this.important = !this.important;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleCompleted()
|
/**
|
||||||
|
* Toggle completed
|
||||||
|
*/
|
||||||
|
toggleCompleted(): void
|
||||||
{
|
{
|
||||||
this.completed = !this.completed;
|
this.completed = !this.completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleDeleted()
|
/**
|
||||||
|
* Toggle deleted
|
||||||
|
*/
|
||||||
|
toggleDeleted(): void
|
||||||
{
|
{
|
||||||
this.deleted = !this.deleted;
|
this.deleted = !this.deleted;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,58 +1,56 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
import { MatButtonModule, MatCheckboxModule, MatDatepickerModule, MatFormFieldModule, MatIconModule, MatInputModule, MatMenuModule, MatRippleModule, MatSelectModule, MatSidenavModule } from '@angular/material';
|
import { MatButtonModule, MatCheckboxModule, MatDatepickerModule, MatFormFieldModule, MatIconModule, MatInputModule, MatMenuModule, MatRippleModule, MatSelectModule, MatSidenavModule } from '@angular/material';
|
||||||
|
|
||||||
import { NgxDnDModule } from '@swimlane/ngx-dnd';
|
import { NgxDnDModule } from '@swimlane/ngx-dnd';
|
||||||
|
|
||||||
import { FuseSharedModule } from '@fuse/shared.module';
|
import { FuseSharedModule } from '@fuse/shared.module';
|
||||||
|
|
||||||
import { TodoService } from './todo.service';
|
import { TodoService } from 'app/main/apps/todo/todo.service';
|
||||||
import { FuseTodoComponent } from './todo.component';
|
import { TodoComponent } from 'app/main/apps/todo/todo.component';
|
||||||
import { FuseTodoMainSidenavComponent } from './sidenavs/main/main-sidenav.component';
|
import { TodoMainSidenavComponent } from 'app/main/apps/todo/sidenavs/main/main-sidenav.component';
|
||||||
import { FuseTodoListItemComponent } from './todo-list/todo-list-item/todo-list-item.component';
|
import { TodoListItemComponent } from 'app/main/apps/todo/todo-list/todo-list-item/todo-list-item.component';
|
||||||
import { FuseTodoListComponent } from './todo-list/todo-list.component';
|
import { TodoListComponent } from 'app/main/apps/todo/todo-list/todo-list.component';
|
||||||
import { FuseTodoDetailsComponent } from './todo-details/todo-details.component';
|
import { TodoDetailsComponent } from 'app/main/apps/todo/todo-details/todo-details.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path : 'all',
|
path : 'all',
|
||||||
component: FuseTodoComponent,
|
component: TodoComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
todo: TodoService
|
todo: TodoService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'all/:todoId',
|
path : 'all/:todoId',
|
||||||
component: FuseTodoComponent,
|
component: TodoComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
todo: TodoService
|
todo: TodoService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'tag/:tagHandle',
|
path : 'tag/:tagHandle',
|
||||||
component: FuseTodoComponent,
|
component: TodoComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
todo: TodoService
|
todo: TodoService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'tag/:tagHandle/:todoId',
|
path : 'tag/:tagHandle/:todoId',
|
||||||
component: FuseTodoComponent,
|
component: TodoComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
todo: TodoService
|
todo: TodoService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'filter/:filterHandle',
|
path : 'filter/:filterHandle',
|
||||||
component: FuseTodoComponent,
|
component: TodoComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
todo: TodoService
|
todo: TodoService
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path : 'filter/:filterHandle/:todoId',
|
path : 'filter/:filterHandle/:todoId',
|
||||||
component: FuseTodoComponent,
|
component: TodoComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
todo: TodoService
|
todo: TodoService
|
||||||
}
|
}
|
||||||
|
@ -65,11 +63,11 @@ const routes: Routes = [
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
FuseTodoComponent,
|
TodoComponent,
|
||||||
FuseTodoMainSidenavComponent,
|
TodoMainSidenavComponent,
|
||||||
FuseTodoListItemComponent,
|
TodoListItemComponent,
|
||||||
FuseTodoListComponent,
|
TodoListComponent,
|
||||||
FuseTodoDetailsComponent
|
TodoDetailsComponent
|
||||||
],
|
],
|
||||||
imports : [
|
imports : [
|
||||||
RouterModule.forChild(routes),
|
RouterModule.forChild(routes),
|
||||||
|
@ -87,7 +85,7 @@ const routes: Routes = [
|
||||||
|
|
||||||
NgxDnDModule,
|
NgxDnDModule,
|
||||||
|
|
||||||
FuseSharedModule,
|
FuseSharedModule
|
||||||
],
|
],
|
||||||
providers : [
|
providers : [
|
||||||
TodoService
|
TodoService
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||||
|
|
||||||
import { FuseUtils } from '@fuse/utils';
|
import { FuseUtils } from '@fuse/utils';
|
||||||
|
|
||||||
import { Todo } from './todo.model';
|
import { Todo } from 'app/main/apps/todo/todo.model';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TodoService implements Resolve<any>
|
export class TodoService implements Resolve<any>
|
||||||
|
@ -14,31 +14,45 @@ export class TodoService implements Resolve<any>
|
||||||
todos: Todo[];
|
todos: Todo[];
|
||||||
selectedTodos: Todo[];
|
selectedTodos: Todo[];
|
||||||
currentTodo: Todo;
|
currentTodo: Todo;
|
||||||
searchText = '';
|
searchText: string;
|
||||||
|
|
||||||
filters: any[];
|
filters: any[];
|
||||||
tags: any[];
|
tags: any[];
|
||||||
routeParams: any;
|
routeParams: any;
|
||||||
|
|
||||||
onTodosChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onTodosChanged: BehaviorSubject<any>;
|
||||||
onSelectedTodosChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onSelectedTodosChanged: BehaviorSubject<any>;
|
||||||
onCurrentTodoChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onCurrentTodoChanged: BehaviorSubject<any>;
|
||||||
|
onFiltersChanged: BehaviorSubject<any>;
|
||||||
onFiltersChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onTagsChanged: BehaviorSubject<any>;
|
||||||
onTagsChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onSearchTextChanged: BehaviorSubject<any>;
|
||||||
onSearchTextChanged: BehaviorSubject<any> = new BehaviorSubject('');
|
onNewTodoClicked: Subject<any>;
|
||||||
onNewTodoClicked: Subject<any> = new Subject();
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {HttpClient} _httpClient
|
||||||
|
* @param {Location} _location
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private http: HttpClient,
|
private _httpClient: HttpClient,
|
||||||
private location: Location // Set current todo
|
private _location: Location
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
this.selectedTodos = [];
|
this.selectedTodos = [];
|
||||||
|
this.searchText = '';
|
||||||
|
this.onTodosChanged = new BehaviorSubject([]);
|
||||||
|
this.onSelectedTodosChanged = new BehaviorSubject([]);
|
||||||
|
this.onCurrentTodoChanged = new BehaviorSubject([]);
|
||||||
|
this.onFiltersChanged = new BehaviorSubject([]);
|
||||||
|
this.onTagsChanged = new BehaviorSubject([]);
|
||||||
|
this.onSearchTextChanged = new BehaviorSubject('');
|
||||||
|
this.onNewTodoClicked = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve
|
* Resolver
|
||||||
|
*
|
||||||
* @param {ActivatedRouteSnapshot} route
|
* @param {ActivatedRouteSnapshot} route
|
||||||
* @param {RouterStateSnapshot} state
|
* @param {RouterStateSnapshot} state
|
||||||
* @returns {Observable<any> | Promise<any> | any}
|
* @returns {Observable<any> | Promise<any> | any}
|
||||||
|
@ -85,12 +99,13 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all filters
|
* Get all filters
|
||||||
|
*
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
getFilters(): Promise<any>
|
getFilters(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/todo-filters')
|
this._httpClient.get('api/todo-filters')
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
this.filters = response;
|
this.filters = response;
|
||||||
this.onFiltersChanged.next(this.filters);
|
this.onFiltersChanged.next(this.filters);
|
||||||
|
@ -101,12 +116,13 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all tags
|
* Get all tags
|
||||||
|
*
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
getTags(): Promise<any>
|
getTags(): Promise<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/todo-tags')
|
this._httpClient.get('api/todo-tags')
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
this.tags = response;
|
this.tags = response;
|
||||||
this.onTagsChanged.next(this.tags);
|
this.onTagsChanged.next(this.tags);
|
||||||
|
@ -117,6 +133,7 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get todos
|
* Get todos
|
||||||
|
*
|
||||||
* @returns {Promise<Todo[]>}
|
* @returns {Promise<Todo[]>}
|
||||||
*/
|
*/
|
||||||
getTodos(): Promise<Todo[]>
|
getTodos(): Promise<Todo[]>
|
||||||
|
@ -136,6 +153,7 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get todos by params
|
* Get todos by params
|
||||||
|
*
|
||||||
* @param handle
|
* @param handle
|
||||||
* @returns {Promise<Todo[]>}
|
* @returns {Promise<Todo[]>}
|
||||||
*/
|
*/
|
||||||
|
@ -143,7 +161,7 @@ export class TodoService implements Resolve<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
this.http.get('api/todo-todos')
|
this._httpClient.get('api/todo-todos')
|
||||||
.subscribe((todos: any) => {
|
.subscribe((todos: any) => {
|
||||||
this.todos = todos.map(todo => {
|
this.todos = todos.map(todo => {
|
||||||
return new Todo(todo);
|
return new Todo(todo);
|
||||||
|
@ -160,6 +178,7 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get todos by filter
|
* Get todos by filter
|
||||||
|
*
|
||||||
* @param handle
|
* @param handle
|
||||||
* @returns {Promise<Todo[]>}
|
* @returns {Promise<Todo[]>}
|
||||||
*/
|
*/
|
||||||
|
@ -175,7 +194,7 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
this.http.get('api/todo-todos?' + param)
|
this._httpClient.get('api/todo-todos?' + param)
|
||||||
.subscribe((todos: any) => {
|
.subscribe((todos: any) => {
|
||||||
|
|
||||||
this.todos = todos.map(todo => {
|
this.todos = todos.map(todo => {
|
||||||
|
@ -194,18 +213,19 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get todos by tag
|
* Get todos by tag
|
||||||
|
*
|
||||||
* @param handle
|
* @param handle
|
||||||
* @returns {Promise<Todo[]>}
|
* @returns {Promise<Todo[]>}
|
||||||
*/
|
*/
|
||||||
getTodosByTag(handle): Promise<Todo[]>
|
getTodosByTag(handle): Promise<Todo[]>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http.get('api/todo-tags?handle=' + handle)
|
this._httpClient.get('api/todo-tags?handle=' + handle)
|
||||||
.subscribe((tags: any) => {
|
.subscribe((tags: any) => {
|
||||||
|
|
||||||
const tagId = tags[0].id;
|
const tagId = tags[0].id;
|
||||||
|
|
||||||
this.http.get('api/todo-todos?tags=' + tagId)
|
this._httpClient.get('api/todo-todos?tags=' + tagId)
|
||||||
.subscribe((todos: any) => {
|
.subscribe((todos: any) => {
|
||||||
|
|
||||||
this.todos = todos.map(todo => {
|
this.todos = todos.map(todo => {
|
||||||
|
@ -225,9 +245,10 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle selected todo by id
|
* Toggle selected todo by id
|
||||||
|
*
|
||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
toggleSelectedTodo(id)
|
toggleSelectedTodo(id): void
|
||||||
{
|
{
|
||||||
// First, check if we already have that todo as selected...
|
// First, check if we already have that todo as selected...
|
||||||
if ( this.selectedTodos.length > 0 )
|
if ( this.selectedTodos.length > 0 )
|
||||||
|
@ -267,7 +288,7 @@ export class TodoService implements Resolve<any>
|
||||||
/**
|
/**
|
||||||
* Toggle select all
|
* Toggle select all
|
||||||
*/
|
*/
|
||||||
toggleSelectAll()
|
toggleSelectAll(): void
|
||||||
{
|
{
|
||||||
if ( this.selectedTodos.length > 0 )
|
if ( this.selectedTodos.length > 0 )
|
||||||
{
|
{
|
||||||
|
@ -280,7 +301,13 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
selectTodos(filterParameter?, filterValue?)
|
/**
|
||||||
|
* Select todos
|
||||||
|
*
|
||||||
|
* @param filterParameter
|
||||||
|
* @param filterValue
|
||||||
|
*/
|
||||||
|
selectTodos(filterParameter?, filterValue?): void
|
||||||
{
|
{
|
||||||
this.selectedTodos = [];
|
this.selectedTodos = [];
|
||||||
|
|
||||||
|
@ -302,7 +329,10 @@ export class TodoService implements Resolve<any>
|
||||||
this.onSelectedTodosChanged.next(this.selectedTodos);
|
this.onSelectedTodosChanged.next(this.selectedTodos);
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectTodos()
|
/**
|
||||||
|
* Deselect todos
|
||||||
|
*/
|
||||||
|
deselectTodos(): void
|
||||||
{
|
{
|
||||||
this.selectedTodos = [];
|
this.selectedTodos = [];
|
||||||
|
|
||||||
|
@ -312,9 +342,10 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set current todo by id
|
* Set current todo by id
|
||||||
|
*
|
||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
setCurrentTodo(id)
|
setCurrentTodo(id): void
|
||||||
{
|
{
|
||||||
this.currentTodo = this.todos.find(todo => {
|
this.currentTodo = this.todos.find(todo => {
|
||||||
return todo.id === id;
|
return todo.id === id;
|
||||||
|
@ -327,30 +358,37 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
if ( tagHandle )
|
if ( tagHandle )
|
||||||
{
|
{
|
||||||
this.location.go('apps/todo/tag/' + tagHandle + '/' + id);
|
this._location.go('apps/todo/tag/' + tagHandle + '/' + id);
|
||||||
}
|
}
|
||||||
else if ( filterHandle )
|
else if ( filterHandle )
|
||||||
{
|
{
|
||||||
this.location.go('apps/todo/filter/' + filterHandle + '/' + id);
|
this._location.go('apps/todo/filter/' + filterHandle + '/' + id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.location.go('apps/todo/all/' + id);
|
this._location.go('apps/todo/all/' + id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle tag on selected todos
|
* Toggle tag on selected todos
|
||||||
|
*
|
||||||
* @param tagId
|
* @param tagId
|
||||||
*/
|
*/
|
||||||
toggleTagOnSelectedTodos(tagId)
|
toggleTagOnSelectedTodos(tagId): void
|
||||||
{
|
{
|
||||||
this.selectedTodos.map(todo => {
|
this.selectedTodos.map(todo => {
|
||||||
this.toggleTagOnTodo(tagId, todo);
|
this.toggleTagOnTodo(tagId, todo);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleTagOnTodo(tagId, todo)
|
/**
|
||||||
|
* Toggle tag on todo
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* @param todo
|
||||||
|
*/
|
||||||
|
toggleTagOnTodo(tagId, todo): void
|
||||||
{
|
{
|
||||||
const index = todo.tags.indexOf(tagId);
|
const index = todo.tags.indexOf(tagId);
|
||||||
|
|
||||||
|
@ -366,7 +404,14 @@ export class TodoService implements Resolve<any>
|
||||||
this.updateTodo(todo);
|
this.updateTodo(todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasTag(tagId, todo)
|
/**
|
||||||
|
* Has tag?
|
||||||
|
*
|
||||||
|
* @param tagId
|
||||||
|
* @param todo
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
hasTag(tagId, todo): any
|
||||||
{
|
{
|
||||||
if ( !todo.tags )
|
if ( !todo.tags )
|
||||||
{
|
{
|
||||||
|
@ -378,14 +423,15 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the todo
|
* Update the todo
|
||||||
|
*
|
||||||
* @param todo
|
* @param todo
|
||||||
* @returns {Promise<any>}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
updateTodo(todo)
|
updateTodo(todo): any
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
this.http.post('api/todo-todos/' + todo.id, {...todo})
|
this._httpClient.post('api/todo-todos/' + todo.id, {...todo})
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
|
|
||||||
this.getTodos().then(todos => {
|
this.getTodos().then(todos => {
|
||||||
|
|
|
@ -91,8 +91,7 @@ const routes = [
|
||||||
FuseCountdownModule,
|
FuseCountdownModule,
|
||||||
FuseHighlightModule,
|
FuseHighlightModule,
|
||||||
FuseMaterialColorPickerModule,
|
FuseMaterialColorPickerModule,
|
||||||
FuseWidgetModule,
|
FuseWidgetModule
|
||||||
FuseAngularMaterialModule
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ComponentsModule
|
export class ComponentsModule
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
templateUrl: './mail.component.html',
|
templateUrl: './mail.component.html',
|
||||||
styleUrls : ['./mail.component.scss']
|
styleUrls : ['./mail.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseMailComponent
|
export class MailComponent
|
||||||
{
|
{
|
||||||
constructor(private translationLoader: FuseTranslationLoaderService)
|
constructor(private translationLoader: FuseTranslationLoaderService)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,26 +1,38 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { FuseConfigService } from '@fuse/services/config.service';
|
import { FuseConfigService } from '@fuse/services/config.service';
|
||||||
import { fuseAnimations } from '@fuse/animations';
|
import { fuseAnimations } from '@fuse/animations';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-coming-soon',
|
selector : 'coming-soon',
|
||||||
templateUrl: './coming-soon.component.html',
|
templateUrl: './coming-soon.component.html',
|
||||||
styleUrls : ['./coming-soon.component.scss'],
|
styleUrls : ['./coming-soon.component.scss'],
|
||||||
animations : fuseAnimations
|
animations : fuseAnimations
|
||||||
})
|
})
|
||||||
export class FuseComingSoonComponent implements OnInit
|
export class ComingSoonComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
comingSoonForm: FormGroup;
|
comingSoonForm: FormGroup;
|
||||||
comingSoonFormErrors: any;
|
comingSoonFormErrors: any;
|
||||||
|
|
||||||
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {FuseConfigService} _fuseConfigService
|
||||||
|
* @param {FormBuilder} _formBuilder
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private fuseConfig: FuseConfigService,
|
private _fuseConfigService: FuseConfigService,
|
||||||
private formBuilder: FormBuilder
|
private _formBuilder: FormBuilder
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.fuseConfig.config = {
|
// Configure the layout
|
||||||
|
this._fuseConfigService.config = {
|
||||||
layout: {
|
layout: {
|
||||||
navigation: 'none',
|
navigation: 'none',
|
||||||
toolbar : 'none',
|
toolbar : 'none',
|
||||||
|
@ -28,23 +40,53 @@ export class FuseComingSoonComponent implements OnInit
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Set the defaults
|
||||||
this.comingSoonFormErrors = {
|
this.comingSoonFormErrors = {
|
||||||
email: {}
|
email: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.comingSoonForm = this.formBuilder.group({
|
this.comingSoonForm = this._formBuilder.group({
|
||||||
email: ['', [Validators.required, Validators.email]]
|
email: ['', [Validators.required, Validators.email]]
|
||||||
});
|
});
|
||||||
|
|
||||||
this.comingSoonForm.valueChanges.subscribe(() => {
|
this.comingSoonForm.valueChanges
|
||||||
this.onRegisterFormValuesChanged();
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
});
|
.subscribe(() => {
|
||||||
|
this.onRegisterFormValuesChanged();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onRegisterFormValuesChanged()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
|
{
|
||||||
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On form values changed
|
||||||
|
*/
|
||||||
|
onRegisterFormValuesChanged(): void
|
||||||
{
|
{
|
||||||
for ( const field in this.comingSoonFormErrors )
|
for ( const field in this.comingSoonFormErrors )
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,18 +6,18 @@ import { MatButtonModule, MatFormFieldModule, MatInputModule } from '@angular/ma
|
||||||
import { FuseSharedModule } from '@fuse/shared.module';
|
import { FuseSharedModule } from '@fuse/shared.module';
|
||||||
import { FuseCountdownModule } from '@fuse/components';
|
import { FuseCountdownModule } from '@fuse/components';
|
||||||
|
|
||||||
import { FuseComingSoonComponent } from './coming-soon.component';
|
import { ComingSoonComponent } from 'app/main/pages/coming-soon/coming-soon.component';
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path : 'coming-soon',
|
path : 'coming-soon',
|
||||||
component: FuseComingSoonComponent
|
component: ComingSoonComponent
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
FuseComingSoonComponent
|
ComingSoonComponent
|
||||||
],
|
],
|
||||||
imports : [
|
imports : [
|
||||||
RouterModule.forChild(routes),
|
RouterModule.forChild(routes),
|
||||||
|
|
|
@ -7,13 +7,19 @@ import { FuseConfigService } from '@fuse/services/config.service';
|
||||||
templateUrl: './error-404.component.html',
|
templateUrl: './error-404.component.html',
|
||||||
styleUrls : ['./error-404.component.scss']
|
styleUrls : ['./error-404.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseError404Component
|
export class Error404Component
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {FuseConfigService} _fuseConfigService
|
||||||
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private fuseConfig: FuseConfigService
|
private _fuseConfigService: FuseConfigService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
this.fuseConfig.config = {
|
// Configure the layout
|
||||||
|
this._fuseConfigService.config = {
|
||||||
layout: {
|
layout: {
|
||||||
navigation: 'none',
|
navigation: 'none',
|
||||||
toolbar : 'none',
|
toolbar : 'none',
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
import { MatIconModule } from '@angular/material';
|
import { MatIconModule } from '@angular/material';
|
||||||
|
|
||||||
import { FuseSharedModule } from '@fuse/shared.module';
|
import { FuseSharedModule } from '@fuse/shared.module';
|
||||||
|
|
||||||
import { FuseError404Component } from './error-404.component';
|
import { Error404Component } from 'app/main/pages/errors/404/error-404.component';
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path : 'errors/error-404',
|
path : 'errors/error-404',
|
||||||
component: FuseError404Component
|
component: Error404Component
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
FuseError404Component
|
Error404Component
|
||||||
],
|
],
|
||||||
imports : [
|
imports : [
|
||||||
RouterModule.forChild(routes),
|
RouterModule.forChild(routes),
|
||||||
|
|
|
@ -3,16 +3,17 @@ import { Component } from '@angular/core';
|
||||||
import { FuseConfigService } from '@fuse/services/config.service';
|
import { FuseConfigService } from '@fuse/services/config.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-error-500',
|
selector : 'error-500',
|
||||||
templateUrl: './error-500.component.html',
|
templateUrl: './error-500.component.html',
|
||||||
styleUrls : ['./error-500.component.scss']
|
styleUrls : ['./error-500.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseError500Component
|
export class Error500Component
|
||||||
{
|
{
|
||||||
constructor(
|
constructor(
|
||||||
private fuseConfig: FuseConfigService
|
private fuseConfig: FuseConfigService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Configure the layout
|
||||||
this.fuseConfig.config = {
|
this.fuseConfig.config = {
|
||||||
layout: {
|
layout: {
|
||||||
navigation: 'none',
|
navigation: 'none',
|
||||||
|
|
|
@ -3,18 +3,18 @@ import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
import { FuseSharedModule } from '@fuse/shared.module';
|
import { FuseSharedModule } from '@fuse/shared.module';
|
||||||
|
|
||||||
import { FuseError500Component } from './error-500.component';
|
import { Error500Component } from 'app/main/pages/errors/500/error-500.component';
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path : 'errors/error-500',
|
path : 'errors/error-500',
|
||||||
component: FuseError500Component
|
component: Error500Component
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
FuseError500Component
|
Error500Component
|
||||||
],
|
],
|
||||||
imports : [
|
imports : [
|
||||||
RouterModule.forChild(routes),
|
RouterModule.forChild(routes),
|
||||||
|
|
|
@ -1,64 +1,107 @@
|
||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||||
import { FormControl } from '@angular/forms';
|
import { FormControl } from '@angular/forms';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
import { Subscription } from 'rxjs';
|
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
||||||
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { FuseUtils } from '@fuse/utils';
|
import { FuseUtils } from '@fuse/utils';
|
||||||
|
|
||||||
import { FaqService } from './faq.service';
|
import { FaqService } from 'app/main/pages/faq/faq.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-faq',
|
selector : 'faq',
|
||||||
templateUrl: './faq.component.html',
|
templateUrl: './faq.component.html',
|
||||||
styleUrls : ['./faq.component.scss']
|
styleUrls : ['./faq.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseFaqComponent implements OnInit, OnDestroy
|
export class FaqComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
faqs: any;
|
faqs: any;
|
||||||
faqsFiltered: any;
|
faqsFiltered: any;
|
||||||
step = 0;
|
step: number;
|
||||||
searchInput;
|
searchInput: any;
|
||||||
onFaqsChanged: Subscription;
|
|
||||||
|
|
||||||
constructor(private faqService: FaqService)
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {FaqService} _faqService
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private _faqService: FaqService
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
this.searchInput = new FormControl('');
|
this.searchInput = new FormControl('');
|
||||||
|
this.step = 0;
|
||||||
|
|
||||||
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
{
|
{
|
||||||
this.onFaqsChanged =
|
this._faqService.onFaqsChanged
|
||||||
this.faqService.onFaqsChanged
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
this.faqs = response;
|
this.faqs = response;
|
||||||
this.faqsFiltered = response;
|
this.faqsFiltered = response;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.searchInput.valueChanges.pipe(
|
this.searchInput.valueChanges
|
||||||
debounceTime(300),
|
.pipe(
|
||||||
distinctUntilChanged()
|
takeUntil(this._unsubscribeAll),
|
||||||
).subscribe(searchText => {
|
debounceTime(300),
|
||||||
this.faqsFiltered = FuseUtils.filterArrayByString(this.faqs, searchText);
|
distinctUntilChanged()
|
||||||
});
|
)
|
||||||
|
.subscribe(searchText => {
|
||||||
|
this.faqsFiltered = FuseUtils.filterArrayByString(this.faqs, searchText);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
{
|
{
|
||||||
this.onFaqsChanged.unsubscribe();
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
setStep(index: number)
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Public methods
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set step
|
||||||
|
*
|
||||||
|
* @param {number} index
|
||||||
|
*/
|
||||||
|
setStep(index: number): void
|
||||||
{
|
{
|
||||||
this.step = index;
|
this.step = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextStep()
|
/**
|
||||||
|
* Next step
|
||||||
|
*/
|
||||||
|
nextStep(): void
|
||||||
{
|
{
|
||||||
this.step++;
|
this.step++;
|
||||||
}
|
}
|
||||||
|
|
||||||
prevStep()
|
/**
|
||||||
|
* Previous step
|
||||||
|
*/
|
||||||
|
prevStep(): void
|
||||||
{
|
{
|
||||||
this.step--;
|
this.step--;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,13 @@ import { MatExpansionModule, MatIconModule } from '@angular/material';
|
||||||
|
|
||||||
import { FuseSharedModule } from '@fuse/shared.module';
|
import { FuseSharedModule } from '@fuse/shared.module';
|
||||||
|
|
||||||
import { FaqService } from './faq.service';
|
import { FaqService } from 'app/main/pages/faq/faq.service';
|
||||||
import { FuseFaqComponent } from './faq.component';
|
import { FaqComponent } from 'app/main/pages/faq/faq.component';
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path : 'faq',
|
path : 'faq',
|
||||||
component: FuseFaqComponent,
|
component: FaqComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
faq: FaqService
|
faq: FaqService
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ const routes = [
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
FuseFaqComponent
|
FaqComponent
|
||||||
],
|
],
|
||||||
imports : [
|
imports : [
|
||||||
RouterModule.forChild(routes),
|
RouterModule.forChild(routes),
|
||||||
|
|
|
@ -7,15 +7,24 @@ import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
export class FaqService implements Resolve<any>
|
export class FaqService implements Resolve<any>
|
||||||
{
|
{
|
||||||
faqs: any;
|
faqs: any;
|
||||||
|
onFaqsChanged: BehaviorSubject<any>;
|
||||||
|
|
||||||
onFaqsChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
/**
|
||||||
|
* Constructor
|
||||||
constructor(private http: HttpClient)
|
*
|
||||||
|
* @param {HttpClient} _httpClient
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private _httpClient: HttpClient
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.onFaqsChanged = new BehaviorSubject({});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve
|
* Resolver
|
||||||
|
*
|
||||||
* @param {ActivatedRouteSnapshot} route
|
* @param {ActivatedRouteSnapshot} route
|
||||||
* @param {RouterStateSnapshot} state
|
* @param {RouterStateSnapshot} state
|
||||||
* @returns {Observable<any> | Promise<any> | any}
|
* @returns {Observable<any> | Promise<any> | any}
|
||||||
|
@ -41,7 +50,7 @@ export class FaqService implements Resolve<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
this.http.get('api/faq')
|
this._httpClient.get('api/faq')
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
this.faqs = response;
|
this.faqs = response;
|
||||||
this.onFaqsChanged.next(this.faqs);
|
this.onFaqsChanged.next(this.faqs);
|
||||||
|
|
|
@ -1,22 +1,52 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { InvoiceService } from '../invoice.service';
|
import { InvoiceService } from 'app/main/pages/invoices/invoice.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-invoice-compact',
|
selector : 'invoice-compact',
|
||||||
templateUrl: './compact.component.html',
|
templateUrl: './compact.component.html',
|
||||||
styleUrls : ['./compact.component.scss']
|
styleUrls : ['./compact.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseInvoiceCompactComponent
|
export class InvoiceCompactComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
invoice: any;
|
invoice: any;
|
||||||
|
|
||||||
constructor(private invoiceService: InvoiceService)
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private _invoiceService: InvoiceService
|
||||||
|
)
|
||||||
{
|
{
|
||||||
this.invoiceService.invoiceOnChanged
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
|
{
|
||||||
|
this._invoiceService.invoiceOnChanged
|
||||||
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe((invoice) => {
|
.subscribe((invoice) => {
|
||||||
this.invoice = invoice;
|
this.invoice = invoice;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
|
{
|
||||||
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@ import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
import { FuseSharedModule } from '@fuse/shared.module';
|
import { FuseSharedModule } from '@fuse/shared.module';
|
||||||
|
|
||||||
import { InvoiceService } from '../invoice.service';
|
import { InvoiceService } from 'app/main/pages/invoices/invoice.service';
|
||||||
import { FuseInvoiceCompactComponent } from './compact.component';
|
import { InvoiceCompactComponent } from 'app/main/pages/invoices/compact/compact.component';
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path : 'invoices/compact',
|
path : 'invoices/compact',
|
||||||
component: FuseInvoiceCompactComponent,
|
component: InvoiceCompactComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
search: InvoiceService
|
search: InvoiceService
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ const routes = [
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
FuseInvoiceCompactComponent
|
InvoiceCompactComponent
|
||||||
],
|
],
|
||||||
imports : [
|
imports : [
|
||||||
RouterModule.forChild(routes),
|
RouterModule.forChild(routes),
|
||||||
|
|
|
@ -3,19 +3,28 @@ import { HttpClient } from '@angular/common/http';
|
||||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class InvoiceService implements Resolve<any>
|
export class InvoiceService implements Resolve<any>
|
||||||
{
|
{
|
||||||
invoice: any;
|
invoice: any;
|
||||||
invoiceOnChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
invoiceOnChanged: BehaviorSubject<any>;
|
||||||
|
|
||||||
constructor(private http: HttpClient)
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {HttpClient} _httpClient
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private _httpClient: HttpClient
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
// Set the defaults
|
||||||
|
this.invoiceOnChanged = new BehaviorSubject({});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve
|
* Resolver
|
||||||
|
*
|
||||||
* @param {ActivatedRouteSnapshot} route
|
* @param {ActivatedRouteSnapshot} route
|
||||||
* @param {RouterStateSnapshot} state
|
* @param {RouterStateSnapshot} state
|
||||||
* @returns {Observable<any> | Promise<any> | any}
|
* @returns {Observable<any> | Promise<any> | any}
|
||||||
|
@ -41,7 +50,7 @@ export class InvoiceService implements Resolve<any>
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
this.http.get('api/invoice')
|
this._httpClient.get('api/invoice')
|
||||||
.subscribe((timeline: any) => {
|
.subscribe((timeline: any) => {
|
||||||
this.invoice = timeline;
|
this.invoice = timeline;
|
||||||
this.invoiceOnChanged.next(this.invoice);
|
this.invoiceOnChanged.next(this.invoice);
|
||||||
|
|
|
@ -1,22 +1,58 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
import { InvoiceService } from '../invoice.service';
|
import { InvoiceService } from 'app/main/pages/invoices/invoice.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-invoice-modern',
|
selector : 'invoice-modern',
|
||||||
templateUrl: './modern.component.html',
|
templateUrl: './modern.component.html',
|
||||||
styleUrls : ['./modern.component.scss']
|
styleUrls : ['./modern.component.scss']
|
||||||
})
|
})
|
||||||
export class FuseInvoiceModernComponent
|
export class InvoiceModernComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
invoice: any;
|
invoice: any;
|
||||||
|
|
||||||
constructor(private invoiceService: InvoiceService)
|
// Private
|
||||||
|
private _unsubscribeAll: Subject<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param {InvoiceService} _invoiceService
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private _invoiceService: InvoiceService
|
||||||
|
)
|
||||||
{
|
{
|
||||||
this.invoiceService.invoiceOnChanged
|
// Set the private defaults
|
||||||
|
this._unsubscribeAll = new Subject();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
// @ Lifecycle hooks
|
||||||
|
// -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On init
|
||||||
|
*/
|
||||||
|
ngOnInit(): void
|
||||||
|
{
|
||||||
|
this._invoiceService.invoiceOnChanged
|
||||||
|
.pipe(takeUntil(this._unsubscribeAll))
|
||||||
.subscribe((invoice) => {
|
.subscribe((invoice) => {
|
||||||
this.invoice = invoice;
|
this.invoice = invoice;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On destroy
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void
|
||||||
|
{
|
||||||
|
// Unsubscribe from all subscriptions
|
||||||
|
this._unsubscribeAll.next();
|
||||||
|
this._unsubscribeAll.complete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@ import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
import { FuseSharedModule } from '@fuse/shared.module';
|
import { FuseSharedModule } from '@fuse/shared.module';
|
||||||
|
|
||||||
import { InvoiceService } from '../invoice.service';
|
import { InvoiceService } from 'app/main/pages/invoices/invoice.service';
|
||||||
import { FuseInvoiceModernComponent } from './modern.component';
|
import { InvoiceModernComponent } from 'app/main/pages/invoices/modern/modern.component';
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path : 'invoices/modern',
|
path : 'invoices/modern',
|
||||||
component: FuseInvoiceModernComponent,
|
component: InvoiceModernComponent,
|
||||||
resolve : {
|
resolve : {
|
||||||
search: InvoiceService
|
search: InvoiceService
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ const routes = [
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
FuseInvoiceModernComponent
|
InvoiceModernComponent
|
||||||
],
|
],
|
||||||
imports : [
|
imports : [
|
||||||
RouterModule.forChild(routes),
|
RouterModule.forChild(routes),
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
|
|
||||||
<mat-toolbar matDialogTitle class="mat-accent m-0">
|
<mat-toolbar matDialogTitle class="mat-accent m-0">
|
||||||
<mat-toolbar-row>
|
<mat-toolbar-row>
|
||||||
<span class="title dialog-title">{{data.article.title}}</span>
|
<span class="title dialog-title">{{_data.article.title}}</span>
|
||||||
</mat-toolbar-row>
|
</mat-toolbar-row>
|
||||||
</mat-toolbar>
|
</mat-toolbar>
|
||||||
|
|
||||||
<div mat-dialog-content class="p-24 m-0" fusePerfectScrollbar>
|
<div mat-dialog-content class="p-24 m-0" fusePerfectScrollbar>
|
||||||
<div [innerHTML]="data.article.content"></div>
|
<div [innerHTML]="_data.article.content"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="end center">
|
<div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="end center">
|
||||||
<button mat-button (click)="dialogRef.close()" class="mat-accent" aria-label="Close">
|
<button mat-button (click)="_matDialogRef.close()" class="mat-accent" aria-label="Close">
|
||||||
CLOSE
|
CLOSE
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</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