diff --git a/cypress/integration/item/analytics/analytics.spec.js b/cypress/integration/item/analytics/analytics.spec.js new file mode 100644 index 000000000..3321d2cbe --- /dev/null +++ b/cypress/integration/item/analytics/analytics.spec.js @@ -0,0 +1,26 @@ +import { buildItemPath } from '../../../../src/config/paths'; +import { + buildDashboardButtonId, + buildGraaspAnalyzerId, +} from '../../../../src/config/selectors'; +import { SAMPLE_ITEMS } from '../../../fixtures/items'; + +const openAnalyticsDashboard = (itemId) => { + cy.get(`#${buildDashboardButtonId(itemId)}`).click(); +}; + +describe('Analytics Scenarios', () => { + it('Send messages in chatbox', () => { + const { id } = SAMPLE_ITEMS.items[0]; + cy.setUpApi(SAMPLE_ITEMS); + cy.visit(buildItemPath(id)); + + // open dashboard + openAnalyticsDashboard(id); + cy.get(`#${buildGraaspAnalyzerId(id)}`) + .should('be.visible') + .then((el) => { + expect(el.attr('src')).to.contain(id); + }); + }); +}); diff --git a/cypress/integration/item/chatbox/chatbox.spec.js b/cypress/integration/item/chatbox/chatbox.spec.js index 9a1fdb7c0..fcca11852 100644 --- a/cypress/integration/item/chatbox/chatbox.spec.js +++ b/cypress/integration/item/chatbox/chatbox.spec.js @@ -10,11 +10,15 @@ import { ITEM_WITH_CHATBOX_MESSAGES, } from '../../../fixtures/chatbox'; import { CURRENT_USER, MEMBERS } from '../../../fixtures/members'; -import { WEBSOCKETS_DELAY_TIME } from '../../../support/constants'; +import { + CHATBOX_LOADING_TIME, + WEBSOCKETS_DELAY_TIME, +} from '../../../support/constants'; const openChatbox = () => { cy.get(`#${ITEM_CHATBOX_BUTTON_ID}`).click(); cy.wait('@getItemChat'); + cy.wait(CHATBOX_LOADING_TIME); }; describe('Chatbox Scenarios', () => { diff --git a/cypress/support/constants.js b/cypress/support/constants.js index 0cbdb78c5..b60129c08 100644 --- a/cypress/support/constants.js +++ b/cypress/support/constants.js @@ -20,3 +20,4 @@ export const CAPTION_EDIT_PAUSE = 2000; export const ROW_HEIGHT = 48; export const TABLE_ITEM_RENDER_TIME = 8000; export const FIXTURES_THUMBNAILS_FOLDER = './thumbnails'; +export const CHATBOX_LOADING_TIME = 4000; diff --git a/src/components/common/AnalyticsDashboardButton.js b/src/components/common/AnalyticsDashboardButton.js new file mode 100644 index 000000000..02ace613d --- /dev/null +++ b/src/components/common/AnalyticsDashboardButton.js @@ -0,0 +1,33 @@ +import React, { useContext } from 'react'; +import { useTranslation } from 'react-i18next'; +import PieChartIcon from '@material-ui/icons/PieChart'; +import PropTypes from 'prop-types'; +import IconButton from '@material-ui/core/IconButton'; +import CloseIcon from '@material-ui/icons/Close'; +import Tooltip from '@material-ui/core/Tooltip'; +import { LayoutContext } from '../context/LayoutContext'; +import { buildDashboardButtonId } from '../../config/selectors'; + +// eslint-disable-next-line no-unused-vars +const AnalyticsDashboardButton = ({ id }) => { + const { t } = useTranslation(); + const { setIsDashboardOpen, isDashboardOpen } = useContext(LayoutContext); + + return ( + + setIsDashboardOpen(!isDashboardOpen)} + id={buildDashboardButtonId(id)} + > + {isDashboardOpen ? : } + + + ); +}; + +AnalyticsDashboardButton.propTypes = { + id: PropTypes.string.isRequired, +}; + +export default AnalyticsDashboardButton; diff --git a/src/components/context/LayoutContext.js b/src/components/context/LayoutContext.js index 19708ea52..4b9a6888f 100644 --- a/src/components/context/LayoutContext.js +++ b/src/components/context/LayoutContext.js @@ -16,6 +16,7 @@ const LayoutContextProvider = ({ children }) => { // todo: separate in item specific context const [isItemSettingsOpen, setIsItemSettingsOpen] = useState(false); const [isItemSharingOpen, setIsItemSharingOpen] = useState(false); + const [isDashboardOpen, setIsDashboardOpen] = useState(false); const [isMainMenuOpen, setIsMainMenuOpen] = useState(true); @@ -38,6 +39,8 @@ const LayoutContextProvider = ({ children }) => { setIsChatboxMenuOpen, isItemSharingOpen, setIsItemSharingOpen, + isDashboardOpen, + setIsDashboardOpen, }), [ editingItemId, @@ -46,6 +49,8 @@ const LayoutContextProvider = ({ children }) => { isItemSettingsOpen, isItemSharingOpen, isMainMenuOpen, + isDashboardOpen, + setIsDashboardOpen, mode, ], ); diff --git a/src/components/item/header/ItemHeaderActions.js b/src/components/item/header/ItemHeaderActions.js index ba3540e88..215572b55 100644 --- a/src/components/item/header/ItemHeaderActions.js +++ b/src/components/item/header/ItemHeaderActions.js @@ -28,6 +28,7 @@ import { } from '../../../utils/membership'; import { hooks } from '../../../config/queryClient'; import { CurrentUserContext } from '../../context/CurrentUserContext'; +import AnalyticsDashboardButton from '../../common/AnalyticsDashboardButton'; const useStyles = makeStyles((theme) => ({ root: { @@ -96,6 +97,7 @@ const ItemHeaderActions = ({ onClickMetadata, onClickChatbox, item }) => { return ( <> {!isItemSettingsOpen && activeActions} + {canEdit && } {canEdit && } ); diff --git a/src/components/main/GraaspAnalyzer.js b/src/components/main/GraaspAnalyzer.js new file mode 100644 index 000000000..2c2d32223 --- /dev/null +++ b/src/components/main/GraaspAnalyzer.js @@ -0,0 +1,36 @@ +import React, { useRef } from 'react'; +import PropTypes from 'prop-types'; +import { Map } from 'immutable'; +import { useTranslation } from 'react-i18next'; +import { + DEFAULT_ANALYZER_HEIGHT, + buildGraaspAnalyzerLink, +} from '../../config/constants'; +import { buildGraaspAnalyzerId } from '../../config/selectors'; + +// todo: use as component +const GraaspAnalyzer = ({ item }) => { + const { t } = useTranslation(); + const ref = useRef(); + const id = item.get('id'); + + return ( +