Ä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 5.1
bearbeitet von xwikiadmin
am 2025/01/07 11:32
Änderungskommentar: Install extension [com.xwiki.mocca-calendar:application-mocca-calendar-ui/2.15]

Zusammenfassung

Details

XWiki.JavaScriptExtension[0]
Code
... ... @@ -16,6 +16,8 @@
16 16   XWiki.MoccaCalendar = {};
17 17   }
18 18  
19 +#template('colorThemeInit.vm')
20 +
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;
... ... @@ -156,6 +156,7 @@
156 156   },
157 157   {
158 158   verticalPosition: "top",
161 + 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() {
... ... @@ -298,24 +298,6 @@
298 298   }
299 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;
... ... @@ -761,14 +761,13 @@
761 761  
762 762  });
763 763  
764 -define('mocca-calendar-notification', {
765 - prefix: 'MoccaCalendar.notification.',
749 +define('mocca-calendar-import-notification', {
750 + prefix: 'MoccaCalendar.import.notification.',
766 766   keys: [
767 - 'import.inprogress',
768 - 'import.done',
769 - 'import.error',
770 - 'import.filetoolarge',
771 - 'addObject.error'
752 + 'inprogress',
753 + 'done',
754 + 'error',
755 + 'filetoolarge'
772 772   ]
773 773  });
774 774  
... ... @@ -775,7 +775,7 @@
775 775  /**
776 776   * Delete event and calendar import actions.
777 777   */
778 -require(['jquery', 'xwiki-meta', 'xwiki-job-runner', 'xwiki-l10n!mocca-calendar-notification'],
762 +require(['jquery', 'xwiki-meta', 'xwiki-job-runner', 'xwiki-l10n!mocca-calendar-import-notification'],
779 779   function($, xwikiMeta, JobRunner, l10n) {
780 780   /**
781 781   * Events triggered before deleteEvents modal is shown: save the button that triggers
... ... @@ -812,64 +812,33 @@
812 812   new XWiki.MoccaCalendar.MoccaCalendarPopup(calendarPopup.interactionParameters, calendarPopup.helper);
813 813   });
814 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 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);
800 + $(document).on('click', '#import-calendar-file-button', function(event) {
801 + var form = $('#import-calendar-file form').get(0);
802 + if (event) {
803 + event.preventDefault();
804 + }
805 + startUploading(form);
847 847   });
848 848  
849 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}`);
809 + var startUploading = function (form) {
810 + var formData = new FormData(form);
811 + var select = form.down('#import-calendar-parent');
812 + var input = form.down('#import-ical-file-input');
813 + if (input.files[0].size < input.dataset.maxFileSize) {
855 855   var params = {};
856 856   params[select.name] = select.value;
857 - let action = form.action + "?" + $.param(params);
816 + formData.action = form.action + "?" + $.param(params);
858 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);
818 + var request = this.request = new XMLHttpRequest();
819 + request.open('POST', formData.action);
820 + request.send(formData);
821 + checkImportJob(select.value);
869 869   } else {
870 - var notification = new XWiki.widgets.Notification(l10n.get('import.filetoolarge'), 'error');
823 + var notification = new XWiki.widgets.Notification(l10n.get('filetoolarge'), 'error');
871 871   }
872 - };
825 + }
873 873  
874 874   const checkImportJob = function(selectedCalendar) {
875 875   let documentReference = XWiki.Model.resolve('MoccaCalendar.Code.ImportJobResource', XWiki.EntityType.DOCUMENT);
... ... @@ -884,8 +884,8 @@
884 884   {name: 'data', value: 'jobStatus'},
885 885   {name: 'form_token', value: xwikiMeta.form_token}
886 886   );
887 - var notification = new XWiki.widgets.Notification(l10n.get('import.inprogress'), 'inprogress');
888 - $('.import-calendar-file-button').prop('disabled', true);
840 + var notification = new XWiki.widgets.Notification(l10n.get('inprogress'), 'inprogress');
841 + $('#import-calendar-file-button').prop('disabled', true);
889 889   return Promise.resolve(new JobRunner({
890 890   createStatusRequest: function(jobId) {
891 891   return {
... ... @@ -903,13 +903,13 @@
903 903   throw new Error(response.error.message);
904 904   } else {
905 905   document.dispatchEvent(new Event('calendarImportCompleted'));
906 - notification.replace(new XWiki.widgets.Notification(l10n.get('import.done'),'done'));
859 + notification.replace(new XWiki.widgets.Notification(l10n.get('done'),'done'));
907 907   }
908 908   }).catch((reason) => {
909 - notification.replace(new XWiki.widgets.Notification(l10n.get('import.error'),'error'));
862 + notification.replace(new XWiki.widgets.Notification(l10n.get('error'),'error'));
910 910   return Promise.reject(reason);
911 911   }).finally(() => {
912 - $('.import-calendar-file-button').prop('disabled', false);
865 + $('#import-calendar-file-button').prop('disabled', false);
913 913   });
914 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. */
... ... @@ -95,45 +95,13 @@
95 95  }
96 96  
97 97  .import-form select,
98 -.import-form input {
93 +.import-form #import-ical-file-input {
99 99   width: 100%;
100 100   margin-bottom: 1.6em;
101 101   border-radius: 0.4em;
102 102  }
103 103  
104 -.import-form input {
99 +.import-form #import-ical-file-input {
105 105   padding: 0.6em 1em;
106 106   border: 1px solid #ccc;
107 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))
... ... @@ -160,7 +160,7 @@
160 160  #end
161 161  
162 162  #macro(importCalendarFileModal)
163 - <div class="modal fade" id="import-calendar-file-$calcounter" tabindex="-1" role="dialog">
156 + <div class="modal fade" id="import-calendar-file" tabindex="-1" role="dialog">
164 164   <div class="modal-dialog">
165 165   <div class="modal-content">
166 166   <div class="modal-header">
... ... @@ -173,46 +173,32 @@
173 173   #set ($escapedCalendarSpace = $escapetool.xml($doc.getSpace()))
174 174   #set ($escapedCalendarName = $escapetool.xml($doc.getDocumentReference().getName()))
175 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">
169 + <form class="xform" action="$actionURL" method="post">
179 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>
171 + <label for="import-calendar-parent">
172 + $escapetool.xml($services.localization.render('MoccaCalendar.calendar'))</label>
173 + <select id="import-calendar-parent" name="parentCalendar">
174 + #foreach ($item in $services.moccacalendar.getAllCalendars()) ## TODO: add filter here, see MOCCACAL-76
175 + #set ($itemdoc = $xwiki.getDocument($item))
176 + #if ($!{itemdoc} && ${itemdoc.hasAccessLevel("edit")})
177 + #set ($selected="")
178 + #if ($itemdoc.getId() == $doc.getId())
179 + #set ($selected=" selected='selected'")
199 199   #end
181 + <option value="$escapetool.html($itemdoc.getFullName())"$selected>
182 + $itemdoc.getDisplayTitle()</option>
200 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(
184 + #end
185 + </select>
186 + <label for="import-ical-file-input">$escapetool.xml($services.localization.render(
208 208   'MoccaCalendar.import.modal.file.label'))</label>
209 - <input type="file" id="import-ical-file-input-${calcounter}" accept=".ics" name="importedfile"
188 + <input type="file" id="import-ical-file-input" accept=".ics" name="importedfile"
210 210   data-max-file-size="$!escapetool.xml($xwiki.getSpacePreference('upload_maxsize'))">
211 211   </div>
212 212   </form>
213 213   </div>
214 214   <div class="modal-footer">
215 - <input type="button" class="btn btn-primary import-calendar-file-button" data-calid="${calcounter}"
194 + <input type="button" class="btn btn-primary" id="import-calendar-file-button"
216 216   value="$escapetool.xml($services.localization.render('MoccaCalendar.import.modal.button.start'))">
217 217   <input type="button" class="btn btn-default"
218 218   value="$escapetool.xml($services.localization.render('cancel'))" data-dismiss="modal">
... ... @@ -221,16 +221,6 @@
221 221   </div>
222 222   </div>
223 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}}
... ... @@ -293,18 +293,12 @@
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"}}
265 +#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"
270 +<button data-toggle="modal" data-target="#import-calendar-file"
308 308   title="$escapetool.xml($services.localization.render('MoccaCalendar.calendarevent.import.title'))">
309 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>
... ... @@ -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")
451 +#set($newPageParams = "template=MoccaCalendar.MoccaCalendarEventTemplate&parentFROM=${escapetool.url($calendarDoc)}&form_token=${services.csrf.getToken()}&ocalcaction=create&disabled=$disableCreationEvent")
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,9 +502,9 @@
502 502   });
503 503  });
504 504  </script>
505 -#importCalendarFileModal
506 506  #if($calcounter == 0)
507 507   #showDeleteEventsModal
470 + #importCalendarFileModal
508 508  #end
509 509  {{/html}}
510 510  #else ## of #if($xcontext.action=='view')