2025-02-06 16:18:32 +01:00

219 lines
6.2 KiB
Vue

<template>
<div class="contribution-form">
<BForm
ref="form"
class="form-style p-3 bg-white app-box-shadow gradido-border-radius"
@submit.prevent="submit"
>
<ValidatedInput
id="contribution-date"
:model-value="formValues.date"
name="date"
:label="$t('contribution.selectDate')"
:no-flip="true"
class="mb-4 bg-248"
type="date"
:rules="validationSchema"
@update:model-value="updateField"
/>
<div v-if="showMessage" class="p-3" data-test="contribtion-message">
{{ noOpenCreation }}
</div>
<div v-else>
<input-textarea
id="contribution-memo"
:model-value="formValues.memo"
name="memo"
:label="$t('contribution.activity')"
:placeholder="$t('contribution.yourActivity')"
:rules="validationSchema"
@update:model-value="updateField"
/>
<ValidatedInput
name="hours"
:model-value="formValues.hours"
:label="$t('form.hours')"
placeholder="0.01"
step="0.01"
type="number"
:rules="validationSchema"
@update:model-value="updateField"
/>
<LabeledInput
id="contribution-amount"
class="mt-3"
name="amount"
:label="$t('form.amount')"
placeholder="20"
readonly
type="text"
trim
/>
<BRow class="mt-5">
<BCol>
<BButton
block
type="reset"
variant="secondary"
data-test="button-cancel"
@click="fullFormReset"
>
{{ $t('form.cancel') }}
</BButton>
</BCol>
<BCol class="text-end mt-lg-0">
<BButton
block
type="submit"
variant="gradido"
:disabled="disabled"
data-test="button-submit"
>
{{ form.id ? $t('form.change') : $t('contribution.submit') }}
</BButton>
</BCol>
</BRow>
</div>
</BForm>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import InputTextarea from '@/components/Inputs/InputTextarea'
import ValidatedInput from '@/components/Inputs/ValidatedInput'
import LabeledInput from '@/components/Inputs/LabeledInput'
import { memo } from '@/validationSchemas'
import { useForm } from 'vee-validate'
import { object, date, number } from 'yup'
const props = defineProps({
modelValue: { type: Object, required: true },
isThisMonth: { type: Boolean, required: true },
minimalDate: { type: Date, required: true },
maxGddLastMonth: { type: Number, required: true },
maxGddThisMonth: { type: Number, required: true },
})
const emit = defineEmits(['update-contribution', 'set-contribution'])
const { t } = useI18n()
const form = ref({ ...props.modelValue })
const maxHours = computed(() => Number(props.isThisMonth ? props.maxGddThisMonth : props.maxGddLastMonth / 20))
const validationSchema = computed(() => {
// const maxGDD = Number(props.isThisMonth ? props.maxGddThisMonth : props.maxGddLastMonth)
// const maxHours = Number(maxGDD / 20)
console.log('compute validationSchema', { maxHours })
return object({
// The date field is required and needs to be a valid date
// contribution date
date: date()
.required('contribution.noDateSelected')
.min(new Date(new Date().setMonth(new Date().getMonth() - 1, 1)).toISOString().slice(0, 10)) // min date is first day of last month
.max(new Date().toISOString().slice(0, 10))
.default(''), // date cannot be in the future
memo,
hours: number().required('contribution.noHours')
.min(0.01, ({min}) => ({ key: 'form.validation.gddCreationTime.min', values: { min } }))
.max(maxHours.value, ({max}) => ({ key: 'form.validation.gddCreationTime.max', values: { max } }))
.test(
'decimal-places',
'form.validation.gddCreationTime.decimal-places',
(value) => {
if (value === undefined || value === null) return true
return /^\d+(\.\d{0,2})?$/.test(value.toString())
}
),
})
})
const {
values: formValues,
meta: formMeta,
resetForm,
setFieldValue,
} = useForm({
initialValues: {
date: props.modelValue.date,
memo: props.modelValue.memo,
hours: props.modelValue.hours,
amount: props.modelValue.amount,
},
validationSchema: validationSchema.value,
})
const updateField = (newValue, name) => {
if (typeof name === 'string' && name.length) {
setFieldValue(name, newValue)
}
if (name === 'hours') {
setFieldValue('amount', (newValue * 20).toFixed(2).toString())
}
}
const showMessage = computed(() => {
if (props.maxGddThisMonth <= 0 && props.maxGddLastMonth <= 0) return true
if (props.modelValue.date)
return (
(props.isThisMonth && props.maxGddThisMonth <= 0) ||
(!props.isThisMonth && props.maxGddLastMonth <= 0)
)
return false
})
const disabled = computed(() => {
return (
!formMeta.value.valid ||
(props.isThisMonth && parseFloat(form.value.amount) > parseFloat(props.maxGddThisMonth)) ||
(!props.isThisMonth && parseFloat(form.value.amount) > parseFloat(props.maxGddLastMonth))
)
})
const noOpenCreation = computed(() => {
if (props.maxGddThisMonth <= 0 && props.maxGddLastMonth <= 0) {
return t('contribution.noOpenCreation.allMonth')
}
if (props.isThisMonth && props.maxGddThisMonth <= 0) {
return t('contribution.noOpenCreation.thisMonth')
}
if (!props.isThisMonth && props.maxGddLastMonth <= 0) {
return t('contribution.noOpenCreation.lastMonth')
}
return ''
})
function submit() {
const dataToSave = { ...formValues }
let emitOption = 'set-contribution'
if (props.modelValue.id) {
dataToSave.id = props.modelValue.id
emitOption = 'update-contribution'
}
emit(emitOption, dataToSave)
fullFormReset()
}
function fullFormReset() {
resetForm({
values: {
date: '',
memo: '',
hours: 0.0,
amount: '',
}
})
}
</script>
<style>
.form-style {
min-height: 410px;
}
span.errors {
color: red;
}
</style>