%PDF- %PDF-
Direktori : /home/vacivi36/ava/blocks/timeline/amd/src/ |
Current File : /home/vacivi36/ava/blocks/timeline/amd/src/view_nav.js |
// This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Manage the timeline view navigation for the timeline block. * * @copyright 2018 Ryan Wyllie <ryan@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ define( [ 'jquery', 'core/custom_interaction_events', 'block_timeline/view', 'core/ajax', 'core/notification', 'core/utils' ], function( $, CustomEvents, View, Ajax, Notification, Utils ) { var SELECTORS = { TIMELINE_DAY_FILTER: '[data-region="day-filter"]', TIMELINE_DAY_FILTER_OPTION: '[data-from]', TIMELINE_VIEW_SELECTOR: '[data-region="view-selector"]', DATA_DAYS_OFFSET: '[data-days-offset]', DATA_DAYS_LIMIT: '[data-days-limit]', TIMELINE_SEARCH_INPUT: '[data-action="search"]', TIMELINE_SEARCH_CLEAR_ICON: '[data-action="clearsearch"]', NO_COURSES_EMPTY_MESSAGE: '[data-region="no-courses-empty-message"]', }; /** * Generic handler to persist user preferences * * @param {string} type The name of the attribute you're updating * @param {string} value The value of the attribute you're updating */ var updateUserPreferences = function(type, value) { var request = { methodname: 'core_user_update_user_preferences', args: { preferences: [ { type: type, value: value } ] } }; Ajax.call([request])[0] .fail(Notification.exception); }; /** * Event listener for the day selector ("Next 7 days", "Next 30 days", etc). * * @param {object} root The root element for the timeline block * @param {object} timelineViewRoot The root element for the timeline view */ var registerTimelineDaySelector = function(root, timelineViewRoot) { var timelineDaySelectorContainer = root.find(SELECTORS.TIMELINE_DAY_FILTER); CustomEvents.define(timelineDaySelectorContainer, [CustomEvents.events.activate]); timelineDaySelectorContainer.on( CustomEvents.events.activate, SELECTORS.TIMELINE_DAY_FILTER_OPTION, function(e, data) { // Update the user preference var filtername = $(e.currentTarget).data('filtername'); var type = 'block_timeline_user_filter_preference'; updateUserPreferences(type, filtername); var option = $(e.target).closest(SELECTORS.TIMELINE_DAY_FILTER_OPTION); if (option.attr('aria-current') == 'true') { // If it's already active then we don't need to do anything. return; } var daysOffset = option.attr('data-from'); var daysLimit = option.attr('data-to'); var elementsWithDaysOffset = root.find(SELECTORS.DATA_DAYS_OFFSET); elementsWithDaysOffset.attr('data-days-offset', daysOffset); if (daysLimit != undefined) { elementsWithDaysOffset.attr('data-days-limit', daysLimit); } else { elementsWithDaysOffset.removeAttr('data-days-limit'); } if (option.attr('data-filtername') === 'overdue') { elementsWithDaysOffset.attr('data-filter-overdue', true); } else { elementsWithDaysOffset.removeAttr('data-filter-overdue'); } // Reset the views to reinitialise the event lists now that we've // updated the day limits. View.reset(timelineViewRoot); data.originalEvent.preventDefault(); } ); }; /** * Event listener for the "sort" button in the timeline navigation that allows for * changing between the timeline dates and courses views. * * On a view change we tell the timeline view module that the view has been shown * so that it can handle how to display the appropriate view. * * @param {object} root The root element for the timeline block * @param {object} timelineViewRoot The root element for the timeline view */ var registerViewSelector = function(root, timelineViewRoot) { var viewSelector = root.find(SELECTORS.TIMELINE_VIEW_SELECTOR); // Listen for when the user changes tab so that we can show the first set of courses // and load their events when they request the sort by courses view for the first time. viewSelector.on('shown shown.bs.tab', function(e) { View.shown(timelineViewRoot); $(e.target).removeClass('active'); }); // Event selector for user_sort CustomEvents.define(viewSelector, [CustomEvents.events.activate]); viewSelector.on(CustomEvents.events.activate, "[data-toggle='tab']", function(e) { var filtername = $(e.currentTarget).data('filtername'); var type = 'block_timeline_user_sort_preference'; updateUserPreferences(type, filtername); }); }; /** * Event listener for the "search" input field in the timeline navigation that allows for * searching the activity name, course name and activity type. * * @param {object} root The root element for the timeline block * @param {object} timelineViewRoot The root element for the timeline view */ const registerSearch = (root, timelineViewRoot) => { const searchInput = root.find(SELECTORS.TIMELINE_SEARCH_INPUT); const clearSearchIcon = root.find(SELECTORS.TIMELINE_SEARCH_CLEAR_ICON); searchInput.on('input', Utils.debounce(() => { if (searchInput.val() !== '') { activeSearchState(clearSearchIcon, timelineViewRoot); } else { clearSearchState(clearSearchIcon, timelineViewRoot); } }, 1000)); clearSearchIcon.on('click', () => { searchInput.val(''); clearSearchState(clearSearchIcon, timelineViewRoot); searchInput.focus(); }); }; /** * Show the clear search icon. * * @param {object} clearSearchIcon Clear search icon element. * @param {object} timelineViewRoot The root element for the timeline view */ const activeSearchState = (clearSearchIcon, timelineViewRoot) => { clearSearchIcon.removeClass('d-none'); View.reset(timelineViewRoot); }; /** * Hide the clear search icon. * * @param {object} clearSearchIcon Clear search icon element. * @param {object} timelineViewRoot The root element for the timeline view */ const clearSearchState = (clearSearchIcon, timelineViewRoot) => { clearSearchIcon.addClass('d-none'); View.reset(timelineViewRoot); }; /** * Initialise the timeline view navigation by adding event listeners to * the navigation elements. * * @param {object} root The root element for the timeline block * @param {object} timelineViewRoot The root element for the timeline view */ var init = function(root, timelineViewRoot) { root = $(root); registerViewSelector(root, timelineViewRoot); // Only need to handle filtering if the user is actively enrolled in a course. if (!root.find(SELECTORS.NO_COURSES_EMPTY_MESSAGE).length) { registerTimelineDaySelector(root, timelineViewRoot); registerSearch(root, timelineViewRoot); } }; return { init: init }; });