From 494bbae4504b4131f4b0342b0ccc7650a4f920f8 Mon Sep 17 00:00:00 2001 From: Michael Douchin Date: Tue, 4 Jun 2024 11:34:31 +0200 Subject: [PATCH] Presentation - Add page edit button & reload presentation on save --- assets/src/components/PresentationCards.js | 39 +++++++++--- assets/src/components/PresentationPage.js | 10 ++++ assets/src/modules/Presentation.js | 59 +++++++++++-------- .../templates/presentation_dock.tpl | 4 ++ lizmap/www/assets/css/presentation.css | 22 +++++++ 5 files changed, 101 insertions(+), 33 deletions(-) diff --git a/assets/src/components/PresentationCards.js b/assets/src/components/PresentationCards.js index e6fe393fd3..909cf9acee 100644 --- a/assets/src/components/PresentationCards.js +++ b/assets/src/components/PresentationCards.js @@ -42,6 +42,15 @@ export default class PresentationCards extends HTMLElement { // Render this.render(); + + // If a presentation was running, display it again + if (mainLizmap.presentation.ACTIVE_LIZMAP_PRESENTATION !== null) { + // Get active page + mainLizmap.presentation.runLizmapPresentation( + mainLizmap.presentation.ACTIVE_LIZMAP_PRESENTATION, + mainLizmap.presentation.LIZMAP_PRESENTATION_ACTIVE_PAGE_NUMBER + ); + } }) .catch(err => console.log(err)) @@ -261,7 +270,8 @@ export default class PresentationCards extends HTMLElement { // Recalculate page numbers let i = 1; - let pages = {}; + let pagesNumbers = {}; + let pagesIds = []; let presentationId = null; for (const child of item.parentElement.children) { if (!child.classList.contains('lizmap-presentation-page-preview')) { @@ -272,16 +282,29 @@ export default class PresentationCards extends HTMLElement { child.querySelector('h3.lizmap-presentation-page-preview-title > span').innerText = pageOrder; presentationId = child.dataset.presentationId; const pageId = child.dataset.pageId; - pages[pageId] = pageOrder; + pagesNumbers[pageId] = pageOrder; + pagesIds.push(pageId); i++; } - // Send new pages to the server - mainLizmap.presentation.setPresentationPagination(presentationId, pages) - .then(data => { - console.log('pagination modifiée'); - }) - .catch(err => console.log(err)) + if (presentationId !== null) { + // Set the component presentation pages object + const presentation = mainLizmap.presentation.getPresentationById(presentationId); + let newPages = []; + for (const i in pagesIds) { + const correspondingPage = presentation.pages.find(x => x.id === pagesIds[i]); + newPages.push(correspondingPage); + } + presentation.pages = newPages; + + // Send new pagesNumbers to the server + mainLizmap.presentation.setPresentationPagination(presentationId, pagesNumbers) + .then(data => { + console.log('pagination modifiée'); + + }) + .catch(err => console.log(err)) + } } function cancelDefault (e) { diff --git a/assets/src/components/PresentationPage.js b/assets/src/components/PresentationPage.js index 55af55ddcd..dba516dc70 100644 --- a/assets/src/components/PresentationPage.js +++ b/assets/src/components/PresentationPage.js @@ -58,6 +58,16 @@ export default class PresentationPage extends HTMLElement { const pageAnchor = this.querySelector('a.lizmap-presentation-page-anchor'); pageAnchor.setAttribute('name', this._properties['page_order']); + // Toolbar buttons + const editButton = this.querySelector('button.liz-presentation-edit.page'); + editButton.value = this._properties['id']; + if (editButton) { + editButton.addEventListener('click', function(event) { + const button = event.currentTarget; + const id = button.value; + mainLizmap.presentation.launchPresentationCreationForm('page', id); + }); + } // title of the page const pageTitle = this.querySelector('h2.lizmap-presentation-page-title'); pageTitle.innerHTML = this._properties['title']; diff --git a/assets/src/modules/Presentation.js b/assets/src/modules/Presentation.js index d2e3ef004b..de5e7248c0 100644 --- a/assets/src/modules/Presentation.js +++ b/assets/src/modules/Presentation.js @@ -37,17 +37,17 @@ export default class Presentation { /** * @string Active page uuid */ - activePageUuid = null; + LIZMAP_PRESENTATION_ACTIVE_PAGE_UUID = null; /** - * @string Active presentation number of pages + * @string Active page number */ - activePresentationPagesCount = 0; + LIZMAP_PRESENTATION_ACTIVE_PAGE_NUMBER = 1; /** - * @string Active page number + * @string Active presentation number of pages */ - activePageNumber = 1; + activePresentationPagesCount = 0; /** * OpenLayers vector layer to draw the presentation results @@ -155,11 +155,11 @@ export default class Presentation { return null; } + // Get presentation data from the PresentationCards component const presentationCards = document.querySelector('lizmap-presentation-cards'); if (presentationCards === null) { return null; } - for (const p in presentationCards.presentations) { const presentation = presentationCards.presentations[p]; if (presentation && presentation.id == presentationId) { @@ -235,8 +235,9 @@ export default class Presentation { * Run a Lizmap presentation. * * @param {integer} presentationId - The presentation id + * @param {integer} pageNumber - The page number to go to */ - async runLizmapPresentation(presentationId) { + async runLizmapPresentation(presentationId, pageNumber = 0) { if (!this.hasPresentations) { this.addMessage('No presentation found for the current Lizmap map !', 'error', 5000); @@ -258,7 +259,6 @@ export default class Presentation { // We allow only one active presentation at a time // We do not remove the active status of the button (btn-primary) this.resetLizmapPresentation(true, true, true, false); - try { // Reset its content from the template const slidesContainer = document.getElementById('lizmap-presentation-slides-container'); @@ -292,7 +292,7 @@ export default class Presentation { }; // Add the pages - let firstPage = null; + let targetPageElement = null; presentation.pages.forEach(page => { const presentationPage = document.createElement('lizmap-presentation-page'); presentationPage.dataset.uuid = page.uuid; @@ -310,8 +310,8 @@ export default class Presentation { observers[page.uuid].observe(presentationPage); // Store first page component - if (firstPage === null) { - firstPage = presentationPage; + if (targetPageElement === null || page.page_order == pageNumber) { + targetPageElement = presentationPage; } }) @@ -322,9 +322,10 @@ export default class Presentation { slidesContainer.classList.add('visible'); // Set first page as active - this.goToGivenPage(1); - if (firstPage !== null) { - mainLizmap.presentation.onPageVisible(firstPage, true); + let targetPageNumber = (pageNumber > 0) ? pageNumber : 1; + if (targetPageElement !== null) { + this.goToGivenPage(targetPageNumber); + mainLizmap.presentation.onPageVisible(targetPageElement, true); } /** @@ -448,7 +449,7 @@ export default class Presentation { slidesContainer.classList.add('visible'); slidesRestore.classList.remove('visible'); // We need to run the setInterfaceFromPage method to set the page & map width - const page = document.querySelector(`lizmap-presentation-page[data-number="${this.activePageNumber}"]`); + const page = document.querySelector(`lizmap-presentation-page[data-number="${this.LIZMAP_PRESENTATION_ACTIVE_PAGE_NUMBER}"]`); if (page) { this.setInterfaceFromPage(page); } @@ -460,7 +461,7 @@ export default class Presentation { * @param {integer} pageNumber The page number to go to */ goToGivenPage(pageNumber) { - // console.log(`from ${this.activePageNumber} to ${pageNumber}`); + // console.log(`from ${this.LIZMAP_PRESENTATION_ACTIVE_PAGE_NUMBER} to ${pageNumber}`); const targetAnchor = document.querySelector(`a.lizmap-presentation-page-anchor[name="${pageNumber}"]`); if (targetAnchor) { targetAnchor.scrollIntoView(); @@ -469,7 +470,7 @@ export default class Presentation { // Go to the previous page goToPreviousPage() { - const targetPage = parseInt(this.activePageNumber) - 1; + const targetPage = parseInt(this.LIZMAP_PRESENTATION_ACTIVE_PAGE_NUMBER) - 1; if (targetPage >= 1) { this.goToGivenPage(targetPage); } @@ -478,7 +479,7 @@ export default class Presentation { // Go to the next page goToNextPage() { // Get current page - const targetPage = parseInt(this.activePageNumber) + 1; + const targetPage = parseInt(this.LIZMAP_PRESENTATION_ACTIVE_PAGE_NUMBER) + 1; if (targetPage <= this.activePresentationPagesCount) { this.goToGivenPage(targetPage); } @@ -559,7 +560,6 @@ export default class Presentation { * @param {HTMLElement} page Lizmap presentation page component */ setInterfaceFromPage(page) { - console.log('setInterfaceFromPage'); // TODO page width must be set from page data const pageWidthClass = 'presentation-half'; const dockWidth = (pageWidthClass == 'presentation-half') ? '50%' : '100%'; @@ -590,19 +590,19 @@ export default class Presentation { let newPageVisible = null; // Set the global object page UUID if not set yet - if (this.activePageUuid === null) { - this.activePageUuid = uuid; + if (this.LIZMAP_PRESENTATION_ACTIVE_PAGE_UUID === null) { + this.LIZMAP_PRESENTATION_ACTIVE_PAGE_UUID = uuid; newPageVisible = uuid; } // Check if the active UUID is different from the given page uuid - if (uuid != this.activePageUuid) { - this.activePageUuid = uuid; + if (uuid != this.LIZMAP_PRESENTATION_ACTIVE_PAGE_UUID) { + this.LIZMAP_PRESENTATION_ACTIVE_PAGE_UUID = uuid; newPageVisible = uuid; } // Set the active page number - this.activePageNumber = page.dataset.number; + this.LIZMAP_PRESENTATION_ACTIVE_PAGE_NUMBER = page.dataset.number; // Store when the page has valid map properties (extent or tree state) let hasMapProperties = false; @@ -668,7 +668,7 @@ export default class Presentation { * Display the form to create a new presentation or a new page * * @param {string} itemType Type of item to edit: presentation or page. - * @param {null|number} id Id of the presentation. If null, it is a creation form. + * @param {null|number} id Id of the presentation or page. If null, it is a creation form. * @param {null|number} presentation_id Id of the parent presentation. Only for creation of page */ async launchPresentationCreationForm(itemType = 'presentation', id = null, presentation_id = null) { @@ -838,11 +838,20 @@ export default class Presentation { const itemType = formData.get('item_type'); const presentationId = (itemType == 'presentation') ? formData.get('id') : formData.get('presentation_id'); const cardsElement = document.querySelector('#presentation-list-container lizmap-presentation-cards'); + + // Setting this attribute detail to the presentation ID triggers the display of its details cardsElement.setAttribute('detail', presentationId); + + // Changing this attribute triggers the refresh of the content from server cardsElement.setAttribute('updated', 'done'); // Go back to the list of presentations mainLizmap.presentation.hideForm(); + + // If the presentation was running, refresh it + // It is done by the component PresentationCards since the change of the updated attribute + // triggers a request and here we cannot wait for it to finish + }, // callback when the form action returns errors diff --git a/lizmap/modules/presentation/templates/presentation_dock.tpl b/lizmap/modules/presentation/templates/presentation_dock.tpl index 0fb6a04b1d..17d058ae66 100644 --- a/lizmap/modules/presentation/templates/presentation_dock.tpl +++ b/lizmap/modules/presentation/templates/presentation_dock.tpl @@ -167,6 +167,10 @@