diff --git a/package-lock.json b/package-lock.json index 4a87af7..1027d9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ff-admin", - "version": "1.3.2", + "version": "1.3.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ff-admin", - "version": "1.3.2", + "version": "1.3.5", "license": "AGPL-3.0-only", "dependencies": { "@fullcalendar/core": "^6.1.15", diff --git a/package.json b/package.json index 32aab8c..cd8151d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ff-admin", - "version": "1.3.2", + "version": "1.3.5", "description": "Feuerwehr/Verein Mitgliederverwaltung UI", "type": "module", "scripts": { diff --git a/src/components/admin/club/newsletter/NewsletterMailProgressModal.vue b/src/components/admin/club/newsletter/NewsletterMailProgressModal.vue index 27f1690..9f5250a 100644 --- a/src/components/admin/club/newsletter/NewsletterMailProgressModal.vue +++ b/src/components/admin/club/newsletter/NewsletterMailProgressModal.vue @@ -19,7 +19,7 @@
- +
diff --git a/src/components/admin/club/newsletter/NewsletterMailRecipientsModal.vue b/src/components/admin/club/newsletter/NewsletterMailRecipientsModal.vue new file mode 100644 index 0000000..fbc1ed3 --- /dev/null +++ b/src/components/admin/club/newsletter/NewsletterMailRecipientsModal.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/src/components/admin/club/newsletter/NewsletterPrintingProgressModal.vue b/src/components/admin/club/newsletter/NewsletterPrintingProgressModal.vue index 416c1e1..8e0b57f 100644 --- a/src/components/admin/club/newsletter/NewsletterPrintingProgressModal.vue +++ b/src/components/admin/club/newsletter/NewsletterPrintingProgressModal.vue @@ -19,7 +19,7 @@
- +
diff --git a/src/components/admin/club/newsletter/NewsletterPrintingRecipientsModal.vue b/src/components/admin/club/newsletter/NewsletterPrintingRecipientsModal.vue new file mode 100644 index 0000000..444ea27 --- /dev/null +++ b/src/components/admin/club/newsletter/NewsletterPrintingRecipientsModal.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/src/components/queryBuilder/BuilderHost.vue b/src/components/queryBuilder/BuilderHost.vue index 55938a4..cbe420e 100644 --- a/src/components/queryBuilder/BuilderHost.vue +++ b/src/components/queryBuilder/BuilderHost.vue @@ -32,7 +32,7 @@ > @@ -54,7 +54,7 @@ class="p-1" :class="typeof value == 'object' ? 'bg-gray-200' : ''" title="Visual Builder" - @click="queryMode = 'builder'" + @click="changeMode('builder')" > @@ -62,7 +62,7 @@ class="p-1" :class="typeof value == 'string' ? 'bg-gray-200' : ''" title="SQL Editor" - @click="queryMode = 'editor'" + @click="changeMode('editor')" > @@ -116,21 +116,9 @@ export default defineComponent({ }, emits: ["update:model-value", "query:run", "query:save", "results:export", "results:clear"], watch: { - queryMode() { - if (this.queryMode == "builder") { - this.value = { - select: "*", - table: "", - where: [], - join: [], - orderBy: [], - }; - } else { - this.value = ""; - } - this.activeQueryId = undefined; - }, activeQueryId() { + if (this.activeQueryId == undefined) return; + let query = this.queries.find((t) => t.id == this.activeQueryId)?.query; if (query != undefined) { if (typeof query == "string") { @@ -188,6 +176,22 @@ export default defineComponent({ showStructure() { this.openModal(markRaw(defineAsyncComponent(() => import("@/components/queryBuilder/StructureModal.vue")))); }, + changeMode(mode: "editor" | "builder") { + this.queryMode = mode; + + this.activeQueryId = undefined; + if (this.queryMode == "builder") { + this.value = { + select: "*", + table: "", + where: [], + join: [], + orderBy: [], + }; + } else { + this.value = ""; + } + }, }, }); diff --git a/src/stores/admin/club/newsletter/newsletterPrintout.ts b/src/stores/admin/club/newsletter/newsletterPrintout.ts index 945ac24..97bc4f3 100644 --- a/src/stores/admin/club/newsletter/newsletterPrintout.ts +++ b/src/stores/admin/club/newsletter/newsletterPrintout.ts @@ -45,6 +45,14 @@ export const useNewsletterPrintoutStore = defineStore("newsletterPrintout", { responseType: "blob", }); }, + fetchNewsletterPrintReceivers(): Promise> { + const newsletterId = useNewsletterStore().activeNewsletter; + return http.get(`/admin/newsletter/${newsletterId}/printrecipients`); + }, + fetchNewsletterMailReceivers(): Promise> { + const newsletterId = useNewsletterStore().activeNewsletter; + return http.get(`/admin/newsletter/${newsletterId}/mailrecipients`); + }, createNewsletterMailPreview() { this.sendingPreview = "loading"; const newsletterId = useNewsletterStore().activeNewsletter; @@ -116,7 +124,7 @@ export const useNewsletterPrintoutStore = defineStore("newsletterPrintout", { chunk.split("//").forEach((r) => { if (r.trim() != "") { let data = JSON.parse(r); - this.pdfSourceMessages.push(data); + this.pdfSourceMessages.unshift(data); let type: NotificationType = "info"; let timeout = undefined; if (data.factor == "failed") { @@ -138,7 +146,7 @@ export const useNewsletterPrintoutStore = defineStore("newsletterPrintout", { chunk.split("//").forEach((r) => { if (r.trim() != "") { let data = JSON.parse(r); - this.mailSourceMessages.push(data); + this.mailSourceMessages.unshift(data); let type: NotificationType = "info"; let timeout = undefined; if (data.factor == "failed") { diff --git a/src/stores/admin/club/protocol/protocolAgenda.ts b/src/stores/admin/club/protocol/protocolAgenda.ts index b032a3a..1341b84 100644 --- a/src/stores/admin/club/protocol/protocolAgenda.ts +++ b/src/stores/admin/club/protocol/protocolAgenda.ts @@ -21,7 +21,10 @@ export const useProtocolAgendaStore = defineStore("protocolAgenda", { }, getters: { detectedChangeProtocolAgenda: (state) => - !isEqual(state.origin, state.agenda) && state.syncingProtocolAgenda != "syncing", + !isEqual( + state.origin.sort((a, b) => a.id - b.id), + state.agenda.sort((a, b) => a.id - b.id) + ) && state.syncingProtocolAgenda != "syncing", }, actions: { setProtocolAgendaSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") { diff --git a/src/stores/admin/club/protocol/protocolDecision.ts b/src/stores/admin/club/protocol/protocolDecision.ts index ade8210..33b4da9 100644 --- a/src/stores/admin/club/protocol/protocolDecision.ts +++ b/src/stores/admin/club/protocol/protocolDecision.ts @@ -22,7 +22,10 @@ export const useProtocolDecisionStore = defineStore("protocolDecision", { }, getters: { detectedChangeProtocolDecision: (state) => - !isEqual(state.origin, state.decision) && state.syncingProtocolDecision != "syncing", + !isEqual( + state.origin.sort((a, b) => a.id - b.id), + state.decision.sort((a, b) => a.id - b.id) + ) && state.syncingProtocolDecision != "syncing", }, actions: { setProtocolDecisionSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") { diff --git a/src/stores/admin/club/protocol/protocolVoting.ts b/src/stores/admin/club/protocol/protocolVoting.ts index dd2c5fb..6b75c04 100644 --- a/src/stores/admin/club/protocol/protocolVoting.ts +++ b/src/stores/admin/club/protocol/protocolVoting.ts @@ -22,7 +22,10 @@ export const useProtocolVotingStore = defineStore("protocolVoting", { }, getters: { detectedChangeProtocolVoting: (state) => - !isEqual(state.origin, state.voting) && state.syncingProtocolVoting != "syncing", + !isEqual( + state.origin.sort((a, b) => a.id - b.id), + state.voting.sort((a, b) => a.id - b.id) + ) && state.syncingProtocolVoting != "syncing", }, actions: { setProtocolVotingSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") { diff --git a/src/stores/admin/club/queryBuilder.ts b/src/stores/admin/club/queryBuilder.ts index d70cd66..2aad8af 100644 --- a/src/stores/admin/club/queryBuilder.ts +++ b/src/stores/admin/club/queryBuilder.ts @@ -13,8 +13,7 @@ export const useQueryBuilderStore = defineStore("queryBuilder", { 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, + activeQueryId: undefined as undefined | string, }; }, actions: { diff --git a/src/stores/admin/configuration/queryStore.ts b/src/stores/admin/configuration/queryStore.ts index 772117e..451cbca 100644 --- a/src/stores/admin/configuration/queryStore.ts +++ b/src/stores/admin/configuration/queryStore.ts @@ -31,7 +31,7 @@ export const useQueryStoreStore = defineStore("queryStore", { this.loading = "failed"; }); }, - fetchQueryById(id: number): Promise> { + fetchQueryById(id: string): Promise> { return http.get(`/admin/querystore/${id}`); }, triggerSave() { diff --git a/src/viewmodels/admin/club/newsletter/newsletter.models.ts b/src/viewmodels/admin/club/newsletter/newsletter.models.ts index 5a85299..31926bc 100644 --- a/src/viewmodels/admin/club/newsletter/newsletter.models.ts +++ b/src/viewmodels/admin/club/newsletter/newsletter.models.ts @@ -8,7 +8,7 @@ export interface NewsletterViewModel { newsletterText: string; newsletterSignatur: string; isSent: boolean; - recipientsByQueryId?: number | null; + recipientsByQueryId?: string | null; recipientsByQuery?: QueryViewModel | null; } @@ -23,7 +23,7 @@ export interface SyncNewsletterViewModel { newsletterTitle: string; newsletterText: string; newsletterSignatur: string; - recipientsByQueryId?: number; + recipientsByQueryId?: string; } export interface SendNewsletterViewModel { diff --git a/src/viewmodels/admin/configuration/query.models.ts b/src/viewmodels/admin/configuration/query.models.ts index c6d1c84..4640630 100644 --- a/src/viewmodels/admin/configuration/query.models.ts +++ b/src/viewmodels/admin/configuration/query.models.ts @@ -7,7 +7,7 @@ export interface TableMeta { } export interface QueryViewModel { - id: number; + id: string; title: string; query: string | DynamicQueryStructure; } @@ -18,6 +18,6 @@ export interface CreateQueryViewModel { } export interface UpdateQueryViewModel { - id: number; + id: string; query: string | DynamicQueryStructure; } diff --git a/src/views/admin/club/newsletter/NewsletterPrintout.vue b/src/views/admin/club/newsletter/NewsletterPrintout.vue index 0580400..3fd49ef 100644 --- a/src/views/admin/club/newsletter/NewsletterPrintout.vue +++ b/src/views/admin/club/newsletter/NewsletterPrintout.vue @@ -27,7 +27,7 @@ primary class="!w-fit whitespace-nowrap flex flex-row gap-2" :disabled="printing != undefined" - @click="createNewsletterPrintout" + @click="openPdfCommit" > Newsletter drucken @@ -39,7 +39,7 @@ primary class="!w-fit whitespace-nowrap flex flex-row gap-2" :disabled="sending != undefined" - @click="createNewsletterSend" + @click="openMailCommit" > Mails versenden @@ -108,10 +108,8 @@ export default defineComponent({ ...mapActions(useModalStore, ["openModal"]), ...mapActions(useNewsletterPrintoutStore, [ "fetchNewsletterPrintout", - "createNewsletterPrintout", "fetchNewsletterPrintoutById", "createNewsletterMailPreview", - "createNewsletterSend", ]), openPdfShow(filename?: string) { this.openModal( @@ -132,6 +130,20 @@ export default defineComponent({ }) .catch(() => {}); }, + openPdfCommit() { + this.openModal( + markRaw( + defineAsyncComponent(() => import("@/components/admin/club/newsletter/NewsletterPrintingRecipientsModal.vue")) + ) + ); + }, + openMailCommit() { + this.openModal( + markRaw( + defineAsyncComponent(() => import("@/components/admin/club/newsletter/NewsletterMailRecipientsModal.vue")) + ) + ); + }, openPdfLogs() { this.openModal( markRaw( diff --git a/src/views/admin/club/newsletter/NewsletterRecipients.vue b/src/views/admin/club/newsletter/NewsletterRecipients.vue index a6f2b5c..568dd0f 100644 --- a/src/views/admin/club/newsletter/NewsletterRecipients.vue +++ b/src/views/admin/club/newsletter/NewsletterRecipients.vue @@ -134,10 +134,10 @@ export default defineComponent({ if (val == "def") { this.activeNewsletterObj.recipientsByQueryId = null; this.activeNewsletterObj.recipientsByQuery = null; - } else if (this.queries.find((q) => q.id == parseInt(val))) { - this.activeNewsletterObj.recipientsByQueryId = parseInt(val); - this.activeNewsletterObj.recipientsByQuery = cloneDeep(this.queries.find((q) => q.id == parseInt(val))); - this.sendQuery(0, 1000, this.recipientsByQuery?.query); + } else if (this.queries.find((q) => q.id == val)) { + this.activeNewsletterObj.recipientsByQueryId = val; + this.activeNewsletterObj.recipientsByQuery = cloneDeep(this.queries.find((q) => q.id == val)); + this.sendQuery(0, 0, this.recipientsByQuery?.query, true); } }, }, @@ -171,7 +171,7 @@ export default defineComponent({ }, loadQuery() { if (this.recipientsByQuery) { - this.sendQuery(0, 1000, this.recipientsByQuery.query); + this.sendQuery(0, 0, this.recipientsByQuery.query, true); } }, }, diff --git a/vite.config.ts b/vite.config.ts index a967155..222a50f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -58,6 +58,14 @@ export default defineConfig({ }, ], }, + workbox: { + runtimeCaching: [ + { + urlPattern: /^\/api\//, + handler: "NetworkFirst", + }, + ], + }, }), ], resolve: {