mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 14:29:34 +00:00
Merge branch 'main' of https://bitbucket.org/studiotem/jandl-taskmanager-app
This commit is contained in:
commit
de366a5db3
10 files changed
+442
-14058
No files matched your search
Generated
+188
-13875
File diff suppressed because it is too large.
Load diff
@@ -18,6 +18,7 @@
|
||||
"axios": "^1.1.3",
|
||||
"axios-auth-refresh": "^3.3.4",
|
||||
"core-js": "^3.8.3",
|
||||
"date-fns": "^2.29.3",
|
||||
"mitt": "^2.1.0",
|
||||
"moment": "^2.29.4",
|
||||
"node-polyfill-webpack-plugin": "^2.0.1",
|
||||
|
||||
@@ -1,60 +1,64 @@
|
||||
{
|
||||
"data": {
|
||||
"user": {
|
||||
"id": 1,
|
||||
"name": "Matej",
|
||||
"surname": "Glasnak",
|
||||
"work_hours_from": "08:00",
|
||||
"work_hours_to": "16:00"
|
||||
},
|
||||
|
||||
"id": 1,
|
||||
"name": "Matej",
|
||||
"surname": "Glasnak",
|
||||
"work_hours_from": "08:00",
|
||||
"work_hours_to": "19:00",
|
||||
"unscheduled_time": 123123123,
|
||||
"dates": [
|
||||
{
|
||||
"id": 1,
|
||||
"task_id": 1,
|
||||
"starts_at": "2022-11-28T09:00:00+00:00",
|
||||
"ends_at": "2022-11-29T12:00:00+00:00",
|
||||
"title": "title",
|
||||
"project_code": "CO-2201",
|
||||
"master_task_color": "#121212",
|
||||
"class": "red"
|
||||
},
|
||||
|
||||
"dates": {
|
||||
"2022-11-10": [
|
||||
{
|
||||
"id": 1,
|
||||
"is_finished": false,
|
||||
"starts_at": "2022-11-10T09:00:00+00:00",
|
||||
"ends_at": "2022-11-12T12:00:00+00:00",
|
||||
"files": []
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"task_id": 2,
|
||||
"starts_at": "2022-12-01T12:00:00+00:00",
|
||||
"ends_at": "2022-12-02T16:00:00+00:00",
|
||||
"title": "title",
|
||||
"project_code": "CO-2201",
|
||||
"master_task_color": "#121212",
|
||||
"style": "bakcground: red"
|
||||
},
|
||||
|
||||
{
|
||||
"id": 2,
|
||||
"is_finished": false,
|
||||
"starts_at": "2022-11-10T12:00:00+00:00",
|
||||
"ends_at": "2022-11-12T16:00:00+00:00",
|
||||
"files": []
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"task_id": null,
|
||||
"starts_at": "2022-11-10T16:00:00+00:00",
|
||||
"ends_at": "2022-11-12T18:00:00+00:00",
|
||||
"title": "title",
|
||||
"is_blocker": true,
|
||||
"master_task_color": null
|
||||
},
|
||||
|
||||
{
|
||||
"id": 4,
|
||||
"is_finished": false,
|
||||
"starts_at": "2022-11-10T16:00:00+00:00",
|
||||
"ends_at": "2022-11-12T18:00:00+00:00",
|
||||
"is_blocker": true
|
||||
}
|
||||
],
|
||||
{
|
||||
"id": 5,
|
||||
"task_id": 1,
|
||||
"starts_at": "2022-11-10T09:00:00+00:00",
|
||||
"ends_at": "2022-11-12T12:00:00+00:00",
|
||||
"title": "title",
|
||||
"project_code": "CO-2201",
|
||||
"master_task_color": "#121212"
|
||||
},
|
||||
|
||||
"2022-12-10": [
|
||||
{
|
||||
"id": 1,
|
||||
"is_finished": false,
|
||||
"starts_at": "2022-11-10T09:00:00+00:00",
|
||||
"ends_at": "2022-11-12T12:00:00+00:00",
|
||||
"files": []
|
||||
},
|
||||
|
||||
{
|
||||
"id": 2,
|
||||
"is_finished": false,
|
||||
"starts_at": "2022-11-10T12:00:00+00:00",
|
||||
"ends_at": "2022-11-12T16:00:00+00:00",
|
||||
"files": []
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"id": 6,
|
||||
"task_id": 2,
|
||||
"starts_at": "2022-11-10T12:00:00+00:00",
|
||||
"ends_at": "2022-11-12T16:00:00+00:00",
|
||||
"title": "title",
|
||||
"project_code": "CO-2201",
|
||||
"master_task_color": "#121212"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": 200
|
||||
}
|
||||
@@ -93,6 +93,7 @@ export default {
|
||||
box-shadow: none !important
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.2)
|
||||
padding: 25px 15px
|
||||
flex: 0 0 auto
|
||||
|
||||
.menu-icon
|
||||
display: none
|
||||
|
||||
@@ -27,10 +27,16 @@ export default {
|
||||
<style lang="sass" scoped>
|
||||
.main-content
|
||||
overflow-y: scroll
|
||||
flex: 1 1 100%
|
||||
|
||||
#main-content
|
||||
height: fit-content
|
||||
|
||||
.split-pane-right-side
|
||||
width: 100vw
|
||||
max-width: 100vw
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
@media (min-width: 992px)
|
||||
.split-pane-right-side
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<slot name="week-number-cell" :week="getWeekNumber(i - 1)">{{ getWeekNumber(i - 1) }}</slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vuecal__flex vuecal__cells" :class="`${view.id}-view`" grow="grow" :wrap="!cellOrSplitMinWidth || !isWeekView" :column="!!cellOrSplitMinWidth">
|
||||
<div class="vuecal__flex vuecal__cells vuecal__scrollable-body" :class="`${view.id}-view`" grow="grow" :wrap="!cellOrSplitMinWidth || !isWeekView" :column="!!cellOrSplitMinWidth">
|
||||
<weekdays-headings v-if="cellOrSplitMinWidth && isWeekView" :transition-direction="transitionDirection" :week-days="weekDays" :switch-to-narrower-view="switchToNarrowerView" :style="cellOrSplitMinWidth ? `min-width: ${cellOrSplitMinWidth}px` : ''">
|
||||
<template #weekday-heading="{ heading, view }" v-if="$slots['weekday-heading']">
|
||||
<slot name="weekday-heading" :heading="heading" :view="view"></slot>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
template(v-for="(heading, i) in headings" :key="i")
|
||||
.vuecal__flex.vuecal__heading(
|
||||
v-if="!heading.hide"
|
||||
:class="{ today: heading.today, clickable: cellHeadingsClickable }"
|
||||
:class="{ today: heading.today, clickable: cellHeadingsClickable, 'yesterday-cell' : new Date(heading.date).toLocaleDateString('sk-SK') == new Date(new Date().setDate(new Date().getDate() - 1)).toLocaleDateString('sk-SK') }"
|
||||
:style="weekdayCellStyles"
|
||||
@click="view.id === 'week' && selectCell(heading.date, $event)"
|
||||
@dblclick="view.id === 'week' && vuecal.dblclickToNavigate && switchToNarrowerView()")
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
variant="outlined"
|
||||
></v-select>
|
||||
<div class="d-flex date-wrapper">
|
||||
<v-btn class="subheader-icon-button prev" variant="outlined"><img :src="require('./_img/icon-prev.svg')" alt=""></v-btn>
|
||||
<v-btn class="subheader-icon-button prev" variant="outlined" @click="prevWeek()"><img :src="require('./_img/icon-prev.svg')" alt=""></v-btn>
|
||||
<v-text-field
|
||||
class="subheader-input disabled"
|
||||
label="Dátum"
|
||||
@@ -16,7 +16,7 @@
|
||||
variant="outlined"
|
||||
append-inner-icon="mdi-calendar-blank-outline"
|
||||
></v-text-field>
|
||||
<v-btn class="subheader-icon-button next" variant="outlined"><img :src="require('./_img/icon-next.svg')" alt=""></v-btn>
|
||||
<v-btn class="subheader-icon-button next" variant="outlined" @click="nextWeek()"><img :src="require('./_img/icon-next.svg')" alt=""></v-btn>
|
||||
</div>
|
||||
<v-text-field
|
||||
class="subheader-input"
|
||||
@@ -28,15 +28,43 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { startOfWeek, endOfWeek, addDays, subDays } from 'date-fns'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
employees: ['Foo', 'Bar', 'Fizz', 'Buzz'],
|
||||
selectedDate: "13.11.2022 - 17.11.2022",
|
||||
plannedTime: "35 h",
|
||||
selectedEmployee: 'Bar'
|
||||
selectedEmployee: 'Bar',
|
||||
date: new Date()
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.getWeek()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getWeek() {
|
||||
this.firstDay = addDays(startOfWeek(this.date), 1)
|
||||
this.lastDay = addDays(endOfWeek(this.date), 1)
|
||||
console.log()
|
||||
|
||||
this.$emit('weekChange', {firstDay: this.firstDay, lastDay: this.lastDay})
|
||||
this.selectedDate = String(this.firstDay.toLocaleDateString('sk-SK') + ' - ' + this.lastDay.toLocaleDateString('sk-SK'))
|
||||
},
|
||||
|
||||
prevWeek() {
|
||||
this.date = subDays(this.date, 7)
|
||||
this.getWeek()
|
||||
},
|
||||
|
||||
nextWeek() {
|
||||
this.date = addDays(this.date, 7)
|
||||
this.getWeek()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -84,6 +112,10 @@ export default {
|
||||
order: 3
|
||||
|
||||
@media (max-width: 600px)
|
||||
.subheader
|
||||
gap: 15px
|
||||
padding: 20px !important
|
||||
|
||||
.subheader-input
|
||||
max-width: 100% !important
|
||||
min-width: 100%
|
||||
@@ -97,5 +129,6 @@ export default {
|
||||
order: 3
|
||||
margin: 0
|
||||
flex: 1 1 calc( 50% - 5px )
|
||||
height: 40px
|
||||
|
||||
</style>
|
||||
@@ -4,18 +4,18 @@
|
||||
:hide-view-selector="true"
|
||||
:hide-title-bar="true"
|
||||
:disable-views="['years', 'year', 'month', 'day']"
|
||||
:time-from="8 * 60"
|
||||
:time-to="24 * 60"
|
||||
:hide-weekends="true"
|
||||
:selected-date="new Date()"
|
||||
:time-from="calConfig.startHour * 60"
|
||||
:time-to="calConfig.endHour * 60"
|
||||
:selected-date="calConfig.date"
|
||||
:onEventClick="taskClicked"
|
||||
:editable-events="vueCalConfig.editing"
|
||||
:events="events"
|
||||
:events="calData.dates"
|
||||
:min-event-width="90"
|
||||
:overlaps-per-time-step="true"
|
||||
:time-cell-height="200"
|
||||
:min-cell-width="300"
|
||||
sticky-split-labels
|
||||
@ready="scrollToYesterday"
|
||||
@view-change="weekChanged"
|
||||
>
|
||||
<template v-slot:weekday-heading="{ heading }">
|
||||
<span class="d-flex align-center">
|
||||
@@ -47,59 +47,20 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import VueCal from 'vue-cal'
|
||||
// import 'vue-cal/dist/vuecal.css'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
// VueCal,
|
||||
props: {
|
||||
calData: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
calConfig: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
events: [
|
||||
{
|
||||
start: '2022-11-28 8:00',
|
||||
end: '2022-11-28 13:30',
|
||||
title: 'Running Marathon',
|
||||
content: '<i class="icon material-icons">directions_run</i>',
|
||||
class: 'red',
|
||||
id: 1
|
||||
},
|
||||
{
|
||||
start: '2022-11-28 9:00',
|
||||
end: '2022-11-28 11:00',
|
||||
title: 'Drink water!',
|
||||
content: '<i class="icon material-icons">local_drink</i>',
|
||||
class: 'green',
|
||||
id: 2
|
||||
},
|
||||
{
|
||||
start: '2022-11-28 10:00',
|
||||
end: '2022-11-28 12:00',
|
||||
title: 'Trip to India',
|
||||
content: '<i class="icon material-icons">flight</i>',
|
||||
class: 'blue',
|
||||
id: 3
|
||||
},
|
||||
{
|
||||
start: '2022-11-28 13:30',
|
||||
end: '2022-11-28 16:00',
|
||||
title: 'Trip to India',
|
||||
content: '<i class="icon material-icons">flight</i>',
|
||||
class: 'blue',
|
||||
id: 3
|
||||
},
|
||||
{
|
||||
start: '2022-11-29 11:00',
|
||||
end: '2022-11-29 13:00',
|
||||
title: 'Trip to India',
|
||||
content: '<i class="icon material-icons">flight</i>',
|
||||
class: 'yellow',
|
||||
id: 3
|
||||
}
|
||||
],
|
||||
|
||||
vueCalConfig: {
|
||||
editing: {
|
||||
title: false,
|
||||
@@ -109,11 +70,27 @@ export default {
|
||||
create: false
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
weekChanged() {
|
||||
const scrollContainer = document.getElementsByClassName('vuecal__scrollable-body')[0]
|
||||
scrollContainer.scrollLeft = 0
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.scrollToYesterday()
|
||||
})
|
||||
},
|
||||
|
||||
scrollToYesterday() {
|
||||
if (!document.getElementsByClassName('yesterday-cell').length) return
|
||||
|
||||
const scrollContainer = document.getElementsByClassName('vuecal__scrollable-body')[0]
|
||||
const yesterdayCell = document.getElementsByClassName('yesterday-cell')[0]
|
||||
scrollContainer.scrollLeft = yesterdayCell.offsetLeft - scrollContainer.offsetLeft - 20
|
||||
},
|
||||
|
||||
getHeadingDate(value) {
|
||||
const date = new Date(value)
|
||||
|
||||
@@ -136,98 +113,88 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
.calendar-wrapper
|
||||
width: 100%
|
||||
overflow-x: scroll
|
||||
padding-top: 50px
|
||||
|
||||
.vuecal
|
||||
transform: scale(1)
|
||||
box-shadow: none !important
|
||||
|
||||
::v-deep
|
||||
.calendar-wrapper
|
||||
width: 100%
|
||||
padding-top: 50px
|
||||
|
||||
.vuecal__cells
|
||||
-ms-overflow-style: none
|
||||
scrollbar-width: none
|
||||
&:deep()
|
||||
|
||||
&::-webkit-scrollbar
|
||||
display: none
|
||||
.vuecal__cells
|
||||
-ms-overflow-style: none
|
||||
scrollbar-width: none
|
||||
&::-webkit-scrollbar
|
||||
display: none
|
||||
|
||||
.vuecal__body
|
||||
max-height: 100%
|
||||
overflow-y: scroll
|
||||
position: relative !important
|
||||
-ms-overflow-style: none
|
||||
scrollbar-width: none
|
||||
.vuecal__body
|
||||
-ms-overflow-style: none
|
||||
scrollbar-width: none
|
||||
&::-webkit-scrollbar
|
||||
display: none
|
||||
|
||||
&::-webkit-scrollbar
|
||||
display: none
|
||||
.weekday-label
|
||||
justify-content: start !important
|
||||
font-size: 24px
|
||||
font-weight: 700
|
||||
|
||||
.weekday-label
|
||||
justify-content: start !important
|
||||
font-size: 24px
|
||||
font-weight: 700
|
||||
.vuecal__weekdays-headings,
|
||||
.vuecal__cell:before
|
||||
border: none
|
||||
|
||||
.vuecal__weekdays-headings,
|
||||
.vuecal__cell:before
|
||||
border: none
|
||||
.vuecal__cells.week-view
|
||||
border-left: 1px solid rgba(0, 0, 0, .1)
|
||||
padding-left: 20px
|
||||
|
||||
.vuecal__cells.week-view
|
||||
border-left: 1px solid rgba(0, 0, 0, .1)
|
||||
padding-left: 20px
|
||||
|
||||
.vuecal__time-column
|
||||
width: 150px
|
||||
box-shadow: none !important
|
||||
|
||||
.time-column-line
|
||||
width: 40px
|
||||
height: 0
|
||||
border: 1px solid rgba(33, 33, 33, 0.08)
|
||||
margin-left: 10px
|
||||
|
||||
@media (max-width: 450px)
|
||||
.vuecal__time-column
|
||||
width: 70px
|
||||
|
||||
width: 150px
|
||||
box-shadow: none !important
|
||||
|
||||
.time-column-line
|
||||
width: 10px
|
||||
width: 40px
|
||||
height: 0
|
||||
border: 1px solid rgba(33, 33, 33, 0.08)
|
||||
margin-left: 10px
|
||||
|
||||
.vuecal__flex
|
||||
flex-wrap: nowrap !important
|
||||
@media (max-width: 450px)
|
||||
.vuecal__time-column
|
||||
width: 70px
|
||||
|
||||
.vuecal__cell
|
||||
padding: 10px 10px 10px 0px
|
||||
.time-column-line
|
||||
width: 10px
|
||||
|
||||
.vuecal__cell--today
|
||||
// background-color: rgba(0, 0, 0, .02) !important
|
||||
background-color: white
|
||||
.vuecal__flex
|
||||
flex-wrap: nowrap !important
|
||||
|
||||
.vuecal:not(.vuecal--day-view) .vuecal__cell--selected:not(.vuecal__cell--today) ,
|
||||
.vuecal__cell--current:not(.vuecal__cell--today)
|
||||
background-color: white
|
||||
.vuecal__cell
|
||||
padding: 10px 10px 10px 0px
|
||||
|
||||
.vuecal__event
|
||||
border-radius: 16px
|
||||
padding: 20px 10px
|
||||
text-align: left
|
||||
.vuecal:not(.vuecal--day-view) .vuecal__cell--selected:not(.vuecal__cell--today) ,
|
||||
.vuecal__cell--current:not(.vuecal__cell--today),
|
||||
.vuecal__cell--today
|
||||
background-color: white
|
||||
|
||||
.vuecal__event-title
|
||||
.vuecal__event
|
||||
border-radius: 16px
|
||||
padding: 20px 10px
|
||||
text-align: left
|
||||
|
||||
&:hover
|
||||
z-index: 10
|
||||
.vuecal__event-title
|
||||
text-align: left
|
||||
|
||||
&.red
|
||||
background: #FFC9C9 !important
|
||||
&:hover
|
||||
z-index: 10
|
||||
|
||||
&.green
|
||||
background: #E9FFE5 !important
|
||||
&.red
|
||||
background: #FFC9C9 !important
|
||||
|
||||
&.blue
|
||||
background: #DADEF8 !important
|
||||
&.green
|
||||
background: #E9FFE5 !important
|
||||
|
||||
&.yellow
|
||||
background: #F6ECD3 !important
|
||||
&.blue
|
||||
background: #DADEF8 !important
|
||||
|
||||
&.yellow
|
||||
background: #F6ECD3 !important
|
||||
</style>
|
||||
@@ -1,7 +1,18 @@
|
||||
<template>
|
||||
<div>
|
||||
<A-task-filter />
|
||||
<Z-timeline />
|
||||
<A-task-filter @weekChange="getWeekData" />
|
||||
<W-loadable :content="timelineData" class="w-loadable" empty-message="Nepodarilo sa nacitat data!">
|
||||
<Z-timeline :calData="timelineData" :calConfig="config" />
|
||||
</W-loadable>
|
||||
|
||||
<v-snackbar
|
||||
v-model="errorToast"
|
||||
:timeout="2000"
|
||||
color="white"
|
||||
:rounded="true"
|
||||
>
|
||||
Nepodarilo sa nacitat data!
|
||||
</v-snackbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -14,5 +25,53 @@ export default {
|
||||
ATaskFilter,
|
||||
ZTimeline,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
timelineData: null,
|
||||
errorToast: false,
|
||||
dataLoaded: false,
|
||||
config: {
|
||||
date: new Date(),
|
||||
startHour: 8,
|
||||
endHour: 16,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
async getWeekData(week) {
|
||||
this.config.date = week.firstDay
|
||||
try {
|
||||
this.timelineData = await this.$axios.get_auth_data('v1/overview/tasks')
|
||||
this.formatData()
|
||||
} catch(error) {
|
||||
this.timelineData = {}
|
||||
console.error(error)
|
||||
this.errorToast = true
|
||||
}
|
||||
},
|
||||
|
||||
formatData() {
|
||||
// format events
|
||||
this.timelineData.dates.forEach(event => {
|
||||
event.start = new Date(event.starts_at)
|
||||
event.end = new Date(event.ends_at)
|
||||
delete event.starts_at
|
||||
delete event.ends_at
|
||||
})
|
||||
|
||||
// format working hours
|
||||
this.config.startHour = Number(this.timelineData.work_hours_from.split(':')[0]) - 1
|
||||
this.config.endHour = Number(this.timelineData.work_hours_to.split(':')[0]) + 1
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
.w-loadable
|
||||
text-align: center
|
||||
padding-top: 20px
|
||||
height: 100%
|
||||
</style>
|
||||
Reference in new issue
Block a user