Änderungen von Dokument Calendar Macro

Zuletzt geändert von xwikiadmin am 2025/12/11 06:30

Von Version 8.1
bearbeitet von xwikiadmin
am 2025/12/03 10:04
Änderungskommentar: Install extension [com.xwiki.mocca-calendar:application-mocca-calendar-ui/2.18.0]
Auf Version 4.1
bearbeitet von xwikiadmin
am 2024/06/24 14:25
Änderungskommentar: Install extension [com.xwiki.mocca-calendar:application-mocca-calendar-ui/2.13.3]

Zusammenfassung

Details

XWiki.JavaScriptExtension[0]
Code
... ... @@ -1,11 +1,5 @@
1 -require.config({
2 - paths: {
3 - purify: "$services.webjars.url('org.webjars.npm:dompurify', 'dist/purify.js')"
4 - },
5 -});
1 +define('moccaCalendar', ['jquery', 'fullcalendar', 'moment'], function(jQuery, fullCalendar, moment) {
6 6  
7 -define('moccaCalendar', ['jquery', 'fullcalendar', 'moment', 'purify'], function(jQuery, fullCalendar, moment, purify) {
8 -
9 9  // Make sure the XWiki 'namespace' and the ModalPopup class exist.
10 10  if (typeof(XWiki) == "undefined" || typeof(XWiki.widgets) == "undefined" || typeof(XWiki.widgets.ModalPopup) == "undefined") {
11 11   if (typeof console != "undefined" && typeof console.warn == "function") {
... ... @@ -16,6 +16,8 @@
16 16   XWiki.MoccaCalendar = {};
17 17   }
18 18  
13 +#template('colorThemeInit.vm')
14 +
19 19   XWiki.MoccaCalendar.Helper = Class.create({
20 20   initialize: function(calendar, dateFormat, jsonServiceUrl, createEventBaseUrl, updateEventUrl, newPageNameUrl, dateCheckUrl, deleteEventInstanceUrl, newPageParams, formToken) {
21 21   this.calendar = calendar;
... ... @@ -38,9 +38,6 @@
38 38   this.timeFormat = '';
39 39   this.dayFormat = dateFormat;
40 40   }
41 - document.addEventListener('calendarImportCompleted', () => {
42 - calendar.fullCalendar('refetchEvents');
43 - });
44 44   },
45 45   displayError: function(errorMessage) {
46 46   if (!errorMessage) {
... ... @@ -128,12 +128,6 @@
128 128   document.cookie = cookieName + value + "; path=/";
129 129   };
130 130  
131 - function removeColorPickers() {
132 - jQuery('#mocca-event-edit-form .color-picker').each(function(index) {
133 - jQuery('#' + jQuery(this).data('colpickId')).remove();
134 - });
135 - }
136 -
137 137   //
138 138   // the dialog to show / edit events
139 139   //
... ... @@ -149,7 +149,7 @@
149 149   // call constructor from ModalPopup with params content, shortcuts, options
150 150   $super(
151 151   // this element will end up as 'this.content'
152 - new Element('form', {'class' : 'xform', 'id' : 'mocca-event-edit-form'}),
139 + new Element('form', {'class' : 'xform'}),
153 153   {
154 154   "show": {method: this.showDialog, keys: []},
155 155   "close": {method: this.closeDialog, keys: ['Esc']}
... ... @@ -156,10 +156,10 @@
156 156   },
157 157   {
158 158   verticalPosition: "top",
146 + backgroundColor: "$theme.pageHeaderBackgroundColor",
159 159   title : this.interactionParameters.editMode ? "$escapetool.javascript($services.localization.render('MoccaCalendar.calendarevent.create'))" : "$escapetool.javascript($services.localization.render('MoccaCalendar.calendarevent.view'))",
160 160   removeOnClose : true,
161 161   onClose : function() {
162 - removeColorPickers();
163 163   document.stopObserving('xwiki:moccacalendar:editmode');
164 164   document.stopObserving('xwiki:moccacalendar:instancesaved');
165 165   }
... ... @@ -200,7 +200,6 @@
200 200   // and we only listen for the results to close the dialog
201 201   document.observe('xwiki:moccacalendar:instancesaved', function(event) {
202 202   this.savedBox.show();
203 - removeColorPickers();
204 204   this.closeDialog();
205 205   this.helper.calendar.fullCalendar('refetchEvents');
206 206   }.bind(this));
... ... @@ -296,32 +296,12 @@
296 296   } else {
297 297   saveUrl = this.interactionParameters.event.saveUrl;
298 298   }
299 - this.content.title.value = purify.sanitize(this.content.title.value)
300 300   this.content.writeAttribute('action', saveUrl + '&xpage=plain&ajax=true');
301 - let formData = new FormData(this.content);
302 - if (formData.get('MoccaCalendar.MoccaCalendarEventClass_0_allDay') == 1) {
303 - this.content.querySelectorAll('input.datetime').forEach(dateInput => {
304 - // Convert the date fields from the displayed format to the one accepted by the backend.
305 - const dateObj = moment(dateInput.value, moment().toMomentFormatString(dateInput.getAttribute('data-format')));
306 - if (dateInput.id == "MoccaCalendar.MoccaCalendarEventClass_0_endDate") {
307 - // For the end date, set the hour to 23:59 instead of 00:00.
308 - dateObj.hours(23);
309 - dateObj.minutes(59);
310 - }
311 - const calendarEventObjectDateFormat = moment().toMomentFormatString(this.helper.dateFormat);
312 - // Add a hidden element to the DOM to avoid flickering.
313 - const tempElement = dateInput.clone();
314 - tempElement.addClassName('hidden');
315 - tempElement.value = dateObj.isValid() ? dateObj.format(calendarEventObjectDateFormat) : "";
316 - dateInput.parentElement.insertBefore(tempElement, dateInput);
317 - });
318 - }
319 319   this.content.request({
320 320   onSuccess: function() {
321 321   this.saving = false;
322 322   this.savingBox.hide();
323 323   this.savedBox.show();
324 - removeColorPickers();
325 325   this.closeDialog();
326 326   this.helper.calendar.fullCalendar('refetchEvents');
327 327   }.bind(this),
... ... @@ -418,20 +418,18 @@
418 418   var buttons = new Element('div', {'class':'buttons'});
419 419   var oldSkin = ! $('body').hasClassName('skin-flamingo'); // FIXME: bad b/w compat hack
420 420   formcontent.insert(buttons);
421 - // When you are in a read only calendar you only need the close button for the modal and you MUST Not fire
422 - // the xwiki:moccacalendar:editloaded event because you will get a bunch of errors.
423 423   if (this.interactionParameters.editMode) {
424 424   var that = this;
425 - if(this.helper.createEventBaseUrl.indexOf('disabled=disabled') === -1) {
426 - buttons.insert(this.createButton("submit","$escapetool.javascript($services.localization.render('save'))","","save-moccacalendar-event","btn"));
427 - buttons.down('#save-moccacalendar-event').observe('click', this.submitForm.bind(this));
428 - // MOCCACAL-128: the event template has a space in the title to avoid showing the page name, but we want to remove this on load
429 - var titleField = formcontent.down('input[name="title"]')
430 - if (titleField && titleField.getAttribute('value').trim() == '') { titleField.setAttribute('value','') }
431 - document.fire('xwiki:moccacalendar:editloaded');
432 - }
389 + buttons.insert(this.createButton("submit","$escapetool.javascript($services.localization.render('save'))","","save-moccacalendar-event","btn"));
390 + buttons.down('#save-moccacalendar-event').observe('click', this.submitForm.bind(this));
433 433   buttons.insert('<span class="buttonwrapper"><a href="#" id="cancel-moccacalendar-event" class="secondary button">' + "$escapetool.javascript($services.localization.render('cancel'))" + '</a></span>');
434 434   buttons.down('#cancel-moccacalendar-event').observe('click', this.closeDialog.bind(this));
393 +
394 + // MOCCACAL-128: the event template has a space in the title to avoid showing the page name, but we want to remove this on load
395 + var titleField = formcontent.down('input[name="title"]')
396 + if (titleField && titleField.getAttribute('value').trim() == '') { titleField.setAttribute('value','') }
397 +
398 + document.fire('xwiki:moccacalendar:editloaded');
435 435   $("MoccaCalendarEvent.MoccaCalendarEventClass_0_title").focus();
436 436   } else {
437 437   var leftGroup = new Element('div', {'class':'btn-group btn-group-left'});
... ... @@ -446,19 +446,13 @@
446 446   }
447 447   // FIXME: this should be a plain link, but then it has no styles
448 448   if (oldSkin) {
449 - if (this.interactionParameters.event.readOnly != true) {
450 - leftGroup.insert(this.createButton("button","$escapetool.javascript($services.localization.render('view'))","","view-moccacalendar-event","btn"));
451 - }
413 + leftGroup.insert(this.createButton("button","$escapetool.javascript($services.localization.render('view'))","","view-moccacalendar-event","btn"));
452 452   leftGroup.insert('<span class="buttonwrapper"><a href="#" id="cancel-moccacalendar-event" class="secondary button">' + "$escapetool.javascript($services.localization.render('cancel'))" + '</a></span>');
453 453   } else {
454 - if (this.interactionParameters.event.readOnly != true) {
455 - leftGroup.insert(' <button class="button btn btn-default" id="view-moccacalendar-event"><span class="glyphicon glyphicon-file"></span> '+"$escapetool.javascript($services.localization.render('view'))"+'</button>');
456 - }
416 + leftGroup.insert(' <button class="button btn btn-default" id="view-moccacalendar-event"><span class="glyphicon glyphicon-file"></span> '+"$escapetool.javascript($services.localization.render('view'))"+'</button>');
457 457   leftGroup.insert('<button class="button btn btn-default" id="cancel-moccacalendar-event"><span class="glyphicon glyphicon-remove"></span> '+"$escapetool.javascript($services.localization.render('cancel'))"+'</button>');
458 458   }
459 - if (this.interactionParameters.event.readOnly != true) {
460 - leftGroup.down("#view-moccacalendar-event").observe('click', function(e) { e.stop(); window.location.href = this.interactionParameters.event.viewUrl; }.bind(this));
461 - }
419 + leftGroup.down("#view-moccacalendar-event").observe('click', function(e) { e.stop(); window.location.href = this.interactionParameters.event.viewUrl; }.bind(this));
462 462   leftGroup.down('#cancel-moccacalendar-event').observe('click', this.closeDialog.bind(this));
463 463   if (this.interactionParameters.event.canDelete) {
464 464   var rightGroup = new Element('div', {'class':'btn-group btn-group-right'});
... ... @@ -498,9 +498,6 @@
498 498   script.remove();
499 499   });
500 500   content.insert('<div id="formcontent"><div id="forminnercontent">' + container.innerHTML + '</div></div>');
501 -
502 - var parentModalPopup = jQuery('.xdialog-box-moccacal-modal-popup').toArray();
503 - document.fire('xwiki:dom:updated', {elements: parentModalPopup});
504 504   },
505 505   handleDatetimeFieldChange : function(event, element) {
506 506   if (this.saving) { return; }
... ... @@ -761,22 +761,10 @@
761 761  
762 762  });
763 763  
764 -define('mocca-calendar-notification', {
765 - prefix: 'MoccaCalendar.notification.',
766 - keys: [
767 - 'import.inprogress',
768 - 'import.done',
769 - 'import.error',
770 - 'import.filetoolarge',
771 - 'addObject.error'
772 - ]
773 -});
774 -
775 775  /**
776 - * Delete event and calendar import actions.
720 + * Deleting an event
777 777   */
778 -require(['jquery', 'xwiki-meta', 'xwiki-job-runner', 'xwiki-l10n!mocca-calendar-notification'],
779 - function($, xwikiMeta, JobRunner, l10n) {
722 +require(['jquery'], function($) {
780 780   /**
781 781   * Events triggered before deleteEvents modal is shown: save the button that triggers
782 782   * the modal, close MoccaCalendarPopup, update the name of event on displayed text.
... ... @@ -811,105 +811,4 @@
811 811   var calendarPopup = relatedTarget.data('calendarPopup');
812 812   new XWiki.MoccaCalendar.MoccaCalendarPopup(calendarPopup.interactionParameters, calendarPopup.helper);
813 813   });
814 -
815 - $(document).on('click', '.add-calendar-object-container a', function(event) {
816 - event.preventDefault();
817 - const addObjectButton = $('#add-calendar-object');
818 - const target = addObjectButton.data('target');
819 - // To be adapted to the standard XWiki rest endpoint for object creation after
820 - // XWIKI-20704: NullPointerException (NPE) when accessing objects with ComputedField properties from REST is fixed.
821 - var documentReference = XWiki.Model.resolve('MoccaCalendar.Code.MoccaCalendarObjectCreator',
822 - XWiki.EntityType.DOCUMENT);
823 - var targetUrl = new XWiki.Document(documentReference).getURL();
824 - var params = {
825 - 'documentRef': target
826 - };
827 - $.ajax({
828 - url: targetUrl,
829 - type: 'POST',
830 - data: params,
831 - success: function (response) {
832 - window.location.reload();
833 - },
834 - error: function (xhr, status, error) {
835 - console.error('Failed to add the MoccaCalendarClass object', error);
836 - var notification = new XWiki.widgets.Notification(l10n.get('addObject.error'), 'error');
837 - }
838 - });
839 - });
840 -
841 - // Trigger the upload manually when the button is clicked.
842 - $(document).on('click', '.import-calendar-file-button', function(event) {
843 - event.preventDefault();
844 - var calId = $(event.target).data('calid');
845 - var form = $(`#import-calendar-file-${calId} form`).get(0);
846 - startUploading(form, calId);
847 - });
848 -
849 - // Start uploading this file by creating a new XHR object with the file data.
850 - var startUploading = function (form, calId) {
851 - var input = form.down(`#import-ical-file-input-${calId}`);
852 - var inputFile = input.files[0];
853 - if (inputFile && inputFile.size < input.dataset.maxFileSize) {
854 - var select = form.down(`#import-calendar-parent-${calId}`);
855 - var params = {};
856 - params[select.name] = select.value;
857 - let action = form.action + "?" + $.param(params);
858 - // Create XMLHttpRequest object and POST the data
859 - var request = new XMLHttpRequest();
860 - request.open('POST', action);
861 - request.onload = function () {
862 - if (request.status === 202 || request.status === 302) {
863 - checkImportJob(select.value);
864 - } else {
865 - new XWiki.widgets.Notification(l10n.get('import.error'),'error');
866 - }
867 - };
868 - request.send(inputFile);
869 - } else {
870 - var notification = new XWiki.widgets.Notification(l10n.get('import.filetoolarge'), 'error');
871 - }
872 - };
873 -
874 - const checkImportJob = function(selectedCalendar) {
875 - let documentReference = XWiki.Model.resolve('MoccaCalendar.Code.ImportJobResource', XWiki.EntityType.DOCUMENT);
876 - var targetURL = new XWiki.Document(documentReference).getURL('get');
877 - var targetJobId = ['moccacalendar', 'import', selectedCalendar];
878 - var data = [];
879 - data.push(
880 - {name: 'outputSyntax', value: 'plain'},
881 - {name: 'sheet', value: 'MoccaCalendar.Code.ImportJobResource'},
882 - {name: 'action', value: 'jobStatus'},
883 - {name: 'jobId', value: targetJobId.join('/')},
884 - {name: 'data', value: 'jobStatus'},
885 - {name: 'form_token', value: xwikiMeta.form_token}
886 - );
887 - var notification = new XWiki.widgets.Notification(l10n.get('import.inprogress'), 'inprogress');
888 - $('.import-calendar-file-button').prop('disabled', true);
889 - return Promise.resolve(new JobRunner({
890 - createStatusRequest: function(jobId) {
891 - return {
892 - url: targetURL,
893 - data: {
894 - outputSyntax: 'plain',
895 - sheet: 'MoccaCalendar.Code.ImportJobResource',
896 - data: 'jobStatus',
897 - jobId: jobId.join('/')
898 - }
899 - };
900 - }
901 - }).run(targetURL, data)).then((response) => {
902 - if (response.error !== null) {
903 - throw new Error(response.error.message);
904 - } else {
905 - document.dispatchEvent(new Event('calendarImportCompleted'));
906 - notification.replace(new XWiki.widgets.Notification(l10n.get('import.done'),'done'));
907 - }
908 - }).catch((reason) => {
909 - notification.replace(new XWiki.widgets.Notification(l10n.get('import.error'),'error'));
910 - return Promise.reject(reason);
911 - }).finally(() => {
912 - $('.import-calendar-file-button').prop('disabled', false);
913 - });
914 - };
915 915  });
XWiki.StyleSheetExtension[0]
Code
... ... @@ -26,12 +26,7 @@
26 26   margin-top: 0.6em;
27 27  }
28 28  .xdialog-box-moccacal-modal-popup {
29 - background-color: @modal-content-bg;
30 - border-color: @modal-content-border-color;
31 31   width: 600px;
32 - top: 3vh !important;
33 - bottom: 3vh !important;
34 - max-height: 94vh;
35 35  }
36 36  
37 37  /* Make sure the date time picker is shown on top of the event modal. */
... ... @@ -84,56 +84,3 @@
84 84  .skin-flamingo .gadget .fc h2 {
85 85   font-size: 140%;
86 86  }
87 -
88 -.import-form {
89 - padding: 2em;
90 -}
91 -
92 -.import-form label {
93 - margin-bottom: 0.8em;
94 - font-weight: bold;
95 -}
96 -
97 -.import-form select,
98 -.import-form input {
99 - width: 100%;
100 - margin-bottom: 1.6em;
101 - border-radius: 0.4em;
102 -}
103 -
104 -.import-form input {
105 - padding: 0.6em 1em;
106 - border: 1px solid #ccc;
107 -}
108 -
109 -#recurrentDays dd {
110 - display: flex;
111 - gap: 0.3rem;
112 - margin-top: 1rem;
113 - justify-content: space-between;
114 -}
115 -
116 -#recurrentDays .xwiki-form-listclass {
117 - display: inline-flex;
118 - align-items: center;
119 - justify-content: center;
120 - padding: 0.8rem 1.1rem;
121 - background-color: @btn-default-bg;
122 - color: @btn-default-color;
123 - border-radius: 6px;
124 - cursor: pointer;
125 - user-select: none;
126 - transition: all 0.2s ease;
127 - position: relative;
128 -}
129 -
130 -#recurrentDays .xwiki-form-listclass input[type="checkbox"] {
131 - position: absolute;
132 - opacity: 0;
133 - pointer-events: none;
134 -}
135 -
136 -#recurrentDays .xwiki-form-listclass:has(input[type="checkbox"]:checked) {
137 - background-color: @btn-primary-bg;
138 - color: @btn-primary-color;
139 -}
Content Type
... ... @@ -1,1 +1,1 @@
1 -LESS
1 +CSS
Inhalt parsen
... ... @@ -1,1 +1,0 @@
1 -Nein
XWiki.WikiMacroClass[0]
Makro-Code
... ... @@ -1,11 +1,4 @@
1 1  {{velocity output="false"}}
2 -#set ($parameterMap = {})
3 -#if ($themeDoc)
4 - ## If a theme doc is found, we add the theme to the ssx requests to make sure that the cache is properly updated.
5 - ## This code can be removed when the following platform issue is fixed:
6 - ## XWIKI-18668: The changes on the color theme are not taken into account for various ss*x resources
7 - #set ($discard = $parameterMap.put('colorTheme', $themeDocFullName))
8 -#end
9 9  $xwiki.jsx.use("Calendar.FullCalendar", {'defer': false, 'minify': false})
10 10  $xwiki.jsx.use("MoccaCalendar.Code.Macro", {'defer': false, 'v' : '2.7'})
11 11  $xwiki.jsx.use("MoccaCalendar.Code.DatePickerExtension", {'defer': false})
... ... @@ -12,8 +12,8 @@
12 12  $xwiki.jsx.use("MoccaCalendar.MoccaCalendarEventSheet")
13 13  $xwiki.jsx.use("MoccaCalendar.Code.MoccaCalendarEventModificationClass")
14 14  #dateTimePicker_import()
15 -$xwiki.ssx.use("Calendar.FullCalendar", $parameterMap)
16 -$xwiki.ssx.use("MoccaCalendar.Code.Macro", $parameterMap)
8 +$xwiki.ssx.use("Calendar.FullCalendar")
9 +$xwiki.ssx.use("MoccaCalendar.Code.Macro")
17 17  #set($calcounter = $request.getAttribute('MoccaCalendar.Code.Macro:counter'))
18 18  #if(!$calcounter) #set($calcounter = 0) #else #set($calcounter = $calcounter + 1) #end
19 19  #set($discard = $request.setAttribute('MoccaCalendar.Code.Macro:counter', $calcounter))
... ... @@ -74,33 +74,6 @@
74 74  #if(!$date)
75 75   #set($date = "")
76 76  #end
77 -#set($gCal = "$!xcontext.macro.params.gCal")
78 -#set($gApiKey = $xcontext.macro.params.gApiKey)
79 -#if(!$gApiKey)
80 - #set($gApiKey = "")
81 -#end
82 -#set($iCal = $xcontext.macro.params.iCal)
83 -#if(!$iCal)
84 - #set ($iCal = "")
85 -#end
86 -## Prepare the fields if the subscribed class is present
87 -#set ($subscribed = $doc.getObject('MoccaCalendar.MoccaCalendarSubscribeClass'))
88 -#if ($subscribed)
89 - #set ($subscribediCal = $subscribed.getValue('iCal'))
90 - #set ($subscribedgCals = $subscribed.getValue('gCal'))
91 - #set ($gApiKeySubscribed = $subscribed.getValue('gApiKey'))
92 - #set ($subscribedColor = $subscribed.getValue('color'))
93 - #set ($subscribedTextColor = $subscribed.getValue('textColor'))
94 - #set ($disableCreationEvent = 'disabled')
95 -#else
96 - #set ($subscribediCals = '')
97 - #set ($subscribedgCals = '')
98 - #set ($gApiKeySubscribed = '')
99 - #set ($subscribedColor = 'blue')
100 - #set ($subscribedTextColor = 'white')
101 - #set ($disableCreationEvent = "")
102 -#end
103 -
104 104  ## If the date format is not set in MoccaCalendarEventClass, we are going to use the date format from the current wiki.
105 105  #set($dateFormat = $!xwiki.getClass("MoccaCalendar.MoccaCalendarEventClass").get("startDate").getProperty('dateFormat').value)
106 106  #if("$!dateFormat" == "")
... ... @@ -158,134 +158,9 @@
158 158   </div>
159 159   </div>
160 160  #end
161 -
162 -#macro(importCalendarFileModal)
163 - <div class="modal fade" id="import-calendar-file-$calcounter" tabindex="-1" role="dialog">
164 - <div class="modal-dialog">
165 - <div class="modal-content">
166 - <div class="modal-header">
167 - <button type="button" class="close" data-dismiss="modal">&times;</button>
168 - <h4 class="modal-title">
169 - $escapetool.xml($services.localization.render('MoccaCalendar.import.modal.title'))
170 - </h4>
171 - </div>
172 - <div class="modal-body">
173 - #set ($escapedCalendarSpace = $escapetool.xml($doc.getSpace()))
174 - #set ($escapedCalendarName = $escapetool.xml($doc.getDocumentReference().getName()))
175 - #set ($actionURL = "$request.getContextPath()/rest/moccacalendar/import")
176 - #set ($xwikiCalendarDoc = $xwiki.getDocument($calendarDoc))
177 - #set ($calendarObject = $xwikiCalendarDoc.getObject('MoccaCalendar.MoccaCalendarClass'))
178 - <form class="xform" action="${actionURL}" method="post">
179 - <div class="import-form">
180 - #set ($calendarReferences = [])
181 - #if ($filter == 'wiki')
182 - #set ($calendarReferences = $services.moccacalendar.getAllCalendars())
183 - #elseif ($filter == 'space')
184 - #set ($calendarReferences = $services.moccacalendar.getAllCalendarsInDocumentSpace($services.model.resolveDocument($calendarDoc)))
185 - #end
186 - #if ($calendarReferences.size() > 0)
187 - <label for="import-calendar-parent-${calcounter}">
188 - $escapetool.xml($services.localization.render('MoccaCalendar.calendar'))</label>
189 - <select id="import-calendar-parent-${calcounter}" name="parentCalendar">
190 - #foreach ($item in $calendarReferences)
191 - #set ($itemdoc = $xwiki.getDocument($item))
192 - #if ($!{itemdoc} && ${itemdoc.hasAccessLevel("edit")})
193 - #set ($selected="")
194 - #if ($itemdoc.getId() == $doc.getId())
195 - #set ($selected=" selected='selected'")
196 - #end
197 - <option value="$escapetool.xml($services.model.serialize($itemdoc.getDocumentReference(),'default'))"$selected>
198 - $itemdoc.getDisplayTitle()</option>
199 - #end
200 - #end
201 - </select>
202 - #else
203 - <select id="import-calendar-parent-${calcounter}" name="parentCalendar" hidden>
204 - <option value="$escapetool.xml($services.model.serialize($services.model.resolveDocument($calendarDoc),'default'))" selected></option>
205 - </select>
206 - #end
207 - <label for="import-ical-file-input-${calcounter}">$escapetool.xml($services.localization.render(
208 - 'MoccaCalendar.import.modal.file.label'))</label>
209 - <input type="file" id="import-ical-file-input-${calcounter}" accept=".ics" name="importedfile"
210 - data-max-file-size="$!escapetool.xml($xwiki.getSpacePreference('upload_maxsize'))">
211 - </div>
212 - </form>
213 - </div>
214 - <div class="modal-footer">
215 - <input type="button" class="btn btn-primary import-calendar-file-button" data-calid="${calcounter}"
216 - value="$escapetool.xml($services.localization.render('MoccaCalendar.import.modal.button.start'))">
217 - <input type="button" class="btn btn-default"
218 - value="$escapetool.xml($services.localization.render('cancel'))" data-dismiss="modal">
219 - </div>
220 - </div>
221 - </div>
222 - </div>
223 -#end
224 -#macro (addCalendarObject $docRef)
225 - {{html clean=false wiki=true}}
226 - <input type="hidden" id="add-calendar-object" data-target="$docRef">
227 -
228 - {{info cssClass="add-calendar-object-container"}}
229 - $escapetool.xml($services.localization.render('rendering.macro.moccacalendar.addObject.description'))
230 - [[**$escapetool.xml($services.localization.render('rendering.macro.moccacalendar.addObject.button'))**>>$docRef]]
231 - {{/info}}
232 - {{/html}}
233 -#end
234 234  {{/velocity}}
235 235  
236 236  {{velocity}}
237 -#macro(getSubscribedCalendars)
238 - #set ($query = ", BaseObject as obj where doc.fullName = obj.name and obj.className = 'MoccaCalendar.MoccaCalendarSubscribeClass'")
239 - #set ($calendarDocumentsReferences = $services.query.hql($query).execute())
240 - #set ($properties = [])
241 - #foreach($reference in $calendarDocumentsReferences)
242 - #set ($document = $xwiki.getDocument($reference))
243 - #set ($class = $document.getObject('MoccaCalendar.MoccaCalendarSubscribeClass'))
244 - #if ($class.getValue('globalDisplay') == '1')
245 - #set ($discard = $properties.add({
246 - 'iCal': $class.getValue('iCal'),
247 - 'gCal': $class.getValue('gCal'),
248 - 'gApiKey': $class.getValue('gApiKey'),
249 - 'color': $class.getValue('color'),
250 - 'textColor': $class.getValue('textColor')
251 - }))
252 - #end
253 - #end
254 -#end
255 -
256 -## Macro for handling iCal sources
257 -#macro(handleICalSources $iCalList $color $textColor)
258 - #set($iCals = $stringtool.split($iCalList, ','))
259 - #foreach($iCal in $iCals)
260 - #set($json = $xwiki.getDocument('Calendar.ICalToJSON').getURL('get', "iCal=$escapetool.url($stringtool.strip($iCal))"))
261 - {
262 - url: "$json&outputSyntax=plain&startfield=datetime",
263 - backgroundColor: "$color",
264 - textColor: "$textColor"
265 - }
266 - #if($foreach.count < $iCals.size())
267 - ,
268 - #end
269 - #end
270 -#end
271 -
272 -## Macro for handling Google Calendar sources
273 -#macro(handleGoogleCalendarSources $gCalList $apiKey $color, $textColor)
274 - #set($googleCalendars = $stringtool.split($gCalList, ','))
275 - #foreach($calendar in $googleCalendars)
276 - {
277 - googleCalendarId: "$stringtool.strip($calendar)",
278 - googleCalendarApiKey: "$apiKey",
279 - backgroundColor: "$color",
280 - textColor: "$textColor"
281 - }
282 - #if($foreach.count < $googleCalendars.size())
283 - ,
284 - #end
285 - #end
286 -#end
287 -
288 -
289 289  ## We need to check if there is a valid license because the macro is registered even if the user doesn't have view right
290 290  ## on the macro definition page. See XWIKI-14828: Rendering macros defined in wiki pages are available to users that
291 291  ## don't have view right on those pages.
... ... @@ -293,20 +293,11 @@
293 293  #if (!$services.licensing.licensor.hasLicensureForEntity($mainReference))
294 294   {{missingLicenseMessage extensionName="moccacalendar.extension.name"/}}
295 295  #else
296 -#if($xcontext.action=='view')
297 -#set ($xwikiCalendarDoc = $xwiki.getDocument($calendarDoc))
298 -#set ($calendarObject = $xwikiCalendarDoc.getObject('MoccaCalendar.MoccaCalendarClass'))
299 -#if ($filter == 'page' && !$calendarObject)
300 - #addCalendarObject($calendarDoc)
301 -#end
302 -{{html clean="false" wiki="false"}}
137 +#if($xcontext.action=='view'){{html clean="false" wiki="false"}}
303 303  #if($canCreateEvents)
304 304  ## create event link
305 305  <div class="calendar-buttons">
306 306  <span class="buttonwrapper">
307 -<button data-toggle="modal" data-target="#import-calendar-file-$calcounter"
308 - title="$escapetool.xml($services.localization.render('MoccaCalendar.calendarevent.import.title'))">
309 - $escapetool.html($services.localization.render('MoccaCalendar.calendarevent.import'))</button>
310 310  <button class="btn btn-success" id="calendar${calcounter}-btn"><span class="glyphicon glyphicon-plus"></span> $escapetool.html($services.localization.render('MoccaCalendar.calendarevent.create'))</button>
311 311  </span>
312 312  </div>
... ... @@ -314,14 +314,7 @@
314 314  #end
315 315  <div id="calendar${calcounter}"></div>
316 316  <script type="text/javascript">
317 -require.config({
318 - paths: {
319 - purify: "$services.webjars.url('org.webjars.npm:dompurify', 'dist/purify.js')"
320 - },
321 -});
322 -
323 -
324 -require(['xwiki-meta', 'jquery', 'moment','purify', 'gcal', 'moccaCalendar'], function(xwikiMeta, jQuery, moment, purify) {
149 +require(['xwiki-meta', 'jquery', 'moccaCalendar'], function(xwikiMeta, jQuery) {
325 325   jQuery(document).ready(function() {
326 326   var defaultView = XWiki.MoccaCalendar.Helper.getCalendarView("$!escapetool.javascript($defaultView)");
327 327  
... ... @@ -344,79 +344,21 @@
344 344  
345 345   // page is now ready, initialize the calendar...
346 346   var calendar = jQuery('#calendar${calcounter}').fullCalendar({
347 - eventSources: [
348 - ## Source where the xwiki events are stored.
349 - {
350 - url: "$!escapetool.javascript($jsonUrl)",
351 - type: 'GET',
352 - data: function() {
353 - // as we also get called before the calendar is fully initialized
354 - // we cannot get the current view reliably from the calendar itself
355 - // instead use our trusty helper
356 - return jQuery.extend(defaultEventData, {'outputView': XWiki.MoccaCalendar.Helper.getCalendarView(defaultView)} );
357 - },
358 - error: function() {
359 - calendarHelper.displayError();
360 - },
361 - traditional: true
362 - }
363 - ## Subscribed iCal sources
364 - #if($subscribediCal)
365 - ,
366 - #handleICalSources($subscribediCal, $subscribedColor, $subscribedTextColor)
367 - #end
368 - ## Subscribed Google Calendar sources
369 - #if($!subscribedgCals != "")
370 - ,
371 - #handleGoogleCalendarSources($subscribedgCals, $gApiKeySubscribed, $subscribedColor, $subscribedTextColor)
372 - #end
373 - ## Global events
374 - #if($doc.getFullName() == 'MoccaCalendar.WebHome')
375 - #getSubscribedCalendars()
376 - #foreach($property in $properties)
377 - ,
378 - #handleICalSources($property['iCal'], $property['color'], $property['textColor'])
379 - ,
380 - #handleGoogleCalendarSources($property['gCal'], $property['gApiKey'], $property['color'], $property['textColor'])
381 - #end
382 - #end
383 - ## In case the user uses the calendar macro directly and dosen't use the UI to create it.
384 - ## iCal sources
385 - #if($!iCal != "")
386 - ,
387 - #handleICalSources($iCal 'black')
388 - #end
389 - ## Google Calendar public sources
390 - #if($!gCal != "")
391 - ,
392 - #handleGoogleCalendarSources($gCal $gApiKey 'blue')
393 - #end
394 - ],
172 + events: {
173 + url : "$!escapetool.javascript($jsonUrl)",
174 + type: 'GET',
175 + data : function() {
176 + // as we also get called before the calendar is fully initialized
177 + // we cannot get the current view reliably from the calendar itself
178 + // instead use our trusty helper
179 + return jQuery.extend(defaultEventData, {'outputView': XWiki.MoccaCalendar.Helper.getCalendarView(defaultView)} );
180 + },
181 + error: function() {
182 + calendarHelper.displayError();
183 + },
184 + traditional: true
185 + },
395 395   eventClick: function(calEvent, jsEvent, view) {
396 - // Prepare the read only events for the modal.
397 - if (!calEvent.viewUrl){
398 - // The XWiki default format for date is yyyy/MM/dd, which translates into 2024/01/17. However, for some weird
399 - // reason, when using the date.format() from JavaScript, it translates into 2024/01/Mon. We need to use the
400 - // moment().toMomentFormatString(format) to get the right format.
401 - const dateFormat = moment().toMomentFormatString(calendarHelper.dateFormat);
402 -
403 - // Get the sheet URL.
404 - const sheetURL = new XWiki.Document('MoccaCalendarEventSheet', 'MoccaCalendar').getURL('get');
405 - // Parameters for the modal content.
406 - const params = {
407 - title: purify.sanitize(calEvent.title),
408 - start: calEvent.start.format(dateFormat),
409 - end: calEvent.end ? calEvent.end.format(dateFormat) : null,
410 - allDay: calEvent.allDay ? "$escapetool.xml($services.localization.render('moccacalendar.subscribedevent.allday.yes'))" :
411 - "$escapetool.xml($services.localization.render('moccacalendar.subscribedevent.allday.no'))",
412 - description: purify.sanitize(calEvent.description),
413 - readOnly: 'true'
414 - };
415 - const queryString = jQuery.param(params);
416 - const requestURL = `${sheetURL}?${queryString}`;
417 - calEvent.url = requestURL;
418 - calEvent.readOnly=true;
419 - }
420 420   new XWiki.MoccaCalendar.MoccaCalendarPopup({editMode: false, event: calEvent}, calendarHelper);
421 421   jsEvent.preventDefault();
422 422   return false;
... ... @@ -485,7 +485,7 @@
485 485   });
486 486   jQuery('#calendar${calcounter}-btn').click( function(e) { calendarHelper.showCreateEvent(); e.preventDefault(); });
487 487   // helper to be used in callback above
488 -#set($newPageParams = "template=MoccaCalendar.MoccaCalendarEventTemplate&parentFROM=${escapetool.url($calendarDoc)}&calendarParentFilter=${escapetool.url($filter)}&form_token=${services.csrf.getToken()}&ocalcaction=create&disabled=$disableCreationEvent")
255 +#set($newPageParams = "template=MoccaCalendar.MoccaCalendarEventTemplate&parentFROM=${escapetool.url($calendarDoc)}&form_token=${services.csrf.getToken()}&ocalcaction=create")
489 489  #set($randomDocUrl = $xwiki.getURL("randomPage${util.generateRandomString(10)}",'edit',$newPageParams))
490 490  #set($updateUrlParams="?xpage=plain&outputSyntax=plain&calendarDoc=${escapetool.url(${calendarDoc})}&")
491 491   var calendarHelper = new XWiki.MoccaCalendar.Helper(calendar,
... ... @@ -502,7 +502,6 @@
502 502   });
503 503  });
504 504  </script>
505 -#importCalendarFileModal
506 506  #if($calcounter == 0)
507 507   #showDeleteEventsModal
508 508  #end
Default categories
... ... @@ -1,1 +1,0 @@
1 -Content
Standardkategorie
... ... @@ -1,0 +1,1 @@
1 +Content
XWiki.WikiMacroParameterClass[11]
Parameter verpflichtend
... ... @@ -1,1 +1,0 @@
1 -Nein
Parameter-Name
... ... @@ -1,1 +1,0 @@
1 -gCal
XWiki.WikiMacroParameterClass[12]
Parameter verpflichtend
... ... @@ -1,1 +1,0 @@
1 -Nein
Parameter-Name
... ... @@ -1,1 +1,0 @@
1 -gApiKey
XWiki.WikiMacroParameterClass[13]
Parameter verpflichtend
... ... @@ -1,1 +1,0 @@
1 -Nein
Parameter-Name
... ... @@ -1,1 +1,0 @@
1 -iCal