From a395a4383c19bfb1e36a54a0fc4c2ef5af5b85db Mon Sep 17 00:00:00 2001 From: adisposkofh Date: Tue, 7 Jul 2026 10:51:11 +0200 Subject: [PATCH] initial work on displaying freebusy schedules in coodle --- .../api/frontend/v1/coodle/FreeBusy.php | 20 +++++++-- public/js/api/factory/coodle.js | 32 ++------------- public/js/api/factory/freeBusy.js | 28 ++++++------- .../CoodleSurvey/CoodleSurveyCalendar.js | 41 +++++++++++-------- .../CoodleSurvey/CoodleSurveyParticipants.js | 3 +- public/js/components/Cis/Coodle/Coodle.js | 2 +- 6 files changed, 61 insertions(+), 65 deletions(-) diff --git a/application/controllers/api/frontend/v1/coodle/FreeBusy.php b/application/controllers/api/frontend/v1/coodle/FreeBusy.php index 6a68c3585..03c0c2c42 100644 --- a/application/controllers/api/frontend/v1/coodle/FreeBusy.php +++ b/application/controllers/api/frontend/v1/coodle/FreeBusy.php @@ -33,6 +33,7 @@ class FreeBusy extends FHCAPI_Controller 'createFreeBusyEntry' => self::PERM_LOGGED, 'updateFreeBusyEntry' => self::PERM_LOGGED, 'deleteFreeBusyEntry' => self::PERM_LOGGED, + 'getFreeBusySchedule' => self::PERM_LOGGED, ]); $this->load->model('person/Freebusy_model', 'FreeBusyModel'); @@ -66,10 +67,9 @@ class FreeBusy extends FHCAPI_Controller $url = $this->input->post("url"); $isActive = $this->input->post("isActive"); - if (!$this->isValid($url)) { + if (!$this->isUrlValid($url)) { $this->terminateWithError("Could not open the provided URL!"); } - $this->addMeta("isValidUrl", $this->isValid($url)); $this->FreeBusyModel->insert( [ @@ -92,7 +92,7 @@ class FreeBusy extends FHCAPI_Controller $url = $this->input->post("url"); $isActive = $this->input->post("isActive"); - if (!$this->isValid($url)) { + if (!$this->isUrlValid($url)) { $this->terminateWithError("Could not open the provided URL!"); } @@ -133,10 +133,22 @@ class FreeBusy extends FHCAPI_Controller $this->terminateWithSuccess(); } + public function getFreeBusySchedule() + { + $uid = $this->input->post("uid"); + $freeBusyEntries = $this->FreeBusyModel->loadWhere(["uid" => $uid, "aktiv" => true]); + $freeBusyEntries = $this->getDataOrTerminateWithError($freeBusyEntries); + foreach ($freeBusyEntries as $freeBusyEntry) { + // + } + + $this->terminateWithSuccess($freeBusyEntries); + } + // ----------------------------------------------------------------------------------------------------------------- // Private methods - private function isValid($url) + private function isUrlValid($url) { return !!@fopen($url, "r"); } diff --git a/public/js/api/factory/coodle.js b/public/js/api/factory/coodle.js index 50c5cc3a4..c40b51aba 100644 --- a/public/js/api/factory/coodle.js +++ b/public/js/api/factory/coodle.js @@ -16,39 +16,13 @@ */ export default { - getFreeBusyUrls() { - return { - method: "get", - url: `/api/frontend/v1/coodle/FreeBusy/getFreeBusyUrls`, - }; - }, - createFreeBusyUrl(params) { + searchParticipants(searchString) { return { method: "post", - url: `/api/frontend/v1/coodle/FreeBusy/createFreeBusyUrl`, - params, - }; - }, - updateFreeBusyUrl(params) { - return { - method: "post", - url: `/api/frontend/v1/coodle/FreeBusy/updateFreeBusyUrl`, - params, - }; - }, - deleteFreeBusyUrl(id) { - return { - method: "post", - url: `/api/frontend/v1/coodle/FreeBusy/deleteFreeBusyUrl`, + url: "/api/frontend/v1/coodle/Coodle/searchParticipants", params: { - id, + searchString, }, }; }, - getFreeBusyTypes() { - return { - method: "get", - url: `/api/frontend/v1/coodle/FreeBusy/getFreeBusyTypes`, - }; - }, }; diff --git a/public/js/api/factory/freeBusy.js b/public/js/api/factory/freeBusy.js index cb0a3e3a8..ef12c7793 100644 --- a/public/js/api/factory/freeBusy.js +++ b/public/js/api/factory/freeBusy.js @@ -16,39 +16,30 @@ */ export default { - searchParticipants(searchString) { - return { - method: "post", - url: `/api/frontend/v1/coodle/Coodle/searchParticipants`, - params: { - searchString, - }, - }; - }, getFreeBusyEntries() { return { method: "get", - url: `/api/frontend/v1/coodle/FreeBusy/getFreeBusyEntries`, + url: "/api/frontend/v1/coodle/FreeBusy/getFreeBusyEntries", }; }, createFreeBusyEntry(params) { return { method: "post", - url: `/api/frontend/v1/coodle/FreeBusy/createFreeBusyEntry`, + url: "/api/frontend/v1/coodle/FreeBusy/createFreeBusyEntry", params, }; }, updateFreeBusyEntry(params) { return { method: "post", - url: `/api/frontend/v1/coodle/FreeBusy/updateFreeBusyEntry`, + url: "/api/frontend/v1/coodle/FreeBusy/updateFreeBusyEntry", params, }; }, deleteFreeBusyEntry(id) { return { method: "post", - url: `/api/frontend/v1/coodle/FreeBusy/deleteFreeBusyEntry`, + url: "/api/frontend/v1/coodle/FreeBusy/deleteFreeBusyEntry", params: { id, }, @@ -57,7 +48,16 @@ export default { getFreeBusyTypes() { return { method: "get", - url: `/api/frontend/v1/coodle/FreeBusy/getFreeBusyTypes`, + url: "/api/frontend/v1/coodle/FreeBusy/getFreeBusyTypes", + }; + }, + getFreeBusySchedule(uid) { + return { + method: "post", + url: "/api/frontend/v1/coodle/FreeBusy/getFreeBusySchedule", + params: { + uid, + }, }; }, }; diff --git a/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyCalendar.js b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyCalendar.js index 175ef281b..c85887e37 100644 --- a/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyCalendar.js +++ b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyCalendar.js @@ -3,6 +3,8 @@ import FhcCalendar from "../../../../Calendar/Base.js"; import ModeWeek from "../../../../Calendar/Mode/Week.js"; import ModeDay from "../../../../Calendar/Mode/Day.js"; +import FreeBusyApi from "../../../../../api/factory/freeBusy.js"; + import { numberPadding } from "../../../../../helpers/DateHelpers.js"; export default { @@ -30,7 +32,7 @@ export default { }, }, timeslotCalendarEvents: [], - cachedParticipantSchedules: {}, + participantSchedules: {}, isTimeslotCardEditInProgress: false, }; }, @@ -61,7 +63,7 @@ export default { ); participantsWithDisplayedSchedules.forEach((participant) => { let participantEvents = - this.cachedParticipantSchedules[participant.uid] ?? []; + this.participantSchedules[participant.uid] ?? []; participantEvents = participantEvents.map((event) => { event.farbe = this.$props.participantScheduleColors.find( @@ -160,15 +162,7 @@ export default { }, surveyFormDataParticipants: { handler() { - let participantsWithDisplayedSchedules = - this.$props.surveyFormDataParticipants.filter( - (participant) => participant.isCalendarShown, - ); - participantsWithDisplayedSchedules.forEach((participant) => { - if (!this.cachedParticipantSchedules[participant.uid]) { - this.fetchParticipantSchedule(participant.uid); - } - }); + this.updateDisplayedSchedules(); }, deep: true, }, @@ -305,16 +299,31 @@ export default { ); this.isTimeslotCardEditInProgress = false; }, - fetchParticipantSchedule(uid) { - // todo: fetch, format as events, add as array with uid as key to cachedParticipantSchedules - }, getEventStyle(event) { if (!event.farbe) return undefined; return "--event-bg:#" + event.farbe; }, onEventClick(clickEvent) { - console.log(clickEvent); - console.log(document.querySelector("#coodleCalendar .grid-body")); + // todo: remove + // console.log(clickEvent); + // console.log(document.querySelector("#coodleCalendar .grid-body")); + }, + updateDisplayedSchedules() { + let participantsWithDisplayedSchedules = + this.$props.surveyFormDataParticipants.filter( + (participant) => participant.isCalendarShown, + ); + participantsWithDisplayedSchedules.forEach((participant) => { + if (!(participant.uid in this.participantSchedules)) { + this.fetchFreeBusySchedule(participant.uid); + } + }); + }, + async fetchFreeBusySchedule(uid) { + this.participantSchedules[uid] = null; + const freeBusyScheduleResponse = await this.$api.call( + FreeBusyApi.getFreeBusySchedule(uid, 1, 1), + ); }, }, created() { diff --git a/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyParticipants.js b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyParticipants.js index 6386e478a..68e94e80f 100644 --- a/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyParticipants.js +++ b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyParticipants.js @@ -22,7 +22,6 @@ export default { // todo: increase depending on feedback warningGroupSize: 10, searchParticipantsAbortController: null, - // todo: increase searchParticipants: debounce(async () => { if (this.searchInput.length < 2) return; @@ -116,6 +115,8 @@ export default { ? searchResult.users : [searchResult]; this.addParticipants(addedParticipants); + this.searchInput = ""; + this.searchResults = []; }, addParticipants(newParticipants) { newParticipants = newParticipants diff --git a/public/js/components/Cis/Coodle/Coodle.js b/public/js/components/Cis/Coodle/Coodle.js index c1c9d5b37..317dae0a0 100644 --- a/public/js/components/Cis/Coodle/Coodle.js +++ b/public/js/components/Cis/Coodle/Coodle.js @@ -10,7 +10,7 @@ export default { return { uid: null, // todo: revert to default view active when dev done - view: "freeBusySettings", + view: "survey", survey: null, // todo: delete example survey after dev // survey: {