Skip to content

Commit 6b9aa08

Browse files
Merge pull request #8470 from christianbeeznest/fixes-plugin-LearningCalendar01
Plugin: Improve Learning Calendar plugin UI and agenda integration
2 parents 18822ab + 43d9750 commit 6b9aa08

15 files changed

Lines changed: 1497 additions & 393 deletions

File tree

assets/vue/components/ccalendarevent/CCalendarEventInfo.vue

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,25 @@
2121
v-else-if="type.invitation === event.invitationType"
2222
:event="event"
2323
/>
24+
<div
25+
v-else-if="event.objectType === 'learning_calendar' && event.eventType"
26+
class="mt-2"
27+
>
28+
<strong>{{ t("Type") }}:</strong>
29+
{{ event.eventType }}
30+
</div>
31+
2432
<ShowLinks
2533
v-else
2634
:clickable-course="true"
2735
:item="event"
2836
:show-status="false"
2937
/>
3038

31-
<CalendarRemindersInfo :event="event" />
39+
<CalendarRemindersInfo
40+
v-if="event.objectType !== 'learning_calendar'"
41+
:event="event"
42+
/>
3243

3344
<div
3445
v-if="event.room"

assets/vue/composables/calendar/calendarEvent.js

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { DateTime } from "luxon"
22

33
import cCalendarEventService from "../../services/ccalendarevent"
4-
const { getCurrentTimezone } = useFormatDate()
5-
64
import { subscriptionVisibility, type } from "../../constants/entity/ccalendarevent"
75
import { useFormatDate } from "../formatDate"
86

7+
const { getCurrentTimezone } = useFormatDate()
8+
99
export function useCalendarEvent() {
1010
return {
1111
findUserLink,
@@ -80,25 +80,76 @@ function allowUnsubscribeToEvent(event, userId) {
8080
return !!findUserLink(event, userId)
8181
}
8282

83+
function mapCalendarEvent(event) {
84+
const timezone = getCurrentTimezone()
85+
const start = DateTime.fromISO(event.startDate, { zone: "utc" }).setZone(timezone)
86+
const end = DateTime.fromISO(event.endDate, { zone: "utc" }).setZone(timezone)
87+
88+
return {
89+
...event,
90+
start: start.toString(),
91+
end: end.toString(),
92+
color: event.color || "#007BFF",
93+
}
94+
}
95+
8396
/**
8497
* @param {Object} params
8598
* @returns {Promise<Object[]>}
8699
*/
87100
async function requestCalendarEvents(params) {
88101
const calendarEvents = await cCalendarEventService.findAll({ params }).then((response) => response.json())
89102

90-
return calendarEvents["hydra:member"].map((event) => {
91-
const timezone = getCurrentTimezone()
92-
const start = DateTime.fromISO(event.startDate, { zone: "utc" }).setZone(timezone)
93-
const end = DateTime.fromISO(event.endDate, { zone: "utc" }).setZone(timezone)
103+
return calendarEvents["hydra:member"].map(mapCalendarEvent)
104+
}
94105

95-
return {
96-
...event,
97-
start: start.toString(),
98-
end: end.toString(),
99-
color: event.color || "#007BFF",
100-
}
106+
function shouldLoadLearningCalendarEvents(commonParams) {
107+
if (!commonParams) {
108+
return true
109+
}
110+
111+
if (commonParams.cid || commonParams.sid || commonParams.gid || commonParams.type === "global") {
112+
return false
113+
}
114+
115+
return true
116+
}
117+
118+
/**
119+
* @param {Object} startDate
120+
* @param {Object} endDate
121+
* @param {Object} commonParams
122+
* @returns {Promise<Object[]>}
123+
*/
124+
async function requestLearningCalendarEvents(startDate, endDate, commonParams) {
125+
if (!shouldLoadLearningCalendarEvents(commonParams)) {
126+
return []
127+
}
128+
129+
const params = new URLSearchParams({
130+
startDate: startDate.toISOString(),
131+
endDate: endDate.toISOString(),
101132
})
133+
134+
try {
135+
const response = await fetch(`/plugin/LearningCalendar/my_events.php?${params.toString()}`, {
136+
credentials: "same-origin",
137+
headers: {
138+
Accept: "application/json",
139+
},
140+
})
141+
142+
if (!response.ok) {
143+
return []
144+
}
145+
146+
const payload = await response.json()
147+
const events = Array.isArray(payload.events) ? payload.events : []
148+
149+
return events.map(mapCalendarEvent)
150+
} catch (error) {
151+
return []
152+
}
102153
}
103154

104155
/**
@@ -126,17 +177,21 @@ async function getCalendarEvents(startDate, endDate, commonParams) {
126177
"startDate[after]": startDate.toISOString(),
127178
})
128179

129-
const [endingEvents, currentEvents, startingEvents] = await Promise.all([
180+
const learningCalendarEventsPromise = requestLearningCalendarEvents(startDate, endDate, commonParams)
181+
182+
const [endingEvents, currentEvents, startingEvents, learningCalendarEvents] = await Promise.all([
130183
endingEventsPromise,
131184
currentEventsPromise,
132185
startingEventsPromise,
186+
learningCalendarEventsPromise,
133187
])
134188

135189
const uniqueEventsMap = new Map()
136190

137191
endingEvents
138192
.concat(startingEvents)
139193
.concat(currentEvents)
194+
.concat(learningCalendarEvents)
140195
.forEach((event) => uniqueEventsMap.set(event.id, event))
141196

142197
return Array.from(uniqueEventsMap.values())

assets/vue/views/ccalendarevent/CCalendarEventList.vue

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,25 @@ const calendarOptions = ref({
667667
return
668668
}
669669
670+
if (event.extendedProps["objectType"] && event.extendedProps["objectType"] === "learning_calendar") {
671+
item.value = {
672+
...event.extendedProps,
673+
id: event.id,
674+
title: event.title,
675+
startDate: event.start ? new Date(event.start) : null,
676+
endDate: event.end ? new Date(event.end) : null,
677+
type: "personal",
678+
resourceLinkListFromEntity: [],
679+
}
680+
681+
allowToEdit.value = false
682+
allowToSubscribe.value = false
683+
allowToUnsubscribe.value = false
684+
dialogShow.value = true
685+
686+
return
687+
}
688+
670689
item.value = { ...event.extendedProps }
671690
672691
item.value["@id"] = "/api/c_calendar_events/" + event.id.match(/\d+$/)[0]

public/main/admin/settings.lib.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ function getStablePluginAllowList(): array
327327
'Static',
328328
'ShowUserInfo',
329329
'StudentFollowUp',
330+
'LearningCalendar',
330331
];
331332
}
332333

public/main/my_space/index.php

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -151,20 +151,27 @@
151151

152152
// 2) Extra actions: "View my progress", calendar plugin, certificates.
153153

154-
// Optional Learning Calendar plugin entry (teachers only).
155-
$pluginCalendar = 'true' === api_get_plugin_setting('learning_calendar', 'enabled');
156-
if ($pluginCalendar && api_is_teacher()) {
157-
$lpCalendar = \LearningCalendarPlugin::create();
158-
$actionsLeft .= Display::url(
159-
Display::getMdiIcon(
160-
'calendar-text',
161-
'ch-tool-icon',
162-
null,
163-
32,
164-
$lpCalendar->get_lang('Learning calendar')
165-
),
166-
api_get_path(WEB_PLUGIN_PATH).'LearningCalendar/start.php'
167-
);
154+
// Optional Learning Calendar plugin entry for users allowed to access reporting.
155+
$learningCalendarPluginPath = api_get_path(SYS_PLUGIN_PATH).'LearningCalendar/LearningCalendarPlugin.php';
156+
if (file_exists($learningCalendarPluginPath)) {
157+
require_once $learningCalendarPluginPath;
158+
}
159+
160+
$canAccessLearningCalendar = $allowToTrack || $is_drh || $is_coach;
161+
if (class_exists('LearningCalendarPlugin') && $canAccessLearningCalendar) {
162+
$learningCalendarPlugin = LearningCalendarPlugin::create();
163+
if ($learningCalendarPlugin->isEnabled()) {
164+
$actionsLeft .= Display::url(
165+
Display::getMdiIcon(
166+
'calendar-text',
167+
'ch-tool-icon',
168+
null,
169+
32,
170+
$learningCalendarPlugin->get_lang('LearningCalendar')
171+
),
172+
api_get_path(WEB_PLUGIN_PATH).'LearningCalendar/start.php'
173+
);
174+
}
168175
}
169176

170177
// Optional StudentFollowUp plugin entry for users allowed to access reporting.

0 commit comments

Comments
 (0)