[Projects overview] Added filter logics and prepared for BE

This commit is contained in:
Matej Glasnák committed 2023-01-27 00:48:39 +01:00
1 parent d7b26d731a
commit 4cd1504343
12 files changed
+1688 -198

No files matched your search

+1 -1
View File
@@ -48,7 +48,7 @@ const options: Options = {
'POST v1/auth/post': true,
'GET v1/master-tasks/(id)': true,
// 'GET v1/master-tasks': true,
'GET v1/master-tasks': true,
'POST v1/master-tasks/(id)': true,
'DELETE v1/master-tasks/(id)': true,
'POST v1/master-tasks': true,
@@ -179,9 +179,9 @@ export default {
taskClicked(task) {
if (task.nonWorking) return
console.log("task", task)
// console.log("task", task)
if (task.end.getTime() - task.start.getTime() <= 3600000) {
console.log("ShortTask")
// console.log("ShortTask")
}
},
@@ -1,18 +1,17 @@
<template>
<div id="calendar" class="mb-12">
<V-full-calendar ref="fullCalendar" :options="calendarOptions" />
<!-- <Z-master-task-modal ref="z-master-task-modal" /> -->
</div>
</template>
<script>
import VFullCalendar from '@fullcalendar/vue3'
import dayGridPlugin from '@fullcalendar/daygrid'
// import ZMasterTaskModal from '@/plugins/tm@modal/master-task/z-master-task-modal.vue'
export default {
emits: ['open-detail'],
components: {
VFullCalendar,
// ZMasterTaskModal
VFullCalendar
},
props: {
@@ -39,9 +38,7 @@ export default {
eventContent: (eventInfo) => {
return { html: eventInfo.event.extendedProps.title_html }
},
eventClick: (info) => {
return this.editTask(info.event._def.publicId, false)
}
eventClick: (info) => this.$emit('open-detail', info.event._def.publicId)
}
}
},
@@ -52,12 +49,6 @@ export default {
this.$refs.fullCalendar?.getApi().gotoDate(new Date(currentYear, this.month, 1))
},
methods: {
editTask(masterTask, editMode) {
this.$events.emit('show-master-task-modal', {masterTask, editMode})
},
},
watch: {
month(selectedMonth) {
const currentYear = new Date().getFullYear()
@@ -109,4 +100,6 @@ export default {
border: none
top: 2px
right: 4px
&:deep(.fc-daygrid-day-frame)
min-height: 100px
</style>
@@ -1,12 +1,12 @@
<template>
<v-row class="px-10 py-8 subheader">
<v-select v-model="filter.selectedProject" class="subheader-input" :items="projects" label="Projekt" variant="outlined"></v-select>
<v-select v-model="filter.selectedProject" class="subheader-input" :items="[null, projects]" label="Projekt" variant="outlined" :disabled="true" />
<v-select v-model="filter.selectedTeam" class="subheader-input" :items="teams" label="Tím" variant="outlined"></v-select>
<v-select v-model="filter.selectedTeam" class="subheader-input" :items="[null, ...teams]" label="Tím" variant="outlined" item-title="name" item-value="id" />
<v-select v-model="filter.selectedEmployee" class="subheader-input" :items="employees" label="Zamestnanec" variant="outlined"></v-select>
<v-select v-model="filter.selectedEmployee" class="subheader-input" :items="[null, ...enrichedEmployees]" label="Zamestnanec" variant="outlined" item-title="_fullName" item-value="id" />
<v-select v-model="filter.selectedMonth" class="subheader-input" :items="months" label="Mesiac" variant="outlined"></v-select>
<v-select v-model="filter.selectedMonth" class="subheader-input" :items="months" label="Mesiac" variant="outlined" />
<div class="subheader-input switch">
<p class="switch-label">Zobraziť ukončené</p>
@@ -19,7 +19,22 @@
export default {
emits: ['filterChanged'],
props: ['projects', 'teams', 'employees'],
props: {
projects: {
type: Array,
required: true
},
teams: {
type: Array,
required: true
},
employees: {
type: Array,
required: true
}
},
data() {
return {
@@ -37,6 +52,7 @@ export default {
{ title: 'November', value: 10 },
{ title: 'December', value: 11 }
],
filter: {
selectedProject: null,
selectedTeam: null,
@@ -47,6 +63,17 @@ export default {
}
},
computed: {
enrichedEmployees() {
const employees = this.employees
return employees.map(employee => {
employee._fullName = `${employee.name} ${employee.surname}`
return employee
})
}
},
watch: {
filter: {
handler() {
@@ -1,8 +1,8 @@
<template>
<div>
<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 :content="masterTasks" empty-message="Nepodarilo sa nacitat data!">
<A-project-filter :projects="projects" :teams="teams" :employees="employees" @filterChanged="onFilterChanged" />
<A-project-calendar :events="filteredEvents" :month="filter.selectedMonth" @open-detail="openMasterTaskModal" />
</W-loadable>
</div>
</template>
@@ -10,6 +10,7 @@
<script>
import AProjectCalendar from './_components/a-project-calendar.vue'
import AProjectFilter from './_components/a-project-filter.vue'
import moment from 'moment'
export default {
components: {
@@ -18,47 +19,96 @@ export default {
},
data() {
return {
filterSettings: {
selectedEmployee: null,
selectedMonth: new Date().getMonth(),
selectedProject: null,
selectedTeam: null,
showFinishedTasks: false
},
// Kravarik: Toto je preco hardcodenute?
projects: ['Projekt1', 'Projekt2', 'Projekt3', 'Projekt4'],
masterTasks: null,
teams: null,
employees: null,
selectedProject: null,
events: [],
filteredEvents: []
filter: {
selectedMonth: new Date().getMonth()
}
}
},
computed: {
filteredEvents() {
if (!this.masterTasks || this.masterTasks.error)
return []
// duplicate all tasks
let events = this.masterTasks
// show/hide finished tasks
if (!this.filter.showFinishedTasks)
events = events.filter(event => !event.is_finished)
// filter by team_id
if (this.filter.selectedTeam)
events = events.filter(event => event.team_id == this.filter.selectedTeam)
// filter by employee_id
if (this.filter.selectedEmployee)
events = events.filter(event => event.employees.find(employee => employee.id == this.filter.selectedEmployee))
// format masterTasks to event format for calendar
events = events.map(event => {
const color = this._stringToHexColor(`${event.project_code}${event.name}`)
return {
id: event.id,
title: `${event.project_code} - ${event.name}`,
title_html: `${event.project_code} - <b>${event.name}</b>`,
start: new Date(event.starts_at),
end: new Date(event.deadline),
is_finished: event.is_finished,
project_code: event.project_code,
backgroundColor: `${color}CC`,
borderColor: color
}
})
return events
}
},
created() {
this._getData()
},
methods: {
async _getData() {
try {
const events = await this.$axios.get_auth_data('v1/overview/projects')
this.events = events.map((item) => ({
id: item.id,
title: `${item.project_code} - ${item.name}`,
title_html: `${item.project_code} - <b>${item.name}</b>`,
start: item.starts_at,
end: item.deadline,
is_finished: item.is_finished,
project_code: item.project_code,
backgroundColor: item.color,
borderColor: item.color
}))
this.filteredEvents = this.events.filter((item) => !item.is_finished)
this.teams = await this.$axios.get_auth_data('v1/teams')
this.employees = await this.$axios.get_auth_data('v1/employees')
this.masterTasks = await this.$axios.get_auth_data('v1/master-tasks')
} catch (error) {
this.$toast.error(error)
this.masterTasks = {error}
}
},
onFilterChanged(filterValues) {
this.filter = filterValues
this.filteredEvents = this.events.filter((item) => this.filter.showFinishedTasks || item.is_finished == false)
},
openMasterTaskModal(masterTaskId) {
const masterTask = this.masterTasks.find(masterTask => masterTask.id == masterTaskId)
this.$events.emit('show-master-task-modal', {masterTask, editMode: false})
},
_stringToHexColor(string) {
let hash = 0;
for (let i = 0; i < string.length; i++) {
hash = string.charCodeAt(i) + ((hash << 5) - hash);
}
let color = '#';
for (let i = 0; i < 3; i++) {
let value = (hash >> (i * 8)) & 0xFF;
color += ('00' + value.toString(16)).substr(-2);
}
return color;
}
}
}
+2 -2
View File
@@ -125,7 +125,7 @@ export default {
},
async onEventMoved(event) {
console.log("drag", event)
// console.log("drag", event)
const task = this.timelineData.tasks.find(task => task.id == event.event.id)
try {
@@ -138,7 +138,7 @@ export default {
task.split = event.newSplit
} catch(error) {
this.$toast.error(error)
task.start = new Date(event.originalEvent.start)
task.end = new Date(event.originalEvent.end)
task.split = event.oldSplit
+2 -2
View File
@@ -56,7 +56,7 @@ export default {
this.timelineData[i].splitId = i + 1
this.splitDays.push({
id: i + 1,
employeeId: this.timelineData[i].id,
employeeId: this.timelineData[i].id,
firstName: this.timelineData[i].name,
name: this.timelineData[i].name + " " + this.timelineData[i].surname,
initials: this.timelineData[i].name.charAt(0).toUpperCase() + this.timelineData[i].surname.charAt(0).toUpperCase(),
@@ -121,7 +121,7 @@ export default {
},
async onEventMoved(event) {
console.log("drag", event)
// console.log("drag", event)
const task = this.timelineData.tasks.find(task => task.id == event.event.id)
const newEmployeeId = this.splitDays.find(split => split.id == event.newSplit).employeeId
-2
View File
@@ -18,8 +18,6 @@ export default {
state.user = data.user
localStorage.setItem('wzo_vue_user_user', JSON.stringify(data.user))
}
console.log(state)
},
auth_error(state: any) {
state.token = ''
@@ -42,11 +42,8 @@ export default {
watch: {
content(value) {
console.log(`XX: ${value}`)
if (value) {
this._stopLoading()
console.log(' STOP LOADING')
}
else
this._startLoading()