Skip to content
This repository has been archived by the owner on Nov 29, 2023. It is now read-only.

Commit

Permalink
Merge pull request #53 from lars-reimann/function_description
Browse files Browse the repository at this point in the history
Show the description of a function in the right pane
  • Loading branch information
lars-reimann authored Jun 18, 2021
2 parents f5b19a8 + 62ffeba commit f79e3a6
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 75 deletions.
19 changes: 12 additions & 7 deletions client/src/Components/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@ import React, {useState} from 'react';
import './App.css';
import ParameterView from "../ParameterView/ParameterView";
import TreeView from "../TreeView/TreeView";
import PythonFunction from "../../model/PythonFunction";

function App() {

const [parameters, setParameters] = useState([]);
const [selection, setSelection ] = useState([]);
const [selection, setSelection] = useState([]);
const [selectedFunction, setSelectedFunction] = useState<Nullable<PythonFunction>>(null);

return (
<div className="App">
<TreeView setParameters = { setParameters }
selection = { selection }
setSelection = { setSelection }/>
<ParameterView inputParameters = { parameters }
selection = { selection }
setSelection = { setSelection }/>
<TreeView setParameters={setParameters}
selection={selection}
setSelection={setSelection}
setSelectedFunction={setSelectedFunction}
/>
<ParameterView inputParameters={parameters}
selection={selection}
selectedFunction={selectedFunction}
/>
</div>
);
}
Expand Down
2 changes: 1 addition & 1 deletion client/src/Components/ParameterView/DocumentationText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import remarkGfm from "remark-gfm";
import classNames from "classnames";

// @ts-ignore
const DocumentationText = ({inputText}) => {
const DocumentationText = ({inputText = ""}) => {

const shortenedText = inputText.split("\n\n")[0];
const hasMultipleLines = shortenedText !== inputText;
Expand Down
14 changes: 11 additions & 3 deletions client/src/Components/ParameterView/ParameterView.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import ParameterNode from "./ParameterNode";
import React from "react";
import PythonParameter from "../../model/PythonParameter";
import PythonFunction from "../../model/PythonFunction";
import DocumentationText from "./DocumentationText";

type ParameterViewProps = {
inputParameters: PythonParameter[],
selection: string[],
setSelection: any
selectedFunction: Nullable<PythonFunction>
};

const ParameterView = ({inputParameters, selection }: ParameterViewProps) => {
const ParameterView = ({inputParameters, selection, selectedFunction}: ParameterViewProps) => {

const hasInputParameters = inputParameters.length > 0;
console.log(selection);

return (
<div className="parameter-view">
Expand All @@ -22,6 +23,13 @@ const ParameterView = ({inputParameters, selection }: ParameterViewProps) => {
.reduce((p, c) => [p, (<span> / </span>), c]) :
"" }
</div>
{ selectedFunction !== null &&
<>
<h1>{selectedFunction.name}</h1>
<DocumentationText inputText={selectedFunction.description} />
</>
}

<h2 className={"parameter-title"}>Parameters</h2>
{
inputParameters?.map(function (parameters) {
Expand Down
45 changes: 29 additions & 16 deletions client/src/Components/Tree/ClassNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PythonClass from "../../model/PythonClass";
import classNames from "classnames";
import FunctionNode from "./FunctionNode";
import {isEmptyList} from "../../Utility/listOperations";
import PythonFunction from "../../model/PythonFunction";

type ClassNodeProps = {
parentPath: string[],
Expand All @@ -11,17 +12,26 @@ type ClassNodeProps = {
setSelection: (newValue: string[]) => void,
moduleName: string,
setParameters: any,
setSelectedFunction: Setter<Nullable<PythonFunction>>
}

const ClassNode = ({parentPath, pythonClass, selection, setSelection, moduleName, setParameters}: ClassNodeProps) => {
const ClassNode = ({
parentPath,
pythonClass,
selection,
setSelection,
moduleName,
setParameters,
setSelectedFunction
}: ClassNodeProps) => {

const [childVisible, setChildVisibility] = useState(false);
const hasMethods = isEmptyList(pythonClass.methods);
const path = parentPath.concat(pythonClass.name);
const cssClasses = classNames(
"tree-view-row", {
"text-muted": !hasMethods,
"cursor-na":!hasMethods,
"cursor-na": !hasMethods,
"pl-3-5rem": !hasMethods,
"pl-3rem": hasMethods,
"selected": (selection.join() === path.join()) && hasMethods,
Expand All @@ -34,23 +44,26 @@ const ClassNode = ({parentPath, pythonClass, selection, setSelection, moduleName
onClick={() => {
setSelection(path);
setChildVisibility(!childVisible);
setSelectedFunction(null);
}}>
{ hasMethods && <span className="indicator visibility-indicator">{ childVisible ? "▼" : "▶" }</span> }
<span className="indicator"> 𝒞 </span>
{ " " }
<span> { pythonClass.name } </span>
{hasMethods && <span className="indicator visibility-indicator">{childVisible ? "▼" : "▶"}</span>}
<span className="indicator"> 𝒞 </span>
{" "}
<span> {pythonClass.name} </span>
</div>
{ hasMethods && childVisible && <div>
{ pythonClass.methods.map(method => (
<FunctionNode parentPath={ path }
key = { method.name }
pythonFunction = { method }
selection = { selection }
setSelection = { setSelection }
isMethod = { true }
setParameters = { setParameters } />
{hasMethods && childVisible && <div>
{pythonClass.methods.map(method => (
<FunctionNode parentPath={path}
key={method.name}
pythonFunction={method}
selection={selection}
setSelection={setSelection}
isMethod={true}
setParameters={setParameters}
setSelectedFunction={setSelectedFunction}
/>
))}
</div> }
</div>}
</div>
);
};
Expand Down
24 changes: 17 additions & 7 deletions client/src/Components/Tree/FunctionNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,18 @@ type FunctionNodeProps = {

/** A parent of a Python class can be a class or a Python module. */
parentPath: string[],
setSelectedFunction: Setter<Nullable<PythonFunction>>
}

const FunctionNode = ({pythonFunction, selection, setSelection, setParameters, parentPath, isMethod = false} : FunctionNodeProps) => {
const FunctionNode = ({
pythonFunction,
selection,
setSelection,
setParameters,
parentPath,
isMethod = false,
setSelectedFunction
}: FunctionNodeProps) => {

const path = parentPath.concat(pythonFunction.name)
const hasParameters = isEmptyList(pythonFunction.parameters);
Expand All @@ -30,15 +39,16 @@ const FunctionNode = ({pythonFunction, selection, setSelection, setParameters, p

return (
<div className="function-node">
<div className = { cssClasses }
onClick = {() => {
setSelection(path);
setParameters(pythonFunction.parameters)
}}>
<div className={cssClasses}
onClick={() => {
setSelection(path);
setParameters(pythonFunction.parameters);
setSelectedFunction(pythonFunction);
}}>
<span className="indicator">
𝑓
</span>
{ " " }
{" "}
<span>
{pythonFunction.name}
</span>
Expand Down
70 changes: 42 additions & 28 deletions client/src/Components/Tree/ModuleNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,25 @@ import FunctionNode from "./FunctionNode";
import {isEmptyList} from "../../Utility/listOperations";
import classNames from "classnames";
import PythonModule from "../../model/PythonModule";
import PythonFunction from "../../model/PythonFunction";

type ModuleNodeProps = {
parentPath: string[],
pythonModule: PythonModule,
selection: string[],
setSelection: (newValue: string[]) => void,
setParameters: any,
setSelectedFunction: Setter<Nullable<PythonFunction>>
}

const ModuleNode = ({parentPath, pythonModule, selection, setSelection, setParameters}: ModuleNodeProps) => {
const ModuleNode = ({
parentPath,
pythonModule,
selection,
setSelection,
setParameters,
setSelectedFunction
}: ModuleNodeProps) => {

/** This is the Name of this module without its packages name prefixed. */

Expand All @@ -28,7 +37,7 @@ const ModuleNode = ({parentPath, pythonModule, selection, setSelection, setParam
const cssClasses = classNames(
"tree-view-row", {
"text-muted": !hasChildren,
"cursor-na":!hasChildren,
"cursor-na": !hasChildren,
"pl-2rem": !hasChildren,
"pl-1-5rem": hasChildren,
"selected": (selection.join() === path.join()) && hasChildren,
Expand All @@ -38,41 +47,46 @@ const ModuleNode = ({parentPath, pythonModule, selection, setSelection, setParam
return (
<div className="module-node">
<div className={cssClasses}
onClick={() => {
setSelection(path)
setChildVisibility(!childVisible)
}}>
{ (hasClasses || hasFunctions) && <span className="indicator visibility-indicator">{ childVisible ? "▼" : "▶" }</span> }
onClick={() => {
setSelection(path)
setChildVisibility(!childVisible)
}}>
{(hasClasses || hasFunctions) &&
<span className="indicator visibility-indicator">{childVisible ? "▼" : "▶"}</span>}
<span className="indicator">
</span>
{ " " }
{" "}
<span>
{ pythonModule.name }
{pythonModule.name}
</span>
</div>
<div>
{ hasClasses && childVisible && <div>
{ pythonModule.classes.map(moduleClass => (
<ClassNode key = { moduleClass.name }
parentPath = { path }
pythonClass = {moduleClass }
selection = { selection }
setSelection = { setSelection }
moduleName = { pythonModule.name }
setParameters = { setParameters } />
{hasClasses && childVisible && <div>
{pythonModule.classes.map(moduleClass => (
<ClassNode key={moduleClass.name}
parentPath={path}
pythonClass={moduleClass}
selection={selection}
setSelection={setSelection}
moduleName={pythonModule.name}
setParameters={setParameters}
setSelectedFunction={setSelectedFunction}
/>
))}
</div> }
{ hasFunctions && childVisible && <div>
{ pythonModule.functions.map(moduleFunction => (
<FunctionNode parentPath = { path }
key = { moduleFunction.name }
pythonFunction = { moduleFunction }
selection = { selection }
setSelection = { setSelection }
setParameters = { setParameters } />
</div>}
{hasFunctions && childVisible && <div>
{pythonModule.functions.map(moduleFunction => (
<FunctionNode parentPath={path}
key={moduleFunction.name}
pythonFunction={moduleFunction}
selection={selection}
setSelection={setSelection}
setParameters={setParameters}
setSelectedFunction={setSelectedFunction}
/>
))}
</div> }
</div>}
</div>
</div>
)
Expand Down
12 changes: 8 additions & 4 deletions client/src/Components/Tree/Tree.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
import React from 'react'
import ModuleNode from "./ModuleNode";
import PythonPackage from "../../model/PythonPackage";
import PythonFunction from "../../model/PythonFunction";

type TreeProps = {
pythonPackage: PythonPackage,
setParameters: any,
selection: string[],
setSelection: any
setSelection: any,
setSelectedFunction: Setter<Nullable<PythonFunction>>
}

const Tree = ({pythonPackage, setParameters, selection, setSelection}: TreeProps) => {
const Tree = ({pythonPackage, setParameters, selection, setSelection, setSelectedFunction}: TreeProps) => {

const path = [pythonPackage.name];

return (
<div className="tree">
{pythonPackage.modules.map(module => (
<ModuleNode parentPath = { path }
<ModuleNode parentPath={path}
key={module.name}
pythonModule={module}
selection={selection}
setSelection={setSelection}
setParameters={setParameters}/>
setParameters={setParameters}
setSelectedFunction={setSelectedFunction}
/>
))}
</div>
);
Expand Down
18 changes: 11 additions & 7 deletions client/src/Components/TreeView/TreeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,26 @@ import Tree from "../Tree/Tree";
import './tree-view.css';
import packageJson from "../../data/sklearn.json";
import PythonPackageBuilder from "../../model/PythonPackageBuilder";
import PythonFunction from "../../model/PythonFunction";

type TreeViewProps = {
setParameters: any,
selection: string[],
setSelection: any
setSelection: any,
setSelectedFunction: Setter<Nullable<PythonFunction>>
}

const TreeView = ({setParameters, selection, setSelection}: TreeViewProps) => {
const TreeView = ({setParameters, selection, setSelection, setSelectedFunction}: TreeViewProps) => {
let pythonPackage = PythonPackageBuilder.make(packageJson);
return(
return (
<div className="tree-view">
<h2 className="package-name">{pythonPackage.name}</h2>
<Tree pythonPackage = { pythonPackage }
setParameters = { setParameters }
selection = { selection }
setSelection = { setSelection }/>
<Tree pythonPackage={pythonPackage}
setParameters={setParameters}
selection={selection}
setSelection={setSelection}
setSelectedFunction={setSelectedFunction}
/>
</div>
)
}
Expand Down
4 changes: 4 additions & 0 deletions client/src/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type Nullable<T> = T | null

type Getter<T> = () => T
type Setter<T> = (T) => void
Loading

0 comments on commit f79e3a6

Please sign in to comment.