mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-01-10 04:25:08 +00:00
Merge branch 'master' of https://github.com/withinpixels/fuse2
This commit is contained in:
commit
be8195663e
87
src/app/core/fuseUtils.ts
Normal file
87
src/app/core/fuseUtils.ts
Normal file
|
@ -0,0 +1,87 @@
|
|||
export class FuseUtils
|
||||
{
|
||||
|
||||
public static filterArrayByString(mainArr, searchText)
|
||||
{
|
||||
if ( searchText === '' )
|
||||
{
|
||||
return mainArr;
|
||||
}
|
||||
|
||||
searchText = searchText.toLowerCase();
|
||||
|
||||
return mainArr.filter(itemObj => {
|
||||
return this.searchInObj(itemObj, searchText);
|
||||
});
|
||||
}
|
||||
|
||||
public static searchInObj(itemObj, searchText)
|
||||
{
|
||||
|
||||
for ( const prop in itemObj )
|
||||
{
|
||||
if ( !itemObj.hasOwnProperty(prop) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const value = itemObj[prop];
|
||||
|
||||
if ( typeof value === 'string' )
|
||||
{
|
||||
if ( this.searchInSting(value, searchText) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
else if ( Array.isArray(value) )
|
||||
{
|
||||
if ( this.searchInArray(value, searchText) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( typeof value === 'object' )
|
||||
{
|
||||
if ( this.searchInObj(value, searchText) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static searchInArray(arr, searchText)
|
||||
{
|
||||
for ( const value of arr )
|
||||
{
|
||||
if ( typeof value === 'string' )
|
||||
{
|
||||
if ( this.searchInSting(value, searchText) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( typeof value === 'object' )
|
||||
{
|
||||
if ( this.searchInObj(value, searchText) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static searchInSting(value, searchText)
|
||||
{
|
||||
if ( value.toLowerCase().includes(searchText) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,152 +1,11 @@
|
|||
/**
|
||||
* Created by vadimdez on 28/06/16.
|
||||
*/
|
||||
import { Pipe, Injectable } from '@angular/core';
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { FuseUtils } from '../fuseUtils';
|
||||
|
||||
@Pipe({
|
||||
name: 'filterBy',
|
||||
pure: false
|
||||
})
|
||||
|
||||
@Injectable()
|
||||
export class FilterPipe {
|
||||
|
||||
private filterByString(filter) {
|
||||
if (filter) {
|
||||
filter = filter.toLowerCase();
|
||||
}
|
||||
return value => {
|
||||
return !filter || (value ? ('' + value).toLowerCase().indexOf(filter) !== -1 : false);
|
||||
}
|
||||
}
|
||||
|
||||
private filterByBoolean(filter) {
|
||||
return value => {
|
||||
return Boolean(value) === filter;
|
||||
}
|
||||
}
|
||||
|
||||
private filterByObject(filter) {
|
||||
return value => {
|
||||
for (let key in filter) {
|
||||
|
||||
if (key === '$or') {
|
||||
if (!this.filterByOr(filter.$or)(this.getValue(value))) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!value.hasOwnProperty(key) && !Object.getOwnPropertyDescriptor(Object.getPrototypeOf(value), key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let val = this.getValue(value[key]);
|
||||
const filterType = typeof filter[key];
|
||||
let isMatching;
|
||||
|
||||
if (filterType === 'boolean') {
|
||||
isMatching = this.filterByBoolean(filter[key])(val);
|
||||
} else if (filterType === 'string') {
|
||||
isMatching = this.filterByString(filter[key])(val);
|
||||
} else if (filterType === 'object') {
|
||||
isMatching = this.filterByObject(filter[key])(val);
|
||||
} else {
|
||||
isMatching = this.filterDefault(filter[key])(val);
|
||||
}
|
||||
|
||||
if (!isMatching) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter value by $or
|
||||
*
|
||||
* @param filter
|
||||
* @returns {(value:any)=>boolean}
|
||||
*/
|
||||
private filterByOr(filter: any[]) {
|
||||
return (value: any) => {
|
||||
let hasMatch = false;
|
||||
const length = filter.length;
|
||||
const isArray = value instanceof Array;
|
||||
|
||||
const arrayComparison = (i) => {
|
||||
return value.indexOf(filter[i]) !== -1;
|
||||
};
|
||||
const otherComparison = (i) => {
|
||||
return value === filter[i];
|
||||
};
|
||||
const comparison = isArray ? arrayComparison : otherComparison;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
if (comparison(i)) {
|
||||
hasMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hasMatch;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks function's value if type is function otherwise same value
|
||||
* @param value
|
||||
* @returns {any}
|
||||
*/
|
||||
private getValue(value: any) {
|
||||
return typeof value === 'function' ? value() : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defatul filterDefault function
|
||||
*
|
||||
* @param filter
|
||||
* @returns {(value:any)=>boolean}
|
||||
*/
|
||||
private filterDefault(filter) {
|
||||
return value => {
|
||||
return filter === undefined || filter == value;
|
||||
}
|
||||
}
|
||||
|
||||
private isNumber(value) {
|
||||
return !isNaN(parseInt(value, 10)) && isFinite(value);
|
||||
}
|
||||
|
||||
transform(array: any[], filter: any): any {
|
||||
const type = typeof filter;
|
||||
|
||||
if (!array) {
|
||||
return array;
|
||||
}
|
||||
|
||||
if (type === 'boolean') {
|
||||
return array.filter(this.filterByBoolean(filter));
|
||||
}
|
||||
|
||||
if (type === 'string') {
|
||||
if (this.isNumber(filter)) {
|
||||
return array.filter(this.filterDefault(filter));
|
||||
}
|
||||
|
||||
return array.filter(this.filterByString(filter));
|
||||
}
|
||||
|
||||
if (type === 'object') {
|
||||
return array.filter(this.filterByObject(filter));
|
||||
}
|
||||
|
||||
if (type === 'function') {
|
||||
return array.filter(filter);
|
||||
}
|
||||
|
||||
return array.filter(this.filterDefault(filter));
|
||||
@Pipe({name: 'filter'})
|
||||
export class FilterPipe implements PipeTransform
|
||||
{
|
||||
transform(mainArr: any[], searchText: string, property: string): any
|
||||
{
|
||||
return FuseUtils.filterArrayByString(mainArr, searchText);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
<md-icon>search</md-icon>
|
||||
|
||||
<input [(ngModel)]="chatSearch.name" type="text" placeholder="Search or start new chat" fxFlex>
|
||||
<input [(ngModel)]="searchText" type="text" placeholder="Search or start new chat" fxFlex>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -106,12 +106,12 @@
|
|||
<!-- CHATS LIST-->
|
||||
<div class="chat-list" fxLayout="column">
|
||||
|
||||
<div md-subheader *ngIf="(user.chatList | filterBy: chatSearch).length > 0">
|
||||
<div md-subheader *ngIf="(user.chatList | filter: searchText).length > 0">
|
||||
Chats
|
||||
</div>
|
||||
|
||||
<button md-button class="contact"
|
||||
*ngFor="let chat of user.chatList | filterBy: chatSearch"
|
||||
*ngFor="let chat of user.chatList | filter: searchText"
|
||||
(click)="getChat(chat.contactId)" ngClass="{'unread':contact.unread}">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
|
@ -146,13 +146,13 @@
|
|||
<!-- CONTACTS LIST-->
|
||||
<div class="contact-list" fxLayout="column">
|
||||
|
||||
<div md-subheader *ngIf="(contacts| filterBy: chatSearch).length > 0">
|
||||
<div md-subheader *ngIf="(contacts| filter: searchText).length > 0">
|
||||
Contacts
|
||||
</div>
|
||||
|
||||
<button md-button class="contact"
|
||||
ng-show="chatSearch"
|
||||
*ngFor="let contact of contacts| filterBy: chatSearch"
|
||||
*ngFor="let contact of contacts| filter: searchText"
|
||||
(click)="getChat(contact.id)">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
|
@ -171,7 +171,7 @@
|
|||
<!-- / CONTACTS LIST-->
|
||||
|
||||
<!-- NO RESULTS MESSAGE -->
|
||||
<div *ngIf="(contacts| filterBy: chatSearch).length === 0" class="no-results-message">
|
||||
<div *ngIf="(contacts| filter: searchText).length === 0" class="no-results-message">
|
||||
No results..
|
||||
</div>
|
||||
<!-- NO RESULTS MESSAGE-->
|
||||
|
|
|
@ -14,6 +14,7 @@ export class ChatsSidenavComponent implements OnInit
|
|||
chats: any[];
|
||||
contacts: any[];
|
||||
chatSearch: any;
|
||||
searchText = '';
|
||||
|
||||
constructor(private chatService: ChatService,
|
||||
private fuseMdSidenavService: FuseMdSidenavHelperService,
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<div class="search" flex fxLayout="row" fxLayoutAlign="start center">
|
||||
<md-icon>search</md-icon>
|
||||
<input fxFlex type="text" placeholder="Search for an e-mail or contact">
|
||||
<input [formControl]="searchInput" placeholder="Search for an e-mail or contact" fxFlex>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { MailService } from './mail.service';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { FuseUtils } from '../../../core/fuseUtils';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-mail',
|
||||
|
@ -14,20 +16,21 @@ export class MailComponent implements OnInit, OnDestroy
|
|||
folders: any[];
|
||||
filters: any[];
|
||||
labels: any[];
|
||||
searchInput: FormControl;
|
||||
|
||||
onSelectedMailsChanged: Subscription;
|
||||
onFoldersChanged: Subscription;
|
||||
onFiltersChanged: Subscription;
|
||||
onLabelsChanged: Subscription;
|
||||
|
||||
constructor(
|
||||
private mailService: MailService
|
||||
)
|
||||
constructor(private mailService: MailService)
|
||||
{
|
||||
this.searchInput = new FormControl('');
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
|
||||
this.onSelectedMailsChanged =
|
||||
this.mailService.onSelectedMailsChanged
|
||||
.subscribe(selectedMails => {
|
||||
|
@ -55,6 +58,14 @@ export class MailComponent implements OnInit, OnDestroy
|
|||
.subscribe(labels => {
|
||||
this.labels = this.mailService.labels;
|
||||
});
|
||||
|
||||
|
||||
this.searchInput.valueChanges
|
||||
.debounceTime(300)
|
||||
.distinctUntilChanged()
|
||||
.subscribe(searchText => {
|
||||
this.mailService.onSearchTextChanged.next(searchText);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
|
|
|
@ -4,6 +4,7 @@ import { Observable } from 'rxjs/Observable';
|
|||
import { Http } from '@angular/http';
|
||||
import { Mail } from './mail.model';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
import { FuseUtils } from "app/core/fuseUtils";
|
||||
|
||||
@Injectable()
|
||||
export class MailService implements Resolve<any>
|
||||
|
@ -11,6 +12,7 @@ export class MailService implements Resolve<any>
|
|||
mails: Mail[];
|
||||
selectedMails: Mail[];
|
||||
currentMail: Mail;
|
||||
searchText = '';
|
||||
|
||||
folders: any[];
|
||||
filters: any[];
|
||||
|
@ -24,10 +26,9 @@ export class MailService implements Resolve<any>
|
|||
onFoldersChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
||||
onFiltersChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
||||
onLabelsChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
||||
onSearchTextChanged: BehaviorSubject<any> = new BehaviorSubject('');
|
||||
|
||||
constructor(
|
||||
private http: Http
|
||||
)
|
||||
constructor(private http: Http)
|
||||
{
|
||||
this.selectedMails = [];
|
||||
}
|
||||
|
@ -59,6 +60,19 @@ export class MailService implements Resolve<any>
|
|||
this.setCurrentMail(null);
|
||||
}
|
||||
|
||||
this.onSearchTextChanged.subscribe(searchText => {
|
||||
if ( searchText !== '' )
|
||||
{
|
||||
this.searchText = searchText;
|
||||
this.getMails();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.searchText = searchText;
|
||||
this.getMails();
|
||||
}
|
||||
});
|
||||
|
||||
resolve();
|
||||
},
|
||||
reject
|
||||
|
@ -154,6 +168,8 @@ export class MailService implements Resolve<any>
|
|||
return new Mail(mail);
|
||||
});
|
||||
|
||||
this.mails = FuseUtils.filterArrayByString(this.mails, this.searchText);
|
||||
|
||||
this.onMailsChanged.next(this.mails);
|
||||
|
||||
resolve(this.mails);
|
||||
|
@ -179,6 +195,8 @@ export class MailService implements Resolve<any>
|
|||
return new Mail(mail);
|
||||
});
|
||||
|
||||
this.mails = FuseUtils.filterArrayByString(this.mails, this.searchText);
|
||||
|
||||
this.onMailsChanged.next(this.mails);
|
||||
|
||||
resolve(this.mails);
|
||||
|
@ -207,6 +225,8 @@ export class MailService implements Resolve<any>
|
|||
return new Mail(mail);
|
||||
});
|
||||
|
||||
this.mails = FuseUtils.filterArrayByString(this.mails, this.searchText);
|
||||
|
||||
this.onMailsChanged.next(this.mails);
|
||||
|
||||
resolve(this.mails);
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<div class="search" flex fxLayout="row" fxLayoutAlign="start center">
|
||||
<md-icon>search</md-icon>
|
||||
<input fxFlex type="text" placeholder="Search for an todo">
|
||||
<input [formControl]="searchInput" placeholder="Search for an todo" fxFlex>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { TodoService } from './todo.service';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { Todo } from './todo.model';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-todo',
|
||||
|
@ -13,6 +15,7 @@ export class TodoComponent implements OnInit, OnDestroy
|
|||
isIndeterminate: boolean;
|
||||
filters: any[];
|
||||
tags: any[];
|
||||
searchInput: FormControl;
|
||||
|
||||
onSelectedTodosChanged: Subscription;
|
||||
onFiltersChanged: Subscription;
|
||||
|
@ -20,10 +23,12 @@ export class TodoComponent implements OnInit, OnDestroy
|
|||
|
||||
constructor(private todoService: TodoService)
|
||||
{
|
||||
this.searchInput = new FormControl('');
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
|
||||
this.onSelectedTodosChanged =
|
||||
this.todoService.onSelectedTodosChanged
|
||||
.subscribe(selectedTodos => {
|
||||
|
@ -45,6 +50,13 @@ export class TodoComponent implements OnInit, OnDestroy
|
|||
.subscribe(tags => {
|
||||
this.tags = this.todoService.tags;
|
||||
});
|
||||
|
||||
this.searchInput.valueChanges
|
||||
.debounceTime(300)
|
||||
.distinctUntilChanged()
|
||||
.subscribe(searchText => {
|
||||
this.todoService.onSearchTextChanged.next(searchText);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
|
|
|
@ -4,6 +4,8 @@ import { Observable } from 'rxjs/Observable';
|
|||
import { Http } from '@angular/http';
|
||||
import { Todo } from './todo.model';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { FuseUtils } from '../../../core/fuseUtils';
|
||||
|
||||
@Injectable()
|
||||
export class TodoService implements Resolve<any>
|
||||
|
@ -11,6 +13,7 @@ export class TodoService implements Resolve<any>
|
|||
todos: Todo[];
|
||||
selectedTodos: Todo[];
|
||||
currentTodo: Todo;
|
||||
searchText = '';
|
||||
|
||||
filters: any[];
|
||||
tags: any[];
|
||||
|
@ -22,6 +25,7 @@ export class TodoService implements Resolve<any>
|
|||
|
||||
onFiltersChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
||||
onTagsChanged: BehaviorSubject<any> = new BehaviorSubject([]);
|
||||
onSearchTextChanged: BehaviorSubject<any> = new BehaviorSubject('');
|
||||
|
||||
constructor(private http: Http)
|
||||
{
|
||||
|
@ -55,6 +59,18 @@ export class TodoService implements Resolve<any>
|
|||
this.setCurrentTodo(null);
|
||||
}
|
||||
|
||||
this.onSearchTextChanged.subscribe(searchText => {
|
||||
if ( searchText !== '' )
|
||||
{
|
||||
this.searchText = searchText;
|
||||
this.getTodos();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.searchText = searchText;
|
||||
this.getTodos();
|
||||
}
|
||||
});
|
||||
resolve();
|
||||
},
|
||||
reject
|
||||
|
@ -129,6 +145,8 @@ export class TodoService implements Resolve<any>
|
|||
return new Todo(todo);
|
||||
});
|
||||
|
||||
this.todos = FuseUtils.filterArrayByString(this.todos, this.searchText);
|
||||
|
||||
this.onTodosChanged.next(this.todos);
|
||||
|
||||
resolve(this.todos);
|
||||
|
@ -160,6 +178,8 @@ export class TodoService implements Resolve<any>
|
|||
return new Todo(todo);
|
||||
});
|
||||
|
||||
this.todos = FuseUtils.filterArrayByString(this.todos, this.searchText);
|
||||
|
||||
this.onTodosChanged.next(this.todos);
|
||||
|
||||
resolve(this.todos);
|
||||
|
@ -188,6 +208,8 @@ export class TodoService implements Resolve<any>
|
|||
return new Todo(todo);
|
||||
});
|
||||
|
||||
this.todos = FuseUtils.filterArrayByString(this.todos, this.searchText);
|
||||
|
||||
this.onTodosChanged.next(this.todos);
|
||||
|
||||
resolve(this.todos);
|
||||
|
|
Loading…
Reference in New Issue
Block a user