Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
import {refreshTableContent} from 'core_table/dynamic';
17
import * as Selectors from 'core_table/local/dynamic/selectors';
18
import {call as fetchMany} from 'core/ajax';
19
import Pending from 'core/pending';
20
import {fetchNotifications} from 'core/notification';
21
 
22
let watching = false;
23
 
24
export default class {
25
    /**
26
     * @property {function[]} clickHandlers a list of handlers to call on click.
27
     */
28
    clickHandlers = [];
29
 
30
    constructor() {
31
        this.addClickHandler(this.handleStateToggle);
32
        this.addClickHandler(this.handleMoveUpDown);
33
        this.registerEventListeners();
34
    }
35
 
36
    /**
37
     * Initialise an instance of the class.
38
     *
39
     * This is just a way of making it easier to initialise an instance of the class from PHP.
40
     */
41
    static init() {
42
        if (watching) {
43
            return;
44
        }
45
        watching = true;
46
        new this();
47
    }
48
 
49
    /**
50
     * Add a click handler to the list of handlers.
51
     *
52
     * @param {Function} handler A handler to call on a click event
53
     */
54
    addClickHandler(handler) {
55
        this.clickHandlers.push(handler.bind(this));
56
    }
57
 
58
    /**
59
     * Register the event listeners for this instance.
60
     */
61
    registerEventListeners() {
62
        document.addEventListener('click', function(e) {
63
            const tableRoot = this.getTableRoot(e);
64
 
65
            if (!tableRoot) {
66
                return;
67
            }
68
 
69
            this.clickHandlers.forEach((handler) => handler(tableRoot, e));
70
        }.bind(this));
71
    }
72
 
73
    /**
74
     * Get the table root from an event.
75
     *
76
     * @param {Event} e
77
     * @returns {HTMLElement|bool}
78
     */
79
    getTableRoot(e) {
80
        const tableRoot = e.target.closest(Selectors.main.region);
81
        if (!tableRoot) {
82
            return false;
83
        }
84
 
85
        return tableRoot;
86
    }
87
 
88
    /**
89
     * Set the plugin state (enabled or disabled)
90
     *
91
     * @param {string} methodname The web service to call
92
     * @param {string} plugin The name of the plugin to set the state for
93
     * @param {number} state The state to set
94
     * @returns {Promise}
95
     */
96
    setPluginState(methodname, plugin, state) {
97
        return fetchMany([{
98
            methodname,
99
            args: {
100
                plugin,
101
                state,
102
            },
103
        }])[0];
104
    }
105
 
106
    setPluginOrder(methodname, plugin, direction) {
107
        return fetchMany([{
108
            methodname,
109
            args: {
110
                plugin,
111
                direction,
112
            },
113
        }])[0];
114
    }
115
 
116
    /**
117
     * Handle state toggling.
118
     *
119
     * @param {HTMLElement} tableRoot
120
     * @param {Event} e
121
     */
122
    async handleStateToggle(tableRoot, e) {
123
        const stateToggle = e.target.closest('[data-action="togglestate"][data-toggle-method]');
124
        if (stateToggle) {
125
            e.preventDefault();
126
            const pendingPromise = new Pending('core_table/dynamic:togglestate');
127
 
128
            await this.setPluginState(
129
                stateToggle.dataset.toggleMethod,
130
                stateToggle.dataset.plugin,
131
                stateToggle.dataset.state === '1' ? 0 : 1
132
            );
133
 
134
            const [updatedRoot] = await Promise.all([
135
                refreshTableContent(tableRoot),
136
                fetchNotifications(),
137
            ]);
138
 
139
            // Refocus on the link that as pressed in the first place.
140
            updatedRoot.querySelector(`[data-action="togglestate"][data-plugin="${stateToggle.dataset.plugin}"]`).focus();
141
            pendingPromise.resolve();
142
        }
143
    }
144
 
145
    async handleMoveUpDown(tableRoot, e) {
146
        const actionLink = e.target.closest('[data-action="move"][data-method][data-direction]');
147
        if (!actionLink) {
148
            return;
149
        }
150
 
151
        e.preventDefault();
152
 
153
        const pendingPromise = new Pending('core_table/dynamic:processAction');
154
 
155
        await this.setPluginOrder(
156
            actionLink.dataset.method,
157
            actionLink.dataset.plugin,
158
            actionLink.dataset.direction === 'up' ? -1 : 1,
159
        );
160
 
161
        const [updatedRoot] = await Promise.all([
162
            refreshTableContent(tableRoot),
163
            fetchNotifications(),
164
        ]);
165
 
166
        // Refocus on the link that as pressed in the first place.
167
        const exactMatch = updatedRoot.querySelector(
168
            `[data-action="move"][data-plugin="${actionLink.dataset.plugin}"][data-direction="${actionLink.dataset.direction}"]`
169
        );
170
        if (exactMatch) {
171
            exactMatch.focus();
172
        } else {
173
            // The move link is not present anymore, so we need to focus on the other one.
174
            updatedRoot.querySelector(`[data-action="move"][data-plugin="${actionLink.dataset.plugin}"]`)?.focus();
175
        }
176
 
177
        pendingPromise.resolve();
178
    }
179
}