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

Update TOC page #3580

Merged
merged 7 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
55 changes: 0 additions & 55 deletions dashboard/src/actions/tableOfContentActions.js

This file was deleted.

133 changes: 133 additions & 0 deletions dashboard/src/actions/tocActions.js
Original file line number Diff line number Diff line change
@@ -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,
});
10 changes: 3 additions & 7 deletions dashboard/src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
57 changes: 32 additions & 25 deletions dashboard/src/modules/components/TableComponent/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -204,31 +205,37 @@ const TableWithFavorite = () => {
</Thead>
<Tbody>
{selectedArray.length > 0 ? (
selectedArray.map((repo, rowIndex) => (
<Tr key={repo?.resource_id}>
<Td
className="dataset_name"
dataLabel={columnNames.name}
onClick={() =>
navigate(`/${HOME}${TOC}/${repo?.resource_id}`)
}
>
{repo?.name}
</Td>
<Td dataLabel={columnNames.uploadedDate}>
{repo?.metadata.dataset.uploaded}
</Td>
<Td
favorites={{
isFavorited: isRepoFavorited(repo),
onFavorite: (_event, isFavoriting) => {
markRepoFavorited(repo, isFavoriting);
},
rowIndex,
}}
/>
</Tr>
))
selectedArray.map((repo, rowIndex) =>
repo ? (
<Tr key={repo.resource_id}>
<Td
className="dataset_name"
dataLabel={columnNames.name}
onClick={() =>
navigate(
`/${HOME}${TOC}/${repo.resource_id}/${repo.name}`
)
}
>
{repo.name}
</Td>
<Td dataLabel={columnNames.uploadedDate}>
{repo.metadata.dataset.uploaded}
</Td>
<Td
favorites={{
isFavorited: isRepoFavorited(repo),
onFavorite: (_event, isFavoriting) => {
markRepoFavorited(repo, isFavoriting);
},
rowIndex,
}}
/>
</Tr>
) : (
<Tr key={uid()}></Tr>
)
)
) : (
<Tr key={"empty-row"}>
<Td colSpan={8}>
Expand Down
30 changes: 30 additions & 0 deletions dashboard/src/modules/components/TableOfContent/DrillDownMenu.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="drilldownMenu-container">
{drillMenuData?.length > 0 && (
<TreeView
data={drillMenuData}
activeItems={activeItems}
onSelect={onSelect}
icon={<FolderIcon />}
expandedIcon={<FolderOpenIcon />}
/>
)}
</div>
);
};

export default DrilldownMenu;
Loading