diff --git a/api/src/Entity/ChecklistItem.php b/api/src/Entity/ChecklistItem.php index df737b9bc3..3c7148a00b 100644 --- a/api/src/Entity/ChecklistItem.php +++ b/api/src/Entity/ChecklistItem.php @@ -77,7 +77,7 @@ normalizationContext: ['groups' => ['read']], order: ['checklist.id', 'id'], )] -#[ApiFilter(filterClass: SearchFilter::class, properties: ['checklist', 'checklist.camp'])] +#[ApiFilter(filterClass: SearchFilter::class, properties: ['checklist', 'checklist.camp', 'checklistNodes'])] #[ORM\Entity(repositoryClass: ChecklistItemRepository::class)] #[ORM\UniqueConstraint(name: 'checklistitem_checklistid_parentid_position_unique', columns: ['checklistid', 'parentid', 'position'])] class ChecklistItem extends BaseEntity implements BelongsToCampInterface, CopyFromPrototypeInterface, HasParentInterface { diff --git a/api/tests/Api/ContentNodes/ChecklistNode/UpdateChecklistNodeTest.php b/api/tests/Api/ContentNodes/ChecklistNode/UpdateChecklistNodeTest.php index 679348df60..5de49c88b7 100644 --- a/api/tests/Api/ContentNodes/ChecklistNode/UpdateChecklistNodeTest.php +++ b/api/tests/Api/ContentNodes/ChecklistNode/UpdateChecklistNodeTest.php @@ -41,9 +41,7 @@ public function testAddChecklistItemForMember() { $this->assertJsonContains([ '_links' => [ 'checklistItems' => [ - 1 => [ - 'href' => '/checklist_items/'.$checklistItemId, - ], + 'href' => '/checklist_items?checklistNodes=%2Fcontent_node%2Fchecklist_nodes%2F'.$this->defaultEntity->getId(), ], ], ]); @@ -59,9 +57,7 @@ public function testAddChecklistItemForManager() { $this->assertJsonContains([ '_links' => [ 'checklistItems' => [ - 1 => [ - 'href' => '/checklist_items/'.$checklistItemId, - ], + 'href' => '/checklist_items?checklistNodes=%2Fcontent_node%2Fchecklist_nodes%2F'.$this->defaultEntity->getId(), ], ], ]); diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodechecklist_nodes__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodechecklist_nodes__1.json index 20693aaa9d..d5fd4f31c9 100644 --- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodechecklist_nodes__1.json +++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodechecklist_nodes__1.json @@ -3,7 +3,9 @@ "items": [ { "_links": { - "checklistItems": [], + "checklistItems": { + "href": "escaped_value" + }, "children": [], "contentType": { "href": "escaped_value" @@ -27,11 +29,9 @@ }, { "_links": { - "checklistItems": [ - { - "href": "escaped_value" - } - ], + "checklistItems": { + "href": "escaped_value" + }, "children": [], "contentType": { "href": "escaped_value" diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodes__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodes__1.json index f473304eb9..535611f336 100644 --- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodes__1.json +++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetCollectionMatchesStructure with data set content_nodes__1.json @@ -83,7 +83,9 @@ }, { "_links": { - "checklistItems": [], + "checklistItems": { + "href": "escaped_value" + }, "children": [], "contentType": { "href": "escaped_value" @@ -107,11 +109,9 @@ }, { "_links": { - "checklistItems": [ - { - "href": "escaped_value" - } - ], + "checklistItems": { + "href": "escaped_value" + }, "children": [], "contentType": { "href": "escaped_value" diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set activities__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set activities__1.json index 810a52ed1f..f53eb94757 100644 --- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set activities__1.json +++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set activities__1.json @@ -94,11 +94,9 @@ }, { "_links": { - "checklistItems": [ - { - "href": "escaped_value" - } - ], + "checklistItems": { + "href": "escaped_value" + }, "children": [], "contentType": { "href": "escaped_value" diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set content_nodechecklist_nodes__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set content_nodechecklist_nodes__1.json index 9b0796fa6f..37208473d1 100644 --- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set content_nodechecklist_nodes__1.json +++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testGetItemMatchesStructure with data set content_nodechecklist_nodes__1.json @@ -1,6 +1,8 @@ { "_links": { - "checklistItems": [], + "checklistItems": { + "href": "escaped_value" + }, "children": [], "contentType": { "href": "escaped_value" diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml index 6cfadfaaa9..f151f36d43 100644 --- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml +++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testOpenApiSpecMatchesSnapshot__1.yml @@ -25606,6 +25606,18 @@ paths: schema: type: string style: form + - + allowEmptyValue: false + allowReserved: false + deprecated: false + description: '' + explode: false + in: query + name: checklistNodes + required: false + schema: + type: string + style: form - allowEmptyValue: false allowReserved: false @@ -25620,6 +25632,20 @@ paths: type: string type: array style: form + - + allowEmptyValue: false + allowReserved: false + deprecated: false + description: '' + explode: true + in: query + name: 'checklistNodes[]' + required: false + schema: + items: + type: string + type: array + style: form - allowEmptyValue: false allowReserved: false @@ -26197,6 +26223,18 @@ paths: schema: type: string style: form + - + allowEmptyValue: false + allowReserved: false + deprecated: false + description: '' + explode: false + in: query + name: checklistNodes + required: false + schema: + type: string + style: form - allowEmptyValue: false allowReserved: false @@ -26211,6 +26249,20 @@ paths: type: string type: array style: form + - + allowEmptyValue: false + allowReserved: false + deprecated: false + description: '' + explode: true + in: query + name: 'checklistNodes[]' + required: false + schema: + items: + type: string + type: array + style: form - allowEmptyValue: false allowReserved: false diff --git a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testRootEndpointMatchesSnapshot__1.json b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testRootEndpointMatchesSnapshot__1.json index 31dba10323..037d9f603d 100644 --- a/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testRootEndpointMatchesSnapshot__1.json +++ b/api/tests/Api/SnapshotTests/__snapshots__/ResponseSnapshotTest__testRootEndpointMatchesSnapshot__1.json @@ -25,7 +25,7 @@ "templated": true }, "checklistItems": { - "href": "/checklist_items{/id}{?checklist,checklist[],checklist.camp,checklist.camp[]}", + "href": "/checklist_items{/id}{?checklist,checklist[],checklist.camp,checklist.camp[],checklistNodes,checklistNodes[]}", "templated": true }, "checklistNodes": { diff --git a/frontend/src/components/checklist/ChecklistItemParent.vue b/frontend/src/components/checklist/ChecklistItemParent.vue index 187a6fefa3..7bc1926990 100644 --- a/frontend/src/components/checklist/ChecklistItemParent.vue +++ b/frontend/src/components/checklist/ChecklistItemParent.vue @@ -66,43 +66,52 @@ export default { props: { checklistItem: { type: Object, required: true }, depth: { type: Number, required: true }, - allChecklistNodes: { type: Array, required: true }, }, data() { return { - checklistNodes: [], + activities: [], } }, - computed: { - activities() { - const camp = this.checklistItem.checklist().camp() - const activities = camp.activities().items + watch: { + checklistItem: { + async handler(checklistItem) { + const camp = checklistItem.checklist().camp() + + await camp.activities()._meta.load + const activities = await Promise.all( + camp.activities().items.map(async (a) => ({ + activity: a, + rootContentNodeUri: await a.$href('rootContentNode'), + })) + ) - // Activities ordered first ScheduleEntry start-time - return sortBy( - activities.filter((a) => - this.checklistNodes.some((cn) => cn.root().id === a.rootContentNode().id) - ), - (activity) => - activity - .scheduleEntries() - .items.map( - (s) => - `${s.dayNumber}`.padStart(3, '0') + - `${s.scheduleEntryNumber}`.padStart(3, '0') + const checklistNodes = await Promise.all( + checklistItem.checklistNodes().items.map(async (cn) => ({ + checklistNode: cn, + rootUri: await cn.$href('root'), + })) + ) + + // Activities ordered by first ScheduleEntry start time + const res = sortBy( + activities + .filter((a) => + checklistNodes.some((cn) => cn.rootUri == a.rootContentNodeUri) ) - .reduce((p, v) => (p < v ? p : v)) - ) - }, - }, - watch: { - allChecklistNodes: { - immediate: true, - handler(allChecklistNodes) { - this.checklistNodes = allChecklistNodes.filter((cn) => - cn.checklistItems().items.some((ci) => ci.id === this.checklistItem.id) + .map((a) => a.activity), + (activity) => + activity + .scheduleEntries() + .items.map( + (s) => + `${s.dayNumber}`.padStart(3, '0') + + `${s.scheduleEntryNumber}`.padStart(3, '0') + ) + .reduce((p, v) => (p < v ? p : v)) ) + this.activities = res }, + immediate: true, }, }, diff --git a/frontend/src/views/camp/checklistOverview/ChecklistOverview.vue b/frontend/src/views/camp/checklistOverview/ChecklistOverview.vue index e3018ccee3..48c0446978 100644 --- a/frontend/src/views/camp/checklistOverview/ChecklistOverview.vue +++ b/frontend/src/views/camp/checklistOverview/ChecklistOverview.vue @@ -16,7 +16,6 @@ :key="value?._meta.self" :checklist-item="value" :depth="depth" - :all-checklist-nodes="allChecklistNodes" /> @@ -42,7 +41,6 @@ export default { data() { return { loading: true, - allChecklistNodes: [], indexedChecklistItems: {}, } }, @@ -72,20 +70,13 @@ export default { await Promise.all([ this.camp.categories()._meta.load, this.camp.activities().$reload(), - this.api - .get() - .checklistNodes({ camp: this.camp._meta.self }) - .$reload() - .then((cns) => { - this.allChecklistNodes = cns.items - }), + this.api.get().checklistNodes({ camp: this.camp._meta.self }).$reload(), this.api .get() .checklistItems({ 'checklist.camp': this.camp._meta.self }) .$reload() .then(({ items }) => { this.processChecklistItems(items) - this.loading = false }), this.api .get() @@ -94,7 +85,9 @@ export default { camp: this.camp._meta.self, }) .$loadItems(), - ]) + ]).then(() => { + this.loading = false + }) }, methods: { processChecklistItems(items) {