mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 22:39:34 +00:00
[tm@store] Added store
This commit is contained in:
1 parent
a1a410c54d
commit
774ca7b607
44 files changed
+989
-720
No files matched your search
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<v-row no-gutters class="align-center">
|
||||
<v-col cols="5">
|
||||
<v-sheet class="py-3">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon icon="mdi-link" size="large"></v-icon>
|
||||
<p class="mx-3">Mastertask</p>
|
||||
</div>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
<v-col cols="7">
|
||||
<v-sheet class="py-3">
|
||||
<p class="task-badge px-4 py-2 rounded-pill">
|
||||
{{ name }}
|
||||
</p>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<v-row no-gutters class="align-center">
|
||||
<v-col cols="5">
|
||||
<v-sheet class="py-3">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon icon="mdi-drag-vertical" size="large"></v-icon>
|
||||
<p class="mx-3">Status</p>
|
||||
</div>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
<v-col cols="7">
|
||||
<v-sheet class="py-3">
|
||||
<p v-if="isFinished" class="status-badge px-4 py-2 rounded-pill">Ukončený</p>
|
||||
<p v-else class="status-badge px-4 py-2 rounded-pill">Neukončený</p>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
isFinished: {
|
||||
type: Number,
|
||||
default: () => 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<v-row no-gutters class="align-center">
|
||||
<v-col cols="5">
|
||||
<v-sheet class="py-3">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon icon="mdi-account-outline" size="large"></v-icon>
|
||||
<p class="mx-3">Priradený</p>
|
||||
</div>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="7">
|
||||
<v-sheet class="py-3 d-flex align-center">
|
||||
<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="`${employee.name} ${employee.surname}`" />
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
employee: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div class="px-5 py-5 border-bottom">
|
||||
<p>Popis zadania</p>
|
||||
<section v-html="description" class="description-detail px-2 py-2 w-100 rounded mt-2" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
description: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<v-row no-gutters class="align-center">
|
||||
<v-col cols="5">
|
||||
<v-sheet class="py-3">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon icon="mdi-clock-time-three-outline" size="large"></v-icon>
|
||||
<p class="mx-3">Naplánovaný čas</p>
|
||||
</div>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
<v-col cols="7">
|
||||
<v-sheet class="py-3">
|
||||
<p>{{ hours }} h</p>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
hours: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<v-row no-gutters class="align-center border-bottom">
|
||||
<v-col cols="5">
|
||||
<v-sheet class="py-3">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon icon="mdi-clock-time-three-outline" size="large"></v-icon>
|
||||
<p class="mx-3">Zostávajúci čas</p>
|
||||
</div>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="7">
|
||||
<v-sheet class="py-3">
|
||||
<p>{{ hours }} h</p>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
hours: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<v-row no-gutters>
|
||||
<v-col cols="5">
|
||||
<v-sheet class="py-3">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon icon="mdi-clock-time-three-outline" size="large"></v-icon>
|
||||
<p class="mx-3">Odpracovaný čas</p>
|
||||
</div>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="7">
|
||||
<v-sheet class="py-3">
|
||||
<p>{{ hours }} h</p>
|
||||
</v-sheet>
|
||||
|
||||
<v-sheet class="py-3">
|
||||
<div class="d-flex align-center mb-3">
|
||||
<v-icon @click="showModal = true" class="add-date cursor-pointer mr-2" icon="mdi-plus" size="medium" />
|
||||
<p class="task-badge rounded-pill">Pridať záznam</p>
|
||||
</div>
|
||||
|
||||
<template v-if="task.timesheets.length">
|
||||
<div v-for="timesheet in task.timesheets" :key="timesheet.id" class="d-flex align-center mb-3">
|
||||
<v-icon @click.stop="deleteTimesheet(timesheet)" class="remove-date cursor-pointer mr-2" icon="mdi-minus" size="medium" />
|
||||
<p class="task-badge rounded-pill">{{ timesheet.time }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-dialog max-width="750" v-model="showModal">
|
||||
<v-card>
|
||||
<div class="d-flex justify-space-between align-center">
|
||||
<h1>Pridať odpracovaný čas</h1>
|
||||
|
||||
<v-icon @click.stop="closeModal()" icon="mdi-close" size="large"></v-icon>
|
||||
</div>
|
||||
<v-card-actions class="mt-10 d-flex justify-start align-center">
|
||||
<v-text-field v-model="form.hours" variant="solo" bg-color="white" type="number" :hint="v$.form.hours.$errors ? errorUtils.parseErrors(v$.form.hours.$errors) : null" :class="{ error: v$.form.hours.$errors.length }" class="mb-2" label="Odpracovaný čas" />
|
||||
</v-card-actions>
|
||||
<v-btn @click="submit()" class="button primary mt-5">Potvrdiť</v-btn>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import errorUtils from '@/plugins/lib@auth/_utils/error.utils'
|
||||
import useVuelidate from '@vuelidate/core'
|
||||
import { required, numeric, minValue } from '@vuelidate/validators'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
hours: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
|
||||
task: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useVuelidate(),
|
||||
errorUtils,
|
||||
showModal: false,
|
||||
form: {
|
||||
hours: null
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
validations() {
|
||||
return {
|
||||
form: {
|
||||
hours: {required, numeric, minValue: minValue(1)}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
async submit() {
|
||||
if (!await this.v$.$validate())
|
||||
return
|
||||
|
||||
const task = JSON.parse(JSON.stringify(this.task))
|
||||
|
||||
task.timesheets.push({
|
||||
id: null,
|
||||
employee_id: task.employee_id,
|
||||
time: typeof this.form.hours == 'string' ? parseInt(this.form.hours) : this.form.hours
|
||||
})
|
||||
|
||||
this._update(task)
|
||||
},
|
||||
|
||||
async deleteTimesheet({ id }) {
|
||||
const task = JSON.parse(JSON.stringify(this.task))
|
||||
task.timesheets = task.timesheets.filter(timesheet => timesheet.id != id)
|
||||
|
||||
this._update(task)
|
||||
},
|
||||
|
||||
closeModal() {
|
||||
this.form = {
|
||||
hours: null
|
||||
}
|
||||
|
||||
this.showModal = false
|
||||
this.$nextTick(() => this.v$.$reset())
|
||||
},
|
||||
|
||||
async _update(task) {
|
||||
try {
|
||||
const { subtask } = await this.$axios.put_auth(`v1/subtasks/${task.id}`, task)
|
||||
|
||||
this.closeModal()
|
||||
this.$events.emit('on-task-edited', subtask)
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message || error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<v-row no-gutters>
|
||||
<v-col cols="5">
|
||||
<v-sheet class="py-3">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon icon="mdi-calendar-week" size="large"></v-icon>
|
||||
<p class="mx-3">Trvanie</p>
|
||||
</div>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="7">
|
||||
<v-sheet class="py-3">
|
||||
<div class="d-flex align-center mb-3">
|
||||
<v-icon @click="showModal = true" class="add-date cursor-pointer mr-2" icon="mdi-plus" size="medium" />
|
||||
<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="remove-date cursor-pointer mr-2" icon="mdi-minus" size="medium" />
|
||||
<p class="task-badge rounded-pill">{{ tmUtils.formatDateTime(timeblock.start) }} - {{ tmUtils.formatDateTime(timeblock.end) }}</p>
|
||||
</div>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-dialog max-width="750" v-model="showModal">
|
||||
<v-card>
|
||||
<div class="d-flex justify-space-between align-center">
|
||||
<h1>Pridať dátum</h1>
|
||||
<v-icon @click.stop="clsoeModal()" icon="mdi-close" size="large"></v-icon>
|
||||
</div>
|
||||
|
||||
<v-card-actions class="mt-10 d-flex flex-column modal-content">
|
||||
<Datepicker v-model="form.date" format="dd.MM.yyyy" locale="sk" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Dátum" :enable-time-picker="false" class="mb-5 modal-input" />
|
||||
<v-text-field v-model="form.starts_at_time" type="time" variant="solo" bg-color="white" :hint="v$.form.starts_at_time.$errors ? errorUtils.parseErrors(v$.form.starts_at_time.$errors) : null" :class="{ error: v$.form.starts_at_time.$errors.length }" class="mb-1 modal-input" label="Začiatok" />
|
||||
<v-text-field v-model="form.ends_at_time" type="time" variant="solo" bg-color="white" :hint="v$.form.ends_at_time.$errors ? errorUtils.parseErrors(v$.form.ends_at_time.$errors) : null" :class="{ error: v$.form.ends_at_time.$errors.length }" class="modal-input" label="Koniec" />
|
||||
</v-card-actions>
|
||||
|
||||
<v-btn @click="submit()" class="button primary mt-5">Potvrdiť</v-btn>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import tmUtils from '@/plugins/tm@_utils/tm.utils'
|
||||
import errorUtils from '@/plugins/lib@auth/_utils/error.utils'
|
||||
import useVuelidate from '@vuelidate/core'
|
||||
import { required } from '@vuelidate/validators'
|
||||
import Datepicker from '@vuepic/vue-datepicker'
|
||||
import moment from 'moment'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Datepicker
|
||||
},
|
||||
|
||||
props: {
|
||||
timeblocks: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
|
||||
task: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useVuelidate(),
|
||||
errorUtils,
|
||||
tmUtils,
|
||||
showModal: false,
|
||||
form: {
|
||||
date: null,
|
||||
starts_at_time: '09:00',
|
||||
ends_at_time: '16:00'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
validations() {
|
||||
return {
|
||||
form: {
|
||||
date: { required },
|
||||
starts_at_time: { required },
|
||||
ends_at_time: { required }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
async submit() {
|
||||
if (!await this.v$.$validate())
|
||||
return
|
||||
|
||||
const task = JSON.parse(JSON.stringify(this.task))
|
||||
|
||||
const splittedStartsAtTime = this.form.starts_at_time.split(':')
|
||||
const splittedEndsAtTime = this.form.ends_at_time.split(':')
|
||||
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()
|
||||
|
||||
task.timeblocks.push({
|
||||
id: null,
|
||||
start: tmUtils.formatDateTimeForBackend(start),
|
||||
end: tmUtils.formatDateTimeForBackend(end)
|
||||
})
|
||||
|
||||
this._update(task)
|
||||
},
|
||||
|
||||
async deleteTimeblock({ id }) {
|
||||
const task = JSON.parse(JSON.stringify(this.task))
|
||||
task.timeblocks = task.timeblocks.filter(timeblock => timeblock.id != id)
|
||||
console.log(task.timeblocks)
|
||||
console.log(id)
|
||||
|
||||
this._update(task)
|
||||
},
|
||||
|
||||
async _update(task) {
|
||||
try {
|
||||
const { subtask } = await this.$axios.put_auth(`v1/subtasks/${task.id}`, task)
|
||||
|
||||
this.closeModal()
|
||||
this.$events.emit('on-task-edited', subtask)
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message || error)
|
||||
}
|
||||
},
|
||||
|
||||
closeModal() {
|
||||
this.form = {
|
||||
date: null,
|
||||
starts_at_time: '09:00',
|
||||
ends_at_time: '16:00'
|
||||
}
|
||||
|
||||
this.showModal = false
|
||||
this.$nextTick(() => this.v$.$reset())
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<A-mastertask-name :name="task.master_task.name" />
|
||||
<A-mastertask-status :status="task.is_finished" />
|
||||
<A-task-timeblocks :timeblocks="task.timeblocks" :task="task" />
|
||||
<A-task-assigned-employee :employee="task.employee" />
|
||||
<A-task-planned-time :hours="task.duration" />
|
||||
<A-task-remaining-time :hours="task.duration - task.spent_time" />
|
||||
<A-task-spent-time :hours="task.spent_time" :task="task" />
|
||||
<A-task-description :description="task.description" />
|
||||
<Z-files :files="task.files" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AMastertaskName from './_components/a-mastertask-name.vue'
|
||||
import AMastertaskStatus from './_components/a-mastertask-status.vue'
|
||||
import ATaskTimeblocks from './_components/a-task-timeblocks.vue'
|
||||
import ATaskAssignedEmployee from './_components/a-task-assigned-employee.vue'
|
||||
import ATaskPlannedTime from './_components/a-task-planned-time.vue'
|
||||
import ATaskSpentTime from './_components/a-task-spent-time.vue'
|
||||
import ATaskRemainingTime from './_components/a-task-remaining-time.vue'
|
||||
import ATaskDescription from './_components/a-task-description.vue'
|
||||
import ZFiles from '@/plugins/tm@modal/_components/z-files.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ZFiles,
|
||||
AMastertaskName,
|
||||
AMastertaskStatus,
|
||||
ATaskTimeblocks,
|
||||
ATaskAssignedEmployee,
|
||||
ATaskPlannedTime,
|
||||
ATaskSpentTime,
|
||||
ATaskRemainingTime,
|
||||
ATaskDescription
|
||||
},
|
||||
|
||||
props: {
|
||||
task: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in new issue
Block a user