[CHR WIP] CHR10, CHR12, CHR13, CHR14, CHR15, CHR17 - WIP not validated

This commit is contained in:
Matej Glasnák committed 2023-06-01 14:07:08 +02:00
1 parent 994d3449d3
commit fcd8199d86
12 files changed
+353 -52

No files matched your search

+9 -2
View File
@@ -16,7 +16,8 @@
<Z-task-add-time-modal ref="z-task-add-time-modal" />
<Z-blocker-modal ref="z-blocker-modal" />
<Z-master-task-modal ref="z-master-task-modal" @master-task-edited="onMasterTaskEdited" />
<Z-master-task-modal ref="z-master-task-modal" @master-task-edited="onMasterTaskEdited" />
<Z-delete-team-member-modal ref="z-delete-team-member-modal" />
</template>
<script>
@@ -30,6 +31,7 @@ import ZTaskAddTimeModal from '@/plugins/tm@modal/task/z-task-add-time-modal.v
import ZBlockerModal from '@/plugins/tm@modal/blocker/z-blocker-modal.vue'
import ZDeleteMasterTaskModal from '@/plugins/tm@modal/master-task/z-delete-master-task-modal.vue'
import ZMasterTaskModal from '@/plugins/tm@modal/master-task/z-master-task-modal.vue'
import ZDeleteTeamMemberModal from '@/plugins/tm@modal/master-task/z-delete-team-member-modal.vue'
export default {
components: {
@@ -42,7 +44,8 @@ export default {
ZCompleteTaskModal,
ZTaskAddTimeModal,
ZBlockerModal,
ZDeleteMasterTaskModal
ZDeleteMasterTaskModal,
ZDeleteTeamMemberModal
},
mounted() {
@@ -66,6 +69,10 @@ export default {
this.$refs['z-delete-master-task-modal'].showModal({mastertask})
})
this.$events.on('show-delete-team-member-modal', ({member, team}) => {
this.$refs['z-delete-team-member-modal'].showModal({member, team})
})
this.$events.on('show-subtask-modal', ({subtask, editMode, mastertask}) => {
if(subtask && subtask.id) {
const id = subtask.id
@@ -15,6 +15,11 @@
.modal-input
width: 100% !important
flex: 0 0 auto
min-height: 60px
input,
.v-field
min-height: 60px
.modal-content
flex: 1 1 100%
@@ -29,4 +34,15 @@
top: 25%
.relative
position: relative !important
position: relative !important
.splitted-inputs
width: 100%
display: flex
justify-content: space-between
.left
width: 70% !important
.right
width: 25% !important
+1 -1
View File
@@ -103,4 +103,4 @@ input[type="time"]::-webkit-calendar-picker-indicator
.v-row.subheader
.v-input
height: 56px !important
height: 40px !important
+19 -2
View File
@@ -17,7 +17,7 @@ transition-group.vuecal__cell(
@keypress.enter="onCellkeyPressEnter($event)"
@touchstart="!isDisabled && onCellTouchStart($event, splitsCount ? split.id : null)"
@mousedown="!isDisabled && onCellMouseDown($event, splitsCount ? split.id : null)"
@click="!isDisabled && onCellClick($event)"
@click="!isDisabled && onCellClick($event, split)"
@dblclick="!isDisabled && onCellDblClick($event)"
@contextmenu="!isDisabled && options.cellContextmenu && onCellContextMenu($event)"
@dragenter="!isDisabled && editEvents.drag && dnd && dnd.cellDragEnter($event, $data, data.startDate)"
@@ -63,6 +63,7 @@ transition-group.vuecal__cell(
<script>
import Event from './event.vue'
import tmUtils from '@/plugins/tm@_utils/tm.utils'
export default {
inject: ['vuecal', 'utils', 'modules', 'view', 'domEvents'],
@@ -80,6 +81,7 @@ export default {
},
data: () => ({
tmUtils,
cellOverlaps: {},
cellOverlapsStreak: 1, // Largest amount of simultaneous events in cell.
// On mouse down, save the time at cursor so it can be reused on cell focus event
@@ -251,7 +253,22 @@ export default {
this.onCellMouseDown(DOMEvent, split, true)
},
onCellClick (DOMEvent) {
onCellClick(DOMEvent, split) {
if (DOMEvent.offsetY > 950 && DOMEvent.offsetY < 1700) {
const dateFrom = split.date
dateFrom.setHours(Math.floor(DOMEvent.offsetY / 100), 0, 0, 0)
const dateTo = new Date(dateFrom)
dateTo.setHours(dateFrom.getHours() + 1)
this.$events.emit('show-subtask-modal', {})
setTimeout(() => {
this.$events.emit('add-timeblock', {
id: null,
start: tmUtils.formatDateTimeForBackend(dateFrom),
end: tmUtils.formatDateTimeForBackend(dateTo)
})
}, 150)
}
if (!this.isDOMElementAnEvent(DOMEvent.target)) this.selectCell(DOMEvent)
},
@@ -245,7 +245,6 @@ export default {
);
const height = Math.max(bottom - top, 5); // Min height is 5px.
return { top, height };
},
@@ -17,7 +17,7 @@
:scroll-to-hour="calConfig.scrollHour"
:split-days="splits"
:sticky-split-labels="true"
:min-split-width="270"
:min-split-width="220"
@ready="onReady()"
@view-change="weekChanged"
@event-drop="eventMoved"
@@ -304,11 +304,11 @@ export default {
// TIME COLUMN
.vuecal__time-column
width: 150px
width: 80px
box-shadow: none !important
.time-column-line
width: 40px
width: 20px
height: 0
border: 1px solid rgba(33, 33, 33, 0.08)
margin-left: 10px
@@ -1,5 +1,5 @@
<template>
<v-row class="px-10 py-8 subheader">
<v-row class="px-7 py-5 subheader">
<v-autocomplete
v-model="selectedEmployee"
class="subheader-input"
@@ -120,8 +120,8 @@ export default {
.subheader-icon-button
border: 1px solid #ABABAB
height: 56px
width: 56px
height: 60px
width: 60px
min-width: auto !important
padding: 0
margin: 0
@@ -136,9 +136,19 @@ export default {
margin: 0
.subheader-input
max-width: 250px !important
min-width: 250px
height: 56px
max-width: 175px
min-width: 175px
height: 60px !important
&:nth-child(2)
max-width: 250px !important
min-width: 250px !important
&:deep(.v-input__control)
.v-field
height: 60px !important
--v-input-control-height: 60px !important
--v-input-padding-top: 19px !important
&:deep(.v-input__details)
display: none
@@ -33,6 +33,7 @@ export default {
onEmployeeSelected(id) {
const employee = this.enrichedEmployees.find(employee => employee.id == id)
console.log('add employee', employee)
this.mastertask.employees.push(employee)
this.showAddEmployeeInput = false
},
@@ -0,0 +1,94 @@
<template>
<v-dialog v-model="visible" max-width="500" >
<v-card>
<h1 class="text-h5">
Chcete túto osobu odstrániť z tímu?
</h1>
<v-card-text>{{ member.name + ' ' + member.surname }} bude odstránený/á z teamu.</v-card-text>
<v-card-actions>
<v-btn
class="button primary"
variant="text"
@click="closeModal()"
>
Zrušiť
</v-btn>
<v-spacer></v-spacer>
<v-btn
class="button primary"
variant="text"
@click="deleteMember()"
>
Áno
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
import tmUtils from '@/plugins/tm@_utils/tm.utils'
export default {
data() {
return {
visible: false,
member: null,
allMembers: null,
teamId: null,
team: null
}
},
methods: {
async showModal({ member, team }) {
this.member = member
this.allMembers = team.employees
this.teamId = team.id
this.team = team
this.visible = true
},
closeModal() {
this.visible = false
},
editDatepicker(type) {
const calendarElement = document.getElementsByClassName('dp__instance_calendar')[0]
const switchBtn = calendarElement.lastChild.querySelectorAll('.dp__button')[0]
if (!calendarElement) return
if (type == 'date') {
calendarElement.lastChild.remove()
} else if (type == 'time') {
switchBtn.click()
//calendarElement.lastChild.remove()
}
},
async deleteMember() {
const filteredMembers = this.allMembers.filter(obj => obj !== this.member)
this.team.employees = filteredMembers
try {
if (this.teamId) {
const { team } = await this.$axios.put_auth(`v1/teams/${this.teamId}`, this.team)
this.$store.commit('tm/update_team', team)
} else {
const { team } = await this.$axios.post_auth(`v1/teams`, this.team)
this.$store.commit('tm/save_team', team)
}
this.$events.emit('memberDeleted', { filteredMembers })
this.closeModal()
} catch (error) {
this.$toast.error(error)
}
},
_enrichTeam(team) {
team.employees = tmUtils.enrichEmployees(team.employees)
return team
}
}
}
</script>
@@ -12,17 +12,33 @@
<v-text-field v-model="mastertask.name" @focus="onInputFocus" class="modal-input" label="Názov mastertasku" variant="solo" :class="{ error: v$.mastertask.name.$errors.length }" :hint="v$.mastertask.name.$errors ? errorUtils.parseErrors(v$.mastertask.name.$errors) : null"></v-text-field>
<Datepicker v-model="mastertask.deadline" @focus="onDateFocus" :min-date="new Date()" class="modal-input" format="dd.MM.yyyy, HH:mm" locale="sk" :class="{ error: v$.mastertask.deadline.$errors.length }" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Deadline" />
<div class="splitted-inputs">
<!-- TODO: Bialko validacie -->
<Datepicker @open="editDatepicker('date')" v-model="mastertask.deadline" @focus="onDateFocus" :min-date="new Date()" class="modal-input left" format="dd.MM.yyyy" locale="sk" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Dátum"
:class="{ error: v$.mastertask.deadline.$errors?.length }" :validations="v$.mastertask.deadline" />
<v-text-field v-model="mastertask.duration" @focus="onInputFocus" class="modal-input mt-5" variant="solo" type="number" disabled :label="`${mastertask.duration} h`"></v-text-field>
<v-text-field class="modal-input right" variant="solo" v-model="mastertask._deadline_time" label="Čas" append-inner-icon="mdi-clock-outline" type="time" @focus="onInputFocus"
:class="{ error: v$.mastertask._deadline_time.$errors.length }" :hint="v$.mastertask._deadline_time.$errors ? errorUtils.parseErrors(v$.mastertask._deadline_time.$errors) : null" />
</div>
<v-select v-model="mastertask.team_id" @focus="onInputFocus" class="modal-input border-select" :class="{ error: v$.mastertask.team_id.$errors.length }" label="Tím" variant="solo" :items="teams" item-value="id" item-title="name"></v-select>
<v-text-field v-model="mastertask.duration" @focus="onInputFocus" class="modal-input" variant="solo" type="number" :label="`${mastertask.duration} h`"></v-text-field>
<v-select v-model="mastertask.team_id" @focus="onInputFocus" class="modal-input border-select" :class="{ error: v$.mastertask.employees.$errors.length }" label="Tím" variant="solo" :items="teams" item-value="id" item-title="name"></v-select>
<template v-if="!mastertask.id && mastertask.team_id">
<v-text-field v-for="(employee, index) in mastertask.employees" :key="employee.id" @focus="onInputFocus" :class="{ error: !mastertask.employees[index].duration }" class="modal-input" :label="`${employee.name} ${employee.surname}`" variant="solo" placeholder="h" v-model="mastertask.employees[index].duration" type="number" min="1" @input="onEmployeeDurationChanged">
<v-text-field v-for="(employee, index) in mastertask.employees" :key="employee.id" @focus="onInputFocus" class="modal-input" :label="`${employee.name} ${employee.surname}`" variant="solo" placeholder="h" v-model="mastertask.employees[index].duration" type="number" min="1" @input="onEmployeeDurationChanged">
<p class="employee-select-avatar d-flex justify-center align-center">
{{ employee.name.charAt(0) + employee.surname.charAt(0) }}
{{ employee?.name.charAt(0) + employee?.surname.charAt(0) }}
</p>
<v-icon @click.stop="removeMemberAlert(employee)" class="remove-input" icon="mdi-close" size="small"></v-icon>
</v-text-field>
</template>
<template v-if="!mastertask.id && !mastertask.team_id && mastertask.employees">
<v-text-field v-for="(employee, index) in mastertask.employees" :key="employee.id" @focus="onInputFocus" class="modal-input" :label="`${employee.name} ${employee.surname}`" variant="solo" placeholder="h" v-model="mastertask.employees[index].duration" type="number" min="1" @input="onEmployeeDurationChanged">
<p class="employee-select-avatar d-flex justify-center align-center">
{{ employee?.name.charAt(0) + employee?.surname.charAt(0) }}
</p>
<!-- <v-icon @click.stop="removeMemberAlert(employee)" class="remove-input" icon="mdi-close" size="small"></v-icon> -->
</v-text-field>
</template>
@@ -30,7 +46,7 @@
<!-- <Z-autocomplete label="Vyhľadať zamestnanca" :options="employeesOptions" class="modal-input" @option-selected="onEmployeeSelected" /> -->
<v-btn class="w-100 mb-5 button secondary" :disabled="!mastertask.team?.id" @click="showAddEmployeeInput = true"> <v-icon class="mx-1" icon="mdi-plus" />Pridať zamestnanca </v-btn>
<v-btn class="w-100 mb-5 button secondary" :class="{error: v$.mastertask.project_id.$errors.length}" @click="showAddEmployeeInput = true"> <v-icon class="mx-1" icon="mdi-plus" />Pridať zamestnanca </v-btn>
<div class="w-100 modal-input" :class="{ error: v$.mastertask.description.$errors.length }">
<QuillEditor ref="description" v-model="mastertask.description" placeholder="Popis" theme="snow" class="rich-text-editor" @input="mastertask.description = $event.srcElement.innerHTML" />
@@ -114,6 +130,7 @@ export default {
data() {
return {
deadline: null,
editMode: false,
visible: false,
errorUtils,
@@ -153,15 +170,21 @@ export default {
return {
mastertask: {
project_id: { required },
team_id: { required },
employees: { required },
name: { required },
description: { required },
deadline: { required }
deadline: { required },
_deadline_time: { required }
}
}
},
mounted() {
this.$events.on('memberDeleted', (filteredMembers) => {
console.log()
//this.mastertask.employees = filteredMembers
}),
this.$events.on('on-mastertask-deleted', (mastertask) => {
if (mastertask?.id == this.mastertask?.id) this.closeModal()
})
@@ -189,11 +212,30 @@ export default {
},
methods: {
removeMemberAlert(member) {
const team = this.mastertask.team
this.$events.emit('show-delete-team-member-modal', { member, team })
},
editDatepicker(type) {
const calendarElement = document.getElementsByClassName('dp__instance_calendar')[0]
const switchBtn = calendarElement.lastChild.querySelectorAll('.dp__button')[0]
if (!calendarElement) return
if (type == 'date') {
calendarElement.lastChild.remove()
} else if (type == 'time') {
switchBtn.click()
//calendarElement.lastChild.remove()
}
},
async showModal({mastertask, editMode = false}) {
this.editMode = null
this.visible = true
this.mastertask = null
this.$nextTick(() => this.v$.$reset())
this.$nextTick(() => {
this.v$.$reset()
})
try {
if (mastertask?.id) {
@@ -206,7 +248,7 @@ export default {
// this.mastertask.project_code = project.code
} else {
this.mastertask = { employees: [], duration: 0 }
this.mastertask = { employees: [], duration: 0, _deadline_time: '17:00' }
}
this.editMode = editMode || !this.mastertask.id
@@ -226,6 +268,8 @@ export default {
if (this.$refs['description'])
this.mastertask.description = this.$refs['description'].getHTML()
this._mergeDeadlineTimeDate()
try {
this.mastertask.deadline = moment(this.mastertask.deadline).format('YYYY-MM-DD HH:MM:SS')
@@ -253,6 +297,15 @@ export default {
addTask() {
this.$events.emit('show-subtask-modal', { subtask: null, editMode: false, mastertask: this.mastertask })
},
_mergeDeadlineTimeDate() {
const date = new Date(this.mastertask.deadline);
const timeParts = this.mastertask._deadline_time.split(':');
date.setHours(parseInt(timeParts[0]));
date.setMinutes(parseInt(timeParts[1]));
this.mastertask.deadline = date
}
},
@@ -260,6 +313,14 @@ export default {
editMode() {
this.$nextTick(() => {
this.$refs['description']?.setHTML(this.mastertask.description || '')
if (!this.mastertask) return
const date = new Date(this.mastertask.deadline)
const hours = date.getHours()
const minutes = date.getMinutes()
this.mastertask._deadline_time = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
})
}
}
@@ -267,6 +328,15 @@ export default {
</script>
<style lang="sass" scoped>
.date-wrap
display: flex
flex-flow: row
width: 100%
gap: 20px
.dp__main
width: calc(50% - 10px) !important
.employee-select-avatar
background: #6200EE
color: #fff
@@ -278,14 +348,20 @@ export default {
position: absolute
top: 50%
right: 0
transform: translate(-50%, -50%)
transform: translate(-120%, -50%)
.remove-input
position: absolute
top: 50%
transform: translate(120%, -50%)
cursor: pointer
.scrolling
overflow: hidden !important
.border-bottom
border-bottom: 1px solid rgba(0,0,0,.1)
.subtask-btn
border: thin solid rgba(var(--v-border-color), var(--v-border-opacity)) !important
color: #7f39fb !important
@@ -16,10 +16,10 @@
<p class="task-badge rounded-pill">Pridať záznam</p>
</div>
<div v-for="timeblock in timeblocks" :key="timeblock.id" class="d-flex align-center mb-3">
<v-icon @click.stop="deleteTimeblock(timeblock)" class="circle-border cursor-pointer mr-2" icon="mdi-minus" size="medium" />
<div v-for="(timeblock, index) in timeblocks" :key="timeblock.id" class="d-flex align-center mb-3">
<v-icon @click.stop="subtask.id ? deleteTimeblock(timeblock) : deleteTimeblockWithoutId(index)" class="circle-border cursor-pointer mr-2" icon="mdi-minus" size="medium" />
<p class="task-badge rounded-pill" :class="{'strike-through': timeblock.is_finished}">{{ tmUtils.formatDateTime(timeblock.start) }} - {{ tmUtils.formatDateTime(timeblock.end) }}</p>
<v-icon @click.stop="toggleTimeblockIsFinished(timeblock)" class="circle-border cursor-pointer ml-2" :class="{'completed': timeblock.is_finished}" icon="mdi-check" size="medium" />
<v-icon v-show="subtask.id" @click.stop="toggleTimeblockIsFinished(timeblock)" class="circle-border cursor-pointer ml-2" :class="{'completed': timeblock.is_finished}" icon="mdi-check" size="medium" />
</div>
</v-sheet>
</v-col>
@@ -107,11 +107,21 @@ export default {
const start = moment(this.form.date).hours(parseInt(splittedStartsAtTime[0])).minutes(parseInt(splittedStartsAtTime[1])).toISOString()
const end = moment(this.form.date).hours(parseInt(splittedEndsAtTime[0])).minutes(parseInt(splittedEndsAtTime[1])).toISOString()
if (!subtask?.timeblocks) { subtask.timeblocks = [] }
if (!subtask?.timesheets) { subtask.timesheets = [] }
if (!subtask?.is_finished) { subtask.is_finished = 0 }
subtask.timeblocks.push({
id: null,
start: tmUtils.formatDateTimeForBackend(start),
end: tmUtils.formatDateTimeForBackend(end)
})
if (!subtask.id) {
this.$emit('update-unfinished-subtask', subtask)
this.closeModal()
return
}
this._update(subtask)
},
@@ -150,6 +160,10 @@ export default {
this._update(subtask)
},
deleteTimeblockWithoutId(i) {
this.$emit('delete-timeblock')
},
async _update(data) {
try {
const { subtask } = await this.$axios.put_auth(`v1/subtasks/${data.id}`, data)
+88 -21
View File
@@ -13,6 +13,27 @@
<v-autocomplete v-model="subtask.master_task_id" label="Master task" :class="{error: v$.subtask.master_task_id.$errors.length}" :items="mastertasks" item-title="name" item-value="id" variant="solo" class="modal-input" clearable />
<v-text-field v-model="subtask.title" @focus="onInputFocus" class="modal-input" label="Názov subtasku" variant="solo"></v-text-field>
<div class="splitted-inputs">
<!-- TODO: Bialko validacie -->
<Datepicker @open="editDatepicker('date')" v-model="subtask.deadline" @focus="onDateFocus" :min-date="new Date()" class="modal-input left" format="dd.MM.yyyy" locale="sk" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Dátum"
:class="{ error: v$.subtask.deadline.$errors?.length }" :validations="v$.subtask.deadline" />
<v-text-field class="modal-input right" variant="solo" v-model="subtask._deadline_time" label="Čas" append-inner-icon="mdi-clock-outline" type="time" @focus="onInputFocus"
:class="{ error: v$.subtask._deadline_time.$errors.length }" :hint="v$.subtask._deadline_time.$errors ? errorUtils.parseErrors(v$.subtask._deadline_time.$errors) : null" />
</div>
<!-- TODO: Toto tu nema byt ci? -->
<!-- <div class="w-full">
<A-task-timeblocks
class="w-full"
:timeblocks="subtask.timeblocks"
:subtask="subtask"
@update-subtask="$emit('update-subtask')"
@update-unfinished-subtask="subtask = $event"
@delete-timeblock="deleteTimeblock($event)"
/>
</div> -->
<template v-if="subtask.id">
<v-autocomplete v-model="subtask.employee_id" label="Priradený" :items="enrichedEmployees" item-title="_fullName" item-value="id" variant="solo" class="modal-input" :class="{ error: employeeValidations[0]?.employee }"
@@ -22,10 +43,10 @@
</template>
<template v-else>
<div v-for="(employee, index) in subtask.employees" :key="`employee-${index}`" class="multiple-employee-select">
<v-autocomplete v-model="employee.id" label="Priradený" :items="enrichedEmployees" item-title="_fullName" item-value="id" variant="solo" class="modal-input employee" :class="{ error: employeeValidations[index]?.employee }"
<div v-for="(employee, index) in subtask.employees" :key="`employee-${index}`" class="splitted-inputs">
<v-autocomplete v-model="employee.id" label="Priradený" :items="enrichedEmployees" item-title="_fullName" item-value="id" variant="solo" class="modal-input left" :class="{ error: employeeValidations[index]?.employee }"
@update:model-value="employeeValidations[index] ? employeeValidations[index].employee = false : null" />
<v-text-field v-model="employee.duration" class="modal-input duration" variant="solo" type="number" label="Časový odhad" append-inner-icon="mdi-clock-outline" :class="{ error: employeeValidations[index]?.duration }" @focus="onInputFocus"
<v-text-field v-model="employee.duration" class="modal-input right" variant="solo" type="number" label="Časový odhad" append-inner-icon="mdi-clock-outline" :class="{ error: employeeValidations[index]?.duration }" @focus="onInputFocus"
@update:model-value="employeeValidations[index] ? employeeValidations[index].duration = false : null" />
</div>
</template>
@@ -60,6 +81,13 @@
<v-card-actions class="d-flex flex-column modal-content">
<div class="w-100">
<Z-task-readonly-info :subtask="subtask" @close-modal="closeModal" @update-subtask="updateSubtask" />
<!-- <div class="mt-10">
<p>Termín</p>
<div class="date-wrap">
<Datepicker @open="editDatepicker('date')" v-model="subtask.deadline" @focus="onDateFocus" :min-date="new Date()" class="modal-input" format="dd.MM.yyyy" locale="sk" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Dátum" />
<Datepicker @open="editDatepicker('time')" v-model="subtask.deadline" @focus="onDateFocus" :min-date="new Date()" class="modal-input" format="HH:mm" locale="sk" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Čas" />
</div>
</div> -->
<div class="d-flex justify-start align-center mt-8">
<v-btn class="done-btn" v-if="!subtask.is_finished" @click.stop="showCompleteTaskModal()">Dokončiť</v-btn>
@@ -74,7 +102,9 @@
</template>
<script>
import Datepicker from '@vuepic/vue-datepicker'
import ZFilesUpload from "@/plugins/tm@_components/z-files-upload.vue"
import ATaskTimeblocks from '@/plugins/tm@modal/task/_components/_components/a-task-timeblocks.vue'
import useVuelidate from "@vuelidate/core"
import { required } from "@vuelidate/validators"
import errorUtils from "@/plugins/lib@auth/_utils/error.utils"
@@ -95,6 +125,8 @@ export default {
components: {
ZTaskReadonlyInfo,
ZFilesUpload,
Datepicker,
// ATaskTimeblocks,
QuillEditor
},
@@ -124,12 +156,21 @@ export default {
return {
subtask: {
master_task_id: { required },
// title: { required }
deadline: { required },
_deadline_time: { required }
// description: { required }
}
}
},
mounted() {
this.$events.on("add-timeblock", (timeblock) => {
if (!this.subtask?.timeblocks) { this.subtask.timeblocks = [] }
if (!this.subtask?.timesheets) { this.subtask.timesheets = [] }
if (!this.subtask?.is_finished) { this.subtask.is_finished = 0 }
this.subtask.timeblocks.push(timeblock)
})
this.$events.on("on-subtask-edited", (subtask) => {
if (subtask?.id == this.subtask?.id)
this.subtask = this._enrichTask(subtask)
@@ -154,15 +195,30 @@ export default {
const data = await this.$axios.get_auth_data(`v1/subtasks/${subtask.id}`)
this.subtask = this._enrichTask(data)
} else {
this.subtask = { master_task: mastertask, employees: [{}] }
this.subtask = { master_task: mastertask, employees: [{}], _deadline_time: '17:00' }
}
this.editMode = editMode || !this.subtask.id
} catch (error) {
this.$toast.error(error)
}
},
deleteTimeblock(i) {
this.subtask.timeblocks.splice(i, 1)
},
editDatepicker(type) {
const calendarElement = document.getElementsByClassName('dp__instance_calendar')[0]
const switchBtn = calendarElement.lastChild.querySelectorAll('.dp__button')[0]
if (!calendarElement) return
if (type == 'date') {
calendarElement.lastChild.remove()
} else if (type == 'time') {
switchBtn.click()
//calendarElement.lastChild.remove()
}
},
closeModal() {
this.visible = false
this.$router.replace({name: this.$route.name})
@@ -171,10 +227,11 @@ export default {
async save() {
const employeesValid = await this._validateEmployees()
if (!(await this.v$.$validate()) || !employeesValid)
return
if (!(await this.v$.$validate())) return
if (!employeesValid) return
this.subtask.description = this.$refs['description'].getHTML()
this._mergeDeadlineTimeDate()
try {
if (this.subtask?.id) {
@@ -194,6 +251,7 @@ export default {
this.closeModal()
} catch (error) {
console.error(error)
this.$toast.error(error)
}
},
@@ -224,6 +282,15 @@ export default {
this.subtask = subtask
},
_mergeDeadlineTimeDate() {
const date = new Date(this.subtask.deadline);
const timeParts = this.subtask._deadline_time.split(':');
date.setHours(parseInt(timeParts[0]));
date.setMinutes(parseInt(timeParts[1]));
this.subtask.deadline = date
},
_validateEmployees() {
return new Promise((resolve) => {
this.employeeValidations = []
@@ -308,6 +375,19 @@ export default {
</script>
<style lang="sass" scoped>
.w-full
width: 100%
.date-wrap
display: flex
flex-flow: row
width: 100%
gap: 20px
margin-bottom: 20px
.dp__main
width: calc(50% - 10px) !important
.scrolling
overflow: hidden !important
@@ -324,17 +404,4 @@ export default {
@media screen and (max-width: 522px)
.files
margin-top: 104px !important
.multiple-employee-select
width: 100%
.modal-input
display: inline-block
.employee
width: 70% !important
.duration
width: 25% !important
margin-left: 5%
</style>