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 (
+
+ );
+};
+
+GraaspAnalyzer.propTypes = {
+ item: PropTypes.instanceOf({
+ Map,
+ }).isRequired,
+};
+
+export default GraaspAnalyzer;
diff --git a/src/components/main/ItemScreen.js b/src/components/main/ItemScreen.js
index 8a70740b4..fe5297dca 100644
--- a/src/components/main/ItemScreen.js
+++ b/src/components/main/ItemScreen.js
@@ -13,6 +13,7 @@ import ItemContent from '../item/ItemContent';
import ItemMain from '../item/ItemMain';
import ItemSettings from '../item/settings/ItemSettings';
import ItemSharingTab from '../item/sharing/ItemSharingTab';
+import GraaspAnalyzer from './GraaspAnalyzer';
import Main from './Main';
import { hooks, useMutation } from '../../config/queryClient';
import {
@@ -36,6 +37,7 @@ const ItemScreen = () => {
setIsItemSettingsOpen,
setIsItemSharingOpen,
isItemSharingOpen,
+ isDashboardOpen,
} = useContext(LayoutContext);
const { data: currentMember } = useContext(CurrentUserContext);
const { data: memberships } = useItemMemberships([itemId]);
@@ -65,6 +67,9 @@ const ItemScreen = () => {
);
}
+ if (isDashboardOpen) {
+ return ;
+ }
return ;
})();
diff --git a/src/config/constants.js b/src/config/constants.js
index e885db83c..f8d9ddaaa 100644
--- a/src/config/constants.js
+++ b/src/config/constants.js
@@ -41,6 +41,12 @@ export const GRAASP_PERFORM_HOST =
process.env.REACT_APP_GRAASP_PERFORM_HOST ||
'http://localhost:3112';
+export const GRAASP_ANALYZER_HOST =
+ process.env.REACT_APP_GRAASP_ANALYZER_HOST || 'http://localhost:3113';
+
+export const buildGraaspAnalyzerLink = (id) =>
+ `${GRAASP_ANALYZER_HOST}/embedded/${id}`;
+
export const GA_MEASUREMENT_ID =
ENV_GA_MEASUREMENT_ID || process.env.REACT_APP_GA_MEASUREMENT_ID;
@@ -71,6 +77,8 @@ export const DEFAULT_LANG = 'en';
export const DEFAULT_PERMISSION_LEVEL = PERMISSION_LEVELS.READ;
+export const DEFAULT_ANALYZER_HEIGHT = 2300;
+
export const PERMISSIONS_EDITION_ALLOWED = [
PERMISSION_LEVELS.WRITE,
PERMISSION_LEVELS.ADMIN,
diff --git a/src/config/selectors.js b/src/config/selectors.js
index b0b1c54f8..2ef89f4e1 100644
--- a/src/config/selectors.js
+++ b/src/config/selectors.js
@@ -173,3 +173,5 @@ export const CATEGORIES_SELECTION_VALUE_SELECTOR = `#${SHARE_ITEM_CATEGORY_LEVEL
export const buildCategoryMenuOptions = (menuName, optionIndex) =>
`#${menuName}-popup li[data-option-index="${optionIndex}"]`;
+export const buildDashboardButtonId = (id) => `dashboard-button-${id}`;
+export const buildGraaspAnalyzerId = (id) => `graasp-analyzer-${id}`;