[Vue3] Fixed usage of value vs modelValue

This commit is contained in:
Ferdinand Thiessen 2021-02-02 01:28:23 +01:00
parent cb68f9ff7e
commit d3d8c1e5f2
7 changed files with 73 additions and 104 deletions

View File

@ -233,8 +233,7 @@ export default boot<UserSessionState>(({ router, store, app }) => {
};
// get all plugins
//const pluginsContext = require.context('src/plugins', true, /.+\/plugin.ts$/);
const pluginsContext = require['context']('src/plugins', true, /.+\/plugin.ts$/);
const pluginsContext = require.context('src/plugins', true, /.+\/plugin.ts$/);
pluginsContext.keys().forEach((fileName: string) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
plugins.push(pluginsContext(fileName).default);

View File

@ -1,17 +1,16 @@
<template>
<q-input
v-model="dateTime"
filled
:readonly="readonly"
:label="label"
:value="getDateTime()"
:placeholder="placeholder"
:rules="customRules"
@input="dateTimeChanged"
>
<template #append>
<q-icon v-if="type == 'date' || type == 'datetime'" name="event" class="cursor-pointer">
<q-popup-proxy ref="qDateProxy" transition-show="scale" transition-hide="scale">
<q-date :value="getDate()" mask="YYYY-MM-DD" @input="dateChanged">
<q-date :model-value="getDate()" mask="YYYY-MM-DD" @input="dateChanged">
<div class="row items-center justify-end">
<q-btn v-close-popup label="Schließen" color="primary" flat />
</div>
@ -24,7 +23,7 @@
class="cursor-pointer"
>
<q-popup-proxy ref="qTimeProxy" transition-show="scale" transition-hide="scale">
<q-time :value="getTime()" mask="HH:mm" @input="timeChanged">
<q-time :model-value="getTime()" mask="HH:mm" @update:modelValue="timeChanged">
<div class="row items-center justify-end">
<q-btn v-close-popup label="Schließen" color="primary" flat />
</div>
@ -37,12 +36,12 @@
<script lang="ts">
import { computed, defineComponent, ref, PropType } from 'vue';
import { date } from 'quasar';
import { date as q_date } from 'quasar';
export default defineComponent({
name: 'IsoDateInput',
props: {
value: { type: String, required: true },
modelValue: { type: Date, default: new Date() },
type: {
type: String,
default: 'date',
@ -57,33 +56,6 @@ export default defineComponent({
},
emits: { input: (date: string) => date.length > 5 },
setup(props, { emit }) {
function getDateTime() {
if (typeof props.value == 'object') {
switch (props.type) {
case 'date':
return getDate();
case 'time':
return getTime();
case 'datetime':
return `${getDate()} ${getTime()}`;
}
}
return props.value;
}
function getDate() {
if (typeof props.value == 'object') {
return date.formatDate(props.value, 'YYYY-MM-DD');
}
return '';
}
function getTime() {
if (typeof props.value == 'object') {
return date.formatDate(props.value, 'HH:mm');
}
return '';
}
const _date = ref('');
const _time = ref('');
const placeholder = computed(() => {
@ -98,34 +70,21 @@ export default defineComponent({
throw 'Invalid type given';
});
function dateChanged(dateString: string) {
_date.value = dateString;
console.log(dateString);
if (/^\d{4}-\d\d-\d\d$/.test(dateString)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', new Date(`${_date.value} ${_time.value}`).toISOString());
} else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', dateString);
const dateTime = computed({
get() {
if (typeof props.modelValue == 'object') {
switch (props.type) {
case 'date':
return getDate();
case 'time':
return getTime();
case 'datetime':
return `${getDate()} ${getTime()}`;
}
}
function timeChanged(timeString: string) {
_time.value = timeString;
if (_date.value == '') {
_date.value = date.formatDate(new Date(), 'YYYY-MM-DD');
}
if (/^\d\d:\d\d$/.test(timeString)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', new Date(`${_date.value} ${_time.value}`).toISOString());
} else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', timeString);
}
}
function dateTimeChanged(dateTimeString: string) {
return props.modelValue;
},
set(dateTimeString: string) {
switch (props.type) {
case 'date':
dateChanged(dateTimeString);
@ -140,13 +99,48 @@ export default defineComponent({
console.log(dateTimeString, _dateTime);
if (/^\d{4}-\d\d-\d\d \d\d:\d\d$/.test(dateTimeString)) {
console.log('dateTimeChanged');
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', new Date(`${_date.value} ${_time.value}`).toISOString());
} else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('input', dateTimeString);
}
}
},
});
function dateChanged(dateString: string) {
_date.value = dateString;
console.log(dateString);
if (/^\d{4}-\d\d-\d\d$/.test(dateString)) {
emit('input', new Date(`${_date.value} ${_time.value}`).toISOString());
} else {
emit('input', dateString);
}
}
function timeChanged(timeString: string) {
_time.value = timeString;
if (_date.value == '') {
_date.value = q_date.formatDate(new Date(), 'YYYY-MM-DD');
}
if (/^\d\d:\d\d$/.test(timeString)) {
emit('input', new Date(`${_date.value} ${_time.value}`).toISOString());
} else {
emit('input', timeString);
}
}
function getDate() {
if (typeof props.modelValue == 'object') {
return q_date.formatDate(props.modelValue, 'YYYY-MM-DD');
}
return '';
}
function getTime() {
if (typeof props.modelValue == 'object') {
return q_date.formatDate(props.modelValue, 'HH:mm');
}
return '';
}
function isDate(val: string) {
@ -161,33 +155,19 @@ 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 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 {
dateTime,
getDate,
getTime,
getDateTime,
dateChanged,
customRules,
timeChanged,
placeholder,
dateTimeChanged,
};
},
});

View File

@ -3,7 +3,7 @@
<q-card-section class="fit row justify-start content-center items-center">
<div class="col-xs-12 col-sm-6 text-center text-h6">Benutzereinstellungen</div>
<div class="col-xs-12 col-sm-6 q-pa-sm">
<UserSelector :user="user" @update:user="userUpdated" />
<UserSelector v-model="user" />
</div>
</q-card-section>
<MainUserSettings :user="user" @update:user="updateUser" />
@ -24,12 +24,6 @@ export default defineComponent({
const store = useStore<UserSessionState>();
const user = ref(<FG.User>store.state.users.currentUser);
// can be dropped with VUE3
const userUpdated = (value: FG.User) => {
user.value = value;
console.log(value);
};
function updateUser(value: FG.User) {
store.dispatch('users/updateUser', value).catch((error) => {
console.warn(error);
@ -38,7 +32,6 @@ export default defineComponent({
return {
user,
userUpdated,
updateUser,
};
},

View File

@ -1,18 +1,17 @@
<template>
<q-select
v-model="selected"
filled
:label="label"
:value="modelValue"
:options="users"
option-label="display_name"
option-value="userid"
map-options
@input="updated"
/>
</template>
<script lang="ts">
import { computed, defineComponent, Prop, onBeforeMount } from 'vue';
import { computed, defineComponent, PropType, onBeforeMount } from 'vue';
import { useStore } from 'vuex';
import { UserSessionState } from '../store';
@ -20,10 +19,10 @@ export default defineComponent({
name: 'UserSelector',
props: {
label: { type: String, default: 'Benutzer' },
modelValue: { required: true, type: Object } as Prop<FG.User>,
modelValue: { required: true, type: Object as PropType<FG.User> },
},
emits: { 'update:modelValue': (user: FG.User) => !!user },
setup(_, { emit }) {
setup(props, { emit }) {
const store = useStore<UserSessionState>();
onBeforeMount(() => {
@ -33,12 +32,13 @@ export default defineComponent({
});
const users = computed(() => store.state.users.users);
const updated = (value: FG.User) => {
emit('update:modelValue', value);
};
const selected = computed({
get: () => props.modelValue,
set: (value: FG.User) => emit('update:modelValue', value),
});
return {
updated,
selected,
users,
};
},

View File

@ -112,7 +112,7 @@ import { Notify } from 'quasar';
import { UserSessionState } from '../../store';
import { hasPermission } from 'src/utils/permission';
import IsoDateInput from 'src/components/utils/IsoDateInput.vue';
import { defineComponent, computed, ref, onBeforeMount, Prop } from 'vue';
import { defineComponent, computed, ref, onBeforeMount, PropType } from 'vue';
export default defineComponent({
name: 'MainUserSettings',
@ -120,8 +120,8 @@ export default defineComponent({
props: {
user: {
required: true,
type: Object,
} as Prop<FG.User>,
type: Object as PropType<FG.User>,
},
newUser: { type: Boolean, required: true },
},
emits: {
@ -138,7 +138,7 @@ export default defineComponent({
});
const isCurrentUser = computed(
() => user_model.value?.userid === store.state.users.currentUser?.userid
() => user_model.value.userid === store.state.users.currentUser?.userid
);
const canSetRoles = computed(() => hasPermission('users_set_roles'));
@ -162,7 +162,7 @@ export default defineComponent({
const new_password2 = ref('');
function save() {
let changed = <FG.User>user_model.value;
let changed = user_model.value;
if (typeof changed.birthday === 'string') changed.birthday = new Date(changed.birthday);
changed = Object.assign(changed, {
password: password.value,
@ -173,8 +173,6 @@ export default defineComponent({
});
}
// TODO: investigate this issue
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('update:user', changed);
if (avatar.value && (avatar.value.length > 0 || avatar.value instanceof File))

View File

@ -10,14 +10,14 @@
label="Rolle"
input-debounce="0"
class="col-xs-12 col-sm-6 q-pa-sm"
:value="role"
:model-value="role"
:options="roles"
option-label="name"
option-value="name"
map-options
clearable
@new-value="createRole"
@input="updateRole"
@update:modelValue="updateRole"
@clear="removeRole"
/>
</q-card-section>
@ -26,7 +26,7 @@
<q-scroll-area style="height: 20em; width: 100%">
<q-input v-if="role.id != -1" v-model="newRoleName" filled label="neuer Name" />
<q-option-group
:value="role.permissions"
:model-value="role.permissions"
:options="permissions"
color="primary"
type="checkbox"

View File

@ -9,7 +9,6 @@ export interface LoginResponse {
permissions: FG.Permission[];
}
//eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
export interface CurrentUserResponse extends FG.User {
permissions: FG.Permission[];
}