From f6e8cc83aec9b6ddc4bb0b8f5d15edba247fd144 Mon Sep 17 00:00:00 2001 From: Ryan Wyllie Date: Mon, 21 Aug 2017 06:27:47 +0000 Subject: [PATCH] MDL-59713 calendar: clicking day in monthly view opens new event modal --- calendar/amd/build/calendar.min.js | 2 +- calendar/amd/build/modal_event_form.min.js | 2 +- calendar/amd/src/calendar.js | 35 ++++++++++++++++-- calendar/amd/src/modal_event_form.js | 36 +++++++++++++++++++ calendar/classes/external/day_exporter.php | 20 +++++++++-- calendar/classes/local/event/forms/create.php | 3 +- calendar/lib.php | 5 +++ calendar/templates/month_detailed.mustache | 13 ++++--- theme/boost/scss/moodle/calendar.scss | 12 +++++-- theme/boost/scss/moodle/core.scss | 4 +++ theme/bootstrapbase/less/moodle/calendar.less | 12 +++++-- theme/bootstrapbase/less/moodle/core.less | 4 +++ theme/bootstrapbase/style/moodle.css | 18 ++++++---- 13 files changed, 144 insertions(+), 22 deletions(-) diff --git a/calendar/amd/build/calendar.min.js b/calendar/amd/build/calendar.min.js index b0336c44482..c7974037cad 100644 --- a/calendar/amd/build/calendar.min.js +++ b/calendar/amd/build/calendar.min.js @@ -1 +1 @@ -define(["jquery","core/ajax","core/str","core/templates","core/notification","core/custom_interaction_events","core/modal_events","core/modal_factory","core_calendar/modal_event_form","core_calendar/summary_modal","core_calendar/repository","core_calendar/events","core_calendar/view_manager"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n={ROOT:"[data-region='calendar']",EVENT_LINK:"[data-action='view-event']",NEW_EVENT_BUTTON:"[data-action='new-event-button']",DAY_CONTENT:"[data-region='day-content']",LOADING_ICON:".loading-icon"},o=function(a){var b="type"+a;return c.get_string(b,"core_calendar").then(function(a){return a})},p=function(a){return c.get_string("subsource","core_calendar",a).then(function(b){return a.url?''+b+"":b})},q=function(b){k.getEventById(b).then(function(c){if(!c.event)throw new Error("Error encountered while trying to fetch calendar event with ID: "+b);var d=c.event,e=o(d.eventtype);if(d.displayeventsource){d.subscription=JSON.parse(d.subscription);var f={url:d.subscription.url,name:d.subscription.name},g=p(f);return a.when(e,g).then(function(a,b){return d.eventtype=a,d.source=b,d})}return e.then(function(a){return d.eventtype=a,d})}).then(function(a){var b={title:a.name,type:j.TYPE,body:d.render("core_calendar/event_summary_body",a),templateContext:{canedit:a.canedit,candelete:a.candelete}};return h.create(b)}).done(function(a){a.getRoot().on(g.hidden,function(){a.destroy()}),a.show()}).fail(e.exception)},r=function(b,c,f,g){var h=c.attr("data-event-id"),i=f.attr("data-day-timestamp"),j=g.attr("data-day-timestamp");i!=j&&d.render("core/loading",{}).then(function(a,b){f.find(n.DAY_CONTENT).addClass("hidden"),g.find(n.DAY_CONTENT).addClass("hidden"),d.appendNodeContents(f,a,b),d.appendNodeContents(g,a,b)}).then(function(){return k.updateEventStartDay(h,j)}).then(function(){a("body").trigger(l.eventMoved,[c,f,g])}).always(function(){var a=f.find(n.LOADING_ICON),b=g.find(n.LOADING_ICON);f.find(n.DAY_CONTENT).removeClass("hidden"),g.find(n.DAY_CONTENT).removeClass("hidden"),d.replaceNode(a,"",""),d.replaceNode(b,"","")}).fail(e.exception)},s=function(a){var b=a.find(n.NEW_EVENT_BUTTON),c=b.attr("data-context-id");return h.create({type:i.TYPE,large:!0,templateContext:{contextid:c}},[a,n.NEW_EVENT_BUTTON])},t=function(b,c){var d=a("body");d.on(l.created,function(){m.reloadCurrentMonth()}),d.on(l.deleted,function(){m.reloadCurrentMonth()}),d.on(l.updated,function(){m.reloadCurrentMonth()}),d.on(l.editActionEvent,function(a,b){window.location.assign(b)}),d.on(l.moveEvent,r),d.on(l.eventMoved,function(){window.location.reload()}),c.then(function(a){d.on(l.editEvent,function(b,c){a.setEventId(c),a.show()})})},u=function(){var b=a(n.ROOT);b.on("click",n.EVENT_LINK,function(b){b.preventDefault();var c=a(this).attr("data-event-id");q(c)});var c=s(b);t(b,c)};return{init:function(){m.init(),u()}}}); \ No newline at end of file +define(["jquery","core/ajax","core/str","core/templates","core/notification","core/custom_interaction_events","core/modal_events","core/modal_factory","core_calendar/modal_event_form","core_calendar/summary_modal","core_calendar/repository","core_calendar/events","core_calendar/view_manager"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n={ROOT:"[data-region='calendar']",DAY:"[data-region='day']",EVENT_ITEM:"[data-region='event-item']",EVENT_LINK:"[data-action='view-event']",NEW_EVENT_BUTTON:"[data-action='new-event-button']",DAY_CONTENT:"[data-region='day-content']",LOADING_ICON:".loading-icon",VIEW_DAY_LINK:"[data-action='view-day-link']"},o=function(a){var b="type"+a;return c.get_string(b,"core_calendar").then(function(a){return a})},p=function(a){return c.get_string("subsource","core_calendar",a).then(function(b){return a.url?''+b+"":b})},q=function(b){k.getEventById(b).then(function(c){if(!c.event)throw new Error("Error encountered while trying to fetch calendar event with ID: "+b);var d=c.event,e=o(d.eventtype);if(d.displayeventsource){d.subscription=JSON.parse(d.subscription);var f={url:d.subscription.url,name:d.subscription.name},g=p(f);return a.when(e,g).then(function(a,b){return d.eventtype=a,d.source=b,d})}return e.then(function(a){return d.eventtype=a,d})}).then(function(a){var b={title:a.name,type:j.TYPE,body:d.render("core_calendar/event_summary_body",a),templateContext:{canedit:a.canedit,candelete:a.candelete}};return h.create(b)}).done(function(a){a.getRoot().on(g.hidden,function(){a.destroy()}),a.show()}).fail(e.exception)},r=function(b,c,f,g){var h=c.attr("data-event-id"),i=f.attr("data-day-timestamp"),j=g.attr("data-day-timestamp");i!=j&&d.render("core/loading",{}).then(function(a,b){f.find(n.DAY_CONTENT).addClass("hidden"),g.find(n.DAY_CONTENT).addClass("hidden"),d.appendNodeContents(f,a,b),d.appendNodeContents(g,a,b)}).then(function(){return k.updateEventStartDay(h,j)}).then(function(){a("body").trigger(l.eventMoved,[c,f,g])}).always(function(){var a=f.find(n.LOADING_ICON),b=g.find(n.LOADING_ICON);f.find(n.DAY_CONTENT).removeClass("hidden"),g.find(n.DAY_CONTENT).removeClass("hidden"),d.replaceNode(a,"",""),d.replaceNode(b,"","")}).fail(e.exception)},s=function(a){var b=a.find(n.NEW_EVENT_BUTTON),c=b.attr("data-context-id");return h.create({type:i.TYPE,large:!0,templateContext:{contextid:c}},[a,n.NEW_EVENT_BUTTON])},t=function(b,c){var d=a("body");d.on(l.created,function(){m.reloadCurrentMonth()}),d.on(l.deleted,function(){m.reloadCurrentMonth()}),d.on(l.updated,function(){m.reloadCurrentMonth()}),d.on(l.editActionEvent,function(a,b){window.location.assign(b)}),d.on(l.moveEvent,r),d.on(l.eventMoved,function(){window.location.reload()}),c.then(function(a){d.on(l.editEvent,function(b,c){a.setEventId(c),a.show()})})},u=function(){var b=a(n.ROOT);b.on("click",n.EVENT_ITEM,function(b){b.preventDefault(),b.stopPropagation();var c=a(b.target),d=null;d=c.is(n.EVENT_LINK)?c.attr("data-event-id"):c.find(n.EVENT_LINK).attr("data-event-id"),q(d)});var c=s(b);t(b,c),b.on("click",n.DAY,function(b){var d=a(b.target);if(!d.is(n.VIEW_DAY_LINK)){var e=a(this).attr("data-new-event-timestamp");c.then(function(a){a.setStartTime(e),a.show()}),b.preventDefault()}})};return{init:function(){m.init(),u()}}}); \ No newline at end of file diff --git a/calendar/amd/build/modal_event_form.min.js b/calendar/amd/build/modal_event_form.min.js index 78b804aa112..f29703f82aa 100644 --- a/calendar/amd/build/modal_event_form.min.js +++ b/calendar/amd/build/modal_event_form.min.js @@ -1 +1 @@ -define(["jquery","core/event","core/str","core/notification","core/templates","core/custom_interaction_events","core/modal","core/modal_registry","core/fragment","core_calendar/events","core_calendar/repository","core_calendar/event_form"],function(a,b,c,d,e,f,g,h,i,j,k,l){var m=!1,n={MORELESS_BUTTON:'[data-action="more-less-toggle"]',SAVE_BUTTON:'[data-action="save"]',LOADING_ICON_CONTAINER:'[data-region="loading-icon-container"]'},o=function(a){g.call(this,a),this.eventId=null,this.reloadingBody=!1,this.reloadingTitle=!1,this.saveButton=this.getFooter().find(n.SAVE_BUTTON),this.moreLessButton=this.getFooter().find(n.MORELESS_BUTTON)};return o.TYPE="core_calendar-modal_event_form",o.prototype=Object.create(g.prototype),o.prototype.constructor=o,o.prototype.setEventId=function(a){this.eventId=a},o.prototype.getEventId=function(){return this.eventId},o.prototype.hasEventId=function(){return null!==this.eventId},o.prototype.getForm=function(){return this.getBody().find("form")},o.prototype.disableButtons=function(){this.saveButton.prop("disabled",!0),this.moreLessButton.prop("disabled",!0)},o.prototype.enableButtons=function(){this.saveButton.prop("disabled",!1),this.moreLessButton.prop("disabled",!1)},o.prototype.setMoreButton=function(){this.moreLessButton.attr("data-collapsed","true"),c.get_string("more","calendar").then(function(a){this.moreLessButton.text(a)}.bind(this))},o.prototype.setLessButton=function(){this.moreLessButton.attr("data-collapsed","false"),c.get_string("less","calendar").then(function(a){this.moreLessButton.text(a)}.bind(this))},o.prototype.toggleMoreLessButton=function(){var a=this.getForm();"true"==this.moreLessButton.attr("data-collapsed")?(a.trigger(l.events.SHOW_ADVANCED),this.setLessButton()):(a.trigger(l.events.HIDE_ADVANCED),this.setMoreButton())},o.prototype.reloadTitleContent=function(){return this.reloadingTitle?this.titlePromise:(this.reloadingTitle=!0,this.hasEventId()?this.titlePromise=c.get_string("editevent","calendar"):this.titlePromise=c.get_string("newevent","calendar"),this.titlePromise.then(function(a){return this.setTitle(a),a}.bind(this)).always(function(){this.reloadingTitle=!1}.bind(this)),this.titlePromise)},o.prototype.reloadBodyContent=function(a,b){if(this.reloadingBody)return this.bodyPromise;this.reloadingBody=!0,this.disableButtons();var c=this.saveButton.attr("data-context-id"),e={};return this.hasEventId()&&(e.eventid=this.getEventId()),"undefined"!=typeof a&&(e.formdata=a),e.haserror="undefined"!=typeof b&&b,this.bodyPromise=i.loadFragment("calendar","event_form",c,e),this.setBody(this.bodyPromise),this.bodyPromise.then(function(){this.enableButtons()}.bind(this))["catch"](d.exception).always(function(){this.reloadingBody=!1}.bind(this)),this.bodyPromise},o.prototype.reloadAllContent=function(){return a.when(this.reloadTitleContent(),this.reloadBodyContent())},o.prototype.show=function(){this.reloadAllContent(),g.prototype.show.call(this)},o.prototype.hide=function(){g.prototype.hide.call(this),this.setEventId(null)},o.prototype.getFormData=function(){return this.getForm().serialize()},o.prototype.save=function(){var b=this.saveButton.find(n.LOADING_ICON_CONTAINER);b.removeClass("hidden"),this.disableButtons();var c=this.getFormData();return k.submitCreateUpdateForm(c).then(function(b){return b.validationerror?this.reloadBodyContent(c,!0):(this.hide(),void(this.hasEventId()?a("body").trigger(j.updated,[b.event]):a("body").trigger(j.created,[b.event])))}.bind(this)).always(function(){b.addClass("hidden"),this.enableButtons()}.bind(this))["catch"](d.exception)},o.prototype.registerEventListeners=function(){g.prototype.registerEventListeners.call(this),this.getModal().on(f.events.activate,n.SAVE_BUTTON,function(a,b){this.getForm().submit(),b.originalEvent.preventDefault(),a.stopPropagation()}.bind(this)),this.getModal().on("submit",function(a){this.save(),a.preventDefault(),a.stopPropagation()}.bind(this)),this.getModal().on(f.events.activate,n.MORELESS_BUTTON,function(a,b){this.toggleMoreLessButton(),b.originalEvent.preventDefault(),a.stopPropagation()}.bind(this)),this.getModal().on(l.events.ADVANCED_SHOWN,function(){this.setLessButton()}.bind(this)),this.getModal().on(l.events.ADVANCED_HIDDEN,function(){this.setMoreButton()}.bind(this))},m||(h.register(o.TYPE,o,"calendar/modal_event_form"),m=!0),o}); \ No newline at end of file +define(["jquery","core/event","core/str","core/notification","core/templates","core/custom_interaction_events","core/modal","core/modal_registry","core/fragment","core_calendar/events","core_calendar/repository","core_calendar/event_form"],function(a,b,c,d,e,f,g,h,i,j,k,l){var m=!1,n={MORELESS_BUTTON:'[data-action="more-less-toggle"]',SAVE_BUTTON:'[data-action="save"]',LOADING_ICON_CONTAINER:'[data-region="loading-icon-container"]'},o=function(a){g.call(this,a),this.eventId=null,this.startTime=null,this.reloadingBody=!1,this.reloadingTitle=!1,this.saveButton=this.getFooter().find(n.SAVE_BUTTON),this.moreLessButton=this.getFooter().find(n.MORELESS_BUTTON)};return o.TYPE="core_calendar-modal_event_form",o.prototype=Object.create(g.prototype),o.prototype.constructor=o,o.prototype.setEventId=function(a){this.eventId=a},o.prototype.getEventId=function(){return this.eventId},o.prototype.hasEventId=function(){return null!==this.eventId},o.prototype.setStartTime=function(a){this.startTime=a},o.prototype.getStartTime=function(){return this.startTime},o.prototype.hasStartTime=function(){return null!==this.startTime},o.prototype.getForm=function(){return this.getBody().find("form")},o.prototype.disableButtons=function(){this.saveButton.prop("disabled",!0),this.moreLessButton.prop("disabled",!0)},o.prototype.enableButtons=function(){this.saveButton.prop("disabled",!1),this.moreLessButton.prop("disabled",!1)},o.prototype.setMoreButton=function(){this.moreLessButton.attr("data-collapsed","true"),c.get_string("more","calendar").then(function(a){this.moreLessButton.text(a)}.bind(this))},o.prototype.setLessButton=function(){this.moreLessButton.attr("data-collapsed","false"),c.get_string("less","calendar").then(function(a){this.moreLessButton.text(a)}.bind(this))},o.prototype.toggleMoreLessButton=function(){var a=this.getForm();"true"==this.moreLessButton.attr("data-collapsed")?(a.trigger(l.events.SHOW_ADVANCED),this.setLessButton()):(a.trigger(l.events.HIDE_ADVANCED),this.setMoreButton())},o.prototype.reloadTitleContent=function(){return this.reloadingTitle?this.titlePromise:(this.reloadingTitle=!0,this.hasEventId()?this.titlePromise=c.get_string("editevent","calendar"):this.titlePromise=c.get_string("newevent","calendar"),this.titlePromise.then(function(a){return this.setTitle(a),a}.bind(this)).always(function(){this.reloadingTitle=!1}.bind(this)),this.titlePromise)},o.prototype.reloadBodyContent=function(a,b){if(this.reloadingBody)return this.bodyPromise;this.reloadingBody=!0,this.disableButtons();var c=this.saveButton.attr("data-context-id"),e={};return this.hasEventId()&&(e.eventid=this.getEventId()),this.hasStartTime()&&(e.starttime=this.getStartTime()),"undefined"!=typeof a&&(e.formdata=a),e.haserror="undefined"!=typeof b&&b,this.bodyPromise=i.loadFragment("calendar","event_form",c,e),this.setBody(this.bodyPromise),this.bodyPromise.then(function(){this.enableButtons()}.bind(this))["catch"](d.exception).always(function(){this.reloadingBody=!1}.bind(this)),this.bodyPromise},o.prototype.reloadAllContent=function(){return a.when(this.reloadTitleContent(),this.reloadBodyContent())},o.prototype.show=function(){this.reloadAllContent(),g.prototype.show.call(this)},o.prototype.hide=function(){g.prototype.hide.call(this),this.setEventId(null),this.setStartTime(null)},o.prototype.getFormData=function(){return this.getForm().serialize()},o.prototype.save=function(){var b=this.saveButton.find(n.LOADING_ICON_CONTAINER);b.removeClass("hidden"),this.disableButtons();var c=this.getFormData();return k.submitCreateUpdateForm(c).then(function(b){return b.validationerror?this.reloadBodyContent(c,!0):(this.hide(),void(this.hasEventId()?a("body").trigger(j.updated,[b.event]):a("body").trigger(j.created,[b.event])))}.bind(this)).always(function(){b.addClass("hidden"),this.enableButtons()}.bind(this))["catch"](d.exception)},o.prototype.registerEventListeners=function(){g.prototype.registerEventListeners.call(this),this.getModal().on(f.events.activate,n.SAVE_BUTTON,function(a,b){this.getForm().submit(),b.originalEvent.preventDefault(),a.stopPropagation()}.bind(this)),this.getModal().on("submit",function(a){this.save(),a.preventDefault(),a.stopPropagation()}.bind(this)),this.getModal().on(f.events.activate,n.MORELESS_BUTTON,function(a,b){this.toggleMoreLessButton(),b.originalEvent.preventDefault(),a.stopPropagation()}.bind(this)),this.getModal().on(l.events.ADVANCED_SHOWN,function(){this.setLessButton()}.bind(this)),this.getModal().on(l.events.ADVANCED_HIDDEN,function(){this.setMoreButton()}.bind(this))},m||(h.register(o.TYPE,o,"calendar/modal_event_form"),m=!0),o}); \ No newline at end of file diff --git a/calendar/amd/src/calendar.js b/calendar/amd/src/calendar.js index 86fd1063e0d..e75671c59fd 100644 --- a/calendar/amd/src/calendar.js +++ b/calendar/amd/src/calendar.js @@ -58,10 +58,13 @@ define([ var SELECTORS = { ROOT: "[data-region='calendar']", + DAY: "[data-region='day']", + EVENT_ITEM: "[data-region='event-item']", EVENT_LINK: "[data-action='view-event']", NEW_EVENT_BUTTON: "[data-action='new-event-button']", DAY_CONTENT: "[data-region='day-content']", LOADING_ICON: '.loading-icon', + VIEW_DAY_LINK: "[data-action='view-day-link']" }; /** @@ -284,14 +287,42 @@ define([ var root = $(SELECTORS.ROOT); // Bind click events to event links. - root.on('click', SELECTORS.EVENT_LINK, function(e) { + root.on('click', SELECTORS.EVENT_ITEM, function(e) { e.preventDefault(); - var eventId = $(this).attr('data-event-id'); + // We've handled the event so stop it from bubbling + // and causing the day click handler to fire. + e.stopPropagation(); + + var target = $(e.target); + var eventId = null; + + if (target.is(SELECTORS.EVENT_LINK)) { + eventId = target.attr('data-event-id'); + } else { + eventId = target.find(SELECTORS.EVENT_LINK).attr('data-event-id'); + } + renderEventSummaryModal(eventId); }); var eventFormPromise = registerEventFormModal(root); registerCalendarEventListeners(root, eventFormPromise); + + // Bind click events to calendar days. + root.on('click', SELECTORS.DAY, function(e) { + var target = $(e.target); + + if (!target.is(SELECTORS.VIEW_DAY_LINK)) { + var startTime = $(this).attr('data-new-event-timestamp'); + eventFormPromise.then(function(modal) { + modal.setStartTime(startTime); + modal.show(); + return; + }); + + e.preventDefault(); + } + }); }; return { diff --git a/calendar/amd/src/modal_event_form.js b/calendar/amd/src/modal_event_form.js index bad5ca4f945..cee039afcab 100644 --- a/calendar/amd/src/modal_event_form.js +++ b/calendar/amd/src/modal_event_form.js @@ -66,6 +66,7 @@ define([ var ModalEventForm = function(root) { Modal.call(this, root); this.eventId = null; + this.startTime = null; this.reloadingBody = false; this.reloadingTitle = false; this.saveButton = this.getFooter().find(SELECTORS.SAVE_BUTTON); @@ -106,6 +107,36 @@ define([ return this.eventId !== null; }; + /** + * Set the start time to the given value. + * + * @method setStartTime + * @param {int} time The start time + */ + ModalEventForm.prototype.setStartTime = function(time) { + this.startTime = time; + }; + + /** + * Retrieve the current start time, if any. + * + * @method getStartTime + * @return {int|null} The start time + */ + ModalEventForm.prototype.getStartTime = function() { + return this.startTime; + }; + + /** + * Check if the modal has start time. + * + * @method hasStartTime + * @return {bool} + */ + ModalEventForm.prototype.hasStartTime = function() { + return this.startTime !== null; + }; + /** * Get the form element from the modal. * @@ -244,6 +275,10 @@ define([ args.eventid = this.getEventId(); } + if (this.hasStartTime()) { + args.starttime = this.getStartTime(); + } + if (typeof formData !== 'undefined') { args.formdata = formData; } @@ -305,6 +340,7 @@ define([ ModalEventForm.prototype.hide = function() { Modal.prototype.hide.call(this); this.setEventId(null); + this.setStartTime(null); }; /** diff --git a/calendar/classes/external/day_exporter.php b/calendar/classes/external/day_exporter.php index 5cac152723a..4a713bc0d9a 100644 --- a/calendar/classes/external/day_exporter.php +++ b/calendar/classes/external/day_exporter.php @@ -82,6 +82,9 @@ class day_exporter extends exporter { 'timestamp' => [ 'type' => PARAM_INT, ], + 'neweventtimestamp' => [ + 'type' => PARAM_INT, + ], 'istoday' => [ 'type' => PARAM_BOOL, 'default' => false, @@ -108,13 +111,26 @@ class day_exporter extends exporter { * @return array Keys are the property names, values are their values. */ protected function get_other_values(renderer_base $output) { + $timestamp = $this->data[0]; + // Need to account for user's timezone. + $usernow = usergetdate(time()); + $today = new \DateTimeImmutable(); + // The start time should use the day's date but the current + // time of the day (adjusted for user's timezone). + $neweventstarttime = $today->setTimestamp($timestamp)->setTime( + $usernow['hours'], + $usernow['minutes'], + $usernow['seconds'] + ); + $return = [ - 'timestamp' => $this->data[0], + 'timestamp' => $timestamp, + 'neweventtimestamp' => $neweventstarttime->getTimestamp() ]; $url = new moodle_url('/calendar/view.php', [ 'view' => 'day', - 'time' => $this->data[0], + 'time' => $timestamp, ]); $return['viewdaylink'] = $url->out(false); diff --git a/calendar/classes/local/event/forms/create.php b/calendar/classes/local/event/forms/create.php index 3e8ed78614d..4a4172df3de 100644 --- a/calendar/classes/local/event/forms/create.php +++ b/calendar/classes/local/event/forms/create.php @@ -42,6 +42,7 @@ class create extends \moodleform { $mform = $this->_form; $haserror = !empty($this->_customdata['haserror']); + $starttime = isset($this->_customdata['starttime']) ? $this->_customdata['starttime'] : 0; $eventtypes = calendar_get_all_allowed_types(); $mform->setDisableShortforms(); @@ -58,7 +59,7 @@ class create extends \moodleform { $mform->setType('name', PARAM_TEXT); // Event time start field. - $mform->addElement('date_time_selector', 'timestart', get_string('date')); + $mform->addElement('date_time_selector', 'timestart', get_string('date'), ['defaulttime' => $starttime]); // Add the select elements for the available event types. $this->add_event_type_elements($mform, $eventtypes); diff --git a/calendar/lib.php b/calendar/lib.php index 30cbaa42038..b088e7140ee 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -3534,6 +3534,7 @@ function calendar_output_fragment_event_form($args) { $html = ''; $data = null; $eventid = isset($args['eventid']) ? clean_param($args['eventid'], PARAM_INT) : null; + $starttime = isset($args['starttime']) ? clean_param($args['starttime'], PARAM_INT) : null; $event = null; $hasformdata = isset($args['formdata']) && !empty($args['formdata']); $formoptions = []; @@ -3546,6 +3547,10 @@ function calendar_output_fragment_event_form($args) { $formoptions['haserror'] = clean_param($args['haserror'], PARAM_BOOL); } + if ($starttime) { + $formoptions['starttime'] = $starttime; + } + if (is_null($eventid)) { $mform = new \core_calendar\local\event\forms\create( null, diff --git a/calendar/templates/month_detailed.mustache b/calendar/templates/month_detailed.mustache index 19b12ffc77d..9d170862943 100644 --- a/calendar/templates/month_detailed.mustache +++ b/calendar/templates/month_detailed.mustache @@ -31,7 +31,7 @@ { } }} - +
{{> core_calendar/month_header }} {{> core_calendar/month_navigation }} @@ -51,17 +51,19 @@ {{/prepadding}} {{#days}} -
  + data-drop-zone="true" + data-region="day" + data-new-event-timestamp="{{neweventtimestamp}}">
{{#events.0}} - {{mday}} + {{mday}} {{/events.0}} {{^events.0}} {{mday}} @@ -75,6 +77,7 @@ {{/underway}} {{^underway}}
  • - +
    {{#js}} require(['jquery', 'core_calendar/drag_drop'], function($, DragDrop) { var root = $('#month-detailed-{{uniqid}}'); diff --git a/theme/boost/scss/moodle/calendar.scss b/theme/boost/scss/moodle/calendar.scss index 47632cd7803..df6829ee144 100644 --- a/theme/boost/scss/moodle/calendar.scss +++ b/theme/boost/scss/moodle/calendar.scss @@ -100,6 +100,10 @@ $calendarEventUserColor: #dce7ec !default; // Pale blue. td { height: 5em; } + + .clickable:hover { + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12); + } } .calendar-controls { @@ -122,8 +126,12 @@ $calendarEventUserColor: #dce7ec !default; // Pale blue. .calendar_event_site, .calendar_event_group, .calendar_event_user { - border-width: 1px 1px 1px 12px; - border-style: solid; + &:hover { + a { + color: $link-hover-color; + text-decoration: $link-hover-decoration; + } + } } .calendar_event_course { diff --git a/theme/boost/scss/moodle/core.scss b/theme/boost/scss/moodle/core.scss index 966d885cca8..f7a36efe5de 100644 --- a/theme/boost/scss/moodle/core.scss +++ b/theme/boost/scss/moodle/core.scss @@ -2155,3 +2155,7 @@ $footer-link-color: $bg-inverse-link-color !default; [data-drag-type="move"] { cursor: move; } + +.clickable { + cursor: pointer; +} diff --git a/theme/bootstrapbase/less/moodle/calendar.less b/theme/bootstrapbase/less/moodle/calendar.less index 59fdeb91b79..d89dd37fd03 100644 --- a/theme/bootstrapbase/less/moodle/calendar.less +++ b/theme/bootstrapbase/less/moodle/calendar.less @@ -94,6 +94,10 @@ td { height: 5em; } + + .clickable:hover { + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12); + } } .calendar-controls { .previous, @@ -112,8 +116,12 @@ .calendar_event_site, .calendar_event_group, .calendar_event_user { - border-width: 1px 1px 1px 12px; - border-style: solid; + &:hover { + a { + color: @linkColorHover; + text-decoration: underline; + } + } } .calendar_event_course { border-color: @calendarEventCourseColor; diff --git a/theme/bootstrapbase/less/moodle/core.less b/theme/bootstrapbase/less/moodle/core.less index 1a47442186d..85e2608c04a 100644 --- a/theme/bootstrapbase/less/moodle/core.less +++ b/theme/bootstrapbase/less/moodle/core.less @@ -2381,3 +2381,7 @@ h3.sectionname .inplaceeditable.inplaceeditingon .editinstructions { } } } + +.clickable { + cursor: pointer; +} diff --git a/theme/bootstrapbase/style/moodle.css b/theme/bootstrapbase/style/moodle.css index 0772ef9f0c2..70102d31a8f 100644 --- a/theme/bootstrapbase/style/moodle.css +++ b/theme/bootstrapbase/style/moodle.css @@ -4774,6 +4774,9 @@ h3.sectionname .inplaceeditable.inplaceeditingon .editinstructions { visibility: visible; transition: opacity 0.15s 0.5s, visibility 0.15s 0.5s; } +.clickable { + cursor: pointer; +} /* admin.less */ .formtable tbody th { font-weight: normal; @@ -5618,6 +5621,9 @@ img.iconsmall { .path-calendar .maincalendar .calendarmonth td { height: 5em; } +.path-calendar .maincalendar .calendarmonth .clickable:hover { + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); +} .path-calendar .maincalendar .calendar-controls .previous, .path-calendar .maincalendar .calendar-controls .next { width: 30%; @@ -5629,12 +5635,12 @@ img.iconsmall { width: 98%; margin: 10px auto; } -.path-calendar .maincalendar .calendar_event_course, -.path-calendar .maincalendar .calendar_event_site, -.path-calendar .maincalendar .calendar_event_group, -.path-calendar .maincalendar .calendar_event_user { - border-width: 1px 1px 1px 12px; - border-style: solid; +.path-calendar .maincalendar .calendar_event_course:hover a, +.path-calendar .maincalendar .calendar_event_site:hover a, +.path-calendar .maincalendar .calendar_event_group:hover a, +.path-calendar .maincalendar .calendar_event_user:hover a { + color: #003d5c; + text-decoration: underline; } .path-calendar .maincalendar .calendar_event_course { border-color: #ffd3bd;