/** Class containing common UI functionalities */ class UIFactory { /** * Create and display a toast * @param {Object} options - The options to be passed to the Toaster class * @return {Object} The Toaster object */ toast(options) { const theToast = new Toaster(options); theToast.makeToast() theToast.show() return theToast } /** * Create and display a modal * @param {Object} options - The options to be passed to the ModalFactory class * @return {Object} The ModalFactory object */ modal (options) { const theModal = new ModalFactory(options); theModal.makeModal() theModal.show() return theModal } /** * Create and display a modal where the modal's content is fetched from the provided URL. * @param {string} url - The URL from which the modal's content should be fetched * @param {ModalFactory~POSTSuccessCallback} POSTSuccessCallback - The callback that handles successful form submission * @param {ModalFactory~POSTFailCallback} POSTFailCallback - The callback that handles form submissions errors and validation errors. * @return {Promise} Promise object resolving to the ModalFactory object */ modalFromURL (url, POSTSuccessCallback, POSTFailCallback) { return AJAXApi.quickFetchURL(url).then((modalHTML) => { const theModal = new ModalFactory({ rawHTML: modalHTML, POSTSuccessCallback: POSTSuccessCallback !== undefined ? POSTSuccessCallback : () => {}, POSTFailCallback: POSTFailCallback !== undefined ? POSTFailCallback : (errorMessage) => {}, }); theModal.makeModal(modalHTML) theModal.show() theModal.$modal.data('modalObject', theModal) return theModal }) } /** * Fetch HTML from the provided URL and override the $container's content. $statusNode allows to specify another HTML node to display the loading * @param {string} url - The URL from which the $container's content should be fetched * @param {(jQuery|string)} $container - The container that should hold the data fetched * @param {(jQuery|string)} [$statusNode=null] - A reference to a HTML node on which the loading animation should be displayed. If not provided, $container will be used * @return {Promise} Promise object resolving to the $container object after its content has been replaced */ reload (url, $container, $statusNode=null) { $container = $($container) $statusNode = $($statusNode) if (!$statusNode) { $statusNode = $container } return AJAXApi.quickFetchURL(url, { statusNode: $statusNode[0] }).then((theHTML) => { $container.replaceWith(theHTML) return $container }) } } /** Class representing a Toast */ class Toaster { /** * Create a Toast. * @param {Object} options - The options supported by Toaster#defaultOptions */ constructor(options) { this.options = Object.assign({}, Toaster.defaultOptions, options) this.bsToastOptions = { autohide: this.options.autohide, delay: this.options.delay, } } /** * @namespace * @property {number} id - The ID to be used for the toast's container * @property {string} title - The title's content of the toast * @property {string} muted - The muted's content of the toast * @property {string} body - The body's content of the toast * @property {string=('primary'|'secondary'|'success'|'danger'|'warning'|'info'|'light'|'dark'|'white'|'transparent')} variant - The variant of the toast * @property {boolean} autohide - If the toast show be hidden after some time defined by the delay * @property {number} delay - The number of milliseconds the toast should stay visible before being hidden * @property {string} titleHtml - The raw HTML title's content of the toast * @property {string} mutedHtml - The raw HTML muted's content of the toast * @property {string} bodyHtml - The raw HTML body's content of the toast * @property {boolean} closeButton - If the toast's title should include a close button */ static defaultOptions = { id: false, title: false, muted: false, body: false, variant: 'default', autohide: true, delay: 5000, titleHtml: false, mutedHtml: false, bodyHtml: false, closeButton: true, } /** Create the HTML of the toast and inject it into the DOM */ makeToast() { if (this.isValid()) { this.$toast = Toaster.buildToast(this.options) $('#mainToastContainer').append(this.$toast) } } /** Display the toast to the user and remove it from the DOM once it get hidden */ show() { if (this.isValid()) { var that = this this.$toast.toast(this.bsToastOptions) .toast('show') .on('hidden.bs.toast', function () { that.removeToast() }) } } /** Remove the toast from the DOM */ removeToast() { this.$toast.remove(); } /** * Check wheter a toast is valid * @return {boolean} Return true if the toast contains at least data to be rendered */ isValid() { return this.options.title !== false || this.options.titleHtml !== false || this.options.muted !== false || this.options.mutedHtml !== false || this.options.body !== false || this.options.bodyHtml !== false } /** * Build the toast HTML * @param {Object} options - The options supported by Toaster#defaultOptions to build the toast * @return {jQuery} The toast jQuery object */ static buildToast(options) { var $toast = $('