Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 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
 * The newchild component.
18
 *
19
 * This is a drop target for moving a category to an as-yet-nonexistant child list under another category.
20
 *
21
 * @module     qbank_managecategories/newchild
22
 * @class      qbank_managecategories/newchild
23
 */
24
 
25
import {BaseComponent, DragDrop} from 'core/reactive';
26
import {categorymanager} from 'qbank_managecategories/categorymanager';
27
import Tooltip from 'theme_boost/bootstrap/tooltip';
28
 
29
export default class extends BaseComponent {
30
    create(descriptor) {
31
        this.name = descriptor.element.id;
32
        this.selectors = {
33
            NEW_CHILD: '.qbank_managecategories-newchild',
34
            CATEGORY_ID: id => `#category-${id}`
35
        };
36
        this.classes = {
37
            DROP_TARGET: 'qbank_managecategories-droptarget',
38
        };
39
        this.ids = {
40
            CATEGORY: id => `category-${id}`,
41
        };
42
    }
43
 
44
    stateReady() {
45
        this.dragdrop = new DragDrop(this);
46
    }
47
 
48
    destroy() {
49
        // The draggable element must be unregistered.
50
        if (this.dragdrop !== undefined) {
51
            this.dragdrop.unregister();
52
            this.dragdrop = undefined;
53
        }
54
    }
55
 
56
    /**
57
     * Static method to create a component instance form the mustache template.
58
     *
59
     * @param {string} target the DOM main element or its ID
60
     * @param {object} selectors optional css selector overrides
61
     * @return {Component}
62
     */
63
    static init(target, selectors) {
64
        const targetElement = document.querySelector(target);
65
        return new this({
66
            element: targetElement,
67
            selectors,
68
            reactive: categorymanager,
69
        });
70
    }
71
 
72
    /**
73
     * Cannot drop a category as a new child of its own descendant.
74
     *
75
     * @param {Object} dropData
76
     * @return {boolean}
77
     */
78
    validateDropData(dropData) {
79
        if (this.getElement().closest(this.selectors.CATEGORY_ID(dropData.id))) {
80
            return false;
81
        }
82
        return true;
83
    }
84
 
85
    showDropZone(dropData, event) {
86
        const dropTarget = event.target.closest(this.selectors.NEW_CHILD);
87
        dropTarget.classList.add(this.classes.DROP_TARGET);
88
        Tooltip.getOrCreateInstance(dropTarget).show();
89
    }
90
 
91
    hideDropZone(dropData, event) {
92
        const dropTarget = event.target.closest(this.selectors.NEW_CHILD);
93
        dropTarget.classList.remove(this.classes.DROP_TARGET);
94
        Tooltip.getOrCreateInstance(dropTarget).hide();
95
    }
96
 
97
    drop(dropData, event) {
98
        const dropTarget = event.target.closest(this.selectors.NEW_CHILD);
99
 
100
        if (!dropTarget) {
101
            return;
102
        }
103
 
104
        const source = document.getElementById(this.ids.CATEGORY(dropData.id));
105
 
106
        if (!source) {
107
            return;
108
        }
109
 
110
        const targetParentId = dropTarget.dataset.parent;
111
 
112
        // Insert the category as the first child of the new parent.
113
        categorymanager.moveCategory(dropData.id, targetParentId);
114
    }
115
 
116
    /**
117
     * Watch for categories moving to a new parent.
118
     *
119
     * @return {Array} A list of watchers.
120
     */
121
    getWatchers() {
122
        return [
123
            // Watch for any category having its parent changed.
124
            {watch: `categories.parent:updated`, handler: this.checkNewChild},
125
        ];
126
    }
127
 
128
    /**
129
     * If an element now has this category as the parent, remove this new child target.
130
     *
131
     * @param {Object} args
132
     * @param {Element} args.element
133
     */
134
    checkNewChild({element}) {
135
        if (element.parent === parseInt(this.element.dataset.parent)) {
136
            this.remove();
137
        }
138
    }
139
}