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
 * Controls the fragment overview loadings.
18
 *
19
 * @module     core_course/local/overview/overviewpage
20
 * @copyright  2025 Ferran Recio <ferran@moodle.com>
21
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 */
23
 
24
import CourseContent from 'core_courseformat/local/content';
25
import {eventTypes as collapsableSectionEventTypes} from 'core/local/collapsable_section/events';
26
import Fragment from 'core/fragment';
27
import {getCurrentCourseEditor} from 'core_courseformat/courseeditor';
28
import Pending from 'core/pending';
29
import Templates from 'core/templates';
30
 
31
/**
32
 * Initialize the overview page.
33
 *
34
 * @param {String} selector The selector where the overview page is located.
35
 */
36
export const init = async(selector) => {
37
    const pageElement = document.querySelector(selector);
38
    if (!pageElement) {
39
        throw new Error('No elements found with the selector: ' + selector);
40
    }
41
 
42
    pageElement.addEventListener(
43
        collapsableSectionEventTypes.shown,
44
        event => {
45
            const fragmentElement = getFragmentContainer(event.target);
46
            if (!fragmentElement) {
47
                return;
48
            }
49
            loadFragmentContent(fragmentElement);
50
        }
51
    );
52
 
53
    // The overview page is considered an alternative course view page so it must
54
    // include the course content component to capture any possible action. For example,
55
    // capturing manual completion toggles.
56
    return new CourseContent({
57
        element: pageElement,
58
        reactive: getCurrentCourseEditor(),
59
    });
60
};
61
 
62
/**
63
 * Load the fragment content.
64
 *
65
 * @private
66
 * @param {HTMLElement} element The element where the fragment content will be loaded.
67
 */
68
const loadFragmentContent = (element) => {
69
    if (element.dataset.loaded) {
70
        return;
71
    }
72
 
73
    const pendingReload = new Pending(`course_overviewtable_${element.dataset.modname}`);
74
 
75
    const promise = Fragment.loadFragment(
76
        'core_course',
77
        'course_overview',
78
        element.dataset.contextid,
79
        {
80
            courseid: element.dataset.courseid,
81
            modname: element.dataset.modname,
82
        }
83
    );
84
 
85
    promise.then(async(html, js) => {
86
        Templates.runTemplateJS(js);
87
        element.innerHTML = html;
88
        // Templates.replaceNode(element, html, js);
89
        element.dataset.loaded = true;
90
        pendingReload.resolve();
91
        return true;
92
    }).catch(() => {
93
        pendingReload.resolve();
94
    });
95
};
96
 
97
/**
98
 * Get the fragment container.
99
 *
100
 * @private
101
 * @param {HTMLElement} element The element where the fragment container is located.
102
 * @return {HTMLElement|null} The fragment container.
103
 */
104
const getFragmentContainer = (element) => {
105
    const result = element.querySelector('[data-region="loading-icon-container"]');
106
    if (!result) {
107
        return null;
108
    }
109
    if (!result.dataset.contextid || !result.dataset.courseid || !result.dataset.modname) {
110
        throw new Error('The element is missing required data attributes.');
111
    }
112
    return result;
113
};