Работа над диалогом выбора даты
This commit is contained in:
@@ -360,13 +360,7 @@ class AuthorList extends BaseList {
|
||||
|
||||
async refresh() {
|
||||
//параметры запроса
|
||||
let newQuery = _.cloneDeep(this.search);
|
||||
newQuery = newQuery.setDefaults(newQuery);
|
||||
delete newQuery.setDefaults;
|
||||
newQuery.offset = (newQuery.page - 1)*newQuery.limit;
|
||||
if (!this.showDeleted)
|
||||
newQuery.del = 0;
|
||||
|
||||
const newQuery = this.getQuery();
|
||||
if (_.isEqual(newQuery, this.prevQuery))
|
||||
return;
|
||||
this.prevQuery = newQuery;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import moment from 'moment';
|
||||
import _ from 'lodash';
|
||||
|
||||
import authorBooksStorage from './authorBooksStorage';
|
||||
@@ -230,7 +231,7 @@ export default class BaseList {
|
||||
|
||||
async expandSeries(seriesItem) {
|
||||
this.$emit('listEvent', {action: 'ignoreScroll'});
|
||||
|
||||
|
||||
const expandedSeries = _.cloneDeep(this.expandedSeries);
|
||||
const key = seriesItem.key;
|
||||
|
||||
@@ -406,7 +407,8 @@ export default class BaseList {
|
||||
//date
|
||||
let dateFound = !s.date;
|
||||
if (!dateFound) {
|
||||
let [from = '0000-00-00', to = '9999-99-99'] = s.date.split(',');
|
||||
const date = this.queryDate(s.date.split(','));
|
||||
let [from = '0000-00-00', to = '9999-99-99'] = date;
|
||||
dateFound = (book.date >= from && book.date <= to);
|
||||
}
|
||||
|
||||
@@ -467,4 +469,51 @@ export default class BaseList {
|
||||
return (dserno ? dserno : (dtitle ? dtitle : dext));
|
||||
});
|
||||
}
|
||||
|
||||
queryDate(date) {
|
||||
if (!(utils.isDigit(date[0]) && utils.isDigit(date[1]))) {//!manual
|
||||
/*
|
||||
{label: 'сегодня', value: 'today'},
|
||||
{label: 'за 3 дня', value: '3days'},
|
||||
{label: 'за неделю', value: 'week'},
|
||||
{label: 'за 2 недели', value: '2weeks'},
|
||||
{label: 'за месяц', value: 'month'},
|
||||
{label: 'за 3 месяца', value: '3months'},
|
||||
{label: 'указать даты', value: 'manual'},
|
||||
*/
|
||||
const sqlFormat = 'YYYY-MM-DD';
|
||||
switch (date) {
|
||||
case 'today': date = utils.dateFormat(moment(), sqlFormat); break;
|
||||
case '3days': date = utils.dateFormat(moment().subtract(3, 'days'), sqlFormat); break;
|
||||
case 'week': date = utils.dateFormat(moment().subtract(1, 'weeks'), sqlFormat); break;
|
||||
case '2weeks': date = utils.dateFormat(moment().subtract(2, 'weeks'), sqlFormat); break;
|
||||
case 'month': date = utils.dateFormat(moment().subtract(1, 'months'), sqlFormat); break;
|
||||
case '3months': date = utils.dateFormat(moment().subtract(3, 'months'), sqlFormat); break;
|
||||
default:
|
||||
date = '';
|
||||
}
|
||||
}
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
getQuery() {
|
||||
let newQuery = _.cloneDeep(this.search);
|
||||
newQuery = newQuery.setDefaults(newQuery);
|
||||
delete newQuery.setDefaults;
|
||||
|
||||
//дата
|
||||
if (newQuery.date) {
|
||||
newQuery.date = this.queryDate(newQuery.date);
|
||||
}
|
||||
|
||||
//offset
|
||||
newQuery.offset = (newQuery.page - 1)*newQuery.limit;
|
||||
|
||||
//del
|
||||
if (!this.showDeleted)
|
||||
newQuery.del = 0;
|
||||
|
||||
return newQuery;
|
||||
}
|
||||
}
|
||||
@@ -204,8 +204,7 @@ class BookView {
|
||||
if (!this.book.date)
|
||||
return '';
|
||||
|
||||
const date = utils.parseDate(this.book.date);
|
||||
return utils.formatDate(date, 'noDate');
|
||||
return utils.sqlDateFormat(this.book.date);
|
||||
}
|
||||
|
||||
selectAuthor() {
|
||||
|
||||
@@ -120,14 +120,35 @@
|
||||
</q-input>
|
||||
|
||||
<div class="q-mx-xs" />
|
||||
<q-input
|
||||
v-model="search.date" :maxlength="inputMaxLength" :debounce="inputDebounce"
|
||||
class="q-mt-xs" :bg-color="inputBgColor()" input-style="cursor: pointer" style="width: 200px;" label="Дата поступления" stack-label outlined dense clearable
|
||||
<q-select
|
||||
v-model="searchDate"
|
||||
class="q-mt-xs"
|
||||
:options="searchDateOptions"
|
||||
dropdown-icon="la la-angle-down la-sm"
|
||||
:bg-color="inputBgColor()"
|
||||
style="width: 200px;"
|
||||
label="Дата поступления" stack-label
|
||||
outlined dense emit-value map-options clearable
|
||||
>
|
||||
<q-tooltip v-if="search.date && showTooltips" :delay="500" anchor="bottom middle" content-style="font-size: 80%" max-width="400px">
|
||||
{{ search.date }}
|
||||
</q-tooltip>
|
||||
</q-input>
|
||||
<template #selected-item="scope">
|
||||
<div v-if="scope.opt.value == 'manual'">
|
||||
<div v-html="formatSearchDate" />
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ scope.opt.label }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #option="scope">
|
||||
<q-item v-bind="scope.itemProps" @click="dateSelectItemClick(scope.opt.value)">
|
||||
<q-item-section>
|
||||
<q-item-label>
|
||||
{{ scope.opt.label }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
|
||||
<div class="q-mx-xs" />
|
||||
<q-input
|
||||
@@ -210,6 +231,7 @@
|
||||
<SelectGenreDialog v-model="selectGenreDialogVisible" v-model:genre="search.genre" :genre-tree="genreTree" />
|
||||
<SelectLangDialog v-model="selectLangDialogVisible" v-model:lang="search.lang" :lang-list="langList" :lang-default="langDefault" />
|
||||
<SelectLibRateDialog v-model="selectLibRateDialogVisible" v-model:librate="search.librate" />
|
||||
<SelectDateDialog v-model="selectDateDialogVisible" v-model:date="search.date" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -225,6 +247,7 @@ import PageScroller from './PageScroller/PageScroller.vue';
|
||||
import SelectGenreDialog from './SelectGenreDialog/SelectGenreDialog.vue';
|
||||
import SelectLangDialog from './SelectLangDialog/SelectLangDialog.vue';
|
||||
import SelectLibRateDialog from './SelectLibRateDialog/SelectLibRateDialog.vue';
|
||||
import SelectDateDialog from './SelectDateDialog/SelectDateDialog.vue';
|
||||
|
||||
import authorBooksStorage from './authorBooksStorage';
|
||||
import DivBtn from '../share/DivBtn.vue';
|
||||
@@ -250,6 +273,7 @@ const componentOptions = {
|
||||
SelectGenreDialog,
|
||||
SelectLangDialog,
|
||||
SelectLibRateDialog,
|
||||
SelectDateDialog,
|
||||
Dialog,
|
||||
DivBtn
|
||||
},
|
||||
@@ -271,6 +295,7 @@ const componentOptions = {
|
||||
|
||||
this.makeTitle();
|
||||
this.updateRouteQueryFromSearch();
|
||||
this.updateSearchDate(true);
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
@@ -334,7 +359,10 @@ const componentOptions = {
|
||||
if (this.getListRoute() != newValue) {
|
||||
this.updateRouteQueryFromSearch();
|
||||
}
|
||||
}
|
||||
},
|
||||
searchDate() {
|
||||
this.updateSearchDate(false);
|
||||
},
|
||||
},
|
||||
};
|
||||
class Search {
|
||||
@@ -354,6 +382,7 @@ class Search {
|
||||
selectGenreDialogVisible = false;
|
||||
selectLangDialogVisible = false;
|
||||
selectLibRateDialogVisible = false;
|
||||
selectDateDialogVisible = false;
|
||||
|
||||
pageCount = 1;
|
||||
|
||||
@@ -378,6 +407,8 @@ class Search {
|
||||
},
|
||||
};
|
||||
|
||||
searchDate = '';
|
||||
|
||||
//settings
|
||||
showCounts = true;
|
||||
showRates = true;
|
||||
@@ -414,6 +445,16 @@ class Search {
|
||||
{label: '1000', value: 1000},
|
||||
];
|
||||
|
||||
searchDateOptions = [
|
||||
{label: 'сегодня', value: 'today'},
|
||||
{label: 'за 3 дня', value: '3days'},
|
||||
{label: 'за неделю', value: 'week'},
|
||||
{label: 'за 2 недели', value: '2weeks'},
|
||||
{label: 'за месяц', value: 'month'},
|
||||
{label: 'за 3 месяца', value: '3months'},
|
||||
{label: 'выбрать даты', value: 'manual'},
|
||||
];
|
||||
|
||||
created() {
|
||||
this.commit = this.$store.commit;
|
||||
this.api = this.$root.api;
|
||||
@@ -928,6 +969,47 @@ class Search {
|
||||
this.genreTreeUpdating = false;
|
||||
}
|
||||
}
|
||||
|
||||
isManualDate(date) {
|
||||
return date && utils.isDigit(date[0]) && utils.isDigit(date[1]);
|
||||
}
|
||||
|
||||
updateSearchDate(toLocal) {
|
||||
if (toLocal) {
|
||||
let local = this.search.date || '';
|
||||
if (this.isManualDate(local))
|
||||
local = 'manual';
|
||||
|
||||
this.searchDate = local;
|
||||
} else {
|
||||
if (this.searchDate != 'manual')
|
||||
this.search.date = this.searchDate || '';
|
||||
}
|
||||
}
|
||||
|
||||
get formatSearchDate() {
|
||||
const result = [];
|
||||
const date = this.search.date;
|
||||
if (this.isManualDate(date)) {
|
||||
const [from, to] = date.split(',')
|
||||
if (from)
|
||||
result.push(`<div style="display: inline-block; width: 15px; text-align: right;">от</div> ${utils.sqlDateFormat(from)}`);
|
||||
if (to)
|
||||
result.push(`<div style="display: inline-block; width: 15px; text-align: right;">до</div> ${utils.sqlDateFormat(to)}`);
|
||||
}
|
||||
|
||||
return result.join('<br>');
|
||||
}
|
||||
|
||||
dateSelectItemClick(itemValue) {
|
||||
if (itemValue == 'manual') {
|
||||
if (!this.isManualDate(this.search.date)) {
|
||||
this.search.date = '';
|
||||
this.searchDate = '';
|
||||
}
|
||||
this.selectDateDialogVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default vueComponent(Search);
|
||||
|
||||
132
client/components/Search/SelectDateDialog/SelectDateDialog.vue
Normal file
132
client/components/Search/SelectDateDialog/SelectDateDialog.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<Dialog ref="dialog" v-model="dialogVisible">
|
||||
<template #header>
|
||||
<div class="row items-center">
|
||||
<div style="font-size: 130%">
|
||||
Выбрать даты
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div ref="box" class="column q-mt-xs overflow-auto no-wrap" style="width: 240px; padding: 0px 10px 10px 10px;">
|
||||
<div class="row items-center">
|
||||
<span class="q-mr-sm">От:</span>
|
||||
<q-btn icon="la la-calendar" color="secondary" :label="labelFrom" dense no-caps style="width: 150px;">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-date v-model="from" mask="YYYY-MM-DD">
|
||||
<div class="row items-center justify-end q-gutter-sm">
|
||||
<q-btn v-close-popup label="Отмена" color="primary" flat />
|
||||
<q-btn v-close-popup label="OK" color="primary" flat @click="save" />
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-btn>
|
||||
<q-icon name="la la-times-circle" class="q-ml-sm text-grey-6 clickable2" size="28px" @click="from = ''; save();" />
|
||||
</div>
|
||||
|
||||
<div class="q-my-sm" />
|
||||
<div class="row items-center">
|
||||
<span class="q-mr-sm">До:</span>
|
||||
<q-btn icon="la la-calendar" color="secondary" :label="labelTo" dense no-caps style="width: 150px;">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-date v-model="to" mask="YYYY-MM-DD">
|
||||
<div class="row items-center justify-end q-gutter-sm">
|
||||
<q-btn v-close-popup label="Отмена" color="primary" flat />
|
||||
<q-btn v-close-popup label="OK" color="primary" flat @click="save" />
|
||||
</div>
|
||||
</q-date>
|
||||
</q-popup-proxy>
|
||||
</q-btn>
|
||||
<q-icon name="la la-times-circle" class="q-ml-sm text-grey-6 clickable2" size="28px" @click="to = ''; save();" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<q-btn class="q-px-md q-ml-sm" color="primary" dense no-caps @click="okClick">
|
||||
OK
|
||||
</q-btn>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
//-----------------------------------------------------------------------------
|
||||
import vueComponent from '../../vueComponent.js';
|
||||
|
||||
import Dialog from '../../share/Dialog.vue';
|
||||
import * as utils from '../../../share/utils';
|
||||
|
||||
const componentOptions = {
|
||||
components: {
|
||||
Dialog
|
||||
},
|
||||
watch: {
|
||||
modelValue(newValue) {
|
||||
this.dialogVisible = newValue;
|
||||
},
|
||||
dialogVisible(newValue) {
|
||||
this.$emit('update:modelValue', newValue);
|
||||
},
|
||||
date() {
|
||||
this.updateFromTo();
|
||||
},
|
||||
}
|
||||
};
|
||||
class SelectDateDialog {
|
||||
_options = componentOptions;
|
||||
_props = {
|
||||
modelValue: Boolean,
|
||||
date: String,
|
||||
};
|
||||
|
||||
dialogVisible = false;
|
||||
|
||||
from = '';
|
||||
to = '';
|
||||
|
||||
created() {
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.updateFromTo();
|
||||
}
|
||||
|
||||
updateFromTo() {
|
||||
this.from = this.splitDate.from;
|
||||
this.to = this.splitDate.to;
|
||||
}
|
||||
|
||||
get splitDate() {
|
||||
const [from = '', to = ''] = (this.date || '').split(',');
|
||||
return {from, to};
|
||||
}
|
||||
|
||||
get labelFrom() {
|
||||
return (this.splitDate.from ? utils.sqlDateFormat(this.splitDate.from) : 'Не указано');
|
||||
}
|
||||
|
||||
get labelTo() {
|
||||
return (this.splitDate.to ? utils.sqlDateFormat(this.splitDate.to) : 'Не указано');
|
||||
}
|
||||
|
||||
save() {
|
||||
let d = this.from;
|
||||
if (this.to)
|
||||
d += `,${this.to}`;
|
||||
this.$emit('update:date', d);
|
||||
}
|
||||
|
||||
okClick() {
|
||||
this.dialogVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
export default vueComponent(SelectDateDialog);
|
||||
//-----------------------------------------------------------------------------
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.clickable2 {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -3,7 +3,7 @@
|
||||
<template #header>
|
||||
<div class="row items-center">
|
||||
<div style="font-size: 130%">
|
||||
Выбрать язык
|
||||
Выбрать языки
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -224,13 +224,7 @@ class SeriesList extends BaseList {
|
||||
|
||||
async refresh() {
|
||||
//параметры запроса
|
||||
let newQuery = _.cloneDeep(this.search);
|
||||
newQuery = newQuery.setDefaults(newQuery);
|
||||
delete newQuery.setDefaults;
|
||||
newQuery.offset = (newQuery.page - 1)*newQuery.limit;
|
||||
if (!this.showDeleted)
|
||||
newQuery.del = 0;
|
||||
|
||||
const newQuery = this.getQuery();
|
||||
if (_.isEqual(newQuery, this.prevQuery))
|
||||
return;
|
||||
this.prevQuery = newQuery;
|
||||
|
||||
@@ -85,13 +85,7 @@ class TitleList extends BaseList {
|
||||
|
||||
async refresh() {
|
||||
//параметры запроса
|
||||
let newQuery = _.cloneDeep(this.search);
|
||||
newQuery = newQuery.setDefaults(newQuery);
|
||||
delete newQuery.setDefaults;
|
||||
newQuery.offset = (newQuery.page - 1)*newQuery.limit;
|
||||
if (!this.showDeleted)
|
||||
newQuery.del = 0;
|
||||
|
||||
const newQuery = this.getQuery();
|
||||
if (_.isEqual(newQuery, this.prevQuery))
|
||||
return;
|
||||
this.prevQuery = newQuery;
|
||||
|
||||
@@ -21,14 +21,15 @@ import {QIcon} from 'quasar/src/components/icon';
|
||||
//import {QTabPanels, QTabPanel} from 'quasar/src/components/tab-panels';
|
||||
//import {QSeparator} from 'quasar/src/components/separator';
|
||||
//import {QList} from 'quasar/src/components/item';
|
||||
//import {QItem, QItemSection, QItemLabel} from 'quasar/src/components/item';
|
||||
import {QItem, QItemSection, QItemLabel} from 'quasar/src/components/item';
|
||||
import {QTooltip} from 'quasar/src/components/tooltip';
|
||||
//import {QSpinner} from 'quasar/src/components/spinner';
|
||||
//import {QTable, QTh, QTr, QTd} from 'quasar/src/components/table';
|
||||
import {QCheckbox} from 'quasar/src/components/checkbox';
|
||||
import {QSelect} from 'quasar/src/components/select';
|
||||
//import {QColor} from 'quasar/src/components/color';
|
||||
//import {QPopupProxy} from 'quasar/src/components/popup-proxy';
|
||||
import {QPopupProxy} from 'quasar/src/components/popup-proxy';
|
||||
import {QDate} from 'quasar/src/components/date';
|
||||
import {QDialog} from 'quasar/src/components/dialog';
|
||||
//import {QChip} from 'quasar/src/components/chip';
|
||||
import {QTree} from 'quasar/src/components/tree';
|
||||
@@ -55,14 +56,15 @@ const components = {
|
||||
//QTabPanels, QTabPanel,
|
||||
//QSeparator,
|
||||
//QList,
|
||||
//QItem, QItemSection, QItemLabel,
|
||||
QItem, QItemSection, QItemLabel,
|
||||
QTooltip,
|
||||
//QSpinner,
|
||||
//QTable, QTh, QTr, QTd,
|
||||
QCheckbox,
|
||||
QSelect,
|
||||
//QColor,
|
||||
//QPopupProxy,
|
||||
QPopupProxy,
|
||||
QDate,
|
||||
QDialog,
|
||||
//QChip,
|
||||
QTree,
|
||||
@@ -91,12 +93,13 @@ const plugins = {
|
||||
//import '@quasar/extras/fontawesome-v5/fontawesome-v5.css';
|
||||
//import fontawesomeV5 from 'quasar/icon-set/fontawesome-v5.js'
|
||||
|
||||
import lang from 'quasar/lang/ru';
|
||||
import '@quasar/extras/line-awesome/line-awesome.css';
|
||||
import lineAwesome from 'quasar/icon-set/line-awesome.js'
|
||||
|
||||
export default {
|
||||
quasar: Quasar,
|
||||
options: { config, components, directives, plugins },
|
||||
options: { config, components, directives, plugins, lang },
|
||||
init: () => {
|
||||
Quasar.iconSet.set(lineAwesome);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import moment from 'moment';
|
||||
import {Buffer} from 'safe-buffer';
|
||||
//import _ from 'lodash';
|
||||
|
||||
@@ -98,7 +99,7 @@ export function makeValidFilename(filename, repl = '_') {
|
||||
else
|
||||
throw new Error('Invalid filename');
|
||||
}
|
||||
|
||||
/*
|
||||
export function formatDate(d, format = 'normal') {
|
||||
switch (format) {
|
||||
case 'normal':
|
||||
@@ -124,4 +125,17 @@ export function parseDate(sqlDate) {
|
||||
result.setYear(parseInt(d[0], 10));
|
||||
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
|
||||
export function isDigit(c) {
|
||||
return !isNaN(parseInt(c, 10));
|
||||
}
|
||||
|
||||
export function dateFormat(date, format = 'DD.MM.YYYY') {
|
||||
return moment(date).format(format);
|
||||
}
|
||||
|
||||
export function sqlDateFormat(date, format = 'DD.MM.YYYY') {
|
||||
return moment(date, 'YYYY-MM-DD').format(format);
|
||||
}
|
||||
Reference in New Issue
Block a user