From aaa842a1aeb9be880773b97997ad97ec47875e6b Mon Sep 17 00:00:00 2001 From: MVarshini Date: Mon, 15 Jan 2024 21:25:00 +0530 Subject: [PATCH] Update TOC page (#3580) * PBENCH-1216 TOC page update --- .../src/actions/tableOfContentActions.js | 55 --- dashboard/src/actions/tocActions.js | 133 ++++++ dashboard/src/actions/types.js | 10 +- .../components/TableComponent/index.jsx | 57 ++- .../TableOfContent/DrillDownMenu.jsx | 30 ++ .../components/TableOfContent/index.jsx | 440 ++++-------------- .../components/TableOfContent/index.less | 69 +-- dashboard/src/reducers/index.js | 4 +- .../src/reducers/tableOfContentReducer.js | 71 --- dashboard/src/reducers/tocReducer.js | 28 ++ dashboard/src/utils/routeConstants.js | 2 +- 11 files changed, 332 insertions(+), 567 deletions(-) delete mode 100644 dashboard/src/actions/tableOfContentActions.js create mode 100644 dashboard/src/actions/tocActions.js create mode 100644 dashboard/src/modules/components/TableOfContent/DrillDownMenu.jsx delete mode 100644 dashboard/src/reducers/tableOfContentReducer.js create mode 100644 dashboard/src/reducers/tocReducer.js diff --git a/dashboard/src/actions/tableOfContentActions.js b/dashboard/src/actions/tableOfContentActions.js deleted file mode 100644 index d844e1a5f2..0000000000 --- a/dashboard/src/actions/tableOfContentActions.js +++ /dev/null @@ -1,55 +0,0 @@ -import * as TYPES from "./types"; - -import API from "../utils/axiosInstance"; -import { DANGER } from "assets/constants/toastConstants"; -import { showToast } from "./toastActions"; -import { uriTemplate } from "../utils/helper"; - -export const fetchTOC = - (param, dataUri, callForSubData) => async (dispatch, getState) => { - try { - dispatch({ type: TYPES.LOADING }); - const endpoints = getState().apiEndpoint.endpoints; - const parent = dataUri?.split("contents/").pop(); - const uri = uriTemplate(endpoints, "datasets_contents", { - dataset: param, - target: parent, - }); - const response = await API.get(uri); - if (response.status === 200 && response.data) { - dispatch({ - type: callForSubData ? "GET_SUB_DIR_DATA" : "GET_TOC_DATA", - payload: response.data, - }); - } - } catch (error) { - const msg = error.response?.data?.message; - dispatch(showToast(DANGER, msg ?? `Error response: ${error}`)); - } - dispatch({ type: TYPES.COMPLETED }); - }; - -export const updateTableData = (data) => ({ - type: TYPES.UPDATE_TABLE_DATA, - payload: data, -}); - -export const updateContentData = (data) => ({ - type: TYPES.UPDATE_CONTENT_DATA, - payload: data, -}); - -export const updateSearchSpace = (data) => ({ - type: TYPES.UPDATE_SEARCH_SPACE, - payload: data, -}); - -export const updateStack = (length) => ({ - type: TYPES.UPDATE_STACK, - payload: length, -}); - -export const updateCurrData = (data) => ({ - type: TYPES.UPDATE_CURR_DATA, - payload: data, -}); diff --git a/dashboard/src/actions/tocActions.js b/dashboard/src/actions/tocActions.js new file mode 100644 index 0000000000..546a540876 --- /dev/null +++ b/dashboard/src/actions/tocActions.js @@ -0,0 +1,133 @@ +import * as TYPES from "./types"; + +import API from "utils/axiosInstance"; +import { DANGER } from "assets/constants/toastConstants"; +import { showToast } from "./toastActions"; +import { uriTemplate } from "utils/helper"; + +/** + * Function to fetch contents data + * @function + * @param {String} datasetId - Dataset ID + * @param {String} path - Path to the file/directory + * @param {String} item - Active item + * @param {Boolean} isSubDir - To identify sub-directory expansion + * @return {Function} - dispatch the action and update the state + */ +export const fetchTOC = + (datasetId, path, item, isSubDir) => async (dispatch, getState) => { + try { + dispatch({ type: TYPES.LOADING }); + const endpoints = getState().apiEndpoint.endpoints; + + const uri = uriTemplate(endpoints, "datasets_contents", { + dataset: datasetId, + target: path, + }); + const response = await API.get(uri); + if (response.status === 200 && response.data) { + if (!isSubDir) { + const inventoryLink = uriTemplate(endpoints, "datasets_inventory", { + dataset: datasetId, + target: path, + }); + dispatch({ + type: TYPES.SET_INVENTORY_LINK, + payload: inventoryLink, + }); + } + dispatch(parseToTreeView(response.data, item, isSubDir, path)); + } + } catch (error) { + const msg = error.response?.data?.message; + dispatch(showToast(DANGER, msg ?? `Error response: ${error}`)); + } + dispatch({ type: TYPES.COMPLETED }); + }; + +const makeOptions = (data, isParent, keyPath, isDirectory) => { + const options = data.map((item) => { + const option = { + name: item.name, + id: isParent ? `${keyPath}*${item.name}` : item.name, + isDirectory, + uri: item.uri, + }; + if (isDirectory) { + option.children = []; + } else { + option.size = item.size; + } + return option; + }); + return options; +}; +/** + * Function to parse contents data totree view + * @function + * @param {Object} contentData - Contentdata to parse + * @param {Object} activeItem - Active item + * @param {Boolean} isSubDir - To identify sub-directory expansion + * @param {String} parent - Parent Name to set the id + * @return {Function} - dispatch the action and update the state + */ +export const parseToTreeView = + (contentData, activeItem, isSubDir, parent) => (dispatch, getState) => { + const keyPath = parent.replaceAll("/", "*"); + const drillMenuData = [...getState().toc.drillMenuData]; + const directories = makeOptions( + contentData.directories, + parent, + keyPath, + true + ); + const files = makeOptions(contentData.files, parent, keyPath, false); + const treeOptions = [...directories, ...files]; + if (isSubDir) { + if (activeItem.includes("*")) { + updateActiveItemChildren(drillMenuData, keyPath, treeOptions); + } else { + const itemName = activeItem.split("*").pop(); + const itemOptions = drillMenuData.find((i) => i.name === itemName); + if (itemOptions) { + itemOptions["children"] = treeOptions; + } + } + } + dispatch({ + type: TYPES.SET_DRILL_MENU_DATA, + payload: isSubDir ? drillMenuData : treeOptions, + }); + }; + +/** + * Function to find the actual key from key path and update it's children + * @function + * @param {Object} arr - Drill down menu + * @param {String} key - key path + * @param {Array} childrenToUpdate - Active item children obtained through API request + * @return {Array} - updated children + */ +const updateActiveItemChildren = (arr, key, childrenToUpdate) => { + // if children are undefined + if (!arr) return; + + // loop over each entry and its children to find + // entry with passed key + arr.forEach((entry) => { + if (entry.id === key) { + entry.children = childrenToUpdate; + } + // recursive call to traverse children + else { + updateActiveItemChildren(entry.children, key, childrenToUpdate); + } + }); + + return arr; +}; + +export const setActiveFileContent = (item) => ({ + type: TYPES.SET_ACTIVE_FILE, + payload: item, +}); diff --git a/dashboard/src/actions/types.js b/dashboard/src/actions/types.js index 751bb07cdd..727e4b4ed5 100644 --- a/dashboard/src/actions/types.js +++ b/dashboard/src/actions/types.js @@ -49,13 +49,9 @@ export const SET_TREE_DATA = "SET_TREE_DATA"; export const SET_METADATA_CHECKED_KEYS = "SET_METADATA_CHECKED_KEYS"; /* TABLE OF CONTENT */ -export const GET_TOC_DATA = "GET_TOC_DATA"; -export const GET_SUB_DIR_DATA = "GET_SUB_DIR_DATA"; -export const UPDATE_TABLE_DATA = "UPDATE_TABLE_DATA"; -export const UPDATE_SEARCH_SPACE = "UPDATE_SEARCH_SPACE"; -export const UPDATE_STACK = "UPDATE_STACK"; -export const UPDATE_CURR_DATA = "UPDATE_CURR_DATA"; -export const UPDATE_CONTENT_DATA = "UPDATE_CONTENT_DATA"; +export const SET_INVENTORY_LINK = "SET_INVENTORY_LINK"; +export const SET_DRILL_MENU_DATA = "SET_DRILL_MENU_DATA"; +export const SET_ACTIVE_FILE = "SET_ACTIVE_FILE"; /* SIDEBAR */ export const SET_ACTIVE_MENU_ITEM = "SET_ACTIVE_MENU_ITEM"; diff --git a/dashboard/src/modules/components/TableComponent/index.jsx b/dashboard/src/modules/components/TableComponent/index.jsx index 9a4bb70a19..e3921a84ff 100644 --- a/dashboard/src/modules/components/TableComponent/index.jsx +++ b/dashboard/src/modules/components/TableComponent/index.jsx @@ -29,6 +29,7 @@ import DatePickerWidget from "../DatePickerComponent"; import { RenderPagination } from "../OverviewComponent/common-component"; import TablePagination from "../PaginationComponent"; import { ViewOptions } from "../ComparisonComponent/common-components"; +import { uid } from "utils/helper"; import { useKeycloak } from "@react-keycloak/web"; import { useNavigate } from "react-router"; @@ -204,31 +205,37 @@ const TableWithFavorite = () => { {selectedArray.length > 0 ? ( - selectedArray.map((repo, rowIndex) => ( - - - navigate(`/${HOME}${TOC}/${repo?.resource_id}`) - } - > - {repo?.name} - - - {repo?.metadata.dataset.uploaded} - - { - markRepoFavorited(repo, isFavoriting); - }, - rowIndex, - }} - /> - - )) + selectedArray.map((repo, rowIndex) => + repo ? ( + + + navigate( + `/${HOME}${TOC}/${repo.resource_id}/${repo.name}` + ) + } + > + {repo.name} + + + {repo.metadata.dataset.uploaded} + + { + markRepoFavorited(repo, isFavoriting); + }, + rowIndex, + }} + /> + + ) : ( + + ) + ) ) : ( diff --git a/dashboard/src/modules/components/TableOfContent/DrillDownMenu.jsx b/dashboard/src/modules/components/TableOfContent/DrillDownMenu.jsx new file mode 100644 index 0000000000..40a1431042 --- /dev/null +++ b/dashboard/src/modules/components/TableOfContent/DrillDownMenu.jsx @@ -0,0 +1,30 @@ +import { FolderIcon, FolderOpenIcon } from "@patternfly/react-icons"; +import React, { useState } from "react"; + +import { TreeView } from "@patternfly/react-core"; +import { useSelector } from "react-redux"; + +const DrilldownMenu = (props) => { + const { drillMenuData } = useSelector((state) => state.toc); + const [activeItems, setActiveItems] = useState([]); + const onSelect = (_evt, item) => { + setActiveItems([item]); + props.drillMenuItem(item); + }; + + return ( +
+ {drillMenuData?.length > 0 && ( + } + expandedIcon={} + /> + )} +
+ ); +}; + +export default DrilldownMenu; diff --git a/dashboard/src/modules/components/TableOfContent/index.jsx b/dashboard/src/modules/components/TableOfContent/index.jsx index de969f3bfe..a9f16eee5a 100644 --- a/dashboard/src/modules/components/TableOfContent/index.jsx +++ b/dashboard/src/modules/components/TableOfContent/index.jsx @@ -1,384 +1,104 @@ import "./index.less"; import { - AngleLeftIcon, - DownloadIcon, - FolderIcon, -} from "@patternfly/react-icons"; -import { - BadgeToggle, - Breadcrumb, - BreadcrumbHeading, - BreadcrumbItem, Divider, - DrilldownMenu, - Dropdown, - DropdownItem, - Menu, - MenuBreadcrumb, - MenuContent, - MenuItem, - MenuList, + Flex, + FlexItem, + List, + ListItem, + Sidebar, + SidebarContent, + SidebarPanel, } from "@patternfly/react-core"; -import React, { useEffect, useState } from "react"; -import { - TableComposable, - Tbody, - Td, - Th, - Thead, - Tr, -} from "@patternfly/react-table"; -import { - fetchTOC, - updateContentData, - updateCurrData, - updateSearchSpace, - updateStack, - updateTableData, -} from "actions/tableOfContentActions"; +import React, { useEffect } from "react"; +import { fetchTOC, setActiveFileContent } from "actions/tocActions"; import { useDispatch, useSelector } from "react-redux"; -import { DEFAULT_PER_PAGE } from "assets/constants/paginationConstants"; -import { EmptyTable } from "../TableComponent/common-components"; -import { SearchTOC } from "./common-components"; -import TablePagination from "../PaginationComponent"; +import { DownloadIcon } from "@patternfly/react-icons"; +import DrilldownMenu from "./DrillDownMenu"; import { useParams } from "react-router"; const TableOfContent = () => { - const { endpoints } = useSelector((state) => state.apiEndpoint); - const [menuDrilledIn, setMenuDrilledIn] = useState([]); - const [drilldownPath, setDrillDownPath] = useState([]); - const [activeMenu, setActiveMenu] = useState("rootMenu"); - const [breadCrumb, setBreadCrumb] = useState(null); - const [activeFile, setActiveFile] = useState(null); - const [breadCrumbLabels, setBreadCrumbLabels] = useState([]); - const [param, setParam] = useState(""); - const [page, setPage] = useState(1); - const [perPage, setPerPage] = useState(DEFAULT_PER_PAGE); - const params = useParams(); const dispatch = useDispatch(); - let dirCount = 0; - let fileCount = 0; + const params = useParams(); + + const { endpoints } = useSelector((state) => state.apiEndpoint); + const { activeFile, inventoryDownloadLink } = useSelector( + (state) => state.toc + ); useEffect(() => { if (Object.keys(endpoints).length > 0) - dispatch(fetchTOC(params["dataset_id"], "", false)); + dispatch(fetchTOC(params["dataset_id"], "", undefined, false)); }, [dispatch, endpoints, params]); - const { stack, searchSpace, tableData, contentData, currData } = useSelector( - (state) => state.tableOfContent - ); - const setTableData = (data) => { - dispatch(updateTableData(data)); - }; - const setContnetData = (data) => { - dispatch(updateContentData(data)); - }; - const setSearchSpace = (data) => { - dispatch(updateSearchSpace(data)); - }; - const setStack = (length) => { - dispatch(updateStack(length)); - }; - const setCurrData = (data) => { - dispatch(updateCurrData(data)); - }; - const onToggle = (isOpen, key, moreBreadCrumbs) => { - if (key === "app") { - setBreadCrumb(appGroupingBreadcrumb(isOpen, moreBreadCrumbs)); + const drillMenuItem = (item) => { + if (!item.isDirectory) { + dispatch(setActiveFileContent(item)); + } else if (!item.children.length) { + dispatch( + fetchTOC( + params["dataset_id"], + item.id.replaceAll("*", "/"), + item.id, + true + ) + ); } }; - - const visibleTableFiles = tableData - ? tableData.slice((page - 1) * perPage, page * perPage) - : []; - const drillOut = (toMenuId, fromPathId, newBreadCrumb) => { - const indexOfMenuId = menuDrilledIn.indexOf(toMenuId); - const menuDrilledInSansLast = menuDrilledIn.slice(0, indexOfMenuId); - const indexOfMenuIdPath = drilldownPath.indexOf(fromPathId); - const pathSansLast = drilldownPath.slice(0, indexOfMenuIdPath); - setMenuDrilledIn(menuDrilledInSansLast); - setDrillDownPath(pathSansLast); - setActiveMenu(toMenuId); - setBreadCrumb(newBreadCrumb); - }; - const drillIn = (fromMenuId, toMenuId, pathId) => { - setMenuDrilledIn([...menuDrilledIn, fromMenuId]); - setDrillDownPath([...drilldownPath, pathId]); - setActiveMenu(toMenuId); - }; - const getDropDown = (moreBreadCrumbs) => { - const dropDownArray = moreBreadCrumbs.map((label, index) => - index < moreBreadCrumbs.length - 1 ? ( - } - onClick={() => { - setStack(index + 2); - const updatedBreadCrumbLabels = breadCrumbLabels.slice( - 0, - index + 1 - ); - const newParam = param.split("/"); - setParam(newParam.slice(0, index + 1).join("/")); - setBreadCrumbLabels(updatedBreadCrumbLabels); - setCurrData(stack[index + 1]); - setTableData(stack[index + 1].files); - setSearchSpace(stack[index + 1].files); - if (updatedBreadCrumbLabels.length === 1) { - setBreadCrumb(initialBreadcrumb(updatedBreadCrumbLabels)); - } else if (updatedBreadCrumbLabels.length > 1) - setBreadCrumb( - appGroupingBreadcrumb(false, updatedBreadCrumbLabels) - ); - }} - > - {label} - - ) : ( - <> - ) - ); - dropDownArray.pop(); - return dropDownArray; - }; - const initialBreadcrumb = (initial) => ( - - - Root - - - {initial.length > 0 ? initial[0] : ""} - - - ); - - const appGroupingBreadcrumb = (isOpen, moreBreadCrumbs) => { - return ( - - - Root - - - onToggle(open, "app", moreBreadCrumbs)} - > - {moreBreadCrumbs.length - 1} - - } - isOpen={isOpen} - dropdownItems={getDropDown(moreBreadCrumbs)} - /> - - - {moreBreadCrumbs[moreBreadCrumbs.length - 1]} - - - ); - }; - const getMyBreadCrumbClick = () => { - drillOut("rootMenu", "group:start_rollout", initialBreadcrumb([])); - setStack(1); - setTableData(stack[0].files); - setContnetData(stack[0]); - setSearchSpace(stack[0].files); - setParam(""); - setBreadCrumbLabels([]); - }; - const getSubFolderData = (data) => { - dispatch(fetchTOC(params["dataset_id"], data, true)); - }; - const attachBreadCrumbs = (data, firstHierarchyLevel) => { - setBreadCrumbLabels([...breadCrumbLabels, data.name]); - - setBreadCrumb( - firstHierarchyLevel - ? initialBreadcrumb(breadCrumbLabels) - : appGroupingBreadcrumb(false, breadCrumbLabels) - ); - const dirPath = param.concat(firstHierarchyLevel ? "" : "/", data.name); - setParam(dirPath); - getSubFolderData(data.uri); - }; - const updateHighlightedRow = (index) => { - const newPage = Math.floor(index / perPage); - if (newPage + 1 !== page) { - setPage(newPage + 1); - } - setActiveFile(index); - }; - return ( - <> -
- - {breadCrumb && ( - <> - {breadCrumb} - - - )} - - - - {contentData?.directories?.map((data, index) => { - return ( - } - direction="down" - onClick={() => { - attachBreadCrumbs(data, true); - }} - drilldownMenu={ - - {currData?.directories?.map((data, index) => { - if (dirCount < currData.directories.length) { - dirCount = dirCount + 1; - return ( - } - onClick={() => { - attachBreadCrumbs(data, false); - }} - > - {data.name} - - ); - } else { - return <>; - } - })} +
+ + + Dataset Name: + {params["dataset_name"]} + + + + + + Download tarball + + + + + + + + +
+ {Object.keys(activeFile).length > 0 && ( + + + File Name: + {activeFile.name} + + + File Size: + {activeFile.size} + - {currData?.files?.map((data, index) => { - if (fileCount < currData.files.length) { - fileCount = fileCount + 1; - return ( - } - onClick={() => { - updateHighlightedRow(index); - }} - > - {data.name} - - ); - } else { - return <>; - } - })} - - } + + To view download + - {data.name} - - ); - })} - {contentData?.files?.map((data, index) => { - return ( - { - updateHighlightedRow(index); - }} - > - {data.name} - - ); - })} - - -
-
-
- + + + + + )}
- - <> - - - Name - mtime - Size - Mode - Type - - - - - {visibleTableFiles.length > 0 ? ( - visibleTableFiles?.map((file, index) => ( - - {file.name} - {file.mtime} - {file.size} - {file.mode} - {file.type} - - - - - - - )) - ) : ( - - - - - - )} - - - - -
-
- + + + ); }; diff --git a/dashboard/src/modules/components/TableOfContent/index.less b/dashboard/src/modules/components/TableOfContent/index.less index b306b8111a..b07b37f9c8 100644 --- a/dashboard/src/modules/components/TableOfContent/index.less +++ b/dashboard/src/modules/components/TableOfContent/index.less @@ -1,50 +1,27 @@ -#rootMenu { - width: 500px; - height: 100%; - box-shadow: none; - border-right: 2px solid #d2d2d2; -} - -.toc { - display: flex; - height: 100%; -} - -.active { - background-color: #efefef; -} - -.dropDown { - position: absolute; - left: 100%; - background-color: blanchedalmond; -} - -.tableTOC { - display: flex; - flex-direction: column; +.toc-container { width: 100%; - padding: 2vh; - .download-icon { - color: #6a6e73; + padding: 1vh; + .heading-container { + padding: 2vh 2vh 0; + font-weight: bold; + justify-content: space-between; + .heading-text { + padding-left: 10px; + } } -} - -.searchTOCContainer { - display: flex; - justify-content: flex-end; -} - -.tocBody { - margin-top: 0.5vw; -} - -.searchInputGroup { - width: 25vw !important; -} - -#d_down_parent { - svg { - fill: #6a6e73; + .header-separator { + margin: 5px 0 15px; + } + .pf-c-sidebar__panel { + padding: 1vh; + margin-right: 2.5vh; + min-width: 60vh; + } + .toc-content { + .file-label { + font-weight: bold; + padding-right: 5px; + } + width: 75vh; } } diff --git a/dashboard/src/reducers/index.js b/dashboard/src/reducers/index.js index 7e7d411f64..53635df3f3 100644 --- a/dashboard/src/reducers/index.js +++ b/dashboard/src/reducers/index.js @@ -6,7 +6,7 @@ import LoadingReducer from "./loadingReducer"; import NavbarReducer from "./navbarReducer"; import OverviewReducer from "./overviewReducer"; import SidebarReducer from "./sidebarReducer"; -import TableOfContentReducer from "./tableOfContentReducer"; +import TableOfContentReducer from "./tocReducer"; import ToastReducer from "./toastReducer"; import { combineReducers } from "redux"; @@ -17,7 +17,7 @@ export default combineReducers({ datasetlist: DatasetListReducer, apiEndpoint: EndpointReducer, overview: OverviewReducer, - tableOfContent: TableOfContentReducer, + toc: TableOfContentReducer, sidebar: SidebarReducer, keyManagement: KeyManagementReducer, comparison: ComparisonReducer, diff --git a/dashboard/src/reducers/tableOfContentReducer.js b/dashboard/src/reducers/tableOfContentReducer.js deleted file mode 100644 index 2769c7e526..0000000000 --- a/dashboard/src/reducers/tableOfContentReducer.js +++ /dev/null @@ -1,71 +0,0 @@ -import { - GET_SUB_DIR_DATA, - GET_TOC_DATA, - UPDATE_CONTENT_DATA, - UPDATE_CURR_DATA, - UPDATE_SEARCH_SPACE, - UPDATE_STACK, - UPDATE_TABLE_DATA, -} from "actions/types"; - -const initialState = { - stack: [], - searchSpace: [], - tableData: [], - contentData: [], - currData: [], -}; - -const TableOfContentReducer = (state = initialState, action = {}) => { - const { type, payload } = action; - switch (type) { - case GET_TOC_DATA: - return { - ...state, - stack: [payload], - searchSpace: payload.files, - tableData: payload.files, - contentData: payload, - }; - - case GET_SUB_DIR_DATA: - return { - ...state, - stack: [...state.stack, payload], - searchSpace: payload.files, - tableData: payload.files, - contentData: payload, - }; - - case UPDATE_TABLE_DATA: - return { - ...state, - tableData: payload, - }; - case UPDATE_CONTENT_DATA: - return { - ...state, - contentData: payload, - }; - case UPDATE_SEARCH_SPACE: - return { - ...state, - searchSpace: payload, - }; - - case UPDATE_STACK: - return { - ...state, - stack: state.stack.slice(0, payload), - }; - - case UPDATE_CURR_DATA: - return { - ...state, - currData: payload, - }; - default: - return state; - } -}; -export default TableOfContentReducer; diff --git a/dashboard/src/reducers/tocReducer.js b/dashboard/src/reducers/tocReducer.js new file mode 100644 index 0000000000..1d810ea609 --- /dev/null +++ b/dashboard/src/reducers/tocReducer.js @@ -0,0 +1,28 @@ +import * as TYPES from "../actions/types"; + +const initialState = { + inventoryDownloadLink: "", + drillMenuData: [], + activeFile: {}, +}; + +const TableOfContentReducer = (state = initialState, action = {}) => { + const { type, payload } = action; + switch (type) { + case TYPES.SET_INVENTORY_LINK: { + return { + ...state, + inventoryDownloadLink: payload, + }; + } + case TYPES.SET_DRILL_MENU_DATA: { + return { ...state, drillMenuData: payload }; + } + case TYPES.SET_ACTIVE_FILE: { + return { ...state, activeFile: payload }; + } + default: + return state; + } +}; +export default TableOfContentReducer; diff --git a/dashboard/src/utils/routeConstants.js b/dashboard/src/utils/routeConstants.js index be2a8063dc..09b12e26eb 100644 --- a/dashboard/src/utils/routeConstants.js +++ b/dashboard/src/utils/routeConstants.js @@ -6,7 +6,7 @@ export const AUTH_LOGIN = "login"; export const AUTH_SIGNUP = "signup"; export const OVERVIEW = "overview"; export const RESULTS = "results"; -export const TABLE_OF_CONTENT = "toc/:dataset_id"; +export const TABLE_OF_CONTENT = "toc/:dataset_id/:dataset_name"; export const TOC = "toc"; export const USER_PROFILE = "user-profile"; export const VISUALIZATION = "visualization";