diff --git a/@types/graphql.d.ts b/@types/graphql.d.ts index 2160468..0e43e87 100644 --- a/@types/graphql.d.ts +++ b/@types/graphql.d.ts @@ -29,6 +29,7 @@ declare namespace GQL { occurrences: Array | null; occurrence: IEventOccurrence | null; tags: Array | null; + revisions: Array | null; } interface IUserOnQueryArguments { @@ -51,6 +52,10 @@ declare namespace GQL { id: string; } + interface IRevisionsOnQueryArguments { + filter: IRevisionsQueryFilter; + } + interface IUser { __typename: 'User'; name: string; @@ -156,6 +161,7 @@ declare namespace GQL { createdAt: any; submittedAt: any | null; dismissedBy: IUser | null; + lastChangedAt: any; } interface IUserRole { @@ -178,6 +184,10 @@ declare namespace GQL { limit?: number | null; } + interface IRevisionsQueryFilter { + limit?: number | null; + } + interface IMutation { __typename: 'Mutation'; signup: Array | null; diff --git a/src/Events/EventRevision.entity.ts b/src/Events/EventRevision.entity.ts index 886f371..f145006 100644 --- a/src/Events/EventRevision.entity.ts +++ b/src/Events/EventRevision.entity.ts @@ -1,10 +1,10 @@ import { - BaseEntity, + BaseEntity, BeforeInsert, BeforeUpdate, Column, Entity, ManyToOne, - PrimaryGeneratedColumn, -} from "typeorm" + PrimaryGeneratedColumn +} from "typeorm"; import { User } from "../Auth/User.entity" import { Event } from "../Calendar/Event.entity" @@ -31,6 +31,9 @@ export default class EventRevision extends BaseEntity { @Column("timestamp") createdAt: Date + @Column("timestamp") + lastChangedAt: Date + @Column("timestamp", {nullable: true}) submittedAt: Date @@ -40,6 +43,18 @@ export default class EventRevision extends BaseEntity { @Column("timestamp", {nullable: true}) staleAt: Date + @BeforeInsert() + setCreatedAt() { + const now = new Date() + this.createdAt = now + this.lastChangedAt = now + } + + @BeforeUpdate() + setLastChanged(){ + this.lastChangedAt = new Date() + } + async isActive() { return !(this.submittedAt || this.staleAt || (await this.dismissedBy)?.id) } diff --git a/src/Events/revisionResolvers.ts b/src/Events/revisionResolvers.ts index ac15a69..d0f83a9 100644 --- a/src/Events/revisionResolvers.ts +++ b/src/Events/revisionResolvers.ts @@ -44,7 +44,6 @@ const revisionResolvers: ResolverMap = { } const newRevision = new EventRevision() - newRevision.createdAt = new Date() newRevision.event = Promise.resolve(event) newRevision.author = Promise.resolve(context.user) const eventRevisions = (await event.revisions) || [] @@ -120,7 +119,7 @@ const revisionResolvers: ResolverMap = { const isOwner = (await event.owner).id === (await context.user).id if (!((await hasHigherRole(context)) || isOwner)) { - throw new Error("Only owner can request revision") + throw new Error("Only owner, embassador or admin can request revision") } if (event.revisionState !== EventRevisionState.CHANGES_REQUIRED) { throw new Error( @@ -149,7 +148,20 @@ const revisionResolvers: ResolverMap = { return revision.event }, }, - Query: {}, + Query: { + revisions: async (_, req: GQL.IRevisionsOnQueryArguments, context: Context) => { + const userHasHigherRole = await hasHigherRole(context) + if (!userHasHigherRole) { + throw new Error("Insufficient permissions to dismiss a revision") + } + return EventRevision.find({ + order: { + lastChangedAt: "DESC", + }, + take: req.filter.limit || 20 + }) + } + }, EventRevision: {}, } diff --git a/src/schema.graphql b/src/schema.graphql index 15f3a97..c475a07 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -141,6 +141,9 @@ input OccurrencesQueryFilter { categories: [Category] limit: Int } +input RevisionsQueryFilter { + limit: Int +} input EventTimeInput { timeZone: TimeZone! @@ -247,6 +250,7 @@ type EventRevision { createdAt: Date! submittedAt: Date dismissedBy: User + lastChangedAt: Date! } input RequestRevisionInput { eventId: ID! @@ -299,4 +303,6 @@ type Query { occurrence(id: ID!): EventOccurrence tags: [EventTag] + + revisions(filter: RevisionsQueryFilter!): [EventRevision] }