Skip to content

Commit

Permalink
Merge pull request ecamp#3580 from usu/chore/period-dayResponsibles-f…
Browse files Browse the repository at this point in the history
…ilter

chore: add filter to query for all dayResponsibles of a period
  • Loading branch information
usu authored Jun 26, 2023
2 parents 5c16725 + 95be1e5 commit bd9d738
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 74 deletions.
2 changes: 1 addition & 1 deletion api/src/Entity/DayResponsible.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
denormalizationContext: ['groups' => ['write']],
normalizationContext: ['groups' => ['read']]
)]
#[ApiFilter(filterClass: SearchFilter::class, properties: ['day'])]
#[ApiFilter(filterClass: SearchFilter::class, properties: ['day', 'day.period'])]
#[UniqueEntity(
fields: ['campCollaboration', 'day'],
message: 'This campCollaboration (user) is already responsible for this day.',
Expand Down
13 changes: 13 additions & 0 deletions api/src/Entity/Period.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,19 @@ public function getContentNodes(): array {
return [];
}

/**
* A link to all the DayResponsibles in this period.
* The list is anyway replaced by a RelatedCollectionLink, thus we don't need to fetch the data now.
*
* @return DayResponsible[]
*/
#[ApiProperty(writable: false, example: '["/day_responsibles/1a2b3c4d"]')]
#[RelatedCollectionLink(DayResponsible::class, ['day.period' => '$this'])]
#[Groups(['read'])]
public function getDayResponsibles(): array {
return [];
}

/**
* @return MaterialItem[]
*/
Expand Down
2 changes: 2 additions & 0 deletions api/tests/Api/Periods/ReadPeriodTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public function testGetSinglePeriodIsAllowedForGuest() {
'materialItems' => ['href' => '/material_items?period=%2Fperiods%2F'.$period->getId()],
'days' => ['href' => '/days?period=%2Fperiods%2F'.$period->getId()],
'scheduleEntries' => ['href' => '/schedule_entries?period=%2Fperiods%2F'.$period->getId()],
'contentNodes' => ['href' => '/content_nodes?period=%2Fperiods%2F'.$period->getId()],
'dayResponsibles' => ['href' => '/day_responsibles?day.period=%2Fperiods%2F'.$period->getId()],
],
]);
}
Expand Down
102 changes: 69 additions & 33 deletions common/helpers/__tests__/dayResponsibles.spec.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,82 @@
import { dayResponsiblesCommaSeparated } from '../dayResponsibles'
import {
dayResponsiblesCommaSeparated,
filterDayResponsiblesByDay,
} from '../dayResponsibles'

describe('dayResponsibles', () => {
it('resolves camp collaboration with and without user', () => {
expect(
dayResponsiblesCommaSeparated(
const dayWith2Responsibles = {
_meta: {
self: '/day/1',
},
period: () => ({
dayResponsibles: () => ({
items: [
{
dayResponsibles: () => ({
items: [
{
campCollaboration: () => ({
inviteEmail: '[email protected]',
}),
},
{
campCollaboration: () => ({
user: () => ({
displayName: 'dummyUser',
}),
}),
},
],
campCollaboration: () => ({
inviteEmail: '[email protected]',
}),
day: () => ({
_meta: { self: '/day/1' },
}),
},
{
campCollaboration: () => ({
user: () => ({
displayName: 'dummyUser',
}),
}),
day: () => ({
_meta: { self: '/day/1' },
}),
},
null
)
).toEqual('[email protected], dummyUser')
})

it('return empty string if no resonsibles', () => {
expect(
dayResponsiblesCommaSeparated(
{
dayResponsibles: () => ({
items: [],
campCollaboration: () => ({
user: () => ({
displayName: 'responsibleUserOnAnotherDay',
}),
}),
day: () => ({
_meta: { self: '/day/2' },
}),
},
null
)
).toEqual('')
],
}),
}),
}

const dayWithoutResponsibles = {
period: () => ({
dayResponsibles: () => ({
items: [],
}),
}),
}

describe('dayResponsiblesCommaSeparated', () => {
it('resolves camp collaboration with and without user', () => {
expect(dayResponsiblesCommaSeparated(dayWith2Responsibles, null)).toEqual(
'[email protected], dummyUser'
)
})

it('return empty string if no responsibles', () => {
expect(dayResponsiblesCommaSeparated(dayWithoutResponsibles, null)).toEqual('')
})

it('return empty string for null object', () => {
expect(dayResponsiblesCommaSeparated(null, null)).toEqual('')
})
})

describe('filterDayResponsiblesByDay', () => {
it('resolves camp collaboration with and without user', () => {
expect(filterDayResponsiblesByDay(dayWith2Responsibles).length).toEqual(2)
})

it('return empty string if no responsibles', () => {
expect(filterDayResponsiblesByDay(dayWithoutResponsibles)).toEqual([])
})

it('return empty string for null object', () => {
expect(filterDayResponsiblesByDay(null)).toEqual([])
})
})
20 changes: 16 additions & 4 deletions common/helpers/dayResponsibles.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
import campCollaborationDisplayName from './campCollaborationDisplayName.js'

const dayResponsiblesCommaSeparated = (day, tc) => {
if (!day) return ''
/**
* Local filtering of dayResponsibles by day
* (avoids separate network request for each day)
*/
const filterDayResponsiblesByDay = (day) => {
if (!day) return []

return day
.period()
.dayResponsibles()
.items.map((dayResponsible) =>
.items.filter((dayResponsible) => dayResponsible.day()._meta.self === day._meta.self)
}

const dayResponsiblesCommaSeparated = (day, tc) => {
if (!day) return ''

return filterDayResponsiblesByDay(day)
.map((dayResponsible) =>
campCollaborationDisplayName(dayResponsible.campCollaboration(), tc)
)
.join(', ')
}

export { dayResponsiblesCommaSeparated }
export { filterDayResponsiblesByDay, dayResponsiblesCommaSeparated }
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,19 @@ import React from 'react'
import { Text, View } from '@react-pdf/renderer'
import dayjs from '@/common/helpers/dayjs.js'
import picassoStyles from './picassoStyles.js'
import campCollaborationDisplayName from '../../../../../common/helpers/campCollaborationDisplayName.js'
import {
dayResponsiblesCommaSeparated,
filterDayResponsiblesByDay,
} from '../../../../../common/helpers/dayResponsibles.js'

function renderDate(day) {
return dayjs.utc(day.start).hour(0).minute(0).second(0).format('ddd LL')
}

function dayResponsibles(day, $tc) {
const responsibles = day.dayResponsibles().items
if (responsibles.length === 0) return ''
if (filterDayResponsiblesByDay(day).length === 0) return ''
const label = $tc('entity.day.fields.dayResponsibles')
const displayNames = responsibles
.map((responsible) =>
campCollaborationDisplayName(responsible.campCollaboration(), $tc)
)
.join(', ')
const displayNames = dayResponsiblesCommaSeparated(day, $tc)
return `${label}: ${displayNames}`
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import DayHeader from './DayHeader.jsx'
import PicassoFooter from './PicassoFooter.jsx'
import YSLogo from './YSLogo.jsx'
import Categories from './Categories.jsx'
import { filterDayResponsiblesByDay } from '../../../../../common/helpers/dayResponsibles.js'

/**
* Generates an array of time row descriptions, used for labeling the vertical axis of the picasso.
Expand Down Expand Up @@ -38,7 +39,9 @@ function PicassoPage(props) {
const period = props.period
const days = props.days
const orientation = props.content.options.orientation
const anyDayResponsibles = days.some((day) => day.dayResponsibles().items.length > 0)
const anyDayResponsibles = days.some(
(day) => filterDayResponsiblesByDay(day).length > 0
)
const scheduleEntries = period.scheduleEntries().items
const times = generateTimes({
getUpTime: props.getUpTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,8 @@ const picassoData = (config) => {
return Promise.all([
period.scheduleEntries().$loadItems(),
period.contentNodes().$loadItems(),
period
.days()
.$loadItems()
.then((days) => {
return Promise.all(
days.items.map((day) => day.dayResponsibles().$loadItems())
)
}),
period.days().$loadItems(),
period.dayResponsibles().$loadItems(),
])
})
)
Expand Down
7 changes: 5 additions & 2 deletions print/components/PicassoChunk.vue
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@

<script>
import { activityResponsiblesCommaSeparated } from '@/../common/helpers/activityResponsibles.js'
import { dayResponsiblesCommaSeparated } from '@/../common/helpers/dayResponsibles.js'
import {
dayResponsiblesCommaSeparated,
filterDayResponsiblesByDay,
} from '@/../common/helpers/dayResponsibles.js'
import { contrastColor } from '@/../common/helpers/colors.js'
import CategoryLabel from './generic/CategoryLabel.vue'
import dayjs from '@/../common/helpers/dayjs.js'
Expand Down Expand Up @@ -225,7 +228,7 @@ export default {
hasDayResponsibles(date) {
const day = this.getDayByDate(date)
if (!day) return false
return day.dayResponsibles().items.length > 0
return filterDayResponsiblesByDay(day).length > 0
},
getDayByDate(date) {
Expand Down
26 changes: 9 additions & 17 deletions print/components/PicassoPeriod.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,26 +58,18 @@ export default {
)
}),
this.camp.categories().$loadItems(),
this.period.days().$loadItems(),
this.period
.days()
.dayResponsibles()
.$loadItems()
.then((days) => {
.then((dayResponsibles) => {
return Promise.all(
days.items.map((day) =>
day
.dayResponsibles()
.$loadItems()
.then((dayResponsibles) => {
return Promise.all(
dayResponsibles.items.map((dayResponsible) => {
if (dayResponsible.campCollaboration().user === null) {
return Promise.resolve(null)
}
return dayResponsible.campCollaboration().user()._meta.load
})
)
})
)
dayResponsibles.items.map((dayResponsible) => {
if (dayResponsible.campCollaboration().user === null) {
return Promise.resolve(null)
}
return dayResponsible.campCollaboration().user()._meta.load
})
)
}),
])
Expand Down

0 comments on commit bd9d738

Please sign in to comment.