Allow to join an open group

Also:

* Refactor interacting with a remote event so that you can interact with
  a remote group as well
* Add a setting for group admins to pick between an open and invite-only
  group
* Fix new groups without posts/todos/resources/events/conversations URL
  set
* Repair local groups that haven't got their
  posts/todos/resources/events/conversations URL set
* Add a scheduled job to refresh remote groups every hour
* Add a user setting to pick when to receive notifications when there's
  new members to approve (will be used when this feature is available)
* Fix pagination for members

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2020-11-06 11:34:32 +01:00
parent 7baad7cafc
commit 7c11807c14
74 changed files with 1174 additions and 626 deletions

View File

@@ -1,13 +1,14 @@
import { mixins } from "vue-class-component";
import { Component, Vue } from "vue-property-decorator";
import { IEvent, IParticipant, ParticipantRole } from "../types/event.model";
import { SnackbarProgrammatic as Snackbar } from "buefy";
import { IParticipant, ParticipantRole } from "../types/participant.model";
import { IEvent } from "../types/event.model";
import {
DELETE_EVENT,
EVENT_PERSON_PARTICIPATION,
FETCH_EVENT,
LEAVE_EVENT,
} from "../graphql/event";
import { SnackbarProgrammatic as Snackbar } from "buefy";
import { IPerson } from "../types/actor";
@Component
@@ -17,7 +18,7 @@ export default class EventMixin extends mixins(Vue) {
actorId: string,
token: string | null = null,
anonymousParticipationConfirmed: boolean | null = null
) {
): Promise<void> {
try {
const { data: resultData } = await this.$apollo.mutate<{ leaveEvent: IParticipant }>({
mutation: LEAVE_EVENT,
@@ -89,7 +90,7 @@ export default class EventMixin extends mixins(Vue) {
this.$notifier.success(this.$t("You have cancelled your participation") as string);
}
protected async openDeleteEventModal(event: IEvent, currentActor: IPerson) {
protected async openDeleteEventModal(event: IEvent, currentActor: IPerson): Promise<void> {
function escapeRegExp(string: string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}
@@ -135,7 +136,7 @@ export default class EventMixin extends mixins(Vue) {
*
* @type {string}
*/
this.$emit("eventDeleted", event.id);
this.$emit("event-deleted", event.id);
this.$buefy.notification.open({
message: this.$t("Event {eventTitle} deleted", { eventTitle }) as string,
@@ -150,6 +151,7 @@ export default class EventMixin extends mixins(Vue) {
}
}
// eslint-disable-next-line class-methods-use-this
urlToHostname(url: string): string | null {
try {
return new URL(url).hostname;

View File

@@ -1,4 +1,5 @@
import { PERSON_MEMBERSHIPS, CURRENT_ACTOR_CLIENT } from "@/graphql/actor";
import { GROUP_MEMBERSHIP_SUBSCRIPTION_CHANGED } from "@/graphql/event";
import { FETCH_GROUP } from "@/graphql/group";
import RouteName from "@/router/name";
import { Group, IActor, IGroup, IPerson, MemberRole } from "@/types/actor";
@@ -29,6 +30,17 @@ import { Component, Vue } from "vue-property-decorator";
id: this.currentActor.id,
};
},
subscribeToMore: {
document: GROUP_MEMBERSHIP_SUBSCRIPTION_CHANGED,
variables() {
return {
actorId: this.currentActor.id,
};
},
skip() {
return !this.currentActor || !this.currentActor.id;
},
},
skip() {
return !this.currentActor || !this.currentActor.id;
},