Compare commits

...

4 Commits

22 changed files with 214 additions and 263 deletions

View File

@ -0,0 +1,15 @@
.list-header {
width: 100%;
padding-bottom: 20px;
}
.add-btn {
margin-right: 16px;
margin-top: -3px;
float: right;
}
:host/deep/.mat-icon {
height: 32px;
width: 32px;
}

View File

@ -0,0 +1,12 @@
<div class="input-group list-header pull-left">
<mat-button-toggle-group #group="matButtonToggleGroup">
<mat-button-toggle *ngFor="let button of filterButtons" value="{{button.value}}" (change)="execute(group)">
{{button.label}}
</mat-button-toggle>
</mat-button-toggle-group>
<button mat-icon-button class="add-btn">
<mat-icon svgIcon="{{addButton.svgIcon}}"
title="{{addButton.tooltip}}"
(click)="add()"></mat-icon>
</button>
</div>

View File

@ -0,0 +1,28 @@
import {Component, EventEmitter, Input, Output} from '@angular/core';
@Component({
selector: 'cc-list-filter',
templateUrl: './list-filter.component.html',
styleUrls: ['./list-filter.component.css']
})
export class ListFilterComponent {
@Input() filterButtons: any[];
@Input() addButton: any;
@Output() executeSearch = new EventEmitter();
@Output() openAddFrom = new EventEmitter();
constructor() {
}
execute(group) {
this.executeSearch.emit(group);
}
add() {
this.openAddFrom.emit();
}
}

View File

@ -0,0 +1,4 @@
.list-header {
width: 100%;
padding-bottom: 20px;
}

View File

@ -0,0 +1,12 @@
<div class="input-group list-header">
<input id="search-field"
type="text" #query class="form-control"
(keyup.enter)="emitSearch()"
[formControl]="searchTerm">
<span class="input-group-btn">
<button class="btn btn-default" type="button"
(click)="emitSearch()">
Suchen
</button>
</span>
</div>

View File

@ -0,0 +1,43 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {Location} from '@angular/common';
import {ActivatedRoute} from '@angular/router';
@Component({
selector: 'cc-list-search',
templateUrl: './search-field.component.html',
styleUrls: ['./search-field.component.css']
})
export class SearchFieldComponent implements OnInit {
@Input() searchTerm;
@Output() executeSearch = new EventEmitter();
@Output() searchTermStream = new EventEmitter();
constructor(private route: ActivatedRoute,
private location: Location) {
}
ngOnInit() {
const paramsObservable = this.route.queryParams
.map(params => decodeURI(params['query'] || ''))
.do(query => this.searchTerm.setValue(query));
const searchTermObservable = this.searchTerm.valueChanges
.debounceTime(400)
.do(query => this.adjustBrowserUrl(query));
this.searchTermStream.emit({params: paramsObservable, searchTerm: searchTermObservable});
}
emitSearch() {
this.executeSearch.emit();
}
adjustBrowserUrl(queryString = '') {
const absoluteUrl = this.location.path().split('?')[0];
const queryPart = queryString !== '' ? `query=${queryString}` : '';
this.location.replaceState(absoluteUrl, queryPart);
}
}

View File

@ -1,36 +1,18 @@
<div class="select-list"> <div class="select-list">
<div class="input-group list-header pull-left"> <cc-list-filter
<mat-button-toggle-group #group="matButtonToggleGroup"> [filterButtons]="[{label: fraction.BLUFOR, value: 'BLUFOR'},
<mat-button-toggle value="BLUFOR" (change)="filterDecorations(group)"> {label: fraction.OPFOR, value: 'OPFOR'},
{{fraction.BLUFOR}} {label: 'Global', value: 'GLOBAL'}]"
</mat-button-toggle> [addButton]="{svgIcon: 'add', tooltip: 'Neue Auszeichnung hinzufügen'}"
<mat-button-toggle value="OPFOR" (change)="filterDecorations(group)"> (executeSearch)="filterDecorations($event)"
{{fraction.OPFOR}} (openAddFrom)="openNewDecorationForm()">
</mat-button-toggle> </cc-list-filter>
<mat-button-toggle value="GLOBAL" (change)="filterDecorations(group)">
Global
</mat-button-toggle>
</mat-button-toggle-group>
<button mat-icon-button class="add-btn">
<mat-icon svgIcon="add" title="Neue Auszeichnung hinzufügen"
(click)="openNewDecorationForm()"></mat-icon>
</button>
</div>
<div class="input-group list-header"> <cc-list-search [searchTerm]="searchTerm"
<input id="search-tasks" (searchTermStream)="initObservable($event)"
type="text" #query class="form-control" (executeSearch)="filterDecorations()">
(keyup.enter)="filterDecorations()" </cc-list-search>
[formControl]="searchTerm">
<span class="input-group-btn">
<button class="btn btn-default" type="button"
(click)="filterDecorations()">
Suchen
</button>
</span>
</div>
<div>
<decoration-item *ngFor="let decoration of decorations$ | async" <decoration-item *ngFor="let decoration of decorations$ | async"
[decoration]="decoration" [decoration]="decoration"
(decorationDelete)="deleteDecoration(decoration)" (decorationDelete)="deleteDecoration(decoration)"
@ -38,5 +20,3 @@
[selected]="decoration._id == selectedDecorationId"> [selected]="decoration._id == selectedDecorationId">
</decoration-item> </decoration-item>
</div> </div>
</div>

View File

@ -1,5 +1,4 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {Location} from '@angular/common';
import {FormControl} from '@angular/forms'; import {FormControl} from '@angular/forms';
import {ActivatedRoute, Router} from '@angular/router'; import {ActivatedRoute, Router} from '@angular/router';
@ -11,7 +10,7 @@ import {MatButtonToggleGroup} from '@angular/material';
import {UIHelpers} from '../../utils/global.helpers'; import {UIHelpers} from '../../utils/global.helpers';
@Component({ @Component({
selector: 'decoration-list', selector: 'cc-decoration-list',
templateUrl: './decoration-list.component.html', templateUrl: './decoration-list.component.html',
styleUrls: ['./decoration-list.component.css', '../../style/select-list.css'] styleUrls: ['./decoration-list.component.css', '../../style/select-list.css']
}) })
@ -29,22 +28,15 @@ export class DecorationListComponent implements OnInit {
constructor(private decorationService: DecorationService, constructor(private decorationService: DecorationService,
private router: Router, private router: Router,
private route: ActivatedRoute, private route: ActivatedRoute) {
private location: Location) {
} }
ngOnInit() { ngOnInit() {
this.decorations$ = this.decorationService.decorations$; this.decorations$ = this.decorationService.decorations$;
}
const paramsStream = this.route.queryParams initObservable(observables: any) {
.map(params => decodeURI(params['query'] || '')) Observable.merge(observables.params as Observable<string>, observables.searchTerm)
.do(query => this.searchTerm.setValue(query));
const searchTermStream = this.searchTerm.valueChanges
.debounceTime(400)
.do(query => this.adjustBrowserUrl(query));
Observable.merge(paramsStream, searchTermStream)
.distinctUntilChanged() .distinctUntilChanged()
.switchMap(query => this.decorationService.findDecorations(query, this.radioModel)) .switchMap(query => this.decorationService.findDecorations(query, this.radioModel))
.subscribe(); .subscribe();
@ -79,12 +71,4 @@ export class DecorationListComponent implements OnInit {
this.radioModel = UIHelpers.toggleReleaseButton(this.radioModel, group); this.radioModel = UIHelpers.toggleReleaseButton(this.radioModel, group);
this.decorations$ = this.decorationService.findDecorations(this.searchTerm.value, this.radioModel); this.decorations$ = this.decorationService.findDecorations(this.searchTerm.value, this.radioModel);
} }
adjustBrowserUrl(queryString = '') {
const absoluteUrl = this.location.path().split('?')[0];
const queryPart = queryString !== '' ? `query=${queryString}` : '';
this.location.replaceState(absoluteUrl, queryPart);
}
} }

View File

@ -4,14 +4,10 @@ import {CommonModule} from '@angular/common';
import {DecorationStore} from '../services/stores/decoration.store'; import {DecorationStore} from '../services/stores/decoration.store';
import {DecorationService} from '../services/army-management/decoration.service'; import {DecorationService} from '../services/army-management/decoration.service';
import {NgModule} from '@angular/core'; import {NgModule} from '@angular/core';
import {MatButtonToggleModule} from '@angular/material';
import {MatIconModule} from '@angular/material/icon';
import {MatButtonModule} from '@angular/material/button';
@NgModule({ @NgModule({
declarations: decorationsRoutingComponents, declarations: decorationsRoutingComponents,
imports: [CommonModule, SharedModule, MatButtonToggleModule, MatButtonModule, MatIconModule, imports: [CommonModule, SharedModule, decorationRoutesModule],
decorationRoutesModule],
providers: [DecorationStore, DecorationService] providers: [DecorationStore, DecorationService]
}) })
export class DecorationsModule { export class DecorationsModule {

View File

@ -1,39 +1,22 @@
<div class="select-list"> <div class="select-list">
<div class="list-header"> <cc-list-filter
<mat-button-toggle-group #group="matButtonToggleGroup"> [filterButtons]="[{label: fraction.BLUFOR, value: 'BLUFOR'},
<mat-button-toggle value="BLUFOR" (change)="filterRanks(group)"> {label: fraction.OPFOR, value: 'OPFOR'}]"
{{fraction.BLUFOR}} [addButton]="{svgIcon: 'add', tooltip: 'Neuen Rang hinzufügen'}"
</mat-button-toggle> (executeSearch)="filterRanks($event)"
<mat-button-toggle value="OPFOR" (change)="filterRanks(group)"> (openAddFrom)="openNewRankForm()">
{{fraction.OPFOR}} </cc-list-filter>
</mat-button-toggle>
</mat-button-toggle-group>
<button mat-icon-button class="add-btn">
<mat-icon svgIcon="add" title="Neuen Rang hinzufügen"
(click)="openNewRankForm()"></mat-icon>
</button>
</div>
<div class="input-group list-header"> <cc-list-search [searchTerm]="searchTerm"
<input id="search-tasks" (searchTermStream)="initObservable($event)"
type="text" #query class="form-control" (executeSearch)="filterRanks()">
(keyup.enter)="filterRanks()" </cc-list-search>
[formControl]="searchTerm">
<span class="input-group-btn">
<button class="btn btn-default" type="button"
(click)="filterRanks()">
Suchen
</button>
</span>
</div>
<div>
<pjm-rank-item *ngFor="let rank of ranks$ | async" <pjm-rank-item *ngFor="let rank of ranks$ | async"
[rank]="rank" [rank]="rank"
(rankDelete)="deleteRank(rank)" (rankDelete)="deleteRank(rank)"
(rankSelected)="selectRank($event)" (rankSelected)="selectRank($event)"
[selected]="rank._id == selectedRankId"> [selected]="rank._id == selectedRankId">
</pjm-rank-item> </pjm-rank-item>
</div>
</div> </div>

View File

@ -1,5 +1,4 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {Location} from '@angular/common';
import {FormControl} from '@angular/forms'; import {FormControl} from '@angular/forms';
import {ActivatedRoute, Router} from '@angular/router'; import {ActivatedRoute, Router} from '@angular/router';
@ -11,7 +10,7 @@ import {UIHelpers} from '../../utils/global.helpers';
import {MatButtonToggleGroup} from '@angular/material'; import {MatButtonToggleGroup} from '@angular/material';
@Component({ @Component({
selector: 'rank-list', selector: 'cc-rank-list',
templateUrl: './rank-list.component.html', templateUrl: './rank-list.component.html',
styleUrls: ['./rank-list.component.css', '../../style/select-list.css'] styleUrls: ['./rank-list.component.css', '../../style/select-list.css']
}) })
@ -29,29 +28,21 @@ export class RankListComponent implements OnInit {
constructor(private rankService: RankService, constructor(private rankService: RankService,
private router: Router, private router: Router,
private route: ActivatedRoute, private route: ActivatedRoute) {
private location: Location) {
} }
ngOnInit() { ngOnInit() {
this.ranks$ = this.rankService.ranks$; this.ranks$ = this.rankService.ranks$;
}
const paramsStream = this.route.queryParams initObservable(observables: any) {
.map(params => decodeURI(params['query'] || '')) Observable.merge(observables.params as Observable<string>, observables.searchTerm)
.do(query => this.searchTerm.setValue(query));
const searchTermStream = this.searchTerm.valueChanges
.debounceTime(400)
.do(query => this.adjustBrowserUrl(query));
Observable.merge(paramsStream, searchTermStream)
.distinctUntilChanged() .distinctUntilChanged()
.switchMap(query => this.rankService.findRanks(query, this.radioModel)) .switchMap(query => this.rankService.findRanks(query, this.radioModel))
.subscribe(); .subscribe();
} }
openNewRankForm() { openNewRankForm() {
this.selectedRankId = null; this.selectedRankId = null;
this.router.navigate([{outlets: {'right': ['new']}}], {relativeTo: this.route}); this.router.navigate([{outlets: {'right': ['new']}}], {relativeTo: this.route});
@ -75,11 +66,4 @@ export class RankListComponent implements OnInit {
}); });
} }
} }
adjustBrowserUrl(queryString = '') {
const absoluteUrl = this.location.path().split('?')[0];
const queryPart = queryString !== '' ? `query=${queryString}` : '';
this.location.replaceState(absoluteUrl, queryPart);
}
} }

View File

@ -4,14 +4,10 @@ import {SharedModule} from '../shared.module';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {RankService} from '../services/army-management/rank.service'; import {RankService} from '../services/army-management/rank.service';
import {RankStore} from '../services/stores/rank.store'; import {RankStore} from '../services/stores/rank.store';
import {MatButtonToggleModule} from '@angular/material';
import {MatIconModule} from '@angular/material/icon';
import {MatButtonModule} from '@angular/material/button';
@NgModule({ @NgModule({
declarations: ranksRoutingComponents, declarations: ranksRoutingComponents,
imports: [CommonModule, SharedModule, MatButtonToggleModule, MatButtonModule, MatIconModule, imports: [CommonModule, SharedModule, rankRouterModule],
rankRouterModule],
providers: [RankStore, RankService] providers: [RankStore, RankService]
}) })
export class RanksModule { export class RanksModule {

View File

@ -5,7 +5,6 @@ import {EditRankComponent} from './edit-rank/edit-rank.component';
import {RankItemComponent} from './rank-list/rank-item.component'; import {RankItemComponent} from './rank-list/rank-item.component';
import {ModuleWithProviders} from '@angular/core'; import {ModuleWithProviders} from '@angular/core';
export const ranksRoutes: Routes = [{ export const ranksRoutes: Routes = [{
path: '', component: RankComponent, path: '', component: RankComponent,
children: [ children: [

View File

@ -2,11 +2,17 @@ import {NgModule} from '@angular/core';
import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {ShowErrorComponent} from './common/show-error/show-error.component'; import {ShowErrorComponent} from './common/show-error/show-error.component';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {ListFilterComponent} from './common/user-interface/list-filter/list-filter.component';
import {SearchFieldComponent} from './common/user-interface/search-field/search-field.component';
import {MatButtonToggleModule} from '@angular/material';
import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
@NgModule({ @NgModule({
declarations: [ShowErrorComponent], declarations: [ShowErrorComponent, ListFilterComponent, SearchFieldComponent],
imports: [CommonModule, FormsModule, ReactiveFormsModule], imports: [CommonModule, FormsModule, ReactiveFormsModule, MatButtonToggleModule, MatButtonModule, MatIconModule],
exports: [FormsModule, ReactiveFormsModule, ShowErrorComponent], exports: [FormsModule, ReactiveFormsModule, MatButtonToggleModule, MatButtonModule, MatIconModule, ShowErrorComponent,
ListFilterComponent, SearchFieldComponent],
}) })
export class SharedModule { export class SharedModule {
} }

View File

@ -1,33 +1,17 @@
<div class="select-list"> <div class="select-list">
<div class="list-header"> <cc-list-filter
<mat-button-toggle-group #group="matButtonToggleGroup"> [filterButtons]="[{label: fraction.BLUFOR, value: 'BLUFOR'},
<mat-button-toggle value="BLUFOR" (change)="filterSquads(group)"> {label: fraction.OPFOR, value: 'OPFOR'}]"
{{fraction.BLUFOR}} [addButton]="{svgIcon: 'add', tooltip: 'Neues Squad hinzufügen'}"
</mat-button-toggle> (executeSearch)="filterSquads($event)"
<mat-button-toggle value="OPFOR" (change)="filterSquads(group)"> (openAddFrom)="openNewRankForm()">
{{fraction.OPFOR}} </cc-list-filter>
</mat-button-toggle>
</mat-button-toggle-group>
<button mat-icon-button class="add-btn">
<mat-icon svgIcon="add" title="Neues Squad hinzufügen"
(click)="openNewSquadForm()"></mat-icon>
</button>
</div>
<div class="input-group search-bar"> <cc-list-search [searchTerm]="searchTerm"
<input id="search-tasks" (searchTermStream)="initObservable($event)"
type="text" #query class="form-control" (executeSearch)="filterSquads()">
(keyup.enter)="filterSquads()" </cc-list-search>
[formControl]="searchTerm">
<span class="input-group-btn">
<button class="btn btn-default" type="button"
(click)="filterSquads()">
Suchen
</button>
</span>
</div>
<div>
<pjm-squad-item *ngFor="let squad of squads$ | async" <pjm-squad-item *ngFor="let squad of squads$ | async"
[squad]="squad" [squad]="squad"
(squadDelete)="deleteSquad(squad)" (squadDelete)="deleteSquad(squad)"
@ -35,5 +19,3 @@
[selected]="squad._id == selectedSquadId"> [selected]="squad._id == selectedSquadId">
</pjm-squad-item> </pjm-squad-item>
</div> </div>
</div>

View File

@ -1,5 +1,4 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {Location} from '@angular/common';
import {FormControl} from '@angular/forms'; import {FormControl} from '@angular/forms';
import {ActivatedRoute, Router} from '@angular/router'; import {ActivatedRoute, Router} from '@angular/router';
@ -11,7 +10,7 @@ import {UIHelpers} from '../../utils/global.helpers';
import {MatButtonToggleGroup} from '@angular/material'; import {MatButtonToggleGroup} from '@angular/material';
@Component({ @Component({
selector: 'squad-list', selector: 'cc-squad-list',
templateUrl: './squad-list.component.html', templateUrl: './squad-list.component.html',
styleUrls: ['./squad-list.component.css', '../../style/select-list.css'] styleUrls: ['./squad-list.component.css', '../../style/select-list.css']
}) })
@ -29,27 +28,18 @@ export class SquadListComponent implements OnInit {
constructor(private squadService: SquadService, constructor(private squadService: SquadService,
private router: Router, private router: Router,
private route: ActivatedRoute, private route: ActivatedRoute) {
private location: Location) {
} }
ngOnInit() { ngOnInit() {
this.squads$ = this.squadService.squads$; this.squads$ = this.squadService.squads$;
}
const paramsStream = this.route.queryParams initObservable(observables: any) {
.map(params => decodeURI(params['query'] || '')) Observable.merge(observables.params as Observable<string>, observables.searchTerm)
.do(query => this.searchTerm.setValue(query));
const searchTermStream = this.searchTerm.valueChanges
.debounceTime(400)
.do(query => this.adjustBrowserUrl(query));
Observable.merge(paramsStream, searchTermStream)
.distinctUntilChanged() .distinctUntilChanged()
.switchMap(query => this.squadService.findSquads(query, this.radioModel)) .switchMap(query => this.squadService.findSquads(query, this.radioModel))
.subscribe(); .subscribe();
} }
openNewSquadForm() { openNewSquadForm() {
@ -75,11 +65,4 @@ export class SquadListComponent implements OnInit {
this.radioModel = UIHelpers.toggleReleaseButton(this.radioModel, group); this.radioModel = UIHelpers.toggleReleaseButton(this.radioModel, group);
this.squads$ = this.squadService.findSquads(this.searchTerm.value, this.radioModel); this.squads$ = this.squadService.findSquads(this.searchTerm.value, this.radioModel);
} }
adjustBrowserUrl(queryString = '') {
const absoluteUrl = this.location.path().split('?')[0];
const queryPart = queryString !== '' ? `query=${queryString}` : '';
this.location.replaceState(absoluteUrl, queryPart);
}
} }

View File

@ -4,14 +4,10 @@ import {SharedModule} from '../shared.module';
import {squadRouterModule, squadsRoutingComponents} from './squads.routing'; import {squadRouterModule, squadsRoutingComponents} from './squads.routing';
import {SquadStore} from '../services/stores/squad.store'; import {SquadStore} from '../services/stores/squad.store';
import {SquadService} from '../services/army-management/squad.service'; import {SquadService} from '../services/army-management/squad.service';
import {MatButtonToggleModule} from '@angular/material';
import {MatIconModule} from '@angular/material/icon';
import {MatButtonModule} from '@angular/material/button';
@NgModule({ @NgModule({
declarations: squadsRoutingComponents, declarations: squadsRoutingComponents,
imports: [CommonModule, SharedModule, MatButtonToggleModule, MatButtonModule, MatIconModule, imports: [CommonModule, SharedModule, squadRouterModule],
squadRouterModule],
providers: [SquadStore, SquadService] providers: [SquadStore, SquadService]
}) })
export class SquadsModule { export class SquadsModule {

View File

@ -1,19 +1,3 @@
.select-list { .select-list {
padding: 20px 2% 0 5%; padding: 20px 2% 0 5%;
} }
.list-header {
width: 100%;
padding-bottom: 20px;
}
.add-btn {
margin-right: 16px;
margin-top: -3px;
float: right;
}
:host/deep/.mat-icon {
height: 32px;
width: 32px;
}

View File

@ -1,34 +1,17 @@
<div class="select-list"> <div class="select-list">
<div class="input-group list-header pull-left"> <cc-list-filter
<mat-button-toggle-group #group="matButtonToggleGroup"> [filterButtons]="[{label: fraction.BLUFOR, value: 'BLUFOR'},
<mat-button-toggle value="BLUFOR" (change)="filterUsers(undefined, group)"> {label: fraction.OPFOR, value: 'OPFOR'},
{{fraction.BLUFOR}} {label: 'Ohne Squad', value: 'UNASSIGNED'}]"
</mat-button-toggle> [addButton]="{svgIcon: 'add-user', tooltip: 'Neuen Teilnehmer hinzufügen'}"
<mat-button-toggle value="OPFOR" (change)="filterUsers(undefined, group)"> (executeSearch)="filterUsers(undefined, $event)"
{{fraction.OPFOR}} (openAddFrom)="openNewUserForm()">
</mat-button-toggle> </cc-list-filter>
<mat-button-toggle value="UNASSIGNED" (change)="filterUsers(undefined, group)">
Ohne Squad
</mat-button-toggle>
</mat-button-toggle-group>
<button mat-icon-button class="add-btn">
<mat-icon svgIcon="add-user" title="Neuen Teilnehmer hinzufügen"
(click)="openNewUserForm()"></mat-icon>
</button>
</div>
<div class="input-group list-header"> <cc-list-search [searchTerm]="searchTerm"
<input id="search-tasks" (searchTermStream)="initObservable($event)"
type="text" #query class="form-control" (executeSearch)="filterUsers()">
(keyup.enter)="filterUsers()" </cc-list-search>
[formControl]="searchTerm">
<span class="input-group-btn">
<button class="btn btn-default" type="button"
(click)="filterUsers()">
Suchen
</button>
</span>
</div>
<div class="search-results" <div class="search-results"
data-infinite-scroll data-infinite-scroll
@ -44,5 +27,4 @@
[selected]="user._id == selectedUserId"> [selected]="user._id == selectedUserId">
</pjm-user-item> </pjm-user-item>
</div> </div>
<br>
</div> </div>

View File

@ -12,7 +12,7 @@ import {MatButtonToggleGroup} from '@angular/material';
import {UIHelpers} from '../../utils/global.helpers'; import {UIHelpers} from '../../utils/global.helpers';
@Component({ @Component({
selector: 'squad-list', selector: 'cc-user-list',
templateUrl: './user-list.component.html', templateUrl: './user-list.component.html',
styleUrls: ['./user-list.component.css', '../../style/select-list.css'] styleUrls: ['./user-list.component.css', '../../style/select-list.css']
}) })
@ -38,22 +38,15 @@ export class UserListComponent implements OnInit {
constructor(private userService: UserService, constructor(private userService: UserService,
private router: Router, private router: Router,
private route: ActivatedRoute, private route: ActivatedRoute) {
private location: Location) {
} }
ngOnInit() { ngOnInit() {
this.users$ = this.userService.users$; this.users$ = this.userService.users$;
}
const paramsStream = this.route.queryParams initObservable(observables: any) {
.map(params => decodeURI(params['query'] || '')) Observable.merge(observables.params as Observable<string>, observables.searchTerm)
.do(query => this.searchTerm.setValue(query));
const searchTermStream = this.searchTerm.valueChanges
.debounceTime(400)
.do(query => this.adjustBrowserUrl(query));
Observable.merge(paramsStream, searchTermStream)
.distinctUntilChanged() .distinctUntilChanged()
.switchMap(query => this.filterUsers()) .switchMap(query => this.filterUsers())
.subscribe(); .subscribe();
@ -101,11 +94,4 @@ export class UserListComponent implements OnInit {
this.filterUsers(ADD); this.filterUsers(ADD);
} }
} }
adjustBrowserUrl(queryString = '') {
const absoluteUrl = this.location.path().split('?')[0];
const queryPart = queryString !== '' ? 'query=${queryString}' : '';
this.location.replaceState(absoluteUrl, queryPart);
}
} }

View File

@ -3,15 +3,10 @@ import {usersRouterModule, usersRoutingComponents} from './users.routing';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {SharedModule} from '../shared.module'; import {SharedModule} from '../shared.module';
import {InfiniteScrollModule} from 'ngx-infinite-scroll'; import {InfiniteScrollModule} from 'ngx-infinite-scroll';
import {MatButtonToggleModule} from '@angular/material';
import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
@NgModule({ @NgModule({
declarations: usersRoutingComponents, declarations: usersRoutingComponents,
imports: [CommonModule, SharedModule, MatButtonToggleModule, MatButtonModule, MatIconModule, imports: [CommonModule, SharedModule, InfiniteScrollModule, usersRouterModule],
InfiniteScrollModule, usersRouterModule],
}) })
export class UsersModule { export class UsersModule {
static routes = usersRouterModule; static routes = usersRouterModule;

View File

@ -34,4 +34,5 @@ export const usersRoutes: Routes = [{
export const usersRouterModule: ModuleWithProviders = RouterModule.forChild(usersRoutes); export const usersRouterModule: ModuleWithProviders = RouterModule.forChild(usersRoutes);
export const usersRoutingComponents = [UserItemComponent, UsersComponent, UserListComponent, EditUserComponent, AwardUserComponent]; export const usersRoutingComponents = [UserItemComponent, UsersComponent, UserListComponent, EditUserComponent,
AwardUserComponent];