-
Matthias Konitzny authoredMatthias Konitzny authored
nodedetails.tsx 7.19 KiB
import React from "react";
import { Node } from "../../common/graph/node";
import { NodeType } from "../../common/graph/nodetype";
import "./nodedetails.css";
import { NodeDataChangeRequest } from "../editor";
type NodeDetailsProps = {
selectedNodes: Node[];
idToObjectType: Map<number, NodeType>;
onNodeDataChange: { (requests: NodeDataChangeRequest[]): void };
};
function NodeDetails({
selectedNodes,
idToObjectType,
onNodeDataChange,
}: NodeDetailsProps) {
if (selectedNodes.length == 0) {
return <div id="nodedetails">No node selected.</div>;
}
const getCollectiveValue = function <ValueType>(
getter: (n: Node) => ValueType,
defaultValue: ValueType
) {
const referenceValue = getter(selectedNodes[0]);
const differentValueFound = selectedNodes.some(
(n: Node) => getter(n) !== referenceValue
);
return differentValueFound ? defaultValue : referenceValue;
};
const referenceData: NodeDataChangeRequest = {
id: -1,
name: getCollectiveValue((n) => n.name, undefined),
description: getCollectiveValue((n) => n.description, undefined),
video: getCollectiveValue((n) => n.video, undefined),
icon: getCollectiveValue((n) => n.icon, undefined),
banner: getCollectiveValue((n) => n.banner, undefined),
references: getCollectiveValue((n) => n.references, undefined),
type: getCollectiveValue((n) => n.type, undefined),
};
const handleDataChange = function <ValueType>(
key: keyof NodeDataChangeRequest,
value: ValueType
) {
Object.assign(referenceData, { [key]: value });
onNodeDataChange(
selectedNodes.map((node) => {
return { ...referenceData, id: node.id, name: node.name };
})
);
};
return (
<div id="nodedetails">
{selectedNodes.length === 1 ? (
<div>
<label htmlFor="node-name" hidden>
Name
</label>
<input
type="text"
id="node-name"
name="node-name"
placeholder="Enter name"
className="bottom-space"
value={referenceData.name}
onChange={(event) =>
handleDataChange("name", event.target.value)
}
></input>
</div>
) : (
<h3>{selectedNodes.length} nodes selected</h3>
)}
{selectedNodes.length === 1 ? (
<div>
<label htmlFor="node-description">Description</label>
<br />
<textarea
id="node-description"
name="node-description"
className="bottom-space"
value={referenceData.description}
onChange={(event) =>
handleDataChange("description", event.target.value)
}
></textarea>
</div>
) : (
""
)}
<div>
<label htmlFor="node-image">Icon Image</label>
<br />
{referenceData.icon && (
<div>
<img
id="node-image-preview"
className="preview-image"
src={referenceData.icon}
/>
<br />
</div>
)}
<input
type="text"
id="node-image"
name="node-image"
placeholder="Image URL"
className="bottom-space"
value={referenceData.icon ?? ""}
onChange={(event) =>
handleDataChange("icon", event.target.value)
}
/>
</div>
<div>
<label htmlFor="node-detail-image">Banner Image</label>
<br />
{referenceData.banner && (
<div>
<img
id="node-image-preview"
className="preview-image"
src={referenceData.banner}
/>
<br />
</div>
)}
<input
type="text"
id="node-detail-image"
name="node-detail-image"
placeholder="Image URL"
className="bottom-space"
value={referenceData.banner ?? ""}
onChange={(event) =>
handleDataChange("banner", event.target.value)
}
/>
</div>
<div>
<label htmlFor="node-type">Type</label>
<br />
<select
id="node-type"
name="node-type"
className="bottom-space"
value={referenceData.type ? referenceData.type.id : ""}
onChange={(event) =>
handleDataChange(
"type",
idToObjectType.get(Number(event.target.value))
)
}
>
<option className="empty-select-option" disabled></option>
{[...idToObjectType.values()].map((type) => (
<option key={type.id} value={type.id}>
{type.name}
</option>
))}
</select>
</div>
<div>
<label htmlFor="node-video">Video</label>
<br />
<input
type="text"
placeholder="Video URL"
id="node-video"
name="node-video"
value={referenceData.video ?? ""}
onChange={(event) =>
handleDataChange("video", event.target.value)
}
></input>
</div>
{selectedNodes.length === 1 ? (
<div>
<label htmlFor="node-references">References</label>{" "}
<small>One URL per line</small>
<br />
<textarea
id="node-references"
name="node-references"
className="bottom-space"
value={referenceData.references}
onChange={(event) =>
handleDataChange("references", event.target.value)
}
></textarea>
</div>
) : (
""
)}
</div>
);
}
export default NodeDetails;