Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Activity view: implement day switcher in sidebar #4202

Merged
merged 9 commits into from
Dec 18, 2023
106 changes: 106 additions & 0 deletions frontend/src/components/activity/DaySwitcher.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<template>
<v-list-item v-if="loading" class="px-3">
<v-list-item-title class="flex-grow-0 basis-auto flex-shrink-0">
<v-avatar color="rgba(0,0,0,0.1)" size="28">
<v-skeleton-loader type="text" width="12" class="v-skeleton-loader--no-margin" />
</v-avatar>
</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"
/>
</v-list-item>
<v-menu v-else offset-y>
<template #activator="{ on }">
<v-list-item class="px-3" v-on="on">
<v-list-item-title class="flex-grow-0 basis-auto flex-shrink-0">
<v-avatar color="rgba(0,0,0,0.07)" size="28">
{{ daySelection.number }}
</v-avatar>
</v-list-item-title>
<v-list-item-subtitle class="basis-auto flex-shrink-0 ml-2">
{{ $date.utc(daySelection.start).format('dd. DD.MM.') }}
</v-list-item-subtitle>
<AvatarRow
:camp-collaborations="
daySelection
.dayResponsibles()
.items.map((responsible) => responsible.campCollaboration())
"
min-size="28"
max-size="28"
/>
</v-list-item>
</template>
<v-sheet
v-for="({ days, period }, key, index) in mappedPeriodDays"
:key="key"
class="rounded-t"
>
<v-divider v-if="index > 0" />
<v-list>
<v-subheader v-if="periods.length > 1">{{ period.description }}</v-subheader>
<v-list-item
v-for="day in days"
:key="day._meta.self"
@click="$emit('changeDay', day)"
>
<v-list-item-title class="flex-grow-0 basis-auto flex-shrink-0">
<v-avatar
:color="
daySelection.id === day.id ? 'rgba(33,150,243,0.17)' : 'rgba(0,0,0,0.07)'
"
:class="
daySelection.id === day.id && 'font-weight-bold blue--text text--darken-4'
"
size="28"
>
{{ day.number }}
</v-avatar>
</v-list-item-title>
<v-list-item-subtitle class="basis-auto flex-shrink-0 ml-2" style="width: 72px">
{{ $date.utc(day.start).format('dd. DD.MM.') }}
</v-list-item-subtitle>
<AvatarRow
:camp-collaborations="
day
.dayResponsibles()
.items.map((responsible) => responsible.campCollaboration())
"
min-size="28"
max-size="28"
/>
</v-list-item>
</v-list>
</v-sheet>
</v-menu>
</template>
<script>
import AvatarRow from '@/components/generic/AvatarRow.vue'
import { keyBy, mapValues, sortBy } from 'lodash'

export default {
name: 'DaySwitcher',
components: { AvatarRow },
props: {
camp: { type: Function, required: true },
daySelection: { type: Object, required: true },
loading: { type: Boolean },
},
computed: {
mappedPeriodDays() {
return mapValues(keyBy(this.periods, '_meta.self'), (period) => {
return { period, days: sortBy(period.days().items, 'number') }
})
},
periods() {
return this.camp().periods().items
},
},
}
</script>
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>