HEX
Server: LiteSpeed
System: Linux server.zepintelhosting.com 4.18.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64
User: enamadmin (1026)
PHP: 8.2.30
Disabled: exec,system,passthru,shell_exec,proc_open,popen,apache_child_terminate
Upload Files
File: /home/enamadmin/public_html/aaelearningb/ai/placement/courseassist/amd/build/placement.min.js.map
{"version":3,"file":"placement.min.js","sources":["../src/placement.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Module to load and render the tools for the AI assist plugin.\n *\n * @module     aiplacement_courseassist/placement\n * @copyright  2024 Huong Nguyen <huongnv13@gmail.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Templates from 'core/templates';\nimport Ajax from 'core/ajax';\nimport 'core/copy_to_clipboard';\nimport Notification from 'core/notification';\nimport Selectors from 'aiplacement_courseassist/selectors';\nimport Policy from 'core_ai/policy';\nimport AIHelper from 'core_ai/helper';\nimport DrawerEvents from 'core/drawer_events';\nimport {subscribe} from 'core/pubsub';\nimport * as MessageDrawerHelper from 'core_message/message_drawer_helper';\n\nconst AICourseAssist = class {\n\n    /**\n     * The user ID.\n     * @type {Integer}\n     */\n    userId;\n    /**\n     * The context ID.\n     * @type {Integer}\n     */\n    contextId;\n\n    /**\n     * Constructor.\n     * @param {Integer} userId The user ID.\n     * @param {Integer} contextId The context ID.\n     */\n    constructor(userId, contextId) {\n        this.userId = userId;\n        this.contextId = contextId;\n\n        this.aiDrawerElement = document.querySelector(Selectors.ELEMENTS.AIDRAWER);\n        this.aiDrawerBodyElement = document.querySelector(Selectors.ELEMENTS.AIDRAWER_BODY);\n        this.pageElement = document.querySelector(Selectors.ELEMENTS.PAGE);\n\n        this.registerEventListeners();\n    }\n\n    /**\n     * Register event listeners.\n     */\n    registerEventListeners() {\n        document.addEventListener('click', async(e) => {\n            const summariseAction = e.target.closest(Selectors.ACTIONS.SUMMARY);\n            if (summariseAction) {\n                e.preventDefault();\n                this.toggleAIDrawer();\n                const isPolicyAccepted = await this.isPolicyAccepted();\n                if (!isPolicyAccepted) {\n                    // Display policy.\n                    this.displayPolicy();\n                    return;\n                }\n                // Display summary.\n                this.displaySummary();\n            }\n        });\n\n        // Close AI drawer if message drawer is shown.\n        subscribe(DrawerEvents.DRAWER_SHOWN, () => {\n            if (this.isAIDrawerOpen()) {\n                this.closeAIDrawer();\n            }\n        });\n    }\n\n    /**\n     * Register event listeners for the policy.\n     */\n    registerPolicyEventListeners() {\n        const acceptAction = document.querySelector(Selectors.ACTIONS.ACCEPT);\n        const declineAction = document.querySelector(Selectors.ACTIONS.DECLINE);\n        if (acceptAction) {\n            acceptAction.addEventListener('click', (e) => {\n                e.preventDefault();\n                this.acceptPolicy().then(() => {\n                    return this.displaySummary();\n                }).catch(Notification.exception);\n            });\n        }\n        if (declineAction) {\n            declineAction.addEventListener('click', (e) => {\n                e.preventDefault();\n                this.closeAIDrawer();\n            });\n        }\n    }\n\n    /**\n     * Register event listeners for the error.\n     */\n    registerErrorEventListeners() {\n        const retryAction = document.querySelector(Selectors.ACTIONS.RETRY);\n        if (retryAction) {\n            retryAction.addEventListener('click', (e) => {\n                e.preventDefault();\n                this.aiDrawerBodyElement.dataset.hasdata = '0';\n                this.displaySummary();\n            });\n        }\n    }\n\n    /**\n     * Register event listeners for the response.\n     */\n    registerResponseEventListeners() {\n        const regenerateAction = document.querySelector(Selectors.ACTIONS.REGENERATE);\n        if (regenerateAction) {\n            regenerateAction.addEventListener('click', (e) => {\n                e.preventDefault();\n                this.aiDrawerBodyElement.dataset.hasdata = '0';\n                this.displaySummary();\n            });\n        }\n    }\n\n    registerLoadingEventListeners() {\n        const cancelAction = document.querySelector(Selectors.ACTIONS.CANCEL);\n        if (cancelAction) {\n            cancelAction.addEventListener('click', (e) => {\n                e.preventDefault();\n                this.setRequestCancelled();\n                this.toggleAIDrawer();\n            });\n        }\n    }\n\n    /**\n     * Check if the AI drawer is open.\n     * @return {boolean} True if the AI drawer is open, false otherwise.\n     */\n    isAIDrawerOpen() {\n        return this.aiDrawerElement.classList.contains('show');\n    }\n\n    /**\n     * Check if the request is cancelled.\n     * @return {boolean} True if the request is cancelled, false otherwise.\n     */\n    isRequestCancelled() {\n        return this.aiDrawerBodyElement.dataset.cancelled === '1';\n    }\n\n    setRequestCancelled() {\n        this.aiDrawerBodyElement.dataset.cancelled = '1';\n    }\n\n    /**\n     * Open the AI drawer.\n     */\n    openAIDrawer() {\n        // Close message drawer if it is shown.\n        MessageDrawerHelper.hide();\n        this.aiDrawerElement.classList.add('show');\n        this.aiDrawerBodyElement.setAttribute('aria-live', 'polite');\n        if (!this.pageElement.classList.contains('show-drawer-right')) {\n            this.addPadding();\n        }\n        // Disable the summary button.\n        this.disableSummaryButton();\n    }\n\n    /**\n     * Close the AI drawer.\n     */\n    closeAIDrawer() {\n        this.aiDrawerElement.classList.remove('show');\n        this.aiDrawerBodyElement.removeAttribute('aria-live');\n        if (this.pageElement.classList.contains('show-drawer-right') && this.aiDrawerBodyElement.dataset.removepadding === '1') {\n            this.removePadding();\n        }\n        // Enable the summary button.\n        this.enableSummaryButton();\n    }\n\n    /**\n     * Toggle the AI drawer.\n     */\n    toggleAIDrawer() {\n        if (this.isAIDrawerOpen()) {\n            this.closeAIDrawer();\n        } else {\n            this.openAIDrawer();\n        }\n    }\n\n    /**\n     * Add padding to the page to make space for the AI drawer.\n     */\n    addPadding() {\n        this.pageElement.classList.add('show-drawer-right');\n        this.aiDrawerBodyElement.dataset.removepadding = '1';\n    }\n\n    /**\n     * Remove padding from the page.\n     */\n    removePadding() {\n        this.pageElement.classList.remove('show-drawer-right');\n        this.aiDrawerBodyElement.dataset.removepadding = '0';\n    }\n\n    /**\n     * Disable the summary button.\n     */\n    disableSummaryButton() {\n        const summaryButton = document.querySelector(Selectors.ACTIONS.SUMMARY);\n        if (summaryButton) {\n            summaryButton.setAttribute('disabled', 1);\n        }\n    }\n\n    /**\n     * Enable the summary button and focus on it.\n     */\n    enableSummaryButton() {\n        const summaryButton = document.querySelector(Selectors.ACTIONS.SUMMARY);\n        if (summaryButton) {\n            summaryButton.removeAttribute('disabled');\n            summaryButton.focus();\n        }\n    }\n\n    /**\n     * Check if the policy is accepted.\n     * @return {bool} True if the policy is accepted, false otherwise.\n     */\n    async isPolicyAccepted() {\n        return await Policy.getPolicyStatus(this.userId);\n    }\n\n    /**\n     * Accept the policy.\n     * @return {Promise<Object>}\n     */\n    acceptPolicy() {\n        return Policy.acceptPolicy();\n    }\n\n    /**\n     * Check if the AI drawer has generated content or not.\n     * @return {boolean} True if the AI drawer has generated content, false otherwise.\n     */\n    hasGeneratedContent() {\n        return this.aiDrawerBodyElement.dataset.hasdata === '1';\n    }\n\n    /**\n     * Display the policy.\n     */\n    displayPolicy() {\n        Templates.render('core_ai/policyblock', {}).then((html) => {\n            this.aiDrawerBodyElement.innerHTML = html;\n            this.registerPolicyEventListeners();\n            return;\n        }).catch(Notification.exception);\n    }\n\n    /**\n     * Display the loading spinner.\n     */\n    displayLoading() {\n        Templates.render('aiplacement_courseassist/loading', {}).then((html) => {\n            this.aiDrawerBodyElement.innerHTML = html;\n            this.registerLoadingEventListeners();\n            return;\n        }).catch(Notification.exception);\n    }\n\n    /**\n     * Display the summary.\n     */\n    async displaySummary() {\n        if (!this.hasGeneratedContent()) {\n            // Display loading spinner.\n            this.displayLoading();\n            // Clear the drawer content to prevent sending some unnecessary content.\n            this.aiDrawerBodyElement.innerHTML = '';\n            const request = {\n                methodname: 'aiplacement_courseassist_summarise_text',\n                args: {\n                    contextid: this.contextId,\n                    prompttext: this.getTextContent(),\n                }\n            };\n            try {\n                const responseObj = await Ajax.call([request])[0];\n                if (responseObj.error) {\n                    this.displayError();\n                    return;\n                } else {\n                    if (!this.isRequestCancelled()) {\n                        // Replace double line breaks with <br> and with </p><p> for paragraphs.\n                        const generatedContent = AIHelper.replaceLineBreaks(responseObj.generatedcontent);\n                        this.displayResponse(generatedContent);\n                        return;\n                    } else {\n                        this.aiDrawerBodyElement.dataset.cancelled = '0';\n                    }\n                }\n            } catch (error) {\n                window.console.log(error);\n                this.displayError();\n            }\n        }\n    }\n\n    /**\n     * Display the response.\n     * @param {String} content The content to display.\n     */\n    displayResponse(content) {\n        Templates.render('aiplacement_courseassist/response', {content: content}).then((html) => {\n            this.aiDrawerBodyElement.innerHTML = html;\n            this.aiDrawerBodyElement.dataset.hasdata = '1';\n            this.registerResponseEventListeners();\n            return;\n        }).catch(Notification.exception);\n    }\n\n    /**\n     * Display the error.\n     */\n    displayError() {\n        Templates.render('aiplacement_courseassist/error', {}).then((html) => {\n            this.aiDrawerBodyElement.innerHTML = html;\n            this.registerErrorEventListeners();\n            return;\n        }).catch(Notification.exception);\n    }\n\n    /**\n     * Get the text content of the main region.\n     * @return {String} The text content.\n     */\n    getTextContent() {\n        const mainRegion = document.querySelector(Selectors.ELEMENTS.MAIN_REGION);\n        return mainRegion.innerText || mainRegion.textContent;\n    }\n};\n\nexport default AICourseAssist;\n"],"names":["constructor","userId","contextId","aiDrawerElement","document","querySelector","Selectors","ELEMENTS","AIDRAWER","aiDrawerBodyElement","AIDRAWER_BODY","pageElement","PAGE","registerEventListeners","addEventListener","async","e","target","closest","ACTIONS","SUMMARY","preventDefault","toggleAIDrawer","this","isPolicyAccepted","displayPolicy","displaySummary","DrawerEvents","DRAWER_SHOWN","isAIDrawerOpen","closeAIDrawer","registerPolicyEventListeners","acceptAction","ACCEPT","declineAction","DECLINE","acceptPolicy","then","catch","Notification","exception","registerErrorEventListeners","retryAction","RETRY","dataset","hasdata","registerResponseEventListeners","regenerateAction","REGENERATE","registerLoadingEventListeners","cancelAction","CANCEL","setRequestCancelled","classList","contains","isRequestCancelled","cancelled","openAIDrawer","MessageDrawerHelper","hide","add","setAttribute","addPadding","disableSummaryButton","remove","removeAttribute","removepadding","removePadding","enableSummaryButton","summaryButton","focus","Policy","getPolicyStatus","hasGeneratedContent","render","html","innerHTML","displayLoading","request","methodname","args","contextid","prompttext","getTextContent","responseObj","Ajax","call","error","displayError","generatedContent","AIHelper","replaceLineBreaks","generatedcontent","displayResponse","window","console","log","content","mainRegion","MAIN_REGION","innerText","textContent"],"mappings":"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"}