From dd6d2a7ce50e7ff02e00995ccc87f8f929ad9709 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 3 Nov 2021 14:23:55 +0100 Subject: Improve advanced input filter --- .../advanced-input-filter.component.html | 6 ++- .../advanced-input-filter.component.scss | 23 ++++++++ .../advanced-input-filter.component.ts | 61 ++++++++++++++++++++-- 3 files changed, 84 insertions(+), 6 deletions(-) (limited to 'client/src/app/shared/shared-forms') diff --git a/client/src/app/shared/shared-forms/advanced-input-filter.component.html b/client/src/app/shared/shared-forms/advanced-input-filter.component.html index c662b9bb6..7031cb53b 100644 --- a/client/src/app/shared/shared-forms/advanced-input-filter.component.html +++ b/client/src/app/shared/shared-forms/advanced-input-filter.component.html @@ -8,9 +8,11 @@ - + diff --git a/client/src/app/shared/shared-forms/advanced-input-filter.component.scss b/client/src/app/shared/shared-forms/advanced-input-filter.component.scss index 07a43761c..ee1b3b508 100644 --- a/client/src/app/shared/shared-forms/advanced-input-filter.component.scss +++ b/client/src/app/shared/shared-forms/advanced-input-filter.component.scss @@ -1,6 +1,10 @@ @use '_variables' as *; @use '_mixins' as *; +.dropdown-item { + font-size: 14px; +} + input { @include peertube-input-text(250px); } @@ -8,3 +12,22 @@ input { .input-group-text { background-color: transparent; } + +my-global-icon { + $size: 18px; + $margin: 2px; + + @include margin-right($margin); + + opacity: 1; + width: 18px; + height: 18px; + + + &.no-visible { + @include margin-right($size + $margin); + + width: 0; + height: 0; + } +} diff --git a/client/src/app/shared/shared-forms/advanced-input-filter.component.ts b/client/src/app/shared/shared-forms/advanced-input-filter.component.ts index a12dddf7a..d8aeaa0fa 100644 --- a/client/src/app/shared/shared-forms/advanced-input-filter.component.ts +++ b/client/src/app/shared/shared-forms/advanced-input-filter.component.ts @@ -3,14 +3,17 @@ import { Subject } from 'rxjs' import { debounceTime, distinctUntilChanged } from 'rxjs/operators' import { AfterViewInit, Component, EventEmitter, Input, OnInit, Output } from '@angular/core' import { ActivatedRoute, Params, Router } from '@angular/router' +import { RestService } from '@app/core' export type AdvancedInputFilter = { title: string - children: { - label: string - queryParams: Params - }[] + children: AdvancedInputFilterChild[] +} + +export type AdvancedInputFilterChild = { + label: string + value: string } const logger = debug('peertube:AdvancedInputFilterComponent') @@ -28,6 +31,8 @@ export class AdvancedInputFilterComponent implements OnInit, AfterViewInit { searchValue: string + private enabledFilters = new Set() + private searchStream: Subject private viewInitialized = false @@ -35,6 +40,7 @@ export class AdvancedInputFilterComponent implements OnInit, AfterViewInit { constructor ( private route: ActivatedRoute, + private restService: RestService, private router: Router ) { } @@ -62,6 +68,18 @@ export class AdvancedInputFilterComponent implements OnInit, AfterViewInit { return this.filters && this.filters.length !== 0 } + isFilterEnabled (filter: AdvancedInputFilterChild) { + return this.enabledFilters.has(filter.value) + } + + onFilterClick (filter: AdvancedInputFilterChild) { + const newSearch = this.isFilterEnabled(filter) + ? this.removeFilterToSearch(this.searchValue, filter) + : this.addFilterToSearch(this.searchValue, filter) + + this.router.navigate([ '.' ], { relativeTo: this.route, queryParams: { search: newSearch.trim() } }) + } + private scheduleSearchUpdate (value: string) { this.searchValue = value this.searchStream.next(this.searchValue) @@ -71,6 +89,7 @@ export class AdvancedInputFilterComponent implements OnInit, AfterViewInit { this.searchValue = value this.setQueryParams(this.searchValue) + this.parseFilters(this.searchValue) this.emitSearch() } @@ -84,6 +103,9 @@ export class AdvancedInputFilterComponent implements OnInit, AfterViewInit { if (this.searchValue === search) return this.searchValue = search + + this.parseFilters(this.searchValue) + this.emitSearch() }) } @@ -98,6 +120,7 @@ export class AdvancedInputFilterComponent implements OnInit, AfterViewInit { ) .subscribe(() => { this.setQueryParams(this.searchValue) + this.parseFilters(this.searchValue) this.emitSearch() }) @@ -120,4 +143,34 @@ export class AdvancedInputFilterComponent implements OnInit, AfterViewInit { if (search) Object.assign(queryParams, { search }) this.router.navigate([ ], { queryParams }) } + + private removeFilterToSearch (search: string, removedFilter: AdvancedInputFilterChild) { + return search.replace(removedFilter.value, '') + } + + private addFilterToSearch (search: string, newFilter: AdvancedInputFilterChild) { + const prefix = newFilter.value.split(':').shift() + + // Tokenize search and remove a potential existing filter + const tokens = this.restService.tokenizeString(search) + .filter(t => !t.startsWith(prefix)) + + tokens.push(newFilter.value) + + return tokens.join(' ') + } + + private parseFilters (search: string) { + const tokens = this.restService.tokenizeString(search) + + this.enabledFilters = new Set() + + for (const group of this.filters) { + for (const filter of group.children) { + if (tokens.includes(filter.value)) { + this.enabledFilters.add(filter.value) + } + } + } + } } -- cgit v1.2.3