#15-messages #22
41 changed files with 347 additions and 62 deletions
|
@ -15,7 +15,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, type PropType } from "vue";
|
import { defineComponent, type PropType } from "vue";
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
import type { ProtocolViewModel } from "../../../../viewmodels/admin/protocol.models";
|
import type { ProtocolViewModel } from "@/viewmodels/admin/protocol.models";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
|
@ -20,8 +20,8 @@ import { useProtocolStore } from "@/stores/admin/protocol";
|
||||||
import { ArrowPathIcon, CloudArrowUpIcon, CloudIcon, ExclamationTriangleIcon } from "@heroicons/vue/24/outline";
|
import { ArrowPathIcon, CloudArrowUpIcon, CloudIcon, ExclamationTriangleIcon } from "@heroicons/vue/24/outline";
|
||||||
import { useProtocolAgendaStore } from "@/stores/admin/protocolAgenda";
|
import { useProtocolAgendaStore } from "@/stores/admin/protocolAgenda";
|
||||||
import { useProtocolPresenceStore } from "@/stores/admin/protocolPresence";
|
import { useProtocolPresenceStore } from "@/stores/admin/protocolPresence";
|
||||||
import { useProtocolDecisionStore } from "../../../../stores/admin/protocolDecision";
|
import { useProtocolDecisionStore } from "@/stores/admin/protocolDecision";
|
||||||
import { useProtocolVotingStore } from "../../../../stores/admin/protocolVoting";
|
import { useProtocolVotingStore } from "@/stores/admin/protocolVoting";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
|
@ -30,7 +30,7 @@ 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 { useQueryStoreStore } from "@/stores/admin/queryStore";
|
import { useQueryStoreStore } from "@/stores/admin/queryStore";
|
||||||
import { useTemplateStore } from "../../../../stores/admin/template";
|
import { useTemplateStore } from "@/stores/admin/template";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
|
@ -35,7 +35,7 @@ import { mapState, mapActions } from "pinia";
|
||||||
import { PencilIcon, TrashIcon, DocumentDuplicateIcon } from "@heroicons/vue/24/outline";
|
import { PencilIcon, TrashIcon, DocumentDuplicateIcon } from "@heroicons/vue/24/outline";
|
||||||
import { useAbilityStore } from "@/stores/ability";
|
import { useAbilityStore } from "@/stores/ability";
|
||||||
import { useModalStore } from "@/stores/modal";
|
import { useModalStore } from "@/stores/modal";
|
||||||
import type { TemplateViewModel } from "../../../../viewmodels/admin/template.models";
|
import type { TemplateViewModel } from "@/viewmodels/admin/template.models";
|
||||||
import { useTemplateStore } from "@/stores/admin/template";
|
import { useTemplateStore } from "@/stores/admin/template";
|
||||||
import Spinner from "@/components/Spinner.vue";
|
import Spinner from "@/components/Spinner.vue";
|
||||||
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||||
|
|
|
@ -47,9 +47,9 @@
|
||||||
import { defineAsyncComponent, defineComponent, markRaw, type PropType } from "vue";
|
import { defineAsyncComponent, defineComponent, markRaw, type PropType } from "vue";
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
import { ArchiveBoxArrowDownIcon, ArchiveBoxXMarkIcon, EyeIcon } from "@heroicons/vue/24/outline";
|
import { ArchiveBoxArrowDownIcon, ArchiveBoxXMarkIcon, EyeIcon } from "@heroicons/vue/24/outline";
|
||||||
import type { TemplateUsageViewModel } from "../../../../viewmodels/admin/templateUsage.models";
|
import type { TemplateUsageViewModel } from "@/viewmodels/admin/templateUsage.models";
|
||||||
import { useTemplateStore } from "../../../../stores/admin/template";
|
import { useTemplateStore } from "@/stores/admin/template";
|
||||||
import { useTemplateUsageStore } from "../../../../stores/admin/templateUsage";
|
import { useTemplateUsageStore } from "@/stores/admin/templateUsage";
|
||||||
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";
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineAsyncComponent, defineComponent, markRaw, type PropType } from "vue";
|
import { defineAsyncComponent, defineComponent, markRaw, type PropType } from "vue";
|
||||||
import { mapActions, mapState, mapWritableState } from "pinia";
|
import { mapActions, mapState, mapWritableState } from "pinia";
|
||||||
import type { DynamicQueryStructure } from "../../types/dynamicQueries";
|
import type { DynamicQueryStructure } from "@/types/dynamicQueries";
|
||||||
import {
|
import {
|
||||||
ArchiveBoxArrowDownIcon,
|
ArchiveBoxArrowDownIcon,
|
||||||
CommandLineIcon,
|
CommandLineIcon,
|
||||||
|
@ -97,8 +97,8 @@ import {
|
||||||
TrashIcon,
|
TrashIcon,
|
||||||
SparklesIcon,
|
SparklesIcon,
|
||||||
} from "@heroicons/vue/24/outline";
|
} from "@heroicons/vue/24/outline";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
import { useModalStore } from "../../stores/modal";
|
import { useModalStore } from "@/stores/modal";
|
||||||
import Table from "./Table.vue";
|
import Table from "./Table.vue";
|
||||||
import { useAbilityStore } from "@/stores/ability";
|
import { useAbilityStore } from "@/stores/ability";
|
||||||
import { useQueryStoreStore } from "@/stores/admin/queryStore";
|
import { useQueryStoreStore } from "@/stores/admin/queryStore";
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, type PropType } from "vue";
|
import { defineComponent, type PropType } from "vue";
|
||||||
import { mapActions, mapState } from "pinia";
|
import { mapActions, mapState } from "pinia";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
|
@ -60,8 +60,8 @@ import {
|
||||||
type ConditionValue,
|
type ConditionValue,
|
||||||
type WhereOperation,
|
type WhereOperation,
|
||||||
type WhereType,
|
type WhereType,
|
||||||
} from "../../types/dynamicQueries";
|
} from "@/types/dynamicQueries";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
import { TrashIcon } from "@heroicons/vue/24/outline";
|
import { TrashIcon } from "@heroicons/vue/24/outline";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, type PropType } from "vue";
|
import { defineComponent, type PropType } from "vue";
|
||||||
import { mapActions, mapState } from "pinia";
|
import { mapActions, mapState } from "pinia";
|
||||||
import type { DynamicQueryStructure } from "../../types/dynamicQueries";
|
import type { DynamicQueryStructure } from "@/types/dynamicQueries";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
import { PlusIcon } from "@heroicons/vue/24/outline";
|
import { PlusIcon } from "@heroicons/vue/24/outline";
|
||||||
import JoinTable from "./JoinTable.vue";
|
import JoinTable from "./JoinTable.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, type PropType } from "vue";
|
import { defineComponent, type PropType } from "vue";
|
||||||
import { mapActions, mapState } from "pinia";
|
import { mapActions, mapState } from "pinia";
|
||||||
import type { DynamicQueryStructure } from "../../types/dynamicQueries";
|
import type { DynamicQueryStructure } from "@/types/dynamicQueries";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
import Table from "./Table.vue";
|
import Table from "./Table.vue";
|
||||||
import { TrashIcon } from "@heroicons/vue/24/outline";
|
import { TrashIcon } from "@heroicons/vue/24/outline";
|
||||||
import { joinTableName } from "@/helpers/queryFormatter";
|
import { joinTableName } from "@/helpers/queryFormatter";
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, type PropType } from "vue";
|
import { defineComponent, type PropType } from "vue";
|
||||||
import { mapActions, mapState } from "pinia";
|
import { mapActions, mapState } from "pinia";
|
||||||
import type { ConditionStructure, WhereType } from "../../types/dynamicQueries";
|
import type { ConditionStructure, WhereType } from "@/types/dynamicQueries";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
import { TrashIcon } from "@heroicons/vue/24/outline";
|
import { TrashIcon } from "@heroicons/vue/24/outline";
|
||||||
import NestedWhere from "./NestedWhere.vue";
|
import NestedWhere from "./NestedWhere.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, type PropType } from "vue";
|
import { defineComponent, type PropType } from "vue";
|
||||||
import { mapActions, mapState } from "pinia";
|
import { mapActions, mapState } from "pinia";
|
||||||
import type { ConditionStructure } from "../../types/dynamicQueries";
|
import type { ConditionStructure } from "@/types/dynamicQueries";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
import NestedCondition from "./NestedCondition.vue";
|
import NestedCondition from "./NestedCondition.vue";
|
||||||
import Condition from "./Condition.vue";
|
import Condition from "./Condition.vue";
|
||||||
import { PlusIcon, RectangleStackIcon } from "@heroicons/vue/24/outline";
|
import { PlusIcon, RectangleStackIcon } from "@heroicons/vue/24/outline";
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, type PropType } from "vue";
|
import { defineComponent, type PropType } from "vue";
|
||||||
import { mapActions, mapState } from "pinia";
|
import { mapActions, mapState } from "pinia";
|
||||||
import type { OrderByStructure } from "../../types/dynamicQueries";
|
import type { OrderByStructure } from "@/types/dynamicQueries";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
import OrderStructure from "./OrderStructure.vue";
|
import OrderStructure from "./OrderStructure.vue";
|
||||||
import { PlusIcon } from "@heroicons/vue/24/outline";
|
import { PlusIcon } from "@heroicons/vue/24/outline";
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, type PropType } from "vue";
|
import { defineComponent, type PropType } from "vue";
|
||||||
import { mapActions, mapState } from "pinia";
|
import { mapActions, mapState } from "pinia";
|
||||||
import type { OrderByStructure, OrderByType } from "../../types/dynamicQueries";
|
import type { OrderByStructure, OrderByType } from "@/types/dynamicQueries";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
import { TrashIcon } from "@heroicons/vue/24/outline";
|
import { TrashIcon } from "@heroicons/vue/24/outline";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, type PropType } from "vue";
|
import { defineComponent, type PropType } from "vue";
|
||||||
import { mapActions, mapState } from "pinia";
|
import { mapActions, mapState } from "pinia";
|
||||||
import type { ConditionStructure, DynamicQueryStructure, OrderByStructure } from "../../types/dynamicQueries";
|
import type { ConditionStructure, DynamicQueryStructure, OrderByStructure } from "@/types/dynamicQueries";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
import ColumnSelect from "./ColumnSelect.vue";
|
import ColumnSelect from "./ColumnSelect.vue";
|
||||||
import Where from "./Where.vue";
|
import Where from "./Where.vue";
|
||||||
import Order from "./Order.vue";
|
import Order from "./Order.vue";
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent } from "vue";
|
import { defineComponent } from "vue";
|
||||||
import { mapState } from "pinia";
|
import { mapState } from "pinia";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
|
@ -33,8 +33,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent, type PropType } from "vue";
|
import { defineComponent, type PropType } from "vue";
|
||||||
import { mapActions, mapState } from "pinia";
|
import { mapActions, mapState } from "pinia";
|
||||||
import type { ConditionStructure } from "../../types/dynamicQueries";
|
import type { ConditionStructure } from "@/types/dynamicQueries";
|
||||||
import { useQueryBuilderStore } from "../../stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
import NestedCondition from "./NestedCondition.vue";
|
import NestedCondition from "./NestedCondition.vue";
|
||||||
import Condition from "./Condition.vue";
|
import Condition from "./Condition.vue";
|
||||||
import { PlusIcon, RectangleStackIcon } from "@heroicons/vue/24/outline";
|
import { PlusIcon, RectangleStackIcon } from "@heroicons/vue/24/outline";
|
||||||
|
|
|
@ -6,7 +6,7 @@ import type {
|
||||||
} from "@/viewmodels/admin/communicationType.models";
|
} from "@/viewmodels/admin/communicationType.models";
|
||||||
import { http } from "@/serverCom";
|
import { http } from "@/serverCom";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosResponse } from "axios";
|
||||||
import type { CommunicationFieldType } from "../../types/fieldTypes";
|
import type { CommunicationFieldType } from "@/types/fieldTypes";
|
||||||
|
|
||||||
export const useCommunicationTypeStore = defineStore("communicationType", {
|
export const useCommunicationTypeStore = defineStore("communicationType", {
|
||||||
state: () => {
|
state: () => {
|
||||||
|
|
105
src/stores/admin/newsletter.ts
Normal file
105
src/stores/admin/newsletter.ts
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
import { defineStore } from "pinia";
|
||||||
|
import type { CreateNewsletterViewModel, SyncNewsletterViewModel } from "@/viewmodels/admin/newsletter.models";
|
||||||
|
import { http } from "@/serverCom";
|
||||||
|
import type { AxiosResponse } from "axios";
|
||||||
|
import type { NewsletterViewModel } from "@/viewmodels/admin/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) => {});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
64
src/stores/admin/newsletterDates.ts
Normal file
64
src/stores/admin/newsletterDates.ts
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
import { defineStore } from "pinia";
|
||||||
|
import { http } from "@/serverCom";
|
||||||
|
import type { NewsletterDatesViewModel, SyncNewsletterDatesViewModel } from "@/viewmodels/admin/newsletterDates.models";
|
||||||
|
import { useProtocolStore } from "./protocol";
|
||||||
|
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, state.dates) && 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 protocolId = useProtocolStore().activeProtocol;
|
||||||
|
return http.get(`/admin/protocol/${protocolId}/agenda`);
|
||||||
|
},
|
||||||
|
async synchronizeActiveNewsletterDates() {
|
||||||
|
this.syncingNewsletterDates = "syncing";
|
||||||
|
const protocolId = useProtocolStore().activeProtocol;
|
||||||
|
|
||||||
|
await http
|
||||||
|
.patch(`/admin/protocol/${protocolId}/synchronize/agenda`, {
|
||||||
|
agenda: differenceWith(this.dates, this.origin, isEqual),
|
||||||
|
})
|
||||||
|
.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) => {});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
65
src/stores/admin/newsletterRecipients.ts
Normal file
65
src/stores/admin/newsletterRecipients.ts
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import { defineStore } from "pinia";
|
||||||
|
import { http } from "@/serverCom";
|
||||||
|
import type {
|
||||||
|
NewsletterRecipientsViewModel,
|
||||||
|
SyncNewsletterRecipientsViewModel,
|
||||||
|
} from "@/viewmodels/admin/newsletterRecipients.models";
|
||||||
|
import { useProtocolStore } from "./protocol";
|
||||||
|
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 protocolId = useProtocolStore().activeProtocol;
|
||||||
|
return http.get(`/admin/protocol/${protocolId}/presence`);
|
||||||
|
},
|
||||||
|
async synchronizeActiveNewsletterRecipients() {
|
||||||
|
this.syncingNewsletterRecipients = "syncing";
|
||||||
|
const protocolId = useProtocolStore().activeProtocol;
|
||||||
|
await http
|
||||||
|
.put(`/admin/protocol/${protocolId}/synchronize/presence`, {
|
||||||
|
presence: 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) => {});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,9 +1,6 @@
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { http } from "@/serverCom";
|
import { http } from "@/serverCom";
|
||||||
import type {
|
import type { ProtocolAgendaViewModel, SyncProtocolAgendaViewModel } from "@/viewmodels/admin/protocolAgenda.models";
|
||||||
ProtocolAgendaViewModel,
|
|
||||||
SyncProtocolAgendaViewModel,
|
|
||||||
} from "../../viewmodels/admin/protocolAgenda.models";
|
|
||||||
import { useProtocolStore } from "./protocol";
|
import { useProtocolStore } from "./protocol";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
import isEqual from "lodash.isequal";
|
import isEqual from "lodash.isequal";
|
||||||
|
|
|
@ -4,7 +4,7 @@ import type { AxiosResponse } from "axios";
|
||||||
import type {
|
import type {
|
||||||
ProtocolDecisionViewModel,
|
ProtocolDecisionViewModel,
|
||||||
SyncProtocolDecisionViewModel,
|
SyncProtocolDecisionViewModel,
|
||||||
} from "../../viewmodels/admin/protocolDecision.models";
|
} from "@/viewmodels/admin/protocolDecision.models";
|
||||||
import { useProtocolStore } from "./protocol";
|
import { useProtocolStore } from "./protocol";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
import isEqual from "lodash.isequal";
|
import isEqual from "lodash.isequal";
|
||||||
|
|
|
@ -4,7 +4,7 @@ import type { AxiosResponse } from "axios";
|
||||||
import type {
|
import type {
|
||||||
ProtocolPresenceViewModel,
|
ProtocolPresenceViewModel,
|
||||||
SyncProtocolPresenceViewModel,
|
SyncProtocolPresenceViewModel,
|
||||||
} from "../../viewmodels/admin/protocolPresence.models";
|
} from "@/viewmodels/admin/protocolPresence.models";
|
||||||
import { useProtocolStore } from "./protocol";
|
import { useProtocolStore } from "./protocol";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
import isEqual from "lodash.isequal";
|
import isEqual from "lodash.isequal";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { http } from "@/serverCom";
|
import { http } from "@/serverCom";
|
||||||
import type { ProtocolPrintoutViewModel } from "../../viewmodels/admin/protocolPrintout.models";
|
import type { ProtocolPrintoutViewModel } from "@/viewmodels/admin/protocolPrintout.models";
|
||||||
import { useProtocolStore } from "./protocol";
|
import { useProtocolStore } from "./protocol";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosResponse } from "axios";
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { http } from "@/serverCom";
|
import { http } from "@/serverCom";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosResponse } from "axios";
|
||||||
import type {
|
import type { ProtocolVotingViewModel, SyncProtocolVotingViewModel } from "@/viewmodels/admin/protocolVoting.models";
|
||||||
ProtocolVotingViewModel,
|
|
||||||
SyncProtocolVotingViewModel,
|
|
||||||
} from "../../viewmodels/admin/protocolVoting.models";
|
|
||||||
import { useProtocolStore } from "./protocol";
|
import { useProtocolStore } from "./protocol";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
import isEqual from "lodash.isequal";
|
import isEqual from "lodash.isequal";
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { http } from "@/serverCom";
|
import { http } from "@/serverCom";
|
||||||
import type { TableMeta } from "../../viewmodels/admin/query.models";
|
import type { TableMeta } from "@/viewmodels/admin/query.models";
|
||||||
import type { DynamicQueryStructure, FieldType } from "../../types/dynamicQueries";
|
import type { DynamicQueryStructure, FieldType } from "@/types/dynamicQueries";
|
||||||
import { flattenQueryResult } from "../../helpers/queryFormatter";
|
import { flattenQueryResult } from "@/helpers/queryFormatter";
|
||||||
|
|
||||||
export const useQueryBuilderStore = defineStore("queryBuilder", {
|
export const useQueryBuilderStore = defineStore("queryBuilder", {
|
||||||
state: () => {
|
state: () => {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import type {
|
||||||
CreateTemplateViewModel,
|
CreateTemplateViewModel,
|
||||||
TemplateViewModel,
|
TemplateViewModel,
|
||||||
UpdateTemplateViewModel,
|
UpdateTemplateViewModel,
|
||||||
} from "../../viewmodels/admin/template.models";
|
} from "@/viewmodels/admin/template.models";
|
||||||
|
|
||||||
export const useTemplateStore = defineStore("template", {
|
export const useTemplateStore = defineStore("template", {
|
||||||
state: () => {
|
state: () => {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { http } from "@/serverCom";
|
import { http } from "@/serverCom";
|
||||||
import type { AxiosResponse } from "axios";
|
import type { AxiosResponse } from "axios";
|
||||||
import type { CreateTemplateViewModel, UpdateTemplateViewModel } from "../../viewmodels/admin/template.models";
|
import type { CreateTemplateViewModel, UpdateTemplateViewModel } from "@/viewmodels/admin/template.models";
|
||||||
import type { TemplateUsageViewModel, UpdateTemplateUsageViewModel } from "../../viewmodels/admin/templateUsage.models";
|
import type { TemplateUsageViewModel, UpdateTemplateUsageViewModel } from "@/viewmodels/admin/templateUsage.models";
|
||||||
import type { PermissionModule } from "../../types/permissionTypes";
|
import type { PermissionModule } from "@/types/permissionTypes";
|
||||||
|
|
||||||
export const useTemplateUsageStore = defineStore("templateUsage", {
|
export const useTemplateUsageStore = defineStore("templateUsage", {
|
||||||
state: () => {
|
state: () => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { CommunicationFieldType } from "../../types/fieldTypes";
|
import type { CommunicationFieldType } from "@/types/fieldTypes";
|
||||||
|
|
||||||
export interface CommunicationTypeViewModel {
|
export interface CommunicationTypeViewModel {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
31
src/viewmodels/admin/newsletter.models.ts
Normal file
31
src/viewmodels/admin/newsletter.models.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import type { QueryViewModel } from "./query.models";
|
||||||
|
|
||||||
|
export interface NewsletterViewModel {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
newsletterTitle: string;
|
||||||
|
newsletterText: string;
|
||||||
|
newsletterSignatur: string;
|
||||||
|
isSent: boolean;
|
||||||
|
recipientsByQueryId?: number;
|
||||||
|
recipientsByQuery?: QueryViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateNewsletterViewModel {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SyncNewsletterViewModel {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
newsletterTitle: string;
|
||||||
|
newsletterText: string;
|
||||||
|
newsletterSignatur: string;
|
||||||
|
recipientsByQueryId?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SendNewsletterViewModel {
|
||||||
|
id: number;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import type { NewsletterConfigType } from "../../enums/newsletterConfigType";
|
import type { NewsletterConfigType } from "@/enums/newsletterConfigType";
|
||||||
import type { CommunicationTypeViewModel } from "./communicationType.models";
|
import type { CommunicationTypeViewModel } from "./communicationType.models";
|
||||||
|
|
||||||
export interface NewsletterConfigViewModel {
|
export interface NewsletterConfigViewModel {
|
||||||
|
|
15
src/viewmodels/admin/newsletterDates.models.ts
Normal file
15
src/viewmodels/admin/newsletterDates.models.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import type { CalendarViewModel } from "./calendar.models";
|
||||||
|
|
||||||
|
export interface NewsletterDatesViewModel {
|
||||||
|
newsletterId: number;
|
||||||
|
calendarId: number;
|
||||||
|
diffTitle: string | null;
|
||||||
|
diffDescription: string | null;
|
||||||
|
calendar: CalendarViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SyncNewsletterDatesViewModel {
|
||||||
|
calendarId: number;
|
||||||
|
diffTitle?: string;
|
||||||
|
diffDescription?: string;
|
||||||
|
}
|
11
src/viewmodels/admin/newsletterRecipients.models.ts
Normal file
11
src/viewmodels/admin/newsletterRecipients.models.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import type { MemberViewModel } from "./member.models";
|
||||||
|
|
||||||
|
export interface NewsletterRecipientsViewModel {
|
||||||
|
newsletterId: number;
|
||||||
|
memberId: number;
|
||||||
|
member: MemberViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SyncNewsletterRecipientsViewModel {
|
||||||
|
memberId: number;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import type { DynamicQueryStructure } from "../../types/dynamicQueries";
|
import type { DynamicQueryStructure } from "@/types/dynamicQueries";
|
||||||
|
|
||||||
export interface TableMeta {
|
export interface TableMeta {
|
||||||
tableName: string;
|
tableName: string;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { PermissionModule } from "../../types/permissionTypes";
|
import type { PermissionModule } from "@/types/permissionTypes";
|
||||||
|
|
||||||
export interface TemplateUsageViewModel {
|
export interface TemplateUsageViewModel {
|
||||||
scope: PermissionModule;
|
scope: PermissionModule;
|
||||||
|
|
|
@ -62,7 +62,7 @@ import { mapActions, mapState, mapWritableState } from "pinia";
|
||||||
import MainTemplate from "@/templates/Main.vue";
|
import MainTemplate from "@/templates/Main.vue";
|
||||||
import Pagination from "@/components/Pagination.vue";
|
import Pagination from "@/components/Pagination.vue";
|
||||||
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
import { useQueryBuilderStore } from "@/stores/admin/queryBuilder";
|
||||||
import BuilderHost from "../../../../components/queryBuilder/BuilderHost.vue";
|
import BuilderHost from "@/components/queryBuilder/BuilderHost.vue";
|
||||||
import type { DynamicQueryStructure, FieldType } from "@/types/dynamicQueries";
|
import type { DynamicQueryStructure, FieldType } from "@/types/dynamicQueries";
|
||||||
import { useQueryStoreStore } from "@/stores/admin/queryStore";
|
import { useQueryStoreStore } from "@/stores/admin/queryStore";
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -23,8 +23,8 @@ import { mapState, mapActions } from "pinia";
|
||||||
import MainTemplate from "@/templates/Main.vue";
|
import MainTemplate from "@/templates/Main.vue";
|
||||||
import { useAbilityStore } from "@/stores/ability";
|
import { useAbilityStore } from "@/stores/ability";
|
||||||
import { useCommunicationTypeStore } from "@/stores/admin/communicationType";
|
import { useCommunicationTypeStore } from "@/stores/admin/communicationType";
|
||||||
import { useNewsletterConfigStore } from "../../../../stores/admin/newsletterConfig";
|
import { useNewsletterConfigStore } from "@/stores/admin/newsletterConfig";
|
||||||
import NewsletterConfigListItem from "../../../../components/admin/settings/newsletterConfig/NewsletterConfigListItem.vue";
|
import NewsletterConfigListItem from "@/components/admin/settings/newsletterConfig/NewsletterConfigListItem.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
|
@ -54,8 +54,8 @@ import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||||
import FailureXMark from "@/components/FailureXMark.vue";
|
import FailureXMark from "@/components/FailureXMark.vue";
|
||||||
import { RouterLink } from "vue-router";
|
import { RouterLink } from "vue-router";
|
||||||
import { configureEditor } from "@/helpers/grapesEditor";
|
import { configureEditor } from "@/helpers/grapesEditor";
|
||||||
import type { TemplateViewModel, UpdateTemplateViewModel } from "../../../../viewmodels/admin/template.models";
|
import type { TemplateViewModel, UpdateTemplateViewModel } from "@/viewmodels/admin/template.models";
|
||||||
import { useTemplateStore } from "../../../../stores/admin/template";
|
import { useTemplateStore } from "@/stores/admin/template";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
import isEqual from "lodash.isequal";
|
import isEqual from "lodash.isequal";
|
||||||
import grapesjs, { Editor } from "grapesjs";
|
import grapesjs, { Editor } from "grapesjs";
|
||||||
|
|
|
@ -16,8 +16,8 @@ import { defineComponent } from "vue";
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
import MainTemplate from "@/templates/Main.vue";
|
import MainTemplate from "@/templates/Main.vue";
|
||||||
import { useTemplateUsageStore } from "@/stores/admin/templateUsage";
|
import { useTemplateUsageStore } from "@/stores/admin/templateUsage";
|
||||||
import TemplateUsageListItem from "../../../../components/admin/settings/templateUsage/TemplateUsageListItem.vue";
|
import TemplateUsageListItem from "@/components/admin/settings/templateUsage/TemplateUsageListItem.vue";
|
||||||
import { useTemplateStore } from "../../../../stores/admin/template";
|
import { useTemplateStore } from "@/stores/admin/template";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
|
@ -8,5 +8,5 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RouterView } from "vue-router";
|
import { RouterView } from "vue-router";
|
||||||
import FullContent from "../../layouts/FullContent.vue";
|
import FullContent from "@/layouts/FullContent.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in a new issue