flaschengeist-frontend/src/plugins/user/components/settings/MainUserSettings.vue

241 lines
6.5 KiB
Vue
Raw Normal View History

<template>
2020-11-18 02:11:34 +00:00
<q-form @submit="save" @reset="reset">
<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="Vorname"
:rules="[notEmpty]"
v-model="user_model.firstname"
filled
/>
<q-input
class="col-xs-12 col-sm-6 q-pa-sm"
label="Nachname"
:rules="[notEmpty]"
v-model="user_model.lastname"
filled
/>
2020-11-15 18:47:05 +00:00
<q-input
class="col-xs-12 col-sm-6 q-pa-sm"
2020-11-15 18:47:05 +00:00
label="Angezeigter Name"
:rules="[notEmpty]"
v-model="user_model.display_name"
filled
/>
<q-input
class="col-xs-12 col-sm-6 q-pa-sm"
label="E-Mail"
:rules="[isEmail, notEmpty]"
v-model="user_model.mail"
filled
/>
<q-input
class="col-xs-12 col-sm-6 q-pa-sm"
2020-11-15 18:47:05 +00:00
label="Benutzername"
:readonly="!newUser"
v-model="user_model.userid"
2020-11-15 18:47:05 +00:00
:rules="[isUseridUsed, notEmpty]"
filled
/>
<q-select
class="col-xs-12 col-sm-6 q-pa-sm"
label="Rollen"
filled
multiple
use-chips
v-model="user_model.roles"
:readonly="!canSetRoles"
:options="allRoles"
option-label="name"
option-value="name"
/>
2020-11-15 18:47:05 +00:00
<IsoDateInput
2020-11-16 01:28:03 +00:00
class="col-xs-12 col-sm-6 q-pa-sm"
v-model="user_model.birthday"
2020-11-15 18:47:05 +00:00
label="Geburtstag"
/>
2020-11-16 01:28:03 +00:00
<q-file
class="col-xs-12 col-sm-6 q-pa-sm"
v-model="avatar"
filled
label="Avatar"
accept=".jpg, image/*"
max-file-size="204800"
hint="Bilddateien, max. 200 KiB"
2020-11-16 01:28:03 +00:00
@rejected="onAvatarRejected"
>
<template v-slot:append>
2020-11-18 02:11:34 +00:00
<q-icon name="mdi-file-image" @click.stop />
2020-11-16 01:28:03 +00:00
</template>
</q-file>
</q-card-section>
<q-separator v-if="!newUser" />
<q-card-section class="fit row justify-start content-center items-center" v-if="!newUser">
<q-input
v-if="isCurrentUser"
class="col-xs-12 col-sm-6 col-md-4 q-pa-sm"
label="Password"
type="password"
hint="Password muss immer eingetragen werden"
:rules="[notEmpty]"
v-model="password"
filled
/>
<q-input
class="col-xs-12 col-sm-6 col-md-4 q-pa-sm"
label="Neues Password"
type="password"
v-model="new_password"
filled
/>
<q-input
class="col-xs-12 col-sm-6 col-md-4 q-pa-sm"
label="Wiederhole neues Password"
type="password"
:disable="new_password.length == 0"
:rules="[samePassword]"
v-model="new_password2"
filled
/>
</q-card-section>
<q-card-actions align="right">
2020-11-18 02:11:34 +00:00
<q-btn label="Reset" type="reset" />
<q-btn color="primary" type="submit" label="Speichern" />
</q-card-actions>
</q-form>
</template>
<script lang="ts">
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { computed, defineComponent, ref, onBeforeMount } from 'vue';
import { useStore } from 'vuex';
import { hasPermission } from 'src/utils/permission';
2020-11-15 18:47:05 +00:00
import IsoDateInput from 'src/components/utils/IsoDateInput.vue';
2020-11-16 01:28:03 +00:00
import { Notify } from 'quasar';
import { UserSessionState } from '../../store';
export default defineComponent({
name: 'MainUserSettings',
2020-11-15 18:47:05 +00:00
components: { IsoDateInput: IsoDateInput },
props: {
newUser: { type: Boolean, default: false },
user: { type: Object, required: true },
},
setup(props, { emit }) {
const store = useStore<UserSessionState>();
const user_model = ref<FG.User>(<FG.User>props.user);
onBeforeMount(() => {
store.dispatch('users/getRoles', false).catch((error) => {
console.warn(error);
});
});
const isCurrentUser = computed(
() => user_model.value.userid === store.state.users.currentUser?.userid
);
const canSetRoles = computed(() => hasPermission('users_set_roles'));
const avatar = ref([]);
2020-11-16 01:28:03 +00:00
function onAvatarRejected() {
Notify.create({
group: false,
type: 'negative',
message: 'Datei zu groß oder keine gültige Bilddatei.',
timeout: 10000,
progress: true,
actions: [{ icon: 'mdi-close', color: 'white' }],
2020-11-16 01:28:03 +00:00
});
avatar.value = [];
2020-11-16 01:28:03 +00:00
}
const allRoles = computed(() => store.state.users.roles.map((role) => role.name));
const password = ref('');
const new_password = ref('');
const new_password2 = ref('');
function save() {
let changed = user_model.value;
2021-01-21 15:23:40 +00:00
if (typeof changed.birthday === 'string') changed.birthday = new Date(changed.birthday);
changed = Object.assign(changed, {
password: password.value,
});
if (new_password.value != '') {
changed = Object.assign(changed, {
new_password: new_password.value,
});
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
emit('update:user', changed);
2020-11-18 02:11:34 +00:00
2021-01-21 15:23:40 +00:00
if (avatar.value && (avatar.value.length > 0 || avatar.value instanceof File))
store
.dispatch('users/uploadAvatar', {
user: changed,
file: avatar.value,
})
.catch((response: Response) => {
if (response && response.status == 400) {
onAvatarRejected();
}
});
reset();
}
function reset() {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
user_model.value = <FG.User>props.user;
password.value = '';
new_password.value = '';
new_password2.value = '';
}
function samePassword(val: string) {
return val == new_password.value || 'Passwörter sind nicht identisch!';
}
function notEmpty(val: string) {
return !!val || 'Feld darf nicht leer sein!';
}
function isEmail(val: string | null) {
return (
2021-01-21 15:23:40 +00:00
!val || /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w\w+)+$/.test(val) || 'E-Mail ist nicht valide.'
);
}
function isUseridUsed(val: string) {
return (
!store.state.users.users.find((user: FG.User) => {
return user.userid == val;
}) ||
!props.newUser ||
'Benutzername ist schon vergeben'
);
}
return {
2020-11-16 01:28:03 +00:00
avatar,
user_model,
2020-11-16 01:28:03 +00:00
onAvatarRejected,
allRoles,
canSetRoles,
password,
new_password,
new_password2,
samePassword,
isCurrentUser,
isEmail,
notEmpty,
isUseridUsed,
save,
reset,
};
},
});
</script>