mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-11-28 08:58:49 +02:00
Improve search UI #683
This commit is contained in:
parent
b6b8170187
commit
d31cf0040c
@ -41,7 +41,7 @@ export class AdminComponent implements OnInit, AfterViewInit {
|
||||
this.configStyles = enumToTranslatedArray(ConfigStyle);
|
||||
const wc = WebConfigClassBuilder.attachPrivateInterface(new WebConfig());
|
||||
this.configPaths = Object.keys(wc.State)
|
||||
.filter(s => !wc.__state[s].volatile);
|
||||
.filter(s => !wc.__state[s].volatile && s === 'Jobs');
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
|
@ -2,6 +2,7 @@ import {Component, EventEmitter, forwardRef, Input, Output,} from '@angular/core
|
||||
import {SearchQueryDTO, SearchQueryTypes, TextSearch,} from '../../../../../../common/entities/SearchQueryDTO';
|
||||
import {ControlValueAccessor, NG_VALIDATORS, NG_VALUE_ACCESSOR, UntypedFormControl, ValidationErrors, Validator,} from '@angular/forms';
|
||||
import {SearchQueryParserService} from '../search-query-parser.service';
|
||||
import {Utils} from '../../../../../../common/Utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-search-query-builder',
|
||||
@ -34,10 +35,15 @@ export class GallerySearchQueryBuilderComponent
|
||||
}
|
||||
|
||||
validateRawSearchText(): void {
|
||||
|
||||
try {
|
||||
this.searchQueryDTO = this.searchQueryParserService.parse(
|
||||
const newDTO = this.searchQueryParserService.parse(
|
||||
this.rawSearchText
|
||||
);
|
||||
if (Utils.equalsFilter(this.searchQueryDTO, newDTO)) {
|
||||
return;
|
||||
}
|
||||
this.searchQueryDTO = newDTO;
|
||||
this.onChange();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
@ -61,6 +67,17 @@ export class GallerySearchQueryBuilderComponent
|
||||
}
|
||||
|
||||
public writeValue(obj: any): void {
|
||||
try {
|
||||
// do not trigger change if nothing changed
|
||||
if (Utils.equalsFilter(this.searchQueryDTO, obj) &&
|
||||
Utils.equalsFilter(this.searchQueryParserService.parse(
|
||||
this.rawSearchText
|
||||
), obj)) {
|
||||
return;
|
||||
}
|
||||
}catch (e) {
|
||||
// if cant parse they are not the same
|
||||
}
|
||||
this.searchQueryDTO = obj;
|
||||
this.rawSearchText = this.searchQueryParserService.stringify(
|
||||
this.searchQueryDTO
|
||||
@ -76,6 +93,14 @@ export class GallerySearchQueryBuilderComponent
|
||||
}
|
||||
|
||||
public onChange(): void {
|
||||
try {
|
||||
if (Utils.equalsFilter(this.searchQueryParserService.parse(this.rawSearchText), this.searchQueryDTO)) {
|
||||
this.propagateChange(this.searchQueryDTO);
|
||||
return;
|
||||
}
|
||||
}catch (e) {
|
||||
// if cant parse they are not the same
|
||||
}
|
||||
this.rawSearchText = this.searchQueryParserService.stringify(
|
||||
this.searchQueryDTO
|
||||
);
|
||||
|
@ -2,8 +2,8 @@
|
||||
<ng-container *ngIf="IsListQuery">
|
||||
<div class="col-md-3 col-4">
|
||||
<select
|
||||
id="listSearchType"
|
||||
name="listSearchType"
|
||||
[id]="'listSearchType'+id"
|
||||
[name]="'listSearchType'+id"
|
||||
class="form-select"
|
||||
[(ngModel)]="queryEntry.type"
|
||||
(ngModelChange)="onChangeType()">
|
||||
@ -12,7 +12,7 @@
|
||||
</select>
|
||||
</div>
|
||||
<ng-container *ngIf="queryEntry.type == SearchQueryTypes.SOME_OF">
|
||||
<label class="col-4 col-sm-auto control-label" for="someOfMinValue">
|
||||
<label class="col-4 col-sm-auto control-label" [for]="'someOfMinValue'+id">
|
||||
<ng-container i18n>At least this many</ng-container>
|
||||
(1-{{AsListQuery.list.length}}):</label>
|
||||
<div class="col-md col">
|
||||
@ -23,8 +23,8 @@
|
||||
i18n-title
|
||||
[(ngModel)]="AsSomeOfQuery.min"
|
||||
(ngModelChange)="onChange()"
|
||||
name="someOfMinValue"
|
||||
id="someOfMinValue"
|
||||
[name]="'someOfMinValue'+id"
|
||||
[id]="'someOfMinValue'+id"
|
||||
required="required">
|
||||
</div>
|
||||
</ng-container>
|
||||
@ -40,6 +40,7 @@
|
||||
</button>
|
||||
<div class="container query-list">
|
||||
<app-gallery-search-query-entry *ngFor="let sq of AsListQuery.list; index as i"
|
||||
[id]="id+'_'+i"
|
||||
[(ngModel)]="AsListQuery.list[i]"
|
||||
(delete)="itemDeleted(i)">
|
||||
</app-gallery-search-query-entry>
|
||||
@ -49,7 +50,7 @@
|
||||
<ng-icon
|
||||
class="me-1"
|
||||
style="margin-left: -0.1em; margin-right: -0.1em"
|
||||
name="ionAddOutline"
|
||||
[name]="'ionAddOutline'+id"
|
||||
title="Add" i18n-title></ng-icon>
|
||||
<span i18n>Add</span>
|
||||
</button>
|
||||
@ -59,8 +60,8 @@
|
||||
<div class="col-lg-4 col-xl-3">
|
||||
<div class="input-group">
|
||||
<select
|
||||
id="searchType"
|
||||
name="searchType"
|
||||
[id]="'searchType'+id"
|
||||
[name]="'searchType'+id"
|
||||
class="form-select"
|
||||
[(ngModel)]="queryEntry.type"
|
||||
(ngModelChange)="onChangeType()">
|
||||
@ -68,11 +69,11 @@
|
||||
</option>
|
||||
</select>
|
||||
<select
|
||||
id="negate"
|
||||
name="negate"
|
||||
[id]="'negate'+id"
|
||||
[name]="'negate'+id"
|
||||
class="form-select w-auto flex-grow-0"
|
||||
title="Negate"
|
||||
p18n-title
|
||||
i18n-title
|
||||
[(ngModel)]="SelectedMatchType"
|
||||
(ngModelChange)="onChange()">
|
||||
<option *ngFor="let mt of MatchingTypes" [ngValue]="mt">{{mt}}
|
||||
@ -82,8 +83,8 @@
|
||||
<div class="col-10 col-lg" *ngIf="IsTextQuery">
|
||||
<div class="input-group">
|
||||
<input
|
||||
id="searchField"
|
||||
name="searchField"
|
||||
[id]="'searchField'+id"
|
||||
[name]="'searchField'+id"
|
||||
placeholder="Search text"
|
||||
i18n-placeholder
|
||||
class="form-control rounded-2"
|
||||
@ -104,15 +105,15 @@
|
||||
step="0.1"
|
||||
[(ngModel)]="AsDistanceQuery.distance"
|
||||
(ngModelChange)="onChange()"
|
||||
name="distance" required>
|
||||
[name]="'distance'+id" required>
|
||||
<span class="input-group-text">km</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="input-group">
|
||||
<label class="control-label me-2" for="maxResolution">From</label>
|
||||
<input id="from"
|
||||
name="from"
|
||||
<label class="control-label me-2" [for]="'maxResolution_'+id">From</label>
|
||||
<input [name]="'maxResolution_'+id"
|
||||
[id]="'maxResolution_'+id"
|
||||
title="From"
|
||||
placeholder="New York"
|
||||
i18n-title
|
||||
@ -132,13 +133,14 @@
|
||||
i18n-title
|
||||
[ngModel]="AsRangeQuery.value | date:'yyyy-MM-dd'"
|
||||
(ngModelChange)="AsRangeQuery.value = $event; onChange() "
|
||||
[value]="AsRangeQuery.value | date:'yyyy-MM-dd'" #from_date="ngModel"
|
||||
[value]="AsRangeQuery.value | date:'yyyy-MM-dd'"
|
||||
#from_date="ngModel"
|
||||
class="form-control input-md rounded-2"
|
||||
type="date">
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.to_date" class="col-10 col-lg d-flex">
|
||||
<input id="to_date"
|
||||
name="to_date"
|
||||
<input [id]="'to_date'+id"
|
||||
[name]="'to_date'+id"
|
||||
title="To date"
|
||||
i18n-title
|
||||
[ngModel]="AsRangeQuery.value | date:'yyyy-MM-dd'"
|
||||
@ -148,8 +150,8 @@
|
||||
type="date">
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.min_rating" class="col-10 col-lg d-flex">
|
||||
<input id="minRating"
|
||||
name="minRating"
|
||||
<input [id]="'minRating'+id"
|
||||
[name]="'minRating'+id"
|
||||
title="Minimum Rating"
|
||||
placeholder="0"
|
||||
i18n-title
|
||||
@ -161,8 +163,8 @@
|
||||
type="number">
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.max_rating" class="col-10 col-lg d-flex">
|
||||
<input id="maxRating"
|
||||
name="maxRating"
|
||||
<input [id]="'maxRating'+id"
|
||||
[name]="'maxRating'+id"
|
||||
title="Maximum Rating"
|
||||
placeholder="5"
|
||||
i18n-title
|
||||
@ -174,8 +176,8 @@
|
||||
type="number">
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.min_person_count" class="col-10 col-lg d-flex">
|
||||
<input id="min_person_count"
|
||||
name="min_person_count"
|
||||
<input [id]="'min_person_count'+id"
|
||||
[name]="'min_person_count'+id"
|
||||
title="Minimum Person count"
|
||||
placeholder="0"
|
||||
i18n-title
|
||||
@ -187,8 +189,8 @@
|
||||
type="number">
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.max_person_count" class="col-10 col-lg d-flex">
|
||||
<input id="max_person_count"
|
||||
name="max_person_count"
|
||||
<input [id]="'max_person_count'+id"
|
||||
[name]="'max_person_count'+id"
|
||||
title="Maximum Person count"
|
||||
placeholder="5"
|
||||
i18n-title
|
||||
@ -201,8 +203,8 @@
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.min_resolution" class="col-10 col-lg">
|
||||
<div class="input-group">
|
||||
<input id="minResolution"
|
||||
name="minResolution"
|
||||
<input [id]="'minResolution'+id"
|
||||
[name]="'minResolution'+id"
|
||||
title="Minimum Resolution"
|
||||
placeholder="0"
|
||||
i18n-title
|
||||
@ -217,8 +219,8 @@
|
||||
|
||||
<div *ngSwitchCase="SearchQueryTypes.max_resolution" class="col-10 col-lg">
|
||||
<div class="input-group">
|
||||
<input id="maxResolution"
|
||||
name="maxResolution"
|
||||
<input [id]="'maxResolution'+id"
|
||||
[name]="'maxResolution'+id"
|
||||
title="Maximum Resolution"
|
||||
placeholder="5"
|
||||
i18n-title
|
||||
@ -232,11 +234,11 @@
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.orientation" class="col-10 col-lg d-flex">
|
||||
<div class="input-group col-md-6">
|
||||
<select class="form-select rounded-2"
|
||||
<select [id]="'orientation-select'+id"
|
||||
[name]="'orientation-select'+id"
|
||||
class="form-select rounded-2"
|
||||
[(ngModel)]="AsOrientationQuery.landscape"
|
||||
(ngModelChange)="onChange()"
|
||||
id="orientation-select"
|
||||
name="orientation-select"
|
||||
title="Orientation"
|
||||
required>
|
||||
<option [ngValue]="true" i18n>Landscape</option>
|
||||
@ -249,8 +251,8 @@
|
||||
<div class="row">
|
||||
<div class="input-group col-md-6">
|
||||
<span class="input-group-text" i18n>Last</span>
|
||||
<input id="daysLength"
|
||||
name="daysLength"
|
||||
<input [id]="'daysLength'+id"
|
||||
[name]="'daysLength'+id"
|
||||
title="Last N Days"
|
||||
placeholder="1"
|
||||
i18n-title
|
||||
@ -265,8 +267,8 @@
|
||||
<div class="input-group col-md-6">
|
||||
<input
|
||||
*ngIf="AsDatePatternQuery.frequency == DatePatternFrequency.days_ago || AsDatePatternQuery.frequency == DatePatternFrequency.weeks_ago || AsDatePatternQuery.frequency == DatePatternFrequency.months_ago || AsDatePatternQuery.frequency == DatePatternFrequency.years_ago"
|
||||
id="agoNumber"
|
||||
name="agoNumber"
|
||||
[id]="'agoNumber'+id"
|
||||
[name]="'agoNumber'+id"
|
||||
title="Ago"
|
||||
placeholder="1"
|
||||
i18n-title
|
||||
@ -278,8 +280,8 @@
|
||||
<select class="form-select rounded-2"
|
||||
[(ngModel)]="AsDatePatternQuery.frequency"
|
||||
(ngModelChange)="onChange()"
|
||||
id="date_pattern-select"
|
||||
name="date_pattern-select"
|
||||
[id]="'date_pattern-select'+id"
|
||||
[name]="'date_pattern-select'+id"
|
||||
title="Date Pattern"
|
||||
required>
|
||||
<option [ngValue]="DatePatternFrequency.days_ago" i18n>Day(s) ago</option>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {Component, EventEmitter, forwardRef, Output} from '@angular/core';
|
||||
import {Component, EventEmitter, forwardRef, Input, Output} from '@angular/core';
|
||||
import {
|
||||
DatePatternFrequency,
|
||||
DatePatternSearch,
|
||||
@ -42,6 +42,7 @@ export class GallerySearchQueryEntryComponent
|
||||
public DatePatternFrequency = DatePatternFrequency;
|
||||
public TextSearchQueryMatchTypes = TextSearchQueryMatchTypes;
|
||||
@Output() delete = new EventEmitter<void>();
|
||||
@Input() id = 'NA';
|
||||
|
||||
constructor() {
|
||||
this.SearchQueryTypesEnum = Utils.enumToArray(SearchQueryTypes);
|
||||
|
@ -4,6 +4,7 @@
|
||||
[placeholder]="placeholder"
|
||||
(keyup)="onSearchChange($event)"
|
||||
(blur)="onFocusLost()"
|
||||
(focus)="onFocus()"
|
||||
[(ngModel)]="rawSearchText"
|
||||
(ngModelChange)="onChange()"
|
||||
(keydown.enter)="OnEnter($event)"
|
||||
|
@ -49,6 +49,7 @@ export class GallerySearchFieldBaseComponent
|
||||
};
|
||||
private autoCompleteItemsSubscription: Subscription = null;
|
||||
private autoCompleteItems: BehaviorSubject<RenderableAutoCompleteItem[]>;
|
||||
inFocus: boolean;
|
||||
|
||||
constructor(
|
||||
private autoCompleteService: AutoCompleteService,
|
||||
@ -68,6 +69,7 @@ export class GallerySearchFieldBaseComponent
|
||||
return '';
|
||||
}
|
||||
if (
|
||||
!this.inFocus ||
|
||||
!this.autoCompleteItems ||
|
||||
!this.autoCompleteItems.value ||
|
||||
this.autoCompleteItems.value.length === 0
|
||||
@ -130,7 +132,12 @@ export class GallerySearchFieldBaseComponent
|
||||
this.mouseOverAutoComplete = value;
|
||||
}
|
||||
|
||||
onFocus(): void {
|
||||
this.inFocus = true;
|
||||
}
|
||||
|
||||
public onFocusLost(): void {
|
||||
this.inFocus = false;
|
||||
if (this.mouseOverAutoComplete === false) {
|
||||
this.autoCompleteRenders = [];
|
||||
}
|
||||
@ -160,6 +167,7 @@ export class GallerySearchFieldBaseComponent
|
||||
0,
|
||||
this.rawSearchText.length - token.current.length
|
||||
) + item.queryHint;
|
||||
console.log('aa');
|
||||
this.onChange();
|
||||
this.emptyAutoComplete();
|
||||
}
|
||||
@ -299,5 +307,6 @@ export class GallerySearchFieldBaseComponent
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function
|
||||
private propagateTouch = (_: never): void => {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
name="search-query-builder"
|
||||
[(ngModel)]="searchQueryDTO"
|
||||
[placeholder]="placeholder"
|
||||
(change)="onQueryChange()"
|
||||
(ngModelChange)="onQueryChange()"
|
||||
(search)="search.emit()">
|
||||
</app-gallery-search-query-builder>
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
import {Component, EventEmitter, forwardRef, Input, Output,TemplateRef} from '@angular/core';
|
||||
import {Component, EventEmitter, forwardRef, Input, Output, TemplateRef} from '@angular/core';
|
||||
import {Router, RouterLink} from '@angular/router';
|
||||
import {AutoCompleteService} from '../autocomplete.service';
|
||||
import {SearchQueryDTO} from '../../../../../../common/entities/SearchQueryDTO';
|
||||
import {ControlValueAccessor, UntypedFormControl, NG_VALIDATORS, NG_VALUE_ACCESSOR, ValidationErrors, Validator,} from '@angular/forms';
|
||||
import {ControlValueAccessor, NG_VALIDATORS, NG_VALUE_ACCESSOR, UntypedFormControl, ValidationErrors, Validator,} from '@angular/forms';
|
||||
import {SearchQueryParserService} from '../search-query-parser.service';
|
||||
import {BsModalRef, BsModalService,} from '../../../../../../../node_modules/ngx-bootstrap/modal';
|
||||
import {Utils} from '../../../../../../common/Utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-search-field',
|
||||
@ -58,6 +59,16 @@ export class GallerySearchFieldComponent
|
||||
}
|
||||
|
||||
public writeValue(obj: SearchQueryDTO): void {
|
||||
try {
|
||||
if (Utils.equalsFilter(this.searchQueryDTO, obj) &&
|
||||
Utils.equalsFilter(this.searchQueryParserService.parse(
|
||||
this.rawSearchText
|
||||
), obj)) {
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
// if cant parse they are not the same
|
||||
}
|
||||
this.searchQueryDTO = obj;
|
||||
this.rawSearchText = this.searchQueryParserService.stringify(
|
||||
this.searchQueryDTO
|
||||
@ -81,9 +92,18 @@ export class GallerySearchFieldComponent
|
||||
}
|
||||
|
||||
onQueryChange(): void {
|
||||
try {
|
||||
if (Utils.equalsFilter(this.searchQueryParserService.parse(this.rawSearchText), this.searchQueryDTO)) {
|
||||
this.onChange();
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
// if cant parse they are not the same
|
||||
}
|
||||
this.rawSearchText = this.searchQueryParserService.stringify(
|
||||
this.searchQueryDTO
|
||||
);
|
||||
|
||||
this.onChange();
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
<app-gallery-search-query-builder
|
||||
name="search-query-builder"
|
||||
[(ngModel)]="searchQueryDTO"
|
||||
(change)="onQueryChange()"
|
||||
(ngModelChange)="onQueryChange()"
|
||||
(search)="Search()">
|
||||
</app-gallery-search-query-builder>
|
||||
|
||||
|
@ -11,6 +11,7 @@ import {AlbumsService} from '../../albums/albums.service';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {UserRoles} from '../../../../../common/entities/UserDTO';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-search',
|
||||
@ -102,11 +103,14 @@ export class GallerySearchComponent implements OnDestroy {
|
||||
this.saveSearchModalRef = null;
|
||||
}
|
||||
|
||||
onQueryChange(): void {
|
||||
public onQueryChange(): void {
|
||||
if (Utils.equalsFilter(this.searchQueryParserService.parse(this.rawSearchText), this.searchQueryDTO)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.rawSearchText = this.searchQueryParserService.stringify(
|
||||
this.searchQueryDTO
|
||||
);
|
||||
// this.validateRawSearchText();
|
||||
}
|
||||
|
||||
validateRawSearchText(): void {
|
||||
|
@ -41,12 +41,13 @@
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="mb-1 row">
|
||||
<label class="col-md-2 control-label" [for]="'jobName'+i" i18n>Job:</label>
|
||||
<label class="col-md-2 control-label" i18n>Job:</label>
|
||||
<div class="col-md-4">
|
||||
{{backendTextService.getJobName(schedule.jobName)}}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<app-settings-job-button class="float-end"
|
||||
[id]="'jobName'+i"
|
||||
[jobName]="schedule.jobName"
|
||||
[allowParallelRun]="schedule.allowParallelRun"
|
||||
(jobError)="error=$event"
|
||||
@ -59,7 +60,9 @@
|
||||
<div class="col-md-10">
|
||||
<select class="form-select" [(ngModel)]="schedule.trigger.type"
|
||||
(ngModelChange)="jobTriggerTypeChanged($event,schedule); onChange($event);"
|
||||
[name]="'repeatType'+i" required>
|
||||
[name]="'repeatType'+i"
|
||||
[id]="'repeatType'+i"
|
||||
required>
|
||||
<option *ngFor="let jobTrigger of JobTriggerTypeMap"
|
||||
[ngValue]="jobTrigger.key">{{jobTrigger.value}}
|
||||
</option>
|
||||
@ -78,7 +81,8 @@
|
||||
<select class="form-select"
|
||||
[(ngModel)]="schedule.trigger.afterScheduleName"
|
||||
(ngModelChange)="onChange($event)"
|
||||
[name]="'triggerAfter'+i" required>
|
||||
[name]="'triggerAfter'+i"
|
||||
[id]="'triggerAfter'+i" required>
|
||||
<ng-container *ngFor="let sch of sortedSchedules">
|
||||
<option *ngIf="sch.name !== schedule.name"
|
||||
[ngValue]="sch.name">{{sch.name}}
|
||||
@ -99,6 +103,7 @@
|
||||
<div class="col-md-10">
|
||||
<app-timestamp-datepicker
|
||||
[name]="'triggerTime'+i"
|
||||
[id]="'triggerTime'+i"
|
||||
(timestampChange)="onChange($event)"
|
||||
[(timestamp)]="schedule.trigger.time"></app-timestamp-datepicker>
|
||||
</div>
|
||||
@ -114,6 +119,7 @@
|
||||
[(ngModel)]="schedule.trigger.periodicity"
|
||||
(ngModelChange)="onChange($event)"
|
||||
[name]="'periodicity' + i"
|
||||
[id]="'periodicity' + i"
|
||||
required>
|
||||
<option *ngFor="let period of periods; let i = index"
|
||||
[ngValue]="i">
|
||||
@ -292,7 +298,7 @@
|
||||
<div class="mb-1 row"
|
||||
[class.mb-3]="settingsService.configStyle == ConfigStyle.full">
|
||||
<label class="col-md-2 control-label"
|
||||
[for]="configEntry.id+'_'+i" i18n>Pick</label>
|
||||
[for]="configEntry.id+'_'+i+'_'+j" i18n>Pick</label>
|
||||
<div class="col-md-10">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" [name]="configEntry.id+'_'+i+'_'+j"
|
||||
|
28
test/cypress/e2e/search.cy.ts
Normal file
28
test/cypress/e2e/search.cy.ts
Normal file
@ -0,0 +1,28 @@
|
||||
describe('Search', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/');
|
||||
cy.get('.card-body');
|
||||
cy.get('.col-sm-12').contains('Login');
|
||||
/* ==== Generated with Cypress Studio ==== */
|
||||
cy.get('#username').type('admin');
|
||||
cy.get('#password').clear();
|
||||
cy.get('#password').type('admin');
|
||||
cy.intercept({
|
||||
method: 'Get',
|
||||
url: '/pgapi/gallery/content/',
|
||||
}).as('getContent');
|
||||
cy.get('.col-sm-12 > .btn').click();
|
||||
});
|
||||
it('Search builder should propagate to search bar', () => {
|
||||
cy.get('.mb-0 > :nth-child(1) > .nav-link').contains('Gallery');
|
||||
|
||||
cy.get('app-gallery-search .search-text').type('a and b', {force: true});
|
||||
cy.get('app-gallery-search ng-icon[name="ionChevronDownOutline"]').click();
|
||||
cy.get('app-gallery-search-query-builder app-gallery-search-field-base input.search-text').should('have.value', 'a and b');
|
||||
cy.get('app-gallery-search-query-entry .btn-danger').last().click();
|
||||
cy.get('app-gallery-search-query-builder app-gallery-search-field-base input.search-text').should('have.value', 'a');
|
||||
cy.get('modal-container .btn-close').click();
|
||||
cy.get('app-gallery-search .search-text').should('have.value', 'a');
|
||||
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user