[quill editor, detail modals, ongoing & unscheduled modals, review, download files]

This commit is contained in:
romankko2 committed 2023-01-24 23:01:12 +01:00
1 parent 33dfb2bd6f
commit 65adc7e3cf
16 files changed
+567 -242

No files matched your search

+5
View File
@@ -58,3 +58,8 @@ th
input[type="time"]::-webkit-calendar-picker-indicator
display: none
border: 1px solid #E5E5E5 !important
.rich-text-editor
.ql-tooltip
left: 0 !important
@@ -14,45 +14,16 @@
</tr>
</tbody>
</v-table>
<Z-team-modal ref="z-team-modal" />
<!-- Kravarik: Aj tento modal prerob novym sposobom -->
<!-- <Z-delete-team-modal v-if="deleteModal" :visible="deleteModal ? true : false" :team="deleteModal.team" @close="(deleteModal = null)" /> -->
<Z-delete-team-modal ref="z-delete-team-modal" />
</div>
</template>
<script>
import ZDeleteTeamModal from '@/plugins/tm@modal/team/z-delete-team-modal.vue'
import ZTeamModal from '@/plugins/tm@modal/team/z-team-modal.vue'
export default {
components: {
ZDeleteTeamModal,
ZTeamModal
},
props: {
teams: {
type: Array,
required: true
}
},
data() {
return {
deleteModal: null
}
},
methods: {
editTeam(team) {
this.$refs['z-team-modal'].create(team)
},
deleteTeam(team) {
this.$refs['z-delete-team-modal'].delete(team)
}
}
}
</script>
@@ -71,9 +71,9 @@
</div>
<div class="event-footer d-flex">
<v-btn rounded class="event-footer-button me-2" :class="{'completed': event.completed}" @click="clickCompleteTask(event)"><img :src="require('./_img/checkmark.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" :class="{'completed': event.completed}" @click.stop="clickCompleteTask(event)"><img :src="require('./_img/checkmark.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" @click.stop="editTask(event.id, true)"><img :src="require('./_img/pencil.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" @click.stop="this.showDeleteModal = {task: event}"><img :src="require('./_img/bin.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" @click.stop="showDeleteModal = {task: event}"><img :src="require('./_img/bin.svg')" alt=""></v-btn>
</div>
</div>
@@ -86,9 +86,8 @@
</template>
</Vue-cal>
<Z-sub-task-modal ref="z-sub-task-modal" />
<!-- Kravarik: Prerobit modaly na novy sposob -->
<Z-sub-task-modal ref="z-sub-task-modal" />
<Z-complete-task-modal v-if="showCompleteModal" :visible="showCompleteModal ? true : false" :task="showCompleteModal.task" @completeTask="completeTask" @close="showCompleteModal = null" />
<Z-delete-task-modal v-if="showDeleteModal" :visible="showDeleteModal ? true : false" :task="showDeleteModal.task" @deleteTask="deleteTask" @close="showDeleteModal = null" />
<Z-add-time-task-modal ref="z-add-time-task-modal" />
@@ -98,16 +97,16 @@
<script>
import ZCompleteTaskModal from '@/plugins/tm@modal/task/z-complete-task-modal.vue'
import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue'
import ZAddTimeTaskModal from '@/plugins/tm@modal/sub-task/z-add-time-task-modal.vue'
import ZSubTaskModal from '@/plugins/tm@modal/sub-task/z-sub-task-modal.vue'
import ZAddTimeTaskModal from '@/plugins/tm@modal/sub-task/z-add-time-task-modal.vue'
export default {
components: {
ZCompleteTaskModal,
ZDeleteTaskModal,
ZSubTaskModal,
ZAddTimeTaskModal
ZAddTimeTaskModal,
ZSubTaskModal
},
props: {
@@ -231,7 +230,19 @@ export default {
deleteTask(id) {
this.$emit('deleteTask', id)
}
},
// completeTask(id) {
// this.$emit('completeTask', id)
// },
// editTask(id) {
// this.$emit('edit-task', id)
// },
// deleteTask(id) {
// this.$emit('deleteTask', id)
// },
}
}
</script>
@@ -1,7 +1,9 @@
<template>
<div>
<A-project-filter :projects="projects" @filterChanged="onFilterChanged" />
<A-project-calendar :events="filteredEvents" :month="filterSettings.selectedMonth" />
<W-loadable :content="events" empty-message="Nepodarilo sa nacitat data!">
<A-project-filter :projects="projects" @filterChanged="onFilterChanged" />
<A-project-calendar :events="filteredEvents" :month="filterSettings.selectedMonth" />
</W-loadable>
</div>
</template>
+26 -3
View File
@@ -3,14 +3,22 @@
<A-task-filter :unscheduledTime="unscheduledTime" @dataChanged="getTimelineData" />
<W-loadable :content="timelineData" class="w-loadable" empty-message="Nepodarilo sa nacitat data!">
<Z-timeline :calData="timelineData" :calConfig="config" :splits="splitDays" @eventMoved="onEventMoved" @completeTask="completeTask" @deleteTask="deleteTask" />
<Z-timeline :calData="timelineData" :calConfig="config" :splits="splitDays"
@eventMoved="onEventMoved" @completeTask="completeTask" @deleteTask="deleteTask" />
<!-- <Z-complete-task-modal ref="z-complete-task-modal" />
<Z-delete-task-modal ref="z-delete-task-modal" />
<Z-sub-task-modal ref="z-sub-task-modal" /> -->
</W-loadable>
</div>
</template>
<script>
import ATaskFilter from './_components/a-tasks-filter.vue'
import ZTimeline from '@/plugins/tm@dashboard/_components/z-timeline.vue'
import ATaskFilter from './_components/a-tasks-filter.vue'
import ZTimeline from '@/plugins/tm@dashboard/_components/z-timeline.vue'
// import ZCompleteTaskModal from '@/plugins/tm@modal/task/z-complete-task-modal.vue'
// import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue'
// import ZSubTaskModal from '@/plugins/tm@modal/sub-task/z-sub-task-modal.vue'
import { addDays, setHours, setMinutes, setSeconds, differenceInCalendarDays } from 'date-fns'
@@ -18,6 +26,9 @@ export default {
components: {
ATaskFilter,
ZTimeline,
// ZDeleteTaskModal,
// ZCompleteTaskModal,
// ZSubTaskModal
},
data() {
@@ -154,6 +165,18 @@ export default {
deleteTask(id) {
this.timelineData.tasks.splice(this.timelineData.tasks.findIndex(item => item.id === id), 1)
}
// editTask(subTask, editMode) {
// this.$refs['z-sub-task-modal'].create(subTask, editMode)
// },
// deleteTask(id) {
// const task = this.timelineData.find(task => task.id == id)
// this.$refs['z-delete-task-modal'].delete(task)
// // TODO: Remove after BE integration
// this.timelineData.tasks.splice(this.timelineData.tasks.findIndex(item => item.id === id), 1)
// }
}
}
</script>
@@ -105,15 +105,16 @@
<v-icon class="mx-1" icon="mdi-plus" />Pridať zamestnanca
</v-btn>
<v-textarea
:class="{ error: v$.masterTask.description.$errors.length }"
label="Popis"
class="modal-input"
variant="solo"
v-model="masterTask.description"
></v-textarea>
<div class="w-100 modal-input">
<QuillEditor
v-model="masterTask.description"
placeholder="Popis"
theme="snow"
class="rich-text-editor"
/>
</div>
<Z-files-upload @files-uploaded="filesUploaded"/>
<Z-files-upload class="mt-15 files" @files-uploaded="filesUploaded"/>
</v-card-actions>
<v-btn class="z-btn" @click="save()">VYTVORIŤ</v-btn>
@@ -256,12 +257,12 @@
</v-row>
<div class="px-5 py-5 border-bottom">
<p>Popis zadania</p>
<section class="description-detail px-2 py-2 w-100 rounded mt-2">{{ masterTask.description }}</section>
<section v-html="masterTask.description" class="description-detail px-2 py-2 w-100 rounded mt-2" />
<p class="mt-5">Prílohy</p>
<div class="w-100 d-flex align-center">
<div v-for="(file, index) in masterTask.files" :key="file.id" class="d-flex align-center flex-wrap" :class="[index === 0 ? 'ml-0': 'ml-2']">
<v-chip class="mt-2">
{{ file.name }}
<p @click="downloadFile" class="cursor-pointer">{{ file.name }}</p>
<v-icon class="mx-1" icon="mdi-paperclip"></v-icon>
</v-chip>
</div>
@@ -308,6 +309,9 @@ import { required } from '@vuelidate/validators'
import errorUtils from '@/plugins/lib@auth/_utils/error.utils'
import ZAutocomplete from '@/plugins/tm@_components/z-autocomplete.vue'
import moment from 'moment'
import { QuillEditor } from '@vueup/vue-quill'
import * as FileSaver from 'file-saver'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
const atLeastOne = (value) => value.length
@@ -317,7 +321,8 @@ export default {
components: {
Datepicker,
ZFilesUpload,
ZAutocomplete
ZAutocomplete,
QuillEditor
},
data() {
@@ -342,7 +347,6 @@ export default {
name: { required },
team: { required },
deadline: { required },
description: { required },
employees: { atLeastOne }
},
}
@@ -360,6 +364,17 @@ export default {
},
methods: {
// async downloadFile() {
// try {
// const file = await this.$axios.get_auth(`v1/files/${this.file.basename}`, { responseType: 'arraybuffer' })
// const blob = new Blob([file], { type: this.file.mimetype })
// FileSaver.saveAs(blob, this.file.name)
// this.isLoading = false
// } catch(error) {
// this.$toast.error(error)
// }
// },
async create(masterTaskId = null, editMode = false) {
this.visible = true
this.masterTask = null
@@ -393,6 +408,7 @@ export default {
try {
if (this.masterTask.id)
await this._update()
else
await this._create()
@@ -593,4 +609,8 @@ v-table, tbody
td:not(:last-child)
border-right: thin solid rgba(var(--v-border-color), var(--v-border-opacity))
@media screen and (max-width: 522px)
.files
margin-top: 104px !important
</style>
@@ -69,20 +69,16 @@
append-inner-icon="mdi-clock-outline"
></v-text-field>
<v-textarea
v-model="task.description"
label="Popis"
class="modal-input"
variant="solo"
:class="{ error: v$.task.description.$errors.length }"
:hint="
v$.task.description.$errors
? errorUtils.parseErrors(v$.task.description.$errors)
: null
"
></v-textarea>
<div class="w-100 modal-input">
<QuillEditor
v-model="task.description"
placeholder="Popis"
theme="snow"
class="rich-text-editor"
/>
</div>
<Z-files-upload @files-uploaded="filesUploaded" />
<Z-files-upload class="mt-15 files" @files-uploaded="filesUploaded" />
</v-card-actions>
<v-btn class="z-btn" @click="save()">{{
@@ -115,7 +111,7 @@
class="trash-icon"
:src="require('@/plugins/tm@overview/_img/trash-icon.svg')"
alt="trash-icon"
@click.stop="deleteTask()"
@click.stop="deleteTask(task)"
/>
</div>
</div>
@@ -203,27 +199,11 @@
</v-sheet>
</v-col>
<v-col cols="7">
<v-sheet class="ma-2 d-flex flex-wrap">
<div
class="d-flex align-center mb-2 me-2"
v-for="(employee, index) in task.employees"
:key="employee.id"
>
<p
class="employee-selected-avatar d-flex justify-center align-center"
>
{{
employee.name.charAt(0) +
employee.surname.charAt(0)
}}
</p>
<p
class="ml-2"
v-html="
`${task.employees[index].name} ${task.employees[index].surname}`
"
/>
</div>
<v-sheet class="ma-2 d-flex align-center">
<p class="employee-selected-avatar d-flex justify-center align-center">
{{ task.assigned_employee.name.charAt(0) + task.assigned_employee.surname.charAt(0)}}
</p>
<p class="ml-2" v-html="`${task.assigned_employee.name} ${task.assigned_employee.surname}`" />
</v-sheet>
</v-col>
</v-row>
@@ -241,7 +221,7 @@
</v-col>
<v-col cols="7">
<v-sheet class="ma-2">
<p>{{ (task.duration / 60 / 60).toFixed(2) }} h</p>
<p>{{ task.duration }} h</p>
</v-sheet>
</v-col>
</v-row>
@@ -260,7 +240,7 @@
<v-col cols="7">
<v-sheet class="ma-2">
<v-text-field
v-model="task.spent_time"
v-model="task.worked_time"
class="modal-input"
variant="solo"
type="number"
@@ -283,17 +263,13 @@
</v-col>
<v-col cols="7">
<v-sheet class="ma-2">
<p>{{ remaining_time }} h</p>
<p>{{ task.duration - task.worked_time }} h</p>
</v-sheet>
</v-col>
</v-row>
<div class="px-5 py-5 border-bottom">
<p>Popis zadania</p>
<section
class="description-detail px-2 py-2 w-100 rounded mt-2"
>
{{ task.description }}
</section>
<section v-html="task.description" class="description-detail px-2 py-2 w-100 rounded mt-2"/>
<p class="mt-5">Prílohy</p>
<div class="w-100 d-flex align-center">
<div
@@ -303,7 +279,7 @@
:class="[index === 0 ? 'ml-0' : 'ml-2']"
>
<v-chip class="mt-2">
{{ file.name }}
<p @click="downloadFile" class="cursor-pointer" >{{ file.name }}</p>
<v-icon
class="mx-1"
icon="mdi-paperclip"
@@ -313,32 +289,39 @@
</div>
</div>
<div class="d-flex justify-start align-center mt-8">
<v-btn class="done-btn">Dokončené</v-btn>
<v-btn class="done-btn" @click.stop="clickCompleteTask()">Dokončené</v-btn>
<v-btn class="add-employee-btn" @click="save()"
>Uložiť zmeny</v-btn
>
</div>
</div>
</v-card-actions>
<Z-delete-task-modal ref="z-delete-task-modal" @deleted="onTaskDeleted" />
</v-card>
</W-loadable>
</v-dialog>
</template>
<script>
import Datepicker from '@vuepic/vue-datepicker';
import ZFilesUpload from '@/plugins/tm@_components/z-files-upload.vue';
import useVuelidate from '@vuelidate/core';
import { required } from '@vuelidate/validators';
import errorUtils from '@/plugins/lib@auth/_utils/error.utils';
import moment from 'moment';
import Datepicker from '@vuepic/vue-datepicker'
import ZFilesUpload from '@/plugins/tm@_components/z-files-upload.vue'
import useVuelidate from '@vuelidate/core'
import { required } from '@vuelidate/validators'
import errorUtils from '@/plugins/lib@auth/_utils/error.utils'
import moment from 'moment'
import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue'
import { QuillEditor } from '@vueup/vue-quill'
import * as FileSaver from 'file-saver'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
export default {
emits: ['close'],
emits: ['close', 'refresh'],
components: {
Datepicker,
ZFilesUpload,
QuillEditor,
ZDeleteTaskModal
},
data() {
@@ -354,7 +337,7 @@ export default {
showAddEmployeeInput: false,
masterTasks: null,
selectedEmployee: null,
};
}
},
validations() {
@@ -364,29 +347,39 @@ export default {
date: { required },
team: { required },
duration: { required },
description: { required },
employee: { required },
},
};
}
},
async created() {
try {
this.masterTasks = await this.$axios.get_auth_data('v1/master-tasks');
this.employees = await this.$axios.get_auth_data('v1/employees');
this.masterTasks = await this.$axios.get_auth_data('v1/master-tasks')
this.employees = await this.$axios.get_auth_data('v1/employees')
} catch (error) {
this.$toast.error(error);
this.$toast.error(error)
}
},
methods: {
// async downloadFile() {
// try {
// const file = await this.$axios.get_auth(`v1/files/${this.file.basename}`, { responseType: 'arraybuffer' })
// const blob = new Blob([file], { type: this.file.mimetype })
// FileSaver.saveAs(blob, this.file.name)
// this.isLoading = false
// } catch(error) {
// this.$toast.error(error)
// }
// },
async create(taskId = null, editMode = false) {
this.visible = true;
this.task = null;
this.visible = true
this.task = null
if (taskId) {
await this._load(taskId);
this.editMode = editMode || !this.task?.id;
await this._load(taskId)
this.editMode = editMode || !this.task?.id
} else {
const task = {
project_code: null,
@@ -396,89 +389,101 @@ export default {
duration: null,
description: null,
files: [],
};
}
setTimeout(() => {
this.task = task;
this.editMode = editMode || !this.task.id;
});
this.task = task
this.editMode = editMode || !this.task.id
})
}
},
async clickCompleteTask() {
try {
await this.$axios.delete(`v1/tasks/${this.task.id}`)
this.close()
} catch (error) {
this.$toast.error(error)
}
this.close()
},
async save() {
if (!(await this.v$.$validate())) return;
if (!(await this.v$.$validate())) return
try {
if (this.task.id) await this._update();
else await this._create();
this.close();
this.$router.push({ name: 'Dashboard - Tasks' });
if (this.task.id) {
await this._update()
this.close()
}
else await this._create()
this.close()
this.$router.push({ name: 'Dashboard - Tasks' })
} catch (error) {
this.$toast.error(error);
this.$toast.error(error)
}
},
close() {
this.visible = false;
this.$emit('close', this.task);
this.visible = false
this.$emit('close', this.task)
},
async _load(taskId) {
try {
this.task = await this.$axios.get_auth_data(`v1/tasks/${taskId}`);
this.task = await this.$axios.get_auth_data(`v1/tasks/${taskId}`)
} catch (error) {
this.$toast.error(error);
this.$toast.error(error)
}
},
async _create() {
try {
await this.$axios.post_auth('v1/master-tasks');
await this.$axios.post_auth('v1/master-tasks')
} catch (error) {
this.$toast.error(error);
this.$toast.error(error)
}
},
async _update() {
try {
await this.$axios.post_auth(`v1/master-tasks/${this.task.id}`);
await this.$axios.post_auth(`v1/master-tasks/${this.task.id}`)
} catch (error) {
this.$toast.error(error);
this.$toast.error(error)
}
},
async deleteTask(taskId) {
try {
await this.$axios.delete(`v1/tasks/${taskId}`);
this.close();
} catch (error) {
this.$toast.error(error);
}
deleteTask(task) {
this.$refs['z-delete-task-modal'].delete(task)
},
onTaskDeleted() {
this.$emit('refresh')
},
employeeSelected(selectedOption) {
const employee = this.employees.find((empl) => empl.id == selectedOption.key);
this.task.employees.push(employee);
this.showAddEmployeeInput = false;
const employee = this.employees.find((empl) => empl.id == selectedOption.key)
this.task.employees.push(employee)
this.showAddEmployeeInput = false
},
// Vuetify input was automatically focus after date input was clicked. This will prevent this unwanted behavior
onDateFocus($event) {
if ($event == undefined) {
this.preventInputFocus = true;
this.preventInputFocus = true
}
},
onInputFocus($event) {
if (this.preventInputFocus) {
$event.target.blur();
this.preventInputFocus = false;
$event.target.blur()
this.preventInputFocus = false
}
},
filesUploaded(files) {
this.task.files = files;
this.task.files = files
},
},
@@ -486,30 +491,30 @@ export default {
employeesOptions() {
const selectedEmployeesIds = this.task.employees.map(
(employee) => employee.id
);
)
const employees =
this.employees.filter(
(employee) => !selectedEmployeesIds.includes(employee.id)
) || [];
) || []
return employees.map((employee) => {
return {
key: employee.id,
value: `${employee.name} ${employee.surname}`,
};
});
}
})
},
formattedStartDate() {
let startDate = moment(this.task.starts_at);
let date = startDate.format('DD.MM.yyyy, HH:mm');
return date;
let startDate = moment(this.task.starts_at)
let date = startDate.format('DD.MM.yyyy, HH:mm')
return date
},
formattedEndDate() {
let endDate = moment(this.task.ends_at);
let date = endDate.format('DD.MM.yyyy, HH:mm');
return date;
let endDate = moment(this.task.ends_at)
let date = endDate.format('DD.MM.yyyy, HH:mm')
return date
},
},
@@ -517,26 +522,26 @@ export default {
selectedMasterTask() {
this.task.team = this.masterTasks.find(
(masterTask) => masterTask.id == this.selectedMasterTask
);
)
console.log(this.task.team.employees)
this.task.team.employees.forEach(
(employee) => {
employee._fullName = `${employee.name} ${employee.surname}`
});
})
console.log(this.task.team.employees)
this.task.employee = null;
this.task.employee = null
this.task.project_code = this.masterTasks.filter(
(x) => x.id == this.selectedMasterTask
)[0].project_code;
)[0].project_code
},
selectedEmployee() {
this.task.employee = this.task.team.employees.find(
(employee) => employee.id == this.selectedEmployee
);
)
},
},
};
}
</script>
<style lang="sass" scoped>
@@ -602,4 +607,8 @@ export default {
color: #fff !important
height: 50px
width: 203px
@media screen and (max-width: 522px)
.files
margin-top: 104px !important
</style>
@@ -1,18 +1,18 @@
<template>
<v-dialog v-model="show" max-width="650">
<v-dialog v-model="visible" max-width="650">
<v-card>
<div class="d-flex justify-space-between align-center">
<h1>Ste si istý, že chcete zmazať <b>{{ task.title }}</b>?</h1>
<v-icon
@click.stop="show = false"
@click.stop="visible = false"
icon="mdi-close"
size="large"
></v-icon>
</div>
<v-card-actions class="mt-10 d-flex justify-start align-center">
<v-btn class="z-btn" variant="flat" @click="deleteTask()">ÁNO</v-btn>
<v-btn class="ml-7 cancel-btn" @click.stop="show = false">ZRUŠIŤ</v-btn>
<v-btn class="ml-7 cancel-btn" @click.stop="visible = false">ZRUŠIŤ</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
@@ -20,42 +20,30 @@
<script>
export default {
emits: ['close'],
emits: ['deleted'],
props: {
visible: {
type: Boolean,
required: true
},
task: {
type: Object,
required: true
data() {
return {
visible: false,
task: null
}
},
methods: {
async delete(task) {
this.task = task
this.visible = true
},
async deleteTask() {
try {
await this.$axios.delete(`v1/tasks/${this.task.id}`)
this.show = false
this.$emit('deleteTask', this.task.id)
this.visible = false
this.$emit('deleted', this.task)
} catch (error) {
this.$toast.error(error)
}
}
},
computed: {
show: {
get() {
return this.visible
},
set(value) {
if (!value) this.$emit('close')
}
},
}
}
</script>
@@ -3,8 +3,7 @@
<v-card>
<div class="d-flex justify-space-between align-center">
<h1>
Ste si istý, že chcete zmazať tím <b>{{ team.name }}</b
>?
Ste si istý, že chcete zmazať tím <b>{{ team.name }}</b>?
</h1>
<v-icon @click.stop="visible = false" icon="mdi-close" size="large"></v-icon>
</div>
@@ -25,7 +24,7 @@ export default {
return {
visible: false,
team: null,
};
}
},
methods: {
@@ -37,13 +36,12 @@ export default {
async deleteTeam() {
try {
await this.$axios.delete(`v1/teams/${this.team.id}`)
this.visible = false
this.$emit('deleted', this.team)
} catch (error) {
this.$toast.error(error)
}
},
},
};
}
}
}
</script>
@@ -11,31 +11,35 @@
</thead>
<tbody>
<tr v-for="task in tasks" :key="task.id">
<tr class="cursor-pointer" v-for="task in tasks" :key="task.id" @click.stop="editTask(task, false)">
<td>{{ task.project_code }}</td>
<td>{{ task.title }}</td>
<td>{{ task.duration / 1000 / 60 / 60 }} h</td>
<td>{{ (task.remaining_time / 1000 / 60 / 60).toFixed(2) }} h</td>
<td class="task-action">
<div class="d-flex justify-start">
<img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" :style="{opacity: 0.3}"/>
<img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="showDeleteModal = { task }" />
<!-- Kravarik: Aj tento modal prerob novym sposobom -->
<Z-delete-task-modal v-if="showDeleteModal" :visible="showDeleteModal ? true : false" :task="showDeleteModal.task" @close="showDeleteModal = null" />
<img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" @click.stop="editTask(task, true)" />
<img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="deleteTask(task)" />
</div>
</td>
</tr>
</tbody>
<Z-sub-task-modal ref="z-sub-task-modal" />
<Z-delete-task-modal ref="z-delete-task-modal" @deleted="onTaskDeleted" />
</v-table>
</template>
<script>
import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue'
import ZSubTaskModal from '@/plugins/tm@modal/sub-task/z-sub-task-modal.vue'
export default {
emits: ['refresh'],
components: {
ZDeleteTaskModal
ZDeleteTaskModal,
ZSubTaskModal
},
props: {
@@ -45,9 +49,17 @@ export default {
}
},
data() {
return {
showDeleteModal: null
methods: {
deleteTask(task) {
this.$refs['z-delete-task-modal'].delete(task)
},
onTaskDeleted() {
this.$emit('refresh')
},
editTask(task, editMode) {
this.$refs['z-sub-task-modal'].create(task, editMode)
}
}
}
@@ -67,4 +79,8 @@ v-table, th, td
border-radius: 50%
margin: 6px
padding: 6px
tbody
tr:hover
background: rgba(0,0,0,.1)
</style>
@@ -10,30 +10,34 @@
</thead>
<tbody>
<tr v-for="task in tasks" :key="task.id">
<tr class="cursor-pointer" v-for="task in tasks" :key="task.id" @click.stop="editTask(task, false)">
<td>{{ task.project_code }}</td>
<td>{{ task.title }}</td>
<td>{{ (task.duration / 1000 / 60 / 60).toFixed(2) }} h</td>
<td class="task-action">
<div class="d-flex justify-start">
<img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" :style="{opacity: 0.3}">
<img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="showDeleteModal = { task }">
<!-- Kravarik: Aj tento modal prerob novym sposobom -->
<Z-delete-task-modal v-if="showDeleteModal" :visible="showDeleteModal ? true : false" :task="showDeleteModal.task" @close="showDeleteModal = null" />
<img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" @click.stop="editTask(task, true)">
<img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="deleteTask(task)">
</div>
</td>
</tr>
</tbody>
<Z-sub-task-modal ref="z-sub-task-modal" />
<Z-delete-task-modal ref="z-delete-task-modal" @deleted="onTaskDeleted"/>
</v-table>
</template>
<script>
import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue'
import ZSubTaskModal from '@/plugins/tm@modal/sub-task/z-sub-task-modal.vue'
export default {
emits: ['refresh'],
components: {
ZDeleteTaskModal
ZDeleteTaskModal,
ZSubTaskModal
},
props: {
@@ -43,9 +47,17 @@ export default {
}
},
data() {
return {
showDeleteModal: null
methods: {
deleteTask(task) {
this.$refs['z-delete-task-modal'].delete(task)
},
onTaskDeleted() {
this.$emit('refresh')
},
editTask(task, editMode) {
this.$refs['z-sub-task-modal'].create(task, editMode)
}
}
}
@@ -65,4 +77,8 @@ v-table, th, td
border-radius: 50%
margin: 6px
padding: 6px
tbody
tr:hover
background: rgba(0,0,0,.1)
</style>
@@ -22,7 +22,7 @@
</v-table>
<Z-team-modal ref="z-team-modal" />
<Z-delete-team-modal ref="z-delete-team-modal" @deleted="onTeamDeleted" />
<Z-delete-team-modal ref="z-delete-team-modal" @deleted="onTeamDeleted" />
</div>
</template>
@@ -45,12 +45,6 @@ export default {
}
},
data() {
return {
deleteModal: null
}
},
methods: {
editTeam(team) {
this.$refs['z-team-modal'].create(team.id)