Sync, improved IsoDateInput, composeable

* Synchronized with backend definitions
* Improved IsoDateInput to support clear (undefined model)
* Split validators to reuse them instead of redefine everywhere
This commit is contained in:
Ferdinand Thiessen 2021-03-20 17:11:51 +01:00
parent b8531ad816
commit 0b255c481a
4 changed files with 83 additions and 52 deletions

View File

@ -6,9 +6,11 @@
:label="label" :label="label"
:placeholder="placeholder" :placeholder="placeholder"
:rules="customRules" :rules="customRules"
:clearable="clearable"
@clear="dateTime = ''"
> >
<template #append> <template #append>
<q-icon v-if="type == 'date' || type == 'datetime'" name="event" class="cursor-pointer"> <q-icon v-if="'date' || type == 'datetime'" name="event" class="cursor-pointer">
<q-popup-proxy ref="qDateProxy" transition-show="scale" transition-hide="scale"> <q-popup-proxy ref="qDateProxy" transition-show="scale" transition-hide="scale">
<q-date v-model="date" mask="YYYY-MM-DD"> <q-date v-model="date" mask="YYYY-MM-DD">
<div class="row items-center justify-end"> <div class="row items-center justify-end">
@ -37,11 +39,12 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, PropType } from 'vue'; import { computed, defineComponent, PropType } from 'vue';
import { date as q_date } from 'quasar'; import { date as q_date } from 'quasar';
import { stringIsDate, stringIsTime, stringIsDateTime } from 'src/utils/validators';
export default defineComponent({ export default defineComponent({
name: 'IsoDateInput', name: 'IsoDateInput',
props: { props: {
modelValue: { type: Object as PropType<Date>, default: new Date() }, modelValue: { type: Object as PropType<Date | undefined>, default: undefined },
type: { type: {
type: String, type: String,
default: 'date', default: 'date',
@ -50,12 +53,21 @@ export default defineComponent({
label: { type: String, default: 'Datum' }, label: { type: String, default: 'Datum' },
readonly: Boolean, readonly: Boolean,
rules: { rules: {
type: Array as PropType<unknown[]>, type: Array as PropType<Validator[]>,
default: () => [], default: () => [],
}, },
}, },
emits: { 'update:modelValue': (date: Date) => !!date }, emits: { 'update:modelValue': (date?: Date) => !!date || !date },
setup(props, { emit }) { setup(props, { emit }) {
const customRules = computed(() => [
props.type == 'date' ? stringIsDate : props.type == 'time' ? stringIsTime : stringIsDateTime,
...props.rules,
]);
const clearable = computed(() =>
customRules.value.every((r) => (<Validator>r)(undefined) === true)
);
const placeholder = computed(() => { const placeholder = computed(() => {
switch (props.type) { switch (props.type) {
case 'date': case 'date':
@ -85,8 +97,9 @@ export default defineComponent({
}); });
const dateTime = computed({ const dateTime = computed({
get: () => q_date.formatDate(props.modelValue, placeholder.value), get: () => (props.modelValue ? q_date.formatDate(props.modelValue, placeholder.value) : ''),
set: (v: string) => { set: (v: string) => {
if (!v) emit('update:modelValue', undefined);
switch (props.type) { switch (props.type) {
case 'date': case 'date':
date.value = v; date.value = v;
@ -113,7 +126,8 @@ export default defineComponent({
} }
function modifyDate(v: string, d: Date | undefined = props.modelValue) { function modifyDate(v: string, d: Date | undefined = props.modelValue) {
if (d && /^\d{4}-\d\d-\d\d$/.test(v)) { if (!d) d = new Date();
if (/^\d{4}-\d\d-\d\d$/.test(v)) {
const split = v.split('-'); const split = v.split('-');
return q_date.adjustDate(d, { return q_date.adjustDate(d, {
year: +split[0], year: +split[0],
@ -123,24 +137,8 @@ export default defineComponent({
} }
} }
function isDate(val: string) {
return !val || /^\d{4}-\d\d-\d\d$/.test(val) || 'Datum ist nicht gültig.';
}
function isTime(val: string) {
return !val || /^\d\d:\d\d$/.test(val) || 'Zeit ist nicht gültig.';
}
function isDateTime(val: string) {
return !val || /^\d{4}-\d\d-\d\d \d\d:\d\d$/.test(val) || 'Datum und Zeit ist nicht gültig.';
}
const customRules = [
props.type == 'date' ? isDate : props.type == 'time' ? isTime : isDateTime,
...props.rules,
];
return { return {
clearable,
date, date,
time, time,
dateTime, dateTime,

View File

@ -34,6 +34,49 @@ declare namespace FG {
original_id?: number; original_id?: number;
receiver_id?: string; receiver_id?: string;
} }
interface Event {
id: number;
start: Date;
end?: Date;
description?: string;
type: EventType | number;
jobs: Array<Job>;
recurrence_rule?: RecurrenceRule;
template_id?: number;
}
interface EventType {
id: number;
name: string;
}
interface Invite {
id: number;
job_id: number;
invitee_id: string;
sender_id: string;
}
interface Job {
id: number;
start: Date;
end?: Date;
type: JobType | number;
comment?: string;
services: Array<Service>;
required_services: number;
}
interface JobType {
id: number;
name: string;
}
interface RecurrenceRule {
frequency: string;
until?: Date;
count?: number;
interval: number;
}
interface Service {
userid: string;
value: number;
}
interface Drink { interface Drink {
id: number; id: number;
article_id?: string; article_id?: string;
@ -86,33 +129,4 @@ declare namespace FG {
id: number; id: number;
name: string; name: string;
} }
interface Event {
id: number;
start: Date;
end?: Date;
description?: string;
type: EventType | number;
jobs: Array<Job>;
}
interface EventType {
id: number;
name: string;
}
interface Job {
id: number;
start: Date;
end?: Date;
type: JobType | number;
comment?: string;
services: Array<Service>;
required_services: number;
}
interface JobType {
id: number;
name: string;
}
interface Service {
userid: string;
value: number;
}
} }

4
src/plugins.d.ts vendored
View File

@ -1,6 +1,10 @@
import { RouteRecordRaw } from 'vue-router'; import { RouteRecordRaw } from 'vue-router';
import { Component, ComputedRef } from 'vue'; import { Component, ComputedRef } from 'vue';
declare global {
type Validator = (value: unknown) => boolean | string;
}
declare namespace FG_Plugin { declare namespace FG_Plugin {
interface ShortCutLink { interface ShortCutLink {
link: string; link: string;

15
src/utils/validators.ts Normal file
View File

@ -0,0 +1,15 @@
export function notEmpty(val: unknown) {
return !!val || 'Feld darf nicht leer sein!';
}
export function stringIsDate(val: string) {
return !val || /^\d{4}-\d\d-\d\d$/.test(val) || 'Datum ist nicht gültig.';
}
export function stringIsTime(val: string) {
return !val || /^\d\d:\d\d$/.test(val) || 'Zeit ist nicht gültig.';
}
export function stringIsDateTime(val: string) {
return !val || /^\d{4}-\d\d-\d\d \d\d:\d\d$/.test(val) || 'Datum und Zeit ist nicht gültig.';
}