Skip to content

Commit

Permalink
feat: dataset file explorer links to file contents (#1270) (#2566)
Browse files Browse the repository at this point in the history
  • Loading branch information
cramakri authored and ciyer committed Jun 5, 2023
1 parent 1241a32 commit e42b194
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 74 deletions.
147 changes: 80 additions & 67 deletions client/src/components/FileExplorer.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import cx from "classnames";
import React, { Component, useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
Expand All @@ -7,7 +8,6 @@ import {
faFolderOpen,
} from "@fortawesome/free-solid-svg-icons";
import { Loader } from "./Loader";
import { type } from "os";

type HashElt = {
name: string;
Expand Down Expand Up @@ -37,11 +37,14 @@ function buildTree(
treeNode: TreeNodeElt[],
jsonObj: JsonObj,
hash: Record<string, HashElt>,
currentPath: string,
currentPathCandidate: string,
foldersOpenOnLoad = 0
) {
if (parts.length === 0) return;
currentPath = currentPath === "" ? parts[0] : currentPath + "/" + parts[0];
const currentPath =
currentPathCandidate === ""
? parts[0]
: currentPathCandidate + "/" + parts[0];

for (let i = 0; i < treeNode.length; i++) {
if (parts[0] === treeNode[i].text) {
Expand Down Expand Up @@ -131,12 +134,48 @@ function getFilesTree(
return treeObj;
}

type FileDisplayProps = {
className: string;
icon: React.ReactNode;
insideProject: boolean;
linkUrl?: string;
node: TreeNodeElt;
};
function FileDisplay({
className,
icon,
insideProject,
linkUrl,
node,
}: FileDisplayProps) {
const eltClassName = cx("fs-element", className);
if (insideProject && linkUrl && node.jsonObj)
return (
<div className={eltClassName} data-cy="dataset-fs-element">
<Link to={`${linkUrl}/${node.jsonObj.atLocation}`}>
{icon} {node.name}
</Link>
</div>
);
return (
<div
className={eltClassName}
data-cy="dataset-fs-element"
style={{ cursor: "default" }}
>
<a>
{icon} {node.name}
</a>
</div>
);
}

type TreeNodeProps = {
path: string;
node: TreeNodeElt;
childrenOpen: boolean;
projectUrl?: string;
lineageUrl: string;
linkUrl?: string;
setOpenFolder: (path: string) => void;
hash: Record<string, HashElt>;
insideProject: boolean;
Expand All @@ -149,7 +188,6 @@ type TreeNodeState = {

class TreeNode extends Component<TreeNodeProps, TreeNodeState> {
constructor(props: TreeNodeProps) {
// eslint-disable-next-line react/prop-types
const childrenOpen = props.childrenOpen as boolean;
super(props);
this.state = {
Expand All @@ -175,13 +213,6 @@ class TreeNode extends Component<TreeNodeProps, TreeNodeState> {
<FontAwesomeIcon className="link-rk-text" icon={faFile} />
);

const order = this.props.node.children.length
? "order-second"
: "order-third";
const hidden = this.props.node.name.startsWith(".")
? " hidden-folder "
: "";

const children = this.props.node.children
? this.props.node.children.map((node) => {
return (
Expand All @@ -191,7 +222,7 @@ class TreeNode extends Component<TreeNodeProps, TreeNodeState> {
node={node}
childrenOpen={this.props.hash[node.path].childrenOpen}
projectUrl={this.props.projectUrl}
lineageUrl={this.props.lineageUrl}
linkUrl={this.props.linkUrl}
setOpenFolder={this.props.setOpenFolder}
hash={this.props.hash}
insideProject={this.props.insideProject}
Expand All @@ -200,60 +231,47 @@ class TreeNode extends Component<TreeNodeProps, TreeNodeState> {
})
: null;

let elementToRender;
const eltClassName = order + " " + hidden;
const order = this.props.node.children.length
? "order-second"
: "order-third";
const hidden = { "hidden-folder": this.props.node.name.startsWith(".") };
const className = cx(order, hidden);
if (this.props.node.jsonObj !== null) {
elementToRender = this.props.insideProject ? (
<div
className={`fs-element ${eltClassName}`}
data-cy="dataset-fs-element"
>
<Link
to={`${this.props.lineageUrl}/${this.props.node.jsonObj.atLocation}`}
>
{icon} {this.props.node.name}
</Link>
</div>
) : (
return (
<FileDisplay
className={className}
icon={icon}
insideProject={this.props.insideProject}
linkUrl={this.props.linkUrl}
node={this.props.node}
/>
);
}

return (
<>
<div
className={`fs-element ${eltClassName}`}
data-cy="dataset-fs-element"
style={{ cursor: "default" }}
className={cx("fs-element", className)}
data-cy="dataset-fs-folder"
onClick={this.handleIconClick}
>
<a>
{icon} {this.props.node.name}
</a>
</div>
);
} else {
const secondElement = this.state.childrenOpen ? (
<div className="ps-3">{children}</div>
) : null;

elementToRender = (
<>
<div
className={`fs-element ${eltClassName}`}
data-cy="dataset-fs-folder"
onClick={this.handleIconClick}
>
<a>
{icon} {this.props.node.name}
</a>
</div>
{secondElement}
</>
);
}
return elementToRender;
{this.state.childrenOpen ? (
<div className="ps-3">{children}</div>
) : null}
</>
);
}
}

type FilesTreeViewProps = {
data: FilesTree;
hash: Record<string, HashElt>;
setOpenFolder: (path: string) => void;
lineageUrl: string;
linkUrl?: string;
insideProject: boolean;
};

Expand All @@ -272,7 +290,7 @@ function FilesTreeView(props: FilesTreeViewProps) {
setOpenFolder={props.setOpenFolder}
path={node.path}
hash={props.data.hash}
lineageUrl={props.lineageUrl}
linkUrl={props.linkUrl}
insideProject={props.insideProject}
/>
);
Expand All @@ -283,7 +301,7 @@ function FilesTreeView(props: FilesTreeViewProps) {
props.data,
tree,
props.setOpenFolder,
props.lineageUrl,
props.linkUrl,
props.insideProject,
]);

Expand All @@ -293,23 +311,18 @@ function FilesTreeView(props: FilesTreeViewProps) {
}

type FileExplorerProps = {
/** This is a list of files with atLocation containing the file path (this is optional) */
files?: JsonObj[];
/** This is the already built fileTree (optional) */
filesTree?: FilesTree;
/** Number of folders that should appear open already when displaying the tree */
foldersOpenOnLoad: number;
lineageUrl: string;
/** Should be replaced for URL, this is the link for the file (when clicked) (optional) */
linkUrl?: string;
/** Set true if the display is inside a project */
insideProject: boolean;
};

/**
* Generic files tree generator.
* Some things are left to do to make it more generic.
*
* @param {*} props.files - This is a list of files with atLocation containing the file path (this is optional)
* @param {*} props.filesTree - This is the already built fileTree (optional)
* @param {*} props.foldersOpenOnLoad - Number of folders that should appear open already when displaying the tree
* @param {*} props.lineageUrl - Should be replaced for URL, this is the link for the file (when clicked) (optional)
* @param {*} props.insideProject - Boolean to be set true if the display is inside a project
*/
function FileExplorer(props: FileExplorerProps) {
const [filesTree, setFilesTree] = useState<
ReturnType<typeof getFilesTree> | undefined
Expand Down Expand Up @@ -340,7 +353,7 @@ function FileExplorer(props: FileExplorerProps) {
data={filesTree}
setOpenFolder={setOpenFolder}
hash={filesTree.hash}
lineageUrl={props.lineageUrl}
linkUrl={props.linkUrl}
insideProject={props.insideProject}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,6 @@ function FileUploaderInput({
<small>
<FileExplorer
filesTree={file.folder_structure}
lineageUrl={" "}
insideProject={false}
foldersOpenOnLoad={0}
/>
Expand Down Expand Up @@ -821,11 +820,7 @@ function FileUploaderInput({
initialFilesTree !== undefined ? (
<Card className="mb-4">
<CardBody style={{ backgroundColor: "#e9ecef" }}>
<FileExplorer
filesTree={initialFilesTree}
lineageUrl=" "
insideProject={false}
/>
<FileExplorer filesTree={initialFilesTree} insideProject={false} />
</CardBody>
</Card>
) : null;
Expand Down
4 changes: 3 additions & 1 deletion client/src/dataset/Dataset.present.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ function DisplayFiles(props) {
return newFile;
});

// see Url.pages.project.file / Url.pages.project.lineage
const linkUrl = props.lineagesUrl?.replace("/lineage", "/blob");
return (
<Card key="datasetDetails" className="mb-4">
<CardHeader className="bg-white p-3 ps-4" data-cy="dataset-file-title">
Expand All @@ -103,7 +105,7 @@ function DisplayFiles(props) {
) : (
<FileExplorer
files={filesWithNames}
lineageUrl={props.lineagesUrl}
linkUrl={linkUrl}
insideProject={props.insideProject}
foldersOpenOnLoad={openFolders}
/>
Expand Down

0 comments on commit e42b194

Please sign in to comment.