Commit | Line | Data |
---|---|---|
e695d9d0 BB |
1 | // This file is part of Moodle - http://moodle.org/ |
2 | // | |
3 | // Moodle is free software: you can redistribute it and/or modify | |
4 | // it under the terms of the GNU General Public License as published by | |
5 | // the Free Software Foundation, either version 3 of the License, or | |
6 | // (at your option) any later version. | |
7 | // | |
8 | // Moodle is distributed in the hope that it will be useful, | |
9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | // GNU General Public License for more details. | |
12 | // | |
13 | // You should have received a copy of the GNU General Public License | |
14 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
15 | ||
16 | /** | |
17 | * Content bank UI actions. | |
18 | * | |
19 | * @module core_contentbank/sort | |
20 | * @package core_contentbank | |
21 | * @copyright 2020 Bas Brands <bas@moodle.com> | |
22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
23 | */ | |
24 | ||
c393d818 | 25 | import selectors from './selectors'; |
e695d9d0 BB |
26 | import {get_string as getString} from 'core/str'; |
27 | import Prefetch from 'core/prefetch'; | |
c393d818 BB |
28 | import Ajax from 'core/ajax'; |
29 | import Notification from 'core/notification'; | |
e695d9d0 | 30 | |
e695d9d0 BB |
31 | /** |
32 | * Set up the contentbank views. | |
33 | * | |
34 | * @method init | |
35 | */ | |
36 | export const init = () => { | |
37 | const contentBank = document.querySelector(selectors.regions.contentbank); | |
38 | Prefetch.prefetchStrings('contentbank', ['sortbyx', 'sortbyxreverse', 'contentname', | |
39 | 'lastmodified', 'size', 'type']); | |
40 | registerListenerEvents(contentBank); | |
41 | }; | |
42 | ||
e695d9d0 BB |
43 | /** |
44 | * Register contentbank related event listeners. | |
45 | * | |
46 | * @method registerListenerEvents | |
47 | * @param {HTMLElement} contentBank The DOM node of the content bank | |
48 | */ | |
49 | const registerListenerEvents = (contentBank) => { | |
50 | ||
51 | // The search. | |
52 | const fileArea = document.querySelector(selectors.regions.filearea); | |
53 | const shownItems = fileArea.querySelectorAll(selectors.elements.listitem); | |
54 | ||
55 | // The view buttons. | |
56 | const viewGrid = contentBank.querySelector(selectors.actions.viewgrid); | |
57 | const viewList = contentBank.querySelector(selectors.actions.viewlist); | |
58 | ||
59 | viewGrid.addEventListener('click', () => { | |
60 | contentBank.classList.remove('view-list'); | |
61 | contentBank.classList.add('view-grid'); | |
62 | viewGrid.classList.add('active'); | |
63 | viewList.classList.remove('active'); | |
c393d818 | 64 | setViewListPreference(false); |
e695d9d0 BB |
65 | }); |
66 | ||
67 | viewList.addEventListener('click', () => { | |
68 | contentBank.classList.remove('view-grid'); | |
69 | contentBank.classList.add('view-list'); | |
70 | viewList.classList.add('active'); | |
71 | viewGrid.classList.remove('active'); | |
c393d818 | 72 | setViewListPreference(true); |
e695d9d0 BB |
73 | }); |
74 | ||
75 | // Sort by file name alphabetical | |
76 | const sortByName = contentBank.querySelector(selectors.actions.sortname); | |
77 | sortByName.addEventListener('click', () => { | |
78 | const ascending = updateSortButtons(contentBank, sortByName); | |
79 | updateSortOrder(fileArea, shownItems, 'data-file', ascending); | |
80 | }); | |
81 | ||
82 | // Sort by date. | |
83 | const sortByDate = contentBank.querySelector(selectors.actions.sortdate); | |
84 | sortByDate.addEventListener('click', () => { | |
85 | const ascending = updateSortButtons(contentBank, sortByDate); | |
86 | updateSortOrder(fileArea, shownItems, 'data-timemodified', ascending); | |
87 | }); | |
88 | ||
89 | // Sort by size. | |
90 | const sortBySize = contentBank.querySelector(selectors.actions.sortsize); | |
91 | sortBySize.addEventListener('click', () => { | |
92 | const ascending = updateSortButtons(contentBank, sortBySize); | |
93 | updateSortOrder(fileArea, shownItems, 'data-bytes', ascending); | |
94 | }); | |
95 | ||
96 | // Sort by type | |
97 | const sortByType = contentBank.querySelector(selectors.actions.sorttype); | |
98 | sortByType.addEventListener('click', () => { | |
99 | const ascending = updateSortButtons(contentBank, sortByType); | |
100 | updateSortOrder(fileArea, shownItems, 'data-type', ascending); | |
101 | }); | |
102 | }; | |
103 | ||
c393d818 BB |
104 | |
105 | /** | |
106 | * Set the contentbank user preference in list view | |
107 | * | |
108 | * @param {Bool} viewList view ContentBank as list. | |
109 | * @return {Promise} Repository promise. | |
110 | */ | |
111 | const setViewListPreference = function(viewList) { | |
112 | ||
113 | // If the given status is not hidden, the preference has to be deleted with a null value. | |
114 | if (viewList === false) { | |
115 | viewList = null; | |
116 | } | |
117 | ||
118 | const request = { | |
119 | methodname: 'core_user_update_user_preferences', | |
120 | args: { | |
121 | preferences: [ | |
122 | { | |
123 | type: 'core_contentbank_view_list', | |
124 | value: viewList | |
125 | } | |
126 | ] | |
127 | } | |
128 | }; | |
129 | ||
130 | return Ajax.call([request])[0].catch(Notification.exception); | |
131 | }; | |
132 | ||
e695d9d0 BB |
133 | /** |
134 | * Update the sort button view. | |
135 | * | |
136 | * @method updateSortButtons | |
137 | * @param {HTMLElement} contentBank The DOM node of the contentbank button | |
138 | * @param {HTMLElement} sortButton The DOM node of the sort button | |
139 | * @return {Bool} sort ascending | |
140 | */ | |
141 | const updateSortButtons = (contentBank, sortButton) => { | |
142 | const sortButtons = contentBank.querySelectorAll(selectors.elements.sortbutton); | |
143 | ||
144 | sortButtons.forEach((button) => { | |
145 | if (button !== sortButton) { | |
146 | button.classList.remove('dir-asc'); | |
147 | button.classList.remove('dir-desc'); | |
148 | button.classList.add('dir-none'); | |
149 | ||
150 | updateButtonTitle(button, false); | |
151 | } | |
152 | }); | |
153 | ||
154 | let ascending = true; | |
155 | ||
156 | if (sortButton.classList.contains('dir-none')) { | |
157 | sortButton.classList.remove('dir-none'); | |
158 | sortButton.classList.add('dir-asc'); | |
159 | } else if (sortButton.classList.contains('dir-asc')) { | |
160 | sortButton.classList.remove('dir-asc'); | |
161 | sortButton.classList.add('dir-desc'); | |
162 | ascending = false; | |
163 | } else if (sortButton.classList.contains('dir-desc')) { | |
164 | sortButton.classList.remove('dir-desc'); | |
165 | sortButton.classList.add('dir-asc'); | |
166 | } | |
167 | ||
168 | updateButtonTitle(sortButton, ascending); | |
169 | ||
170 | return ascending; | |
171 | }; | |
172 | ||
173 | /** | |
174 | * Update the button title. | |
175 | * | |
176 | * @method updateButtonTitle | |
177 | * @param {HTMLElement} button Button to update | |
178 | * @param {Bool} ascending Sort direction | |
179 | * @return {Promise} string promise | |
180 | */ | |
181 | const updateButtonTitle = (button, ascending) => { | |
182 | ||
183 | const sortString = (ascending ? 'sortbyxreverse' : 'sortbyx'); | |
184 | ||
185 | return getString(button.dataset.string, 'contentbank') | |
186 | .then(columnName => { | |
187 | return getString(sortString, 'core', columnName); | |
188 | }) | |
189 | .then(sortByString => { | |
190 | button.setAttribute('title', sortByString); | |
191 | return sortByString; | |
192 | }) | |
193 | .catch(); | |
194 | }; | |
195 | ||
196 | /** | |
197 | * Update the sort order of the itemlist and update the DOM | |
198 | * | |
199 | * @method updateSortOrder | |
200 | * @param {HTMLElement} fileArea the Dom container for the itemlist | |
201 | * @param {Array} itemList Nodelist of Dom elements | |
202 | * @param {String} attribute, the attribut to sort on | |
203 | * @param {Bool} ascending, Sort Ascending | |
204 | */ | |
205 | const updateSortOrder = (fileArea, itemList, attribute, ascending) => { | |
206 | const sortList = [].slice.call(itemList).sort(function(a, b) { | |
207 | ||
208 | let aa = a.getAttribute(attribute); | |
209 | let bb = b.getAttribute(attribute); | |
210 | if (!isNaN(aa)) { | |
211 | aa = parseInt(aa); | |
212 | bb = parseInt(bb); | |
213 | } | |
214 | ||
215 | if (ascending) { | |
216 | return aa > bb ? 1 : -1; | |
217 | } else { | |
218 | return aa < bb ? 1 : -1; | |
219 | } | |
220 | }); | |
cd08d856 AN |
221 | sortList.forEach(listItem => fileArea.appendChild(listItem)); |
222 | }; |