Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: dashboard slideshow #3081

Open
wants to merge 87 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 67 commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
fa9f0d5
chore: update ItemGrid to current standard and fix missing dep in use…
jenniferarnesen Sep 3, 2024
3d3990e
feat: fullscreen for visualization items
jenniferarnesen Sep 3, 2024
6f604b0
feat: add the navigation buttons and keep track of current index in I…
jenniferarnesen Sep 4, 2024
f25c305
fix: remove stray char
jenniferarnesen Sep 4, 2024
6033db1
chore: full of debug comments
jenniferarnesen Sep 5, 2024
99c8983
feat: use single fs element and load different vis into it
jenniferarnesen Sep 6, 2024
aa5bf33
feat: sizing of the iframe as well as positioning of the nav buttons …
jenniferarnesen Sep 6, 2024
7116a28
chore: remove props no longer used
jenniferarnesen Sep 6, 2024
2c79ce3
chore: override display for LL
jenniferarnesen Sep 9, 2024
41ffd12
chore: fs for LL items
jenniferarnesen Sep 9, 2024
609b249
fix: only show Slideshow if fullscreen allowed in sys settings
jenniferarnesen Sep 9, 2024
8c08c6a
fix: filter out SPACER and MESSAGES items from sorted items list
jenniferarnesen Sep 9, 2024
3df05ba
feat: styling and show/hide controls
jenniferarnesen Sep 9, 2024
5765c9b
Merge branch 'master' into feat/slide-show-display-none
jenniferarnesen Sep 27, 2024
2a6bd82
Merge branch 'master' into feat/slide-show-display-none
jenniferarnesen Oct 8, 2024
0934590
chore: fix jest tests
jenniferarnesen Oct 8, 2024
ed77aac
feat: add exit button and always show controls on hover
jenniferarnesen Oct 8, 2024
6c4e86b
chore: consistent class names
jenniferarnesen Oct 8, 2024
540377c
fix: always show fs controls at bottm
jenniferarnesen Oct 10, 2024
63a33a1
fix: persistent nav bar
jenniferarnesen Oct 31, 2024
cada906
Merge branch 'master' into feat/slide-show-display-none
jenniferarnesen Nov 1, 2024
a25b0d6
fix: slideshow control bar styles
cooper-joe Nov 5, 2024
4d8f8df
fix: text item style
jenniferarnesen Nov 5, 2024
021a6de
chore: move fullscreen handling to a hook
jenniferarnesen Nov 6, 2024
34a643a
chore: renaming vars
jenniferarnesen Nov 8, 2024
6d70db5
fix: force load when in fullscreen
jenniferarnesen Nov 8, 2024
ff6b76a
fix: add controls buffer to App items
jenniferarnesen Nov 8, 2024
78d9280
chore: slideshow button tooltip and refactor fs enabled on types
jenniferarnesen Nov 10, 2024
642f5ec
fix: remove padding around items when in fullscreen
jenniferarnesen Nov 12, 2024
d447245
chore: update comment
jenniferarnesen Nov 12, 2024
985f5e9
chore: no fullscreen items tooltip message
jenniferarnesen Nov 12, 2024
8be0a82
fix: text item style fixes
jenniferarnesen Nov 12, 2024
05c7893
chore: rename redux to slideshow
jenniferarnesen Nov 21, 2024
b5793b6
fix: margins and styling on app item in fullscreen
jenniferarnesen Nov 21, 2024
fd265f9
fix: styling fixes for List items
jenniferarnesen Nov 21, 2024
d5a35f8
chore: isFS not needed in plugin
jenniferarnesen Nov 22, 2024
1b4f9b2
fix: clean and organize CSS
jenniferarnesen Nov 25, 2024
84c65a9
chore: marginblock around text item
jenniferarnesen Nov 25, 2024
f5ebb4a
chore: remove unneeded css classes
jenniferarnesen Nov 26, 2024
efa4e82
chore: remove fullscreen css from previous solution that isnt needed now
jenniferarnesen Nov 26, 2024
dedcd15
chore: call it isFullscreen
jenniferarnesen Nov 26, 2024
65b8f18
fix: print issue with tables
jenniferarnesen Nov 27, 2024
86fa2ff
chore: subtract 40px from item height instead of adding extra div to …
jenniferarnesen Nov 27, 2024
e68cc4d
feat: force load current next and previous items when in fullscreen
jenniferarnesen Nov 27, 2024
29d35e9
chore: remove unused css
jenniferarnesen Nov 27, 2024
6a63d6d
feat: use opacity to go to next or prev slide for smooth transition
jenniferarnesen Nov 27, 2024
5668b66
feat: make smooth transition when entering fullscreen and paging
jenniferarnesen Nov 28, 2024
3b12aa8
Merge branch 'master' into feat/slide-show-display-none
jenniferarnesen Nov 28, 2024
3c60122
chore: remove temp code from ListItem
jenniferarnesen Nov 28, 2024
b952fe8
Merge branch 'feat/slide-show-display-none' of github.com:dhis2/dashb…
jenniferarnesen Nov 28, 2024
1ac2ee3
chore: rename from fullscreen to slideshow
jenniferarnesen Nov 28, 2024
6916453
chore: rename fullscreen to slideshow
jenniferarnesen Nov 29, 2024
7145728
chore: separate SlideshowControlbar component
jenniferarnesen Nov 29, 2024
acfa1c4
chore: cypress test
jenniferarnesen Nov 29, 2024
5f48ea5
chore: snapshot test update
jenniferarnesen Nov 29, 2024
e2273c7
chore: code smell fixes
jenniferarnesen Nov 29, 2024
5b46fca
chore: restore
jenniferarnesen Nov 29, 2024
ce23d41
chore: rename prop to fullscreenView
jenniferarnesen Dec 2, 2024
e2247da
test: add more cypress testing
jenniferarnesen Dec 2, 2024
b38adb9
fix: override width and height and z-index for displayed item
jenniferarnesen Dec 3, 2024
00f1ab6
chore: add checks to cypress test
jenniferarnesen Dec 3, 2024
629f7bf
chore: make scrollbox the exception not the rule
jenniferarnesen Dec 3, 2024
b3b1f97
chore: add check for no item context menu button in fullscreen
jenniferarnesen Dec 3, 2024
f3b72f3
chore: update snapshots
jenniferarnesen Dec 4, 2024
165ed4f
chore: useMemo instead of useRef in useSlideshow
jenniferarnesen Dec 4, 2024
f3985b5
fix: set height of slideshow controlbar to 40px
jenniferarnesen Dec 4, 2024
b1855a6
fix: set height on slideshow grid to prevent growing controlbar on hi…
jenniferarnesen Dec 4, 2024
caf0e6b
fix: disable slideshow button when offline and not cached
jenniferarnesen Dec 5, 2024
b6573bf
fix: show nav buttons as disabled when only one item
jenniferarnesen Dec 6, 2024
8043cfc
fix: add background color to fs element to avoid brief flashing of black
jenniferarnesen Dec 6, 2024
286fd89
fix: do not tab to invisible elements
jenniferarnesen Dec 6, 2024
24888cd
fix: more tweaking to get transition to slideshow bg colors right
jenniferarnesen Dec 6, 2024
f1fc4c8
Merge branch 'master' into feat/slide-show-display-none
jenniferarnesen Dec 6, 2024
9f4906f
fix: tabIndex is a string not a number
jenniferarnesen Dec 10, 2024
347e520
fix: messages item scrollbar was missing
jenniferarnesen Dec 11, 2024
df0fda2
fix: display message on unloaded items when offline and not cached
jenniferarnesen Dec 11, 2024
b01cfa4
feat: filter badges
jenniferarnesen Dec 12, 2024
e38ecf5
fix: with flex external container needed to prevent button from takin…
jenniferarnesen Dec 12, 2024
b2d7937
feat: add tooltip to filter badge - not working yet
jenniferarnesen Dec 12, 2024
a01587e
feat: show all filters in a popover when clicking a button with total…
HendrikThePendric Dec 12, 2024
2dce45e
fix: use string pluralization and remove unneeded style
jenniferarnesen Dec 13, 2024
c5eb94a
fix: show different message when single filter
jenniferarnesen Dec 16, 2024
0c5f5e8
fix: use correct prop in i18n
jenniferarnesen Dec 16, 2024
ecc63aa
chore: temporary to get a build
jenniferarnesen Dec 17, 2024
6e7071a
test: add cypress test that navigates backwards to start
jenniferarnesen Dec 17, 2024
11e1f8c
fix: remove tabbing when element not visible during slideshow
jenniferarnesen Dec 18, 2024
524c937
fix: slideshow filter content and style
cooper-joe Dec 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions cypress/e2e/slideshow.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
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
jenniferarnesen marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions cypress/e2e/slideshow/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
'../common/index.js'
91 changes: 91 additions & 0 deletions cypress/e2e/slideshow/slideshow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
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 the next slide is shown
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()
})
1 change: 1 addition & 0 deletions cypress/support/e2e.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// import '@dhis2/cypress-commands'
import { enableAutoLogin } from '@dhis2/cypress-commands'
import 'cypress-real-events'
import './commands.js'

enableAutoLogin()
Expand Down
13 changes: 11 additions & 2 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -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-11-21T14:44:35.575Z\n"
"PO-Revision-Date: 2024-11-21T14:44:35.577Z\n"

msgid "Untitled dashboard"
msgstr "Untitled dashboard"
Expand All @@ -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"

Expand Down Expand Up @@ -526,12 +529,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?"

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
6 changes: 6 additions & 0 deletions src/actions/slideshow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { SET_SLIDESHOW } from '../reducers/slideshow.js'

export const acSetSlideshow = (isSlideshow) => ({
type: SET_SLIDESHOW,
value: isSlideshow,
})
29 changes: 15 additions & 14 deletions src/components/Item/AppItem/Item.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import i18n from '@dhis2/d2-i18n'
import { Divider, colors, spacers, IconQuestion24 } from '@dhis2/ui'
import cx from 'classnames'
import PropTypes from 'prop-types'
import React from 'react'
import { connect } from 'react-redux'
Expand All @@ -9,8 +11,9 @@ import {
} from '../../../reducers/itemFilters.js'
import ItemHeader from '../ItemHeader/ItemHeader.js'
import { getIframeSrc } from './getIframeSrc.js'
import styles from './styles/AppItem.module.css'

const AppItem = ({ dashboardMode, item, itemFilters, apps }) => {
const AppItem = ({ dashboardMode, item, itemFilters, apps, isFullscreen }) => {
let appDetails

const appKey = item.appKey
Expand Down Expand Up @@ -39,26 +42,23 @@ const AppItem = ({ dashboardMode, item, itemFilters, apps }) => {
<iframe
title={appDetails.name}
src={getIframeSrc(appDetails, item, itemFilters)}
className={
!hideTitle
? 'dashboard-item-content'
: 'dashboard-item-content-hidden-title'
}
className={cx(styles.content, {
[styles.hiddenTitle]: hideTitle,
[styles.fullscreen]: isFullscreen,
})}
style={{ border: 'none' }}
/>
</>
) : (
<>
<ItemHeader title={`${appKey} app not found`} />
<ItemHeader
title={i18n.t('{{appKey}} app not found', { appKey })}
/>
<Divider margin={`0 0 ${spacers.dp4} 0`} />
<div
className="dashboard-item-content"
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '90%',
}}
className={cx(styles.content, styles.centered, {
[styles.fullscreen]: isFullscreen,
})}
>
<IconQuestion24 color={colors.grey500} />
</div>
Expand All @@ -69,6 +69,7 @@ const AppItem = ({ dashboardMode, item, itemFilters, apps }) => {
AppItem.propTypes = {
apps: PropTypes.array,
dashboardMode: PropTypes.string,
isFullscreen: PropTypes.bool,
item: PropTypes.object,
itemFilters: PropTypes.object,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ exports[`renders a valid App item in view mode 1`] = `
class="ui-Divider"
/>
<iframe
class="dashboard-item-content"
class="content"
src="launchurl?dashboardItemId=rainbowdash"
title="Scorecard"
/>
Expand Down Expand Up @@ -51,7 +51,7 @@ exports[`renders a valid App item with filter in edit mode 1`] = `
class="ui-Divider"
/>
<iframe
class="dashboard-item-content"
class="content"
src="launchurl?dashboardItemId=rainbowdash"
title="Scorecard"
/>
Expand All @@ -76,7 +76,7 @@ exports[`renders a valid App item with filter in view mode 1`] = `
class="ui-Divider"
/>
<iframe
class="dashboard-item-content"
class="content"
src="launchurl?dashboardItemId=rainbowdash&userOrgUnit=rainbow"
title="Scorecard"
/>
Expand Down Expand Up @@ -109,7 +109,7 @@ exports[`renders a valid App item with title in edit mode irrespective of app se
class="ui-Divider"
/>
<iframe
class="dashboard-item-content"
class="content"
src="launchurl?dashboardItemId=twilightsparkle"
title="No Title"
/>
Expand All @@ -119,7 +119,7 @@ exports[`renders a valid App item with title in edit mode irrespective of app se
exports[`renders a valid App item without title in view mode if specified in app settings 1`] = `
<div>
<iframe
class="dashboard-item-content-hidden-title"
class="content hiddenTitle"
src="launchurl?dashboardItemId=twilightsparkle"
title="No Title"
/>
Expand All @@ -144,8 +144,7 @@ exports[`renders an invalid App item 1`] = `
class="ui-Divider"
/>
<div
class="dashboard-item-content"
style="display: flex; justify-content: center; align-items: center; height: 90%;"
class="content centered"
>
<svg
color="#a0adba"
Expand Down
21 changes: 21 additions & 0 deletions src/components/Item/AppItem/styles/AppItem.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.content {
composes: content from '../../styles/Item.module.css';
flex: 1;
}

.hiddenTitle {
margin-block-start: 5px;
margin-block-end: 4px;
margin-inline: 4px;
}

.fullscreen {
composes: fullscreen from '../../styles/Item.module.css';
}

.centered {
display: flex;
justify-content: center;
align-items: center;
block-size: 90%;
}
16 changes: 14 additions & 2 deletions src/components/Item/ListItem/Item.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useConfig } from '@dhis2/app-runtime'
import i18n from '@dhis2/d2-i18n'
import { Divider, IconFileDocument16, colors, spacers } from '@dhis2/ui'
import cx from 'classnames'
import PropTypes from 'prop-types'
import React from 'react'
import { connect } from 'react-redux'
Expand All @@ -22,7 +23,13 @@ const getContentItems = (item) =>
array.findIndex((el) => el.id === item.id) === index
)

const ListItem = ({ item, dashboardMode, removeItem, updateItem }) => {
const ListItem = ({
item,
dashboardMode,
removeItem,
updateItem,
isFullscreen,
}) => {
const { baseUrl } = useConfig()
const contentItems = getContentItems(item)

Expand Down Expand Up @@ -74,7 +81,11 @@ const ListItem = ({ item, dashboardMode, removeItem, updateItem }) => {
isShortened={item.shortened}
/>
<Divider margin={`0 0 ${spacers.dp4} 0`} />
<div className="dashboard-item-content">
<div
className={cx(classes.content, {
[classes.fullscreen]: isFullscreen,
})}
>
<ul className={classes.list}>
{contentItems.map((contentItem) => (
<li className={classes.item} key={contentItem.id}>
Expand All @@ -92,6 +103,7 @@ const ListItem = ({ item, dashboardMode, removeItem, updateItem }) => {

ListItem.propTypes = {
dashboardMode: PropTypes.string,
isFullscreen: PropTypes.bool,
item: PropTypes.object,
removeItem: PropTypes.func,
updateItem: PropTypes.func,
Expand Down
13 changes: 13 additions & 0 deletions src/components/Item/ListItem/Item.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,16 @@
outline: none;
color: var(--colors-red800);
}

.content {
composes: content from '../styles/Item.module.css';
flex: 1;
}

.fullscreen .list {
padding-inline: 24px;
}

.fullscreen {
composes: fullscreen from '../styles/Item.module.css';
}
2 changes: 1 addition & 1 deletion src/components/Item/MessagesItem/Item.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const MessagesItem = ({ messages, item, dashboardMode }) => {
/>
<Divider margin={`0 0 ${spacers.dp4} 0`} />
{messages.length > 0 && (
<div className="dashboard-item-content">
<div className={classes.content}>
<ul className={classes.list}>{getMessageItems()}</ul>
<div className={classes.seeAll}>
<a href={getMessageHref()}>
Expand Down
5 changes: 5 additions & 0 deletions src/components/Item/MessagesItem/styles/Item.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@
max-block-size: 30px;
overflow: hidden;
}

.content {
composes: content from '../../styles/Item.module.css';
flex: 1;
}
Loading
Loading