From 9d32df942d10d7a4bd8f8fa91ae4644ad6601f3a Mon Sep 17 00:00:00 2001 From: Vikas Agarwal Date: Mon, 6 Apr 2020 13:59:30 +0530 Subject: [PATCH] Initial working draft for user level reports --- src/api/projectReports.js | 9 ++ src/components/UserSidebar/UserSidebar.jsx | 7 + src/config/constants.js | 6 + src/reducers/index.js | 2 + src/routes.jsx | 3 +- src/routes/reports/actions/index.js | 34 +++++ .../containers/UserReportsContainer.jsx | 125 ++++++++++++++++++ src/routes/reports/reducers/index.js | 51 +++++++ src/routes/reports/routes.jsx | 15 +++ 9 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 src/routes/reports/actions/index.js create mode 100644 src/routes/reports/containers/UserReportsContainer.jsx create mode 100644 src/routes/reports/reducers/index.js create mode 100644 src/routes/reports/routes.jsx diff --git a/src/api/projectReports.js b/src/api/projectReports.js index 6dfa68ba1..9ccb0411c 100644 --- a/src/api/projectReports.js +++ b/src/api/projectReports.js @@ -51,4 +51,13 @@ export function getProjectSummary(projectId) { export function getProjectReportUrl(projectId, reportName) { return axios.get(`${PROJECTS_API_URL}/v5/projects/${projectId}/reports/embed?reportName=${reportName}`) .then(resp => resp.data) +} + +/** + * Gets signed URL for embeding the requested report. + * @param {*} reportName unique name of the report + */ +export function getUserReportUrl(reportName) { + return axios.get(`${PROJECTS_API_URL}/v5/projects/reports/embed?reportName=${reportName}`) + .then(resp => resp.data) } \ No newline at end of file diff --git a/src/components/UserSidebar/UserSidebar.jsx b/src/components/UserSidebar/UserSidebar.jsx index 7dd5f53c9..c234185d4 100644 --- a/src/components/UserSidebar/UserSidebar.jsx +++ b/src/components/UserSidebar/UserSidebar.jsx @@ -9,6 +9,7 @@ import MenuList from '../MenuList/MenuList' import NotificationsIcon from '../../assets/icons/ui-bell.svg' import AllProjectsIcon from '../../assets/icons/v.2.5/icon-all-projects.svg' import MyProfileIcon from '../../assets/icons/v.2.5/icon-my-profile.svg' +import ReportsIcon from '../../assets/icons/v.2.5/icon-reports.svg' import NotificationSettingsIcon from '../../assets/icons/v.2.5/icon-notification-setting.svg' import AccountSecurityIcon from '../../assets/icons/v.2.5/icon-account-security.svg' @@ -20,6 +21,12 @@ const navLinks = [{ Icon: AllProjectsIcon, iconClassName: 'fill', exact: false, +}, { + label: 'REPORTS', + to: '/reports', + Icon: ReportsIcon, + iconClassName: 'stroke', + exact: false, }, { label: 'MY PROFILE', to: '/settings/profile', diff --git a/src/config/constants.js b/src/config/constants.js index d0acc1943..6d67af5b2 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -419,6 +419,12 @@ export const LOAD_PROJECT_SUMMARY_SUCCESS = 'LOAD_PROJECT_SUMMARY_SUCCESS' export const LOAD_PROJECT_SUMMARY_FAILURE = 'LOAD_PROJECT_SUMMARY_FAILURE' export const SET_LOOKER_SESSION_EXPIRED = 'SET_LOOKER_SESSION_EXPIRED' +// User Reports +export const LOAD_USER_REPORTS = 'LOAD_USER_REPORTS' +export const LOAD_USER_REPORTS_PENDING = 'LOAD_USER_REPORTS_PENDING' +export const LOAD_USER_REPORTS_SUCCESS = 'LOAD_USER_REPORTS_SUCCESS' +export const LOAD_USER_REPORTS_FAILURE = 'LOAD_USER_REPORTS_FAILURE' + // Product attachments export const ADD_PRODUCT_ATTACHMENT = 'ADD_PRODUCT_ATTACHMENT' export const ADD_PRODUCT_ATTACHMENT_PENDING = 'ADD_PRODUCT_ATTACHMENT_PENDING' diff --git a/src/reducers/index.js b/src/reducers/index.js index 36e40fc17..722b3d6bf 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -7,6 +7,7 @@ import { projectTopics } from '../projects/reducers/projectTopics' import { topics } from './topics' import { productsTimelines } from '../projects/reducers/productsTimelines' import { projectReports } from '../projects/reducers/projectReports' +import { userReports } from '../routes/reports/reducers' import navSearch from './navSearch' import projectSearch from '../projects/reducers/projectSearch' import projectSearchSuggestions from '../projects/reducers/projectSearchSuggestions' @@ -33,4 +34,5 @@ export default combineReducers({ settings, templates, productsTimelines, + userReports, }) diff --git a/src/routes.jsx b/src/routes.jsx index f12a62495..ddbf6cd72 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -9,6 +9,7 @@ import projectRoutes from './projects/routes.jsx' import notificationsRoutes from './routes/notifications/routes.jsx' import settingsRoutes from './routes/settings/routes.jsx' import metaDataRoutes from './routes/metadata/routes.jsx' +import reportsListRoutes from './routes/reports/routes' import TopBarContainer from './components/TopBar/TopBarContainer' import ProjectsToolBar from './components/TopBar/ProjectsToolBar' import RedirectComponent from './components/RedirectComponent' @@ -154,7 +155,7 @@ class Routes extends React.Component { {/* Handle /projects/* routes */} {projectRoutes} - {/* {reportsListRoutes} */} + {reportsListRoutes} {notificationsRoutes} {settingsRoutes} {metaDataRoutes} diff --git a/src/routes/reports/actions/index.js b/src/routes/reports/actions/index.js new file mode 100644 index 000000000..b50dee87b --- /dev/null +++ b/src/routes/reports/actions/index.js @@ -0,0 +1,34 @@ +import { + LOAD_USER_REPORTS, + SET_LOOKER_SESSION_EXPIRED, +} from '../../../config/constants' +import { + getUserReportUrl, +} from '../../../api/projectReports' + +/** + * Redux action to start fetching the signed URL for embeding the given report + * @param {*} reportName unique name of the report + */ +export function loadUserReportsUrls(reportName) { + return (dispatch) => { + return dispatch({ + type: LOAD_USER_REPORTS, + payload: getUserReportUrl(reportName), + }) + } +} + +/** + * Redux action set the flag `lookerSessionExpired` + * + * @param {Boolean} isExpired true to indicate that looker session is expired + */ +export function setLookerSessionExpired(isExpired) { + return (dispatch) => { + return dispatch({ + type: SET_LOOKER_SESSION_EXPIRED, + payload: { lookerSessionExpired: isExpired } + }) + } +} \ No newline at end of file diff --git a/src/routes/reports/containers/UserReportsContainer.jsx b/src/routes/reports/containers/UserReportsContainer.jsx new file mode 100644 index 000000000..c45f47fd3 --- /dev/null +++ b/src/routes/reports/containers/UserReportsContainer.jsx @@ -0,0 +1,125 @@ +import React, { Component } from 'react' +import MediaQuery from 'react-responsive' +import Modal from 'react-modal' +import Sticky from 'react-stickynode' +import { connect } from 'react-redux' +import { withRouter } from 'react-router-dom' +import { loadUserReportsUrls, setLookerSessionExpired } from '../actions' +import { SCREEN_BREAKPOINT_MD, PROJECT_REPORTS, REPORT_SESSION_LENGTH } from '../../../config/constants' +import TwoColsLayout from '../../../components/TwoColsLayout' +import UserSidebar from '../../../components/UserSidebar/UserSidebar' +import spinnerWhileLoading from '../../../components/LoadingSpinner' + +const LookerEmbedReport = (props) => { + return (