From 6787e570407ef4b018281376ff3e8467c9706339 Mon Sep 17 00:00:00 2001 From: Felix Ruf Date: Tue, 6 Aug 2024 17:18:35 +0200 Subject: [PATCH 1/5] changed node variable to vite env variable --- src/Mealz/UserBundle/Entity/Profile.php | 6 +++++- src/Resources/src/components/menuParticipants/MenuTable.vue | 3 +-- .../src/components/participations/ParticipantsTableBody.vue | 3 +-- .../src/components/participations/ParticipationsTable.vue | 2 +- src/Resources/src/main.ts | 2 +- src/Resources/tsconfig.app.json | 4 ++-- src/Resources/vite.config.ts | 3 +++ 7 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Mealz/UserBundle/Entity/Profile.php b/src/Mealz/UserBundle/Entity/Profile.php index 141c7eb33..32f9915e4 100644 --- a/src/Mealz/UserBundle/Entity/Profile.php +++ b/src/Mealz/UserBundle/Entity/Profile.php @@ -98,7 +98,11 @@ public function setHidden(bool $hidden): void public function getFullName(): string { - return "$this->name, $this->firstName"; + $fullname = "$this->name, $this->firstName"; + if ($this->isGuest()) { + $fullname .= $this->getCompany() === '' || $this->getCompany() === null ? ' (Guest)' : " ($this->company)"; + } + return $fullname; } public function addRole(Role $role): static diff --git a/src/Resources/src/components/menuParticipants/MenuTable.vue b/src/Resources/src/components/menuParticipants/MenuTable.vue index 6b3d913e1..9222a41c9 100644 --- a/src/Resources/src/components/menuParticipants/MenuTable.vue +++ b/src/Resources/src/components/menuParticipants/MenuTable.vue @@ -20,7 +20,6 @@ import MenuTableBody from '@/components/menuParticipants/MenuTableBody.vue'; import MenuTableHead from './MenuTableHead.vue'; import { useProgress } from '@marcoschulte/vue3-progress'; import LoadingSpinner from '../misc/LoadingSpinner.vue'; -import process from 'node:process'; const props = defineProps<{ weekId: number; @@ -49,7 +48,7 @@ onMounted(async () => { }); // expose functions for testing -if (process?.env?.NODE_ENV === 'TEST') { +if (import.meta.env.VITE_ENV === 'TEST') { defineExpose({ loaded }); } diff --git a/src/Resources/src/components/participations/ParticipantsTableBody.vue b/src/Resources/src/components/participations/ParticipantsTableBody.vue index ece328517..a7ae2f4a4 100644 --- a/src/Resources/src/components/participations/ParticipantsTableBody.vue +++ b/src/Resources/src/components/participations/ParticipantsTableBody.vue @@ -21,7 +21,6 @@ import { type IBookedData, getShowParticipations } from '@/api/getShowParticipat import ParticipantsTableSlot from './ParticipantsTableSlot.vue'; import { computed, onMounted, onUnmounted, ref } from 'vue'; import { type Dictionary } from '@/types/types'; -import process from 'node:process'; const { participationsState, getMealsWithVariations, loadedState } = getShowParticipations(); @@ -116,7 +115,7 @@ function convertToIBookedData(participant: Dictionary): Dictionary< } // expose functions for testing -if (process?.env?.NODE_ENV === 'TEST') { +if (import.meta.env.VITE_ENV === 'TEST') { defineExpose({ scrollAmount, setScrollDirection, scrollDirectionDown, mealsWithVariations }); } diff --git a/src/Resources/src/components/participations/ParticipationsTable.vue b/src/Resources/src/components/participations/ParticipationsTable.vue index 11dfbe8cd..4ab11bca0 100644 --- a/src/Resources/src/components/participations/ParticipationsTable.vue +++ b/src/Resources/src/components/participations/ParticipationsTable.vue @@ -43,7 +43,7 @@ onUpdated(() => { } }); -if (process?.env?.NODE_ENV === 'TEST') { +if (import.meta.env.VITE_ENV === 'TEST') { defineExpose({ tableHeight }); } diff --git a/src/Resources/src/main.ts b/src/Resources/src/main.ts index d884d89d3..210da9a74 100644 --- a/src/Resources/src/main.ts +++ b/src/Resources/src/main.ts @@ -27,7 +27,7 @@ const i18n = createI18n({ // fill stores with data Promise.all([userDataStore.fillStore(), environmentStore.fillStore()]).then(() => { const MainApp = createApp(App); - MainApp.config.performance = process.env.NODE_ENV !== 'production'; // enable Vue Devtools + MainApp.config.performance = import.meta.env.VITE_ENV !== 'production'; // enable Vue Devtools MainApp.use(i18n); MainApp.use(router); MainApp.use(VueScreen); diff --git a/src/Resources/tsconfig.app.json b/src/Resources/tsconfig.app.json index 8694d00ba..31154f4ed 100644 --- a/src/Resources/tsconfig.app.json +++ b/src/Resources/tsconfig.app.json @@ -23,8 +23,8 @@ "strict": true, "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2022", - "types": ["node"], - "typeRoots": ["./node_modules/@types", "./src/types"], + "types": ["node", "vite/client"], + "typeRoots": ["./node_modules/@types", "./src/types", "./node_modules"], "useDefineForClassFields": true, "baseUrl": ".", diff --git a/src/Resources/vite.config.ts b/src/Resources/vite.config.ts index 0d82cd05c..070230da5 100644 --- a/src/Resources/vite.config.ts +++ b/src/Resources/vite.config.ts @@ -36,6 +36,9 @@ export default defineConfig({ '@': fileURLToPath(new URL('./src', import.meta.url)) } }, + define: { + 'import.meta.env.VITE_ENV': JSON.stringify(process.env.NODE_ENV) + }, server: { host: true, port: 5173, From d69ce7828bf1a50de9e7bfa282b1dd70064f3b05 Mon Sep 17 00:00:00 2001 From: Felix Ruf Date: Wed, 7 Aug 2024 11:21:43 +0200 Subject: [PATCH 2/5] added Guest label to displayed lists of participants --- .gitignore | 1 - .../MealBundle/Controller/ApiController.php | 11 ++--------- .../Controller/ParticipantController.php | 4 ++-- .../MealBundle/Helper/ParticipationHelper.php | 14 ++++++++++++-- .../Service/ParticipationService.php | 18 +++++++++++++++++- src/Mealz/UserBundle/Entity/Profile.php | 6 +----- src/Resources/env.d.ts | 1 + .../src/api/getParticipationsByDay.ts | 13 ++++++++++--- .../src/components/dashboard/MealData.vue | 1 + .../components/dashboard/VariationsData.vue | 1 + .../src/components/dishes/DishTableRow.vue | 4 ++-- .../eventParticipation/EventPopup.vue | 2 +- .../src/components/guest/GuestMeal.vue | 1 + .../src/components/guest/GuestVariation.vue | 1 + .../AddParticipantsSearchBar.vue | 9 +-------- .../menuParticipants/MenuTableBody.vue | 10 ++++++++-- .../src/components/misc/VeggiIcon.vue | 2 +- .../participations/ParticipantsListByDay.vue | 14 ++++++++------ .../participations/ParticipantsTableRow.vue | 3 ++- src/Resources/src/locales/en.json | 2 +- .../src/services/filterParticipantsList.ts | 10 ++++++---- .../src/services/useConvertDisplayName.ts | 10 ++++++++++ src/Resources/src/stores/profilesStore.ts | 17 ++++++++++++++++- src/Resources/src/views/PrintableList.vue | 3 ++- src/Resources/tsconfig.node.json | 4 ++-- 25 files changed, 109 insertions(+), 53 deletions(-) create mode 100644 src/Resources/env.d.ts create mode 100644 src/Resources/src/services/useConvertDisplayName.ts diff --git a/.gitignore b/.gitignore index b8c69ec88..57bb6717a 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,6 @@ node_modules ###< friendsofphp/php-cs-fixer ### /src/Resources/style/output.css -/**/*.d.ts /src/Resources/style/output.css.map test_ci_cypress.sh tests/e2e/cypress/videos/ diff --git a/src/Mealz/MealBundle/Controller/ApiController.php b/src/Mealz/MealBundle/Controller/ApiController.php index 2db121da2..78e0db763 100644 --- a/src/Mealz/MealBundle/Controller/ApiController.php +++ b/src/Mealz/MealBundle/Controller/ApiController.php @@ -200,16 +200,9 @@ public function listParticipantsByDate(DateTime $date): JsonResponse return new JsonResponse(['message' => 'Day not found'], 404); } - $list = []; - $data = $this->participationSrv->getParticipationList($day); + $participants = $this->participationSrv->getParticipationList($day); - foreach ($data as $participant) { - $list[] = $participant->getProfile()->getFirstName() . ' ' . $participant->getProfile()->getName(); - } - - $uniqueArray = array_unique($list); - - return new JsonResponse(array_values($uniqueArray), 200); + return new JsonResponse($participants, 200); } private function addSlots(array &$slotArray, array $slots, Day $day, ?int $activeParticipations): void diff --git a/src/Mealz/MealBundle/Controller/ParticipantController.php b/src/Mealz/MealBundle/Controller/ParticipantController.php index c58397903..c6a1c148e 100644 --- a/src/Mealz/MealBundle/Controller/ParticipantController.php +++ b/src/Mealz/MealBundle/Controller/ParticipantController.php @@ -438,8 +438,8 @@ private function addParticipationInfo(array $response, ArrayCollection $particip /** @var Participant $participant */ foreach ($participants as $participant) { $participationData = $this->participationHelper->getParticipationMealData($participant); - $response[$day->getId()][$participant->getProfile()->getFullName()]['booked'][] = $participationData; - $response[$day->getId()][$participant->getProfile()->getFullName()]['profile'] = $participant->getProfile()->getUsername(); + $response[$day->getId()][$this->participationHelper->getParticipantName($participant)]['booked'][] = $participationData; + $response[$day->getId()][$this->participationHelper->getParticipantName($participant)]['profile'] = $participant->getProfile()->getUsername(); } return $response; diff --git a/src/Mealz/MealBundle/Helper/ParticipationHelper.php b/src/Mealz/MealBundle/Helper/ParticipationHelper.php index 96804efbb..592f53030 100644 --- a/src/Mealz/MealBundle/Helper/ParticipationHelper.php +++ b/src/Mealz/MealBundle/Helper/ParticipationHelper.php @@ -115,6 +115,16 @@ public function getParticipationMealData(Participant $participant): array return $participationData; } + public function getParticipantName(Participant $participant): string + { + $fullname = $participant->getProfile()->getFullName(); + if (true === $participant->getProfile()->isGuest()) { + $fullname .= ' (Guest)'; + } + + return $fullname; + } + protected function compareNameOfParticipants(Participant $participant1, Participant $participant2): int { $result = strcasecmp($participant1->getProfile()->getName(), $participant2->getProfile()->getName()); @@ -144,7 +154,7 @@ private function getParticipationbySlot(Participant $participant, ?Slot $slot, b $combinedDishes = $this->getCombinedDishesFromMeal($meal, $participant); if (true === $meal->isParticipant($participant) && (null === $slot || $slot->isDisabled() || $slot->isDeleted())) { - $slots[''][$participant->getProfile()->getFullName()] = $this->getParticipationData( + $slots[''][$this->getParticipantName($participant)] = $this->getParticipationData( $meal, $profile, $participant, @@ -154,7 +164,7 @@ private function getParticipationbySlot(Participant $participant, ?Slot $slot, b } if (true === $meal->isParticipant($participant)) { - $slots[$slot->getTitle()][$participant->getProfile()->getFullName()] = $this->getParticipationData( + $slots[$slot->getTitle()][$this->getParticipantName($participant)] = $this->getParticipationData( $meal, $profile, $participant, diff --git a/src/Mealz/MealBundle/Service/ParticipationService.php b/src/Mealz/MealBundle/Service/ParticipationService.php index b9b773d9f..f6b0c8291 100644 --- a/src/Mealz/MealBundle/Service/ParticipationService.php +++ b/src/Mealz/MealBundle/Service/ParticipationService.php @@ -248,7 +248,23 @@ public function getCountByMeal(Meal $meal, bool $withoutCombined = false): int public function getParticipationList(Day $day): array { - return $this->participantRepo->getParticipantsByDay($day->getDateTime(), ['load_meal' => false]); + $participants = $this->participantRepo->getParticipantsByDay($day->getDateTime(), ['load_meal' => false]); + + $profiles = array_map( + fn ($participant) => $participant->getProfile(), + $participants + ); + + $profileData = array_map( + fn ($profile) => [ + 'user' => $profile->getUsername(), + 'fullName' => $profile->getFullName(), + 'roles' => $profile->getRoles(), + ], + array_unique($profiles) + ); + + return $profileData; } /** diff --git a/src/Mealz/UserBundle/Entity/Profile.php b/src/Mealz/UserBundle/Entity/Profile.php index 32f9915e4..141c7eb33 100644 --- a/src/Mealz/UserBundle/Entity/Profile.php +++ b/src/Mealz/UserBundle/Entity/Profile.php @@ -98,11 +98,7 @@ public function setHidden(bool $hidden): void public function getFullName(): string { - $fullname = "$this->name, $this->firstName"; - if ($this->isGuest()) { - $fullname .= $this->getCompany() === '' || $this->getCompany() === null ? ' (Guest)' : " ($this->company)"; - } - return $fullname; + return "$this->name, $this->firstName"; } public function addRole(Role $role): static diff --git a/src/Resources/env.d.ts b/src/Resources/env.d.ts new file mode 100644 index 000000000..151aa6856 --- /dev/null +++ b/src/Resources/env.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file diff --git a/src/Resources/src/api/getParticipationsByDay.ts b/src/Resources/src/api/getParticipationsByDay.ts index 2e317160c..a59c408c8 100644 --- a/src/Resources/src/api/getParticipationsByDay.ts +++ b/src/Resources/src/api/getParticipationsByDay.ts @@ -1,4 +1,6 @@ import useApi from '@/api/api'; +import type { IProfile } from '@/stores/profilesStore'; +import type { Dictionary } from '@/types/types'; import { onMounted, readonly, ref } from 'vue'; /** @@ -7,7 +9,7 @@ import { onMounted, readonly, ref } from 'vue'; * @returns list of participants */ export function useParticipationsListData(date: string) { - const listDataState = ref([]); + const listDataState = ref([]); const loaded = ref(false); const useParticipationsError = ref(false); @@ -20,16 +22,21 @@ export function useParticipationsListData(date: string) { return; } - const { error, response: listData, request } = useApi('GET', `/api/participations/day/${date}`); + const { + error, + response: listData, + request + } = useApi>('GET', `/api/participations/day/${date}`); useParticipationsError.value = error.value; if (loaded.value === false) { await request(); loaded.value = true; - listDataState.value = listData.value as string[]; + listDataState.value = Object.values(listData.value ?? {}); } } + return { useParticipationsError, listData: readonly(listDataState), diff --git a/src/Resources/src/components/dashboard/MealData.vue b/src/Resources/src/components/dashboard/MealData.vue index e4c111793..2f49f3ed2 100644 --- a/src/Resources/src/components/dashboard/MealData.vue +++ b/src/Resources/src/components/dashboard/MealData.vue @@ -11,6 +11,7 @@ {{ title }} diff --git a/src/Resources/src/components/dashboard/VariationsData.vue b/src/Resources/src/components/dashboard/VariationsData.vue index 2463f90ef..66cc12f3a 100644 --- a/src/Resources/src/components/dashboard/VariationsData.vue +++ b/src/Resources/src/components/dashboard/VariationsData.vue @@ -18,6 +18,7 @@ {{ locale.substring(0, 2) === 'en' ? variation.title.en : variation.title.de }} diff --git a/src/Resources/src/components/dishes/DishTableRow.vue b/src/Resources/src/components/dishes/DishTableRow.vue index cae0d1493..e3c908c9d 100644 --- a/src/Resources/src/components/dishes/DishTableRow.vue +++ b/src/Resources/src/components/dishes/DishTableRow.vue @@ -12,7 +12,7 @@ { if (showParticipations.value === true) { isLoading.value = true; - participations.value = (await getParticipantsForEvent(props.date)) as string[]; + participations.value = ((await getParticipantsForEvent(props.date)) as string[]).sort(); isLoading.value = false; } }); diff --git a/src/Resources/src/components/guest/GuestMeal.vue b/src/Resources/src/components/guest/GuestMeal.vue index f705bc201..5006d92d7 100644 --- a/src/Resources/src/components/guest/GuestMeal.vue +++ b/src/Resources/src/components/guest/GuestMeal.vue @@ -8,6 +8,7 @@ {{ title }} diff --git a/src/Resources/src/components/guest/GuestVariation.vue b/src/Resources/src/components/guest/GuestVariation.vue index b10acd144..78e550a4e 100644 --- a/src/Resources/src/components/guest/GuestVariation.vue +++ b/src/Resources/src/components/guest/GuestVariation.vue @@ -18,6 +18,7 @@ {{ locale.substring(0, 2) === 'en' ? variation.title.en : variation.title.de }} diff --git a/src/Resources/src/components/menuParticipants/AddParticipantsSearchBar.vue b/src/Resources/src/components/menuParticipants/AddParticipantsSearchBar.vue index 86283b818..9760a8d70 100644 --- a/src/Resources/src/components/menuParticipants/AddParticipantsSearchBar.vue +++ b/src/Resources/src/components/menuParticipants/AddParticipantsSearchBar.vue @@ -92,7 +92,7 @@ const props = defineProps<{ weekId: number; }>(); -const { ProfilesState, fetchAbsentingProfiles } = useProfiles(props.weekId); +const { ProfilesState, fetchAbsentingProfiles, getDisplayName } = useProfiles(props.weekId); const { t } = useI18n(); const slot = useSlots(); @@ -130,13 +130,6 @@ const filteredProfiles = computed(() => { }); }); -function getDisplayName(profile: IProfile) { - if (profile.roles.includes('ROLE_GUEST')) { - return `(${t('menu.guest')}) ${profile.fullName}`; - } - return profile.fullName; -} - function handleClick() { openProp.value = true; useDetectClickOutside(combobox, () => (openProp.value = false)); diff --git a/src/Resources/src/components/menuParticipants/MenuTableBody.vue b/src/Resources/src/components/menuParticipants/MenuTableBody.vue index 346589bcb..785453f28 100644 --- a/src/Resources/src/components/menuParticipants/MenuTableBody.vue +++ b/src/Resources/src/components/menuParticipants/MenuTableBody.vue @@ -32,6 +32,7 @@ import { useI18n } from 'vue-i18n'; import MenuTableRow from './MenuTableRow.vue'; import MenuTableDataRows from '@/components/menuParticipants/MenuTableDataRows.vue'; import { computed } from 'vue'; +import getDisplayName from '@/services/useConvertDisplayName'; const props = defineProps<{ weekId: number; @@ -43,7 +44,12 @@ const { t } = useI18n(); const participants = computed(() => getParticipants()); const filteredParticipants = computed(() => { - if (getFilter() === '') return participants.value; - return participants.value.filter((participant) => participant.toLowerCase().includes(getFilter().toLowerCase())); + if (getFilter() === '') { + return participants.value.map((participant) => getDisplayName(participant)); + } + + return participants.value + .filter((participant) => participant.toLowerCase().includes(getFilter().toLowerCase())) + .map((participant) => getDisplayName(participant)); }); diff --git a/src/Resources/src/components/misc/VeggiIcon.vue b/src/Resources/src/components/misc/VeggiIcon.vue index fb3c9931a..3a82425ca 100644 --- a/src/Resources/src/components/misc/VeggiIcon.vue +++ b/src/Resources/src/components/misc/VeggiIcon.vue @@ -1,5 +1,5 @@ +
+ {{ t('flashMessage.success.participations.no') }} +
diff --git a/src/Resources/src/components/participations/ParticipantsTableRow.vue b/src/Resources/src/components/participations/ParticipantsTableRow.vue index 5c946fd5c..1e99bd0d0 100644 --- a/src/Resources/src/components/participations/ParticipantsTableRow.vue +++ b/src/Resources/src/components/participations/ParticipantsTableRow.vue @@ -6,7 +6,7 @@ >
- {{ getDisplayName(participantName) }} + {{ getDisplayName(participantName, t) }} string ) { if (fullname.includes('(Guest)')) { return `${fullname.split(' (Guest)')[0]} (${t('menu.guest')})`; } From 1af596078d918a2aa256ac686dd67aea9f02627e Mon Sep 17 00:00:00 2001 From: Felix Ruf Date: Wed, 7 Aug 2024 11:44:32 +0200 Subject: [PATCH 4/5] fixed typing issue --- src/Resources/src/services/useConvertDisplayName.ts | 2 +- src/Resources/src/views/PrintableList.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Resources/src/services/useConvertDisplayName.ts b/src/Resources/src/services/useConvertDisplayName.ts index 1fb9502ac..8eb04ec58 100644 --- a/src/Resources/src/services/useConvertDisplayName.ts +++ b/src/Resources/src/services/useConvertDisplayName.ts @@ -1,4 +1,4 @@ -export default function getDisplayName(fullname: string, t: (str: string) => string ) { +export default function getDisplayName(fullname: string, t: (str: string) => string) { if (fullname.includes('(Guest)')) { return `${fullname.split(' (Guest)')[0]} (${t('menu.guest')})`; } diff --git a/src/Resources/src/views/PrintableList.vue b/src/Resources/src/views/PrintableList.vue index 6f0c77e7c..aa19efcf5 100644 --- a/src/Resources/src/views/PrintableList.vue +++ b/src/Resources/src/views/PrintableList.vue @@ -77,7 +77,7 @@ :class="[index === 0 ? 'border-gray-300' : 'border-gray-200', 'border-t']" > - {{ getDisplayName(String(participantName)) }} + {{ getDisplayName(String(participantName), t) }} Date: Wed, 7 Aug 2024 11:55:58 +0200 Subject: [PATCH 5/5] another fix for broken cypress test --- tests/e2e/cypress/e2e/GuestInvitation.cy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/cypress/e2e/GuestInvitation.cy.ts b/tests/e2e/cypress/e2e/GuestInvitation.cy.ts index 2e3ebba94..3cd370998 100644 --- a/tests/e2e/cypress/e2e/GuestInvitation.cy.ts +++ b/tests/e2e/cypress/e2e/GuestInvitation.cy.ts @@ -86,7 +86,7 @@ describe('Test GuestEventInvitation', () => { .parent() .find('table') .find('td') - .contains('John Doe'); + .contains('(Gast) Doe, John'); }); }); }); \ No newline at end of file