From c3d46d69327ede5623b5b8b0f552bf9ebcd7fb3f Mon Sep 17 00:00:00 2001 From: Urban Suppiger <urban@suppiger.net> Date: Sun, 29 Sep 2024 12:15:51 +0200 Subject: [PATCH] render checklists in react pdf --- .../scheduleEntry/contentNode/Checklist.vue | 98 +++++++++++++++++++ .../scheduleEntry/contentNode/ContentNode.vue | 2 + pdf/src/prepareInMainThread.js | 13 ++- 3 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 pdf/src/campPrint/scheduleEntry/contentNode/Checklist.vue diff --git a/pdf/src/campPrint/scheduleEntry/contentNode/Checklist.vue b/pdf/src/campPrint/scheduleEntry/contentNode/Checklist.vue new file mode 100644 index 0000000000..cd7dec4a51 --- /dev/null +++ b/pdf/src/campPrint/scheduleEntry/contentNode/Checklist.vue @@ -0,0 +1,98 @@ +<template> + <View class="content-node"> + <InstanceName :content-node="contentNode" /> + + <View v-for="entry in checklistsWithItems" class="checklist"> + <Text class="checklist-title">{{ entry.checklist.name }}</Text> + <View v-for="item in entry.items" class="checklist-item"> + <View class="checklist-item-column checklist-item-column-1"> + <Text>{{ item.number }}</Text> + </View> + <View class="checklist-item-column checklist-item-column-2"> + <Text>{{ item.text }}</Text> + </View> + </View> + </View> + </View> +</template> + +<script setup> +import uniqWith from 'lodash/uniqWith.js' +import sortBy from 'lodash/sortBy.js' + +const props = defineProps({ + contentNode: { type: Object, required: true }, +}) + +function calculateItemNumber(item) { + if (!item.parent) { + return item.position + 1 + } + + return calculateItemNumber(item.parent()) + '.' + (item.position + 1) +} +const items = props.contentNode.checklistItems().items.map((item) => { + const number = calculateItemNumber(item) + return { + ...item, + number, + } +}) + +const checklists = uniqWith( + props.contentNode + .checklistItems() + .items.map((checklistItem) => checklistItem.checklist()), + function (checklist1, checklist2) { + return checklist1._meta.self === checklist2._meta.self + } +) + +const checklistsWithItems = checklists.map((checklist) => ({ + checklist, + items: sortBy( + items.filter((item) => item.checklist()._meta.self === checklist._meta.self), + 'number' + ), +})) +</script> + +<script> +import PdfComponent from '@/PdfComponent.js' +import InstanceName from '../InstanceName.vue' + +export default { + name: 'Checklist', + components: { InstanceName }, + extends: PdfComponent, +} +</script> +<pdf-style> +.checklist { + display: flex; + flex-direction: column; + margin-bottom:8pt; +} +.checklist-title{ + font-weight:bold; + margin-bottom:3pt; + margin-top:2pt; +} +.checklist-item { + display: flex; + flex-direction: row; + padding-bottom:5pt; +} +.checklist-item-column { + flex-grow: 1; +} +.checklist-item-column-1 { + flex-basis: 300pt; + padding-right: 2pt; + font-variant-numeric: tabular-nums; +} +.checklist-item-column-2 { + flex-basis: 9700pt; + padding-left: 2pt; +} +</pdf-style> diff --git a/pdf/src/campPrint/scheduleEntry/contentNode/ContentNode.vue b/pdf/src/campPrint/scheduleEntry/contentNode/ContentNode.vue index 29d11ccc12..df1d078f29 100644 --- a/pdf/src/campPrint/scheduleEntry/contentNode/ContentNode.vue +++ b/pdf/src/campPrint/scheduleEntry/contentNode/ContentNode.vue @@ -18,6 +18,7 @@ import Notes from './Notes.vue' import SafetyConsiderations from './SafetyConsiderations.vue' import Material from './Material.vue' import Storycontext from './Storycontext.vue' +import Checklist from './Checklist.vue' export default { name: 'ContentNode', @@ -41,6 +42,7 @@ export default { SafetyConsiderations, Material, Storycontext, + Checklist, }[this.contentTypeName] }, }, diff --git a/pdf/src/prepareInMainThread.js b/pdf/src/prepareInMainThread.js index 15d71e252e..17e57a74ec 100644 --- a/pdf/src/prepareInMainThread.js +++ b/pdf/src/prepareInMainThread.js @@ -47,7 +47,11 @@ export async function prepareInMainThread(config) { } const activityData = (config) => { - if (!config.contents.some((c) => ['Program', 'Activity'].includes(c.type))) { + if ( + !config.contents.some((c) => + ['Program', 'Activity', 'ActivityList'].includes(c.type) + ) + ) { return [] } @@ -89,6 +93,13 @@ export async function prepareInMainThread(config) { }), camp.materialLists().$loadItems(), config.apiGet().contentTypes().$loadItems(), + camp.checklists().$loadItems(), + config + .apiGet() + .checklistItems({ + 'checklist.camp': camp._meta.self, + }) + .$loadItems(), ] }