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 b1.0 #3601

Merged
merged 13 commits into from
Jan 19, 2024
1 change: 1 addition & 0 deletions dashboard/src/actions/datasetListActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const fetchDatasets = (page) => async (dispatch, getState) => {
getState().datasetlist;
const datasetType = getState().comparison.datasetType;
let publicData = [...getState().datasetlist.publicData];

const params = new URLSearchParams();
addParams(params, loggedIn, datasetType);
params.append("offset", offset);
Expand Down
7 changes: 3 additions & 4 deletions dashboard/src/actions/overviewActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { DANGER, ERROR_MSG } from "assets/constants/toastConstants";

import API from "../utils/axiosInstance";
import Cookies from "js-cookie";
import { MY_DATASETS } from "assets/constants/compareConstants";
import { addParams } from "./datasetListActions";
import { clearCachedSession } from "./authActions";
import { findNoOfDays } from "utils/dateFunctions";
Expand All @@ -13,16 +14,14 @@ import { uriTemplate } from "../utils/helper";

export const getDatasets = () => async (dispatch, getState) => {
const alreadyRendered = getState().overview.loadingDone;
const datasetType = getState().comparison.datasetType;

const loggedIn = Cookies.get("isLoggedIn");
try {
if (alreadyRendered) {
dispatch({ type: TYPES.LOADING });
}
const params = new URLSearchParams();

addParams(params, loggedIn, datasetType);
addParams(params, loggedIn, MY_DATASETS);

dispatch(setSelectedRuns([]));
const endpoints = getState().apiEndpoint.endpoints;
Expand Down Expand Up @@ -439,7 +438,7 @@ export const getKeySummary = async (dispatch, getState) => {
try {
const endpoints = getState().apiEndpoint.endpoints;
const response = await API.get(uriTemplate(endpoints, "datasets_list"), {
params: { keysummary: true },
params: { keysummary: true, mine: true },
});
if (response.status === 200) {
if (response.data.keys) {
Expand Down
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