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()"
:placeholder="placeholder"
v-on:input="dateTimeChanged"
:rules="rules"
:rules="customRules"
>
<template v-slot:append>
<q-icon name="event" class="cursor-pointer" v-if="type == 'date' || type == 'datetime'">
@ -43,6 +43,7 @@ interface Props {
label?: string;
readonly: boolean;
type: string;
rules: Array<any>;
}
export default defineComponent({
@ -60,11 +61,14 @@ export default defineComponent({
validator: function(value: string) {
return ['date', 'time', 'datetime'].indexOf(value) !== -1;
}
},
rules: {
default: []
}
},
setup(props: Props, { emit }: { emit: any }) {
function getDateTime() {
if (props.value) {
if (typeof props.value == 'object') {
switch (props.type) {
case 'date':
return getDate();
@ -74,16 +78,17 @@ export default defineComponent({
return `${getDate()} ${getTime()}`;
}
}
return props.value;
}
function getDate() {
if (props.value) {
if (typeof props.value == 'object') {
return date.formatDate(props.value, 'YYYY-MM-DD');
}
return '';
}
function getTime() {
if (props.value) {
if (typeof props.value == 'object') {
return date.formatDate(props.value, 'HH:mm');
}
return '';
@ -95,7 +100,6 @@ export default defineComponent({
switch (props.type) {
case 'date':
return 'YYYY-MM-DD';
break;
case 'time':
return 'HH:mm';
case 'datetime':
@ -108,11 +112,11 @@ export default defineComponent({
console.log(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
emit('input', new Date(`${_date.value} ${_time.value}`));
} 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');
}
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
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');
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
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.';
}
const rules = computed(() => {
switch (props.type) {
case 'date':
return [isDate];
break;
case 'time':
return [isTime];
break;
case 'datetime':
return [isDateTime];
break;
}
});
// const customRules = computed(() => {
// const _rules = props.rules;
// switch (props.type) {
// case 'date':
// _rules.push(isDate);
// case 'time':
// _rules.push(isTime);
// case 'datetime':
// _rules.push(isDateTime);
// }
// });
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const customRules = [
props.type == 'date' ? isDate : props.type == 'time' ? isTime : isDateTime,
...props.rules
];
return {
getDate,
getTime,
getDateTime,
dateChanged,
rules,
customRules,
timeChanged,
placeholder,
dateTimeChanged

View File

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