release v2.0.0 #4

Merged
crimsen merged 481 commits from develop into master 2024-01-18 15:15:08 +00:00
5 changed files with 65 additions and 13 deletions
Showing only changes of commit 939dde3651 - Show all commits

View File

@ -13,6 +13,7 @@ declare namespace FG {
firstname: string; firstname: string;
lastname: string; lastname: string;
mail: string; mail: string;
avatar_url?: string;
birthday?: Date; birthday?: Date;
roles: Array<string>; roles: Array<string>;
} }
@ -26,9 +27,10 @@ declare namespace FG {
id: number; id: number;
time: Date; time: Date;
amount: number; amount: number;
sender_id: string; reversal?: this;
receiver_id: string; sender_id?: string;
author_id: string; receiver_id?: string;
author_id?: string;
} }
interface Event { interface Event {
id: number; id: number;

View File

@ -5,10 +5,16 @@
Benutzereinstellungen Benutzereinstellungen
</div> </div>
<div class="col-xs-12 col-sm-6 q-pa-sm"> <div class="col-xs-12 col-sm-6 q-pa-sm">
<UserSelector :user="user" @update:user="userUpdated" /> <UserSelector
:user="user"
@update:user="userUpdated"
/>
</div> </div>
</q-card-section> </q-card-section>
<MainUserSettings :user="user" @update:user="updateUser" /> <MainUserSettings
:user="user"
@update:user="updateUser"
/>
</q-card> </q-card>
</template> </template>
@ -33,7 +39,7 @@ export default defineComponent({
}; };
function updateUser(value: FG.User) { function updateUser(value: FG.User) {
store.dispatch('user/updateUser', value).catch(error => { store.dispatch('user/updateUser', value).catch((error) => {
console.warn(error); console.warn(error);
}); });
} }
@ -41,9 +47,9 @@ export default defineComponent({
return { return {
user, user,
userUpdated, userUpdated,
updateUser updateUser,
}; };
} },
}); });
</script> </script>

View File

@ -36,13 +36,10 @@ export default defineComponent({
const store = <Store<StateInterface>>root.$store; const store = <Store<StateInterface>>root.$store;
onMounted(() => store.dispatch('user/getUsers', false)); onMounted(() => store.dispatch('user/getUsers', false));
const avatarLink = computed(() => {
const hash = MD5(store.state.user.currentUser?.mail || '').toString();
return `https://www.gravatar.com/avatar/${hash}?s=500&d=robohash`;
});
const name = ref(store.state.user.currentUser?.display_name); const name = ref(store.state.user.currentUser?.display_name);
const avatarLink = ref(store.state.user.currentUser?.avatar_url);
function userHasBirthday(user: FG.User) { function userHasBirthday(user: FG.User) {
const today = new Date(); const today = new Date();
return ( return (

View File

@ -54,9 +54,25 @@
option-value="name" option-value="name"
/> />
<IsoDateInput <IsoDateInput
class="col-xs-12 col-sm-6 q-pa-sm"
v-model="props.user.birthday" v-model="props.user.birthday"
label="Geburtstag" label="Geburtstag"
/> />
<q-file
class="col-xs-12 col-sm-6 q-pa-sm"
v-model="avatar"
filled
label="Avatar"
accept=".jpg, image/*"
@rejected="onAvatarRejected"
>
<template v-slot:append>
<q-icon
name="mdi-file-image"
@click.stop
/>
</template>
</q-file>
</q-card-section> </q-card-section>
<q-separator v-if="!props.newUser" /> <q-separator v-if="!props.newUser" />
<q-card-section <q-card-section
@ -115,6 +131,7 @@ import { Store } from 'vuex';
import { StateInterface } from 'src/store'; import { StateInterface } from 'src/store';
import { hasPermission } from 'src/components/permission'; import { hasPermission } from 'src/components/permission';
import IsoDateInput from 'src/components/utils/IsoDateInput.vue'; import IsoDateInput from 'src/components/utils/IsoDateInput.vue';
import { Notify } from 'quasar';
interface Props { interface Props {
user?: FG.User; user?: FG.User;
@ -155,6 +172,14 @@ export default defineComponent({
})[0]; })[0];
}); });
const avatar = ref<string>('');
function onAvatarRejected() {
Notify.create({
color: 'negative',
message: 'Ungültige Bilddatei',
});
}
const allRoles = computed(() => const allRoles = computed(() =>
store.state.user.roles.map((role) => role.name) store.state.user.roles.map((role) => role.name)
); );
@ -174,6 +199,11 @@ export default defineComponent({
} }
emit('update:user', changed); emit('update:user', changed);
if (avatar.value != '')
void store.dispatch('user/uploadAvatar', {
user: changed,
file: avatar.value,
});
} }
function reset() { function reset() {
@ -210,6 +240,8 @@ export default defineComponent({
} }
return { return {
avatar,
onAvatarRejected,
props, props,
allRoles, allRoles,
canSetRoles, canSetRoles,

View File

@ -119,6 +119,21 @@ const actions: ActionTree<UserStateInterface, StateInterface> = {
}); });
}, },
uploadAvatar({ commit }, payload: { user: FG.User; file: string }) {
commit('setLoading');
const formData = new FormData();
formData.append('file', payload.file);
return axios
.post(`/users/${payload.user.userid}/avatar`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.finally(() => {
commit('setLoading', false);
});
},
setUser({ commit, state, dispatch }, data: FG.User) { setUser({ commit, state, dispatch }, data: FG.User) {
commit('setLoading'); commit('setLoading');
axios axios