Fix lint issues, update deps
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
@@ -1,36 +1,53 @@
|
||||
<template>
|
||||
<div class="p-6">
|
||||
<div>
|
||||
<header class="">
|
||||
<h2 class="">{{ $t("Pick an identity") }}</h2>
|
||||
<h2 class="">{{ t("Pick an identity") }}</h2>
|
||||
</header>
|
||||
<section class="">
|
||||
<div class="list is-hoverable list-none">
|
||||
<a
|
||||
class="my-2 block dark:bg-violet-3 rounded-xl p-2"
|
||||
<transition-group
|
||||
tag="ul"
|
||||
class="grid grid-cols-1 gap-y-3 m-5 max-w-md"
|
||||
enter-active-class="duration-300 ease-out"
|
||||
enter-from-class="transform opacity-0"
|
||||
enter-to-class="opacity-100"
|
||||
leave-active-class="duration-200 ease-in"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="transform opacity-0"
|
||||
>
|
||||
<li
|
||||
class="relative focus-within:shadow-lg"
|
||||
v-for="identity in identities"
|
||||
:key="identity.id"
|
||||
:class="{
|
||||
active: currentIdentity && identity.id === currentIdentity.id,
|
||||
}"
|
||||
@click="currentIdentity = identity"
|
||||
:key="identity?.id"
|
||||
>
|
||||
<div class="flex gap-2">
|
||||
<img
|
||||
class="rounded"
|
||||
v-if="identity.avatar"
|
||||
:src="identity.avatar.url"
|
||||
alt=""
|
||||
width="48"
|
||||
height="48"
|
||||
/>
|
||||
<input
|
||||
class="sr-only peer"
|
||||
type="radio"
|
||||
:value="identity"
|
||||
name="availableActors"
|
||||
v-model="currentIdentity"
|
||||
:id="`availableActor-${identity?.id}`"
|
||||
/>
|
||||
<label
|
||||
class="flex flex-wrap p-3 bg-white hover:bg-gray-50 dark:bg-violet-3 dark:hover:bg-violet-3/60 border border-gray-300 rounded-lg cursor-pointer peer-checked:ring-primary peer-checked:ring-2 peer-checked:border-transparent"
|
||||
:for="`availableActor-${identity?.id}`"
|
||||
>
|
||||
<figure class="h-12 w-12" v-if="identity?.avatar">
|
||||
<img
|
||||
class="rounded-full h-full w-full object-cover"
|
||||
:src="identity.avatar.url"
|
||||
alt=""
|
||||
width="48"
|
||||
height="48"
|
||||
/>
|
||||
</figure>
|
||||
<AccountCircle v-else :size="48" />
|
||||
<div class="">
|
||||
<p>@{{ identity.preferredUsername }}</p>
|
||||
<small>{{ identity.name }}</small>
|
||||
<div class="flex-1">
|
||||
<h3>{{ identity?.name }}</h3>
|
||||
<small>{{ `@${identity?.preferredUsername}` }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
</transition-group>
|
||||
</section>
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useI18n } from "vue-i18n";
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
|
||||
@@ -321,7 +321,7 @@ import {
|
||||
import { Dialog } from "@/plugins/dialog";
|
||||
import { Notifier } from "@/plugins/notifier";
|
||||
import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
|
||||
const EVENTS_PER_PAGE = 10;
|
||||
const POSTS_PER_PAGE = 10;
|
||||
|
||||
@@ -308,7 +308,7 @@ import {
|
||||
formatDateTimeString,
|
||||
} from "@/filters/datetime";
|
||||
import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
|
||||
const EVENTS_PER_PAGE = 10;
|
||||
const PARTICIPATIONS_PER_PAGE = 10;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-if="user" class="section">
|
||||
<div v-if="user">
|
||||
<breadcrumbs-nav
|
||||
:links="[
|
||||
{ name: RouteName.ADMIN, text: t('Admin') },
|
||||
@@ -18,10 +18,10 @@
|
||||
<section>
|
||||
<h2 class="text-lg font-bold mb-3">{{ t("Details") }}</h2>
|
||||
<div class="flex flex-col">
|
||||
<div class="overflow-x-auto sm:-mx-6">
|
||||
<div class="overflow-x-auto">
|
||||
<div class="inline-block py-2 min-w-full sm:px-2">
|
||||
<div class="overflow-hidden shadow-md sm:rounded-lg">
|
||||
<table v-if="metadata.length > 0" class="min-w-full">
|
||||
<table v-if="metadata.length > 0" class="table w-full">
|
||||
<tbody>
|
||||
<tr
|
||||
class="border-b"
|
||||
@@ -229,48 +229,46 @@
|
||||
aria-modal
|
||||
>
|
||||
<form @submit.prevent="updateUserRole">
|
||||
<div>
|
||||
<header>
|
||||
<h2 class="modal-card-title">{{ t("Change user role") }}</h2>
|
||||
</header>
|
||||
<section>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.ADMINISTRATOR"
|
||||
>
|
||||
{{ t("Administrator") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.MODERATOR"
|
||||
>
|
||||
{{ t("Moderator") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.USER"
|
||||
>
|
||||
{{ t("User") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-checkbox v-model="newUser.notify">{{
|
||||
t("Notify the user of the change")
|
||||
}}</o-checkbox>
|
||||
</section>
|
||||
<footer class="mt-2 flex gap-2">
|
||||
<o-button @click="isRoleChangeModalActive = false">{{
|
||||
t("Close")
|
||||
}}</o-button>
|
||||
<o-button native-type="submit" variant="primary">{{
|
||||
t("Change role")
|
||||
}}</o-button>
|
||||
</footer>
|
||||
</div>
|
||||
<header>
|
||||
<h2>{{ t("Change user role") }}</h2>
|
||||
</header>
|
||||
<section>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.ADMINISTRATOR"
|
||||
>
|
||||
{{ t("Administrator") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.MODERATOR"
|
||||
>
|
||||
{{ t("Moderator") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.USER"
|
||||
>
|
||||
{{ t("User") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-checkbox v-model="newUser.notify">{{
|
||||
t("Notify the user of the change")
|
||||
}}</o-checkbox>
|
||||
</section>
|
||||
<footer class="mt-2 flex gap-2">
|
||||
<o-button @click="isRoleChangeModalActive = false" outlined>{{
|
||||
t("Close")
|
||||
}}</o-button>
|
||||
<o-button native-type="submit" variant="primary">{{
|
||||
t("Change role")
|
||||
}}</o-button>
|
||||
</footer>
|
||||
</form>
|
||||
</o-modal>
|
||||
<o-modal
|
||||
@@ -284,24 +282,22 @@
|
||||
aria-modal
|
||||
>
|
||||
<form @submit.prevent="confirmUser">
|
||||
<div>
|
||||
<header>
|
||||
<h2>{{ t("Confirm user") }}</h2>
|
||||
</header>
|
||||
<section>
|
||||
<o-checkbox v-model="newUser.notify">{{
|
||||
t("Notify the user of the change")
|
||||
}}</o-checkbox>
|
||||
</section>
|
||||
<footer>
|
||||
<o-button @click="isConfirmationModalActive = false">{{
|
||||
t("Close")
|
||||
}}</o-button>
|
||||
<o-button native-type="submit" variant="primary">{{
|
||||
t("Confirm user")
|
||||
}}</o-button>
|
||||
</footer>
|
||||
</div>
|
||||
<header>
|
||||
<h2>{{ t("Confirm user") }}</h2>
|
||||
</header>
|
||||
<section>
|
||||
<o-checkbox v-model="newUser.notify">{{
|
||||
t("Notify the user of the change")
|
||||
}}</o-checkbox>
|
||||
</section>
|
||||
<footer>
|
||||
<o-button @click="isConfirmationModalActive = false">{{
|
||||
t("Close")
|
||||
}}</o-button>
|
||||
<o-button native-type="submit" variant="primary">{{
|
||||
t("Confirm user")
|
||||
}}</o-button>
|
||||
</footer>
|
||||
</form>
|
||||
</o-modal>
|
||||
</div>
|
||||
@@ -424,7 +420,7 @@ const metadata = computed(
|
||||
},
|
||||
{
|
||||
key: t("Uploaded media total size"),
|
||||
value: formatBytes(user.value.mediaSize, 2, t("0 Bytes")),
|
||||
value: formatBytes(user.value.mediaSize),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -443,10 +443,10 @@ const instanceLanguages = computed({
|
||||
return codeForLanguage(language);
|
||||
})
|
||||
.filter((code) => code !== undefined) as string[];
|
||||
// adminSettings = {
|
||||
// ...adminSettings,
|
||||
// instanceLanguages: newInstanceLanguages,
|
||||
// };
|
||||
settingsToWrite.value = {
|
||||
...settingsToWrite.value,
|
||||
instanceLanguages: newFilteredInstanceLanguages,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -218,10 +218,7 @@
|
||||
</p>
|
||||
<o-dropdown>
|
||||
<template #trigger>
|
||||
<o-button
|
||||
icon-right="dots-horizontal"
|
||||
#default="{ active }"
|
||||
>
|
||||
<o-button icon-right="dots-horizontal">
|
||||
{{ t("Actions") }}
|
||||
</o-button>
|
||||
</template>
|
||||
@@ -260,8 +257,8 @@
|
||||
<o-dropdown-item
|
||||
aria-role="listitem"
|
||||
v-if="canManageEvent || event?.draft"
|
||||
@click="openDeleteEventModalWrapper"
|
||||
@keyup.enter="openDeleteEventModalWrapper"
|
||||
@click="openDeleteEventModal"
|
||||
@keyup.enter="openDeleteEventModal"
|
||||
><span class="flex gap-1">
|
||||
<Delete />
|
||||
{{ t("Delete") }}
|
||||
@@ -386,7 +383,11 @@
|
||||
has-modal-card
|
||||
ref="shareModal"
|
||||
>
|
||||
<share-event-modal :event="event" :eventCapacityOK="eventCapacityOK" />
|
||||
<share-event-modal
|
||||
v-if="event"
|
||||
:event="event"
|
||||
:eventCapacityOK="eventCapacityOK"
|
||||
/>
|
||||
</o-modal>
|
||||
<o-modal
|
||||
v-model:active="isJoinModalActive"
|
||||
@@ -394,34 +395,34 @@
|
||||
ref="participationModal"
|
||||
:close-button-aria-label="t('Close')"
|
||||
>
|
||||
<identity-picker v-model="identity">
|
||||
<identity-picker v-if="identity" v-model="identity">
|
||||
<template #footer>
|
||||
<footer class="modal-card-foot">
|
||||
<button
|
||||
class="button"
|
||||
<footer class="flex gap-2">
|
||||
<o-button
|
||||
outlined
|
||||
ref="cancelButton"
|
||||
@click="isJoinModalActive = false"
|
||||
@keyup.enter="isJoinModalActive = false"
|
||||
>
|
||||
{{ t("Cancel") }}
|
||||
</button>
|
||||
<button
|
||||
</o-button>
|
||||
<o-button
|
||||
v-if="identity"
|
||||
class="button is-primary"
|
||||
variant="primary"
|
||||
ref="confirmButton"
|
||||
@click="
|
||||
event?.joinOptions === EventJoinOptions.RESTRICTED
|
||||
? joinEventWithConfirmation(identity)
|
||||
: joinEvent(identity)
|
||||
? joinEventWithConfirmation(identity as IPerson)
|
||||
: joinEvent(identity as IPerson)
|
||||
"
|
||||
@keyup.enter="
|
||||
event?.joinOptions === EventJoinOptions.RESTRICTED
|
||||
? joinEventWithConfirmation(identity)
|
||||
: joinEvent(identity)
|
||||
? joinEventWithConfirmation(identity as IPerson)
|
||||
: joinEvent(identity as IPerson)
|
||||
"
|
||||
>
|
||||
{{ t("Confirm my particpation") }}
|
||||
</button>
|
||||
</o-button>
|
||||
</footer>
|
||||
</template>
|
||||
</identity-picker>
|
||||
@@ -449,7 +450,10 @@
|
||||
</p>
|
||||
<form
|
||||
@submit.prevent="
|
||||
joinEvent(actorForConfirmation, messageForConfirmation)
|
||||
joinEvent(
|
||||
actorForConfirmation as IPerson,
|
||||
messageForConfirmation
|
||||
)
|
||||
"
|
||||
>
|
||||
<o-field :label="t('Message')">
|
||||
@@ -487,22 +491,13 @@
|
||||
:can-cancel="['escape', 'outside']"
|
||||
>
|
||||
<template #default="props">
|
||||
<!-- <event-map
|
||||
:routingType="routingType"
|
||||
<event-map
|
||||
:routingType="routingType ?? RoutingType.OPENSTREETMAP"
|
||||
:address="event.physicalAddress"
|
||||
@close="props.close"
|
||||
/> -->
|
||||
/>
|
||||
</template>
|
||||
</o-modal>
|
||||
<dialog
|
||||
variant="danger"
|
||||
:title="t('Delete event')"
|
||||
:message="deleteEventMessage"
|
||||
:confirmText="t('Delete {eventTitle}', { eventTitle: event?.title })"
|
||||
:onConfirm="
|
||||
() => (event?.id ? deleteEvent({ eventId: event?.id }) : null)
|
||||
"
|
||||
></dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -514,12 +509,14 @@ import {
|
||||
EventVisibility,
|
||||
MemberRole,
|
||||
ParticipantRole,
|
||||
RoutingType,
|
||||
} from "@/types/enums";
|
||||
import {
|
||||
EVENT_PERSON_PARTICIPATION,
|
||||
EVENT_PERSON_PARTICIPATION_SUBSCRIPTION_CHANGED,
|
||||
// EVENT_PERSON_PARTICIPATION_SUBSCRIPTION_CHANGED,
|
||||
FETCH_EVENT,
|
||||
JOIN_EVENT,
|
||||
LEAVE_EVENT,
|
||||
} from "@/graphql/event";
|
||||
import { IEvent } from "@/types/event.model";
|
||||
import {
|
||||
@@ -543,7 +540,7 @@ import {
|
||||
isParticipatingInThisEvent,
|
||||
removeAnonymousParticipation,
|
||||
} from "@/services/AnonymousParticipationStorage";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
import EventMetadataSidebar from "@/components/Event/EventMetadataSidebar.vue";
|
||||
import EventBanner from "@/components/Event/EventBanner.vue";
|
||||
import EventMap from "@/components/Event/EventMap.vue";
|
||||
@@ -583,19 +580,21 @@ import {
|
||||
useAnonymousParticipationConfig,
|
||||
useAnonymousReportsConfig,
|
||||
useEventCategories,
|
||||
useRoutingType,
|
||||
} from "@/composition/apollo/config";
|
||||
import { useCreateReport } from "@/composition/apollo/report";
|
||||
import Share from "vue-material-design-icons/Share.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useProgrammatic } from "@oruga-ui/oruga-next";
|
||||
import { Dialog } from "@/plugins/dialog";
|
||||
import { Notifier } from "@/plugins/notifier";
|
||||
import { AbsintheGraphQLErrors } from "@/types/errors.model";
|
||||
import { useHead } from "@vueuse/head";
|
||||
import { Snackbar } from "@/plugins/snackbar";
|
||||
|
||||
const ShareEventModal = defineAsyncComponent(
|
||||
() => import("@/components/Event/ShareEventModal.vue")
|
||||
);
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
const IntegrationTwitch = defineAsyncComponent(
|
||||
() => import("@/components/Event/Integrations/TwitchIntegration.vue")
|
||||
);
|
||||
@@ -611,6 +610,7 @@ const IntegrationJitsiMeet = defineAsyncComponent(
|
||||
const IntegrationEtherpad = defineAsyncComponent(
|
||||
() => import("@/components/Event/Integrations/EtherpadIntegration.vue")
|
||||
);
|
||||
/* eslint-enable @typescript-eslint/no-unused-vars */
|
||||
|
||||
const props = defineProps<{
|
||||
uuid: string;
|
||||
@@ -629,7 +629,7 @@ const currentActorId = computed(() => currentActor.value?.id);
|
||||
const { loggedUser } = useLoggedUser();
|
||||
const {
|
||||
result: participationsResult,
|
||||
subscribeToMore: subscribeToMoreParticipation,
|
||||
// subscribeToMore: subscribeToMoreParticipation,
|
||||
} = useQuery<{ person: IPerson }>(
|
||||
EVENT_PERSON_PARTICIPATION,
|
||||
() => ({
|
||||
@@ -653,7 +653,7 @@ const {
|
||||
// }));
|
||||
|
||||
const participations = computed(
|
||||
() => participationsResult.value?.person.participations.elements ?? []
|
||||
() => participationsResult.value?.person.participations?.elements ?? []
|
||||
);
|
||||
|
||||
const { person } = usePersonStatusGroup(
|
||||
@@ -680,7 +680,7 @@ const { identities } = useCurrentUserIdentities();
|
||||
// };
|
||||
// },
|
||||
|
||||
const identity = ref<IPerson | null>(null);
|
||||
const identity = ref<IPerson | undefined | null>(null);
|
||||
|
||||
const reportModal = ref();
|
||||
const oldParticipationRole = ref<string | undefined>(undefined);
|
||||
@@ -786,12 +786,6 @@ onMounted(async () => {
|
||||
// return router.push({ name: RouteName.HOME });
|
||||
// });
|
||||
});
|
||||
/**
|
||||
* Delete the event, then redirect to home.
|
||||
*/
|
||||
const openDeleteEventModalWrapper = async (): Promise<void> => {
|
||||
await openDeleteEventModal(event.value);
|
||||
};
|
||||
|
||||
const deleteEventMessage = computed(() => {
|
||||
const participantsLength = event.value?.participantStats.participant;
|
||||
@@ -814,17 +808,62 @@ const deleteEventMessage = computed(() => {
|
||||
})}`;
|
||||
});
|
||||
|
||||
const { mutate: deleteEvent } = useDeleteEvent();
|
||||
const notifier = inject<Notifier>("notifier");
|
||||
const dialog = inject<Dialog>("dialog");
|
||||
|
||||
const openDeleteEventModal = async (
|
||||
event: IEvent | undefined
|
||||
): Promise<void> => {
|
||||
function escapeRegExp(string: string) {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
||||
}
|
||||
const {
|
||||
mutate: deleteEvent,
|
||||
onDone: onDeleteEventDone,
|
||||
onError: onDeleteEventError,
|
||||
} = useDeleteEvent();
|
||||
|
||||
const escapeRegExp = (string: string) => {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
||||
};
|
||||
|
||||
const notifier = inject<Notifier>("notifier");
|
||||
const openDeleteEventModal = () => {
|
||||
dialog?.prompt({
|
||||
title: t("Delete event"),
|
||||
message: deleteEventMessage.value,
|
||||
confirmText: t("Delete event"),
|
||||
cancelText: t("Cancel"),
|
||||
variant: "danger",
|
||||
hasIcon: true,
|
||||
hasInput: true,
|
||||
inputAttrs: {
|
||||
placeholder: event.value?.title,
|
||||
pattern: escapeRegExp(event.value?.title ?? ""),
|
||||
},
|
||||
onConfirm: (result: string) => {
|
||||
console.log("calling delete event", result);
|
||||
if (result.trim() === event.value?.title) {
|
||||
event.value?.id ? deleteEvent({ eventId: event.value?.id }) : null;
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
onDeleteEventDone(() => {
|
||||
router.push({ name: RouteName.MY_EVENTS });
|
||||
});
|
||||
|
||||
onDeleteEventError((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
const {
|
||||
mutate: createReportMutation,
|
||||
onDone: onCreateReportDone,
|
||||
onError: onCreateReportError,
|
||||
} = useCreateReport();
|
||||
|
||||
onCreateReportDone(() => {
|
||||
notifier?.success(t("Event {eventTitle} reported", { eventTitle }));
|
||||
});
|
||||
|
||||
onCreateReportError((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
const reportEvent = async (
|
||||
content: string,
|
||||
@@ -836,22 +875,12 @@ const reportEvent = async (
|
||||
reportModal.value.close();
|
||||
if (!organizer.value) return;
|
||||
|
||||
const { mutate, onDone, onError } = useCreateReport();
|
||||
|
||||
mutate({
|
||||
createReportMutation({
|
||||
eventId: event.value?.id ?? "",
|
||||
reportedId: organizer.value?.id ?? "",
|
||||
content,
|
||||
forward,
|
||||
});
|
||||
|
||||
onDone(() => {
|
||||
notifier?.success(t("Event {eventTitle} reported", { eventTitle }));
|
||||
});
|
||||
|
||||
onError((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
};
|
||||
|
||||
const joinEventWithConfirmation = (actor: IPerson): void => {
|
||||
@@ -876,7 +905,7 @@ const {
|
||||
|
||||
const participationCachedData = store.readQuery<{ person: IPerson }>({
|
||||
query: EVENT_PERSON_PARTICIPATION,
|
||||
variables: { eventId: event.value?.id, actorId: identity.value.id },
|
||||
variables: { eventId: event.value?.id, actorId: identity.value?.id },
|
||||
});
|
||||
|
||||
if (participationCachedData?.person == undefined) {
|
||||
@@ -887,7 +916,7 @@ const {
|
||||
}
|
||||
store.writeQuery({
|
||||
query: EVENT_PERSON_PARTICIPATION,
|
||||
variables: { eventId: event.value?.id, actorId: identity.value.id },
|
||||
variables: { eventId: event.value?.id, actorId: identity.value?.id },
|
||||
data: {
|
||||
person: {
|
||||
...participationCachedData?.person,
|
||||
@@ -934,14 +963,14 @@ const {
|
||||
}));
|
||||
|
||||
const joinEvent = async (
|
||||
identity: IPerson,
|
||||
identityForJoin: IPerson,
|
||||
message: string | null = null
|
||||
): Promise<void> => {
|
||||
isJoinConfirmationModalActive.value = false;
|
||||
isJoinModalActive.value = false;
|
||||
joinEventMutation({
|
||||
eventId: event.value?.id,
|
||||
actorId: identity?.id,
|
||||
actorId: identityForJoin?.id,
|
||||
message,
|
||||
});
|
||||
};
|
||||
@@ -960,8 +989,6 @@ onJoinEventMutationError((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
const dialog = inject<Dialog>("dialog");
|
||||
|
||||
const confirmLeave = (): void => {
|
||||
dialog?.confirm({
|
||||
title: t('Leaving event "{title}"', {
|
||||
@@ -975,10 +1002,11 @@ const confirmLeave = (): void => {
|
||||
),
|
||||
confirmText: t("Leave event"),
|
||||
cancelText: t("Cancel"),
|
||||
type: "danger",
|
||||
variant: "danger",
|
||||
hasIcon: true,
|
||||
onConfirm: () => {
|
||||
if (currentActor.value?.id) {
|
||||
if (event.value && currentActor.value?.id) {
|
||||
console.log("calling leave event");
|
||||
leaveEvent(event.value, currentActor.value.id);
|
||||
}
|
||||
},
|
||||
@@ -1071,14 +1099,14 @@ onFetchEventError(({ graphQLErrors }) =>
|
||||
handleErrors(graphQLErrors as AbsintheGraphQLErrors)
|
||||
);
|
||||
|
||||
const actorIsParticipant = computed((): boolean => {
|
||||
if (actorIsOrganizer.value) return true;
|
||||
// const actorIsParticipant = computed((): boolean => {
|
||||
// if (actorIsOrganizer.value) return true;
|
||||
|
||||
return (
|
||||
participations.value.length > 0 &&
|
||||
participations.value[0].role === ParticipantRole.PARTICIPANT
|
||||
);
|
||||
});
|
||||
// return (
|
||||
// participations.value.length > 0 &&
|
||||
// participations.value[0].role === ParticipantRole.PARTICIPANT
|
||||
// );
|
||||
// });
|
||||
|
||||
const actorIsOrganizer = computed((): boolean => {
|
||||
return (
|
||||
@@ -1101,11 +1129,11 @@ const canManageEvent = computed((): boolean => {
|
||||
return actorIsOrganizer.value || hasGroupPrivileges.value;
|
||||
});
|
||||
|
||||
const endDate = computed((): string | undefined => {
|
||||
return event.value?.endsOn && event.value.endsOn > event.value.beginsOn
|
||||
? event.value.endsOn
|
||||
: event.value?.beginsOn;
|
||||
});
|
||||
// const endDate = computed((): string | undefined => {
|
||||
// return event.value?.endsOn && event.value.endsOn > event.value.beginsOn
|
||||
// ? event.value.endsOn
|
||||
// : event.value?.beginsOn;
|
||||
// });
|
||||
|
||||
const maximumAttendeeCapacity = computed((): number | undefined => {
|
||||
return event.value?.options?.maximumAttendeeCapacity;
|
||||
@@ -1122,21 +1150,22 @@ const eventCapacityOK = computed((): boolean => {
|
||||
);
|
||||
});
|
||||
|
||||
const numberOfPlacesStillAvailable = computed((): number | undefined => {
|
||||
if (event.value?.draft) return maximumAttendeeCapacity.value;
|
||||
return (
|
||||
(maximumAttendeeCapacity.value ?? 0) -
|
||||
(event.value?.participantStats.participant ?? 0)
|
||||
);
|
||||
});
|
||||
// const numberOfPlacesStillAvailable = computed((): number | undefined => {
|
||||
// if (event.value?.draft) return maximumAttendeeCapacity.value;
|
||||
// return (
|
||||
// (maximumAttendeeCapacity.value ?? 0) -
|
||||
// (event.value?.participantStats.participant ?? 0)
|
||||
// );
|
||||
// });
|
||||
|
||||
const anonymousParticipationConfirmed = async (): Promise<boolean> => {
|
||||
return isParticipatingInThisEvent(props.uuid);
|
||||
};
|
||||
|
||||
const cancelAnonymousParticipation = async (): Promise<void> => {
|
||||
if (!event.value || !anonymousActorId.value) return;
|
||||
const token = (await getLeaveTokenForParticipation(props.uuid)) as string;
|
||||
await leaveEvent(event.value, anonymousActorId.value, token);
|
||||
leaveEvent(event.value, anonymousActorId.value, token);
|
||||
await removeAnonymousParticipation(props.uuid);
|
||||
anonymousParticipation.value = null;
|
||||
};
|
||||
@@ -1192,19 +1221,134 @@ const integrations = computed((): Record<string, IEventMetadataDescription> => {
|
||||
|
||||
const showMap = ref(false);
|
||||
|
||||
const routingType = computed((): string | undefined => {
|
||||
return config.value?.maps?.routing?.type;
|
||||
});
|
||||
const { routingType } = useRoutingType();
|
||||
|
||||
const eventCategory = computed((): string | undefined => {
|
||||
if (event.value?.category === "MEETING") {
|
||||
return undefined;
|
||||
}
|
||||
return (eventCategories.value ?? []).find((eventCategory) => {
|
||||
return eventCategory.id === event.value?.category;
|
||||
return (eventCategories.value ?? []).find((eventCategoryToFind) => {
|
||||
return eventCategoryToFind.id === event.value?.category;
|
||||
})?.label as string;
|
||||
});
|
||||
|
||||
const {
|
||||
mutate: leaveEventMutation,
|
||||
onDone: onLeaveEventMutationDone,
|
||||
onError: onLeaveEventMutationError,
|
||||
} = useMutation<{ leaveEvent: { actor: { id: string } } }>(LEAVE_EVENT, () => ({
|
||||
update: (
|
||||
store: ApolloCache<{
|
||||
leaveEvent: IParticipant;
|
||||
}>,
|
||||
{ data }: FetchResult,
|
||||
{ context, variables }
|
||||
) => {
|
||||
if (data == null) return;
|
||||
let participation;
|
||||
|
||||
const token = context?.token;
|
||||
const actorId = variables?.actorId;
|
||||
const localEventId = variables?.eventId;
|
||||
const eventUUID = context?.eventUUID;
|
||||
const isAnonymousParticipationConfirmed =
|
||||
context?.isAnonymousParticipationConfirmed;
|
||||
|
||||
if (!token) {
|
||||
const participationCachedData = store.readQuery<{
|
||||
person: IPerson;
|
||||
}>({
|
||||
query: EVENT_PERSON_PARTICIPATION,
|
||||
variables: { eventId: localEventId, actorId },
|
||||
});
|
||||
if (participationCachedData == null) return;
|
||||
const { person: cachedPerson } = participationCachedData;
|
||||
[participation] = cachedPerson?.participations?.elements ?? [undefined];
|
||||
|
||||
store.modify({
|
||||
id: `Person:${actorId}`,
|
||||
fields: {
|
||||
participations() {
|
||||
return {
|
||||
elements: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const eventCachedData = store.readQuery<{ event: IEvent }>({
|
||||
query: FETCH_EVENT,
|
||||
variables: { uuid: eventUUID },
|
||||
});
|
||||
if (eventCachedData == null) return;
|
||||
const { event: eventCached } = eventCachedData;
|
||||
if (eventCached === null) {
|
||||
console.error("Cannot update event cache, because of null value.");
|
||||
return;
|
||||
}
|
||||
const participantStats = { ...eventCached.participantStats };
|
||||
if (participation && participation?.role === ParticipantRole.NOT_APPROVED) {
|
||||
participantStats.notApproved -= 1;
|
||||
} else if (isAnonymousParticipationConfirmed === false) {
|
||||
participantStats.notConfirmed -= 1;
|
||||
} else {
|
||||
participantStats.going -= 1;
|
||||
participantStats.participant -= 1;
|
||||
}
|
||||
store.writeQuery({
|
||||
query: FETCH_EVENT,
|
||||
variables: { uuid: eventUUID },
|
||||
data: {
|
||||
event: {
|
||||
...eventCached,
|
||||
participantStats,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
const leaveEvent = (
|
||||
eventToLeave: IEvent,
|
||||
actorId: string,
|
||||
token: string | null = null,
|
||||
isAnonymousParticipationConfirmed: boolean | null = null
|
||||
): void => {
|
||||
leaveEventMutation(
|
||||
{
|
||||
eventId: eventToLeave.id,
|
||||
actorId,
|
||||
token,
|
||||
},
|
||||
{
|
||||
context: {
|
||||
token,
|
||||
isAnonymousParticipationConfirmed,
|
||||
eventUUID: eventToLeave.uuid,
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
onLeaveEventMutationDone(({ data }) => {
|
||||
if (data) {
|
||||
notifier?.success(t("You have cancelled your participation"));
|
||||
}
|
||||
});
|
||||
|
||||
const snackbar = inject<Snackbar>("snackbar");
|
||||
|
||||
onLeaveEventMutationError((error) => {
|
||||
snackbar?.open({
|
||||
message: error.message,
|
||||
variant: "danger",
|
||||
position: "bottom",
|
||||
});
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
useHead({
|
||||
title: computed(() => eventTitle.value ?? ""),
|
||||
meta: [{ name: "description", content: eventDescription.value }],
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
<event-participation-card
|
||||
v-if="'role' in element"
|
||||
:participation="element"
|
||||
:options="{ hideDate: false }"
|
||||
@event-deleted="eventDeleted"
|
||||
class="participation"
|
||||
/>
|
||||
|
||||
@@ -283,7 +283,7 @@ import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import Incognito from "vue-material-design-icons/Incognito.vue";
|
||||
import EmptyContent from "@/components/Utils/EmptyContent.vue";
|
||||
import { Notifier } from "@/plugins/notifier";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
|
||||
const PARTICIPANTS_PER_PAGE = 10;
|
||||
const MESSAGE_ELLIPSIS_LENGTH = 130;
|
||||
|
||||
@@ -267,7 +267,7 @@ import {
|
||||
import { formatTimeString, formatDateString } from "@/filters/datetime";
|
||||
import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import { Notifier } from "@/plugins/notifier";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ import { IGroup, usernameWithDomain, displayName } from "@/types/actor";
|
||||
import { ActivityType } from "@/types/enums";
|
||||
import { Paginate } from "@/types/paginate";
|
||||
import { IActivity } from "../../types/activity.model";
|
||||
import Observer from "../../components/Utils/Observer.vue";
|
||||
import Observer from "../../components/Utils/ObserverElement.vue";
|
||||
import SkeletonActivityItem from "../../components/Activity/SkeletonActivityItem.vue";
|
||||
import RouteName from "../../router/name";
|
||||
import TimelineText from "vue-material-design-icons/TimelineText.vue";
|
||||
|
||||
@@ -219,7 +219,7 @@ import {
|
||||
displayName,
|
||||
} from "@/types/actor";
|
||||
import RouteName from "@/router/name";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
import LazyImageWrapper from "@/components/Image/LazyImageWrapper.vue";
|
||||
import ActorInline from "@/components/Account/ActorInline.vue";
|
||||
import { formatDistanceToNowStrict, Locale } from "date-fns";
|
||||
|
||||
@@ -202,7 +202,6 @@ import {
|
||||
InternalRefetchQueriesInclude,
|
||||
} from "@apollo/client/core";
|
||||
import { useMutation, useQuery } from "@vue/apollo-composable";
|
||||
import { useCurrentActorClient } from "@/composition/apollo/actor";
|
||||
import { computed, nextTick, reactive, ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { integerTransformer, useRouteQuery } from "vue-use-route-query";
|
||||
@@ -275,7 +274,7 @@ const moveModal = ref(false);
|
||||
const renameModal = ref(false);
|
||||
const modalError = ref("");
|
||||
|
||||
const resourceRenameInput = ref<HTMLElement>();
|
||||
const resourceRenameInput = ref<any>();
|
||||
const modalNewResourceInput = ref<HTMLElement>();
|
||||
const modalNewResourceLinkInput = ref<HTMLElement>();
|
||||
|
||||
@@ -307,7 +306,7 @@ const {
|
||||
refetchQueries: () => postRefreshQueries(),
|
||||
}));
|
||||
|
||||
createResourceDone(({ data }) => {
|
||||
createResourceDone(() => {
|
||||
createLinkResourceModal.value = false;
|
||||
createResourceModal.value = false;
|
||||
newResource.title = "";
|
||||
@@ -447,25 +446,25 @@ const { mutate: deleteResource, onError: onDeleteResourceError } = useMutation(
|
||||
|
||||
onDeleteResourceError((e) => console.error(e));
|
||||
|
||||
const handleRename = async (resource: IResource): Promise<void> => {
|
||||
const handleRename = async (resourceToRename: IResource): Promise<void> => {
|
||||
renameModal.value = true;
|
||||
updatedResource.value = { ...resource };
|
||||
updatedResource.value = { ...resourceToRename };
|
||||
await nextTick();
|
||||
resourceRenameInput.value?.$el.focus();
|
||||
resourceRenameInput.value?.$el.querySelector("input")?.select();
|
||||
};
|
||||
|
||||
const handleMove = (resource: IResource): void => {
|
||||
const handleMove = (resourceToMove: IResource): void => {
|
||||
moveModal.value = true;
|
||||
updatedResource.value = { ...resource };
|
||||
updatedResource.value = { ...resourceToMove };
|
||||
};
|
||||
|
||||
const moveResource = async (
|
||||
resource: IResource,
|
||||
resourceToMove: IResource,
|
||||
oldParent: IResource | undefined
|
||||
): Promise<void> => {
|
||||
const parentPath = oldParent && oldParent.path ? oldParent.path || "/" : "/";
|
||||
await updateResource(resource, parentPath);
|
||||
await updateResource(resourceToMove, parentPath);
|
||||
moveModal.value = false;
|
||||
};
|
||||
|
||||
@@ -501,10 +500,10 @@ const { mutate: updateResourceMutation } = useMutation<{
|
||||
console.error("Cannot update resource cache, because of null value.");
|
||||
return;
|
||||
}
|
||||
const updatedResource: IResource = data.updateResource;
|
||||
const postUpdatedResource: IResource = data.updateResource;
|
||||
|
||||
const updatedElementList = oldParentCachedResource.children.elements.filter(
|
||||
(cachedResource) => cachedResource.id !== updatedResource.id
|
||||
(cachedResource) => cachedResource.id !== postUpdatedResource.id
|
||||
);
|
||||
|
||||
store.writeQuery({
|
||||
@@ -526,14 +525,14 @@ const { mutate: updateResourceMutation } = useMutation<{
|
||||
console.debug("Finished removing ressource from old parent");
|
||||
|
||||
console.debug("Adding resource to new parent");
|
||||
if (!updatedResource.parent || !updatedResource.parent.path) {
|
||||
if (!postUpdatedResource.parent || !postUpdatedResource.parent.path) {
|
||||
console.debug("No cache found for new parent");
|
||||
return;
|
||||
}
|
||||
const newParentCachedData = store.readQuery<{ resource: IResource }>({
|
||||
query: GET_RESOURCE,
|
||||
variables: {
|
||||
path: updatedResource.parent.path,
|
||||
path: postUpdatedResource.parent.path,
|
||||
username: resource.value.actor.preferredUsername,
|
||||
},
|
||||
});
|
||||
@@ -547,7 +546,7 @@ const { mutate: updateResourceMutation } = useMutation<{
|
||||
store.writeQuery({
|
||||
query: GET_RESOURCE,
|
||||
variables: {
|
||||
path: updatedResource.parent.path,
|
||||
path: postUpdatedResource.parent.path,
|
||||
username: resource.value.actor.preferredUsername,
|
||||
},
|
||||
data: {
|
||||
@@ -565,15 +564,15 @@ const { mutate: updateResourceMutation } = useMutation<{
|
||||
}));
|
||||
|
||||
const updateResource = async (
|
||||
resource: IResource,
|
||||
resourceToUpdate: IResource,
|
||||
parentPath: string | null = null
|
||||
): Promise<void> => {
|
||||
updateResourceMutation(
|
||||
{
|
||||
id: resource.id,
|
||||
title: resource.title,
|
||||
parentId: resource.parent ? resource.parent.id : null,
|
||||
path: resource.path,
|
||||
id: resourceToUpdate.id,
|
||||
title: resourceToUpdate.title,
|
||||
parentId: resourceToUpdate.parent ? resourceToUpdate.parent.id : null,
|
||||
path: resourceToUpdate.path,
|
||||
},
|
||||
{ context: { parentPath } }
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user