|
@@ -1,85 +1,108 @@
|
|
|
<template>
|
|
|
- <div class="root column fit">
|
|
|
- <div class="col fit" style="position: relative">
|
|
|
- <div v-show="loadingVisible" class="fit row justify-center items-center" style="position: absolute; background-color: rgba(0, 0, 0, 0.2); z-index: 1">
|
|
|
- <div class="bg-white row justify-center items-center" style="width: 180px; height: 50px; border-radius: 10px; box-shadow: 2px 2px 10px #333333">
|
|
|
- <q-spinner color="primary" size="2em" />
|
|
|
- <div class="q-ml-sm">
|
|
|
- Поиск авторов...
|
|
|
- </div>
|
|
|
+ <div class="root column fit" style="position: relative">
|
|
|
+ <div v-show="loadingMessage" class="fit row justify-center items-center" style="position: absolute; background-color: rgba(0, 0, 0, 0.2); z-index: 1">
|
|
|
+ <div class="bg-white row justify-center items-center" style="width: 180px; height: 50px; border-radius: 10px; box-shadow: 2px 2px 10px #333333">
|
|
|
+ <q-spinner color="primary" size="2em" />
|
|
|
+ <div class="q-ml-sm">
|
|
|
+ {{ loadingMessage }}
|
|
|
</div>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
|
|
|
- <div ref="scroller" class="col fit column no-wrap" style="overflow: auto; position: relative" @scroll="onScroll">
|
|
|
- <div ref="toolPanel" class="tool-panel column bg-green-11" style="position: sticky; top: 0;">
|
|
|
- <div class="header q-mx-md q-mt-sm row justify-between items-center">
|
|
|
- <div class="row items-center">
|
|
|
- <div class="q-mr-xs">
|
|
|
- Коллекция
|
|
|
- </div>
|
|
|
- <div class="clickable" @click="showCollectionInfo">
|
|
|
- {{ collection }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="q-ml-md">
|
|
|
+ <div ref="scroller" class="col fit column no-wrap" style="overflow: auto; position: relative" @scroll="onScroll">
|
|
|
+ <div ref="toolPanel" class="tool-panel column bg-green-11" style="position: sticky; top: 0; z-index: 10;">
|
|
|
+ <div class="header q-mx-md q-mt-xs row items-center justify-between">
|
|
|
+ <div class="row items-center q-mr-xs" style="font-size: 150%;">
|
|
|
+ <div class="q-py-xs q-px-sm bg-green-12" style="border: 1px solid #aaaaaa; border-radius: 6px">
|
|
|
{{ projectName }}
|
|
|
</div>
|
|
|
+ <div class="q-ml-md q-mr-xs">
|
|
|
+ Коллекция
|
|
|
+ </div>
|
|
|
+ <div class="clickable" @click="showCollectionInfo">
|
|
|
+ {{ collection }}
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div class="row q-mx-md q-my-sm items-center">
|
|
|
- <q-input
|
|
|
- ref="authorInput" v-model="author" :maxlength="5000" :debounce="inputDebounce"
|
|
|
- class="bg-white q-mt-xs" style="width: 300px;" label="Автор" stack-label outlined dense clearable
|
|
|
- />
|
|
|
- <div class="q-mx-xs" />
|
|
|
- <q-input
|
|
|
- v-model="series" :maxlength="inputMaxLength" :debounce="inputDebounce"
|
|
|
- class="bg-white q-mt-xs" style="width: 200px;" label="Серия" stack-label outlined dense clearable
|
|
|
- />
|
|
|
- <div class="q-mx-xs" />
|
|
|
- <q-input
|
|
|
- v-model="title" :maxlength="inputMaxLength" :debounce="inputDebounce"
|
|
|
- class="bg-white q-mt-xs" style="width: 200px;" label="Название" stack-label outlined dense clearable
|
|
|
- />
|
|
|
- <div class="q-mx-xs" />
|
|
|
- <q-input
|
|
|
- v-model="genre" :maxlength="inputMaxLength" :debounce="inputDebounce"
|
|
|
- class="bg-white q-mt-xs" style="width: 200px;" label="Жанр" stack-label outlined dense clearable readonly
|
|
|
- @click="selectGenre"
|
|
|
- />
|
|
|
- <div class="q-mx-xs" />
|
|
|
- <q-input
|
|
|
- v-model="lang" :maxlength="inputMaxLength" :debounce="inputDebounce"
|
|
|
- class="bg-white q-mt-xs" style="width: 80px;" label="Язык" stack-label outlined dense clearable readonly
|
|
|
- @click="selectLang"
|
|
|
+ <div class="row items-center" style="font-size: 120%;">
|
|
|
+ <div class="q-mr-xs">
|
|
|
+ На странице
|
|
|
+ </div>
|
|
|
+ <q-select
|
|
|
+ v-model="limit" :options="limitOptions" class="bg-white"
|
|
|
+ dropdown-icon="la la-angle-down la-sm"
|
|
|
+ outlined dense emit-value map-options
|
|
|
/>
|
|
|
- <div class="q-mx-xs" />
|
|
|
- <q-btn round dense style="height: 20px" color="info" icon="la la-question" @click="showSearchHelp" />
|
|
|
-
|
|
|
- <div class="q-mx-xs" />
|
|
|
- <div class="row items-center q-mt-xs">
|
|
|
- <div v-show="queryFound > 0">
|
|
|
- Найдено {{ totalFound }} авторов
|
|
|
- </div>
|
|
|
- <div v-show="queryFound == 0">
|
|
|
- Ничего не найдено
|
|
|
- </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="row q-mx-md q-mb-sm items-center">
|
|
|
+ <q-input
|
|
|
+ ref="authorInput" v-model="author" :maxlength="5000" :debounce="inputDebounce"
|
|
|
+ class="bg-white q-mt-xs" style="width: 300px;" label="Автор" stack-label outlined dense clearable
|
|
|
+ />
|
|
|
+ <div class="q-mx-xs" />
|
|
|
+ <q-input
|
|
|
+ v-model="series" :maxlength="inputMaxLength" :debounce="inputDebounce"
|
|
|
+ class="bg-white q-mt-xs" style="width: 200px;" label="Серия" stack-label outlined dense clearable
|
|
|
+ />
|
|
|
+ <div class="q-mx-xs" />
|
|
|
+ <q-input
|
|
|
+ v-model="title" :maxlength="inputMaxLength" :debounce="inputDebounce"
|
|
|
+ class="bg-white q-mt-xs" style="width: 200px;" label="Название" stack-label outlined dense clearable
|
|
|
+ />
|
|
|
+ <div class="q-mx-xs" />
|
|
|
+ <q-input
|
|
|
+ v-model="genre" :maxlength="inputMaxLength" :debounce="inputDebounce"
|
|
|
+ class="bg-white q-mt-xs" style="width: 200px;" label="Жанр" stack-label outlined dense clearable readonly
|
|
|
+ @click="selectGenre"
|
|
|
+ />
|
|
|
+ <div class="q-mx-xs" />
|
|
|
+ <q-input
|
|
|
+ v-model="lang" :maxlength="inputMaxLength" :debounce="inputDebounce"
|
|
|
+ class="bg-white q-mt-xs" style="width: 80px;" label="Язык" stack-label outlined dense clearable readonly
|
|
|
+ @click="selectLang"
|
|
|
+ />
|
|
|
+ <div class="q-mx-xs" />
|
|
|
+ <q-btn round dense style="height: 20px" color="info" icon="la la-question" @click="showSearchHelp" />
|
|
|
+
|
|
|
+ <div class="q-mx-xs" />
|
|
|
+ <div class="row items-center q-mt-xs">
|
|
|
+ <div v-show="queryFound > 0">
|
|
|
+ Найдено {{ totalFound }} авторов
|
|
|
</div>
|
|
|
-
|
|
|
- <div class="q-mx-xs" />
|
|
|
- <div class="col row justify-end q-mt-xs">
|
|
|
- <q-select
|
|
|
- v-model="limit" :options="limitOptions" class="bg-white"
|
|
|
- dropdown-icon="la la-angle-down la-sm"
|
|
|
- outlined dense emit-value map-options
|
|
|
- />
|
|
|
+ <div v-show="queryFound == 0">
|
|
|
+ Ничего не найдено
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
|
|
|
- <div v-for="item in tableData" :key="item.key" style="border-bottom: 1px solid #aaaaaa">
|
|
|
- <div class="q-my-sm q-ml-md" style="font-size: 120%">
|
|
|
- {{ item.value }}
|
|
|
- </div>
|
|
|
+ <div v-show="totalPages > 1" class="row justify-center items-center q-ml-md q-my-xs" style="font-size: 120%">
|
|
|
+ <div class="q-mr-xs">
|
|
|
+ Страница
|
|
|
+ </div>
|
|
|
+ <div class="bg-white">
|
|
|
+ <NumInput v-model="page" :min="1" :max="totalPages" style="width: 150px" />
|
|
|
+ </div>
|
|
|
+ <div class="q-ml-xs">
|
|
|
+ из {{ totalPages }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-for="item in tableData" :key="item.key" style="border-bottom: 1px solid #aaaaaa">
|
|
|
+ <div class="q-my-sm q-ml-md" style="font-size: 120%">
|
|
|
+ {{ item.value }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-show="totalPages > 1" class="row justify-center items-center q-ml-md q-my-xs" style="font-size: 120%">
|
|
|
+ <div class="q-mr-xs">
|
|
|
+ Страница
|
|
|
+ </div>
|
|
|
+ <div class="bg-white">
|
|
|
+ <NumInput v-model="page" :min="1" :max="totalPages" style="width: 150px" />
|
|
|
+ </div>
|
|
|
+ <div class="q-ml-xs">
|
|
|
+ из {{ totalPages }}
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -90,11 +113,14 @@
|
|
|
//-----------------------------------------------------------------------------
|
|
|
import vueComponent from '../vueComponent.js';
|
|
|
|
|
|
+import NumInput from '../share/NumInput.vue';
|
|
|
import * as utils from '../../share/utils';
|
|
|
+
|
|
|
//import _ from 'lodash';
|
|
|
|
|
|
const componentOptions = {
|
|
|
components: {
|
|
|
+ NumInput,
|
|
|
},
|
|
|
watch: {
|
|
|
config() {
|
|
@@ -115,9 +141,16 @@ const componentOptions = {
|
|
|
lang() {
|
|
|
this.refresh();
|
|
|
},
|
|
|
+ page() {
|
|
|
+ this.refresh();
|
|
|
+ },
|
|
|
limit() {
|
|
|
+ this.updatePageCount();
|
|
|
this.refresh();
|
|
|
},
|
|
|
+ totalFound() {
|
|
|
+ this.updatePageCount();
|
|
|
+ }
|
|
|
},
|
|
|
};
|
|
|
class Search {
|
|
@@ -125,7 +158,9 @@ class Search {
|
|
|
collection = '';
|
|
|
projectName = '';
|
|
|
|
|
|
- loadingVisible = false;
|
|
|
+ loadingMessage = '';
|
|
|
+ page = 1;
|
|
|
+ totalPages = 1;
|
|
|
|
|
|
//input field consts
|
|
|
inputMaxLength = 1000;
|
|
@@ -220,6 +255,13 @@ class Search {
|
|
|
this.lastScrollTop = curScrollTop;
|
|
|
}
|
|
|
|
|
|
+ updatePageCount() {
|
|
|
+ this.totalPages = Math.floor(this.totalFound/this.limit);
|
|
|
+ this.totalPages = (this.totalPages < 1 ? 1 : this.totalPages);
|
|
|
+ if (this.page > this.totalPages)
|
|
|
+ this.page = 1;
|
|
|
+ }
|
|
|
+
|
|
|
async updateTableData() {
|
|
|
let result = [];
|
|
|
|
|
@@ -231,6 +273,8 @@ class Search {
|
|
|
}
|
|
|
|
|
|
async refresh() {
|
|
|
+ const offset = (this.page - 1)*this.limit;
|
|
|
+
|
|
|
const newQuery = {
|
|
|
author: this.author,
|
|
|
series: this.series,
|
|
@@ -238,6 +282,7 @@ class Search {
|
|
|
genre: this.genre,
|
|
|
lang: this.lang,
|
|
|
limit: this.limit,
|
|
|
+ offset,
|
|
|
};
|
|
|
|
|
|
this.queryExecute = newQuery;
|
|
@@ -255,7 +300,7 @@ class Search {
|
|
|
(async() => {
|
|
|
await utils.sleep(500);
|
|
|
if (inSearch)
|
|
|
- this.loadingVisible = true;
|
|
|
+ this.loadingMessage = 'Поиск авторов...';
|
|
|
})();
|
|
|
|
|
|
try {
|
|
@@ -271,7 +316,7 @@ class Search {
|
|
|
return;
|
|
|
} finally {
|
|
|
inSearch = false;
|
|
|
- this.loadingVisible = false;
|
|
|
+ this.loadingMessage = '';
|
|
|
}
|
|
|
}
|
|
|
} finally {
|
|
@@ -293,7 +338,6 @@ export default vueComponent(Search);
|
|
|
}
|
|
|
|
|
|
.header {
|
|
|
- font-size: 150%;
|
|
|
min-height: 30px;
|
|
|
}
|
|
|
|