folder structure

This commit is contained in:
Julian Krauser 2025-01-02 18:28:13 +01:00
parent dfb5547bd2
commit da0408cc4d
203 changed files with 354 additions and 354 deletions

View file

@ -0,0 +1,77 @@
import { defineStore } from "pinia";
import type {
CreateCalendarViewModel,
UpdateCalendarViewModel,
CalendarViewModel,
} from "@/viewmodels/admin/club/calendar.models";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
export const useCalendarStore = defineStore("calendar", {
state: () => {
return {
calendars: [] as Array<CalendarViewModel>,
loading: "loading" as "loading" | "fetched" | "failed",
loadingFields: "loading" as "loading" | "fetched" | "failed",
};
},
getters: {
formattedItems: (state) => {
return state.calendars.map((c) => ({
id: c.id,
title: c.title,
start: c.starttime,
end: c.endtime,
backgroundColor: c.type.color,
}));
},
},
actions: {
fetchCalendars() {
this.loading = "loading";
http
.get("/admin/calendar")
.then((result) => {
this.calendars = result.data;
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchCalendarById(id: string): Promise<AxiosResponse<any, any>> {
return http.get(`/admin/calendar/${id}`);
},
async createCalendar(calendar: CreateCalendarViewModel): Promise<AxiosResponse<any, any>> {
const result = await http.post(`/admin/calendar`, {
starttime: calendar.starttime,
endtime: calendar.endtime,
title: calendar.title,
content: calendar.content,
allDay: calendar.allDay,
location: calendar.location,
typeId: calendar.typeId,
});
this.fetchCalendars();
return result;
},
async updateCalendar(calendar: UpdateCalendarViewModel): Promise<AxiosResponse<any, any>> {
const result = await http.patch(`/admin/calendar/${calendar.id}`, {
starttime: calendar.starttime,
endtime: calendar.endtime,
title: calendar.title,
content: calendar.content,
allDay: calendar.allDay,
location: calendar.location,
typeId: calendar.typeId,
});
this.fetchCalendars();
return result;
},
async deleteCalendar(calendar: number): Promise<AxiosResponse<any, any>> {
const result = await http.delete(`/admin/calendar/${calendar}`);
this.fetchCalendars();
return result;
},
},
});

View file

@ -0,0 +1,78 @@
import { defineStore } from "pinia";
import type { CreateMemberViewModel, UpdateMemberViewModel } from "@/viewmodels/admin/club/member/member.models";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type { MemberViewModel } from "@/viewmodels/admin/club/member/member.models";
import { useMemberStore } from "./member";
import type {
CreateCommunicationViewModel,
CommunicationViewModel,
UpdateCommunicationViewModel,
} from "@/viewmodels/admin/club/member/communication.models";
export const useCommunicationStore = defineStore("communication", {
state: () => {
return {
communications: [] as Array<CommunicationViewModel>,
loading: "loading" as "loading" | "fetched" | "failed",
};
},
actions: {
fetchCommunicationsForMember() {
const memberId = useMemberStore().activeMember;
this.loading = "loading";
http
.get(`/admin/member/${memberId}/communications`)
.then((result) => {
this.communications = result.data;
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchCommunicationById(id: number) {
const memberId = useMemberStore().activeMember;
return http.get(`/admin/member/${memberId}/communication/${id}`);
},
async createCommunication(communication: CreateCommunicationViewModel): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.post(`/admin/member/${memberId}/communication`, {
preferred: communication.preferred,
mobile: communication.mobile,
email: communication.email,
city: communication.city,
street: communication.street,
streetNumber: communication.streetNumber,
streetNumberAddition: communication.streetNumberAddition,
typeId: communication.typeId,
isNewsletterMain: communication.isNewsletterMain,
isSMSAlarming: communication.isSMSAlarming,
});
this.fetchCommunicationsForMember();
return result;
},
async updateCommunication(communication: UpdateCommunicationViewModel): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.patch(`/admin/member/${memberId}/communication/${communication.id}`, {
preferred: communication.preferred,
mobile: communication.mobile,
email: communication.email,
city: communication.city,
street: communication.street,
streetNumber: communication.streetNumber,
streetNumberAddition: communication.streetNumberAddition,
isNewsletterMain: communication.isNewsletterMain,
isSMSAlarming: communication.isSMSAlarming,
});
this.fetchCommunicationsForMember();
return result;
},
async deleteCommunication(communication: number): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.delete(`/admin/member/${memberId}/communication/${communication}`);
this.fetchCommunicationsForMember();
return result;
},
},
});

View file

@ -0,0 +1,88 @@
import { defineStore } from "pinia";
import type { CreateMemberViewModel, UpdateMemberViewModel } from "@/viewmodels/admin/club/member/member.models";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type { MemberViewModel } from "@/viewmodels/admin/club/member/member.models";
export const useMemberStore = defineStore("member", {
state: () => {
return {
members: [] as Array<MemberViewModel & { tab_pos: number }>,
totalCount: 0 as number,
loading: "loading" as "loading" | "fetched" | "failed",
activeMember: null as number | null,
activeMemberObj: null as MemberViewModel | null,
loadingActive: "loading" as "loading" | "fetched" | "failed",
};
},
actions: {
fetchMembers(offset = 0, count = 25, clear = false) {
if (clear) this.members = [];
this.loading = "loading";
http
.get(`/admin/member?offset=${offset}&count=${count}`)
.then((result) => {
this.totalCount = result.data.total;
result.data.members
.filter((elem: MemberViewModel) => this.members.findIndex((m) => m.id == elem.id) == -1)
.map((elem: MemberViewModel, index: number): MemberViewModel & { tab_pos: number } => {
return {
...elem,
tab_pos: index + offset,
};
})
.forEach((elem: MemberViewModel & { tab_pos: number }) => {
this.members.push(elem);
});
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchMemberByActiveId() {
this.loadingActive = "loading";
http
.get(`/admin/member/${this.activeMember}`)
.then((res) => {
this.activeMemberObj = res.data;
this.loadingActive = "fetched";
})
.catch((err) => {
this.loadingActive = "failed";
});
},
fetchMemberById(id: number) {
return http.get(`/admin/member/${id}`);
},
async createMember(member: CreateMemberViewModel): Promise<AxiosResponse<any, any>> {
const result = await http.post(`/admin/member`, {
salutation: member.salutation,
firstname: member.firstname,
lastname: member.lastname,
nameaffix: member.nameaffix,
birthdate: member.birthdate,
internalId: member.internalId,
});
this.fetchMembers();
return result;
},
async updateActiveMember(member: UpdateMemberViewModel): Promise<AxiosResponse<any, any>> {
const result = await http.patch(`/admin/member/${member.id}`, {
salutation: member.salutation,
firstname: member.firstname,
lastname: member.lastname,
nameaffix: member.nameaffix,
birthdate: member.birthdate,
internalId: member.internalId,
});
this.fetchMembers();
return result;
},
async deleteMember(member: number): Promise<AxiosResponse<any, any>> {
const result = await http.delete(`/admin/member/${member}`);
this.fetchMembers();
return result;
},
},
});

View file

@ -0,0 +1,67 @@
import { defineStore } from "pinia";
import type { CreateMemberViewModel, UpdateMemberViewModel } from "@/viewmodels/admin/club/member/member.models";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type { MemberViewModel } from "@/viewmodels/admin/club/member/member.models";
import { useMemberStore } from "./member";
import type {
CreateMemberAwardViewModel,
MemberAwardViewModel,
UpdateMemberAwardViewModel,
} from "@/viewmodels/admin/club/member/memberAward.models";
export const useMemberAwardStore = defineStore("memberAward", {
state: () => {
return {
memberAwards: [] as Array<MemberAwardViewModel>,
loading: "loading" as "loading" | "fetched" | "failed",
};
},
actions: {
fetchMemberAwardsForMember() {
const memberId = useMemberStore().activeMember;
this.loading = "loading";
http
.get(`/admin/member/${memberId}/awards`)
.then((result) => {
this.memberAwards = result.data;
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchMemberAwardById(id: number) {
const memberId = useMemberStore().activeMember;
return http.get(`/admin/member/${memberId}/award/${id}`);
},
async createMemberAward(memberAward: CreateMemberAwardViewModel): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.post(`/admin/member/${memberId}/award`, {
given: memberAward.given,
note: memberAward.note,
date: memberAward.date,
awardId: memberAward.awardId,
});
this.fetchMemberAwardsForMember();
return result;
},
async updateMemberAward(memberAward: UpdateMemberAwardViewModel): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.patch(`/admin/member/${memberId}/award/${memberAward.id}`, {
given: memberAward.given,
note: memberAward.note,
date: memberAward.date,
awardId: memberAward.awardId,
});
this.fetchMemberAwardsForMember();
return result;
},
async deleteMemberAward(memberAward: number): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.delete(`/admin/member/${memberId}/award/${memberAward}`);
this.fetchMemberAwardsForMember();
return result;
},
},
});

View file

@ -0,0 +1,71 @@
import { defineStore } from "pinia";
import type { CreateMemberViewModel, UpdateMemberViewModel } from "@/viewmodels/admin/club/member/member.models";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type { MemberViewModel } from "@/viewmodels/admin/club/member/member.models";
import { useMemberStore } from "./member";
import type {
CreateMemberExecutivePositionViewModel,
MemberExecutivePositionViewModel,
UpdateMemberExecutivePositionViewModel,
} from "@/viewmodels/admin/club/member/memberExecutivePosition.models";
export const useMemberExecutivePositionStore = defineStore("memberExecutivePosition", {
state: () => {
return {
memberExecutivePositions: [] as Array<MemberExecutivePositionViewModel>,
loading: "loading" as "loading" | "fetched" | "failed",
};
},
actions: {
fetchMemberExecutivePositionsForMember() {
const memberId = useMemberStore().activeMember;
this.loading = "loading";
http
.get(`/admin/member/${memberId}/positions`)
.then((result) => {
this.memberExecutivePositions = result.data;
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchMemberExecutivePositionById(id: number) {
const memberId = useMemberStore().activeMember;
return http.get(`/admin/member/${memberId}/position/${id}`);
},
async createMemberExecutivePosition(
memberExecutivePosition: CreateMemberExecutivePositionViewModel
): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.post(`/admin/member/${memberId}/position`, {
note: memberExecutivePosition.note,
start: memberExecutivePosition.start,
end: memberExecutivePosition.end,
executivePositionId: memberExecutivePosition.executivePositionId,
});
this.fetchMemberExecutivePositionsForMember();
return result;
},
async updateMemberExecutivePosition(
memberExecutivePosition: UpdateMemberExecutivePositionViewModel
): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.patch(`/admin/member/${memberId}/position/${memberExecutivePosition.id}`, {
note: memberExecutivePosition.note,
start: memberExecutivePosition.start,
end: memberExecutivePosition.end,
executivePositionId: memberExecutivePosition.executivePositionId,
});
this.fetchMemberExecutivePositionsForMember();
return result;
},
async deleteMemberExecutivePosition(memberExecutivePosition: number): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.delete(`/admin/member/${memberId}/position/${memberExecutivePosition}`);
this.fetchMemberExecutivePositionsForMember();
return result;
},
},
});

View file

@ -0,0 +1,71 @@
import { defineStore } from "pinia";
import type { CreateMemberViewModel, UpdateMemberViewModel } from "@/viewmodels/admin/club/member/member.models";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type { MemberViewModel } from "@/viewmodels/admin/club/member/member.models";
import { useMemberStore } from "./member";
import type {
CreateMemberQualificationViewModel,
MemberQualificationViewModel,
UpdateMemberQualificationViewModel,
} from "@/viewmodels/admin/club/member/memberQualification.models";
export const useMemberQualificationStore = defineStore("memberQualification", {
state: () => {
return {
memberQualifications: [] as Array<MemberQualificationViewModel>,
loading: "loading" as "loading" | "fetched" | "failed",
};
},
actions: {
fetchMemberQualificationsForMember() {
const memberId = useMemberStore().activeMember;
this.loading = "loading";
http
.get(`/admin/member/${memberId}/qualifications`)
.then((result) => {
this.memberQualifications = result.data;
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchMemberQualificationById(id: number) {
const memberId = useMemberStore().activeMember;
return http.get(`/admin/member/${memberId}/qualification/${id}`);
},
async createMemberQualification(
memberQualification: CreateMemberQualificationViewModel
): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.post(`/admin/member/${memberId}/qualification`, {
note: memberQualification.note,
start: memberQualification.start,
qualificationId: memberQualification.qualificationId,
});
this.fetchMemberQualificationsForMember();
return result;
},
async updateMemberQualification(
memberQualification: UpdateMemberQualificationViewModel
): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.patch(`/admin/member/${memberId}/qualification/${memberQualification.id}`, {
note: memberQualification.note,
start: memberQualification.start,
end: memberQualification.end,
terminationReason: memberQualification.terminationReason,
qualificationId: memberQualification.qualificationId,
});
this.fetchMemberQualificationsForMember();
return result;
},
async deleteMemberQualification(memberQualification: number): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.delete(`/admin/member/${memberId}/qualification/${memberQualification}`);
this.fetchMemberQualificationsForMember();
return result;
},
},
});

View file

@ -0,0 +1,65 @@
import { defineStore } from "pinia";
import type { CreateMemberViewModel, UpdateMemberViewModel } from "@/viewmodels/admin/club/member/member.models";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type { MemberViewModel } from "@/viewmodels/admin/club/member/member.models";
import { useMemberStore } from "./member";
import type {
CreateMembershipViewModel,
MembershipViewModel,
UpdateMembershipViewModel,
} from "@/viewmodels/admin/club/member/membership.models";
export const useMembershipStore = defineStore("membership", {
state: () => {
return {
memberships: [] as Array<MembershipViewModel>,
loading: "loading" as "loading" | "fetched" | "failed",
};
},
actions: {
fetchMembershipsForMember() {
const memberId = useMemberStore().activeMember;
this.loading = "loading";
http
.get(`/admin/member/${memberId}/memberships`)
.then((result) => {
this.memberships = result.data;
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchMembershipById(id: number) {
const memberId = useMemberStore().activeMember;
return http.get(`/admin/member/${memberId}/membership/${id}`);
},
async createMembership(membership: CreateMembershipViewModel): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.post(`/admin/member/${memberId}/membership`, {
start: membership.start,
statusId: membership.statusId,
});
this.fetchMembershipsForMember();
return result;
},
async updateMembership(membership: UpdateMembershipViewModel): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.patch(`/admin/member/${memberId}/membership/${membership.id}`, {
start: membership.start,
end: membership.end,
terminationReason: membership.terminationReason,
statusId: membership.statusId,
});
this.fetchMembershipsForMember();
return result;
},
async deleteMembership(membership: number): Promise<AxiosResponse<any, any>> {
const memberId = useMemberStore().activeMember;
const result = await http.delete(`/admin/member/${memberId}/membership/${membership}`);
this.fetchMembershipsForMember();
return result;
},
},
});

View file

@ -0,0 +1,105 @@
import { defineStore } from "pinia";
import type { CreateNewsletterViewModel, SyncNewsletterViewModel } from "@/viewmodels/admin/club/newsletter/newsletter.models";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type { NewsletterViewModel } from "@/viewmodels/admin/club/newsletter/newsletter.models";
import cloneDeep from "lodash.clonedeep";
import isEqual from "lodash.isequal";
import difference from "lodash.difference";
export const useNewsletterStore = defineStore("newsletter", {
state: () => {
return {
newsletters: [] as Array<NewsletterViewModel & { tab_pos: number }>,
totalCount: 0 as number,
loading: "loading" as "loading" | "fetched" | "failed",
activeNewsletter: null as number | null,
activeNewsletterObj: null as NewsletterViewModel | null,
origin: null as NewsletterViewModel | null,
loadingActive: "loading" as "loading" | "fetched" | "failed",
syncingNewsletter: "synced" as "synced" | "syncing" | "detectedChanges" | "failed",
};
},
getters: {
detectedChangeNewsletter: (state) =>
!isEqual(state.origin, state.activeNewsletterObj) && state.syncingNewsletter != "syncing",
},
actions: {
setNewsletterSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") {
this.syncingNewsletter = state;
},
fetchNewsletters(offset = 0, count = 25, clear = false) {
if (clear) this.newsletters = [];
this.loading = "loading";
http
.get(`/admin/newsletter?offset=${offset}&count=${count}`)
.then((result) => {
this.totalCount = result.data.total;
result.data.newsletters
.filter((elem: NewsletterViewModel) => this.newsletters.findIndex((m) => m.id == elem.id) == -1)
.map((elem: NewsletterViewModel, index: number): NewsletterViewModel & { tab_pos: number } => {
return {
...elem,
tab_pos: index + offset,
};
})
.forEach((elem: NewsletterViewModel & { tab_pos: number }) => {
this.newsletters.push(elem);
});
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchNewsletterByActiveId() {
this.loadingActive = "loading";
http
.get(`/admin/newsletter/${this.activeNewsletter}`)
.then((res) => {
this.origin = res.data;
this.activeNewsletterObj = cloneDeep(this.origin);
this.loadingActive = "fetched";
})
.catch((err) => {
this.loadingActive = "failed";
});
},
fetchNewsletterById(id: number) {
return http.get(`/admin/newsletter/${id}`);
},
async createNewsletter(newsletter: CreateNewsletterViewModel): Promise<AxiosResponse<any, any>> {
const result = await http.post(`/admin/newsletter`, {
title: newsletter.title,
});
this.fetchNewsletters();
return result;
},
async synchronizeActiveNewsletter(): Promise<void> {
if (this.origin == null || this.activeNewsletterObj == null) return;
this.syncingNewsletter = "syncing";
await http
.patch(`/admin/newsletter/${this.origin.id}/synchronize`, {
title: this.activeNewsletterObj.title,
description: this.activeNewsletterObj.description,
newsletterTitle: this.activeNewsletterObj.newsletterTitle,
newsletterText: this.activeNewsletterObj.newsletterText,
newsletterSignatur: this.activeNewsletterObj.newsletterSignatur,
recipientsByQueryId: this.activeNewsletterObj.recipientsByQueryId,
})
.then((res) => {
this.syncingNewsletter = "synced";
})
.catch((err) => {
this.syncingNewsletter = "failed";
});
this.fetchNewsletterById(this.origin.id)
.then((res) => {
this.origin = res.data;
if (this.detectedChangeNewsletter) this.syncingNewsletter = "detectedChanges";
})
.catch((err) => {});
},
},
});

View file

@ -0,0 +1,73 @@
import { defineStore } from "pinia";
import { http } from "@/serverCom";
import type { NewsletterDatesViewModel, SyncNewsletterDatesViewModel } from "@/viewmodels/admin/club/newsletter/newsletterDates.models";
import { useNewsletterStore } from "./newsletter";
import cloneDeep from "lodash.clonedeep";
import isEqual from "lodash.isequal";
import differenceWith from "lodash.differencewith";
export const useNewsletterDatesStore = defineStore("newsletterDates", {
state: () => {
return {
dates: [] as Array<NewsletterDatesViewModel>,
origin: [] as Array<NewsletterDatesViewModel>,
loading: "loading" as "loading" | "fetched" | "failed",
syncingNewsletterDates: "synced" as "synced" | "syncing" | "detectedChanges" | "failed",
};
},
getters: {
detectedChangeNewsletterDates: (state) =>
!isEqual(
state.origin.sort(
(a: NewsletterDatesViewModel, b: NewsletterDatesViewModel) =>
new Date(a.calendar.starttime).getTime() - new Date(b.calendar.starttime).getTime()
),
state.dates.sort(
(a: NewsletterDatesViewModel, b: NewsletterDatesViewModel) =>
new Date(a.calendar.starttime).getTime() - new Date(b.calendar.starttime).getTime()
)
) && state.syncingNewsletterDates != "syncing",
},
actions: {
setNewsletterDatesSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") {
this.syncingNewsletterDates = state;
},
fetchNewsletterDates() {
this.loading = "loading";
this.fetchNewsletterDatesPromise()
.then((result) => {
this.origin = result.data;
this.dates = cloneDeep(this.origin);
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchNewsletterDatesPromise() {
const newsletterId = useNewsletterStore().activeNewsletter;
return http.get(`/admin/newsletter/${newsletterId}/dates`);
},
async synchronizeActiveNewsletterDates() {
this.syncingNewsletterDates = "syncing";
const newsletterId = useNewsletterStore().activeNewsletter;
await http
.patch(`/admin/newsletter/${newsletterId}/synchronize/dates`, {
dates: this.dates,
})
.then((res) => {
this.syncingNewsletterDates = "synced";
})
.catch((err) => {
this.syncingNewsletterDates = "failed";
});
this.fetchNewsletterDatesPromise()
.then((res) => {
this.origin = res.data;
if (this.detectedChangeNewsletterDates) this.syncingNewsletterDates = "detectedChanges";
})
.catch((err) => {});
},
},
});

View file

@ -0,0 +1,127 @@
import { defineStore } from "pinia";
import { http, newEventSource } from "@/serverCom";
import { useNewsletterStore } from "./newsletter";
import type { AxiosResponse } from "axios";
import type { EventSourcePolyfill } from "event-source-polyfill";
export const useNewsletterPrintoutStore = defineStore("newsletterPrintout", {
state: () => {
return {
printout: [] as Array<string>,
loading: "loading" as "loading" | "fetched" | "failed",
printing: undefined as undefined | "loading" | "success" | "failed",
sending: undefined as undefined | "loading" | "success" | "failed",
sendingPreview: undefined as undefined | "loading" | "success" | "failed",
pdfProgessSource: undefined as undefined | EventSourcePolyfill,
mailProgessSource: undefined as undefined | EventSourcePolyfill,
pdfSourceMessages: [] as Array<Object>,
mailSourceMessages: [] as Array<Object>,
};
},
actions: {
fetchNewsletterPrintout() {
const newsletterId = useNewsletterStore().activeNewsletter;
this.loading = "loading";
http
.get(`/admin/newsletter/${newsletterId}/printouts`)
.then((result) => {
this.printout = result.data;
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchNewsletterPrintoutById(printout: string): Promise<AxiosResponse<any, any>> {
const newsletterId = useNewsletterStore().activeNewsletter;
return http.get(`/admin/newsletter/${newsletterId}/printout/${printout}`, {
responseType: "blob",
});
},
fetchNewsletterPrintoutPreview(): Promise<AxiosResponse<any, any>> {
const newsletterId = useNewsletterStore().activeNewsletter;
return http.get(`/admin/newsletter/${newsletterId}/printoutpreview`, {
responseType: "blob",
});
},
createNewsletterMailPreview() {
this.sendingPreview = "loading";
const newsletterId = useNewsletterStore().activeNewsletter;
if (newsletterId == null) return;
return http
.post(`/admin/newsletter/${newsletterId}/mailpreview`)
.then((res) => {
this.sendingPreview = "success";
})
.catch((err) => {
this.sendingPreview = "failed";
})
.finally(() => {
setTimeout(() => {
this.sendingPreview = undefined;
}, 1500);
});
},
createNewsletterPrintout() {
this.printing = "loading";
const newsletterId = useNewsletterStore().activeNewsletter;
if (newsletterId == null) return;
return http
.post(`/admin/newsletter/${newsletterId}/printout`)
.then((res) => {
this.fetchNewsletterPrintout();
this.printing = "success";
})
.catch((err) => {
this.printing = "failed";
})
.finally(() => {
setTimeout(() => {
this.printing = undefined;
}, 1500);
});
},
createNewsletterSend() {
this.sending = "loading";
const newsletterId = useNewsletterStore().activeNewsletter;
if (newsletterId == null) return;
return http
.post(`/admin/newsletter/${newsletterId}/send`)
.then((res) => {
this.sending = "success";
})
.catch((err) => {
this.sending = "failed";
})
.finally(() => {
setTimeout(() => {
this.sending = undefined;
}, 1500);
});
},
subscribePdfPrintingProgress() {
// const newsletterId = useNewsletterStore().activeNewsletter;
// if (this.pdfProgessSource != undefined) return;
// this.pdfProgessSource = newEventSource(`/admin/newsletter/${newsletterId}/printoutprogress`);
// this.pdfProgessSource.onmessage = (event) => {
// console.log("pdf", event);
// };
},
subscribeMailSendingProgress() {
// const newsletterId = useNewsletterStore().activeNewsletter;
// if (this.mailProgessSource != undefined) return;
// this.mailProgessSource = newEventSource(`/admin/newsletter/${newsletterId}/sendprogress`);
// this.mailProgessSource.onmessage = (event) => {
// console.log("mail", event);
// };
},
unsubscribePdfPrintingProgress() {
this.pdfProgessSource?.close();
this.pdfProgessSource = undefined;
},
unsubscribeMailSendingProgress() {
this.mailProgessSource?.close();
this.mailProgessSource = undefined;
},
},
});

View file

@ -0,0 +1,65 @@
import { defineStore } from "pinia";
import { http } from "@/serverCom";
import type {
NewsletterRecipientsViewModel,
SyncNewsletterRecipientsViewModel,
} from "@/viewmodels/admin/club/newsletter/newsletterRecipients.models";
import { useNewsletterStore } from "./newsletter";
import cloneDeep from "lodash.clonedeep";
import isEqual from "lodash.isequal";
export const useNewsletterRecipientsStore = defineStore("newsletterRecipients", {
state: () => {
return {
recipients: [] as Array<number>,
origin: [] as Array<number>,
loading: "loading" as "loading" | "fetched" | "failed",
syncingNewsletterRecipients: "synced" as "synced" | "syncing" | "detectedChanges" | "failed",
};
},
getters: {
detectedChangeNewsletterRecipients: (state) =>
!isEqual(state.origin, state.recipients) && state.syncingNewsletterRecipients != "syncing",
},
actions: {
setNewsletterRecipientsSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") {
this.syncingNewsletterRecipients = state;
},
fetchNewsletterRecipients() {
this.loading = "loading";
this.fetchNewsletterRecipientsPromise()
.then((result) => {
this.origin = result.data.map((d: NewsletterRecipientsViewModel) => d.memberId);
this.recipients = cloneDeep(this.origin);
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchNewsletterRecipientsPromise() {
const newsletterId = useNewsletterStore().activeNewsletter;
return http.get(`/admin/newsletter/${newsletterId}/recipients`);
},
async synchronizeActiveNewsletterRecipients() {
this.syncingNewsletterRecipients = "syncing";
const newsletterId = useNewsletterStore().activeNewsletter;
await http
.patch(`/admin/newsletter/${newsletterId}/synchronize/recipients`, {
recipients: this.recipients,
})
.then((res) => {
this.syncingNewsletterRecipients = "synced";
})
.catch((err) => {
this.syncingNewsletterRecipients = "failed";
});
this.fetchNewsletterRecipientsPromise()
.then((result) => {
this.origin = result.data.map((d: NewsletterRecipientsViewModel) => d.memberId);
if (this.detectedChangeNewsletterRecipients) this.syncingNewsletterRecipients = "detectedChanges";
})
.catch((err) => {});
},
},
});

View file

@ -0,0 +1,105 @@
import { defineStore } from "pinia";
import type { CreateProtocolViewModel, SyncProtocolViewModel } from "@/viewmodels/admin/club/protocol/protocol.models";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type { ProtocolViewModel } from "@/viewmodels/admin/club/protocol/protocol.models";
import cloneDeep from "lodash.clonedeep";
import isEqual from "lodash.isequal";
import difference from "lodash.difference";
export const useProtocolStore = defineStore("protocol", {
state: () => {
return {
protocols: [] as Array<ProtocolViewModel & { tab_pos: number }>,
totalCount: 0 as number,
loading: "loading" as "loading" | "fetched" | "failed",
activeProtocol: null as number | null,
activeProtocolObj: null as ProtocolViewModel | null,
origin: null as ProtocolViewModel | null,
loadingActive: "loading" as "loading" | "fetched" | "failed",
syncingProtocol: "synced" as "synced" | "syncing" | "detectedChanges" | "failed",
};
},
getters: {
detectedChangeProtocol: (state) =>
!isEqual(state.origin, state.activeProtocolObj) && state.syncingProtocol != "syncing",
},
actions: {
setProtocolSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") {
this.syncingProtocol = state;
},
fetchProtocols(offset = 0, count = 25, clear = false) {
if (clear) this.protocols = [];
this.loading = "loading";
http
.get(`/admin/protocol?offset=${offset}&count=${count}`)
.then((result) => {
this.totalCount = result.data.total;
result.data.protocols
.filter((elem: ProtocolViewModel) => this.protocols.findIndex((m) => m.id == elem.id) == -1)
.map((elem: ProtocolViewModel, index: number): ProtocolViewModel & { tab_pos: number } => {
return {
...elem,
tab_pos: index + offset,
};
})
.forEach((elem: ProtocolViewModel & { tab_pos: number }) => {
this.protocols.push(elem);
});
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchProtocolByActiveId() {
this.loadingActive = "loading";
http
.get(`/admin/protocol/${this.activeProtocol}`)
.then((res) => {
this.origin = res.data;
this.activeProtocolObj = cloneDeep(this.origin);
this.loadingActive = "fetched";
})
.catch((err) => {
this.loadingActive = "failed";
});
},
fetchProtocolById(id: number) {
return http.get(`/admin/protocol/${id}`);
},
async createProtocol(protocol: CreateProtocolViewModel): Promise<AxiosResponse<any, any>> {
const result = await http.post(`/admin/protocol`, {
title: protocol.title,
date: protocol.date,
});
this.fetchProtocols();
return result;
},
async synchronizeActiveProtocol(): Promise<void> {
if (this.origin == null || this.activeProtocolObj == null) return;
this.syncingProtocol = "syncing";
await http
.patch(`/admin/protocol/${this.origin.id}/synchronize`, {
title: this.activeProtocolObj.title,
date: this.activeProtocolObj.date,
starttime: this.activeProtocolObj.starttime,
endtime: this.activeProtocolObj.endtime,
summary: this.activeProtocolObj.summary,
})
.then((res) => {
this.syncingProtocol = "synced";
})
.catch((err) => {
this.syncingProtocol = "failed";
});
this.fetchProtocolById(this.origin.id)
.then((res) => {
this.origin = res.data;
if (this.detectedChangeProtocol) this.syncingProtocol = "detectedChanges";
})
.catch((err) => {});
},
},
});

View file

@ -0,0 +1,79 @@
import { defineStore } from "pinia";
import { http } from "@/serverCom";
import type { ProtocolAgendaViewModel, SyncProtocolAgendaViewModel } from "@/viewmodels/admin/club/protocol/protocolAgenda.models";
import { useProtocolStore } from "./protocol";
import cloneDeep from "lodash.clonedeep";
import isEqual from "lodash.isequal";
import differenceWith from "lodash.differencewith";
export const useProtocolAgendaStore = defineStore("protocolAgenda", {
state: () => {
return {
agenda: [] as Array<ProtocolAgendaViewModel>,
origin: [] as Array<ProtocolAgendaViewModel>,
loading: "loading" as "loading" | "fetched" | "failed",
syncingProtocolAgenda: "synced" as "synced" | "syncing" | "detectedChanges" | "failed",
};
},
getters: {
detectedChangeProtocolAgenda: (state) =>
!isEqual(state.origin, state.agenda) && state.syncingProtocolAgenda != "syncing",
},
actions: {
setProtocolAgendaSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") {
this.syncingProtocolAgenda = state;
},
fetchProtocolAgenda() {
this.loading = "loading";
this.fetchProtocolAgendaPromise()
.then((result) => {
this.origin = result.data;
this.agenda = cloneDeep(this.origin);
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchProtocolAgendaPromise() {
const protocolId = useProtocolStore().activeProtocol;
return http.get(`/admin/protocol/${protocolId}/agenda`);
},
createProtocolAgenda() {
const protocolId = useProtocolStore().activeProtocol;
if (protocolId == null) return;
return http
.post(`/admin/protocol/${protocolId}/agenda`)
.then((res) => {
this.agenda.push({
id: Number(res.data),
topic: "",
context: "",
protocolId: Number(protocolId),
});
})
.catch((err) => {});
},
async synchronizeActiveProtocolAgenda() {
this.syncingProtocolAgenda = "syncing";
const protocolId = useProtocolStore().activeProtocol;
await http
.patch(`/admin/protocol/${protocolId}/synchronize/agenda`, {
agenda: differenceWith(this.agenda, this.origin, isEqual),
})
.then((res) => {
this.syncingProtocolAgenda = "synced";
})
.catch((err) => {
this.syncingProtocolAgenda = "failed";
});
this.fetchProtocolAgendaPromise()
.then((res) => {
this.origin = res.data;
if (this.detectedChangeProtocolAgenda) this.syncingProtocolAgenda = "detectedChanges";
})
.catch((err) => {});
},
},
});

View file

@ -0,0 +1,83 @@
import { defineStore } from "pinia";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type {
ProtocolDecisionViewModel,
SyncProtocolDecisionViewModel,
} from "@/viewmodels/admin/club/protocol/protocolDecision.models";
import { useProtocolStore } from "./protocol";
import cloneDeep from "lodash.clonedeep";
import isEqual from "lodash.isequal";
import differenceWith from "lodash.differencewith";
export const useProtocolDecisionStore = defineStore("protocolDecision", {
state: () => {
return {
decision: [] as Array<ProtocolDecisionViewModel>,
origin: [] as Array<ProtocolDecisionViewModel>,
loading: "loading" as "loading" | "fetched" | "failed",
syncingProtocolDecision: "synced" as "synced" | "syncing" | "detectedChanges" | "failed",
};
},
getters: {
detectedChangeProtocolDecision: (state) =>
!isEqual(state.origin, state.decision) && state.syncingProtocolDecision != "syncing",
},
actions: {
setProtocolDecisionSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") {
this.syncingProtocolDecision = state;
},
fetchProtocolDecision() {
this.loading = "loading";
this.fetchProtocolDecisionPromise()
.then((result) => {
this.origin = result.data;
this.decision = cloneDeep(this.origin);
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchProtocolDecisionPromise() {
const protocolId = useProtocolStore().activeProtocol;
return http.get(`/admin/protocol/${protocolId}/decisions`);
},
createProtocolDecision() {
const protocolId = useProtocolStore().activeProtocol;
if (protocolId == null) return;
return http
.post(`/admin/protocol/${protocolId}/decision`)
.then((res) => {
this.decision.push({
id: Number(res.data),
topic: "",
context: "",
protocolId: Number(protocolId),
});
})
.catch((err) => {});
},
async synchronizeActiveProtocolDecision() {
this.syncingProtocolDecision = "syncing";
const protocolId = useProtocolStore().activeProtocol;
await http
.patch(`/admin/protocol/${protocolId}/synchronize/decisions`, {
decisions: differenceWith(this.decision, this.origin, isEqual),
})
.then((res) => {
this.syncingProtocolDecision = "synced";
})
.catch((err) => {
this.syncingProtocolDecision = "failed";
});
this.fetchProtocolDecisionPromise()
.then((res) => {
this.origin = res.data;
if (this.detectedChangeProtocolDecision) this.syncingProtocolDecision = "detectedChanges";
})
.catch((err) => {});
},
},
});

View file

@ -0,0 +1,66 @@
import { defineStore } from "pinia";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type {
ProtocolPresenceViewModel,
SyncProtocolPresenceViewModel,
} from "@/viewmodels/admin/club/protocol/protocolPresence.models";
import { useProtocolStore } from "./protocol";
import cloneDeep from "lodash.clonedeep";
import isEqual from "lodash.isequal";
export const useProtocolPresenceStore = defineStore("protocolPresence", {
state: () => {
return {
presence: [] as Array<number>,
origin: [] as Array<number>,
loading: "loading" as "loading" | "fetched" | "failed",
syncingProtocolPresence: "synced" as "synced" | "syncing" | "detectedChanges" | "failed",
};
},
getters: {
detectedChangeProtocolPresence: (state) =>
!isEqual(state.origin, state.presence) && state.syncingProtocolPresence != "syncing",
},
actions: {
setProtocolPresenceSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") {
this.syncingProtocolPresence = state;
},
fetchProtocolPresence() {
this.loading = "loading";
this.fetchProtocolPresencePromise()
.then((result) => {
this.origin = result.data.map((d: ProtocolPresenceViewModel) => d.memberId);
this.presence = cloneDeep(this.origin);
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchProtocolPresencePromise() {
const protocolId = useProtocolStore().activeProtocol;
return http.get(`/admin/protocol/${protocolId}/presence`);
},
async synchronizeActiveProtocolPresence() {
this.syncingProtocolPresence = "syncing";
const protocolId = useProtocolStore().activeProtocol;
await http
.put(`/admin/protocol/${protocolId}/synchronize/presence`, {
presence: this.presence,
})
.then((res) => {
this.syncingProtocolPresence = "synced";
})
.catch((err) => {
this.syncingProtocolPresence = "failed";
});
this.fetchProtocolPresencePromise()
.then((result) => {
this.origin = result.data.map((d: ProtocolPresenceViewModel) => d.memberId);
if (this.detectedChangeProtocolPresence) this.syncingProtocolPresence = "detectedChanges";
})
.catch((err) => {});
},
},
});

View file

@ -0,0 +1,55 @@
import { defineStore } from "pinia";
import { http } from "@/serverCom";
import type { ProtocolPrintoutViewModel } from "@/viewmodels/admin/club/protocol/protocolPrintout.models";
import { useProtocolStore } from "./protocol";
import type { AxiosResponse } from "axios";
export const useProtocolPrintoutStore = defineStore("protocolPrintout", {
state: () => {
return {
printout: [] as Array<ProtocolPrintoutViewModel>,
loading: "loading" as "loading" | "fetched" | "failed",
printing: undefined as undefined | "loading" | "success" | "failed",
};
},
actions: {
fetchProtocolPrintout() {
const protocolId = useProtocolStore().activeProtocol;
this.loading = "loading";
http
.get(`/admin/protocol/${protocolId}/printouts`)
.then((result) => {
this.printout = result.data;
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchProtocolPrintoutById(printoutId: number): Promise<AxiosResponse<any, any>> {
const protocolId = useProtocolStore().activeProtocol;
return http.get(`/admin/protocol/${protocolId}/printout/${printoutId}`, {
responseType: "blob",
});
},
createProtocolPrintout() {
this.printing = "loading";
const protocolId = useProtocolStore().activeProtocol;
if (protocolId == null) return;
return http
.post(`/admin/protocol/${protocolId}/printout`)
.then((res) => {
this.fetchProtocolPrintout();
this.printing = "success";
})
.catch((err) => {
this.printing = "failed";
})
.finally(() => {
setTimeout(() => {
this.printing = undefined;
}, 1500);
});
},
},
});

View file

@ -0,0 +1,83 @@
import { defineStore } from "pinia";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type { ProtocolVotingViewModel, SyncProtocolVotingViewModel } from "@/viewmodels/admin/club/protocol/protocolVoting.models";
import { useProtocolStore } from "./protocol";
import cloneDeep from "lodash.clonedeep";
import isEqual from "lodash.isequal";
import differenceWith from "lodash.differencewith";
export const useProtocolVotingStore = defineStore("protocolVoting", {
state: () => {
return {
voting: [] as Array<ProtocolVotingViewModel>,
origin: [] as Array<ProtocolVotingViewModel>,
loading: "loading" as "loading" | "fetched" | "failed",
syncingProtocolVoting: "synced" as "synced" | "syncing" | "detectedChanges" | "failed",
};
},
getters: {
detectedChangeProtocolVoting: (state) =>
!isEqual(state.origin, state.voting) && state.syncingProtocolVoting != "syncing",
},
actions: {
setProtocolVotingSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") {
this.syncingProtocolVoting = state;
},
fetchProtocolVoting() {
this.loading = "loading";
this.fetchProtocolVotingPromise()
.then((result) => {
this.origin = result.data;
this.voting = cloneDeep(this.origin);
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
fetchProtocolVotingPromise() {
const protocolId = useProtocolStore().activeProtocol;
return http.get(`/admin/protocol/${protocolId}/votings`);
},
createProtocolVoting() {
const protocolId = useProtocolStore().activeProtocol;
if (protocolId == null) return;
return http
.post(`/admin/protocol/${protocolId}/voting`)
.then((res) => {
this.voting.push({
id: Number(res.data),
topic: "",
context: "",
favour: 0,
abstain: 0,
against: 0,
protocolId: Number(protocolId),
});
})
.catch((err) => {});
},
async synchronizeActiveProtocolVoting() {
this.syncingProtocolVoting = "syncing";
const protocolId = useProtocolStore().activeProtocol;
await http
.patch(`/admin/protocol/${protocolId}/synchronize/votings`, {
votings: differenceWith(this.voting, this.origin, isEqual),
})
.then((res) => {
this.syncingProtocolVoting = "synced";
})
.catch((err) => {
this.syncingProtocolVoting = "failed";
});
this.fetchProtocolVotingPromise()
.then((res) => {
this.origin = res.data;
if (this.detectedChangeProtocolVoting) this.syncingProtocolVoting = "detectedChanges";
})
.catch((err) => {});
},
},
});

View file

@ -0,0 +1,92 @@
import { defineStore } from "pinia";
import { http } from "@/serverCom";
import type { TableMeta } from "@/viewmodels/admin/settings/query.models";
import type { DynamicQueryStructure, FieldType } from "@/types/dynamicQueries";
export const useQueryBuilderStore = defineStore("queryBuilder", {
state: () => {
return {
tableMetas: [] as Array<TableMeta>,
loading: "loading" as "loading" | "fetched" | "failed",
data: [] as Array<{ id: FieldType; [key: string]: FieldType }>,
totalLength: 0 as number,
loadingData: "fetched" as "loading" | "fetched" | "failed",
queryError: "" as string | { sql: string; code: string; msg: string },
query: undefined as undefined | DynamicQueryStructure | string,
activeQueryId: undefined as undefined | number,
isLoadedQuery: undefined as undefined | number,
};
},
actions: {
fetchTableMetas() {
this.loading = "loading";
http
.get("/admin/querybuilder/tables")
.then((result) => {
this.tableMetas = result.data;
this.loading = "fetched";
})
.catch((err) => {
this.loading = "failed";
});
},
sendQuery(offset = 0, count = 25, query?: DynamicQueryStructure | string) {
this.queryError = "";
if (offset == 0) {
this.data = [];
this.totalLength = 0;
}
let queryToSend = query ?? this.query;
if (queryToSend == undefined || queryToSend == "" || (typeof queryToSend != "string" && queryToSend.table == ""))
return;
this.loadingData = "loading";
http
.post(`/admin/querybuilder/query?offset=${offset}&count=${count}`, {
query: queryToSend,
})
.then((result) => {
if (result.data.stats == "success") {
this.data = [...this.data, ...result.data.rows];
this.totalLength = result.data.total;
this.loadingData = "fetched";
} else {
this.queryError = result.data ?? "An error occurred";
this.loadingData = "failed";
}
})
.catch((err) => {
this.queryError = "An error occurred";
this.loadingData = "failed";
});
},
clearResults() {
this.data = [];
this.totalLength = 0;
this.queryError = "";
this.loadingData = "fetched";
},
exportData() {
if (this.data.length == 0) return;
const csvString = [Object.keys(this.data[0]), ...this.data.map((d) => Object.values(d))]
.map((e) => e.join(";"))
.join("\n");
// Create a Blob from the CSV string
const blob = new Blob([csvString], { type: "text/csv" });
// Create a download link
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "items.csv";
// Append the link to the document and trigger the download
document.body.appendChild(a);
a.click();
// Clean up
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
},
},
});