team table, create team modal, delete team modal

This commit is contained in:
romankko2 committed 2022-11-25 23:15:34 +01:00
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>
&nbsp;
</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 -2
View File
@@ -2,7 +2,7 @@
<div>
<A-task-filter />
<Z-timeline />
</div>
</div>
</template>
<script>
@@ -15,4 +15,4 @@ export default {
ZTimeline,
},
}
</script>
</script>