Fixed IsoDateInput and Rulevalidation + CreateEvent Validation

This commit is contained in:
Dominik 2021-01-28 00:55:17 +01:00
parent 663d1d3e4d
commit 1dc0603df3
3 changed files with 243 additions and 86 deletions

View File

@ -6,7 +6,7 @@
:value="getDateTime()" :value="getDateTime()"
:placeholder="placeholder" :placeholder="placeholder"
v-on:input="dateTimeChanged" v-on:input="dateTimeChanged"
:rules="rules" :rules="customRules"
> >
<template v-slot:append> <template v-slot:append>
<q-icon name="event" class="cursor-pointer" v-if="type == 'date' || type == 'datetime'"> <q-icon name="event" class="cursor-pointer" v-if="type == 'date' || type == 'datetime'">
@ -43,6 +43,7 @@ interface Props {
label?: string; label?: string;
readonly: boolean; readonly: boolean;
type: string; type: string;
rules: Array<any>;
} }
export default defineComponent({ export default defineComponent({
@ -60,11 +61,14 @@ export default defineComponent({
validator: function(value: string) { validator: function(value: string) {
return ['date', 'time', 'datetime'].indexOf(value) !== -1; return ['date', 'time', 'datetime'].indexOf(value) !== -1;
} }
},
rules: {
default: []
} }
}, },
setup(props: Props, { emit }: { emit: any }) { setup(props: Props, { emit }: { emit: any }) {
function getDateTime() { function getDateTime() {
if (props.value) { if (typeof props.value == 'object') {
switch (props.type) { switch (props.type) {
case 'date': case 'date':
return getDate(); return getDate();
@ -74,16 +78,17 @@ export default defineComponent({
return `${getDate()} ${getTime()}`; return `${getDate()} ${getTime()}`;
} }
} }
return props.value;
} }
function getDate() { function getDate() {
if (props.value) { if (typeof props.value == 'object') {
return date.formatDate(props.value, 'YYYY-MM-DD'); return date.formatDate(props.value, 'YYYY-MM-DD');
} }
return ''; return '';
} }
function getTime() { function getTime() {
if (props.value) { if (typeof props.value == 'object') {
return date.formatDate(props.value, 'HH:mm'); return date.formatDate(props.value, 'HH:mm');
} }
return ''; return '';
@ -95,7 +100,6 @@ export default defineComponent({
switch (props.type) { switch (props.type) {
case 'date': case 'date':
return 'YYYY-MM-DD'; return 'YYYY-MM-DD';
break;
case 'time': case 'time':
return 'HH:mm'; return 'HH:mm';
case 'datetime': case 'datetime':
@ -108,11 +112,11 @@ export default defineComponent({
console.log(dateString); console.log(dateString);
if (/^\d{4}-\d\d-\d\d$/.test(dateString)) { if (/^\d{4}-\d\d-\d\d$/.test(dateString)) {
console.log('dateChanged', new Date(`${_date.value} ${_time.value}`));
// eslint-disable-next-line @typescript-eslint/no-unsafe-call // eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', new Date(`${_date.value} ${_time.value}`)); emit('input', new Date(`${_date.value} ${_time.value}`));
} else { } else {
console.log('no date'); // eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', dateString);
} }
} }
@ -122,9 +126,11 @@ export default defineComponent({
_date.value = date.formatDate(new Date(), 'YYYY-MM-DD'); _date.value = date.formatDate(new Date(), 'YYYY-MM-DD');
} }
if (/^\d\d:\d\d$/.test(timeString)) { if (/^\d\d:\d\d$/.test(timeString)) {
console.log('timeChanged', new Date(`${_date.value} ${_time.value}`));
// eslint-disable-next-line @typescript-eslint/no-unsafe-call // eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', new Date(`${_date.value} ${_time.value}`)); emit('input', new Date(`${_date.value} ${_time.value}`));
} else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', timeString);
} }
} }
@ -145,6 +151,9 @@ export default defineComponent({
console.log('dateTimeChanged'); console.log('dateTimeChanged');
// eslint-disable-next-line @typescript-eslint/no-unsafe-call // eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', new Date(`${_date.value} ${_time.value}`)); emit('input', new Date(`${_date.value} ${_time.value}`));
} else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', dateTimeString);
} }
} }
} }
@ -161,26 +170,30 @@ export default defineComponent({
return !val || /^\d{4}-\d\d-\d\d \d\d:\d\d$/.test(val) || 'Datum und Zeit ist nicht gültig.'; return !val || /^\d{4}-\d\d-\d\d \d\d:\d\d$/.test(val) || 'Datum und Zeit ist nicht gültig.';
} }
const rules = computed(() => { // const customRules = computed(() => {
switch (props.type) { // const _rules = props.rules;
case 'date': // switch (props.type) {
return [isDate]; // case 'date':
break; // _rules.push(isDate);
case 'time': // case 'time':
return [isTime]; // _rules.push(isTime);
break; // case 'datetime':
case 'datetime': // _rules.push(isDateTime);
return [isDateTime]; // }
break; // });
}
}); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const customRules = [
props.type == 'date' ? isDate : props.type == 'time' ? isTime : isDateTime,
...props.rules
];
return { return {
getDate, getDate,
getTime, getTime,
getDateTime, getDateTime,
dateChanged, dateChanged,
rules, customRules,
timeChanged, timeChanged,
placeholder, placeholder,
dateTimeChanged dateTimeChanged

View File

@ -26,67 +26,32 @@
label="Veranstaltungsbeginn" label="Veranstaltungsbeginn"
:rules="[noValidDate, notEmpty]" :rules="[noValidDate, notEmpty]"
/> />
<q-card-section class="fit justify-start content-center items-center"> </q-card-section>
<q-input <q-card-section class="fit justify-start content-center items-center">
class="col-xs-12 col-sm-6 q-pa-sm" <q-input
label="Beschreibung" class="col-xs-12 col-sm-6 q-pa-sm"
type="textarea" label="Beschreibung"
v-model="event.description" type="textarea"
filled v-model="event.description"
/> filled
</q-card-section> />
</q-card-section> </q-card-section>
<q-card-section> <q-card-section>
<q-btn color="primary" label="Schicht hinzufügen" @click="addJob()" /> <q-btn color="primary" label="Schicht hinzufügen" @click="addJob()" />
</q-card-section> </q-card-section>
<q-card-section v-for="job in event.jobs" v-bind:key="job.id"> <q-card-section v-for="(job, index) in event.jobs" v-bind:key="index">
<q-card class="q-my-auto"> <q-card class="q-my-auto">
<q-card-section class="fit row justify-start content-center items-center"> <job
<IsoDateInput :job="job"
class="col-xs-12 col-sm-6 q-pa-sm" :jobCanDelete="jobDeleteDisabled"
v-model="job.start" @setStart="setStart"
label="Beginn" @setRequired="setRequired"
type="datetime" @setEnd="setEnd"
:rules="[noValidDate, notEmpty]" @setComment="setComment"
/> @setJobType="setJobType"
<IsoDateInput @removeJob="removeJob(index)"
class="col-xs-12 col-sm-6 q-pa-sm" />
v-model="job.end"
label="Ende"
type="datetime"
:rules="[noValidDate, isAfterDate, notEmpty]"
/>
<q-input
class="col-xs-12 col-sm-6 q-pa-sm"
label="Beschreibung"
type="textarea"
v-model="job.comment"
filled
:rules="[notEmpty]"
/>
<q-select
filled
use-input
label="Dienstart"
input-debounce="0"
class="col-xs-12 col-sm-6 q-pa-sm"
v-model="job.type"
:options="jobtypes"
option-label="name"
option-value="name"
map-options
clearable
:rules="[notEmpty]"
/>
<q-input label="Dienstanzahl" type="number" v-model="job.required_services" filled />
<q-btn
label="Schicht löschen"
color="negative"
@click="removeJob(job.id)"
:disabled="jobDeleteDisabled"
/>
</q-card-section>
</q-card> </q-card>
</q-card-section> </q-card-section>
<q-card-actions align="right"> <q-card-actions align="right">
@ -101,6 +66,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, ref, onBeforeMount, computed } from '@vue/composition-api'; import { defineComponent, ref, onBeforeMount, computed } from '@vue/composition-api';
import IsoDateInput from 'src/components/utils/IsoDateInput.vue'; import IsoDateInput from 'src/components/utils/IsoDateInput.vue';
import Job from './Job.vue';
import { Store } from 'vuex'; import { Store } from 'vuex';
import { StateInterface } from 'src/store'; import { StateInterface } from 'src/store';
import { ScheduleInterface } from '../../store/schedule'; import { ScheduleInterface } from '../../store/schedule';
@ -108,12 +74,11 @@ import { date } from 'quasar';
// import { emit } from 'process'; // import { emit } from 'process';
export default defineComponent({ export default defineComponent({
name: 'CreateEvent', name: 'CreateEvent',
components: { IsoDateInput }, components: { IsoDateInput, Job },
setup(_, { root }) { setup(_, { root }) {
const store = <Store<StateInterface>>root.$store; const store = <Store<StateInterface>>root.$store;
const state = <ScheduleInterface>store.state.schedule; const state = <ScheduleInterface>store.state.schedule;
const eventtypes = computed(() => state.eventTypes); const eventtypes = computed(() => state.eventTypes);
const jobtypes = computed(() => state.jobTypes);
const jobDeleteDisabled = computed(() => event.value.jobs.length < 2); const jobDeleteDisabled = computed(() => event.value.jobs.length < 2);
const newJob = ref<FG.Job>(({ const newJob = ref<FG.Job>(({
@ -137,17 +102,42 @@ export default defineComponent({
void store.dispatch('schedule/getJobTypes'); void store.dispatch('schedule/getJobTypes');
}); });
function setStart(data: { job: FG.Job; value: Date }) {
data.job.start = data.value;
}
function setEnd(data: { job: FG.Job; value: Date }) {
data.job.end = data.value;
}
function setComment(data: { job: FG.Job; value: string }) {
data.job.comment = data.value;
}
function setJobType(data: { job: FG.Job; value: FG.JobType }) {
data.job.type = data.value;
}
function setRequired(data: { job: FG.Job; value: number }) {
data.job.required_services = data.value;
}
function addJob() { function addJob() {
const addJob = Object.assign({}, newJob.value); const addJob = Object.assign({}, newJob.value);
event.value.jobs.unshift(addJob); event.value.jobs.unshift(addJob);
} }
function removeJob(id: number) { //function removeJob(id: number) {
let jobtoremove = event.value.jobs.findIndex(job => job.id == id); // let jobtoremove = event.value.jobs.findIndex(job => job.id == id);
if (jobtoremove != undefined) { // if (jobtoremove != undefined) {
event.value.jobs.splice(jobtoremove, 1); // event.value.jobs.splice(jobtoremove, 1);
} // }
//}
function removeJob(index: number) {
event.value.jobs.splice(index, 1);
} }
function save() { function save() {
console.log('Event:', event); console.log('Event:', event);
store.dispatch('schedule/addEvent', event.value).catch(error => { store.dispatch('schedule/addEvent', event.value).catch(error => {
@ -177,13 +167,17 @@ export default defineComponent({
addJob, addJob,
eventtypes, eventtypes,
removeJob, removeJob,
jobtypes,
notEmpty, notEmpty,
noValidDate, noValidDate,
save, save,
reset, reset,
event, event,
isAfterDate isAfterDate,
setStart,
setEnd,
setComment,
setJobType,
setRequired
}; };
} }
}); });

View File

@ -0,0 +1,150 @@
<template>
<q-card-section class="fit row justify-start content-center items-center">
<q-card-section class="fit row justify-start content-center items-center">
<IsoDateInput
class="col-xs-12 col-sm-6 q-pa-sm"
:value="job.start"
v-on:input="setStart"
label="Beginn"
type="datetime"
:rules="[noValidDate, notEmpty]"
/>
<IsoDateInput
ref="bla"
class="col-xs-12 col-sm-6 q-pa-sm"
:value="job.end"
v-on:input="setEnd"
label="Ende"
type="datetime"
:rules="[noValidDate, isAfterDate, notEmpty]"
/>
</q-card-section>
<q-card-section class=" row fit justify-start content-center items-center">
<q-select
filled
use-input
label="Dienstart"
input-debounce="0"
class="col-xs-12 col-sm-6 q-pa-sm"
:value="job.type"
:options="jobtypes"
v-on:input="setJobType"
option-label="name"
option-value="name"
map-options
clearable
:rules="[notEmpty]"
/>
<q-input
filled
class="col-xs-12 col-sm-6 q-pa-sm"
label="Dienstanzahl"
type="number"
:value="job.required_services"
@input="setRequired"
:rules="[notEmpty]"
/>
</q-card-section>
<q-card-section class="fit row justify-start content-center items-center">
<q-input
class="col-xs-12 col-sm-6 q-pa-sm"
label="Beschreibung"
type="textarea"
:value="job.comment"
v-on:input="setComment"
filled
:rules="[notEmpty]"
/>
</q-card-section>
<q-btn label="Schicht löschen" color="negative" @click="removeJob" :disabled="jobCanDelete" />
</q-card-section>
</template>
<script lang="ts">
import { defineComponent, computed } from '@vue/composition-api';
import IsoDateInput from 'src/components/utils/IsoDateInput.vue';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
import { ScheduleInterface } from '../../store/schedule';
import { date } from 'quasar';
interface Props {
job: FG.Job;
jobCanDelete: boolean;
}
export default defineComponent({
name: 'Job',
components: { IsoDateInput },
props: {
job: {
required: true
},
jobCanDelete: {
default: false
}
},
setup(props: Props, { root, emit }) {
const store = <Store<StateInterface>>root.$store;
const state = <ScheduleInterface>store.state.schedule;
const jobtypes = computed(() => state.jobTypes);
function setStart(value: Date) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('setStart', { job: props.job, value });
}
function setEnd(value: Date) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('setEnd', { job: props.job, value });
}
function setComment(value: string) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('setComment', { job: props.job, value });
}
function setJobType(value: FG.JobType) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
console.log('setJobType', value);
emit('setJobType', { job: props.job, value });
}
function setRequired(value: number) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('setRequired', { job: props.job, value });
}
function removeJob() {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('removeJob');
}
function notEmpty(val: string) {
return !!val || 'Feld darf nicht leer sein!';
}
function noValidDate(val: string) {
console.log(val);
return !!date.isValid(val) || 'Datum/Zeit muss gesetzt sein!';
}
function isAfterDate(val: Date) {
console.log('isAfterDate', props.job.start, val);
return props.job.start < new Date(val) || 'Ende muss hinter dem Start liegen';
}
return {
jobtypes,
setStart,
setEnd,
setComment,
setJobType,
setRequired,
removeJob,
notEmpty,
noValidDate,
isAfterDate
};
}
});
</script>
<style></style>