mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-22 06:49:35 +00:00
team table, create team modal, delete team modal
This commit is contained in:
1 parent
0e33d86c98
commit
f6d0764969
24 files changed
+1750
-886
No files matched your search
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2 20H22" stroke="#14181F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M19.6585 9.70128L12.6585 3.57628C12.2815 3.24638 11.7185 3.24638 11.3415 3.57628L4.3415 9.70128C4.12448 9.89117 4 10.1655 4 10.4539V19.0001C4 19.5524 4.44772 20.0001 5 20.0001H9C9.55228 20.0001 10 19.5524 10 19.0001V15.0001C10 14.4478 10.4477 14.0001 11 14.0001H13C13.5523 14.0001 14 14.4478 14 15.0001V19.0001C14 19.5524 14.4477 20.0001 15 20.0001H19C19.5523 20.0001 20 19.5524 20 19.0001V10.4539C20 10.1655 19.8755 9.89117 19.6585 9.70128Z" stroke="#14181F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 740 B |
@@ -8,8 +8,8 @@
|
||||
variant="outlined"
|
||||
></v-select>
|
||||
<div class="d-flex date-wrapper">
|
||||
<v-btn class="subheader-icon-button " variant="outlined"><img :src="require('./_img/icon-prev.svg')" alt=""></v-btn>
|
||||
<v-text-field
|
||||
<v-btn class="subheader-icon-button prev" variant="outlined"><img :src="require('./_img/icon-prev.svg')" alt=""></v-btn>
|
||||
<v-text-field
|
||||
class="subheader-input disabled"
|
||||
:items="items"
|
||||
label="Dátum"
|
||||
@@ -17,7 +17,7 @@
|
||||
variant="outlined"
|
||||
append-inner-icon="mdi-calendar-blank-outline"
|
||||
></v-text-field>
|
||||
<v-btn class="subheader-icon-button " variant="outlined"><img :src="require('./_img/icon-next.svg')" alt=""></v-btn>
|
||||
<v-btn class="subheader-icon-button next" variant="outlined"><img :src="require('./_img/icon-next.svg')" alt=""></v-btn>
|
||||
</div>
|
||||
<v-text-field
|
||||
class="subheader-input"
|
||||
@@ -51,13 +51,19 @@ export default {
|
||||
gap: 30px
|
||||
flex-wrap: wrap
|
||||
|
||||
.subheader-icon-button
|
||||
.subheader-icon-button
|
||||
border: 1px solid #ABABAB
|
||||
height: 56px
|
||||
width: 56px
|
||||
min-width: auto !important
|
||||
padding: 0
|
||||
margin: 0 10px
|
||||
margin: 0
|
||||
|
||||
&.prev
|
||||
margin-right: 10px
|
||||
|
||||
&.next
|
||||
margin-left: 10px
|
||||
|
||||
&:deep(.v-btn__append)
|
||||
margin: 0
|
||||
@@ -69,13 +75,10 @@ export default {
|
||||
&:deep(.v-input__details)
|
||||
display: none
|
||||
|
||||
&.disabled
|
||||
&.disabled
|
||||
pointer-events: none !important
|
||||
|
||||
|
||||
.date-wrapper
|
||||
flex: 0 1 402px
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
@@ -1,326 +1,220 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-sheet tile height="54" color="grey lighten-3" class="d-flex">
|
||||
<v-btn icon class="ma-2" @click="$refs.calendar.prev()">
|
||||
<v-icon>mdi-chevron-left</v-icon>
|
||||
</v-btn>
|
||||
<v-select v-model="type" :items="types" dense outlined hide-details class="ma-2" label="type"></v-select>
|
||||
<v-select v-model="mode" :items="modes" dense outlined hide-details label="event-overlap-mode" class="ma-2"></v-select>
|
||||
<v-select v-model="weekday" :items="weekdays" dense outlined hide-details label="weekdays" class="ma-2"></v-select>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon class="ma-2" @click="$refs.calendar.next()">
|
||||
<v-icon>mdi-chevron-right</v-icon>
|
||||
</v-btn>
|
||||
</v-sheet>
|
||||
<v-sheet height="600">
|
||||
<v-calendar ref="calendar" v-model="value" :weekdays="weekday" :type="type" :events="events" :event-overlap-mode="mode" :event-overlap-threshold="60" :event-color="getEventColor" :event-ripple="false" @change="getEvents" @mousedown:event="startDrag" @mousedown:time="startTime" @mousemove:time="mouseMove" @mouseup:time="endDrag" @mouseleave="cancelDrag">
|
||||
<template #event="{ event, timed }">
|
||||
<div class="pl-1" v-html="getEventHTML(event, timed)"></div>
|
||||
<div v-if="timed" class="v-event-drag-bottom" @mousedown.stop="extendBottom(event)"></div>
|
||||
</template>
|
||||
<template #day-body="{ date, week }">
|
||||
<div class="v-current-time" :class="{ first: date === week[0].date }" :style="{ top: nowY }">
|
||||
<div class="v-current-time-time">
|
||||
{{ nowTime }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</v-calendar>
|
||||
<!-- {{ lastEvent }} -->
|
||||
</v-sheet>
|
||||
<div class="calendar-wrapper">
|
||||
<Vue-cal
|
||||
: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()"
|
||||
:onEventClick="taskClicked"
|
||||
:editable-events="vueCalConfig.editing"
|
||||
:events="events"
|
||||
:min-event-width="90"
|
||||
:overlaps-per-time-step="true"
|
||||
:time-cell-height="200"
|
||||
:min-cell-width="300"
|
||||
sticky-split-labels
|
||||
>
|
||||
<template v-slot:weekday-heading="{ heading }">
|
||||
<span class="d-flex align-center">
|
||||
<img v-if="getHeadingDate(heading.date) == 'Dnes'" :src="require('./_img/home-icon.svg')" class="mr-2">
|
||||
<p>{{ getHeadingDate(heading.date) }}</p>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template v-slot:time-cell="{ hours, minutes }">
|
||||
<span class="d-flex align-center justify-center">
|
||||
<p>{{hours}}:{{String(minutes).padStart(2, '0')}}</p>
|
||||
<div class="time-column-line"></div>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template v-slot:event="{ event }">
|
||||
<div class="vuecal__event-title vuecal__event-title--edit"
|
||||
contenteditable
|
||||
@blur="event.title = $event.target.innerHTML"
|
||||
v-html="event.title" />
|
||||
<small class="vuecal__event-time">
|
||||
|
||||
<strong>Event start:</strong> <span>{{ event.start.formatTime("h O'clock") }}</span><br/>
|
||||
<strong>Event end:</strong> <span>{{ event.end.formatTime("h O'clock") }}</span>
|
||||
</small>
|
||||
</template>
|
||||
</Vue-cal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
// import VueCal from 'vue-cal'
|
||||
// import 'vue-cal/dist/vuecal.css'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
// VueCal,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
type: 'day',
|
||||
types: ['month', 'week', 'day', '4day'],
|
||||
mode: 'stack',
|
||||
modes: ['stack', 'column'],
|
||||
weekday: [0, 1, 2, 3, 4, 5, 6],
|
||||
weekdays: [
|
||||
{ text: 'Sun - Sat', value: [0, 1, 2, 3, 4, 5, 6] },
|
||||
{ text: 'Mon - Sun', value: [1, 2, 3, 4, 5, 6, 0] },
|
||||
{ text: 'Mon - Fri', value: [1, 2, 3, 4, 5] },
|
||||
{ text: 'Mon, Wed, Fri', value: [1, 3, 5] }
|
||||
events: [
|
||||
{
|
||||
start: '2022-11-21 8:00',
|
||||
end: '2022-11-21 13:30',
|
||||
title: 'Running Marathon',
|
||||
content: '<i class="icon material-icons">directions_run</i>',
|
||||
class: 'red',
|
||||
id: 1
|
||||
},
|
||||
{
|
||||
start: '2022-11-21 9:00',
|
||||
end: '2022-11-21 11:00',
|
||||
title: 'Drink water!',
|
||||
content: '<i class="icon material-icons">local_drink</i>',
|
||||
class: 'green',
|
||||
id: 2
|
||||
},
|
||||
{
|
||||
start: '2022-11-21 10:00',
|
||||
end: '2022-11-21 12:00',
|
||||
title: 'Trip to India',
|
||||
content: '<i class="icon material-icons">flight</i>',
|
||||
class: 'blue',
|
||||
id: 3
|
||||
},
|
||||
{
|
||||
start: '2022-11-21 13:30',
|
||||
end: '2022-11-21 16:00',
|
||||
title: 'Trip to India',
|
||||
content: '<i class="icon material-icons">flight</i>',
|
||||
class: 'blue',
|
||||
id: 3
|
||||
},
|
||||
{
|
||||
start: '2022-11-22 11:00',
|
||||
end: '2022-11-22 13:00',
|
||||
title: 'Trip to India',
|
||||
content: '<i class="icon material-icons">flight</i>',
|
||||
class: 'yellow',
|
||||
id: 3
|
||||
}
|
||||
],
|
||||
value: '',
|
||||
events: [],
|
||||
colors: ['#2196F3', '#3F51B5', '#673AB7', '#00BCD4', '#4CAF50', '#FF9800', '#757575'],
|
||||
names: ['Meeting', 'Holiday', 'PTO', 'Travel', 'Event', 'Birthday', 'Conference', 'Party'],
|
||||
|
||||
dragEvent: null,
|
||||
dragStart: null,
|
||||
lastEvent: '',
|
||||
createEvent: null,
|
||||
createStart: null,
|
||||
extendOriginal: null,
|
||||
vueCalConfig: {
|
||||
editing: {
|
||||
title: false,
|
||||
drag: true,
|
||||
resize: false,
|
||||
delete: false,
|
||||
create: false
|
||||
}
|
||||
},
|
||||
|
||||
isMounted: false
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
nowY() {
|
||||
const cal = this.$refs.calendar
|
||||
if (!cal && !this.isMounted) {
|
||||
return -1
|
||||
}
|
||||
|
||||
return cal.timeToY(cal.times.now) + 'px'
|
||||
},
|
||||
|
||||
nowTime() {
|
||||
const cal = this.$refs.calendar
|
||||
if (!cal && !this.isMounted) {
|
||||
return -1
|
||||
}
|
||||
|
||||
return cal.formatTime(cal.times.now)
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
const cal = this.$refs.calendar
|
||||
this.isMounted = true
|
||||
|
||||
// scroll to the current time
|
||||
const minutes = cal.times.now.hour * 60 + cal.times.now.minute
|
||||
const firstTime = Math.max(0, minutes - (minutes % 30) - 30)
|
||||
cal.scrollToTime(firstTime)
|
||||
|
||||
// every minute update the current time bar
|
||||
setInterval(() => cal.updateTimes(), 60 * 1000)
|
||||
},
|
||||
|
||||
methods: {
|
||||
getEvents({ start, end }) {
|
||||
const events = []
|
||||
getHeadingDate(value) {
|
||||
const date = new Date(value)
|
||||
|
||||
const min = new Date(`${start.date}T00:00:00`)
|
||||
const max = new Date(`${end.date}T23:59:59`)
|
||||
const days = (max.getTime() - min.getTime()) / 86400000
|
||||
const eventCount = this.rnd(days, days + 20)
|
||||
const today = new Date()
|
||||
const yesterday = new Date((new Date()).setDate(today.getDate() - 1))
|
||||
const tomorrow = new Date((new Date()).setDate(today.getDate() + 1))
|
||||
|
||||
for (let i = 0; i < eventCount; i++) {
|
||||
const allDay = this.rnd(0, 3) === 0
|
||||
const firstTimestamp = this.rnd(min.getTime(), max.getTime())
|
||||
const first = new Date(firstTimestamp - (firstTimestamp % 900000))
|
||||
const secondTimestamp = this.rnd(2, allDay ? 288 : 8) * 900000
|
||||
const second = new Date(first.getTime() + secondTimestamp)
|
||||
if (today.toLocaleDateString('sk-SK') === date.toLocaleDateString('sk-SK')) return "Dnes"
|
||||
if (yesterday.toLocaleDateString('sk-SK') === date.toLocaleDateString('sk-SK')) return "Včera"
|
||||
if (tomorrow.toLocaleDateString('sk-SK') === date.toLocaleDateString('sk-SK')) return "Zajtra"
|
||||
|
||||
events.push({
|
||||
name: this.names[this.rnd(0, this.names.length - 1)],
|
||||
start: this.formatDate(first, !allDay),
|
||||
end: this.formatDate(second, !allDay),
|
||||
color: this.colors[this.rnd(0, this.colors.length - 1)]
|
||||
})
|
||||
}
|
||||
return date.toLocaleDateString('sk-SK')
|
||||
},
|
||||
|
||||
this.events = events
|
||||
},
|
||||
getEventColor(event) {
|
||||
const rgb = parseInt(event.color.substring(1), 16)
|
||||
const r = (rgb >> 16) & 0xff
|
||||
const g = (rgb >> 8) & 0xff
|
||||
const b = (rgb >> 0) & 0xff
|
||||
|
||||
return event === this.dragEvent ? `rgba(${r}, ${g}, ${b}, 0.5)` : event === this.createEvent ? `rgba(${r}, ${g}, ${b}, 0.5)` : event.color
|
||||
},
|
||||
getEventHTML(event, timed) {
|
||||
const cal = this.$refs.calendar
|
||||
let name = event.name
|
||||
if (event.start.hasTime) {
|
||||
if (timed) {
|
||||
const showStart = event.start.hour < 12 && event.end.hour >= 12
|
||||
const start = cal.formatTime(event.start, showStart)
|
||||
const end = cal.formatTime(event.end, true)
|
||||
// const singline = diffMinutes(event.start, event.end) <= this.parsedEventOverlapThreshold
|
||||
const singline = event.end - event.start <= this.parsedEventOverlapThreshold
|
||||
const separator = singline ? ', ' : '<br>'
|
||||
return `<strong>${name}</strong>${separator}${start} - ${end}`
|
||||
} else {
|
||||
const time = this.formatTime(event.start, true)
|
||||
return `<strong>${time}</strong> ${name}`
|
||||
}
|
||||
}
|
||||
return name
|
||||
},
|
||||
rnd(a, b) {
|
||||
return Math.floor((b - a + 1) * Math.random()) + a
|
||||
},
|
||||
formatDate(a, withTime) {
|
||||
return withTime ? `${a.getFullYear()}-${a.getMonth() + 1}-${a.getDate()} ${a.getHours()}:${a.getMinutes()}` : `${a.getFullYear()}-${a.getMonth() + 1}-${a.getDate()}`
|
||||
},
|
||||
eventMove(e) {
|
||||
console.log('eventMove', e)
|
||||
},
|
||||
startDrag(e) {
|
||||
if (e.event && e.timed) {
|
||||
this.dragEvent = e.event
|
||||
this.dragTime = null
|
||||
this.extendOriginal = null
|
||||
}
|
||||
|
||||
this.lastEvent = 'startDrag'
|
||||
},
|
||||
startTime(e) {
|
||||
const mouse = this.toDate(e)
|
||||
|
||||
if (this.dragEvent && this.dragTime === null) {
|
||||
const start = this.toDate(this.dragEvent.start)
|
||||
|
||||
this.dragTime = mouse.getTime() - start.getTime()
|
||||
} else {
|
||||
this.createStart = this.roundTime(mouse.getTime())
|
||||
this.createEvent = {
|
||||
name: '(no title)',
|
||||
start: this.toTimestamp(new Date(this.createStart)),
|
||||
end: this.toTimestamp(new Date(this.createStart)),
|
||||
color: this.colors[this.rnd(0, this.colors.length - 1)]
|
||||
}
|
||||
this.events.push(this.createEvent)
|
||||
}
|
||||
this.lastEvent = 'startTime'
|
||||
},
|
||||
extendBottom(event) {
|
||||
this.createEvent = event
|
||||
this.createStart = this.toDate(event.start).getTime()
|
||||
this.extendOriginal = event.end
|
||||
},
|
||||
mouseMoveEvent(e) {
|
||||
console.log('mouseMoveEvent', e)
|
||||
},
|
||||
mouseMove(e) {
|
||||
if (this.dragEvent && this.dragTime !== null) {
|
||||
const start = this.toDate(this.dragEvent.start)
|
||||
const end = this.toDate(this.dragEvent.end)
|
||||
const duration = end.getTime() - start.getTime()
|
||||
const mouse = this.toDate(e)
|
||||
|
||||
const newStartTime = mouse.getTime() - this.dragTime
|
||||
const newStart = new Date(this.roundTime(newStartTime))
|
||||
const newEnd = new Date(newStart.getTime() + duration)
|
||||
|
||||
this.dragEvent.start = this.toTimestamp(newStart)
|
||||
this.dragEvent.end = this.toTimestamp(newEnd)
|
||||
} else if (this.createEvent && this.createStart !== null) {
|
||||
const mouse = this.toDate(e).getTime()
|
||||
const mouseRounded = this.roundTime(mouse, false)
|
||||
const min = Math.min(mouseRounded, this.createStart)
|
||||
const max = Math.max(mouseRounded, this.createStart)
|
||||
|
||||
this.createEvent.start = this.toTimestamp(new Date(min))
|
||||
this.createEvent.end = this.toTimestamp(new Date(max))
|
||||
}
|
||||
},
|
||||
endDrag(e) {
|
||||
this.dragTime = null
|
||||
this.dragEvent = null
|
||||
this.createEvent = null
|
||||
this.createStart = null
|
||||
this.extendOriginal = null
|
||||
|
||||
this.lastEvent = 'endDrag'
|
||||
},
|
||||
cancelDrag(e) {
|
||||
if (this.createEvent) {
|
||||
if (this.extendOriginal) {
|
||||
this.createEvent.end = this.extendOriginal
|
||||
} else {
|
||||
const i = this.events.indexOf(this.createEvent)
|
||||
if (i !== -1) {
|
||||
this.events.splice(i, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.createEvent = null
|
||||
this.createStart = null
|
||||
this.dragTime = null
|
||||
this.dragEvent = null
|
||||
|
||||
this.lastEvent = 'cancelDrag'
|
||||
},
|
||||
roundTime(time, down = true) {
|
||||
const roundDownTime = 15 * 60 * 1000 // 15 minutes
|
||||
|
||||
return down ? time - (time % roundDownTime) : time + (roundDownTime - (time % roundDownTime))
|
||||
},
|
||||
toDate(tms) {
|
||||
return typeof tms === 'string' ? new Date(tms) : new Date(tms.year, tms.month - 1, tms.day, tms.hour, tms.minute)
|
||||
},
|
||||
toTimestamp(date) {
|
||||
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}`
|
||||
taskClicked(task) {
|
||||
console.log("task", task)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
.v-calendar
|
||||
user-select: none
|
||||
-webkit-user-select: none
|
||||
.calendar-wrapper
|
||||
width: 100%
|
||||
overflow-x: scroll
|
||||
padding-top: 50px
|
||||
|
||||
.v-event-drag-bottom
|
||||
position: absolute
|
||||
left: 0
|
||||
right: 0
|
||||
bottom: 4px
|
||||
height: 4px
|
||||
cursor: ns-resize
|
||||
.vuecal
|
||||
transform: scale(1)
|
||||
|
||||
.v-event-drag-bottom::after
|
||||
display: none
|
||||
position: absolute
|
||||
left: 50%
|
||||
height: 4px
|
||||
border-top: 1px solid white
|
||||
border-bottom: 1px solid white
|
||||
width: 20px
|
||||
margin-left: -10px
|
||||
opacity: 0.8
|
||||
content: ''
|
||||
::v-deep
|
||||
|
||||
.v-event-timed:hover .v-event-drag-bottom::after
|
||||
display: block
|
||||
.vuecal__cells
|
||||
-ms-overflow-style: none
|
||||
scrollbar-width: none
|
||||
|
||||
.v-current-time
|
||||
height: 1px
|
||||
background-color: red
|
||||
position: absolute
|
||||
left: -1px
|
||||
right: 0
|
||||
pointer-events: none
|
||||
&::-webkit-scrollbar
|
||||
display: none
|
||||
|
||||
&.first::after
|
||||
content: ''
|
||||
position: absolute
|
||||
background-color: red
|
||||
width: 7px
|
||||
height: 7px
|
||||
border-radius: 3.5px
|
||||
margin-top: -3px
|
||||
margin-left: -3px
|
||||
.vuecal__body
|
||||
max-height: 100%
|
||||
overflow-y: scroll
|
||||
position: relative !important
|
||||
-ms-overflow-style: none
|
||||
scrollbar-width: none
|
||||
|
||||
&::-webkit-scrollbar
|
||||
display: none
|
||||
|
||||
.v-current-time-time
|
||||
display: none
|
||||
.weekday-label
|
||||
justify-content: start !important
|
||||
font-size: 24px
|
||||
font-weight: 700
|
||||
|
||||
.vuecal__weekdays-headings,
|
||||
.vuecal__cell:before
|
||||
border: none
|
||||
|
||||
&.first .v-current-time-time
|
||||
display: block
|
||||
position: absolute
|
||||
left: -60px
|
||||
color: red
|
||||
font-size: 10px
|
||||
padding: 1px
|
||||
background-color: white
|
||||
width: 50px
|
||||
height: 20px
|
||||
text-align: right
|
||||
top: -9px
|
||||
.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
|
||||
|
||||
.vuecal__flex
|
||||
flex-wrap: nowrap !important
|
||||
|
||||
.vuecal__cell
|
||||
padding: 10px 10px 10px 0px
|
||||
|
||||
.vuecal__cell--today
|
||||
background-color: rgba(0, 0, 0, .02) !important
|
||||
|
||||
.vuecal:not(.vuecal--day-view) .vuecal__cell--selected:not(.vuecal__cell--today) ,
|
||||
.vuecal__cell--current:not(.vuecal__cell--today)
|
||||
background-color: white
|
||||
|
||||
.vuecal__event
|
||||
border-radius: 16px
|
||||
padding: 20px 10px
|
||||
text-align: left
|
||||
|
||||
.vuecal__event-title
|
||||
text-align: left
|
||||
|
||||
&:hover
|
||||
z-index: 10
|
||||
|
||||
&.red
|
||||
background: #FFC9C9 !important
|
||||
|
||||
&.green
|
||||
background: #E9FFE5 !important
|
||||
|
||||
&.blue
|
||||
background: #DADEF8 !important
|
||||
|
||||
&.yellow
|
||||
background: #F6ECD3 !important
|
||||
</style>
|
||||
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<A-task-filter />
|
||||
<Z-timeline />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -15,4 +15,4 @@ export default {
|
||||
ZTimeline,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
Reference in new issue
Block a user