Skip to content

Commit

Permalink
Merge pull request #4202 from manuelmeister/feature/change-day-in-act…
Browse files Browse the repository at this point in the history
…ivity

Activity view: implement day switcher in sidebar
  • Loading branch information
pmattmann committed Dec 18, 2023
2 parents 45d4e38 + a4fb42b commit f2d0503
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 23 deletions.
131 changes: 131 additions & 0 deletions frontend/src/components/activity/DaySwitcher.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<template>
<v-list-item v-if="loading" class="pl-4 pr-0" inactive>
<v-list-item-title class="flex-grow-0 basis-auto flex-shrink-0">
<v-skeleton-loader type="text" width="3ch" class="v-skeleton-loader--no-margin" />
</v-list-item-title>
<v-list-item-subtitle class="basis-auto flex-shrink-0 ml-2">
<v-skeleton-loader type="text" class="v-skeleton-loader--no-margin" />
</v-list-item-subtitle>
<v-skeleton-loader
type="avatar"
width="28"
height="28"
class="v-skeleton-loader--no-margin v-skeleton-loader--inherit-size ml-6 mr-1"
/>
<v-icon>mdi-menu-down</v-icon>
</v-list-item>
<e-select
v-else
:value="daySelection.number"
:items="items"
item-value="number"
:filled="false"
return-object
:menu-props="{
offsetY: true,
contentClass: 'e-day-switcher__menu',
maxHeight: 'min(400px, calc(100vh - 32px))',
}"
input-class="e-day-switcher__select mt-0 pt-0"
@change="changeDay"
>
<template #selection="{ index, parent }">
<v-list-item
v-if="index === 0"
class="pl-4 pr-0"
inactive
@click.stop="parent.isMenuActive = !parent.isMenuActive"
>
<v-list-item-title class="flex-grow-0 basis-num flex-shrink-0 font-weight-bold">
{{ daySelection.number }}.
</v-list-item-title>
<v-list-item-subtitle class="basis-auto flex-shrink-0 ml-2">
{{ $date.utc(daySelection.start).format('dd. DD. MMM') }}
</v-list-item-subtitle>
<AvatarRow
:camp-collaborations="
daySelection
.dayResponsibles()
.items.map((responsible) => responsible.campCollaboration())
"
min-size="28"
max-size="28"
/>
</v-list-item>
</template>
<template #item="{ item: day, attrs, on }">
<v-list-item v-bind="attrs" v-on="on">
<v-list-item-title class="flex-grow-0 basis-num flex-shrink-0 font-weight-bold">
{{ day.number }}.
</v-list-item-title>
<v-list-item-subtitle class="basis-auto flex-shrink-0 ml-2">
{{ $date.utc(day.start).format('dd. DD. MMM') }}
</v-list-item-subtitle>
<AvatarRow
:camp-collaborations="
day
.dayResponsibles()
.items.map((responsible) => responsible.campCollaboration())
"
min-size="28"
max-size="28"
/>
</v-list-item>
</template>
</e-select>
</template>
<script>
import AvatarRow from '@/components/generic/AvatarRow.vue'
import { reduce, sortBy } from 'lodash'
export default {
name: 'DaySwitcher',
components: { AvatarRow },
props: {
camp: { type: Function, required: true },
daySelection: { type: Object, required: true },
loading: { type: Boolean },
},
computed: {
items() {
return reduce(
this.periods,
(result, period, index) => {
if (index > 0) {
result.push({ divider: true })
}
if (this.periods.length > 1) {
result.push({ header: period.description })
}
result.push(...sortBy(period.days().items, 'number'))
return result
},
[]
)
},
periods() {
return sortBy(this.camp().periods().items, 'start')
},
},
methods: {
changeDay(value) {
this.$emit('changeDay', value)
},
},
}
</script>

<style>
.basis-num {
flex-basis: 2.5ch;
}
.e-day-switcher__menu {
transform: translateX(-12px);
}
.e-day-switcher__select .v-input__append-inner {
align-self: center;
margin-top: 0;
}
</style>
6 changes: 5 additions & 1 deletion frontend/src/components/generic/AvatarRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ export default {
props: {
campCollaborations: { type: Array, default: () => [] },
maxSize: { type: [Number, String], default: 20 },
minSize: { type: [Number, String], default: 16 },
},
data: () => ({
maxHeight: 1000,
}),
computed: {
size() {
return Math.min(Number(this.maxSize), this.maxHeight)
return Math.min(
Number(this.maxSize),
Math.max(this.maxHeight, Number(this.minSize))
)
},
maxWidth() {
return this.campCollaborations?.length * (this.size * 0.5) + this.size
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/components/program/picasso/DayResponsibles.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ export default {
})
},
},
watch: {
// reset selectedCampCollaborations when date changes
date() {
this.oldSelectedCampCollaborations = [...this.currentCampCollaborationIRIs]
this.selectedCampCollaborations = [...this.currentCampCollaborationIRIs]
},
},
async mounted() {
await Promise.all([
this.period.camp().campCollaborations()._meta.load,
Expand Down
34 changes: 18 additions & 16 deletions frontend/src/components/program/picasso/Picasso.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,25 @@ Listing all given activity schedule entries in a calendar view.
>
<!-- day header -->
<template #day-label-header="{ date }">
<div class="e-picasso-daily_head-day-label">
{{
entryWidth > 140
? $date
.utc(date)
.format($tc('components.program.picasso.picasso.datetime.fullDate'))
: $date
.utc(date)
.format(
$tc(
'components.program.picasso.picasso.datetime.smallDate',
widthPluralization
<slot name="day-label-header" :date="date">
<div class="e-picasso-daily_head-day-label">
{{
entryWidth > 140
? $date
.utc(date)
.format($tc('components.program.picasso.picasso.datetime.fullDate'))
: $date
.utc(date)
.format(
$tc(
'components.program.picasso.picasso.datetime.smallDate',
widthPluralization
)
)
)
}}
</div>
<day-responsibles :date="date" :period="period" :readonly="!editable" />
}}
</div>
<day-responsibles :date="date" :period="period" :readonly="!editable" />
</slot>
</template>

<!-- template for single scheduleEntry -->
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,10 @@ export default new Router({
props: {
navigation: (route) => ({ camp: campFromRoute(route) }),
default: (route) => ({ scheduleEntry: scheduleEntryFromRoute(route) }),
aside: (route) => ({ day: dayFromScheduleEntryInRoute(route) }),
aside: (route) => ({
camp: campFromRoute(route),
day: dayFromScheduleEntryInRoute(route),
}),
},
},
{
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/scss/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ body {
margin-top: 12px;
}

.basis-auto {
flex-basis: auto !important;
}

.select-left .v-select__selections {
justify-content: flex-start !important;
}

.flex-full {
flex: 1 1 0;
}
Expand Down
42 changes: 37 additions & 5 deletions frontend/src/views/activity/SideBarProgram.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,26 @@
>
<ScheduleEntries :period="period" :show-button="false">
<template #default="slotProps">
<v-skeleton-loader v-if="slotProps.loading" class="ma-3" type="list-item@6" />
<DaySwitcher
:camp="camp"
:day-selection="daySelection"
:loading="slotProps.loading"
@changeDay="selectedDay = $event"
/>
<v-divider />
<v-skeleton-loader v-if="slotProps.loading" class="mx-1" type="list-item@6" />
<Picasso
v-else
class="ec-sidebar-program__picasso"
:schedule-entries="slotProps.scheduleEntries"
:period="period()"
:start="currentDayAsString"
:interval-height="36"
:end="currentDayAsString"
type="day"
/>
>
<template #day-label-header><span hidden></span></template>
</Picasso>
</template>
</ScheduleEntries>
</SideBar>
Expand All @@ -26,20 +36,42 @@ import SideBar from '@/components/navigation/SideBar.vue'
import ScheduleEntries from '@/components/program/ScheduleEntries.vue'
import { HTML5_FMT } from '@/common/helpers/dateFormat.js'
import DaySwitcher from '@/components/activity/DaySwitcher.vue'
export default {
name: 'SideBarProgram',
components: { SideBar, Picasso, ScheduleEntries },
components: { DaySwitcher, SideBar, Picasso, ScheduleEntries },
props: {
day: { type: Function, required: true },
camp: { type: Function, required: true },
},
data() {
return {
selectedDay: null,
}
},
computed: {
period() {
return this.day().period
return this.daySelection.period
},
daySelection() {
return this.selectedDay ?? this.day()
},
currentDayAsString() {
return this.$date.utc(this.day().start).format(HTML5_FMT.DATE)
return this.$date.utc(this.daySelection.start).format(HTML5_FMT.DATE)
},
},
}
</script>
<style scoped lang="scss">
.ec-sidebar-program__picasso :deep(.e-picasso) {
@media #{map-get($display-breakpoints, 'md-and-up')} {
height: calc(100vh - 202px);
}
}
.ec-sidebar-program__picasso :deep(.v-calendar-daily__head) {
display: none;
}
</style>

0 comments on commit f2d0503

Please sign in to comment.