mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-01-10 12:35:07 +00:00
(Todo app) ongoing..
This commit is contained in:
parent
1f8b1a3f27
commit
0339874110
|
@ -84,4 +84,14 @@ export class FuseUtils
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static genearateGUID()
|
||||||
|
{
|
||||||
|
function S4()
|
||||||
|
{
|
||||||
|
return (((1 + Math.random()) * 0x10000) || 0).toString(16).substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (S4() + S4());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@
|
||||||
md-raised-button
|
md-raised-button
|
||||||
(click)="dialogRef.close(eventForm)"
|
(click)="dialogRef.close(eventForm)"
|
||||||
class="save-button mat-accent"
|
class="save-button mat-accent"
|
||||||
[disabled]="eventForm.pristine"
|
[disabled]="eventForm.invalid"
|
||||||
aria-label="SAVE">
|
aria-label="SAVE">
|
||||||
SAVE
|
SAVE
|
||||||
</button>
|
</button>
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
md-raised-button
|
md-raised-button
|
||||||
(click)="dialogRef.close(['save',eventForm])"
|
(click)="dialogRef.close(['save',eventForm])"
|
||||||
class="save-button mat-accent"
|
class="save-button mat-accent"
|
||||||
[disabled]="eventForm.pristine"
|
[disabled]="eventForm.invalid"
|
||||||
aria-label="SAVE">
|
aria-label="SAVE">
|
||||||
SAVE
|
SAVE
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { Observable } from 'rxjs/Observable';
|
||||||
import { Http } from '@angular/http';
|
import { Http } from '@angular/http';
|
||||||
import { Subject } from 'rxjs/Subject';
|
import { Subject } from 'rxjs/Subject';
|
||||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||||
|
import { FuseUtils } from '../../../core/fuseUtils';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ChatService implements Resolve<any>
|
export class ChatService implements Resolve<any>
|
||||||
|
@ -80,7 +81,7 @@ export class ChatService implements Resolve<any>
|
||||||
return item.id === contactId;
|
return item.id === contactId;
|
||||||
});
|
});
|
||||||
|
|
||||||
const chatId = this.guidGenerator();
|
const chatId = FuseUtils.genearateGUID();
|
||||||
|
|
||||||
const chat = {
|
const chat = {
|
||||||
id : chatId,
|
id : chatId,
|
||||||
|
@ -243,18 +244,4 @@ export class ChatService implements Resolve<any>
|
||||||
}, reject);
|
}, reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Random ID Generator
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
guidGenerator()
|
|
||||||
{
|
|
||||||
function S4()
|
|
||||||
{
|
|
||||||
return (((1 + Math.random()) * 0x10000) || 0).toString(16).substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (S4() + S4());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,15 @@
|
||||||
<!-- SIDENAV CONTENT -->
|
<!-- SIDENAV CONTENT -->
|
||||||
<div class="content" perfect-scrollbar>
|
<div class="content" perfect-scrollbar>
|
||||||
|
|
||||||
|
<div class="p-24" fxFlexAlign="row" fxLayoutAlign="center center">
|
||||||
|
<button md-raised-button
|
||||||
|
class="mat-accent add-todo-button"
|
||||||
|
(click)="newTodo()"
|
||||||
|
aria-label="ADD TASK">
|
||||||
|
ADD TASK
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
|
|
||||||
<div class="nav-item">
|
<div class="nav-item">
|
||||||
|
|
|
@ -26,5 +26,9 @@
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
|
|
||||||
|
.add-todo-button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { TodoService } from '../../todo.service';
|
import { TodoService } from '../../todo.service';
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-todo-main-sidenav',
|
selector : 'fuse-todo-main-sidenav',
|
||||||
|
@ -18,7 +19,7 @@ export class MainSidenavComponent implements OnInit, OnDestroy
|
||||||
onFiltersChanged: Subscription;
|
onFiltersChanged: Subscription;
|
||||||
onTagsChanged: Subscription;
|
onTagsChanged: Subscription;
|
||||||
|
|
||||||
constructor(private todoService: TodoService)
|
constructor(private todoService: TodoService, private router: Router)
|
||||||
{
|
{
|
||||||
// Data
|
// Data
|
||||||
this.accounts = {
|
this.accounts = {
|
||||||
|
@ -49,4 +50,13 @@ export class MainSidenavComponent implements OnInit, OnDestroy
|
||||||
this.onFiltersChanged.unsubscribe();
|
this.onFiltersChanged.unsubscribe();
|
||||||
this.onTagsChanged.unsubscribe();
|
this.onTagsChanged.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newTodo()
|
||||||
|
{
|
||||||
|
this.router.navigate(['/apps/todo/all']).then(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.todoService.onNewTodoClicked.next('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,14 +46,16 @@
|
||||||
|
|
||||||
<div class="todo-content">
|
<div class="todo-content">
|
||||||
|
|
||||||
<form [formGroup]="todoForm">
|
<form [formGroup]="todoForm" (submit)="addTodo()">
|
||||||
|
|
||||||
<md-input-container class="title mt-8" floatPlaceholder="never" fxFill>
|
<md-input-container class="title mt-8" floatPlaceholder="never" fxFill>
|
||||||
<textarea mdInput
|
<textarea mdInput
|
||||||
|
#titleInput
|
||||||
name="title"
|
name="title"
|
||||||
formControlName="title"
|
formControlName="title"
|
||||||
placeholder="Title"
|
placeholder="Title"
|
||||||
mdTextareaAutosize>
|
mdTextareaAutosize
|
||||||
|
required>
|
||||||
</textarea>
|
</textarea>
|
||||||
</md-input-container>
|
</md-input-container>
|
||||||
|
|
||||||
|
@ -96,6 +98,11 @@
|
||||||
mdAutosizeMinRows="6">
|
mdAutosizeMinRows="6">
|
||||||
</textarea>
|
</textarea>
|
||||||
</md-input-container>
|
</md-input-container>
|
||||||
|
|
||||||
|
<button *ngIf="formType === 'new'"
|
||||||
|
md-raised-button class="mat-accent"
|
||||||
|
[disabled]="todoForm.invalid">SAVE
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { AfterViewInit, Component, OnDestroy, OnInit, ViewChildren } from '@angular/core';
|
||||||
import { TodoService } from '../todo.service';
|
import { TodoService } from '../todo.service';
|
||||||
import { Todo } from '../todo.model';
|
import { Todo } from '../todo.model';
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
||||||
|
import { FuseUtils } from '../../../../core/fuseUtils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-todo-details',
|
selector : 'fuse-todo-details',
|
||||||
|
@ -13,17 +14,19 @@ export class TodoDetailsComponent implements OnInit, OnDestroy
|
||||||
{
|
{
|
||||||
todo: Todo;
|
todo: Todo;
|
||||||
tags: any[];
|
tags: any[];
|
||||||
|
formType: string;
|
||||||
todoForm: FormGroup;
|
todoForm: FormGroup;
|
||||||
|
@ViewChildren('titleInput') titleInputField;
|
||||||
|
|
||||||
onFormChange: any;
|
onFormChange: any;
|
||||||
onCurrentTodoChanged: Subscription;
|
onCurrentTodoChanged: Subscription;
|
||||||
onTagsChanged: Subscription;
|
onTagsChanged: Subscription;
|
||||||
|
onNewTodoClicked: Subscription;
|
||||||
|
|
||||||
constructor(private todoService: TodoService,
|
constructor(private todoService: TodoService,
|
||||||
private formBuilder: FormBuilder)
|
private formBuilder: FormBuilder)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
ngOnInit()
|
||||||
|
@ -31,12 +34,16 @@ export class TodoDetailsComponent implements OnInit, OnDestroy
|
||||||
// Subscribe to update the current todo
|
// Subscribe to update the current todo
|
||||||
this.onCurrentTodoChanged =
|
this.onCurrentTodoChanged =
|
||||||
this.todoService.onCurrentTodoChanged
|
this.todoService.onCurrentTodoChanged
|
||||||
.subscribe(currentTodo => {
|
.subscribe(todo => {
|
||||||
this.todo = currentTodo;
|
|
||||||
|
this.formType = 'edit';
|
||||||
|
|
||||||
|
this.todo = todo;
|
||||||
|
|
||||||
if ( this.todo )
|
if ( this.todo )
|
||||||
{
|
{
|
||||||
this.todoForm = this.createTodoForm();
|
this.todoForm = this.createTodoForm();
|
||||||
|
|
||||||
this.onFormChange = this.todoForm.valueChanges
|
this.onFormChange = this.todoForm.valueChanges
|
||||||
.debounceTime(500)
|
.debounceTime(500)
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
|
@ -52,6 +59,23 @@ export class TodoDetailsComponent implements OnInit, OnDestroy
|
||||||
.subscribe(labels => {
|
.subscribe(labels => {
|
||||||
this.tags = labels;
|
this.tags = labels;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Subscribe to update on tag change
|
||||||
|
this.onNewTodoClicked = this.todoService.onNewTodoClicked
|
||||||
|
.subscribe(() => {
|
||||||
|
this.todo = new Todo({});
|
||||||
|
this.todo.id = FuseUtils.genearateGUID();
|
||||||
|
this.formType = 'new';
|
||||||
|
this.todoForm = this.createTodoForm();
|
||||||
|
this.focusTitleField();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
focusTitleField()
|
||||||
|
{
|
||||||
|
setTimeout(() => {
|
||||||
|
this.titleInputField.first.nativeElement.focus();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createTodoForm()
|
createTodoForm()
|
||||||
|
@ -120,12 +144,20 @@ export class TodoDetailsComponent implements OnInit, OnDestroy
|
||||||
this.todoService.toggleTagOnTodo(tagId, this.todo);
|
this.todoService.toggleTagOnTodo(tagId, this.todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addTodo()
|
||||||
|
{
|
||||||
|
this.todoService.updateTodo(this.todoForm.getRawValue());
|
||||||
|
}
|
||||||
|
|
||||||
ngOnDestroy()
|
ngOnDestroy()
|
||||||
{
|
{
|
||||||
if ( this.onFormChange )
|
if ( this.onFormChange )
|
||||||
{
|
{
|
||||||
this.onFormChange.unsubscribe();
|
this.onFormChange.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onCurrentTodoChanged.unsubscribe();
|
this.onCurrentTodoChanged.unsubscribe();
|
||||||
|
|
||||||
|
this.onNewTodoClicked.unsubscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,12 @@
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.move-disabled {
|
||||||
|
.handle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tags {
|
.tags {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { Component, HostBinding, Input, OnDestroy, OnInit, ViewEncapsulation } f
|
||||||
import { Todo } from '../../todo.model';
|
import { Todo } from '../../todo.model';
|
||||||
import { TodoService } from '../../todo.service';
|
import { TodoService } from '../../todo.service';
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
import { ActivatedRoute, ActivatedRouteSnapshot, Route, Router } from '@angular/router';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector : 'fuse-todo-list-item',
|
selector : 'fuse-todo-list-item',
|
||||||
|
@ -15,12 +16,19 @@ export class TodoListItemComponent implements OnInit, OnDestroy
|
||||||
tags: any[];
|
tags: any[];
|
||||||
@HostBinding('class.selected') selected: boolean;
|
@HostBinding('class.selected') selected: boolean;
|
||||||
@HostBinding('class.completed') completed: boolean;
|
@HostBinding('class.completed') completed: boolean;
|
||||||
|
@HostBinding('class.move-disabled') moveDisabled: boolean;
|
||||||
|
|
||||||
onSelectedTodosChanged: Subscription;
|
onSelectedTodosChanged: Subscription;
|
||||||
onTagsChanged: Subscription;
|
onTagsChanged: Subscription;
|
||||||
|
|
||||||
constructor(private todoService: TodoService)
|
constructor(private todoService: TodoService,
|
||||||
|
private route: ActivatedRoute)
|
||||||
{
|
{
|
||||||
|
// Disable move if path is not /all
|
||||||
|
if ( route.snapshot.url[0].path !== 'all' )
|
||||||
|
{
|
||||||
|
this.moveDisabled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit()
|
ngOnInit()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div *ngIf="todos.length === 0" fxLayout="column" fxLayoutAlign="center center" fxFlex>
|
<div *ngIf="todos.length === 0" fxLayout="column" fxLayoutAlign="center center" fxFlex>
|
||||||
<span class="hint-text mat-h3">There are no todos!</span>
|
<span class="hint-text mat-h3">There are no todos!</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="todo-list" ngxDroppable [model]="todos" (out)="log($event)">
|
<div class="todo-list" ngxDroppable [model]="todos" (out)="onDrop($event)">
|
||||||
<fuse-todo-list-item class="todo-list-item has-handle"
|
<fuse-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
|
||||||
|
|
|
@ -74,29 +74,12 @@ export class TodoListComponent implements OnInit, OnDestroy
|
||||||
*/
|
*/
|
||||||
readTodo(todoId)
|
readTodo(todoId)
|
||||||
{
|
{
|
||||||
const tagHandle = this.route.snapshot.params.tagHandle,
|
|
||||||
filterHandle = this.route.snapshot.params.filterHandle;
|
|
||||||
|
|
||||||
if ( tagHandle )
|
|
||||||
{
|
|
||||||
this.location.go('apps/todo/tag/' + tagHandle + '/' + todoId);
|
|
||||||
}
|
|
||||||
else if ( filterHandle )
|
|
||||||
{
|
|
||||||
this.location.go('apps/todo/filter/' + filterHandle + '/' + todoId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.location.go('apps/todo/all/' + todoId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set current todo
|
// Set current todo
|
||||||
this.todoService.setCurrentTodo(todoId);
|
this.todoService.setCurrentTodo(todoId);
|
||||||
}
|
}
|
||||||
|
|
||||||
log(ev)
|
onDrop(ev)
|
||||||
{
|
{
|
||||||
console.info(this.todos);
|
this.todoService.updateTodos(this.todos);
|
||||||
console.info(ev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,9 @@ import { Observable } from 'rxjs/Observable';
|
||||||
import { Http } from '@angular/http';
|
import { Http } from '@angular/http';
|
||||||
import { Todo } from './todo.model';
|
import { Todo } from './todo.model';
|
||||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
|
||||||
import { FuseUtils } from '../../../core/fuseUtils';
|
import { FuseUtils } from '../../../core/fuseUtils';
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TodoService implements Resolve<any>
|
export class TodoService implements Resolve<any>
|
||||||
|
@ -26,8 +27,10 @@ export class TodoService implements Resolve<any>
|
||||||
onFiltersChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onFiltersChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
||||||
onTagsChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
onTagsChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
||||||
onSearchTextChanged: BehaviorSubject<any> = new BehaviorSubject('');
|
onSearchTextChanged: BehaviorSubject<any> = new BehaviorSubject('');
|
||||||
|
onNewTodoClicked: Subject<any> = new Subject();
|
||||||
|
|
||||||
constructor(private http: Http)
|
constructor(private http: Http,
|
||||||
|
private location: Location)
|
||||||
{
|
{
|
||||||
this.selectedTodos = [];
|
this.selectedTodos = [];
|
||||||
}
|
}
|
||||||
|
@ -317,6 +320,23 @@ export class TodoService implements Resolve<any>
|
||||||
});
|
});
|
||||||
|
|
||||||
this.onCurrentTodoChanged.next(this.currentTodo);
|
this.onCurrentTodoChanged.next(this.currentTodo);
|
||||||
|
|
||||||
|
const tagHandle = this.routeParams.tagHandle,
|
||||||
|
filterHandle = this.routeParams.filterHandle;
|
||||||
|
|
||||||
|
if ( tagHandle )
|
||||||
|
{
|
||||||
|
this.location.go('apps/todo/tag/' + tagHandle + '/' + id);
|
||||||
|
}
|
||||||
|
else if ( filterHandle )
|
||||||
|
{
|
||||||
|
this.location.go('apps/todo/filter/' + filterHandle + '/' + id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.location.go('apps/todo/all/' + id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -360,10 +380,7 @@ export class TodoService implements Resolve<any>
|
||||||
|
|
||||||
this.getTodos().then(todos => {
|
this.getTodos().then(todos => {
|
||||||
|
|
||||||
if ( todos && this.currentTodo )
|
this.setCurrentTodo(todo.id);
|
||||||
{
|
|
||||||
this.setCurrentTodo(this.currentTodo.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(todos);
|
resolve(todos);
|
||||||
|
|
||||||
|
@ -371,4 +388,27 @@ export class TodoService implements Resolve<any>
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the todo
|
||||||
|
* @param todo
|
||||||
|
* @returns {Promise<any>}
|
||||||
|
*/
|
||||||
|
updateTodos(todos)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
this.http.post('api/todo-todos/', {...todos})
|
||||||
|
|
||||||
|
.subscribe(response => {
|
||||||
|
|
||||||
|
this.getTodos().then(_todos => {
|
||||||
|
console.log(response);
|
||||||
|
resolve(_todos);
|
||||||
|
}, reject);
|
||||||
|
});
|
||||||
|
});*/
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user