diff --git a/client/src/Components/App/App.tsx b/client/src/Components/App/App.tsx index 559d020e3..956dbdd9b 100644 --- a/client/src/Components/App/App.tsx +++ b/client/src/Components/App/App.tsx @@ -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>(null); return (
- - + +
); } diff --git a/client/src/Components/ParameterView/DocumentationText.tsx b/client/src/Components/ParameterView/DocumentationText.tsx index 7e9e045a2..154acae5a 100644 --- a/client/src/Components/ParameterView/DocumentationText.tsx +++ b/client/src/Components/ParameterView/DocumentationText.tsx @@ -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; diff --git a/client/src/Components/ParameterView/ParameterView.tsx b/client/src/Components/ParameterView/ParameterView.tsx index 41971e830..399b01a8f 100644 --- a/client/src/Components/ParameterView/ParameterView.tsx +++ b/client/src/Components/ParameterView/ParameterView.tsx @@ -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 }; -const ParameterView = ({inputParameters, selection }: ParameterViewProps) => { +const ParameterView = ({inputParameters, selection, selectedFunction}: ParameterViewProps) => { const hasInputParameters = inputParameters.length > 0; - console.log(selection); return (
@@ -22,6 +23,13 @@ const ParameterView = ({inputParameters, selection }: ParameterViewProps) => { .reduce((p, c) => [p, ( / ), c]) : "" }
+ { selectedFunction !== null && + <> +

{selectedFunction.name}

+ + + } +

Parameters

{ inputParameters?.map(function (parameters) { diff --git a/client/src/Components/Tree/ClassNode.tsx b/client/src/Components/Tree/ClassNode.tsx index d1fc17ed9..569a2bf5c 100644 --- a/client/src/Components/Tree/ClassNode.tsx +++ b/client/src/Components/Tree/ClassNode.tsx @@ -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[], @@ -11,9 +12,18 @@ type ClassNodeProps = { setSelection: (newValue: string[]) => void, moduleName: string, setParameters: any, + setSelectedFunction: Setter> } -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); @@ -21,7 +31,7 @@ const ClassNode = ({parentPath, pythonClass, selection, setSelection, moduleName 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, @@ -34,23 +44,26 @@ const ClassNode = ({parentPath, pythonClass, selection, setSelection, moduleName onClick={() => { setSelection(path); setChildVisibility(!childVisible); + setSelectedFunction(null); }}> - { hasMethods && { childVisible ? "▼" : "▶" } } - 𝒞 - { " " } - { pythonClass.name } + {hasMethods && {childVisible ? "▼" : "▶"}} + 𝒞 + {" "} + {pythonClass.name} - { hasMethods && childVisible &&
- { pythonClass.methods.map(method => ( - + {hasMethods && childVisible &&
+ {pythonClass.methods.map(method => ( + ))} -
} +
} ); }; diff --git a/client/src/Components/Tree/FunctionNode.tsx b/client/src/Components/Tree/FunctionNode.tsx index bb9b70324..38431d3f1 100644 --- a/client/src/Components/Tree/FunctionNode.tsx +++ b/client/src/Components/Tree/FunctionNode.tsx @@ -12,9 +12,18 @@ type FunctionNodeProps = { /** A parent of a Python class can be a class or a Python module. */ parentPath: string[], + setSelectedFunction: Setter> } -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); @@ -30,15 +39,16 @@ const FunctionNode = ({pythonFunction, selection, setSelection, setParameters, p return (
-
{ - setSelection(path); - setParameters(pythonFunction.parameters) - }}> +
{ + setSelection(path); + setParameters(pythonFunction.parameters); + setSelectedFunction(pythonFunction); + }}> 𝑓 - { " " } + {" "} {pythonFunction.name} diff --git a/client/src/Components/Tree/ModuleNode.tsx b/client/src/Components/Tree/ModuleNode.tsx index a784e28ae..4ab556234 100644 --- a/client/src/Components/Tree/ModuleNode.tsx +++ b/client/src/Components/Tree/ModuleNode.tsx @@ -4,6 +4,7 @@ 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[], @@ -11,9 +12,17 @@ type ModuleNodeProps = { selection: string[], setSelection: (newValue: string[]) => void, setParameters: any, + setSelectedFunction: Setter> } -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. */ @@ -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, @@ -38,41 +47,46 @@ const ModuleNode = ({parentPath, pythonModule, selection, setSelection, setParam return (
{ - setSelection(path) - setChildVisibility(!childVisible) - }}> - { (hasClasses || hasFunctions) && { childVisible ? "▼" : "▶" } } + onClick={() => { + setSelection(path) + setChildVisibility(!childVisible) + }}> + {(hasClasses || hasFunctions) && + {childVisible ? "▼" : "▶"}} - { " " } + {" "} - { pythonModule.name } + {pythonModule.name}
- { hasClasses && childVisible &&
- { pythonModule.classes.map(moduleClass => ( - + {hasClasses && childVisible &&
+ {pythonModule.classes.map(moduleClass => ( + ))} -
} - { hasFunctions && childVisible &&
- { pythonModule.functions.map(moduleFunction => ( - +
} + {hasFunctions && childVisible &&
+ {pythonModule.functions.map(moduleFunction => ( + ))} -
} +
}
) diff --git a/client/src/Components/Tree/Tree.tsx b/client/src/Components/Tree/Tree.tsx index 07788b005..06624820d 100644 --- a/client/src/Components/Tree/Tree.tsx +++ b/client/src/Components/Tree/Tree.tsx @@ -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> } -const Tree = ({pythonPackage, setParameters, selection, setSelection}: TreeProps) => { +const Tree = ({pythonPackage, setParameters, selection, setSelection, setSelectedFunction}: TreeProps) => { const path = [pythonPackage.name]; return (
{pythonPackage.modules.map(module => ( - + setParameters={setParameters} + setSelectedFunction={setSelectedFunction} + /> ))}
); diff --git a/client/src/Components/TreeView/TreeView.tsx b/client/src/Components/TreeView/TreeView.tsx index 52a846a82..a7c29e068 100644 --- a/client/src/Components/TreeView/TreeView.tsx +++ b/client/src/Components/TreeView/TreeView.tsx @@ -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> } -const TreeView = ({setParameters, selection, setSelection}: TreeViewProps) => { +const TreeView = ({setParameters, selection, setSelection, setSelectedFunction}: TreeViewProps) => { let pythonPackage = PythonPackageBuilder.make(packageJson); - return( + return (

{pythonPackage.name}

- +
) } diff --git a/client/src/global.d.ts b/client/src/global.d.ts new file mode 100644 index 000000000..89bd2ba5f --- /dev/null +++ b/client/src/global.d.ts @@ -0,0 +1,4 @@ +type Nullable = T | null + +type Getter = () => T +type Setter = (T) => void \ No newline at end of file diff --git a/client/src/model/PythonFunction.ts b/client/src/model/PythonFunction.ts index 10a4cec6d..ed0a8a05d 100644 --- a/client/src/model/PythonFunction.ts +++ b/client/src/model/PythonFunction.ts @@ -11,13 +11,26 @@ export default class PythonFunction { // TODO: Implementieren readonly returnType: PythonReturnType; readonly docstring: string; + readonly summary: string; + readonly description: string; - constructor(name: string, decorators: string[], parameters: PythonParameter[], hasReturnType: boolean, returnType: PythonReturnType, docstring: string) { + constructor( + name: string, + decorators: string[], + parameters: PythonParameter[], + hasReturnType: boolean, + returnType: PythonReturnType, + docstring: string, + summary: string, + description: string, + ) { this.name = name; this.decorators = decorators; this.parameters = parameters; this.hasReturnType = hasReturnType; this.returnType = returnType; this.docstring = docstring; + this.summary = summary; + this.description = description; } } \ No newline at end of file diff --git a/client/src/model/PythonPackageBuilder.ts b/client/src/model/PythonPackageBuilder.ts index 707131791..8e788f5a2 100644 --- a/client/src/model/PythonPackageBuilder.ts +++ b/client/src/model/PythonPackageBuilder.ts @@ -30,7 +30,16 @@ export default class PythonPackageBuilder { ps.push(new PythonParameter(p.name, p.type, p.hasDefault, p.defaultValue, p.limitation, p.ignored, p.description)); }); - fs.push(new PythonFunction(f.name, f.decorators, ps, f.hasReturnType, new PythonReturnType(), f.fullDocstring)) + fs.push(new PythonFunction( + f.name, + f.decorators, + ps, + f.hasReturnType, + new PythonReturnType(), + f.fullDocstring, + f.summary, + f.description + )) }); ms.push(new PythonModule(m.name, m.imports, cs, fs))