Refactor frontend and 'reports' query again

This commit is contained in:
Wolfgang Huß 2019-11-07 15:54:26 +01:00
parent 446549d1b5
commit 2a23bbf101
12 changed files with 114 additions and 43 deletions

View File

@ -1,4 +1,5 @@
import uuid from 'uuid/v4'
import { undefinedToNullResolver } from './helpers/Resolver'
export default {
Mutation: {
@ -38,18 +39,15 @@ export default {
if (disable === undefined) disable = false // default for creation
if (closed === undefined) closed = false // default for creation
cypherHeader = `
MATCH (moderator:User {id: $moderatorId})
MATCH (resource {id: $resourceId})
WHERE resource:User OR resource:Comment OR resource:Post
WHERE resource: User OR resource: Comment OR resource: Post
OPTIONAL MATCH (:User)-[lastDecision:DECIDED {last: true}]->(resource)
SET (CASE WHEN lastDecision IS NOT NULL THEN lastDecision END).last = false
WITH resource
MATCH (moderator:User {id: $moderatorId})
CREATE (resource)<-[decision:DECIDED]-(moderator)
SET decision.last = true
WITH decision, resource, moderator
OPTIONAL MATCH (:User)-[lastDecision:DECIDED {last: true}]->(resource)
SET (
CASE
WHEN lastDecision IS NOT NULL
THEN lastDecision END).last = false
`
`
} else {
// an open decision …
if (disable === undefined) disable = existingDecisionTxResult.decision.properties.disable // default set to existing
@ -77,24 +75,20 @@ export default {
}
let decisionUUID = null
let cypherClosed = ''
// if (closed) {
// decisionUUID = uuid()
// cypherClosed = `
// OPTIONAL MATCH (:User)-[report:REPORTED {closed: false}]->(resource)
// SET report.closed = true, report.decisionUuid = $decisionUUID
// SET decision.uuid = $decisionUUID
// `
// }
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 (
CASE
WHEN decision.createdAt IS NOT NULL
THEN decision END).updatedAt = toString(datetime())
SET (
CASE
WHEN decision.createdAt IS NULL
THEN decision END).createdAt = toString(datetime())
`SET (CASE WHEN decision.createdAt IS NOT NULL THEN decision END).updatedAt = toString(datetime())
SET (CASE WHEN decision.createdAt IS NULL THEN decision END).createdAt = toString(datetime())
SET decision.disable = $disable, decision.closed = $closed
SET resource.disabled = $disable
` +
@ -148,4 +142,7 @@ export default {
return createdRelationshipWithNestedAttributes
},
},
DECIDED: {
...undefinedToNullResolver(['updatedAt', 'uuid']),
},
}

View File

@ -1,3 +1,5 @@
import { undefinedToNullResolver } from './helpers/Resolver'
export default {
Mutation: {
report: async (_parent, params, context, _resolveInfo) => {
@ -11,7 +13,7 @@ export default {
MATCH (submitter:User {id: $submitterId})
MATCH (resource {id: $resourceId})
WHERE resource:User OR resource:Comment OR resource:Post
CREATE (resource)<-[report:REPORTED {createdAt: $createdAt, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription}]-(submitter)
CREATE (resource)<-[report:REPORTED {createdAt: $createdAt, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription, closed: false}]-(submitter)
RETURN report, submitter, resource, labels(resource)[0] as type
`,
{
@ -78,7 +80,9 @@ export default {
const cypher = `
MATCH (submitter:User)-[report:REPORTED]->(resource)
WHERE resource:User OR resource:Comment OR resource:Post
RETURN report, submitter, resource, labels(resource)[0] as type
OPTIONAL MATCH (:User)-[decision:DECIDED {uuid: report.decisionUuid}]->(resource)
OPTIONAL MATCH (:User)-[decisionPending:DECIDED {last: true}]->(resource)
RETURN report, submitter, resource, labels(resource)[0] as type, decision, decisionPending
${orderByClause}
`
const result = await session.run(cypher, {})
@ -88,16 +92,28 @@ export default {
submitter: r.get('submitter'),
resource: r.get('resource'),
type: r.get('type'),
decision: r.get('decision'),
decisionPending: r.get('decisionPending'),
}
})
if (!dbResponse) return null
response = []
dbResponse.forEach(ele => {
const { report, submitter, resource, type } = ele
const { report, submitter, resource, type, decision, decisionPending } = ele
const responseEle = {
...report.properties,
decisionAt: decision
? decision.properties.updatedAt
: decisionPending
? decisionPending.properties.updatedAt
: null,
decisionDisable: decision
? decision.properties.disable
: decisionPending
? decisionPending.properties.disable
: null,
post: null,
comment: null,
user: null,
@ -122,7 +138,19 @@ export default {
session.close()
}
// Wolle console.log('response: ')
// response.forEach((ele, index) => {
// // console.log('ele #', index, ': ', ele)
// // if (ele.decision === undefined)
// // console.log('ele #', index, ': ', ele)
// if (ele.decision) console.log('ele #', index, ': ', ele)
// })
// // Wolle console.log('response: ', response)
return response
},
},
REPORTED: {
...undefinedToNullResolver(['decisionUuid', 'decisionAt', 'decisionDisable']),
},
}

View File

@ -411,6 +411,7 @@ describe('report resources', () => {
})
})
})
describe('query for reported resource', () => {
const reportsQuery = gql`
query {

View File

@ -5,8 +5,7 @@ type DECIDED {
# reasonDescription: String
disable: Boolean!
closed: Boolean!
# internal
uuid: ID
last: Boolean!
moderator: User
@ -15,7 +14,7 @@ type DECIDED {
# resource: ReportResource
# @cypher(statement: "MATCH (resource)<-[:DECIDED]-(:User) RETURN resource")
type: String
@cypher(statement: "MATCH (resource)<-[:DECIDED]-(:User) RETURN labels(resource)[0]")
@cypher(statement: "MATCH (resource)<-[:DECIDED]-(user:User) RETURN labels(resource)[0]")
user: User
post: Post
comment: Comment

View File

@ -25,7 +25,7 @@ enum NotificationReason {
type Query {
notifications(read: Boolean, orderBy: NotificationOrdering): [NOTIFIED]
}
type Mutation {
markAsRead(id: ID!): NOTIFIED
}

View File

@ -1,7 +1,16 @@
type REPORTED {
createdAt: String
reasonCategory: ReasonCategory
reasonDescription: String
createdAt: String!
reasonCategory: ReasonCategory!
reasonDescription: String!
closed: Boolean!
decisionUuid: ID
decisionDisable: Boolean
decisionAt: String
# Wolle decision: DECIDED
# @cypher(statement: "MATCH (resource)<-[decision:DECIDED {uuid: $decisionUuid}]-(user:User) RETURN decision")
submitter: User
@cypher(statement: "MATCH (resource)<-[:REPORTED]-(user:User) RETURN user")
# not yet supported
@ -12,8 +21,6 @@ type REPORTED {
user: User
post: Post
comment: Comment
# decided: DECIDED
}
# this list equals the strings of an array in file "webapp/constants/modals.js"

View File

@ -697,6 +697,14 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
// report content a second time
authenticatedUser = await dewey.toJson()
await Promise.all([
mutate({
mutation: reportMutation,
variables: {
resourceId: 'c5',
reasonCategory: 'doxing',
reasonDescription: "That's my friends privat data!",
},
}),
mutate({
mutation: reportMutation,
variables: {

View File

@ -20,5 +20,8 @@ MATCH (moderator:User)-[disabled:DISABLED]->(resource)
DELETE disabled
CREATE (moderator)-[decision:DECIDED]->(resource)
SET decision.createdAt = toString(datetime()), decision.disable = true, decision.last = true, decision.closed = false
RETURN decision;
WITH decision
MATCH (:User)-[report:REPORTED]->(resource)
SET report.closed = false
RETURN decision, report;
" | cypher-shell

View File

@ -8,6 +8,10 @@ export const reportListQuery = () => {
createdAt
reasonCategory
reasonDescription
closed
decisionUuid
decisionAt
decisionDisable
type
submitter {
id

View File

@ -454,8 +454,9 @@
"type": "Typ",
"content": "Inhalt",
"author": "Autor",
"decision": "Entscheidung",
"decided": "Entschieden",
"noDecision": "Keine Entscheidung!",
"enabledBy": "Aktiviert von",
"disabledBy": "Deaktiviert von",
"reasonCategory": "Kategorie",
"reasonDescription": "Beschreibung",

View File

@ -455,8 +455,9 @@
"type": "Type",
"content": "Content",
"author": "Author",
"decision": "Decision",
"decided": "Decided",
"noDecision": "No decision!",
"enabledBy": "Enabled by",
"disabledBy": "Disabled by",
"reasonCategory": "Category",
"reasonDescription": "Description",

View File

@ -87,17 +87,30 @@
<span v-else></span>
</td>
<td class="ds-table-col ds-table-head-col-border">
<!-- disabledBy -->
<!-- closed -->
<span v-if="content.closed" class="decision">
{{ $t('moderation.reports.decided') }}
</span>
<span v-else class="no-decision">
{{ $t('moderation.reports.noDecision') }}
</span>
<!-- decidedByModerator -->
<div v-if="content.resource.decidedByModerator">
{{ $t('moderation.reports.disabledBy') }}
<br />
<div v-if="content.decisionDisable">
{{ $t('moderation.reports.disabledBy') }}
</div>
<div v-else>
{{ $t('moderation.reports.enabledBy') }}
</div>
<hc-user
:user="content.resource.decidedByModerator"
:showAvatar="false"
:trunc="30"
:date-time="content.decisionAt"
positionDatetime="below"
/>
</div>
<span v-else class="no-decision">{{ $t('moderation.reports.noDecision') }}</span>
</td>
</tr>
<tr>
@ -175,6 +188,7 @@ export default {
reports: {
immediate: true,
handler(newReports) {
// Wolle console.log('newReports: ', newReports)
const newReportedContentStructure = []
newReports.forEach(report => {
const resource =
@ -192,6 +206,10 @@ export default {
if (idx === -1) {
idx = newReportedContentStructure.length
newReportedContentStructure.push({
closed: report.closed,
decisionUuid: report.decisionUuid,
decisionAt: report.decisionAt,
decisionDisable: report.decisionDisable,
type: report.type,
resource,
user: report.user,
@ -203,6 +221,7 @@ export default {
}
newReportedContentStructure[idx].reports.push(report)
})
// Wolle console.log('newReportedContentStructure: ', newReportedContentStructure)
this.reportedContentStructure = newReportedContentStructure
},
},
@ -221,6 +240,9 @@ export default {
.ds-table-head-col-border {
border-bottom: $border-color-softer dotted $border-size-base;
}
.decision {
color: $color-secondary;
}
.no-decision {
color: $text-color-danger;
}