From cf02ca450653bbe6978e131a16511beeb722d525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Wed, 20 Nov 2019 15:17:29 +0100 Subject: [PATCH] Refactor decide mutation to new CaseFolder structure --- backend/src/models/Comment.js | 12 +- backend/src/models/Post.js | 12 +- backend/src/models/User.js | 12 +- backend/src/schema/index.js | 4 +- backend/src/schema/resolvers/comments.js | 29 ++- backend/src/schema/resolvers/moderation.js | 245 +++++++++++------- .../src/schema/resolvers/moderation.spec.js | 24 +- backend/src/schema/resolvers/posts.js | 2 +- backend/src/schema/resolvers/users.js | 2 +- backend/src/schema/types/type/Comment.gql | 11 +- backend/src/schema/types/type/Post.gql | 10 +- .../types/type/{DECIDED.gql => REVIEWED.gql} | 12 +- backend/src/schema/types/type/User.gql | 10 +- webapp/graphql/Moderation.js | 6 +- webapp/pages/moderation/index.vue | 6 +- 15 files changed, 254 insertions(+), 143 deletions(-) rename backend/src/schema/types/type/{DECIDED.gql => REVIEWED.gql} (54%) diff --git a/backend/src/models/Comment.js b/backend/src/models/Comment.js index ee2f9512d..06ebe2930 100644 --- a/backend/src/models/Comment.js +++ b/backend/src/models/Comment.js @@ -25,12 +25,12 @@ module.exports = { target: 'User', direction: 'in', }, - decidedByModerator: { - type: 'relationship', - relationship: 'DECIDED', - target: 'User', - direction: 'in', - }, + // Wolle reviewedByModerator: { + // type: 'relationship', + // relationship: 'DECIDED', + // target: 'User', + // direction: 'in', + // }, notified: { type: 'relationship', relationship: 'NOTIFIED', diff --git a/backend/src/models/Post.js b/backend/src/models/Post.js index 2d812d491..695664a56 100644 --- a/backend/src/models/Post.js +++ b/backend/src/models/Post.js @@ -17,12 +17,12 @@ module.exports = { image: { type: 'string', allow: [null] }, deleted: { type: 'boolean', default: false }, disabled: { type: 'boolean', default: false }, - decidedByModerator: { - type: 'relationship', - relationship: 'DECIDED', - target: 'User', - direction: 'in', - }, + // Wolle reviewedByModerator: { + // type: 'relationship', + // relationship: 'DECIDED', + // target: 'User', + // direction: 'in', + // }, notified: { type: 'relationship', relationship: 'NOTIFIED', diff --git a/backend/src/models/User.js b/backend/src/models/User.js index 329ee6f8d..48f887406 100644 --- a/backend/src/models/User.js +++ b/backend/src/models/User.js @@ -42,12 +42,12 @@ module.exports = { }, }, friends: { type: 'relationship', relationship: 'FRIENDS', target: 'User', direction: 'both' }, - decidedByModerator: { - type: 'relationship', - relationship: 'DECIDED', - target: 'User', - direction: 'in', - }, + // Wolle reviewedByModerator: { + // type: 'relationship', + // relationship: 'DECIDED', + // target: 'User', + // direction: 'in', + // }, rewarded: { type: 'relationship', relationship: 'REWARDED', diff --git a/backend/src/schema/index.js b/backend/src/schema/index.js index 5fefe26f7..d66662acf 100644 --- a/backend/src/schema/index.js +++ b/backend/src/schema/index.js @@ -24,7 +24,7 @@ export default applyScalars( 'SocialMedia', 'NOTIFIED', 'REPORTED', - 'DECIDED', + 'REVIEWED', 'Donations', ], // add 'User' here as soon as possible @@ -46,7 +46,7 @@ export default applyScalars( 'EMOTED', 'NOTIFIED', 'REPORTED', - 'DECIDED', + 'REVIEWED', 'Donations', ], // add 'User' here as soon as possible diff --git a/backend/src/schema/resolvers/comments.js b/backend/src/schema/resolvers/comments.js index 83816117e..b11d78301 100644 --- a/backend/src/schema/resolvers/comments.js +++ b/backend/src/schema/resolvers/comments.js @@ -69,8 +69,35 @@ export default { hasOne: { author: '<-[:WROTE]-(related:User)', post: '-[:COMMENTS]->(related:Post)', - decidedByModerator: '<-[:DECIDED]-(related:User)', + // Wolle reviewedByModerator: '<-[:DECIDED]-(related:User)', }, }), + // Wolle reviewedByModerator: async (parent, params, context, resolveInfo) => { + // console.log('reviewedByModerator !!!') + // console.log('reviewedByModerator !!!') + // console.log('reviewedByModerator !!!') + // console.log('reviewedByModerator !!!') + // console.log('reviewedByModerator !!!') + // if (typeof parent.reviewedByModerator !== 'undefined') return parent.reviewedByModerator + // // const { id } = parent + // // const statement = ` + // // MATCH (p:Post {id: $id})-[:TAGGED|CATEGORIZED]->(categoryOrTag)<-[:TAGGED|CATEGORIZED]-(post:Post) + // // WHERE NOT post.deleted AND NOT post.disabled + // // RETURN DISTINCT post + // // LIMIT 10 + // // ` + // // let reviewedByModerator + // // const session = context.driver.session() + // // try { + // // const result = await session.run(statement, { id }) + // // relatedContributions = result.records.map(r => r.get('post').properties) + // // } finally { + // // session.close() + // // } + // // return reviewedByModerator + // return { + // id: 'Hallo !!!' + // } + // }, }, } diff --git a/backend/src/schema/resolvers/moderation.js b/backend/src/schema/resolvers/moderation.js index 7876439d0..fa1704603 100644 --- a/backend/src/schema/resolvers/moderation.js +++ b/backend/src/schema/resolvers/moderation.js @@ -1,33 +1,32 @@ import uuid from 'uuid/v4' import { undefinedToNullResolver } from './helpers/Resolver' -const queryOpenDecisionWriteTransaction = (session, resourceId) => { - return session.writeTransaction(async txc => { - const queryOpenDecisionTransactionResponse = await txc.run( - ` - //MATCH (moderator:User)-[decision:DECIDED {closed: false}]->(resource {id: $resourceId}) - //WHERE resource:User OR resource:Comment OR resource:Post - //RETURN decision, moderator {.id} AS decisionModerator +// const queryOpenDecisionWriteTransaction = (session, resourceId) => { +// return session.writeTransaction(async txc => { +// const queryOpenDecisionTransactionResponse = await txc.run( +// ` +// //MATCH (moderator:User)-[decision:DECIDED {closed: false}]->(resource {id: $resourceId}) +// //WHERE resource:User OR resource:Comment OR resource:Post +// //RETURN decision, moderator {.id} AS decisionModerator - // Wolle only review on reported resources +// // Wolle only review on reported resources - MATCH (moderator:User)-[:REPORTED]->(caseFolder:CaseFolder {closed: false})-[:FLAGGED]->(resource {id: $resourceId}) - WHERE resource:User OR resource:Post OR resource:Comment - RETURN caseFolder, moderator {.id} AS caseModerator - `, - { resourceId }, - ) - return queryOpenDecisionTransactionResponse.records.map(record => ({ - caseFolder: record.get('caseFolder'), - caseModerator: record.get('caseModerator'), - })) - }) -} +// MATCH (caseModerator:User)-[:REPORTED]->(caseFolder:CaseFolder {closed: false})-[:FLAGGED]->(resource {id: $resourceId}) +// WHERE resource:User OR resource:Post OR resource:Comment +// RETURN caseFolder, caseModerator {.id} +// `, +// { resourceId }, +// ) +// return queryOpenDecisionTransactionResponse.records.map(record => ({ +// caseFolder: record.get('caseFolder'), +// caseModerator: record.get('caseModerator'), +// })) +// }) +// } export default { Mutation: { decide: async (_object, params, context, _resolveInfo) => { - let createdRelationshipWithNestedAttributes = null // Wolle console.log('params: ', params) const { resourceId } = params // Wolle console.log('resourceId: ', resourceId) @@ -35,101 +34,161 @@ export default { // Wolle console.log('disable: ', disable) const { user: moderator, driver } = context + let createdRelationshipWithNestedAttributes = null // return value + const session = driver.session() try { - const queryOpenDecisionWriteTxResultPromise = queryOpenDecisionWriteTransaction( - session, - resourceId, - ) - const [openDecisionTxResult] = await queryOpenDecisionWriteTxResultPromise + // const queryOpenDecisionWriteTxResultPromise = queryOpenDecisionWriteTransaction( + // session, + // resourceId, + // ) + // console.log('queryOpenDecisionWriteTxResultPromise: ', queryOpenDecisionWriteTxResultPromise) + // console.log('queryOpenDecisionWriteTxResultPromise: ', queryOpenDecisionWriteTxResultPromise) + // console.log('queryOpenDecisionWriteTxResultPromise: ', queryOpenDecisionWriteTxResultPromise) + // console.log('queryOpenDecisionWriteTxResultPromise: ', queryOpenDecisionWriteTxResultPromise) + // console.log('queryOpenDecisionWriteTxResultPromise: ', queryOpenDecisionWriteTxResultPromise) + // const [openDecisionTxResult] = await queryOpenDecisionWriteTxResultPromise - let cypherHeader = '' + // let cypherHeader = '' - if (!openDecisionTxResult) { - // no open caseFolder, then create one - if (disable === undefined) disable = false // default for creation - if (closed === undefined) closed = false // default for creation - cypherHeader = ` - MATCH (resource {id: $resourceId}) - WHERE resource: User OR resource: Comment OR resource: Post - OPTIONAL MATCH (:User)-[lastDecision:DECIDED {latest: true}]->(resource) - SET (CASE WHEN lastDecision IS NOT NULL THEN lastDecision END).latest = false - WITH resource - MATCH (moderator:User {id: $moderatorId}) - CREATE (resource)<-[decision:DECIDED]-(moderator) - SET decision.latest = true - ` - } else { - // an open caseFolder, then change it - if (disable === undefined) disable = openDecisionTxResult.caseFolder.properties.disable // default set to existing - if (closed === undefined) closed = openDecisionTxResult.caseFolder.properties.closed // default set to existing - // current moderator is not the same as old - if (moderator.id !== openDecisionTxResult.caseModerator.id) { - // from a different moderator, then create relation with properties to new moderator - cypherHeader = ` - MATCH (moderator:User)-[oldDecision:DECIDED {closed: false}]->(resource {id: $resourceId}) - WHERE resource:User OR resource:Comment OR resource:Post - DELETE oldDecision - MATCH (moderator:User {id: $moderatorId}) - MATCH (resource {id: $resourceId}) - WHERE resource:User OR resource:Comment OR resource:Post - CREATE (resource)<-[decision:DECIDED]-(moderator) - SET decision = oldDecision - ` - } else { - // an open caseFolder from same moderator, then match this - cypherHeader = ` - MATCH (moderator:User)-[decision:DECIDED {closed: false}]->(resource {id: $resourceId}) - WHERE resource:User OR resource:Comment OR resource:Post - ` - } - } - let decisionUUID = null - let cypherClosed = '' - if (closed) { - decisionUUID = uuid() - cypherClosed = ` - WITH decision, resource, moderator - OPTIONAL MATCH (:User)-[report:REPORTED {closed: false}]->(resource) - SET (CASE WHEN report IS NOT NULL THEN report END).closed = true - SET (CASE WHEN report IS NOT NULL THEN report END).decisionUuid = $decisionUUID - SET decision.uuid = $decisionUUID - ` - } + // // Wolle openDecisionTxResult should not be undefined !!! + // if (!openDecisionTxResult) { + // // no open caseFolder, then create one + // if (disable === undefined) disable = false // default for creation + // if (closed === undefined) closed = false // default for creation + // cypherHeader = ` + // MATCH (resource {id: $resourceId}) + // WHERE resource: User OR resource: Comment OR resource: Post + // OPTIONAL MATCH (:User)-[lastDecision:DECIDED {latest: true}]->(resource) + // SET (CASE WHEN lastDecision IS NOT NULL THEN lastDecision END).latest = false + // WITH resource + // MATCH (moderator:User {id: $moderatorId}) + // CREATE (resource)<-[decision:DECIDED]-(moderator) + // SET decision.latest = true + // ` + // } else { + // // an open caseFolder, then change it + // if (disable === undefined) disable = openDecisionTxResult.caseFolder.properties.disable // default set to existing + // if (closed === undefined) closed = openDecisionTxResult.caseFolder.properties.closed // default set to existing + // // current moderator is not the same as old + // if (moderator.id !== openDecisionTxResult.caseModerator.id) { + // // from a different moderator, then create relation with properties to new moderator + // cypherHeader = ` + // MATCH (moderator:User)-[oldDecision:DECIDED {closed: false}]->(resource {id: $resourceId}) + // WHERE resource:User OR resource:Comment OR resource:Post + // DELETE oldDecision + // MATCH (moderator:User {id: $moderatorId}) + // MATCH (resource {id: $resourceId}) + // WHERE resource:User OR resource:Comment OR resource:Post + // CREATE (resource)<-[decision:DECIDED]-(moderator) + // SET decision = oldDecision + // ` + // } else { + // // an open caseFolder from same moderator, then match this + // cypherHeader = ` + // MATCH (moderator:User)-[decision:DECIDED {closed: false}]->(resource {id: $resourceId}) + // WHERE resource:User OR resource:Comment OR resource:Post + // ` + // } + // } + // let decisionUUID = null + // let cypherClosed = '' + // if (closed) { + // decisionUUID = uuid() + // cypherClosed = ` + // WITH decision, resource, moderator + // OPTIONAL MATCH (:User)-[report:REPORTED {closed: false}]->(resource) + // SET (CASE WHEN report IS NOT NULL THEN report END).closed = true + // SET (CASE WHEN report IS NOT NULL THEN report END).decisionUuid = $decisionUUID + // SET decision.uuid = $decisionUUID + // ` + // } + // const cypher = + // cypherHeader + + // `SET decision.updatedAt = toString(datetime()) + // SET (CASE WHEN decision.createdAt IS NULL THEN decision END).createdAt = decision.updatedAt + // SET decision.disable = $disable, decision.closed = $closed + // SET resource.disabled = $disable + // ` + + // cypherClosed + + // `RETURN decision, resource, moderator, labels(resource)[0] AS type + // ` const cypher = - cypherHeader + - `SET decision.updatedAt = toString(datetime()) - SET (CASE WHEN decision.createdAt IS NULL THEN decision END).createdAt = decision.updatedAt - SET decision.disable = $disable, decision.closed = $closed + ` + // Wolle only review on reported resources + + MATCH (moderator:User {id: $moderatorId}) + MATCH (resource {id: $resourceId}) + WHERE resource:User OR resource:Post OR resource:Comment + + // no open caseFolder, create one, update existing + MERGE (resource)<-[:FLAGGED]-(caseFolder:CaseFolder {closed: false}) + ON CREATE SET caseFolder.id = randomUUID(), caseFolder.createdAt = $createdAt, caseFolder.updatedAt = caseFolder.createdAt, caseFolder.disable = $disable, caseFolder.closed = $closed + ON MATCH SET caseFolder.updatedAt = $createdAt, caseFolder.disable = $disable, caseFolder.closed = $closed + + // Create review on caseFolder + WITH moderator, resource, caseFolder + CREATE (caseFolder)<-[review:REVIEWED {createdAt: $createdAt, updatedAt: $createdAt, disable: $disable, closed: $closed}]-(moderator) + SET resource.disabled = $disable - ` + - cypherClosed + - `RETURN decision, resource, moderator, labels(resource)[0] AS type + + RETURN moderator, review, caseFolder {.id}, resource, labels(resource)[0] AS type + + //RETURN decision, resource, moderator, labels(resource)[0] AS type ` + // Wolle console.log('cypher: ', cypher) // console.log('disable: ', disable) + // const mutateDecisionWriteTxResultPromise = session.writeTransaction(async txc => { + // const mutateDecisionTransactionResponse = await txc.run( + // cypher, { + // resourceId, + // moderatorId: moderator.id, + // disable, + // closed, + // decisionUUID, + // }) + // return mutateDecisionTransactionResponse.records.map(record => ({ + // decision: record.get('decision'), + // resource: record.get('resource'), + // moderator: record.get('moderator'), + // type: record.get('type'), + // })) + // }) const mutateDecisionWriteTxResultPromise = session.writeTransaction(async txc => { - const mutateDecisionTransactionResponse = await txc.run(cypher, { + const mutateDecisionTransactionResponse = await txc.run( + cypher, { resourceId, moderatorId: moderator.id, + createdAt: new Date().toISOString(), disable, closed, - decisionUUID, }) return mutateDecisionTransactionResponse.records.map(record => ({ - decision: record.get('decision'), - resource: record.get('resource'), moderator: record.get('moderator'), + review: record.get('review'), + caseFolder: record.get('caseFolder'), + resource: record.get('resource'), type: record.get('type'), })) }) const txResult = await mutateDecisionWriteTxResultPromise if (!txResult[0]) return null - const { decision, resource, moderator: moderatorInResult, type } = txResult[0] + // const { decision, resource, moderator: moderatorInResult, type } = txResult[0] + // createdRelationshipWithNestedAttributes = { + // ...decision.properties, + // moderator: moderatorInResult.properties, + // type, + // post: null, + // comment: null, + // user: null, + // } + const { moderator: moderatorInResult, review, caseFolder, resource, type } = txResult[0] createdRelationshipWithNestedAttributes = { - ...decision.properties, + ...review.properties, moderator: moderatorInResult.properties, + caseFolderId: caseFolder.id, type, post: null, comment: null, @@ -153,7 +212,7 @@ export default { return createdRelationshipWithNestedAttributes }, }, - DECIDED: { - ...undefinedToNullResolver(['uuid']), + REVIEWED: { + // Wolle ...undefinedToNullResolver(['uuid']), }, } diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 31014224e..4e082a3e0 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -34,7 +34,7 @@ const commentQuery = gql` Comment(id: $id) { id disabled - decidedByModerator { + reviewedByModerator { id } } @@ -45,7 +45,7 @@ const postQuery = gql` Post(id: $id) { id disabled - decidedByModerator { + reviewedByModerator { id } } @@ -172,7 +172,7 @@ describe('moderate resources', () => { }) }) - it('changes .decidedByModerator', async () => { + it('changes .reviewedByModerator', async () => { resourceVariables = { id: 'comment-id', } @@ -180,9 +180,9 @@ describe('moderate resources', () => { ...disableVariables, resourceId: 'comment-id', } - const before = { data: { Comment: [{ id: 'comment-id', decidedByModerator: null }] } } + const before = { data: { Comment: [{ id: 'comment-id', reviewedByModerator: null }] } } const expected = { - data: { Comment: [{ id: 'comment-id', decidedByModerator: { id: 'moderator-id' } }] }, + data: { Comment: [{ id: 'comment-id', reviewedByModerator: { id: 'moderator-id' } }] }, } await expect( query({ query: commentQuery, variables: resourceVariables }), @@ -241,7 +241,7 @@ describe('moderate resources', () => { }) }) - it('changes .decidedByModerator', async () => { + it('changes .reviewedByModerator', async () => { resourceVariables = { id: 'sample-post-id', } @@ -249,10 +249,10 @@ describe('moderate resources', () => { ...disableVariables, resourceId: 'sample-post-id', } - const before = { data: { Post: [{ id: 'sample-post-id', decidedByModerator: null }] } } + const before = { data: { Post: [{ id: 'sample-post-id', reviewedByModerator: null }] } } const expected = { data: { - Post: [{ id: 'sample-post-id', decidedByModerator: { id: 'moderator-id' } }], + Post: [{ id: 'sample-post-id', reviewedByModerator: { id: 'moderator-id' } }], }, } @@ -387,9 +387,9 @@ describe('moderate resources', () => { }) }) - it('changes .decidedByModerator', async () => { + it('changes .reviewedByModerator', async () => { const expected = { - data: { Comment: [{ id: 'comment-id', decidedByModerator: { id: 'moderator-id' } }] }, + data: { Comment: [{ id: 'comment-id', reviewedByModerator: { id: 'moderator-id' } }] }, } await expect( @@ -443,9 +443,9 @@ describe('moderate resources', () => { }) }) - it('changes .decidedByModerator', async () => { + it('changes .reviewedByModerator', async () => { const expected = { - data: { Post: [{ id: 'post-id', decidedByModerator: { id: 'moderator-id' } }] }, + data: { Post: [{ id: 'post-id', reviewedByModerator: { id: 'moderator-id' } }] }, } await expect( mutate({ mutation: decideMutation, variables: enableVariables }), diff --git a/backend/src/schema/resolvers/posts.js b/backend/src/schema/resolvers/posts.js index 12e050298..2d60fb697 100644 --- a/backend/src/schema/resolvers/posts.js +++ b/backend/src/schema/resolvers/posts.js @@ -307,7 +307,7 @@ export default { }, hasOne: { author: '<-[:WROTE]-(related:User)', - decidedByModerator: '<-[:DECIDED]-(related:User)', + // Wolle reviewedByModerator: '<-[:DECIDED]-(related:User)', pinnedBy: '<-[:PINNED]-(related:User)', }, count: { diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index 0bb921bc4..8ddadc745 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -199,7 +199,7 @@ export default { }, hasOne: { invitedBy: '<-[:INVITED]-(related:User)', - decidedByModerator: '<-[:DECIDED]-(related:User)', + // Wolle reviewedByModerator: '<-[:DECIDED]-(related:User)', location: '-[:IS_IN]->(related:Location)', }, hasMany: { diff --git a/backend/src/schema/types/type/Comment.gql b/backend/src/schema/types/type/Comment.gql index 4c1b9968e..9604318cf 100644 --- a/backend/src/schema/types/type/Comment.gql +++ b/backend/src/schema/types/type/Comment.gql @@ -9,7 +9,16 @@ type Comment { updatedAt: String deleted: Boolean disabled: Boolean - decidedByModerator: User @relation(name: "DECIDED", direction: "IN") + # Wolle reviewedByModerator: User # Wolle @relation(name: "DECIDED", direction: "IN") + reviewedByModerator: User + @cypher( + statement: """ + MATCH (this)<-[:FLAGGED]-(caseFolder:CaseFolder)<-[review:REVIEWED]-(moderator:User) + RETURN moderator + ORDER BY caseFolder.updatedAt ASC, review.updatedAt ASC + LIMIT 1 + """ + ) } type Mutation { diff --git a/backend/src/schema/types/type/Post.gql b/backend/src/schema/types/type/Post.gql index 77ec432e2..a79de1d0f 100644 --- a/backend/src/schema/types/type/Post.gql +++ b/backend/src/schema/types/type/Post.gql @@ -46,8 +46,16 @@ type Post { visibility: Visibility deleted: Boolean disabled: Boolean + reviewedByModerator: User + @cypher( + statement: """ + MATCH (this)<-[:FLAGGED]-(caseFolder:CaseFolder)<-[review:REVIEWED]-(moderator:User) + RETURN moderator + ORDER BY caseFolder.updatedAt ASC, review.updatedAt ASC + LIMIT 1 + """ + ) pinned: Boolean - decidedByModerator: User @relation(name: "DECIDED", direction: "IN") createdAt: String updatedAt: String language: String diff --git a/backend/src/schema/types/type/DECIDED.gql b/backend/src/schema/types/type/REVIEWED.gql similarity index 54% rename from backend/src/schema/types/type/DECIDED.gql rename to backend/src/schema/types/type/REVIEWED.gql index 0c56a9896..d3f064436 100644 --- a/backend/src/schema/types/type/DECIDED.gql +++ b/backend/src/schema/types/type/REVIEWED.gql @@ -1,25 +1,25 @@ -type DECIDED { +type REVIEWED { createdAt: String! updatedAt: String! # reasonCategory: ReasonCategory # reasonDescription: String disable: Boolean! closed: Boolean! - uuid: ID - last: Boolean! + caseFolderId: ID! + # Wolle last: Boolean! moderator: User - @cypher(statement: "MATCH (resource)<-[:DECIDED]-(moderator:User) RETURN moderator") + # @cypher(statement: "MATCH (resource)<-[:DECIDED]-(moderator:User) RETURN moderator") # not yet supported # resource: ReportResource # @cypher(statement: "MATCH (resource)<-[:DECIDED]-(:User) RETURN resource") type: String - @cypher(statement: "MATCH (resource)<-[:DECIDED]-(user:User) RETURN labels(resource)[0]") + # @cypher(statement: "MATCH (resource)<-[:DECIDED]-(user:User) RETURN labels(resource)[0]") user: User post: Post comment: Comment } type Mutation { - decide(resourceId: ID!, disable: Boolean, closed: Boolean): DECIDED + decide(resourceId: ID!, disable: Boolean, closed: Boolean): REVIEWED } diff --git a/backend/src/schema/types/type/User.gql b/backend/src/schema/types/type/User.gql index ebe9c2a3c..cd5906229 100644 --- a/backend/src/schema/types/type/User.gql +++ b/backend/src/schema/types/type/User.gql @@ -8,7 +8,15 @@ type User { coverImg: String deleted: Boolean disabled: Boolean - decidedByModerator: User @relation(name: "DECIDED", direction: "IN") + reviewedByModerator: User + @cypher( + statement: """ + MATCH (this)<-[:FLAGGED]-(caseFolder:CaseFolder)<-[review:REVIEWED]-(moderator:User) + RETURN moderator + ORDER BY caseFolder.updatedAt ASC, review.updatedAt ASC + LIMIT 1 + """ + ) role: UserGroup! publicKey: String invitedBy: User @relation(name: "INVITED", direction: "IN") diff --git a/webapp/graphql/Moderation.js b/webapp/graphql/Moderation.js index ea2da0df1..f11a52a8a 100644 --- a/webapp/graphql/Moderation.js +++ b/webapp/graphql/Moderation.js @@ -29,7 +29,7 @@ export const reportListQuery = () => { name disabled deleted - decidedByModerator { + reviewedByModerator { id slug name @@ -60,7 +60,7 @@ export const reportListQuery = () => { disabled deleted } - decidedByModerator { + reviewedByModerator { id slug name @@ -84,7 +84,7 @@ export const reportListQuery = () => { contributionsCount commentedCount } - decidedByModerator { + reviewedByModerator { id slug name diff --git a/webapp/pages/moderation/index.vue b/webapp/pages/moderation/index.vue index 77d3ecc73..033a617b1 100644 --- a/webapp/pages/moderation/index.vue +++ b/webapp/pages/moderation/index.vue @@ -101,8 +101,8 @@ > {{ $t('moderation.reports.decideButton') }} - -
+ +

@@ -113,7 +113,7 @@ {{ $t('moderation.reports.enabledBy') }}