Search: Improve handling of search query updates in UI components #1995
This commit is contained in:
parent
ac9fc4108b
commit
adb40433a5
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<v-form ref="form" lazy-validation
|
<v-form ref="form" lazy-validation
|
||||||
dense autocomplete="off" class="p-photo-toolbar p-album-toolbar" accept-charset="UTF-8"
|
dense autocomplete="off" class="p-photo-toolbar p-album-toolbar" accept-charset="UTF-8"
|
||||||
@submit.prevent="updateQuery">
|
@submit.prevent="updateQuery()">
|
||||||
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
||||||
<v-toolbar-title :title="album.Title">
|
<v-toolbar-title :title="album.Title">
|
||||||
{{ album.Title }}
|
{{ album.Title }}
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
|
|
||||||
<v-btn icon class="hidden-xs-only action-reload" :title="$gettext('Reload')" @click.stop="refresh">
|
<v-btn icon class="hidden-xs-only action-reload" :title="$gettext('Reload')" @click.stop="refresh()">
|
||||||
<v-icon>refresh</v-icon>
|
<v-icon>refresh</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<v-btn v-if="$config.feature('download')" icon class="hidden-xs-only action-download" :title="$gettext('Download')"
|
<v-btn v-if="$config.feature('download')" icon class="hidden-xs-only action-download" :title="$gettext('Download')"
|
||||||
@click.stop="download">
|
@click.stop="download()">
|
||||||
<v-icon>get_app</v-icon>
|
<v-icon>get_app</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
|
@ -83,12 +83,22 @@ export default {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
|
updateFilter: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
updateQuery: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
settings: {
|
settings: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
refresh: Function,
|
refresh: {
|
||||||
filterChange: Function,
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const cameras = [{
|
const cameras = [{
|
||||||
|
@ -149,24 +159,10 @@ export default {
|
||||||
this.album.update();
|
this.album.update();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dropdownChange() {
|
|
||||||
this.updateQuery();
|
|
||||||
|
|
||||||
if (window.innerWidth < 600) {
|
|
||||||
this.searchExpanded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.filter.order !== this.album.Order) {
|
|
||||||
this.album.Order = this.filter.order;
|
|
||||||
this.updateAlbum();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setView(name) {
|
setView(name) {
|
||||||
this.settings.view = name;
|
if (name) {
|
||||||
this.updateQuery();
|
this.refresh({'view': name});
|
||||||
},
|
}
|
||||||
updateQuery() {
|
|
||||||
this.filterChange();
|
|
||||||
},
|
},
|
||||||
download() {
|
download() {
|
||||||
this.onDownload(`${this.$config.apiUri}/albums/${this.album.UID}/dl?t=${this.$config.downloadToken()}`);
|
this.onDownload(`${this.$config.apiUri}/albums/${this.album.UID}/dl?t=${this.$config.downloadToken()}`);
|
||||||
|
|
|
@ -207,21 +207,15 @@ export default {
|
||||||
},
|
},
|
||||||
openPhoto: {
|
openPhoto: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('cards view: openPhoto is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
editPhoto: {
|
editPhoto: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('cards view: editPhoto is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
openLocation: {
|
openLocation: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('cards view: openLocation is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
album: {
|
album: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
|
@ -167,12 +167,18 @@ export default {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
refresh: Function,
|
refresh: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
album: {
|
album: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
context: String,
|
context: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -122,21 +122,15 @@ export default {
|
||||||
},
|
},
|
||||||
openPhoto: {
|
openPhoto: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('list view: openPhoto is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
editPhoto: {
|
editPhoto: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('list view: editPhoto is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
openLocation: {
|
openLocation: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default:() => {},
|
||||||
console.warn('list view: openLocation is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
album: {
|
album: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
|
@ -128,15 +128,11 @@ export default {
|
||||||
},
|
},
|
||||||
openPhoto: {
|
openPhoto: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default:() => {},
|
||||||
console.warn('mosaic view: openPhoto is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
editPhoto: {
|
editPhoto: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('mosaic view: editPhoto is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
album: {
|
album: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
|
@ -1,23 +1,24 @@
|
||||||
<template>
|
<template>
|
||||||
<v-form ref="form" lazy-validation
|
<v-form ref="form" lazy-validation
|
||||||
dense autocomplete="off" class="p-photo-toolbar" accept-charset="UTF-8"
|
dense autocomplete="off" class="p-photo-toolbar" accept-charset="UTF-8"
|
||||||
@submit.prevent="updateQuery">
|
@submit.prevent="updateQuery()">
|
||||||
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
||||||
<v-text-field :value="filter.q"
|
<v-text-field :value="filter.q"
|
||||||
class="input-search background-inherit elevation-0"
|
class="input-search background-inherit elevation-0"
|
||||||
solo hide-details clearable overflow single-line validate-on-blur
|
solo hide-details clearable overflow single-line
|
||||||
|
validate-on-blur
|
||||||
autocorrect="off"
|
autocorrect="off"
|
||||||
autocapitalize="none"
|
autocapitalize="none"
|
||||||
browser-autocomplete="off"
|
browser-autocomplete="off"
|
||||||
:label="$gettext('Search')"
|
:label="$gettext('Search')"
|
||||||
prepend-inner-icon="search"
|
prepend-inner-icon="search"
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
@input="onChangeQuery"
|
@change="(v) => {updateFilter({'q': v})}"
|
||||||
@keyup.enter.native="updateQuery"
|
@keyup.enter.native="refresh()"
|
||||||
@click:clear="clearQuery"
|
@click:clear="() => {updateQuery({'q': ''})}"
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
|
|
||||||
<v-btn icon class="hidden-xs-only action-reload" :title="$gettext('Reload')" @click.stop="refresh">
|
<v-btn icon class="hidden-xs-only action-reload" :title="$gettext('Reload')" @click.stop="refresh()">
|
||||||
<v-icon>refresh</v-icon>
|
<v-icon>refresh</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-layout row wrap>
|
<v-layout row wrap>
|
||||||
<v-flex xs12 sm6 md3 pa-2 class="p-countries-select">
|
<v-flex xs12 sm6 md3 pa-2 class="p-countries-select">
|
||||||
<v-select v-model="filter.country"
|
<v-select :value="filter.country"
|
||||||
:label="$gettext('Country')"
|
:label="$gettext('Country')"
|
||||||
flat solo hide-details
|
flat solo hide-details
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
|
@ -57,60 +58,60 @@
|
||||||
item-text="Name"
|
item-text="Name"
|
||||||
:items="countryOptions"
|
:items="countryOptions"
|
||||||
class="input-countries"
|
class="input-countries"
|
||||||
@change="dropdownChange"
|
@change="(v) => {updateQuery({'country': v})}"
|
||||||
>
|
>
|
||||||
</v-select>
|
</v-select>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 sm6 md3 pa-2 class="p-camera-select">
|
<v-flex xs12 sm6 md3 pa-2 class="p-camera-select">
|
||||||
<v-select v-model="filter.camera"
|
<v-select :value="filter.camera"
|
||||||
:label="$gettext('Camera')"
|
:label="$gettext('Camera')"
|
||||||
flat solo hide-details
|
flat solo hide-details
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
item-value="ID"
|
item-value="ID"
|
||||||
item-text="Name"
|
item-text="Name"
|
||||||
:items="cameraOptions"
|
:items="cameraOptions"
|
||||||
@change="dropdownChange">
|
@change="(v) => {updateQuery({'camera': v})}">
|
||||||
</v-select>
|
</v-select>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 sm6 md3 pa-2 class="p-view-select">
|
<v-flex xs12 sm6 md3 pa-2 class="p-view-select">
|
||||||
<v-select id="viewSelect"
|
<v-select id="viewSelect"
|
||||||
v-model="settings.view"
|
:value="settings.view"
|
||||||
:label="$gettext('View')" flat solo
|
:label="$gettext('View')" flat solo
|
||||||
hide-details
|
hide-details
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
:items="options.views"
|
:items="options.views"
|
||||||
@change="dropdownChange">
|
@change="(v) => {setView(v)}">
|
||||||
</v-select>
|
</v-select>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 sm6 md3 pa-2 class="p-time-select">
|
<v-flex xs12 sm6 md3 pa-2 class="p-time-select">
|
||||||
<v-select v-model="filter.order"
|
<v-select :value="filter.order"
|
||||||
:label="$gettext('Sort Order')"
|
:label="$gettext('Sort Order')"
|
||||||
flat solo hide-details
|
flat solo hide-details
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
:items="options.sorting"
|
:items="options.sorting"
|
||||||
@change="dropdownChange">
|
@change="(v) => {updateQuery({'order': v})}">
|
||||||
</v-select>
|
</v-select>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 sm6 md3 pa-2 class="p-year-select">
|
<v-flex xs12 sm6 md3 pa-2 class="p-year-select">
|
||||||
<v-select v-model="filter.year"
|
<v-select :value="filter.year"
|
||||||
:label="$gettext('Year')"
|
:label="$gettext('Year')"
|
||||||
flat solo hide-details
|
flat solo hide-details
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
item-value="value"
|
item-value="value"
|
||||||
item-text="text"
|
item-text="text"
|
||||||
:items="yearOptions()"
|
:items="yearOptions()"
|
||||||
@change="dropdownChange">
|
@change="(v) => {updateQuery({'year': v})}">
|
||||||
</v-select>
|
</v-select>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 sm6 md3 pa-2 class="p-month-select">
|
<v-flex xs12 sm6 md3 pa-2 class="p-month-select">
|
||||||
<v-select v-model="filter.month"
|
<v-select :value="filter.month"
|
||||||
:label="$gettext('Month')"
|
:label="$gettext('Month')"
|
||||||
flat solo hide-details
|
flat solo hide-details
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
item-value="value"
|
item-value="value"
|
||||||
item-text="text"
|
item-text="text"
|
||||||
:items="monthOptions()"
|
:items="monthOptions()"
|
||||||
@change="dropdownChange">
|
@change="(v) => {updateQuery({'month': v})}">
|
||||||
</v-select>
|
</v-select>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<!-- v-flex xs12 sm6 md3 pa-2 class="p-lens-select">
|
<!-- v-flex xs12 sm6 md3 pa-2 class="p-lens-select">
|
||||||
|
@ -125,25 +126,25 @@
|
||||||
</v-select>
|
</v-select>
|
||||||
</v-flex -->
|
</v-flex -->
|
||||||
<v-flex xs12 sm6 md3 pa-2 class="p-color-select">
|
<v-flex xs12 sm6 md3 pa-2 class="p-color-select">
|
||||||
<v-select v-model="filter.color"
|
<v-select :value="filter.color"
|
||||||
:label="$gettext('Color')"
|
:label="$gettext('Color')"
|
||||||
flat solo hide-details
|
flat solo hide-details
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
item-value="Slug"
|
item-value="Slug"
|
||||||
item-text="Name"
|
item-text="Name"
|
||||||
:items="colorOptions()"
|
:items="colorOptions()"
|
||||||
@change="dropdownChange">
|
@change="(v) => {updateQuery({'color': v})}">
|
||||||
</v-select>
|
</v-select>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 sm6 md3 pa-2 class="p-category-select">
|
<v-flex xs12 sm6 md3 pa-2 class="p-category-select">
|
||||||
<v-select v-model="filter.label"
|
<v-select :value="filter.label"
|
||||||
:label="$gettext('Category')"
|
:label="$gettext('Category')"
|
||||||
flat solo hide-details
|
flat solo hide-details
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
item-value="Slug"
|
item-value="Slug"
|
||||||
item-text="Name"
|
item-text="Name"
|
||||||
:items="categoryOptions"
|
:items="categoryOptions"
|
||||||
@change="dropdownChange">
|
@change="(v) => {updateQuery({'label': v})}">
|
||||||
</v-select>
|
</v-select>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
|
@ -158,17 +159,26 @@ import * as options from "options/options";
|
||||||
export default {
|
export default {
|
||||||
name: 'PPhotoToolbar',
|
name: 'PPhotoToolbar',
|
||||||
props: {
|
props: {
|
||||||
dirty: Boolean,
|
|
||||||
filter: {
|
filter: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
|
updateFilter: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
updateQuery: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
settings: {
|
settings: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
refresh: Function,
|
refresh: {
|
||||||
filterChange: Function,
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -176,7 +186,6 @@ export default {
|
||||||
isFullScreen: !!document.fullscreenElement,
|
isFullScreen: !!document.fullscreenElement,
|
||||||
config: this.$config.values,
|
config: this.$config.values,
|
||||||
searchExpanded: false,
|
searchExpanded: false,
|
||||||
q: this.filter.q ? this.filter.q : '',
|
|
||||||
all: {
|
all: {
|
||||||
countries: [{ID: "", Name: this.$gettext("All Countries")}],
|
countries: [{ID: "", Name: this.$gettext("All Countries")}],
|
||||||
cameras: [{ID: 0, Name: this.$gettext("All Cameras")}],
|
cameras: [{ID: 0, Name: this.$gettext("All Cameras")}],
|
||||||
|
@ -228,27 +237,10 @@ export default {
|
||||||
yearOptions() {
|
yearOptions() {
|
||||||
return this.all.years.concat(options.IndexedYears());
|
return this.all.years.concat(options.IndexedYears());
|
||||||
},
|
},
|
||||||
dropdownChange() {
|
|
||||||
this.updateQuery();
|
|
||||||
|
|
||||||
if (window.innerWidth < 600) {
|
|
||||||
this.searchExpanded = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setView(name) {
|
setView(name) {
|
||||||
this.settings.view = name;
|
if (name) {
|
||||||
this.updateQuery();
|
this.refresh({'view': name});
|
||||||
},
|
}
|
||||||
onChangeQuery(val) {
|
|
||||||
this.q = val ? String(val) : '';
|
|
||||||
},
|
|
||||||
clearQuery() {
|
|
||||||
this.q = '';
|
|
||||||
this.updateQuery();
|
|
||||||
},
|
|
||||||
updateQuery() {
|
|
||||||
this.filter.q = this.q.trim();
|
|
||||||
this.filterChange();
|
|
||||||
},
|
},
|
||||||
showUpload() {
|
showUpload() {
|
||||||
Event.publish("dialog.upload");
|
Event.publish("dialog.upload");
|
||||||
|
|
|
@ -54,15 +54,11 @@ export default {
|
||||||
},
|
},
|
||||||
success: {
|
success: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default() {
|
default: () => {},
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
error: {
|
error: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default() {
|
default: () => {},
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
<div v-infinite-scroll="loadMore" class="p-page p-page-album-photos" :infinite-scroll-disabled="scrollDisabled"
|
<div v-infinite-scroll="loadMore" class="p-page p-page-album-photos" :infinite-scroll-disabled="scrollDisabled"
|
||||||
:infinite-scroll-distance="scrollDistance" :infinite-scroll-listen-for-event="'scrollRefresh'">
|
:infinite-scroll-distance="scrollDistance" :infinite-scroll-listen-for-event="'scrollRefresh'">
|
||||||
|
|
||||||
<p-album-toolbar :album="model" :settings="settings" :filter="filter" :filter-change="updateQuery"
|
<p-album-toolbar :filter="filter" :album="model" :settings="settings" :refresh="refresh"
|
||||||
:refresh="refresh"></p-album-toolbar>
|
:update-filter="updateFilter" :update-query="updateQuery"></p-album-toolbar>
|
||||||
|
|
||||||
<v-container v-if="loading" fluid class="pa-4">
|
<v-container v-if="loading" fluid class="pa-4">
|
||||||
<v-progress-linear color="secondary-dark" :indeterminate="true"></v-progress-linear>
|
<v-progress-linear color="secondary-dark" :indeterminate="true"></v-progress-linear>
|
||||||
|
@ -55,7 +55,10 @@ import Viewer from "common/viewer";
|
||||||
export default {
|
export default {
|
||||||
name: 'PPageAlbumPhotos',
|
name: 'PPageAlbumPhotos',
|
||||||
props: {
|
props: {
|
||||||
staticFilter: Object
|
staticFilter: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const uid = this.$route.params.uid;
|
const uid = this.$route.params.uid;
|
||||||
|
@ -261,8 +264,51 @@ export default {
|
||||||
this.listen = true;
|
this.listen = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
updateQuery() {
|
updateSettings(props) {
|
||||||
this.filter.q = this.filter.q.trim();
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.settings.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.settings[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.settings[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateFilter(props) {
|
||||||
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.filter.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.filter[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.filter[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateQuery(props) {
|
||||||
|
this.updateFilter(props);
|
||||||
|
|
||||||
|
if (this.model.Order !== this.filter.order) {
|
||||||
|
this.model.Order = this.filter.order;
|
||||||
|
this.updateAlbum();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.loading) return;
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
view: this.settings.view
|
view: this.settings.view
|
||||||
|
@ -299,10 +345,10 @@ export default {
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
},
|
},
|
||||||
refresh() {
|
refresh(props) {
|
||||||
if (this.loading) {
|
this.updateSettings(props);
|
||||||
return;
|
|
||||||
}
|
if (this.loading) return;
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.page = 0;
|
this.page = 0;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="scrollDistance"
|
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="scrollDistance"
|
||||||
:infinite-scroll-listen-for-event="'scrollRefresh'">
|
:infinite-scroll-listen-for-event="'scrollRefresh'">
|
||||||
|
|
||||||
<v-form ref="form" class="p-albums-search" lazy-validation dense @submit.prevent="updateQuery">
|
<v-form ref="form" class="p-albums-search" lazy-validation dense @submit.prevent="updateQuery()">
|
||||||
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
||||||
<v-text-field :value="filter.q"
|
<v-text-field :value="filter.q"
|
||||||
solo hide-details clearable overflow single-line validate-on-blur
|
solo hide-details clearable overflow single-line validate-on-blur
|
||||||
|
@ -14,12 +14,12 @@
|
||||||
autocapitalize="none"
|
autocapitalize="none"
|
||||||
prepend-inner-icon="search"
|
prepend-inner-icon="search"
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
@input="onChangeQuery"
|
@change="(v) => {updateFilter({'q': v})}"
|
||||||
@keyup.enter.native="updateQuery"
|
@keyup.enter.native="refresh()"
|
||||||
@click:clear="clearQuery"
|
@click:clear="() => {updateQuery({'q': ''})}"
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
|
|
||||||
<v-overflow-btn v-model="filter.category"
|
<v-overflow-btn :value="filter.category"
|
||||||
solo hide-details single-line
|
solo hide-details single-line
|
||||||
:label="$gettext('Category')"
|
:label="$gettext('Category')"
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
|
@ -28,11 +28,11 @@
|
||||||
append-icon=""
|
append-icon=""
|
||||||
:items="categories"
|
:items="categories"
|
||||||
class="hidden-xs-only input-category background-inherit elevation-0"
|
class="hidden-xs-only input-category background-inherit elevation-0"
|
||||||
@change="updateQuery"
|
@change="(v) => {updateFilter({'category': v})}"
|
||||||
>
|
>
|
||||||
</v-overflow-btn>
|
</v-overflow-btn>
|
||||||
|
|
||||||
<v-btn icon class="action-reload" :title="$gettext('Reload')" @click.stop="refresh">
|
<v-btn icon class="action-reload" :title="$gettext('Reload')" @click.stop="refresh()">
|
||||||
<v-icon>refresh</v-icon>
|
<v-icon>refresh</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<v-btn v-if="staticFilter.type === 'album'" icon class="action-add" :title="$gettext('Add Album')"
|
<v-btn v-if="staticFilter.type === 'album'" icon class="action-add" :title="$gettext('Add Album')"
|
||||||
@click.prevent="create">
|
@click.prevent="create()">
|
||||||
<v-icon>add</v-icon>
|
<v-icon>add</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
|
@ -218,8 +218,14 @@ import {Input, InputInvalid, ClickShort, ClickLong} from "common/input";
|
||||||
export default {
|
export default {
|
||||||
name: 'PPageAlbums',
|
name: 'PPageAlbums',
|
||||||
props: {
|
props: {
|
||||||
staticFilter: Object,
|
staticFilter: {
|
||||||
view: String,
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
view: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const query = this.$route.query;
|
const query = this.$route.query;
|
||||||
|
@ -483,15 +489,44 @@ export default {
|
||||||
this.listen = true;
|
this.listen = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChangeQuery(val) {
|
updateSettings(props) {
|
||||||
this.q = val ? String(val) : '';
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.settings.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.settings[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.settings[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
clearQuery() {
|
updateFilter(props) {
|
||||||
this.q = '';
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
this.updateQuery();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.filter.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.filter[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.filter[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
updateQuery() {
|
updateQuery(props) {
|
||||||
this.filter.q = this.q.trim();
|
this.updateFilter(props);
|
||||||
|
|
||||||
if (this.loading) return;
|
if (this.loading) return;
|
||||||
|
|
||||||
|
@ -574,8 +609,11 @@ export default {
|
||||||
this.listen = true;
|
this.listen = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
refresh() {
|
refresh(props) {
|
||||||
|
this.updateSettings(props);
|
||||||
|
|
||||||
if (this.loading) return;
|
if (this.loading) return;
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.page = 0;
|
this.page = 0;
|
||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="scrollDistance"
|
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="scrollDistance"
|
||||||
:infinite-scroll-listen-for-event="'scrollRefresh'">
|
:infinite-scroll-listen-for-event="'scrollRefresh'">
|
||||||
|
|
||||||
<v-form ref="form" class="p-labels-search" lazy-validation dense @submit.stop.prevent>
|
<v-form ref="form" class="p-labels-search" lazy-validation dense @submit.stop.prevent="updateQuery()">
|
||||||
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
||||||
<v-text-field :value="filter.q"
|
<v-text-field :value="filter.q"
|
||||||
solo hide-details clearable overflow single-line validate-on-blur
|
solo hide-details clearable overflow single-line validate-on-blur
|
||||||
|
@ -14,19 +14,19 @@
|
||||||
autocorrect="off"
|
autocorrect="off"
|
||||||
autocapitalize="none"
|
autocapitalize="none"
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
@input="onChangeQuery"
|
@change="(v) => {updateFilter({'q': v})}"
|
||||||
@keyup.enter.native="updateQuery"
|
@keyup.enter.native="refresh()"
|
||||||
@click:clear="clearQuery"
|
@click:clear="() => {updateQuery({'q': ''})}"
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
|
|
||||||
<v-btn icon class="action-reload" :title="$gettext('Reload')" @click.stop="refresh">
|
<v-btn icon class="action-reload" :title="$gettext('Reload')" @click.stop="refresh()">
|
||||||
<v-icon>refresh</v-icon>
|
<v-icon>refresh</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<v-btn v-if="!filter.all" icon class="action-show-all" :title="$gettext('Show more')" @click.stop="showAll">
|
<v-btn v-if="!filter.all" icon class="action-show-all" :title="$gettext('Show more')" @click.stop="showAll()">
|
||||||
<v-icon>unfold_more</v-icon>
|
<v-icon>unfold_more</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn v-else icon class="action-show-important" :title="$gettext('Show less')" @click.stop="showImportant">
|
<v-btn v-else icon class="action-show-important" :title="$gettext('Show less')" @click.stop="showImportant()">
|
||||||
<v-icon>unfold_less</v-icon>
|
<v-icon>unfold_less</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
|
@ -167,8 +167,6 @@ export default {
|
||||||
const routeName = this.$route.name;
|
const routeName = this.$route.name;
|
||||||
const q = query['q'] ? query['q'] : '';
|
const q = query['q'] ? query['q'] : '';
|
||||||
const all = query['all'] ? query['all'] : '';
|
const all = query['all'] ? query['all'] : '';
|
||||||
const filter = {"q": String(q), all: String(all)};
|
|
||||||
const settings = {};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
view: 'all',
|
view: 'all',
|
||||||
|
@ -184,9 +182,8 @@ export default {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
page: 0,
|
page: 0,
|
||||||
selection: [],
|
selection: [],
|
||||||
settings: settings,
|
settings: {},
|
||||||
q: q,
|
filter: {q, all},
|
||||||
filter: filter,
|
|
||||||
lastFilter: {},
|
lastFilter: {},
|
||||||
routeName: routeName,
|
routeName: routeName,
|
||||||
titleRule: v => v.length <= this.$config.get('clip') || this.$gettext("Name too long"),
|
titleRule: v => v.length <= this.$config.get('clip') || this.$gettext("Name too long"),
|
||||||
|
@ -200,8 +197,7 @@ export default {
|
||||||
|
|
||||||
this.routeName = this.$route.name;
|
this.routeName = this.$route.name;
|
||||||
this.lastFilter = {};
|
this.lastFilter = {};
|
||||||
this.q = query['q'] ? query['q'] : '';
|
this.filter.q = query['q'] ? query['q'] : '';
|
||||||
this.filter.q = this.q;
|
|
||||||
this.filter.all = query['all'] ? query['all'] : '';
|
this.filter.all = query['all'] ? query['all'] : '';
|
||||||
|
|
||||||
this.search();
|
this.search();
|
||||||
|
@ -368,7 +364,7 @@ export default {
|
||||||
this.lastId = "";
|
this.lastId = "";
|
||||||
},
|
},
|
||||||
loadMore() {
|
loadMore() {
|
||||||
if (this.scrollDisabled) return;
|
if (this.scrollDisabled || this.$scrollbar.disabled()) return;
|
||||||
|
|
||||||
this.scrollDisabled = true;
|
this.scrollDisabled = true;
|
||||||
this.listen = false;
|
this.listen = false;
|
||||||
|
@ -387,8 +383,12 @@ export default {
|
||||||
Object.assign(params, this.staticFilter);
|
Object.assign(params, this.staticFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (offset === 0) {
|
||||||
|
this.results = [];
|
||||||
|
}
|
||||||
|
|
||||||
Label.search(params).then(resp => {
|
Label.search(params).then(resp => {
|
||||||
this.results = this.dirty ? resp.models : this.results.concat(resp.models);
|
this.results = (offset === 0) ? resp.models : this.results.concat(resp.models);
|
||||||
|
|
||||||
this.scrollDisabled = (resp.count < resp.limit);
|
this.scrollDisabled = (resp.count < resp.limit);
|
||||||
|
|
||||||
|
@ -415,15 +415,44 @@ export default {
|
||||||
this.listen = true;
|
this.listen = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChangeQuery(val) {
|
updateSettings(props) {
|
||||||
this.q = val ? String(val) : '';
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.settings.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.settings[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.settings[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
clearQuery() {
|
updateFilter(props) {
|
||||||
this.q = '';
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
this.updateQuery();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.filter.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.filter[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.filter[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
updateQuery() {
|
updateQuery(props) {
|
||||||
this.filter.q = this.q.trim();
|
this.updateFilter(props);
|
||||||
|
|
||||||
if (this.loading) return;
|
if (this.loading) return;
|
||||||
|
|
||||||
|
@ -459,12 +488,16 @@ export default {
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
},
|
},
|
||||||
refresh() {
|
refresh(props) {
|
||||||
|
this.updateSettings(props);
|
||||||
|
|
||||||
if (this.loading) return;
|
if (this.loading) return;
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.page = 0;
|
this.page = 0;
|
||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
this.scrollDisabled = false;
|
this.scrollDisabled = false;
|
||||||
|
|
||||||
this.loadMore();
|
this.loadMore();
|
||||||
},
|
},
|
||||||
search() {
|
search() {
|
||||||
|
|
|
@ -11,15 +11,15 @@
|
||||||
:label="$gettext('Search')"
|
:label="$gettext('Search')"
|
||||||
prepend-inner-icon="search"
|
prepend-inner-icon="search"
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
@input="onChangeQuery"
|
@change="(v) => {updateFilter({'q': v})}"
|
||||||
@keyup.enter.native="updateQuery"
|
@keyup.enter.native="updateQuery()"
|
||||||
@click:clear="clearQuery"
|
@click:clear="() => {updateQuery({'q': ''})}"
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn icon class="action-reload" :title="$gettext('Reload')" @click.stop="onReload">
|
<v-btn icon class="action-reload" :title="$gettext('Reload')" @click.stop="onReload()">
|
||||||
<v-icon>refresh</v-icon>
|
<v-icon>refresh</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn v-if="!isPublic" icon class="action-delete" :title="$gettext('Delete')" @click.stop="onDelete">
|
<v-btn v-if="!isPublic" icon class="action-delete" :title="$gettext('Delete')" @click.stop="onDelete()">
|
||||||
<v-icon>delete</v-icon>
|
<v-icon>delete</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn icon href="https://docs.photoprism.app/getting-started/troubleshooting/" target="_blank" class="action-bug-report"
|
<v-btn icon href="https://docs.photoprism.app/getting-started/troubleshooting/" target="_blank" class="action-bug-report"
|
||||||
|
@ -108,7 +108,6 @@ export default {
|
||||||
loading: false,
|
loading: false,
|
||||||
scrollDisabled: false,
|
scrollDisabled: false,
|
||||||
scrollDistance: window.innerHeight*2,
|
scrollDistance: window.innerHeight*2,
|
||||||
q: q,
|
|
||||||
filter: {q},
|
filter: {q},
|
||||||
isPublic: this.$config.get("public"),
|
isPublic: this.$config.get("public"),
|
||||||
batchSize: 100,
|
batchSize: 100,
|
||||||
|
@ -127,10 +126,7 @@ export default {
|
||||||
watch: {
|
watch: {
|
||||||
'$route'() {
|
'$route'() {
|
||||||
const query = this.$route.query;
|
const query = this.$route.query;
|
||||||
|
this.filter.q = query['q'] ? query['q'] : '';
|
||||||
this.q = query['q'] ? query['q'] : '';
|
|
||||||
this.filter.q = this.q;
|
|
||||||
|
|
||||||
this.onReload();
|
this.onReload();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -138,15 +134,26 @@ export default {
|
||||||
this.loadMore();
|
this.loadMore();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onChangeQuery(val) {
|
updateFilter(props) {
|
||||||
this.q = val ? String(val) : '';
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.filter.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.filter[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.filter[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
clearQuery() {
|
updateQuery(props) {
|
||||||
this.q = '';
|
this.updateFilter(props);
|
||||||
this.updateQuery();
|
|
||||||
},
|
|
||||||
updateQuery() {
|
|
||||||
this.filter.q = this.q.trim();
|
|
||||||
|
|
||||||
if (this.loading) return;
|
if (this.loading) return;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="scrollDistance"
|
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="scrollDistance"
|
||||||
:infinite-scroll-listen-for-event="'scrollRefresh'">
|
:infinite-scroll-listen-for-event="'scrollRefresh'">
|
||||||
|
|
||||||
<v-form ref="form" class="p-people-search" lazy-validation dense @submit.prevent="updateQuery">
|
<v-form ref="form" class="p-people-search" lazy-validation dense @submit.prevent="updateQuery()">
|
||||||
<v-toolbar dense flat class="page-toolbar" color="secondary-light pa-0">
|
<v-toolbar dense flat class="page-toolbar" color="secondary-light pa-0">
|
||||||
<v-text-field :value="filter.q"
|
<v-text-field :value="filter.q"
|
||||||
solo hide-details clearable overflow single-line validate-on-blur
|
solo hide-details clearable overflow single-line validate-on-blur
|
||||||
|
@ -14,21 +14,21 @@
|
||||||
autocorrect="off"
|
autocorrect="off"
|
||||||
autocapitalize="none"
|
autocapitalize="none"
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
@input="onChangeQuery"
|
@change="(v) => {updateFilter({'q': v})}"
|
||||||
@keyup.enter.native="updateQuery"
|
@keyup.enter.native="refresh()"
|
||||||
@click:clear="clearQuery"
|
@click:clear="() => {updateQuery({'q': ''})}"
|
||||||
></v-text-field>
|
></v-text-field>
|
||||||
|
|
||||||
<v-divider vertical></v-divider>
|
<v-divider vertical></v-divider>
|
||||||
|
|
||||||
<v-btn icon overflow flat depressed color="secondary-dark" class="action-reload" :title="$gettext('Reload')" @click.stop="refresh">
|
<v-btn icon overflow flat depressed color="secondary-dark" class="action-reload" :title="$gettext('Reload')" @click.stop="refresh()">
|
||||||
<v-icon>refresh</v-icon>
|
<v-icon>refresh</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<v-btn v-if="!filter.hidden" icon class="action-show-hidden" :title="$gettext('Show hidden')" @click.stop="onShowHidden">
|
<v-btn v-if="!filter.hidden" icon class="action-show-hidden" :title="$gettext('Show hidden')" @click.stop="onShowHidden()">
|
||||||
<v-icon>visibility</v-icon>
|
<v-icon>visibility</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn v-else icon class="action-exclude-hidden" :title="$gettext('Exclude hidden')" @click.stop="onExcludeHidden">
|
<v-btn v-else icon class="action-exclude-hidden" :title="$gettext('Exclude hidden')" @click.stop="onExcludeHidden()">
|
||||||
<v-icon>visibility_off</v-icon>
|
<v-icon>visibility_off</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
|
@ -193,8 +193,6 @@ export default {
|
||||||
const q = query['q'] ? query['q'] : '';
|
const q = query['q'] ? query['q'] : '';
|
||||||
const hidden = query['hidden'] ? query['hidden'] : '';
|
const hidden = query['hidden'] ? query['hidden'] : '';
|
||||||
const order = this.sortOrder();
|
const order = this.sortOrder();
|
||||||
const filter = {q, hidden, order};
|
|
||||||
const settings = {};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
view: 'all',
|
view: 'all',
|
||||||
|
@ -210,9 +208,8 @@ export default {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
page: 0,
|
page: 0,
|
||||||
selection: [],
|
selection: [],
|
||||||
settings: settings,
|
settings: {},
|
||||||
q: q,
|
filter: {q, hidden, order},
|
||||||
filter: filter,
|
|
||||||
lastFilter: {},
|
lastFilter: {},
|
||||||
routeName: routeName,
|
routeName: routeName,
|
||||||
titleRule: v => v.length <= this.$config.get("clip") || this.$gettext("Name too long"),
|
titleRule: v => v.length <= this.$config.get("clip") || this.$gettext("Name too long"),
|
||||||
|
@ -244,8 +241,7 @@ export default {
|
||||||
const query = this.$route.query;
|
const query = this.$route.query;
|
||||||
|
|
||||||
this.routeName = this.$route.name;
|
this.routeName = this.$route.name;
|
||||||
this.q = query["q"] ? query["q"] : "";
|
this.filter.q = query["q"] ? query["q"] : "";
|
||||||
this.filter.q = this.q;
|
|
||||||
this.filter.hidden = query["hidden"] ? query["hidden"] : "";
|
this.filter.hidden = query["hidden"] ? query["hidden"] : "";
|
||||||
this.filter.order = this.sortOrder();
|
this.filter.order = this.sortOrder();
|
||||||
|
|
||||||
|
@ -527,15 +523,44 @@ export default {
|
||||||
this.listen = true;
|
this.listen = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChangeQuery(val) {
|
updateSettings(props) {
|
||||||
this.q = val ? String(val) : '';
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.settings.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.settings[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.settings[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
clearQuery() {
|
updateFilter(props) {
|
||||||
this.q = '';
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
this.updateQuery();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.filter.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.filter[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.filter[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
updateQuery() {
|
updateQuery(props) {
|
||||||
this.filter.q = this.q.trim();
|
this.updateFilter(props);
|
||||||
|
|
||||||
if (this.loading || !this.active) {
|
if (this.loading || !this.active) {
|
||||||
return;
|
return;
|
||||||
|
@ -573,10 +598,10 @@ export default {
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
},
|
},
|
||||||
refresh() {
|
refresh(props) {
|
||||||
if (this.loading || !this.active) {
|
this.updateSettings(props);
|
||||||
return;
|
|
||||||
}
|
if (this.loading || !this.active) return;
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.page = 0;
|
this.page = 0;
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="scrollDistance"
|
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="scrollDistance"
|
||||||
:infinite-scroll-listen-for-event="'scrollRefresh'">
|
:infinite-scroll-listen-for-event="'scrollRefresh'">
|
||||||
|
|
||||||
<p-photo-toolbar :settings="settings" :filter="filter" :filter-change="updateQuery" :dirty="dirty"
|
<p-photo-toolbar :filter="filter" :settings="settings" :refresh="refresh"
|
||||||
:refresh="refresh"></p-photo-toolbar>
|
:update-filter="updateFilter" :update-query="updateQuery"></p-photo-toolbar>
|
||||||
|
|
||||||
<v-container v-if="loading" fluid class="pa-4">
|
<v-container v-if="loading" fluid class="pa-4">
|
||||||
<v-progress-linear color="secondary-dark" :indeterminate="true"></v-progress-linear>
|
<v-progress-linear color="secondary-dark" :indeterminate="true"></v-progress-linear>
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {Photo, MediaLive, MediaRaw, MediaVideo, MediaAnimated} from "model/photo";
|
import {MediaAnimated, MediaLive, MediaRaw, MediaVideo, Photo} from "model/photo";
|
||||||
import Thumb from "model/thumb";
|
import Thumb from "model/thumb";
|
||||||
import Viewer from "common/viewer";
|
import Viewer from "common/viewer";
|
||||||
import Event from "pubsub-js";
|
import Event from "pubsub-js";
|
||||||
|
@ -50,7 +50,11 @@ import Event from "pubsub-js";
|
||||||
export default {
|
export default {
|
||||||
name: 'PPagePhotos',
|
name: 'PPagePhotos',
|
||||||
props: {
|
props: {
|
||||||
staticFilter: Object
|
staticFilter: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const query = this.$route.query;
|
const query = this.$route.query;
|
||||||
|
@ -98,7 +102,7 @@ export default {
|
||||||
complete: false,
|
complete: false,
|
||||||
results: [],
|
results: [],
|
||||||
scrollDisabled: true,
|
scrollDisabled: true,
|
||||||
scrollDistance: window.innerHeight*2,
|
scrollDistance: window.innerHeight * 2,
|
||||||
batchSize: batchSize,
|
batchSize: batchSize,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
page: 0,
|
page: 0,
|
||||||
|
@ -232,7 +236,7 @@ export default {
|
||||||
showMerged = false;
|
showMerged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showMerged && selected.Type === MediaLive || selected.Type === MediaVideo|| selected.Type === MediaAnimated) {
|
if (showMerged && selected.Type === MediaLive || selected.Type === MediaVideo || selected.Type === MediaAnimated) {
|
||||||
if (selected.isPlayable()) {
|
if (selected.isPlayable()) {
|
||||||
this.$viewer.play({video: selected});
|
this.$viewer.play({video: selected});
|
||||||
} else {
|
} else {
|
||||||
|
@ -303,10 +307,46 @@ export default {
|
||||||
this.listen = true;
|
this.listen = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
updateQuery() {
|
updateSettings(props) {
|
||||||
if (this.loading) return;
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.filter.q = this.filter.q.trim();
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.settings.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.settings[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.settings[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateFilter(props) {
|
||||||
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.filter.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.filter[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.filter[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateQuery(props) {
|
||||||
|
this.updateFilter(props);
|
||||||
|
|
||||||
|
if (this.loading) return;
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
view: this.settings.view
|
view: this.settings.view
|
||||||
|
@ -341,10 +381,10 @@ export default {
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
},
|
},
|
||||||
refresh() {
|
refresh(props) {
|
||||||
if (this.loading) {
|
this.updateSettings(props);
|
||||||
return;
|
|
||||||
}
|
if (this.loading) return;
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.page = 0;
|
this.page = 0;
|
||||||
|
|
|
@ -231,11 +231,11 @@ export default {
|
||||||
this.search();
|
this.search();
|
||||||
},
|
},
|
||||||
clearQuery() {
|
clearQuery() {
|
||||||
this.filter.q = "";
|
this.filter.q = '';
|
||||||
this.search();
|
this.search();
|
||||||
},
|
},
|
||||||
updateQuery() {
|
updateQuery() {
|
||||||
this.filter.q = this.filter.q.trim();
|
if (this.loading) return;
|
||||||
|
|
||||||
if (this.query() !== this.filter.q) {
|
if (this.query() !== this.filter.q) {
|
||||||
if (this.filter.q) {
|
if (this.filter.q) {
|
||||||
|
@ -247,6 +247,7 @@ export default {
|
||||||
},
|
},
|
||||||
search() {
|
search() {
|
||||||
if (this.loading) return;
|
if (this.loading) return;
|
||||||
|
|
||||||
// Don't query the same data more than once
|
// Don't query the same data more than once
|
||||||
if (JSON.stringify(this.lastFilter) === JSON.stringify(this.filter)) return;
|
if (JSON.stringify(this.lastFilter) === JSON.stringify(this.filter)) return;
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
|
@ -122,15 +122,16 @@ export default {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
view: String,
|
view: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const query = this.$route.query;
|
const query = this.$route.query;
|
||||||
const routeName = this.$route.name;
|
const routeName = this.$route.name;
|
||||||
const q = query["q"] ? query["q"] : "";
|
const q = query["q"] ? query["q"] : "";
|
||||||
const category = query["category"] ? query["category"] : "";
|
const category = query["category"] ? query["category"] : "";
|
||||||
const filter = {q, category};
|
|
||||||
const settings = {};
|
|
||||||
|
|
||||||
let categories = [{"value": "", "text": this.$gettext("All Categories")}];
|
let categories = [{"value": "", "text": this.$gettext("All Categories")}];
|
||||||
|
|
||||||
|
@ -154,8 +155,8 @@ export default {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
page: 0,
|
page: 0,
|
||||||
selection: [],
|
selection: [],
|
||||||
settings: settings,
|
settings: {},
|
||||||
filter: filter,
|
filter: {q, category},
|
||||||
lastFilter: {},
|
lastFilter: {},
|
||||||
routeName: routeName,
|
routeName: routeName,
|
||||||
titleRule: v => v.length <= this.$config.get('clip') || this.$gettext("Title too long"),
|
titleRule: v => v.length <= this.$config.get('clip') || this.$gettext("Title too long"),
|
||||||
|
|
|
@ -157,21 +157,15 @@ export default {
|
||||||
},
|
},
|
||||||
openPhoto: {
|
openPhoto: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('cards view: openPhoto is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
editPhoto: {
|
editPhoto: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('cards view: editPhoto is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
openLocation: {
|
openLocation: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('cards view: openLocation is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
album: {
|
album: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
|
@ -104,21 +104,15 @@ export default {
|
||||||
},
|
},
|
||||||
openPhoto: {
|
openPhoto: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('list view: openPhoto is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
editPhoto: {
|
editPhoto: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('list view: editPhoto is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
openLocation: {
|
openLocation: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: () => () => {
|
default: () => {},
|
||||||
console.warn('list view: openLocation is undefined');
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
album: {
|
album: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="scrollDistance"
|
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="scrollDistance"
|
||||||
:infinite-scroll-listen-for-event="'scrollRefresh'">
|
:infinite-scroll-listen-for-event="'scrollRefresh'">
|
||||||
|
|
||||||
<v-form ref="form" lazy-validation
|
<v-form ref="form" lazy-validation dense
|
||||||
dense autocomplete="off" class="p-photo-toolbar p-album-toolbar" accept-charset="UTF-8">
|
autocomplete="off" class="p-photo-toolbar p-album-toolbar"
|
||||||
|
accept-charset="UTF-8" @submit.prevent="updateQuery()">
|
||||||
<v-toolbar flat color="secondary" :dense="$vuetify.breakpoint.smAndDown">
|
<v-toolbar flat color="secondary" :dense="$vuetify.breakpoint.smAndDown">
|
||||||
<v-toolbar-title>
|
<v-toolbar-title>
|
||||||
{{ model.Title }}
|
{{ model.Title }}
|
||||||
|
@ -12,12 +13,12 @@
|
||||||
|
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
|
|
||||||
<v-btn icon class="hidden-xs-only action-reload" @click.stop="refresh">
|
<v-btn icon class="hidden-xs-only action-reload" @click.stop="refresh()">
|
||||||
<v-icon>refresh</v-icon>
|
<v-icon>refresh</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<v-btn v-if="$config.feature('download')" icon class="hidden-xs-only action-download" :title="$gettext('Download')"
|
<v-btn v-if="$config.feature('download')" icon class="hidden-xs-only action-download" :title="$gettext('Download')"
|
||||||
@click.stop="download">
|
@click.stop="download()">
|
||||||
<v-icon>get_app</v-icon>
|
<v-icon>get_app</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
|
@ -98,7 +99,10 @@ import Viewer from "common/viewer";
|
||||||
export default {
|
export default {
|
||||||
name: 'PPageAlbumPhotos',
|
name: 'PPageAlbumPhotos',
|
||||||
props: {
|
props: {
|
||||||
staticFilter: Object
|
staticFilter: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const uid = this.$route.params.uid;
|
const uid = this.$route.params.uid;
|
||||||
|
@ -317,8 +321,44 @@ export default {
|
||||||
this.listen = true;
|
this.listen = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
updateQuery() {
|
updateSettings(props) {
|
||||||
this.filter.q = this.filter.q.trim();
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.settings.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.settings[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.settings[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateFilter(props) {
|
||||||
|
if (!props || typeof props !== "object" || props.target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (!this.filter.hasOwnProperty(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
this.filter[key] = value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.filter[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateQuery(props) {
|
||||||
|
this.updateFilter(props);
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
view: this.settings.view
|
view: this.settings.view
|
||||||
|
@ -355,10 +395,10 @@ export default {
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
},
|
},
|
||||||
refresh() {
|
refresh(props) {
|
||||||
if (this.loading) {
|
this.updateSettings(props);
|
||||||
return;
|
|
||||||
}
|
if (this.loading) return;
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.page = 0;
|
this.page = 0;
|
||||||
|
|
Loading…
Reference in a new issue