first approach, filtering out resubmission work, but expensive and query don't longer work

This commit is contained in:
einhorn_b 2023-11-20 18:48:46 +01:00
parent d20904fbfe
commit ac7c4bf686
14 changed files with 154 additions and 9 deletions

View File

@ -4,6 +4,15 @@
<b-form @reset.prevent="onReset" @submit="onSubmit(messageType.DIALOG)">
<b-tabs content-class="mt-3" v-model="chatOrMemo">
<b-tab :title="$t('moderator.chat')" active>
<b-form-group>
<b-form-checkbox v-model="showResubmissionDate">
{{ $t('moderator.show-submission-form') }}
</b-form-checkbox>
</b-form-group>
<b-form-group v-if="showResubmissionDate">
<b-form-datepicker v-model="resubmissionDate"></b-form-datepicker>
<time-picker v-model="resubmissionTime"></time-picker>
</b-form-group>
<b-form-textarea
id="textarea"
v-model="form.text"
@ -65,8 +74,12 @@
<script>
import { adminCreateContributionMessage } from '@/graphql/adminCreateContributionMessage'
import { adminUpdateContribution } from '@/graphql/adminUpdateContribution'
import TimePicker from '@/components/input/TimePicker'
export default {
components: {
TimePicker,
},
name: 'ContributionMessagesFormular',
props: {
contributionId: {
@ -85,6 +98,9 @@ export default {
memo: this.contributionMemo,
},
loading: false,
resubmissionDate: null,
resubmissionTime: '00:00',
showResubmissionDate: false,
chatOrMemo: 0, // 0 = Chat, 1 = Memo
messageType: {
DIALOG: 'DIALOG',
@ -93,6 +109,22 @@ export default {
}
},
methods: {
combineResubmissionDateAndTime() {
if (this.resubmissionDate) {
const formattedDate = new Date(this.resubmissionDate)
console.log('resubmission time: %s', this.resubmissionTime)
const [hours, minutes] = this.resubmissionTime.split(':')
console.log('hours: %s, minutes: %s', hours, minutes)
formattedDate.setHours(parseInt(hours))
console.log('set hours: %d', formattedDate.getHours())
formattedDate.setMinutes(parseInt(minutes))
console.log('set minutes: %d', formattedDate.getMinutes())
console.log('IOS String: %s', formattedDate.toISOString())
return formattedDate.toString()
} else {
return null
}
},
onSubmit(mType) {
this.loading = true
if (this.chatOrMemo === 0) {
@ -103,6 +135,9 @@ export default {
contributionId: this.contributionId,
message: this.form.text,
messageType: mType,
resubmissionAt: this.showResubmissionDate
? this.combineResubmissionDateAndTime()
: null,
},
})
.then((result) => {
@ -141,6 +176,9 @@ export default {
onReset(event) {
this.form.text = ''
this.form.memo = this.contributionMemo
this.showResubmissionDate = false
this.resubmissionDate = null
this.resubmissionTime = '00:00'
},
enableMemo() {
this.chatOrMemo = 1

View File

@ -0,0 +1,48 @@
<template>
<div>
<input
type="text"
v-model="timeValue"
@input="updateValues"
@blur="validateAndCorrect"
placeholder="hh:mm"
/>
</div>
</template>
<script>
export default {
// Code written from chatGPT 3.5
name: 'TimePicker',
props: {
value: {
type: String,
default: '00:00',
},
},
data() {
return {
timeValue: this.value,
}
},
methods: {
updateValues(event) {
// Allow only numbers and ":"
const inputValue = event.target.value.replace(/[^0-9:]/g, '')
this.timeValue = inputValue
this.$emit('input', inputValue)
},
validateAndCorrect() {
let [hours, minutes] = this.timeValue.split(':')
// Validate hours and minutes
hours = Math.min(Math.max(parseInt(hours) || 0, 0), 23)
minutes = Math.min(Math.max(parseInt(minutes) || 0, 0), 59)
// Update the value with correct format
this.timeValue = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`
this.$emit('input', this.timeValue)
},
},
}
</script>

View File

@ -1,11 +1,17 @@
import gql from 'graphql-tag'
export const adminCreateContributionMessage = gql`
mutation ($contributionId: Int!, $message: String!, $messageType: ContributionMessageType) {
mutation (
$contributionId: Int!
$message: String!
$messageType: ContributionMessageType
$resubmissionAt: String
) {
adminCreateContributionMessage(
contributionId: $contributionId
message: $message
messageType: $messageType
resubmissionAt: $resubmissionAt
) {
id
message

View File

@ -9,6 +9,7 @@ export const adminListContributions = gql`
$userId: Int
$query: String
$noHashtag: Boolean
$hideResubmission: Boolean
) {
adminListContributions(
currentPage: $currentPage
@ -18,6 +19,7 @@ export const adminListContributions = gql`
userId: $userId
query: $query
noHashtag: $noHashtag
hideResubmission: $hideResubmission
) {
contributionCount
contributionList {

View File

@ -99,6 +99,8 @@
}
},
"hide_details": "Details verbergen",
"hide_resubmission": "Wiedervorlage verbergen",
"hide_resubmission_tooltip": "Verbirgt alle Schöpfungen für die ein Moderator ein Erinnerungsdatum festgelegt hat.",
"lastname": "Nachname",
"math": {
"equals": "=",
@ -111,6 +113,7 @@
"moderator": {
"chat": "Chat",
"history": "Die Daten wurden geändert. Dies sind die alten Daten.",
"show-submission-form": "warten auf Erinnerung?",
"moderator": "Moderator",
"notice": "Moderator Notiz",
"memo": "Memo",

View File

@ -99,6 +99,8 @@
}
},
"hide_details": "Hide details",
"hide_resubmission": "Hide resubmission",
"hide_resubmission_tooltip": "Hides all creations for which a moderator has set a reminder date.",
"lastname": "Lastname",
"math": {
"equals": "=",
@ -111,6 +113,7 @@
"moderator": {
"chat": "Chat",
"history": "The data has been changed. This is the old data.",
"show-submission-form": "wait for reminder?",
"moderator": "Moderator",
"notice": "Moderator note",
"memo": "Memo",

View File

@ -2,10 +2,16 @@
<template>
<div class="creation-confirm">
<user-query class="mb-2 mt-2" v-model="query" :placeholder="$t('user_memo_search')" />
<label class="mb-4">
<p class="mb-2">
<input type="checkbox" class="noHashtag" v-model="noHashtag" />
<span class="ml-2" v-b-tooltip="$t('no_hashtag_tooltip')">{{ $t('no_hashtag') }}</span>
</label>
</p>
<p class="mb-4">
<input type="checkbox" class="hideResubmission" v-model="hideResubmission" />
<span class="ml-2" v-b-tooltip="$t('hide_resubmission_tooltip')">
{{ $t('hide_resubmission') }}
</span>
</p>
<div>
<b-tabs v-model="tabIndex" content-class="mt-3" fill>
<b-tab active :title-link-attributes="{ 'data-test': 'open' }">
@ -125,6 +131,7 @@ export default {
pageSize: 25,
query: '',
noHashtag: null,
hideResubmission: true,
}
},
watch: {
@ -438,6 +445,7 @@ export default {
statusFilter: this.statusFilter,
query: this.query,
noHashtag: this.noHashtag,
hideResubmission: this.hideResubmission,
}
},
fetchPolicy: 'no-cache',

View File

@ -12,7 +12,7 @@ Decimal.set({
})
const constants = {
DB_VERSION: '0076-add_updated_by_contribution',
DB_VERSION: '0077-add_resubmission_date_contribution_message',
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info

View File

@ -1,3 +1,4 @@
import { isValidDateString } from '@/graphql/validator/DateString'
import { IsInt, IsString, IsEnum } from 'class-validator'
import { ArgsType, Field, Int, InputType } from 'type-graphql'
@ -17,4 +18,8 @@ export class ContributionMessageArgs {
@Field(() => ContributionMessageType, { defaultValue: ContributionMessageType.DIALOG })
@IsEnum(ContributionMessageType)
messageType: ContributionMessageType
@Field(() => String, { nullable: true })
@isValidDateString()
resubmissionAt?: string | null
}

View File

@ -22,4 +22,8 @@ export class SearchContributionsFilterArgs {
@Field(() => Boolean, { nullable: true })
@IsBoolean()
noHashtag?: boolean | null
@Field(() => Boolean, { nullable: true })
@IsBoolean()
hideResubmission?: boolean | null
}

View File

@ -125,7 +125,7 @@ export class ContributionMessageResolver {
@Authorized([RIGHTS.ADMIN_CREATE_CONTRIBUTION_MESSAGE])
@Mutation(() => ContributionMessage)
async adminCreateContributionMessage(
@Args() { contributionId, message, messageType }: ContributionMessageArgs,
@Args() { contributionId, message, messageType, resubmissionAt }: ContributionMessageArgs,
@Ctx() context: Context,
): Promise<ContributionMessage> {
const moderator = getUser(context)
@ -156,6 +156,9 @@ export class ContributionMessageResolver {
contributionMessage.userId = moderator.id
contributionMessage.type = messageType
contributionMessage.isModerator = true
if (resubmissionAt) {
contributionMessage.resubmissionAt = new Date(resubmissionAt)
}
await queryRunner.manager.insert(DbContributionMessage, contributionMessage)
if (messageType !== ContributionMessageType.MODERATOR) {

View File

@ -1,6 +1,7 @@
/* eslint-disable security/detect-object-injection */
import { Brackets, In, Like, Not, SelectQueryBuilder } from '@dbTools/typeorm'
import { Contribution as DbContribution } from '@entity/Contribution'
import { Brackets, In, Like, MoreThan, Not, SelectQueryBuilder } from '@dbTools/typeorm'
import { Contribution, Contribution as DbContribution } from '@entity/Contribution'
import { ContributionMessage } from '@entity/ContributionMessage'
import { Paginated } from '@arg/Paginated'
import { SearchContributionsFilterArgs } from '@arg/SearchContributionsFilterArgs'
@ -46,6 +47,30 @@ export const findContributions = async (
...(filter.userId && { userId: filter.userId }),
...(filter.noHashtag && { memo: Not(Like(`%#%`)) }),
})
if (relations?.messages && filter.hideResubmission) {
queryBuilder.andWhere((qb: SelectQueryBuilder<Contribution>) => {
const newestContributionMessageResubmissionDateSubQuery = qb
.subQuery()
// .select(['contributionMessage.resubmission_at', 'MAX(contributionMessage.created_at)'])
.select('contributionMessage.resubmission_at')
.from(ContributionMessage, 'contributionMessage')
.where('contributionMessage.contribution_id = Contribution.id')
.orderBy('contributionMessage.resubmissionAt', 'DESC')
.limit(1)
// .andWhere({ resubmissionAt: MoreThan(currentDate) })
.getQuery()
return (
'NOT EXISTS ' +
newestContributionMessageResubmissionDateSubQuery +
' OR ' +
newestContributionMessageResubmissionDateSubQuery +
' IS NULL ' +
' OR ' +
newestContributionMessageResubmissionDateSubQuery +
' <= NOW()'
)
})
}
queryBuilder.printSql()
if (filter.query) {
const queryString = '%' + filter.query + '%'

View File

@ -4,7 +4,7 @@ import dotenv from 'dotenv'
dotenv.config()
const constants = {
DB_VERSION: '0076-add_updated_by_contribution',
DB_VERSION: '0077-add_resubmission_date_contribution_message',
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info
LOG_LEVEL: process.env.LOG_LEVEL || 'info',

View File

@ -10,7 +10,7 @@ Decimal.set({
})
const constants = {
DB_VERSION: '0076-add_updated_by_contribution',
DB_VERSION: '0077-add_resubmission_date_contribution_message',
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info