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
/**
17
 * Course course module item component.
18
 *
19
 * This component is used to control specific course modules interactions like drag and drop.
20
 *
21
 * @module     core_courseformat/local/content/section/cmitem
22
 * @class      core_courseformat/local/content/section/cmitem
23
 * @copyright  2021 Ferran Recio <ferran@moodle.com>
24
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25
 */
26
 
27
import DndCmItem from 'core_courseformat/local/courseeditor/dndcmitem';
28
 
29
export default class extends DndCmItem {
30
 
31
    /**
32
     * Constructor hook.
33
     */
34
    create() {
35
        // Optional component name for debugging.
36
        this.name = 'content_section_cmitem';
37
        // Default query selectors.
38
        this.selectors = {
39
            BULKSELECT: `[data-for='cmBulkSelect']`,
40
            BULKCHECKBOX: `[data-bulkcheckbox]`,
41
            CARD: `[data-region='activity-card']`,
42
            DRAGICON: `.editing_move`,
43
            INPLACEEDITABLE: `[data-inplaceeditablelink]`,
44
        };
45
        // Most classes will be loaded later by DndCmItem.
46
        this.classes = {
47
            LOCKED: 'editinprogress',
48
            HIDE: 'd-none',
49
            SELECTED: 'selected',
50
        };
51
        // We need our id to watch specific events.
52
        this.id = this.element.dataset.id;
53
    }
54
 
55
    /**
56
     * Initial state ready method.
57
     * @param {Object} state the state data
58
     */
59
    stateReady(state) {
60
        this.configDragDrop(this.id);
61
        this.getElement(this.selectors.DRAGICON)?.classList.add(this.classes.DRAGICON);
62
        this._refreshBulk({state});
63
    }
64
 
65
    /**
66
     * Component watchers.
67
     *
68
     * @returns {Array} of watchers
69
     */
70
    getWatchers() {
71
        return [
72
            {watch: `cm[${this.id}]:deleted`, handler: this.unregister},
73
            {watch: `cm[${this.id}]:updated`, handler: this._refreshCm},
74
            {watch: `bulk:updated`, handler: this._refreshBulk},
75
        ];
76
    }
77
 
78
    /**
79
     * Return the custom activity card drag shadow image.
80
     *
81
     * The element returned will be used when the user drags the card.
82
     *
83
     * @returns {HTMLElement}
84
     */
85
    setDragImage() {
86
        return this.getElement(this.selectors.CARD);
87
    }
88
 
89
    /**
90
     * Update a course index cm using the state information.
91
     *
92
     * @param {object} param
93
     * @param {Object} param.element details the update details.
94
     */
95
    _refreshCm({element}) {
96
        // Update classes.
97
        this.element.classList.toggle(this.classes.DRAGGING, element.dragging ?? false);
98
        this.element.classList.toggle(this.classes.LOCKED, element.locked ?? false);
99
        this.locked = element.locked;
100
    }
101
 
102
    /**
103
     * Update the bulk editing interface.
104
     *
105
     * @param {object} param
106
     * @param {Object} param.state the state data
107
     */
108
    _refreshBulk({state}) {
109
        const bulk = state.bulk;
110
        // For now, dragging elements in bulk is not possible.
111
        this.setDraggable(!bulk.enabled);
112
        // Convert the card into an active element in bulk mode.
113
        if (bulk.enabled) {
114
            this.element.dataset.action = 'toggleSelectionCm';
115
            this.element.dataset.preventDefault = 1;
116
        } else {
117
            this.element.removeAttribute('data-action');
118
            this.element.removeAttribute('data-preventDefault');
119
        }
120
 
121
        this.getElement(this.selectors.BULKSELECT)?.classList.toggle(this.classes.HIDE, !bulk.enabled);
122
 
123
        const disabled = !this._isCmBulkEnabled(bulk);
124
        const selected = this._isSelected(bulk);
125
        this._refreshActivityCard(bulk, selected);
126
        this._setCheckboxValue(selected, disabled);
127
    }
128
 
129
    /**
130
     * Update the activity card depending on the bulk selection.
131
     *
132
     * @param {Object} bulk the current bulk state data
133
     * @param {Boolean} selected if the activity is selected.
134
     */
135
    _refreshActivityCard(bulk, selected) {
136
        this.getElement(this.selectors.INPLACEEDITABLE)?.classList.toggle(this.classes.HIDE, bulk.enabled);
137
        this.getElement(this.selectors.CARD)?.classList.toggle(this.classes.SELECTED, selected);
138
        this.element.classList.toggle(this.classes.SELECTED, selected);
139
    }
140
 
141
    /**
142
     * Modify the checkbox element.
143
     * @param {Boolean} checked the new checked value
144
     * @param {Boolean} disabled the new disabled value
145
     */
146
    _setCheckboxValue(checked, disabled) {
147
        const checkbox = this.getElement(this.selectors.BULKCHECKBOX);
148
        if (!checkbox) {
149
            return;
150
        }
151
        checkbox.checked = checked;
152
        checkbox.disabled = disabled;
153
        // Is selectable is used to easily scan the page for bulk checkboxes.
154
        if (disabled) {
155
            checkbox.removeAttribute('data-is-selectable');
156
        } else {
157
            checkbox.dataset.isSelectable = 1;
158
        }
159
    }
160
 
161
    /**
162
     * Check if cm bulk selection is available.
163
     * @param {Object} bulk the current state bulk attribute
164
     * @returns {Boolean}
165
     */
166
    _isCmBulkEnabled(bulk) {
167
        if (!bulk.enabled) {
168
            return false;
169
        }
170
        return (bulk.selectedType === '' || bulk.selectedType === 'cm');
171
    }
172
 
173
    /**
174
     * Check if the cm id is part of the current bulk selection.
175
     * @param {Object} bulk the current state bulk attribute
176
     * @returns {Boolean}
177
     */
178
    _isSelected(bulk) {
179
        if (bulk.selectedType !== 'cm') {
180
            return false;
181
        }
182
        return bulk.selection.includes(this.id);
183
    }
184
}