#15-messages #22
6 changed files with 81 additions and 17 deletions
|
@ -11,7 +11,7 @@ export function flattenQueryResult(result: Array<QueryResult>): Array<{ [key: st
|
|||
|
||||
for (const key in row) {
|
||||
const value = row[key];
|
||||
const newKey = prefix ? `${prefix}.${key}` : key;
|
||||
const newKey = prefix ? `${prefix}_${key}` : key;
|
||||
|
||||
if (Array.isArray(value) && value.every((item) => typeof item === "object" && item !== null)) {
|
||||
console.log(value, newKey);
|
||||
|
|
|
@ -2,7 +2,6 @@ import { defineStore } from "pinia";
|
|||
import { http } from "@/serverCom";
|
||||
import type { TableMeta } from "@/viewmodels/admin/query.models";
|
||||
import type { DynamicQueryStructure, FieldType } from "@/types/dynamicQueries";
|
||||
import { flattenQueryResult } from "@/helpers/queryFormatter";
|
||||
|
||||
export const useQueryBuilderStore = defineStore("queryBuilder", {
|
||||
state: () => {
|
||||
|
@ -31,23 +30,21 @@ export const useQueryBuilderStore = defineStore("queryBuilder", {
|
|||
this.loading = "failed";
|
||||
});
|
||||
},
|
||||
sendQuery(offset = 0, count = 25) {
|
||||
sendQuery(offset = 0, count = 25, query?: DynamicQueryStructure | string) {
|
||||
this.queryError = "";
|
||||
this.data = [];
|
||||
this.totalLength = 0;
|
||||
if (this.query == undefined || this.query == "" || (typeof this.query != "string" && this.query.table == ""))
|
||||
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: this.query,
|
||||
query: queryToSend,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.data.stats == "success") {
|
||||
this.data = flattenQueryResult(result.data.rows).map((row) => ({
|
||||
id: row.id ?? "", // Ensure id is present
|
||||
...row,
|
||||
}));
|
||||
this.data = result.data.rows;
|
||||
this.totalLength = result.data.total;
|
||||
this.loadingData = "fetched";
|
||||
} else {
|
||||
|
|
|
@ -8,8 +8,8 @@ export interface NewsletterViewModel {
|
|||
newsletterText: string;
|
||||
newsletterSignatur: string;
|
||||
isSent: boolean;
|
||||
recipientsByQueryId?: number;
|
||||
recipientsByQuery?: QueryViewModel;
|
||||
recipientsByQueryId?: number | null;
|
||||
recipientsByQuery?: QueryViewModel | null;
|
||||
}
|
||||
|
||||
export interface CreateNewsletterViewModel {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<QuillEditor
|
||||
id="summary"
|
||||
theme="snow"
|
||||
placeholder="Zusammenfassung zur Sitzung..."
|
||||
placeholder="Zusammenfassung zum Newsletter..."
|
||||
style="height: 250px; max-height: 250px; min-height: 250px"
|
||||
contentType="html"
|
||||
:toolbar="toolbarOptions"
|
||||
|
|
|
@ -5,11 +5,27 @@
|
|||
↺ laden fehlgeschlagen
|
||||
</p>
|
||||
|
||||
-- select members by query
|
||||
<select v-model="recipientsByQueryId">
|
||||
<option value="def">Optional</option>
|
||||
<option v-for="query in queries" :key="query.id" :value="query.id">{{ query.title }}</option>
|
||||
</select>
|
||||
<p>Empfänger durch gespeicherte Abfrage</p>
|
||||
<div class="flex flex-col gap-2 grow overflow-y-auto">
|
||||
<div
|
||||
v-for="member in queried"
|
||||
:key="member.id"
|
||||
class="flex flex-row h-fit w-full border border-primary rounded-md bg-primary p-2 text-white justify-between items-center"
|
||||
>
|
||||
<div>
|
||||
<p>{{ member.lastname }}, {{ member.firstname }} {{ member.nameaffix ? `- ${member.nameaffix}` : "" }}</p>
|
||||
<p>Newsletter senden an Typ: {{ member.sendNewsletter?.type.type }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-full">
|
||||
<Combobox v-model="recipients" :disabled="!can('create', 'club', 'newsletter')" multiple>
|
||||
<ComboboxLabel>Empfänger suchen</ComboboxLabel>
|
||||
<ComboboxLabel>weitere Empfänger suchen</ComboboxLabel>
|
||||
<div class="relative mt-1">
|
||||
<ComboboxInput
|
||||
class="rounded-md shadow-sm relative block w-full px-3 py-2 border border-gray-300 focus:border-primary placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-0 focus:z-10 sm:text-sm resize-none"
|
||||
|
@ -64,7 +80,6 @@
|
|||
</div>
|
||||
</Combobox>
|
||||
</div>
|
||||
<br />
|
||||
<p>Ausgewählte Empfänger</p>
|
||||
<div class="flex flex-col gap-2 grow overflow-y-auto">
|
||||
<div
|
||||
|
@ -104,8 +119,12 @@ import { CheckIcon, ChevronUpDownIcon } from "@heroicons/vue/20/solid";
|
|||
import { TrashIcon } from "@heroicons/vue/24/outline";
|
||||
import { useMemberStore } from "@/stores/admin/member";
|
||||
import type { MemberViewModel } from "@/viewmodels/admin/member.models";
|
||||
import { useNewsletterStore } from "@/stores/admin/newsletter";
|
||||
import { useNewsletterRecipientsStore } from "@/stores/admin/newsletterRecipients";
|
||||
import { useAbilityStore } from "@/stores/ability";
|
||||
import { useQueryStoreStore } from "@/stores/admin/queryStore";
|
||||
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
|
@ -113,6 +132,11 @@ export default defineComponent({
|
|||
props: {
|
||||
newsletterId: String,
|
||||
},
|
||||
watch: {
|
||||
recipientsByQuery() {
|
||||
this.loadQuery();
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
query: "" as String,
|
||||
|
@ -120,7 +144,10 @@ export default defineComponent({
|
|||
},
|
||||
computed: {
|
||||
...mapWritableState(useNewsletterRecipientsStore, ["recipients", "loading"]),
|
||||
...mapWritableState(useNewsletterStore, ["activeNewsletterObj"]),
|
||||
...mapState(useMemberStore, ["members"]),
|
||||
...mapState(useQueryStoreStore, ["queries"]),
|
||||
...mapState(useQueryBuilderStore, ["data"]),
|
||||
...mapState(useAbilityStore, ["can"]),
|
||||
filtered(): Array<MemberViewModel> {
|
||||
return this.query === ""
|
||||
|
@ -144,20 +171,60 @@ export default defineComponent({
|
|||
selected(): Array<MemberViewModel> {
|
||||
return this.members.filter((m) => this.recipients.includes(m.id));
|
||||
},
|
||||
queried(): Array<MemberViewModel> {
|
||||
let keys = Object.keys(this.data?.[0] ?? {});
|
||||
let memberKey = keys.find((k) => k.includes("member_id"));
|
||||
return this.members.filter((m) =>
|
||||
this.data
|
||||
.map((t) => ({
|
||||
id: t.id,
|
||||
...(memberKey ? { memberId: t[memberKey] } : {}),
|
||||
}))
|
||||
.some((d) => (d.memberId ?? d.id) == m.id)
|
||||
);
|
||||
},
|
||||
recipientsByQueryId: {
|
||||
get() {
|
||||
return this.activeNewsletterObj?.recipientsByQueryId ?? "def";
|
||||
},
|
||||
set(val: string) {
|
||||
if (this.activeNewsletterObj == undefined) return;
|
||||
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);
|
||||
}
|
||||
},
|
||||
},
|
||||
recipientsByQuery() {
|
||||
return this.activeNewsletterObj?.recipientsByQuery;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetchMembers();
|
||||
this.fetchMembers(0, 1000, true);
|
||||
this.fetchNewsletterRecipients();
|
||||
this.fetchQueries();
|
||||
this.loadQuery();
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useMemberStore, ["fetchMembers"]),
|
||||
...mapActions(useNewsletterRecipientsStore, ["fetchNewsletterRecipients"]),
|
||||
...mapActions(useQueryStoreStore, ["fetchQueries"]),
|
||||
...mapActions(useQueryBuilderStore, ["sendQuery"]),
|
||||
removeSelected(id: number) {
|
||||
let index = this.recipients.findIndex((s) => s == id);
|
||||
if (index != -1) {
|
||||
this.recipients.splice(index, 1);
|
||||
}
|
||||
},
|
||||
loadQuery() {
|
||||
if (this.recipientsByQuery) {
|
||||
this.sendQuery(0, 1000, this.recipientsByQuery.query);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -141,7 +141,7 @@ export default defineComponent({
|
|||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetchMembers();
|
||||
this.fetchMembers(0, 1000, true);
|
||||
this.fetchProtocolPresence();
|
||||
},
|
||||
methods: {
|
||||
|
|
Loading…
Reference in a new issue