mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-01-20 04:59:33 +02:00
Updating random photo query builder to use advanced search #58
This commit is contained in:
parent
41292ec4b4
commit
270d5af74d
@ -154,15 +154,11 @@ export class GalleryMWs {
|
||||
|
||||
|
||||
public static async search(req: Request, res: Response, next: NextFunction) {
|
||||
if (Config.Client.Search.enabled === false || !req.query[QueryParams.gallery.search.query]) {
|
||||
if (Config.Client.Search.enabled === false || !(req.params.searchQueryDTO)) {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!(req.params.text)) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const query: SearchQueryDTO = <any>req.query[QueryParams.gallery.search.query];
|
||||
const query: SearchQueryDTO = JSON.parse(<any>req.params.searchQueryDTO);
|
||||
|
||||
try {
|
||||
const result = await ObjectManagers.getInstance().SearchManager.search(query);
|
||||
@ -199,11 +195,12 @@ export class GalleryMWs {
|
||||
|
||||
|
||||
public static async getRandomImage(req: Request, res: Response, next: NextFunction) {
|
||||
if (Config.Client.RandomPhoto.enabled === false) {
|
||||
if (Config.Client.RandomPhoto.enabled === false || !(req.params.searchQueryDTO)) {
|
||||
return next();
|
||||
}
|
||||
|
||||
try {
|
||||
const query: SearchQueryDTO = <any>req.query[QueryParams.gallery.search.query];
|
||||
const query: SearchQueryDTO = JSON.parse(<any>req.params.searchQueryDTO);
|
||||
|
||||
const photo = await ObjectManagers.getInstance()
|
||||
.SearchManager.getRandomPhoto(query);
|
||||
|
@ -450,6 +450,7 @@ export class SearchManager implements ISearchManager {
|
||||
textParam['CtextC' + paramCounter.value] = `%,${(<TextSearch>query).text},%`;
|
||||
textParam['Ctext' + paramCounter.value] = `%,${(<TextSearch>query).text}`;
|
||||
textParam['textC' + paramCounter.value] = `${(<TextSearch>query).text},%`;
|
||||
textParam['text_exact' + paramCounter.value] = `${(<TextSearch>query).text}`;
|
||||
|
||||
qb[whereFN](`${fieldName} ${LIKE} :CtextC${paramCounter.value} COLLATE utf8_general_ci`,
|
||||
textParam);
|
||||
@ -457,6 +458,8 @@ export class SearchManager implements ISearchManager {
|
||||
textParam);
|
||||
qb[whereFN](`${fieldName} ${LIKE} :textC${paramCounter.value} COLLATE utf8_general_ci`,
|
||||
textParam);
|
||||
qb[whereFN](`${fieldName} ${LIKE} :text_exact${paramCounter.value} COLLATE utf8_general_ci`,
|
||||
textParam);
|
||||
}));
|
||||
}
|
||||
if ((<TextSearch>query).negate) {
|
||||
|
@ -113,7 +113,7 @@ export class GalleryRouter {
|
||||
}
|
||||
|
||||
protected static addRandom(app: Express) {
|
||||
app.get(['/api/gallery/random'],
|
||||
app.get(['/api/gallery/random/:searchQueryDTO'],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
@ -184,7 +184,7 @@ export class GalleryRouter {
|
||||
}
|
||||
|
||||
protected static addSearch(app: Express) {
|
||||
app.get('/api/search/:text',
|
||||
app.get('/api/search/:searchQueryDTO',
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
|
@ -1,14 +0,0 @@
|
||||
export enum OrientationType {
|
||||
any = 0, portrait = 1, landscape = 2
|
||||
}
|
||||
|
||||
// TODO replace it with advanced search
|
||||
export interface RandomQueryDTO {
|
||||
directory?: string;
|
||||
recursive?: boolean;
|
||||
orientation?: OrientationType;
|
||||
fromDate?: string;
|
||||
toDate?: string;
|
||||
minResolution?: number;
|
||||
maxResolution?: number;
|
||||
}
|
@ -94,6 +94,7 @@ import {ErrorInterceptor} from './model/network/helper/error.interceptor';
|
||||
import {CSRFInterceptor} from './model/network/helper/csrf.interceptor';
|
||||
import {SettingsEntryComponent} from './ui/settings/_abstract/settings-entry/settings-entry.component';
|
||||
import {GallerySearchQueryEntryComponent} from './ui/gallery/search/query-enrty/query-entry.search.gallery.component';
|
||||
import {StringifySearchQuery} from './pipes/StringifySearchQuery';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@ -215,7 +216,8 @@ export function translationsFactory(locale: string) {
|
||||
StringifySortingMethod,
|
||||
DurationPipe,
|
||||
FileSizePipe,
|
||||
GPXFilesFilterPipe
|
||||
GPXFilesFilterPipe,
|
||||
StringifySearchQuery
|
||||
],
|
||||
providers: [
|
||||
{provide: HTTP_INTERCEPTORS, useClass: CSRFInterceptor, multi: true},
|
||||
|
13
src/frontend/app/pipes/StringifySearchQuery.ts
Normal file
13
src/frontend/app/pipes/StringifySearchQuery.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import {Pipe, PipeTransform} from '@angular/core';
|
||||
import {SearchQueryDTO} from '../../../common/entities/SearchQueryDTO';
|
||||
|
||||
|
||||
@Pipe({name: 'searchQuery'})
|
||||
export class StringifySearchQuery implements PipeTransform {
|
||||
transform(query: SearchQueryDTO): string {
|
||||
console.log(query);
|
||||
console.log(SearchQueryDTO.stringify(query));
|
||||
return SearchQueryDTO.stringify(query);
|
||||
}
|
||||
}
|
||||
|
@ -128,9 +128,7 @@ export class GalleryService {
|
||||
const cw = new ContentWrapper();
|
||||
cw.searchResult = this.galleryCacheService.getSearch(query);
|
||||
if (cw.searchResult == null) {
|
||||
const params: { [key: string]: any } = {};
|
||||
params[QueryParams.gallery.search.query] = query;
|
||||
cw.searchResult = (await this.networkService.getJson<ContentWrapper>('/search', params)).searchResult;
|
||||
cw.searchResult = (await this.networkService.getJson<ContentWrapper>('/search/' + query)).searchResult;
|
||||
this.galleryCacheService.setSearch(query, cw.searchResult);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
<div class="photo-position" *ngIf="gridMedia.hasPositionData()">
|
||||
<span class="oi oi-map-marker"></span>
|
||||
<ng-template [ngIf]="getPositionText()">
|
||||
<a [routerLink]="['/search', getPositionText(), {type:SearchTypes[SearchTypes.position]}]"
|
||||
<a [routerLink]="['/search', getPositionSearchQuery()]"
|
||||
*ngIf="searchEnabled">
|
||||
{{getPositionText()}}
|
||||
</a>
|
||||
@ -37,13 +37,13 @@
|
||||
<div class="photo-keywords" *ngIf="keywords">
|
||||
<ng-template ngFor let-keyword [ngForOf]="keywords" let-last="last">
|
||||
<a *ngIf="searchEnabled"
|
||||
[routerLink]="['/search', keyword.value, {type: SearchTypes[keyword.type]}]" [ngSwitch]="keyword.type">
|
||||
<ng-template [ngSwitchCase]="SearchTypes.keyword">#</ng-template><!--
|
||||
--><ng-template [ngSwitchCase]="SearchTypes.person"><span class="oi oi-person"></span></ng-template><!--
|
||||
[routerLink]="['/search', getTextSearchQuery(keyword.value,keyword.type)]" [ngSwitch]="keyword.type">
|
||||
<ng-template [ngSwitchCase]="SearchQueryTypes.keyword">#</ng-template><!--
|
||||
--><ng-template [ngSwitchCase]="SearchQueryTypes.person"><span class="oi oi-person"></span></ng-template><!--
|
||||
-->{{keyword.value}}</a>
|
||||
<span *ngIf="!searchEnabled" [ngSwitch]="keyword.type">
|
||||
<ng-template [ngSwitchCase]="SearchTypes.keyword">#</ng-template><!--
|
||||
--><ng-template [ngSwitchCase]="SearchTypes.person"><span class="oi oi-person"></span></ng-template><!--
|
||||
<ng-template [ngSwitchCase]="SearchQueryTypes.keyword">#</ng-template><!--
|
||||
--><ng-template [ngSwitchCase]="SearchQueryTypes.person"><span class="oi oi-person"></span></ng-template><!--
|
||||
-->{{keyword.value}}</span>
|
||||
<ng-template [ngIf]="!last">, </ng-template>
|
||||
</ng-template>
|
||||
|
@ -6,7 +6,7 @@ import {Thumbnail, ThumbnailManagerService} from '../../thumbnailManager.service
|
||||
import {Config} from '../../../../../../common/config/public/Config';
|
||||
import {PageHelper} from '../../../../model/page.helper';
|
||||
import {PhotoDTO, PhotoMetadata} from '../../../../../../common/entities/PhotoDTO';
|
||||
import {SearchQueryTypes} from '../../../../../../common/entities/SearchQueryDTO';
|
||||
import {SearchQueryDTO, SearchQueryTypes, TextSearch, TextSearchQueryMatchTypes} from '../../../../../../common/entities/SearchQueryDTO';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-grid-photo',
|
||||
@ -91,6 +91,18 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
getPositionSearchQuery(): string {
|
||||
return JSON.stringify(<TextSearch>{type: SearchQueryTypes.position, text: this.getPositionText()});
|
||||
}
|
||||
|
||||
getTextSearchQuery(name: string, type: SearchQueryTypes): string {
|
||||
return JSON.stringify(<TextSearch>{
|
||||
type: type,
|
||||
matchType: TextSearchQueryMatchTypes.exact_match,
|
||||
text: name
|
||||
});
|
||||
}
|
||||
|
||||
getPositionText(): string {
|
||||
if (!this.gridMedia || !this.gridMedia.isPhoto()) {
|
||||
return '';
|
||||
|
@ -58,7 +58,7 @@
|
||||
*ngIf="facesEnabled && activePhoto && zoom == 1 && activePhoto.gridMedia.Photo.metadata.faces && activePhoto.gridMedia.Photo.metadata.faces.length > 0">
|
||||
<a
|
||||
class="face"
|
||||
[routerLink]="['/search', face.name, {type: SearchTypes[SearchTypes.person]}]"
|
||||
[routerLink]="['/search', getPersonSearchQuery(face.name)]"
|
||||
[style.top.%]="face.box.top / activePhoto.gridMedia.Photo.metadata.size.height*100"
|
||||
[style.left.%]="face.box.left / activePhoto.gridMedia.Photo.metadata.size.width*100"
|
||||
[style.height.%]="face.box.height / activePhoto.gridMedia.Photo.metadata.size.height*100"
|
||||
|
@ -7,7 +7,7 @@ import {filter} from 'rxjs/operators';
|
||||
import {PhotoDTO} from '../../../../../../common/entities/PhotoDTO';
|
||||
import {GalleryLightboxMediaComponent} from '../media/media.lightbox.gallery.component';
|
||||
import {Config} from '../../../../../../common/config/public/Config';
|
||||
import {SearchQueryTypes} from '../../../../../../common/entities/SearchQueryDTO';
|
||||
import {SearchQueryTypes, TextSearch, TextSearchQueryMatchTypes} from '../../../../../../common/entities/SearchQueryDTO';
|
||||
|
||||
export enum PlayBackStates {
|
||||
Paused = 1,
|
||||
@ -47,12 +47,12 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
||||
public controllersVisible = true;
|
||||
public drag = {x: 0, y: 0};
|
||||
public SearchQueryTypes = SearchQueryTypes;
|
||||
public faceContainerDim = {width: 0, height: 0};
|
||||
private visibilityTimer: number = null;
|
||||
private timer: Observable<number>;
|
||||
private timerSub: Subscription;
|
||||
private prevDrag = {x: 0, y: 0};
|
||||
private prevZoom = 1;
|
||||
public faceContainerDim = {width: 0, height: 0};
|
||||
|
||||
constructor(public fullScreenService: FullScreenService) {
|
||||
}
|
||||
@ -296,6 +296,14 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
||||
this.closed.emit();
|
||||
}
|
||||
|
||||
getPersonSearchQuery(name: string): string {
|
||||
return JSON.stringify(<TextSearch>{
|
||||
type: SearchQueryTypes.person,
|
||||
matchType: TextSearchQueryMatchTypes.exact_match,
|
||||
text: name
|
||||
});
|
||||
}
|
||||
|
||||
private checkZoomAndDrag() {
|
||||
const fixDrag = (drag: { x: number, y: number }) => {
|
||||
if (this.zoom === 1) {
|
||||
@ -378,6 +386,5 @@ export class ControlsLightboxComponent implements OnDestroy, OnInit, OnChanges {
|
||||
this.faceContainerDim.width = this.photoFrameDim.width;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -92,14 +92,14 @@
|
||||
<div class="col-10 keywords">
|
||||
<ng-template ngFor let-keyword [ngForOf]="keywords" let-last="last">
|
||||
<a *ngIf="searchEnabled"
|
||||
[routerLink]="['/search', keyword.value, {type: SearchTypes[keyword.type]}]" [ngSwitch]="keyword.type">
|
||||
<ng-template [ngSwitchCase]="SearchTypes.keyword">#</ng-template><!--
|
||||
[routerLink]="['/search', getTextSearchQuery(keyword.value,keyword.type)]" [ngSwitch]="keyword.type">
|
||||
<ng-template [ngSwitchCase]="SearchQueryTypes.keyword">#</ng-template><!--
|
||||
-->
|
||||
<ng-template [ngSwitchCase]="SearchTypes.person"><span class="oi oi-person"></span></ng-template><!--
|
||||
<ng-template [ngSwitchCase]="SearchQueryTypes.person"><span class="oi oi-person"></span></ng-template><!--
|
||||
-->{{keyword.value}}</a>
|
||||
<span *ngIf="!searchEnabled" [ngSwitch]="keyword.type">
|
||||
<ng-template [ngSwitchCase]="SearchTypes.keyword">#</ng-template><!--
|
||||
--><ng-template [ngSwitchCase]="SearchTypes.person"><span class="oi oi-person"></span></ng-template><!--
|
||||
<ng-template [ngSwitchCase]="SearchQueryTypes.keyword">#</ng-template><!--
|
||||
--><ng-template [ngSwitchCase]="SearchQueryTypes.person"><span class="oi oi-person"></span></ng-template><!--
|
||||
-->{{keyword.value}}</span>
|
||||
<ng-template [ngIf]="!last">, </ng-template>
|
||||
</ng-template>
|
||||
|
@ -6,7 +6,7 @@ import {VideoDTO, VideoMetadata} from '../../../../../../common/entities/VideoDT
|
||||
import {Utils} from '../../../../../../common/Utils';
|
||||
import {QueryService} from '../../../../model/query.service';
|
||||
import {MapService} from '../../map/map.service';
|
||||
import {SearchQueryTypes} from '../../../../../../common/entities/SearchQueryDTO';
|
||||
import {SearchQueryTypes, TextSearch, TextSearchQueryMatchTypes} from '../../../../../../common/entities/SearchQueryDTO';
|
||||
|
||||
@Component({
|
||||
selector: 'app-info-panel',
|
||||
@ -121,5 +121,14 @@ export class InfoPanelLightboxComponent implements OnInit {
|
||||
close() {
|
||||
this.closed.emit();
|
||||
}
|
||||
|
||||
getTextSearchQuery(name: string, type: SearchQueryTypes): string {
|
||||
return JSON.stringify(<TextSearch>{
|
||||
type: type,
|
||||
matchType: TextSearchQueryMatchTypes.exact_match,
|
||||
text: name
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -10,15 +10,7 @@
|
||||
<ol *ngIf="searchResult" class="breadcrumb">
|
||||
<li class="active">
|
||||
<ng-container i18n>Searching for:</ng-container>
|
||||
<span class="search-type" [ngSwitch]="searchResult.searchType">
|
||||
<span *ngSwitchCase="SearchTypes.photo" class="oi oi-image"></span>
|
||||
<span *ngSwitchCase="SearchTypes.video" class="oi oi-video"></span>
|
||||
<span *ngSwitchCase="SearchTypes.directory" class="oi oi-folder"></span>
|
||||
<span *ngSwitchCase="SearchTypes.keyword" class="oi oi-tag"></span>
|
||||
<span *ngSwitchCase="SearchTypes.person" class="oi oi-person"></span>
|
||||
<span *ngSwitchCase="SearchTypes.position" class="oi oi-map-marker"></span>
|
||||
</span>
|
||||
<strong> {{searchResult.searchText}}</strong>
|
||||
<strong> {{searchResult.searchQuery | searchQuery}}</strong>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
|
@ -44,6 +44,7 @@ export class GalleryNavigatorComponent implements OnChanges {
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
console.log(this.searchResult);
|
||||
this.getPath();
|
||||
this.DefaultSorting = this.galleryService.getDefaultSorting(this.directory);
|
||||
}
|
||||
|
@ -3,10 +3,11 @@
|
||||
<ng-container i18n>Random link</ng-container>
|
||||
</button>
|
||||
|
||||
|
||||
<ng-template #randomModal>
|
||||
<!-- sharing Modal-->
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" i18n>Random Link generator</h5>
|
||||
<h5 class="modal-title" i18n>Random Link creator</h5>
|
||||
<button type="button" class="close" (click)="hideModal()" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
@ -30,105 +31,27 @@
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<label class="control-label" i18n>In Folder:</label>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<input disabled type="text"
|
||||
class="full-width form-control"
|
||||
[ngModel]="data.directory">
|
||||
</div>
|
||||
</div>
|
||||
<form #searchPanelForm="ngForm" class="form-horizontal">
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
i18n-placeholder
|
||||
placeholder="Search"
|
||||
[(ngModel)]="rawSearchText"
|
||||
(ngModelChange)="validateRawSearchText()"
|
||||
size="30"
|
||||
name="srch-term-preview"
|
||||
id="srch-term-preview"
|
||||
autocomplete="off">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<label class="control-label" i18n>Include subfolders:</label>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<bSwitch
|
||||
class="switch"
|
||||
name="includeSubfolders"
|
||||
[switch-on-color]="'success'"
|
||||
[switch-inverse]="'inverse'"
|
||||
[switch-off-text]="text.No"
|
||||
[switch-on-text]="text.Yes"
|
||||
[switch-handle-width]="'100'"
|
||||
[switch-label-width]="'20'"
|
||||
(change)="update()"
|
||||
[(ngModel)]="data.recursive">
|
||||
</bSwitch>
|
||||
</div>
|
||||
</div>
|
||||
<app-gallery-search-query-entry
|
||||
[(ngModel)]="searchQueryDTO"
|
||||
(change)="onQueryChange()"
|
||||
name="search-root"
|
||||
(delete)="resetQuery()">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<label class="control-label" i18n>Orientation:</label>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<select class="form-control" [(ngModel)]="data.orientation" (change)="update()" name="orientation"
|
||||
required>
|
||||
<option [ngValue]="OrientationType.any" i18n>Any</option>
|
||||
<option [ngValue]="OrientationType.landscape" i18n>Landscape</option>
|
||||
<option [ngValue]="OrientationType.portrait" i18n>Portrait</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-4">
|
||||
<label class="control-label" i18n>Date:</label>
|
||||
</div>
|
||||
<div class="col-4 form-group">
|
||||
<input type="text"
|
||||
placeholder="from: YYYY-MM-DD"
|
||||
class="form-control"
|
||||
bsDatepicker
|
||||
(bsValueChange)="update()"
|
||||
[(ngModel)]="data.fromDate"
|
||||
[bsConfig]="{ dateInputFormat: 'YYYY-MM-DD' }">
|
||||
</div>
|
||||
<div class="col-4 form-group">
|
||||
<input type="text"
|
||||
placeholder="to: YYYY-MM-DD"
|
||||
class="form-control"
|
||||
bsDatepicker
|
||||
(bsValueChange)="update()"
|
||||
[(ngModel)]="data.toDate"
|
||||
[bsConfig]="{ dateInputFormat: 'YYYY-MM-DD' }">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<label class="control-label" i18n>Resolution:</label>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control"
|
||||
(change)="update()"
|
||||
[(ngModel)]="data.minResolution"
|
||||
id="minResolution" placeholder="min" step="1" min="0">
|
||||
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">Mpx</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control"
|
||||
(change)="update()"
|
||||
[(ngModel)]="data.maxResolution"
|
||||
id="maxResolution" placeholder="max" step="1" min="0">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text">Mpx</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</app-gallery-search-query-entry>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
@ -1,16 +1,16 @@
|
||||
import {Component, OnDestroy, OnInit, TemplateRef} from '@angular/core';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {GalleryService} from '../gallery.service';
|
||||
import {ContentWrapper} from '../../../../../common/entities/ConentWrapper';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {DirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {BsModalService} from 'ngx-bootstrap/modal';
|
||||
import {BsModalRef} from 'ngx-bootstrap/modal/bs-modal-ref.service';
|
||||
import {OrientationType, RandomQueryDTO} from '../../../../../common/entities/RandomQueryDTO';
|
||||
import {NetworkService} from '../../../model/network/network.service';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {SearchQueryDTO, SearchQueryTypes, TextSearch} from '../../../../../common/entities/SearchQueryDTO';
|
||||
import {ActivatedRoute, Params} from '@angular/router';
|
||||
import {QueryParams} from '../../../../../common/QueryParams';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -20,37 +20,55 @@ import {Subscription} from 'rxjs';
|
||||
})
|
||||
export class RandomQueryBuilderGalleryComponent implements OnInit, OnDestroy {
|
||||
|
||||
public searchQueryDTO: SearchQueryDTO;
|
||||
public rawSearchText: string;
|
||||
enabled = true;
|
||||
url = '';
|
||||
|
||||
data: RandomQueryDTO = {
|
||||
orientation: OrientationType.any,
|
||||
directory: '',
|
||||
recursive: true,
|
||||
minResolution: null,
|
||||
maxResolution: null,
|
||||
toDate: null,
|
||||
fromDate: null
|
||||
};
|
||||
contentSubscription: Subscription = null;
|
||||
|
||||
readonly OrientationType: typeof OrientationType;
|
||||
modalRef: BsModalRef;
|
||||
|
||||
text = {
|
||||
Yes: 'Yes',
|
||||
No: 'No'
|
||||
};
|
||||
|
||||
private readonly subscription: Subscription = null;
|
||||
|
||||
constructor(public _galleryService: GalleryService,
|
||||
private _notification: NotificationService,
|
||||
public i18n: I18n,
|
||||
private _route: ActivatedRoute,
|
||||
private modalService: BsModalService) {
|
||||
this.OrientationType = OrientationType;
|
||||
this.text.Yes = i18n('Yes');
|
||||
this.text.No = i18n('No');
|
||||
this.resetQuery();
|
||||
|
||||
this.subscription = this._route.params.subscribe((params: Params) => {
|
||||
if (!params[QueryParams.gallery.search.query]) {
|
||||
return;
|
||||
}
|
||||
const searchQuery = JSON.parse(params[QueryParams.gallery.search.query]);
|
||||
if (searchQuery) {
|
||||
this.searchQueryDTO = searchQuery;
|
||||
this.onQueryChange();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get HTMLSearchQuery() {
|
||||
return JSON.stringify(this.searchQueryDTO);
|
||||
}
|
||||
|
||||
validateRawSearchText() {
|
||||
try {
|
||||
this.searchQueryDTO = SearchQueryDTO.parse(this.rawSearchText);
|
||||
this.url = NetworkService.buildUrl(Config.Client.publicUrl + '/api/gallery/random/' + this.HTMLSearchQuery);
|
||||
console.log(this.searchQueryDTO);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
onQueryChange() {
|
||||
this.rawSearchText = SearchQueryDTO.stringify(this.searchQueryDTO);
|
||||
this.url = NetworkService.buildUrl(Config.Client.publicUrl + '/api/gallery/random/' + this.HTMLSearchQuery);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.contentSubscription = this._galleryService.content.subscribe((content: ContentWrapper) => {
|
||||
@ -58,7 +76,7 @@ export class RandomQueryBuilderGalleryComponent implements OnInit, OnDestroy {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
this.data.directory = Utils.concatUrls((<DirectoryDTO>content.directory).path, (<DirectoryDTO>content.directory).name);
|
||||
// this.data.directory = Utils.concatUrls((<DirectoryDTO>content.directory).path, (<DirectoryDTO>content.directory).name);
|
||||
});
|
||||
}
|
||||
|
||||
@ -66,19 +84,12 @@ export class RandomQueryBuilderGalleryComponent implements OnInit, OnDestroy {
|
||||
if (this.contentSubscription !== null) {
|
||||
this.contentSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
if (this.subscription !== null) {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
update() {
|
||||
setTimeout(() => {
|
||||
const data = Utils.clone(this.data);
|
||||
for (const key of Object.keys(data)) {
|
||||
if (!(<any>data)[key]) {
|
||||
delete (<any>data)[key];
|
||||
}
|
||||
}
|
||||
this.url = NetworkService.buildUrl(Config.Client.publicUrl + '/api/gallery/random/', data);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
openModal(template: TemplateRef<any>) {
|
||||
if (!this.enabled) {
|
||||
@ -87,9 +98,10 @@ export class RandomQueryBuilderGalleryComponent implements OnInit, OnDestroy {
|
||||
if (this.modalRef) {
|
||||
this.modalRef.hide();
|
||||
}
|
||||
this.modalRef = this.modalService.show(template);
|
||||
|
||||
this.modalRef = this.modalService.show(template, {class: 'modal-lg'});
|
||||
document.body.style.paddingRight = '0px';
|
||||
this.update();
|
||||
this.onQueryChange();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -102,4 +114,10 @@ export class RandomQueryBuilderGalleryComponent implements OnInit, OnDestroy {
|
||||
this.modalRef = null;
|
||||
}
|
||||
|
||||
|
||||
resetQuery() {
|
||||
this.searchQueryDTO = <TextSearch>{text: '', type: SearchQueryTypes.any_text};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
(focus)="onFocus()"
|
||||
[(ngModel)]="rawSearchText"
|
||||
(ngModelChange)="validateRawSearchText()"
|
||||
(keydown.enter)="Search()"
|
||||
#name="ngModel"
|
||||
size="30"
|
||||
ngControl="search"
|
||||
@ -78,6 +79,14 @@
|
||||
(delete)="resetQuery()">
|
||||
|
||||
</app-gallery-search-query-entry>
|
||||
|
||||
<div class="input-group-btn float-right" style="display: block">
|
||||
<button class="btn btn-primary" type="button"
|
||||
[routerLink]="['/search', HTMLSearchQuery]"
|
||||
(click)="hideModal()">
|
||||
<span class="oi oi-magnifying-glass"></span> Search
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {Component, OnDestroy, TemplateRef} from '@angular/core';
|
||||
import {AutoCompleteService} from './autocomplete.service';
|
||||
import {AutoCompleteItem} from '../../../../../common/entities/AutoCompleteItem';
|
||||
import {ActivatedRoute, Params, RouterLink} from '@angular/router';
|
||||
import {ActivatedRoute, Params, Router, RouterLink} from '@angular/router';
|
||||
import {GalleryService} from '../gallery.service';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
@ -36,24 +36,27 @@ export class GallerySearchComponent implements OnDestroy {
|
||||
private _galleryService: GalleryService,
|
||||
private navigationService: NavigationService,
|
||||
private _route: ActivatedRoute,
|
||||
public router: Router,
|
||||
private modalService: BsModalService) {
|
||||
|
||||
this.SearchQueryTypes = SearchQueryTypes;
|
||||
this.MetadataSearchQueryTypes = MetadataSearchQueryTypes.map(v => ({key: v, value: SearchQueryTypes[v]}));
|
||||
|
||||
this.subscription = this._route.params.subscribe((params: Params) => {
|
||||
const searchQuery = params[QueryParams.gallery.search.query];
|
||||
if (!params[QueryParams.gallery.search.query]) {
|
||||
return;
|
||||
}
|
||||
const searchQuery = JSON.parse(params[QueryParams.gallery.search.query]);
|
||||
if (searchQuery) {
|
||||
this.searchQueryDTO = searchQuery;
|
||||
this.onQueryChange();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
get HTMLSearchQuery() {
|
||||
const searchQuery: any = {};
|
||||
searchQuery[QueryParams.gallery.search.query] = this.searchQueryDTO;
|
||||
return searchQuery;
|
||||
return JSON.stringify(this.searchQueryDTO);
|
||||
}
|
||||
|
||||
|
||||
@ -118,6 +121,10 @@ export class GallerySearchComponent implements OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
Search() {
|
||||
this.router.navigate(['/search', this.HTMLSearchQuery]).catch(console.error);
|
||||
}
|
||||
|
||||
private emptyAutoComplete() {
|
||||
this.autoCompleteItems = [];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user