update usage of salutation
This commit is contained in:
parent
e330e3a7d6
commit
3866d406b2
9 changed files with 96 additions and 34 deletions
|
@ -6,7 +6,7 @@
|
||||||
<br />
|
<br />
|
||||||
<form class="flex flex-col gap-4 py-2" @submit.prevent="triggerCreate">
|
<form class="flex flex-col gap-4 py-2" @submit.prevent="triggerCreate">
|
||||||
<div>
|
<div>
|
||||||
<Listbox v-model="selectedSalutation" name="salutation">
|
<Listbox v-model="selectedSalutation" name="salutation" by="id">
|
||||||
<ListboxLabel>Anrede</ListboxLabel>
|
<ListboxLabel>Anrede</ListboxLabel>
|
||||||
<div class="relative mt-1">
|
<div class="relative mt-1">
|
||||||
<ListboxButton
|
<ListboxButton
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
<ListboxOption
|
<ListboxOption
|
||||||
v-slot="{ active, selected }"
|
v-slot="{ active, selected }"
|
||||||
v-for="salutation in salutations"
|
v-for="salutation in salutations"
|
||||||
:key="salutation"
|
:key="salutation.id"
|
||||||
:value="salutation"
|
:value="salutation"
|
||||||
as="template"
|
as="template"
|
||||||
>
|
>
|
||||||
|
@ -39,7 +39,9 @@
|
||||||
'relative cursor-default select-none py-2 pl-10 pr-4',
|
'relative cursor-default select-none py-2 pl-10 pr-4',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<span :class="[selected ? 'font-medium' : 'font-normal', 'block truncate']">{{ salutation }}</span>
|
<span :class="[selected ? 'font-medium' : 'font-normal', 'block truncate']">{{
|
||||||
|
salutation.salutation
|
||||||
|
}}</span>
|
||||||
<span v-if="selected" class="absolute inset-y-0 left-0 flex items-center pl-3 text-primary">
|
<span v-if="selected" class="absolute inset-y-0 left-0 flex items-center pl-3 text-primary">
|
||||||
<CheckIcon class="h-5 w-5" aria-hidden="true" />
|
<CheckIcon class="h-5 w-5" aria-hidden="true" />
|
||||||
</span>
|
</span>
|
||||||
|
@ -97,9 +99,9 @@ import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||||
import FailureXMark from "@/components/FailureXMark.vue";
|
import FailureXMark from "@/components/FailureXMark.vue";
|
||||||
import { Listbox, ListboxButton, ListboxOptions, ListboxOption, ListboxLabel } from "@headlessui/vue";
|
import { Listbox, ListboxButton, ListboxOptions, ListboxOption, ListboxLabel } from "@headlessui/vue";
|
||||||
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/vue/20/solid";
|
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/vue/20/solid";
|
||||||
import { Salutation } from "@/enums/salutation";
|
|
||||||
import { useMemberStore } from "@/stores/admin/club/member/member";
|
import { useMemberStore } from "@/stores/admin/club/member/member";
|
||||||
import type { CreateMemberViewModel } from "@/viewmodels/admin/club/member/member.models";
|
import type { CreateMemberViewModel } from "@/viewmodels/admin/club/member/member.models";
|
||||||
|
import { useSalutationStore } from "../../../../stores/admin/settings/salutation";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -108,12 +110,11 @@ export default defineComponent({
|
||||||
return {
|
return {
|
||||||
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
|
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
|
||||||
timeout: undefined as any,
|
timeout: undefined as any,
|
||||||
salutations: [] as Array<string>,
|
selectedSalutation: null as null | number,
|
||||||
selectedSalutation: Salutation.none as Salutation,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
computed: {
|
||||||
this.salutations = Object.values(Salutation);
|
...mapState(useSalutationStore, ["salutations"]),
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
try {
|
try {
|
||||||
|
@ -123,10 +124,12 @@ export default defineComponent({
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useModalStore, ["closeModal"]),
|
...mapActions(useModalStore, ["closeModal"]),
|
||||||
...mapActions(useMemberStore, ["createMember"]),
|
...mapActions(useMemberStore, ["createMember"]),
|
||||||
|
...mapActions(useSalutationStore, ["fetchSalutations"]),
|
||||||
triggerCreate(e: any) {
|
triggerCreate(e: any) {
|
||||||
|
if (!this.selectedSalutation) return;
|
||||||
let formData = e.target.elements;
|
let formData = e.target.elements;
|
||||||
let createMember: CreateMemberViewModel = {
|
let createMember: CreateMemberViewModel = {
|
||||||
salutation: this.selectedSalutation,
|
salutationId: this.selectedSalutation,
|
||||||
firstname: formData.firstname.value,
|
firstname: formData.firstname.value,
|
||||||
lastname: formData.lastname.value,
|
lastname: formData.lastname.value,
|
||||||
nameaffix: formData.nameaffix.value,
|
nameaffix: formData.nameaffix.value,
|
||||||
|
|
|
@ -41,9 +41,6 @@ import { useModalStore } from "@/stores/modal";
|
||||||
import Spinner from "@/components/Spinner.vue";
|
import Spinner from "@/components/Spinner.vue";
|
||||||
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||||
import FailureXMark from "@/components/FailureXMark.vue";
|
import FailureXMark from "@/components/FailureXMark.vue";
|
||||||
import { Listbox, ListboxButton, ListboxOptions, ListboxOption, ListboxLabel } from "@headlessui/vue";
|
|
||||||
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/vue/20/solid";
|
|
||||||
import { Salutation } from "@/enums/salutation";
|
|
||||||
import { useMemberStore } from "@/stores/admin/club/member/member";
|
import { useMemberStore } from "@/stores/admin/club/member/member";
|
||||||
import type { CreateMemberViewModel } from "@/viewmodels/admin/club/member/member.models";
|
import type { CreateMemberViewModel } from "@/viewmodels/admin/club/member/member.models";
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
export enum Salutation {
|
|
||||||
sir = "sir",
|
|
||||||
madam = "madam",
|
|
||||||
other = "other",
|
|
||||||
none = "none",
|
|
||||||
}
|
|
53
src/stores/admin/settings/salutation.ts
Normal file
53
src/stores/admin/settings/salutation.ts
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import { defineStore } from "pinia";
|
||||||
|
import type {
|
||||||
|
CreateSalutationViewModel,
|
||||||
|
UpdateSalutationViewModel,
|
||||||
|
SalutationViewModel,
|
||||||
|
} from "@/viewmodels/admin/settings/salutation.models";
|
||||||
|
import { http } from "@/serverCom";
|
||||||
|
import type { AxiosResponse } from "axios";
|
||||||
|
|
||||||
|
export const useSalutationStore = defineStore("salutation", {
|
||||||
|
state: () => {
|
||||||
|
return {
|
||||||
|
salutations: [] as Array<SalutationViewModel>,
|
||||||
|
loading: "loading" as "loading" | "fetched" | "failed",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
fetchSalutations() {
|
||||||
|
this.loading = "loading";
|
||||||
|
http
|
||||||
|
.get("/admin/salutation")
|
||||||
|
.then((result) => {
|
||||||
|
this.salutations = result.data;
|
||||||
|
this.loading = "fetched";
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.loading = "failed";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fetchSalutationById(id: number): Promise<AxiosResponse<any, any>> {
|
||||||
|
return http.get(`/admin/salutation/${id}`);
|
||||||
|
},
|
||||||
|
async createSalutation(salutation: CreateSalutationViewModel): Promise<AxiosResponse<any, any>> {
|
||||||
|
const result = await http.post(`/admin/salutation`, {
|
||||||
|
salutation: salutation.salutation,
|
||||||
|
});
|
||||||
|
this.fetchSalutations();
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
async updateActiveSalutation(salutation: UpdateSalutationViewModel): Promise<AxiosResponse<any, any>> {
|
||||||
|
const result = await http.patch(`/admin/salutation/${salutation.id}`, {
|
||||||
|
salutation: salutation.salutation,
|
||||||
|
});
|
||||||
|
this.fetchSalutations();
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
async deleteSalutation(salutation: number): Promise<AxiosResponse<any, any>> {
|
||||||
|
const result = await http.delete(`/admin/salutation/${salutation}`);
|
||||||
|
this.fetchSalutations();
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -11,6 +11,7 @@ export type PermissionModule =
|
||||||
| "executive_position"
|
| "executive_position"
|
||||||
| "communication_type"
|
| "communication_type"
|
||||||
| "membership_status"
|
| "membership_status"
|
||||||
|
| "salutation"
|
||||||
| "calendar_type"
|
| "calendar_type"
|
||||||
| "user"
|
| "user"
|
||||||
| "role"
|
| "role"
|
||||||
|
@ -53,6 +54,7 @@ export const permissionModules: Array<PermissionModule> = [
|
||||||
"executive_position",
|
"executive_position",
|
||||||
"communication_type",
|
"communication_type",
|
||||||
"membership_status",
|
"membership_status",
|
||||||
|
"salutation",
|
||||||
"calendar_type",
|
"calendar_type",
|
||||||
"user",
|
"user",
|
||||||
"role",
|
"role",
|
||||||
|
@ -71,6 +73,7 @@ export const sectionsAndModules: SectionsAndModulesObject = {
|
||||||
"executive_position",
|
"executive_position",
|
||||||
"communication_type",
|
"communication_type",
|
||||||
"membership_status",
|
"membership_status",
|
||||||
|
"salutation",
|
||||||
"calendar_type",
|
"calendar_type",
|
||||||
"query_store",
|
"query_store",
|
||||||
"template",
|
"template",
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Salutation } from "@/enums/salutation";
|
|
||||||
import type { CommunicationViewModel } from "./communication.models";
|
import type { CommunicationViewModel } from "./communication.models";
|
||||||
import type { MembershipViewModel } from "./membership.models";
|
import type { MembershipViewModel } from "./membership.models";
|
||||||
|
import type { SalutationViewModel } from "../../settings/salutation.models";
|
||||||
|
|
||||||
export interface MemberViewModel {
|
export interface MemberViewModel {
|
||||||
id: number;
|
id: number;
|
||||||
salutation: Salutation;
|
salutation: SalutationViewModel;
|
||||||
firstname: string;
|
firstname: string;
|
||||||
lastname: string;
|
lastname: string;
|
||||||
nameaffix: string;
|
nameaffix: string;
|
||||||
|
@ -19,7 +19,7 @@ export interface MemberViewModel {
|
||||||
|
|
||||||
export interface MemberStatisticsViewModel {
|
export interface MemberStatisticsViewModel {
|
||||||
id: number;
|
id: number;
|
||||||
salutation: Salutation;
|
salutation: string;
|
||||||
firstname: string;
|
firstname: string;
|
||||||
lastname: string;
|
lastname: string;
|
||||||
nameaffix: string;
|
nameaffix: string;
|
||||||
|
@ -30,7 +30,7 @@ export interface MemberStatisticsViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateMemberViewModel {
|
export interface CreateMemberViewModel {
|
||||||
salutation: Salutation;
|
salutationId: number;
|
||||||
firstname: string;
|
firstname: string;
|
||||||
lastname: string;
|
lastname: string;
|
||||||
nameaffix: string;
|
nameaffix: string;
|
||||||
|
@ -40,7 +40,7 @@ export interface CreateMemberViewModel {
|
||||||
|
|
||||||
export interface UpdateMemberViewModel {
|
export interface UpdateMemberViewModel {
|
||||||
id: number;
|
id: number;
|
||||||
salutation: Salutation;
|
salutationId: number;
|
||||||
firstname: string;
|
firstname: string;
|
||||||
lastname: string;
|
lastname: string;
|
||||||
nameaffix: string;
|
nameaffix: string;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import type { Salutation } from "../../../../enums/salutation";
|
|
||||||
|
|
||||||
export interface MembershipViewModel {
|
export interface MembershipViewModel {
|
||||||
id: number;
|
id: number;
|
||||||
start: Date;
|
start: Date;
|
||||||
|
@ -15,7 +13,7 @@ export interface MembershipStatisticsViewModel {
|
||||||
status: string;
|
status: string;
|
||||||
statusId: number;
|
statusId: number;
|
||||||
memberId: number;
|
memberId: number;
|
||||||
memberSalutation: Salutation;
|
memberSalutation: string;
|
||||||
memberFirstname: string;
|
memberFirstname: string;
|
||||||
memberLastname: string;
|
memberLastname: string;
|
||||||
memberNameaffix: string;
|
memberNameaffix: string;
|
||||||
|
|
13
src/viewmodels/admin/settings/salutation.models.ts
Normal file
13
src/viewmodels/admin/settings/salutation.models.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
export interface SalutationViewModel {
|
||||||
|
id: number;
|
||||||
|
salutation: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateSalutationViewModel {
|
||||||
|
salutation: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateSalutationViewModel {
|
||||||
|
id: number;
|
||||||
|
salutation: string;
|
||||||
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
>
|
>
|
||||||
<p class="mx-auto">Mitglied bearbeiten</p>
|
<p class="mx-auto">Mitglied bearbeiten</p>
|
||||||
<div>
|
<div>
|
||||||
<Listbox v-model="member.salutation" name="salutation">
|
<Listbox v-model="member.salutation" name="salutation" by="id">
|
||||||
<ListboxLabel>Anrede</ListboxLabel>
|
<ListboxLabel>Anrede</ListboxLabel>
|
||||||
<div class="relative mt-1">
|
<div class="relative mt-1">
|
||||||
<ListboxButton
|
<ListboxButton
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
<ListboxOption
|
<ListboxOption
|
||||||
v-slot="{ active, selected }"
|
v-slot="{ active, selected }"
|
||||||
v-for="salutation in salutations"
|
v-for="salutation in salutations"
|
||||||
:key="salutation"
|
:key="salutation.id"
|
||||||
:value="salutation"
|
:value="salutation"
|
||||||
as="template"
|
as="template"
|
||||||
>
|
>
|
||||||
|
@ -42,7 +42,9 @@
|
||||||
'relative cursor-default select-none py-2 pl-10 pr-4',
|
'relative cursor-default select-none py-2 pl-10 pr-4',
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<span :class="[selected ? 'font-medium' : 'font-normal', 'block truncate']">{{ salutation }}</span>
|
<span :class="[selected ? 'font-medium' : 'font-normal', 'block truncate']">{{
|
||||||
|
salutation.salutation
|
||||||
|
}}</span>
|
||||||
<span v-if="selected" class="absolute inset-y-0 left-0 flex items-center pl-3 text-primary">
|
<span v-if="selected" class="absolute inset-y-0 left-0 flex items-center pl-3 text-primary">
|
||||||
<CheckIcon class="h-5 w-5" aria-hidden="true" />
|
<CheckIcon class="h-5 w-5" aria-hidden="true" />
|
||||||
</span>
|
</span>
|
||||||
|
@ -101,7 +103,7 @@ import { Listbox, ListboxButton, ListboxOptions, ListboxOption, ListboxLabel } f
|
||||||
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/vue/20/solid";
|
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/vue/20/solid";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
import isEqual from "lodash.isequal";
|
import isEqual from "lodash.isequal";
|
||||||
import { Salutation } from "@/enums/salutation";
|
import { useSalutationStore } from "../../../../stores/admin/settings/salutation";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -123,7 +125,6 @@ export default defineComponent({
|
||||||
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
|
status: null as null | "loading" | { status: "success" | "failed"; reason?: string },
|
||||||
member: null as null | MemberViewModel,
|
member: null as null | MemberViewModel,
|
||||||
timeout: null as any,
|
timeout: null as any,
|
||||||
salutations: [] as Array<string>,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -131,10 +132,10 @@ export default defineComponent({
|
||||||
return isEqual(this.activeMemberObj, this.member);
|
return isEqual(this.activeMemberObj, this.member);
|
||||||
},
|
},
|
||||||
...mapState(useMemberStore, ["activeMemberObj", "loadingActive"]),
|
...mapState(useMemberStore, ["activeMemberObj", "loadingActive"]),
|
||||||
|
...mapState(useSalutationStore, ["salutations"]),
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.fetchItem();
|
this.fetchItem();
|
||||||
this.salutations = Object.values(Salutation);
|
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
try {
|
try {
|
||||||
|
@ -154,11 +155,11 @@ export default defineComponent({
|
||||||
let formData = e.target.elements;
|
let formData = e.target.elements;
|
||||||
let updateMember: UpdateMemberViewModel = {
|
let updateMember: UpdateMemberViewModel = {
|
||||||
id: this.member.id,
|
id: this.member.id,
|
||||||
salutation: formData.salutation.value,
|
salutationId: formData.salutation.value,
|
||||||
firstname: formData.firstname.value,
|
firstname: formData.firstname.value,
|
||||||
lastname: formData.lastname.value,
|
lastname: formData.lastname.value,
|
||||||
nameaffix: formData.nameaffix.value,
|
nameaffix: formData.nameaffix.value,
|
||||||
birthdate: formData.birthdate.value,
|
birthdate: formData.birthdate.value,
|
||||||
internalId: formData.internalId.value,
|
internalId: formData.internalId.value,
|
||||||
};
|
};
|
||||||
this.status = "loading";
|
this.status = "loading";
|
||||||
|
|
Loading…
Reference in a new issue