import React from "react"; import { ReactNode } from "react"; import { Node } from "../structures/graph/node"; import { NodeType } from "../structures/graph/nodetype"; import "./nodedetails.css"; type propTypes = { selectedNode: Node; allTypes: NodeType[]; onChange: { (): void }; }; export class NodeDetails extends React.Component<propTypes> { constructor(props: propTypes) { super(props); this.handleNodeTypeChange = this.handleNodeTypeChange.bind(this); this.handleTextChange = this.handleTextChange.bind(this); } private handleNodeTypeChange(event: any) { this.props.selectedNode.setType(event.target.value); this.props.onChange(); } /** * Generic function for handeling a changing text input and applying the new value to the currently selected node. * @param event Change event of text input. * @param property Property to give new value. */ private handleTextChange(event: any, property: string) { const newValue = event.target.value; // Actual change? if ((this.props.selectedNode as any)[property] == newValue) { return; } //TODO: Make sure, that this event is not triggered to quickly! (this.props.selectedNode as any)[property] = newValue; this.props.selectedNode.graph.storeCurrentData( "Changed " + property + " of node [" + this.props.selectedNode.toString() + "]" ); this.props.onChange(); } render(): ReactNode { if (this.props.selectedNode === undefined) { return <p>No Node selected.</p>; } return ( <div id="nodedetails"> <p> <label htmlFor="node-name" hidden> Name </label> <input type="text" id="node-name" name="node-name" placeholder="Enter name" className="bottom-space" value={this.props.selectedNode.label} onChange={(event) => this.handleTextChange(event, "label") } ></input> </p> <p> <label htmlFor="node-description">Description</label> <br /> <textarea id="node-description" name="node-description" className="bottom-space" value={this.props.selectedNode.description} onChange={(event) => this.handleTextChange(event, "description") } ></textarea> </p> <p> <label htmlFor="node-image">Icon Image</label> <br /> {this.props.selectedNode.icon ? ( <div> <img id="node-image-preview" className="preview-image" src={this.props.selectedNode.icon} /> <br /> </div> ) : ( "" )} <input type="text" id="node-image" name="node-image" placeholder="Image URL" className="bottom-space" value={this.props.selectedNode.icon} onChange={(event) => this.handleTextChange(event, "icon") } /> </p> <p> <label htmlFor="node-detail-image">Banner Image</label> <br /> {this.props.selectedNode.banner ? ( <div> <img id="node-image-preview" className="preview-image" src={this.props.selectedNode.banner} /> <br /> </div> ) : ( "" )} <input type="text" id="node-detail-image" name="node-detail-image" placeholder="Image URL" className="bottom-space" value={this.props.selectedNode.banner} onChange={(event) => this.handleTextChange(event, "banner") } /> </p> <p> <label htmlFor="node-type">Type</label> <br /> <select id="node-type" name="node-type" className="bottom-space" value={this.props.selectedNode.type.id} onChange={this.handleNodeTypeChange} > {this.props.allTypes.map((type) => ( <option key={type.id} value={type.id}> {type.name} </option> ))} </select> </p> <p> <label htmlFor="node-video">Video</label> <br /> <input type="text" placeholder="Video URL" id="node-video" name="node-video" value={this.props.selectedNode.video} onChange={(event) => this.handleTextChange(event, "video") } ></input> </p> <p> <label htmlFor="node-references">References</label>{" "} <small>One URL per line</small> <br /> <textarea id="node-references" name="node-references" className="bottom-space" value={this.props.selectedNode.references} onChange={(event) => this.handleTextChange(event, "references") } ></textarea> </p> </div> ); } }