Работа над диалогом выбора даты

This commit is contained in:
Book Pauk
2022-10-31 20:38:35 +07:00
parent bcd0308641
commit 8982b3eaf0
10 changed files with 301 additions and 40 deletions

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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() {

View File

@@ -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);

View 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>

View File

@@ -3,7 +3,7 @@
<template #header>
<div class="row items-center">
<div style="font-size: 130%">
Выбрать язык
Выбрать языки
</div>
</div>
</template>

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);
}