Skip to content

Commit

Permalink
feat(context): allow user to filter context list (#588)
Browse files Browse the repository at this point in the history
* feat(context): allow user to filter context list

* light interface changes

* Add a display control for the context filter
  • Loading branch information
mbarbeau authored Mar 4, 2020
1 parent f20c830 commit 836d656
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
<igo-list [navigation]="true">
<ng-template ngFor let-groupContexts [ngForOf]="contexts | keyvalue">
<mat-form-field *ngIf="showFilter()" class="contextFilter">
<input
matInput
type="text"
[placeholder]="'igo.context.contextManager.filterPlaceHolder' | translate"
[(ngModel)]="term">
<button
mat-button
mat-icon-button
matSuffix
class="clear-button"
*ngIf="term.length"
aria-label="Clear"
color="warn"
(click)="term = ''">
<mat-icon svgIcon="close"></mat-icon>
</button>
</mat-form-field>

<ng-template ngFor let-groupContexts [ngForOf]="contexts$ | async | keyvalue">

<igo-collapsible *ngIf="groupContexts.value.length && auth.authenticated" [title]="titleMapping[groupContexts.key] | translate">

<ng-template ngFor let-context [ngForOf]="groupContexts.value">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.contextFilter {
width: calc(100% - 20px);
margin: 5px;
padding-left: 6px;
}

.clear-button {
padding-right: 5px;
}

mat-form-field {
height: 40px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,31 @@ import {
Input,
Output,
EventEmitter,
ChangeDetectorRef
ChangeDetectorRef,
OnInit
} from '@angular/core';

import { AuthService } from '@igo2/auth';

import { DetailedContext, ContextsList } from '../shared/context.interface';
import { ContextListControlsEnum } from './context-list.enum';
import { Subscription, BehaviorSubject } from 'rxjs';

@Component({
selector: 'igo-context-list',
templateUrl: './context-list.component.html'
templateUrl: './context-list.component.html',
styleUrls: ['./context-list.component.scss']
})
export class ContextListComponent {
export class ContextListComponent implements OnInit {
contexts$: BehaviorSubject<ContextsList> = new BehaviorSubject(undefined);

@Input()
get contexts(): ContextsList {
return this._contexts;
}
set contexts(value: ContextsList) {
this._contexts = value;
this.contexts$.next(value);
this.cdRef.detectChanges();
}
private _contexts: ContextsList = { ours: [] };
Expand Down Expand Up @@ -60,5 +67,78 @@ export class ContextListComponent {
public: 'igo.context.contextManager.publicContexts'
};

/**
* Context filter term
*/
@Input()
set term(value: string) {
this.term$.next(value);
}
get term(): string {
return this.term$.value;
}
public term$: BehaviorSubject<string> = new BehaviorSubject('');
term$$: Subscription;

public showContextFilter = ContextListControlsEnum.default;

public thresholdToFilter = 5;

constructor(private cdRef: ChangeDetectorRef, public auth: AuthService) {}

ngOnInit() {
this.term$$ = this.term$.subscribe((value) => {
if (value === '') {
this.contexts$.next(this.contexts);
}

if (value.length) {
let ours; let publics; let shared;
ours = this.contexts.ours.filter((context) => {
const filterNormalized = value.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
const contextTitleNormalized = context.title.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
return contextTitleNormalized.includes(filterNormalized);
});
const updateContexts: ContextsList = {
ours
};

if (this.contexts.public) {
publics = this.contexts.public.filter((context) => {
const filterNormalized = value.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
const contextTitleNormalized = context.title.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
return contextTitleNormalized.includes(filterNormalized);
});
updateContexts.public = publics;
}
if (this.contexts.shared) {
shared = this.contexts.shared.filter((context) => {
const filterNormalized = value.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
const contextTitleNormalized = context.title.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
return contextTitleNormalized.includes(filterNormalized);
});
updateContexts.shared = shared;
}

this.contexts$.next(updateContexts);
}
});
}

public showFilter() {
switch (this.showContextFilter) {
case ContextListControlsEnum.always:
return true;
case ContextListControlsEnum.never:
return false;
default:
let totalLength = this.contexts.ours.length;
this.contexts.public ? totalLength += this.contexts.public.length : totalLength += 0;
this.contexts.shared ? totalLength += this.contexts.shared.length : totalLength += 0;
if (totalLength >= this.thresholdToFilter) {
return true;
}
return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum ContextListControlsEnum {
always = 'always',
never = 'never',
default = 'default'
}
8 changes: 7 additions & 1 deletion packages/context/src/lib/context.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import {
MatInputModule,
MatFormFieldModule
} from '@angular/material';

import { IgoContextManagerModule } from './context-manager/context-manager.module';
import { IgoContextMapButtonModule } from './context-map-button/context-map-button.module';
import { IgoShareMapModule } from './share-map/share-map.module';
import { IgoSidenavModule } from './sidenav/sidenav.module';

@NgModule({
imports: [],
imports: [
MatInputModule,
MatFormFieldModule],
declarations: [],
exports: [
IgoContextManagerModule,
Expand Down
3 changes: 2 additions & 1 deletion packages/context/src/locale/en.context.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
"ourContexts": "Our contexts",
"publicContexts": "Public contexts",
"save": "Save this context",
"sharedContexts": "Shared contexts"
"sharedContexts": "Shared contexts",
"filterPlaceHolder": "Filer the contexts list"
},
"permission": {
"addBtn": "Add",
Expand Down
3 changes: 2 additions & 1 deletion packages/context/src/locale/fr.context.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
"ourContexts": "Vos contextes",
"publicContexts": "Contextes publics",
"save": "Sauvegarder ce contexte",
"sharedContexts": "Contextes partagés"
"sharedContexts": "Contextes partagés",
"filterPlaceHolder": "Filtrer la liste des contextes"
},
"permission": {
"addBtn": "Ajouter",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, ChangeDetectionStrategy, Input, OnInit } from '@angular/core';
import { Component, ChangeDetectionStrategy, Input, OnInit, OnDestroy } from '@angular/core';
import { Observable, BehaviorSubject, Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
import olFormatGeoJSON from 'ol/format/GeoJSON';
Expand Down Expand Up @@ -40,7 +40,7 @@ import { SearchState } from '../search.state';
templateUrl: './search-results-tool.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SearchResultsToolComponent implements OnInit {
export class SearchResultsToolComponent implements OnInit, OnDestroy {
/**
* to show hide results icons
*/
Expand Down Expand Up @@ -121,6 +121,11 @@ export class SearchResultsToolComponent implements OnInit {
this.settingsChange$.next(true);
});
}

ngOnDestroy() {
this.searchTerm$$.unsubscribe();
}

/**
* Try to add a feature to the map when it's being focused
* @internal
Expand Down

0 comments on commit 836d656

Please sign in to comment.