Skip to content
This repository was archived by the owner on Jan 19, 2025. It is now read-only.
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
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"@types/react-router-dom": "^5.1.7",
"bootstrap": "^4.6.0",
"formik": "^2.2.9",
"immutable": "^4.0.0-rc.12",
"react": "^17.0.2",
"react-bootstrap": "^1.6.1",
"react-dom": "^17.0.2",
Expand Down
16 changes: 12 additions & 4 deletions client/src/Components/App/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {useState} from 'react';
import pythonPackageJson from "../../data/sklearn.json";
import AnnotationStore from "../../model/annotation/AnnotationStore";
import PythonDeclaration from "../../model/python/PythonDeclaration";
import {parsePythonPackageJson, PythonPackageJson} from "../../model/python/PythonPackageBuilder";
import Menu from "../Menu/Menu";
Expand All @@ -10,19 +11,26 @@ import AppCSS from './App.module.css';
export default function App(): JSX.Element {
const pythonPackage = parsePythonPackageJson(pythonPackageJson as PythonPackageJson);
const [selection, setSelection] = useState<PythonDeclaration>(pythonPackage);
const [annotationStore, setAnnotationStore] = useState(new AnnotationStore());

return (
<div className={AppCSS.app}>
<div className={AppCSS.menu}>
<Menu selection={selection}/>
</div>
<div className={AppCSS.leftPane}>
<TreeView pythonPackage={pythonPackage}
selection={selection}
setSelection={setSelection}/>
<TreeView
pythonPackage={pythonPackage}
selection={selection}
setSelection={setSelection}
/>
</div>
<div className={AppCSS.rightPane}>
<ParameterView selection={selection}/>
<ParameterView
selection={selection}
annotationStore={annotationStore}
setAnnotationStore={setAnnotationStore}
/>
</div>
</div>
);
Expand Down
17 changes: 8 additions & 9 deletions client/src/Components/Dialog/RenameDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import React, {useState} from "react";
import {Button, Form, Modal} from "react-bootstrap";
import RenameAnnotation from "../../model/annotation/RenameAnnotation";
import {Nullable, Setter} from "../../util/types";
import {isValidPythonIdentifier} from "../../util/validation";
import "../ParameterView/ParameterView.css";

interface RenameDialogProps {
isVisible: boolean
setIsVisible: Setter<boolean>
originalName: string
renameAnnotation: Nullable<RenameAnnotation>
setRenameAnnotation: Setter<Nullable<RenameAnnotation>>
oldName: string
newName: Nullable<string>
setNewName: Setter<Nullable<string>>
}

export default function RenameDialog(props: RenameDialogProps): JSX.Element {
const [currentUserInput, setCurrentUserInput] = useState(props.renameAnnotation?.newName ?? props.originalName);
const [currentUserInput, setCurrentUserInput] = useState(props.newName ?? props.oldName);

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => setCurrentUserInput(event.target.value);

Expand All @@ -23,11 +22,11 @@ export default function RenameDialog(props: RenameDialogProps): JSX.Element {
};

const submit = () => {
if (currentUserInput === props.originalName) {
props.setRenameAnnotation(null);
if (currentUserInput === props.oldName) {
props.setNewName(null);
props.setIsVisible(false);
} else if (isValidPythonIdentifier(currentUserInput)) {
props.setRenameAnnotation(new RenameAnnotation(currentUserInput));
props.setNewName(currentUserInput);
props.setIsVisible(false);
}
};
Expand All @@ -46,7 +45,7 @@ export default function RenameDialog(props: RenameDialogProps): JSX.Element {
<Modal.Body>
<Form.Group>
<Form.Label>
New name for &quot;{props.originalName}&quot;:
New name for &quot;{props.oldName}&quot;:
</Form.Label>
<Form.Control
type="text"
Expand Down
34 changes: 21 additions & 13 deletions client/src/Components/ParameterView/ParameterNode.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
import React, {useState} from "react";
import {Dropdown} from "react-bootstrap";
import RenameAnnotation from "../../model/annotation/RenameAnnotation";
import AnnotationStore from "../../model/annotation/AnnotationStore";
import PythonParameter from "../../model/python/PythonParameter";
import {Nullable} from "../../util/types";
import {Nullable, Setter} from "../../util/types";
import RenameDialog from "../Dialog/RenameDialog";
import DocumentationText from "./DocumentationText";
import "./ParameterView.css";
import RenameAnnotationView from "./RenameAnnotationView";

interface ParameterNodeProps {
inputParameter: PythonParameter
pythonParameter: PythonParameter
annotationStore: AnnotationStore
setAnnotationStore: Setter<AnnotationStore>
}

export default function ParameterNode(props: ParameterNodeProps): JSX.Element {
const [showRenameDialog, setShowRenameDialog] = useState(false);
const [renameAnnotation, setRenameAnnotation] = useState<Nullable<RenameAnnotation>>(null);

const newName = props.annotationStore.getRenamingFor(props.pythonParameter);
const setNewName = (newName: Nullable<string>) => {
props.setAnnotationStore(
props.annotationStore.setRenamingFor(props.pythonParameter, newName)
);
};

const openRenameDialog = () => setShowRenameDialog(true);
const handleEnumSelect = () => console.log("TODO");

return (
<div className="parameter-list">
<div className="parameter-header">
<h4 className="parameter-name">{props.inputParameter.name}</h4>
<h4 className="parameter-name">{props.pythonParameter.name}</h4>
<Dropdown>
<Dropdown.Toggle size="sm" variant="outline-primary">
+ @Annotation
Expand All @@ -34,26 +42,26 @@ export default function ParameterNode(props: ParameterNodeProps): JSX.Element {
</Dropdown>
</div>
<RenameAnnotationView
renameAnnotation={renameAnnotation}
setRenameAnnotation={setRenameAnnotation}
newName={newName}
setNewName={setNewName}
onRenameEdit={openRenameDialog}
/>

{/*This additional check cause the dialog to be thrown away after closing it, resetting its state*/}
{showRenameDialog && <RenameDialog
isVisible={showRenameDialog}
setIsVisible={setShowRenameDialog}
originalName={props.inputParameter.name}
renameAnnotation={renameAnnotation}
setRenameAnnotation={setRenameAnnotation}
oldName={props.pythonParameter.name}
newName={newName}
setNewName={setNewName}
/>}

{
props.inputParameter.description &&
<DocumentationText inputText={props.inputParameter?.description}/>
props.pythonParameter.description &&
<DocumentationText inputText={props.pythonParameter?.description}/>
}
{
!props.inputParameter.description &&
!props.pythonParameter.description &&
<p className="pl-3-5rem text-muted">There is no documentation for this parameter.</p>
}
</div>
Expand Down
27 changes: 18 additions & 9 deletions client/src/Components/ParameterView/ParameterView.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
import React from "react";
import AnnotationStore from "../../model/annotation/AnnotationStore";
import PythonDeclaration from "../../model/python/PythonDeclaration";
import PythonFunction from "../../model/python/PythonFunction";
import {isEmptyList} from "../../util/listOperations";
import {Setter} from "../../util/types";
import DocumentationText from "./DocumentationText";
import ParameterNode from "./ParameterNode";

interface ParameterViewProps {
selection: PythonDeclaration
selection: PythonDeclaration,
annotationStore: AnnotationStore
setAnnotationStore: Setter<AnnotationStore>
}

export default function ParameterView({selection}: ParameterViewProps): JSX.Element {
export default function ParameterView(props: ParameterViewProps): JSX.Element {
return (
<div className="parameter-view">
{selection instanceof PythonFunction &&
{props.selection instanceof PythonFunction &&
<>
<h1>{selection.name}</h1>
<DocumentationText inputText={selection.description}/>
<h1>{props.selection.name}</h1>
<DocumentationText inputText={props.selection.description}/>
<h2 className={"parameter-title"}>Parameters</h2>
{
!isEmptyList(selection.parameters) ?
selection.parameters.map(function (parameters) {
return (<ParameterNode key={parameters.name} inputParameter={parameters}/>);
}) :
!isEmptyList(props.selection.parameters) ?
props.selection.parameters.map(parameters => (
<ParameterNode
key={parameters.name}
pythonParameter={parameters}
annotationStore={props.annotationStore}
setAnnotationStore={props.setAnnotationStore}
/>
)) :
<span className="text-muted" style={{paddingLeft: '1rem'}}>There are no parameters.</span>
}
</>
Expand Down
15 changes: 7 additions & 8 deletions client/src/Components/ParameterView/RenameAnnotationView.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import {faTrash, faWrench} from '@fortawesome/free-solid-svg-icons';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import React from "react";
import {Button, ButtonGroup, Col, Row} from "react-bootstrap";
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faTrash, faWrench} from '@fortawesome/free-solid-svg-icons';
import RenameAnnotation from "../../model/annotation/RenameAnnotation";
import {Nullable, Setter} from "../../util/types";

interface RenameAnnotationViewProps {
renameAnnotation: Nullable<RenameAnnotation>,
setRenameAnnotation: Setter<Nullable<RenameAnnotation>>,
newName: Nullable<string>,
setNewName: Setter<Nullable<string>>,
onRenameEdit: () => void,
}

const RenameAnnotationView: React.FC<RenameAnnotationViewProps> = (props) => {
const deleteRenameAnnotation = () => props.setRenameAnnotation(null);
const deleteRenameAnnotation = () => props.setNewName(null);

if (props.renameAnnotation !== null) {
if (props.newName !== null) {
return (<div>
<h5>Annotations</h5>
<Row>
<Col className="align-items-center" xs="auto">
<code>{`@rename: ${props.renameAnnotation.newName}`}</code>
<code>{`@rename: ${props.newName}`}</code>
</Col>
<Col xs="auto">
<ButtonGroup>
Expand Down
29 changes: 29 additions & 0 deletions client/src/model/annotation/AnnotationStore.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {Map} from "immutable";
import {Nullable} from "../../util/types";
import PythonDeclaration from "../python/PythonDeclaration";

export default class AnnotationStore {
private readonly renamings: RenameAnnotationStore

constructor(renamings: RenameAnnotationStore = Map()) {
this.renamings = renamings;
}

getRenamingFor(declaration: PythonDeclaration): Nullable<string> {
return this.renamings.get(declaration.pathAsString()) ?? null;
}

setRenamingFor(declaration: PythonDeclaration, newName: Nullable<string>): AnnotationStore {
if (newName === null) {
return this.removeRenamingFor(declaration);
}

return new AnnotationStore(this.renamings.set(declaration.pathAsString(), newName));
}

removeRenamingFor(declaration: PythonDeclaration): AnnotationStore {
return new AnnotationStore(this.renamings.remove(declaration.pathAsString()));
}
}

export type RenameAnnotationStore = Map<string, string>
7 changes: 0 additions & 7 deletions client/src/model/annotation/RenameAnnotation.tsx

This file was deleted.

4 changes: 4 additions & 0 deletions client/src/model/python/PythonDeclaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export default abstract class PythonDeclaration {
return result;
}

pathAsString(): string {
return this.path().join("/");
}

getByRelativePath(relativePath: string[]): Nullable<PythonDeclaration> {
if (isEmptyList(relativePath)) {
return this;
Expand Down
5 changes: 5 additions & 0 deletions client/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5913,6 +5913,11 @@ immer@8.0.1:
resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656"
integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==

immutable@^4.0.0-rc.12:
version "4.0.0-rc.12"
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0-rc.12.tgz#ca59a7e4c19ae8d9bf74a97bdf0f6e2f2a5d0217"
integrity sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A==

import-cwd@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
Expand Down