diff --git a/.changeset/bright-hairs-pay.md b/.changeset/bright-hairs-pay.md new file mode 100644 index 000000000..31a25505f --- /dev/null +++ b/.changeset/bright-hairs-pay.md @@ -0,0 +1,5 @@ +--- +'@churros/app': major +--- + +Remove /posts/:group/create - the URL was not used anywhere in the UI anymore diff --git a/.changeset/fifty-cars-judge.md b/.changeset/fifty-cars-judge.md new file mode 100644 index 000000000..8253b860d --- /dev/null +++ b/.changeset/fifty-cars-judge.md @@ -0,0 +1,5 @@ +--- +'@churros/api': major +--- + +change return type and argument type for Mutation.deleteArticle diff --git a/.changeset/odd-horses-fold.md b/.changeset/odd-horses-fold.md new file mode 100644 index 000000000..33de39797 --- /dev/null +++ b/.changeset/odd-horses-fold.md @@ -0,0 +1,5 @@ +--- +'@churros/app': patch +--- + +make delete button on posts work diff --git a/packages/api/src/modules/posts/resolvers/mutation.delete-article.ts b/packages/api/src/modules/posts/resolvers/mutation.delete-article.ts index fc6e8f4d7..a0533b965 100644 --- a/packages/api/src/modules/posts/resolvers/mutation.delete-article.ts +++ b/packages/api/src/modules/posts/resolvers/mutation.delete-article.ts @@ -1,33 +1,30 @@ -import { builder, log, prisma, publish } from '#lib'; +import { builder, ensureGlobalId, log, prisma, publish } from '#lib'; +import { LocalID } from '#modules/global'; +import { ArticleType, canEditArticle } from '#modules/posts'; builder.mutationField('deleteArticle', (t) => - t.field({ - type: 'Boolean', - args: { id: t.arg.id() }, + t.prismaField({ + type: ArticleType, + errors: {}, + description: 'Supprimer un post', + args: { id: t.arg({ type: LocalID }) }, async authScopes(_, { id }, { user }) { - if (!user) return false; - if (user.canEditGroups) return true; - - const article = await prisma.article.findUniqueOrThrow({ where: { id } }); - - // Who can delete this article? - return ( - // Admins - user.admin || - // The author - user.id === article.authorId || - // Other authors of the group - user.groups.some( - ({ groupId, canEditArticles }) => canEditArticles && groupId === article.groupId, - ) - ); + const post = await prisma.article.findUniqueOrThrow({ + where: { id: ensureGlobalId(id, 'Article') }, + include: canEditArticle.prismaIncludes, + }); + return canEditArticle(post, { authorId: null, group: null }, user); }, - async resolve(_, { id }, { user }) { - await prisma.article.delete({ where: { id } }); + async resolve(query, _, { id }, { user }) { + id = ensureGlobalId(id, 'Article'); await log('article', 'delete', { message: `Article ${id} deleted` }, id, user); + + const result = await prisma.article.delete({ ...query, where: { id } }); + publish(id, 'deleted', id); - return true; + + return result; }, }), ); diff --git a/packages/app/schema.graphql b/packages/app/schema.graphql index aeacee442..accb0c221 100644 --- a/packages/app/schema.graphql +++ b/packages/app/schema.graphql @@ -2371,7 +2371,10 @@ type Mutation @rateLimit(limit: 1200, duration: 600) { """ deduplicateBookings(event: LocalID!): MutationDeduplicateBookingsResult! deleteAnnouncement(id: ID!): Boolean! - deleteArticle(id: ID!): Boolean! + """ + Supprimer un post + """ + deleteArticle(id: LocalID!): MutationDeleteArticleResult! deleteArticlePicture(id: ID!): Boolean! deleteComment(id: ID!): Comment! """ @@ -3343,6 +3346,12 @@ type MutationDeduplicateBookingsSuccess { data: Int! } +union MutationDeleteArticleResult = Error | MutationDeleteArticleSuccess | ZodError + +type MutationDeleteArticleSuccess { + data: Article! +} + union MutationDeleteContributionResult = Error | MutationDeleteContributionSuccess | ZodError type MutationDeleteContributionSuccess { diff --git a/packages/app/src/lib/ROUTES.ts b/packages/app/src/lib/ROUTES.ts index 34ca3b042..2c5ebfebc 100644 --- a/packages/app/src/lib/ROUTES.ts +++ b/packages/app/src/lib/ROUTES.ts @@ -220,9 +220,6 @@ const PAGES = { '/logout': `/logout`, '/logs': `/logs`, '/notifications': `/notifications`, - '/posts/create': (params?: { group?: string | number }) => { - return `/posts${params?.group ? `/${params?.group}` : ''}/create`; - }, '/posts/[id]': (id: string | number, params?: {}) => { return `/posts/${id}`; }, @@ -579,7 +576,6 @@ export type KIT_ROUTES = { '/logout': never; '/logs': never; '/notifications': never; - '/posts/create': 'group'; '/posts/[id]': 'id'; '/posts/[id]/edit': 'id'; '/posts/[id]/edit/body': 'id'; diff --git a/packages/app/src/lib/components/FormArticle.houdini.svelte b/packages/app/src/lib/components/FormArticle.houdini.svelte deleted file mode 100644 index bbdba8d65..000000000 --- a/packages/app/src/lib/components/FormArticle.houdini.svelte +++ /dev/null @@ -1,514 +0,0 @@ - - - { - if (!selectedGroup) return; - const result = await NotificationSendCountQuery.fetch({ - variables: { - group: selectedGroup.uid, - visibility: input.visibility, - }, - }); - if (result.data) ({ notificationsSendCountForArticle } = result.data); - }} -> - - - -{#if $data?.event} - -

- Ce post est lié à l'évènement - -

-
-{:else} - -

- Pour créer un post lié à un évènement, se rendre sur la page de l'évènement puis choisir ⋮ > - Post lié -

-
-{/if} - -
{ - if ( - !input.id && - (input.visibility === Visibility.Public || input.visibility === Visibility.SchoolRestricted) - ) { - openModalWarnNotifications(); - track('post-visibiliy-warning-shown', { visibility: input.visibility }); - } else { - await updateArticle(); - } - }} -> -

- -

-
-
- -
-
- {#if !input.id} - - {:else if selectedGroup} - - - - - Lorem ipsum - - {/if} - -
-

- {#if selectedGroup} - {HELP_VISIBILITY_DYNAMIC([selectedGroup, ...selectedGroup.children])[input.visibility]} - {:else} - {HELP_VISIBILITY[input.visibility]} - {/if} -

-
- - - {#if serverError} - Impossible de sauvegarder les modifications :
{serverError}
- {/if} -
- {#if !input.id} - Publier - {:else if confirmingDelete} -

Es-tu sûr·e ?

- { - confirmingDelete = false; - }}>Annuler - { - if (!input.id) return; - toasts.success(`Post supprimé`, '', { - lifetime: 5000, - showLifetime: true, - data: { - id: input.id, - confirm: true, - // gotoOnCancel: `${afterGoTo($data)}/edit/`.replaceAll('//', '/'), - gotoOnCancel: route('/posts/[id]/edit', input.id), - }, - labels: { - action: 'Annuler', - close: 'OK', - }, - async action({ data, id }) { - data.confirm = false; - await toasts.remove(id); - await goto(data.gotoOnCancel); - }, - async closed({ data: { id, confirm } }) { - if (confirm) { - await $zeus.mutate({ - deleteArticlePicture: [{ id }, true], - deleteArticle: [{ id }, true], - }); - } - }, - }); - confirmingDelete = false; - await goto('/'); - }} - danger>Oui - { - input.visibility = Visibility.Private; - confirmingDelete = false; - }}>Rendre privé - {:else} - Enregistrer - {#if input.id} - { - confirmingDelete = true; - }}>Supprimer - {/if} - {/if} -
- - - diff --git a/packages/app/src/lib/navigation.ts b/packages/app/src/lib/navigation.ts index a271f970e..668850a7f 100644 --- a/packages/app/src/lib/navigation.ts +++ b/packages/app/src/lib/navigation.ts @@ -458,10 +458,6 @@ export const topnavConfigs: Partial<{ commonActions.copyID, ], }), - '/(app)/posts/[[group]]/create': { - title: 'Nouveau post', - actions: [], - }, '/(app)/events/[id]/scan': ({ params: { id } }) => ({ title: 'Scanner des billets', back: route('/events/[id]', id), diff --git a/packages/app/src/routes/(app)/posts/[[group]]/create/+page.gql b/packages/app/src/routes/(app)/posts/[[group]]/create/+page.gql deleted file mode 100644 index a474758d5..000000000 --- a/packages/app/src/routes/(app)/posts/[[group]]/create/+page.gql +++ /dev/null @@ -1,7 +0,0 @@ -query PagePostCreateWithGroup { - me: assertMe { - canCreatePostsOn { - ...FormArticleGroups @mask_disable - } - } -} diff --git a/packages/app/src/routes/(app)/posts/[[group]]/create/+page.svelte b/packages/app/src/routes/(app)/posts/[[group]]/create/+page.svelte deleted file mode 100644 index b30d763b8..000000000 --- a/packages/app/src/routes/(app)/posts/[[group]]/create/+page.svelte +++ /dev/null @@ -1,34 +0,0 @@ - - -
-

Nouveau post

- - g.uid === $page.params.group) ?? null} - /> - -
- - diff --git a/packages/app/src/routes/(app)/posts/[id]/+page.svelte b/packages/app/src/routes/(app)/posts/[id]/+page.svelte index 76999c55d..67c490817 100644 --- a/packages/app/src/routes/(app)/posts/[id]/+page.svelte +++ b/packages/app/src/routes/(app)/posts/[id]/+page.svelte @@ -10,12 +10,15 @@ import { LoadingText, loading } from '$lib/loading'; import { Lightbox } from 'svelte-lightbox'; import type { PageData } from './$houdini'; + import { page } from '$app/stores'; + import ModalDelete from './ModalDelete.svelte'; export let data: PageData; $: ({ PagePostDetail } = data); - // HINT: Don't forget to add an entry in packages/app/src/lib/navigation.ts for the top navbar's title and/or action buttons + +
diff --git a/packages/app/src/routes/(app)/posts/[id]/ModalDelete.svelte b/packages/app/src/routes/(app)/posts/[id]/ModalDelete.svelte new file mode 100644 index 000000000..48d04c943 --- /dev/null +++ b/packages/app/src/routes/(app)/posts/[id]/ModalDelete.svelte @@ -0,0 +1,105 @@ + + + { + deletionResult = undefined; + pushState('', { NAVTOP_DELETING: false }); + }} +> +
+

Es-tu sûr·e ?

+

Il est impossible de revenir en arrière

+ {#if deletionResult} + + {#each deletionResult.messages as message} +

{message}

+ {/each} +
+ {/if} +
+ {#if deletionResult} + OK + {:else} + Annuler + Supprimer + {/if} +
+
+
+ + diff --git a/packages/app/src/routes/(app)/posts/[id]/edit/visibility/+page.svelte b/packages/app/src/routes/(app)/posts/[id]/edit/visibility/+page.svelte index 8dc3dbf0c..f85d516f8 100644 --- a/packages/app/src/routes/(app)/posts/[id]/edit/visibility/+page.svelte +++ b/packages/app/src/routes/(app)/posts/[id]/edit/visibility/+page.svelte @@ -1,6 +1,6 @@