mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
Improving search modal ui #587
This commit is contained in:
parent
286c3f4a87
commit
a62e25219d
@ -106,6 +106,7 @@ import {UsersComponent} from './ui/settings/users/users.component';
|
||||
import {SharingsListComponent} from './ui/settings/sharings-list/sharings-list.component';
|
||||
import {ThemeService} from './model/theme.service';
|
||||
import {StringifyConfigPriority} from './pipes/StringifyConfigPriority';
|
||||
import {StringifySearchType} from './pipes/StringifySearchType';
|
||||
|
||||
@Injectable()
|
||||
export class MyHammerConfig extends HammerGestureConfig {
|
||||
@ -237,6 +238,7 @@ Marker.prototype.options.icon = iconDefault;
|
||||
MDFilesFilterPipe,
|
||||
StringifySearchQuery,
|
||||
StringifyConfigPriority,
|
||||
StringifySearchType,
|
||||
FileDTOToPathPipe,
|
||||
PhotoFilterPipe,
|
||||
UsersComponent,
|
||||
|
12
src/frontend/app/pipes/StringifySearchType.ts
Normal file
12
src/frontend/app/pipes/StringifySearchType.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import {EnumTranslations} from '../ui/EnumTranslations';
|
||||
import {SearchQueryTypes} from '../../../common/entities/SearchQueryDTO';
|
||||
|
||||
@Pipe({ name: 'stringifySearchType' })
|
||||
export class StringifySearchType implements PipeTransform {
|
||||
|
||||
transform(type: SearchQueryTypes): string {
|
||||
return EnumTranslations[SearchQueryTypes[type]];
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import {UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {ConfigPriority, MapProviders, NavigationLinkTypes} from '../../../common/config/public/ClientConfig';
|
||||
import {ReIndexingSensitivity} from '../../../common/config/private/PrivateConfig';
|
||||
import {SortingMethods} from '../../../common/entities/SortingMethods';
|
||||
import {SearchQueryTypes} from '../../../common/entities/SearchQueryDTO';
|
||||
|
||||
export const EnumTranslations: Record<string, string> = {};
|
||||
export const enumToTranslatedArray = (EnumType: any): { key: number; value: string }[] => {
|
||||
@ -49,3 +50,24 @@ EnumTranslations[NavigationLinkTypes[NavigationLinkTypes.search]] = $localize`Se
|
||||
EnumTranslations[NavigationLinkTypes[NavigationLinkTypes.gallery]] = $localize`Gallery`;
|
||||
EnumTranslations[NavigationLinkTypes[NavigationLinkTypes.albums]] = $localize`Albums`;
|
||||
EnumTranslations[NavigationLinkTypes[NavigationLinkTypes.faces]] = $localize`Faces`;
|
||||
|
||||
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.AND]] = $localize`And`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.OR]] = $localize`Or`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.SOME_OF]] = $localize`Some of`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.any_text]] = $localize`Any text`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.from_date]] = $localize`From`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.to_date]] = $localize`Until`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.distance]] = $localize`Distance`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.min_rating]] = $localize`Min rating`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.max_rating]] = $localize`Max rating`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.min_resolution]] = $localize`Min resolution`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.max_resolution]] = $localize`Max resolution`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.directory]] = $localize`Directory`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.file_name]] = $localize`File name`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.caption]] = $localize`Caption`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.orientation]] = $localize`Orientation`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.position]] = $localize`Position`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.person]] = $localize`Person`;
|
||||
EnumTranslations[SearchQueryTypes[SearchQueryTypes.keyword]] = $localize`Keyword`;
|
||||
|
||||
|
@ -1,39 +1,40 @@
|
||||
<div class="row mt-1 mb-1" *ngIf="queryEntry">
|
||||
<ng-container *ngIf="IsListQuery">
|
||||
<div class="col-md-3">
|
||||
<div class="col-md-3 col-4">
|
||||
<select
|
||||
id="listSearchType"
|
||||
name="listSearchType"
|
||||
class="form-select"
|
||||
[(ngModel)]="queryEntry.type"
|
||||
(ngModelChange)="onChangeType()">
|
||||
<option *ngFor="let opt of SearchQueryTypesEnum" [ngValue]="opt.key">{{opt.value}}
|
||||
<option *ngFor="let opt of SearchQueryTypesEnum" [ngValue]="opt.key">{{opt.key | stringifySearchType}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<ng-container *ngIf="queryEntry.type == SearchQueryTypes.SOME_OF">
|
||||
<label class="col-md-4 control-label" for="someOfMinValue">
|
||||
<label class="col-4 col-sm-auto control-label" for="someOfMinValue">
|
||||
<ng-container i18n>At least this many</ng-container>
|
||||
(1-{{AsListQuery.list.length}}):</label>
|
||||
<input
|
||||
type="number" min="1" [max]="AsListQuery.list.length"
|
||||
class="form-control col-md-2" placeholder="1"
|
||||
title="At least this many"
|
||||
i18n-title
|
||||
[(ngModel)]="AsSomeOfQuery.min"
|
||||
(ngModelChange)="onChange()"
|
||||
name="someOfMinValue"
|
||||
id="someOfMinValue"
|
||||
required="required">
|
||||
<div class="col-md-2"></div>
|
||||
<div class="col-md col">
|
||||
<input
|
||||
type="number" min="1" [max]="AsListQuery.list.length"
|
||||
class="form-control" placeholder="1"
|
||||
title="At least this many"
|
||||
i18n-title
|
||||
[(ngModel)]="AsSomeOfQuery.min"
|
||||
(ngModelChange)="onChange()"
|
||||
name="someOfMinValue"
|
||||
id="someOfMinValue"
|
||||
required="required">
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="queryEntry.type != SearchQueryTypes.SOME_OF">
|
||||
<div class="col-md-8"></div>
|
||||
<div class="col"></div>
|
||||
</ng-container>
|
||||
|
||||
<button [ngClass]="'btn-danger'"
|
||||
class="btn float-end col-md-1"
|
||||
class="btn float-end col-1 align-self-center"
|
||||
(click)="deleteItem()">
|
||||
<span class="oi oi-trash" aria-hidden="true" aria-label="Delete"></span>
|
||||
</button>
|
||||
@ -43,8 +44,8 @@
|
||||
(delete)="itemDeleted(i)">
|
||||
</app-gallery-search-query-entry>
|
||||
</div>
|
||||
<div class="col d-flex justify-content-center">
|
||||
<button class="btn btn-primary mx-auto" (click)="addQuery()">
|
||||
<div class="col query-list d-flex justify-content-start">
|
||||
<button class="btn btn-primary" (click)="addQuery()">
|
||||
<span class="oi oi-plus" aria-hidden="true" aria-label="Add"> Add</span>
|
||||
</button>
|
||||
</div>
|
||||
@ -57,11 +58,11 @@
|
||||
class="form-select"
|
||||
[(ngModel)]="queryEntry.type"
|
||||
(ngModelChange)="onChangeType()">
|
||||
<option *ngFor="let opt of SearchQueryTypesEnum" [ngValue]="opt.key">{{opt.value}}
|
||||
<option *ngFor="let opt of SearchQueryTypesEnum" [ngValue]="opt.key">{{opt.key | stringifySearchType}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-8" *ngIf="IsTextQuery">
|
||||
<div class="col-11 col-md-8" *ngIf="IsTextQuery">
|
||||
<div class="input-group">
|
||||
<span title="exact match"
|
||||
p18n-title
|
||||
@ -86,36 +87,38 @@
|
||||
</div>
|
||||
</div>
|
||||
<ng-container [ngSwitch]="queryEntry.type">
|
||||
<div *ngSwitchCase="SearchQueryTypes.distance" class="col-md-8 row">
|
||||
<div class="col-md-4">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" placeholder="1"
|
||||
id="distance"
|
||||
min="0"
|
||||
step="0.1"
|
||||
[(ngModel)]="AsDistanceQuery.distance"
|
||||
(ngModelChange)="onChange()"
|
||||
name="distance" required>
|
||||
<span class="input-group-text">km</span>
|
||||
<div *ngSwitchCase="SearchQueryTypes.distance" class="col-11 col-md-8 ">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" placeholder="1"
|
||||
id="distance"
|
||||
min="0"
|
||||
step="0.1"
|
||||
[(ngModel)]="AsDistanceQuery.distance"
|
||||
(ngModelChange)="onChange()"
|
||||
name="distance" required>
|
||||
<span class="input-group-text">km</span>
|
||||
</div>
|
||||
</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"
|
||||
title="From"
|
||||
placeholder="New York"
|
||||
i18n-title
|
||||
class="form-control input-md rounded-2"
|
||||
[(ngModel)]="AsDistanceQuery.from.text"
|
||||
(ngModelChange)="onChange()"
|
||||
type="text">
|
||||
<div class="col-md-8">
|
||||
<div class="input-group">
|
||||
<label class="control-label me-2" for="maxResolution">From</label>
|
||||
<input id="from"
|
||||
name="from"
|
||||
title="From"
|
||||
placeholder="New York"
|
||||
i18n-title
|
||||
class="form-control input-md rounded-2"
|
||||
[(ngModel)]="AsDistanceQuery.from.text"
|
||||
(ngModelChange)="onChange()"
|
||||
type="text">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Range Search Query -->
|
||||
<div *ngSwitchCase="SearchQueryTypes.from_date" class="col-md-8 d-flex">
|
||||
<div *ngSwitchCase="SearchQueryTypes.from_date" class="col-11 col-md-8 d-flex">
|
||||
<input id="from_date"
|
||||
name="from_date"
|
||||
title="From date"
|
||||
@ -126,7 +129,7 @@
|
||||
class="form-control input-md rounded-2"
|
||||
type="date">
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.to_date" class="col-md-8 d-flex">
|
||||
<div *ngSwitchCase="SearchQueryTypes.to_date" class="col-11 col-md-8 d-flex">
|
||||
<input id="to_date"
|
||||
name="to_date"
|
||||
title="To date"
|
||||
@ -137,7 +140,7 @@
|
||||
class="form-control input-md rounded-2"
|
||||
type="date">
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.min_rating" class="col-md-8 d-flex">
|
||||
<div *ngSwitchCase="SearchQueryTypes.min_rating" class="col-11 col-md-8 d-flex">
|
||||
<input id="minRating"
|
||||
name="minRating"
|
||||
title="Minimum Rating"
|
||||
@ -150,7 +153,7 @@
|
||||
(ngModelChange)="onChange()"
|
||||
type="number">
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.max_rating" class="col-md-8 d-flex">
|
||||
<div *ngSwitchCase="SearchQueryTypes.max_rating" class="col-11 col-md-8 d-flex">
|
||||
<input id="maxRating"
|
||||
name="maxRating"
|
||||
title="Maximum Rating"
|
||||
@ -163,7 +166,7 @@
|
||||
(ngModelChange)="onChange()"
|
||||
type="number">
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.min_resolution" class="col-md-8">
|
||||
<div *ngSwitchCase="SearchQueryTypes.min_resolution" class="col-11 col-md-8">
|
||||
<div class="input-group">
|
||||
<input id="minResolution"
|
||||
name="minResolution"
|
||||
@ -179,7 +182,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngSwitchCase="SearchQueryTypes.max_resolution" class="col-md-8">
|
||||
<div *ngSwitchCase="SearchQueryTypes.max_resolution" class="col-11 col-md-8">
|
||||
<div class="input-group">
|
||||
<input id="maxResolution"
|
||||
name="maxResolution"
|
||||
@ -194,7 +197,7 @@
|
||||
<span class="input-group-text">Mpx</span>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngSwitchCase="SearchQueryTypes.orientation" class="col-md-8 d-flex">
|
||||
<div *ngSwitchCase="SearchQueryTypes.orientation" class="col-11 col-md-8 d-flex">
|
||||
<div class="input-group col-md-6">
|
||||
<select class="form-select rounded-2"
|
||||
[(ngModel)]="AsOrientationQuery.landscape"
|
||||
@ -210,7 +213,7 @@
|
||||
</div>
|
||||
</ng-container>
|
||||
<button [ngClass]="'btn-danger'"
|
||||
class="btn float-end col-md-1"
|
||||
class="btn float-end col-1 align-self-center"
|
||||
(click)="deleteItem()">
|
||||
<span class="oi oi-trash" aria-hidden="true" aria-label="Delete"></span>
|
||||
</button>
|
||||
|
@ -37,24 +37,27 @@
|
||||
(search)="Search()">
|
||||
</app-gallery-search-query-builder>
|
||||
|
||||
|
||||
<div class="btn-group float-end row" style="display: block">
|
||||
<div class="pe-0">
|
||||
<button *ngIf="CanCreateAlbum"
|
||||
class="btn btn-secondary me-2" type="button"
|
||||
[disabled]="rawSearchText == ''"
|
||||
(click)="openSaveSearchModal(saveSearchModal)">
|
||||
<span class="oi oi-folder me-2"></span><ng-container i18n>Save</ng-container>
|
||||
</button>
|
||||
<button class="btn btn-primary" type="button"
|
||||
[routerLink]="['/search', HTMLSearchQuery]"
|
||||
(click)="hideSearchModal()">
|
||||
<span class="oi oi-magnifying-glass me-2"></span><ng-container i18n>Search</ng-container>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="btn-group float-end row" style="display: block">
|
||||
<div class="pe-0">
|
||||
<button *ngIf="CanCreateAlbum"
|
||||
class="btn btn-secondary me-2" type="button"
|
||||
[disabled]="rawSearchText == ''"
|
||||
(click)="openSaveSearchModal(saveSearchModal)">
|
||||
<span class="oi oi-folder me-2"></span>
|
||||
<ng-container i18n>Save</ng-container>
|
||||
</button>
|
||||
<button class="btn btn-primary" type="button"
|
||||
[routerLink]="['/search', HTMLSearchQuery]"
|
||||
(click)="hideSearchModal()">
|
||||
<span class="oi oi-magnifying-glass me-2"></span>
|
||||
<ng-container i18n>Search</ng-container>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #saveSearchModal>
|
||||
@ -90,7 +93,8 @@
|
||||
<button class="btn btn-primary" type="button"
|
||||
[disabled]="saveSearchName == ''"
|
||||
(click)="saveSearch()">
|
||||
<span class="oi oi-folder me-2"></span><ng-container i18n>Save as album</ng-container>
|
||||
<span class="oi oi-folder me-2"></span>
|
||||
<ng-container i18n>Save as album</ng-container>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user