diff --git a/cypress/e2e/slideshow.feature b/cypress/e2e/slideshow.feature new file mode 100644 index 000000000..ff2c4c2ec --- /dev/null +++ b/cypress/e2e/slideshow.feature @@ -0,0 +1,31 @@ +Feature: Slideshow + + Scenario: I view a dashboard in slideshow + Given I open the "Delivery" dashboard + When I click the slideshow button + Then item 1 is shown in fullscreen + When I click the next slide button + Then item 2 is shown in fullscreen + When I click the previous slide button + Then item 1 is shown in fullscreen + When I click the exit slideshow button + Then the normal view is shown + + + Scenario: I view fullscreen on the second item of the dashboard + Given I open the "Delivery" dashboard + When I click the fullscreen button on the second item + Then item 2 is shown in fullscreen + When I click the exit slideshow button + Then the normal view is shown + + Scenario: I view fullscreen on the third item of the dashboard and navigate backwards + Given I open the "Delivery" dashboard + When I click the fullscreen button on the third item + Then item 3 is shown in fullscreen + When I click the previous slide button + Then item 2 is shown in fullscreen + When I click the previous slide button + Then item 1 is shown in fullscreen + When I click the exit slideshow button + Then the normal view is shown diff --git a/cypress/e2e/slideshow/index.js b/cypress/e2e/slideshow/index.js new file mode 100644 index 000000000..6a8a6a12a --- /dev/null +++ b/cypress/e2e/slideshow/index.js @@ -0,0 +1 @@ +'../common/index.js' diff --git a/cypress/e2e/slideshow/slideshow.js b/cypress/e2e/slideshow/slideshow.js new file mode 100644 index 000000000..254dd3976 --- /dev/null +++ b/cypress/e2e/slideshow/slideshow.js @@ -0,0 +1,103 @@ +import { When, Then } from '@badeball/cypress-cucumber-preprocessor' +import { + getDashboardItem, + clickMenuButton, +} from '../../elements/dashboardItem.js' + +const sortedDashboardItemIds = ['GaVhJpqABYX', 'qXsjttMYuoZ', 'Rwb3oXJ3bZ9'] + +const assertItemIsVisible = (slideshowItemIndex) => { + getDashboardItem(sortedDashboardItemIds[slideshowItemIndex]).should( + 'have.css', + 'opacity', + '1' + ) +} + +const assertItemIsNotVisible = (slideshowItemIndex) => { + getDashboardItem(sortedDashboardItemIds[slideshowItemIndex]).should( + 'have.css', + 'opacity', + '0' + ) +} + +const getSlideshowExitButton = () => + cy.getByDataTest('slideshow-exit-button', { timeout: 15000 }) + +When('I click the slideshow button', () => { + cy.get('button').contains('Slideshow').realClick() +}) + +Then('item 1 is shown in fullscreen', () => { + getSlideshowExitButton().should('be.visible') + + // check that only the first item is shown + assertItemIsVisible(0) + assertItemIsNotVisible(1) + assertItemIsNotVisible(2) + + cy.getByDataTest('slideshow-page-counter').should('have.text', '1 / 11') + + // visible item does not have context menu button + getDashboardItem(sortedDashboardItemIds[0]) + .findByDataTest('dashboarditem-menu-button') + .should('not.exist') +}) + +When('I click the exit slideshow button', () => { + getSlideshowExitButton().realClick() +}) + +Then('the normal view is shown', () => { + getSlideshowExitButton().should('not.exist') + + // check that multiple items are shown + assertItemIsVisible(0) + assertItemIsVisible(1) + assertItemIsVisible(2) + + // items have context menu button + getDashboardItem(sortedDashboardItemIds[0]) + .findByDataTest('dashboarditem-menu-button') + .should('be.visible') + + getDashboardItem(sortedDashboardItemIds[1]) + .findByDataTest('dashboarditem-menu-button') + .should('be.visible') +}) + +// When I click the next slide button +When('I click the next slide button', () => { + cy.getByDataTest('slideshow-next-button').realClick() +}) + +Then('item 2 is shown in fullscreen', () => { + assertItemIsNotVisible(0) + assertItemIsVisible(1) + assertItemIsNotVisible(2) + + cy.getByDataTest('slideshow-page-counter').should('have.text', '2 / 11') +}) + +When('I click the previous slide button', () => { + cy.getByDataTest('slideshow-prev-button').realClick() +}) + +When('I click the fullscreen button on the second item', () => { + clickMenuButton(sortedDashboardItemIds[1]) + cy.contains('View fullscreen').realClick() +}) + +When('I click the fullscreen button on the third item', () => { + clickMenuButton(sortedDashboardItemIds[2]) + cy.contains('View fullscreen').realClick() +}) + +Then('item 3 is shown in fullscreen', () => { + assertItemIsNotVisible(0) + assertItemIsNotVisible(1) + assertItemIsVisible(2) + + cy.getByDataTest('slideshow-page-counter').should('have.text', '3 / 11') +}) diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js index 7045ae0f0..e87f217a8 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.js @@ -1,5 +1,6 @@ // import '@dhis2/cypress-commands' import { enableAutoLogin } from '@dhis2/cypress-commands' +import 'cypress-real-events' import './commands.js' enableAutoLogin() diff --git a/i18n/en.pot b/i18n/en.pot index 76eae083b..4dae5376b 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2024-08-27T07:26:05.058Z\n" -"PO-Revision-Date: 2024-08-27T07:26:05.060Z\n" +"POT-Creation-Date: 2024-12-19T08:40:31.084Z\n" +"PO-Revision-Date: 2024-12-19T08:40:31.085Z\n" msgid "Untitled dashboard" msgstr "Untitled dashboard" @@ -26,6 +26,9 @@ msgstr "Show fewer dashboards" msgid "Show more dashboards" msgstr "Show more dashboards" +msgid "{{appKey}} app not found" +msgstr "{{appKey}} app not found" + msgid "Remove this item" msgstr "Remove this item" @@ -152,6 +155,12 @@ msgstr "Open this item in {{appName}}" msgid "Not available offline" msgstr "Not available offline" +msgid "Resources" +msgstr "Resources" + +msgid "Reports" +msgstr "Reports" + msgid "Visualizations" msgstr "Visualizations" @@ -176,12 +185,6 @@ msgstr "Line lists" msgid "Apps" msgstr "Apps" -msgid "Reports" -msgstr "Reports" - -msgid "Resources" -msgstr "Resources" - msgid "Users" msgstr "Users" @@ -487,6 +490,23 @@ msgstr "No, cancel" msgid "Yes, remove filters" msgstr "Yes, remove filters" +msgid "Exit slideshow" +msgstr "Exit slideshow" + +msgid "Previous item" +msgstr "Previous item" + +msgid "Next item" +msgstr "Next item" + +msgid "{{name}}: {{filter}}" +msgstr "{{name}}: {{filter}}" + +msgid "{{count}} filters active" +msgid_plural "{{count}} filters active" +msgstr[0] "{{count}} filter active" +msgstr[1] "{{count}} filters active" + msgid "The dashboard couldn't be made available offline. Try again." msgstr "The dashboard couldn't be made available offline. Try again." @@ -526,12 +546,18 @@ msgstr "Close dashboard" msgid "More" msgstr "More" +msgid "No dashboard items to show in slideshow" +msgstr "No dashboard items to show in slideshow" + msgid "Edit" msgstr "Edit" msgid "Share" msgstr "Share" +msgid "Slideshow" +msgstr "Slideshow" + msgid "Clear dashboard filters?" msgstr "Clear dashboard filters?" diff --git a/package.json b/package.json index 8a4846ff1..fabd1952f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dashboard-app", - "version": "100.3.2", + "version": "999.99.0-dashboard-slideshow", "description": "DHIS2 Dashboard app", "private": true, "license": "BSD-3-Clause", @@ -54,6 +54,7 @@ "@testing-library/jest-dom": "^6.1.2", "@testing-library/react": "^12", "cypress": "^13.13.1", + "cypress-real-events": "^1.13.0", "d2-manifest": "^1.0.0", "eslint-plugin-cypress": "^3.3.0", "immutability-helper": "^3.1.1", diff --git a/src/actions/slideshow.js b/src/actions/slideshow.js new file mode 100644 index 000000000..38a841ff6 --- /dev/null +++ b/src/actions/slideshow.js @@ -0,0 +1,6 @@ +import { SET_SLIDESHOW } from '../reducers/slideshow.js' + +export const acSetSlideshow = (isSlideshow) => ({ + type: SET_SLIDESHOW, + value: isSlideshow, +}) diff --git a/src/components/App.js b/src/components/App.js index 28820c851..f4e3aa21f 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -48,7 +48,7 @@ const App = (props) => { return ( systemSettings && ( <> - + { +const AppItem = ({ dashboardMode, item, itemFilters, apps, isFullscreen }) => { let appDetails const appKey = item.appKey @@ -39,26 +42,23 @@ const AppItem = ({ dashboardMode, item, itemFilters, apps }) => {