feat: Implement deletable event sphere management and refactor point instances for better event handling
This commit is contained in:
@@ -6,7 +6,7 @@ import {
|
||||
useSelectedFloorItem,
|
||||
} from "../../../store/builder/store";
|
||||
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||
import { useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";
|
||||
import { useDeletableEventSphere, useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";
|
||||
import { useEffect } from "react";
|
||||
import { useBuilderStore } from "../../../store/builder/useBuilderStore";
|
||||
|
||||
@@ -15,6 +15,7 @@ export default function PostProcessing() {
|
||||
const { selectedWallItem } = useSelectedWallItem();
|
||||
const { selectedFloorItem } = useSelectedFloorItem();
|
||||
const { selectedEventSphere } = useSelectedEventSphere();
|
||||
const { deletableEventSphere } = useDeletableEventSphere();
|
||||
const { selectedAisle, selectedWall, selectedDecal, selectedFloor, selectedWallAsset, deletableWallAsset } = useBuilderStore();
|
||||
|
||||
function flattenChildren(children: any[]) {
|
||||
@@ -56,6 +57,10 @@ export default function PostProcessing() {
|
||||
// console.log('deletableWallAsset: ', deletableWallAsset);
|
||||
}, [deletableWallAsset])
|
||||
|
||||
useEffect(() => {
|
||||
// console.log('deletableEventSphere: ', deletableEventSphere);
|
||||
}, [deletableEventSphere])
|
||||
|
||||
return (
|
||||
<EffectComposer autoClear={false}>
|
||||
<N8AO
|
||||
@@ -217,6 +222,21 @@ export default function PostProcessing() {
|
||||
xRay={true}
|
||||
/>
|
||||
)}
|
||||
{deletableEventSphere && (
|
||||
<Outline
|
||||
selection={[deletableEventSphere]}
|
||||
selectionLayer={10}
|
||||
width={1000}
|
||||
blendFunction={BlendFunction.ALPHA}
|
||||
edgeStrength={10}
|
||||
resolutionScale={2}
|
||||
pulseSpeed={0}
|
||||
visibleEdgeColor={CONSTANTS.outlineConfig.assetDeleteColor}
|
||||
hiddenEdgeColor={CONSTANTS.outlineConfig.assetDeleteColor}
|
||||
blur={true}
|
||||
xRay={true}
|
||||
/>
|
||||
)}
|
||||
</EffectComposer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,11 +16,11 @@ interface ConnectionLine {
|
||||
}
|
||||
|
||||
export function Arrows({ connections }: { readonly connections: ConnectionLine[] }) {
|
||||
const [hoveredLineKey, setHoveredLineKey] = useState<string | null>(null);
|
||||
const [hoveredArrowTrigger, setHoveredArrowTrigger] = useState<string | null>(null);
|
||||
const groupRef = useRef<THREE.Group>(null);
|
||||
const { scene } = useThree();
|
||||
const { toolMode } = useToolMode();
|
||||
const { eventStore, productStore } = useSceneContext();
|
||||
const { productStore } = useSceneContext();
|
||||
const { removeTrigger } = productStore();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
@@ -103,15 +103,15 @@ export function Arrows({ connections }: { readonly connections: ConnectionLine[]
|
||||
return (
|
||||
<group
|
||||
key={key}
|
||||
onPointerOver={() => setHoveredLineKey(trigger.triggerUuid)}
|
||||
onPointerOut={() => setHoveredLineKey(null)}
|
||||
onPointerOver={() => setHoveredArrowTrigger(trigger.triggerUuid)}
|
||||
onPointerOut={() => setHoveredArrowTrigger(null)}
|
||||
onClick={() => { removeConnection(trigger) }}
|
||||
>
|
||||
<mesh
|
||||
geometry={shaftGeometry}
|
||||
>
|
||||
<meshStandardMaterial
|
||||
color={toolMode === '3D-Delete' && hoveredLineKey === trigger.triggerUuid ? "red" : "#42a5f5"}
|
||||
color={toolMode === '3D-Delete' && hoveredArrowTrigger === trigger.triggerUuid ? "red" : "#42a5f5"}
|
||||
/>
|
||||
</mesh>
|
||||
<mesh
|
||||
@@ -120,7 +120,7 @@ export function Arrows({ connections }: { readonly connections: ConnectionLine[]
|
||||
geometry={headGeometry}
|
||||
>
|
||||
<meshStandardMaterial
|
||||
color={toolMode === '3D-Delete' && hoveredLineKey === trigger.triggerUuid ? "red" : "#42a5f5"}
|
||||
color={toolMode === '3D-Delete' && hoveredArrowTrigger === trigger.triggerUuid ? "red" : "#42a5f5"}
|
||||
/>
|
||||
</mesh>
|
||||
</group>
|
||||
|
||||
@@ -1,38 +1,46 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import * as THREE from "three";
|
||||
import useModuleStore, { useSubModuleStore } from "../../../../../store/useModuleStore";
|
||||
import { useToolMode } from "../../../../../store/builder/store";
|
||||
import { TransformControls } from "@react-three/drei";
|
||||
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
|
||||
import { useSelectedEventSphere, useSelectedEventData, } from "../../../../../store/simulation/useSimulationStore";
|
||||
import { useSelectedEventSphere, useSelectedEventData, useDeletableEventSphere } from "../../../../../store/simulation/useSimulationStore";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { usePlayButtonStore } from "../../../../../store/usePlayButtonStore";
|
||||
import { upsertProductOrEventApi } from "../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useToolMode } from "../../../../../store/builder/store";
|
||||
import { useVersionContext } from "../../../../builder/version/versionContext";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
import PointInstances from "../instances/pointInstances";
|
||||
|
||||
function PointsCreator() {
|
||||
const { gl, raycaster, scene, pointer, camera } = useThree();
|
||||
const { subModule } = useSubModuleStore();
|
||||
const { toolMode } = useToolMode();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { eventStore, productStore } = useSceneContext();
|
||||
const { events, getEventByModelUuid } = eventStore();
|
||||
const { getEventByModelUuid: getEventByModelUuidFromProduct, updatePoint: updatePointFromProduct, getEventByModelUuid: getEventByModelUuidFromProduct2, getPointByUuid: getPointByUuidFromProduct, getTriggersByTriggeredPointUuid, removeTrigger, removePoint } = productStore();
|
||||
const { getEventByModelUuid } = eventStore();
|
||||
const { getEventByModelUuid: getEventByModelUuidFromProduct, updatePoint: updatePointFromProduct, getPointByUuid: getPointByUuidFromProduct, getTriggersByTriggeredPointUuid, removeTrigger, removePoint } = productStore();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { activeModule } = useModuleStore();
|
||||
const transformRef = useRef<any>(null);
|
||||
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
|
||||
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
|
||||
const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere, } = useSelectedEventSphere();
|
||||
const { selectedEventSphere, clearSelectedEventSphere, } = useSelectedEventSphere();
|
||||
const { clearDeletableEventSphere } = useDeletableEventSphere();
|
||||
const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { toolMode } = useToolMode();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
clearSelectedEventSphere();
|
||||
clearSelectedEventData();
|
||||
clearDeletableEventSphere();
|
||||
}, [toolMode, activeModule])
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
@@ -208,205 +216,7 @@ function PointsCreator() {
|
||||
{activeModule === "simulation" && (
|
||||
<>
|
||||
<group name="EventPointsGroup" visible={!isPlaying}>
|
||||
{events.map((event, index) => {
|
||||
const updatedEvent = selectedProduct.productUuid !== ''
|
||||
? getEventByModelUuidFromProduct2(selectedProduct.productUuid, event.modelUuid)
|
||||
: null;
|
||||
|
||||
const usedEvent = updatedEvent || event;
|
||||
|
||||
if (usedEvent.type === "transfer") {
|
||||
return (
|
||||
<group
|
||||
key={`${index}-${usedEvent.modelUuid}`}
|
||||
position={usedEvent.position}
|
||||
rotation={usedEvent.rotation}
|
||||
>
|
||||
{usedEvent.points.map((point, j) => (
|
||||
<mesh
|
||||
name="Event-Sphere"
|
||||
uuid={point.uuid}
|
||||
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (toolMode === 'cursor') {
|
||||
setSelectedEventSphere(
|
||||
sphereRefs.current[point.uuid]
|
||||
);
|
||||
}
|
||||
}}
|
||||
key={`${index}-${point.uuid}`}
|
||||
position={new THREE.Vector3(...point.position)}
|
||||
userData={{
|
||||
modelUuid: usedEvent.modelUuid,
|
||||
pointUuid: point.uuid,
|
||||
}}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color="orange" />
|
||||
</mesh>
|
||||
))}
|
||||
</group>
|
||||
);
|
||||
} else if (usedEvent.type === "vehicle") {
|
||||
const point = usedEvent.point;
|
||||
return (
|
||||
<group
|
||||
key={`${index}-${usedEvent.modelUuid}`}
|
||||
position={usedEvent.position}
|
||||
rotation={usedEvent.rotation}
|
||||
>
|
||||
<mesh
|
||||
name="Event-Sphere"
|
||||
uuid={point.uuid}
|
||||
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (toolMode === 'cursor') {
|
||||
setSelectedEventSphere(
|
||||
sphereRefs.current[point.uuid]
|
||||
);
|
||||
}
|
||||
}}
|
||||
position={new THREE.Vector3(...point.position)}
|
||||
userData={{
|
||||
modelUuid: usedEvent.modelUuid,
|
||||
pointUuid: point.uuid,
|
||||
}}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color="blue" />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
} else if (usedEvent.type === "roboticArm") {
|
||||
const point = usedEvent.point;
|
||||
return (
|
||||
<group
|
||||
key={`${index}-${usedEvent.modelUuid}`}
|
||||
position={usedEvent.position}
|
||||
rotation={usedEvent.rotation}
|
||||
>
|
||||
<mesh
|
||||
name="Event-Sphere"
|
||||
uuid={point.uuid}
|
||||
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (toolMode === 'cursor') {
|
||||
setSelectedEventSphere(
|
||||
sphereRefs.current[point.uuid]
|
||||
);
|
||||
}
|
||||
}}
|
||||
position={new THREE.Vector3(...point.position)}
|
||||
userData={{
|
||||
modelUuid: usedEvent.modelUuid,
|
||||
pointUuid: point.uuid,
|
||||
}}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color="green" />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
} else if (usedEvent.type === "machine") {
|
||||
const point = usedEvent.point;
|
||||
return (
|
||||
<group
|
||||
key={`${index}-${usedEvent.modelUuid}`}
|
||||
position={usedEvent.position}
|
||||
rotation={usedEvent.rotation}
|
||||
>
|
||||
<mesh
|
||||
name="Event-Sphere"
|
||||
uuid={point.uuid}
|
||||
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (toolMode === 'cursor') {
|
||||
setSelectedEventSphere(
|
||||
sphereRefs.current[point.uuid]
|
||||
);
|
||||
}
|
||||
}}
|
||||
position={new THREE.Vector3(...point.position)}
|
||||
userData={{
|
||||
modelUuid: usedEvent.modelUuid,
|
||||
pointUuid: point.uuid,
|
||||
}}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color="purple" />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
} else if (usedEvent.type === "storageUnit") {
|
||||
const point = usedEvent.point;
|
||||
return (
|
||||
<group
|
||||
key={`${index}-${usedEvent.modelUuid}`}
|
||||
position={usedEvent.position}
|
||||
rotation={usedEvent.rotation}
|
||||
>
|
||||
<mesh
|
||||
name="Event-Sphere"
|
||||
uuid={point.uuid}
|
||||
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (toolMode === 'cursor') {
|
||||
setSelectedEventSphere(
|
||||
sphereRefs.current[point.uuid]
|
||||
);
|
||||
}
|
||||
}}
|
||||
position={new THREE.Vector3(...point.position)}
|
||||
userData={{
|
||||
modelUuid: usedEvent.modelUuid,
|
||||
pointUuid: point.uuid,
|
||||
}}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color="red" />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
} else if (usedEvent.type === "human") {
|
||||
const point = usedEvent.point;
|
||||
return (
|
||||
<group
|
||||
key={`${index}-${usedEvent.modelUuid}`}
|
||||
position={usedEvent.position}
|
||||
rotation={usedEvent.rotation}
|
||||
>
|
||||
<mesh
|
||||
name="Event-Sphere"
|
||||
uuid={point.uuid}
|
||||
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (toolMode === 'cursor') {
|
||||
setSelectedEventSphere(
|
||||
sphereRefs.current[point.uuid]
|
||||
);
|
||||
}
|
||||
}}
|
||||
position={new THREE.Vector3(...point.position)}
|
||||
userData={{
|
||||
modelUuid: usedEvent.modelUuid,
|
||||
pointUuid: point.uuid,
|
||||
}}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color="white" />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
<PointInstances />
|
||||
</group>
|
||||
|
||||
{selectedEventSphere && transformMode && (
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
import * as THREE from "three";
|
||||
import { MeshProps } from "@react-three/fiber";
|
||||
import { useRef } from "react";
|
||||
import { useToolMode } from "../../../../../../store/builder/store";
|
||||
import { useDeletableEventSphere, useSelectedEventSphere } from "../../../../../../store/simulation/useSimulationStore";
|
||||
import { useSceneContext } from "../../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../../products/productContext";
|
||||
import { useVersionContext } from "../../../../../builder/version/versionContext";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { upsertProductOrEventApi } from "../../../../../../services/simulation/products/UpsertProductOrEventApi";
|
||||
|
||||
interface PointInstanceProps extends Omit<MeshProps, 'ref'> {
|
||||
point: {
|
||||
uuid: string;
|
||||
position: [number, number, number];
|
||||
};
|
||||
modelUuid: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export default function PointInstance({
|
||||
point,
|
||||
modelUuid,
|
||||
color,
|
||||
...meshProps
|
||||
}: PointInstanceProps) {
|
||||
const ref = useRef<THREE.Mesh>(null);
|
||||
const { setSelectedEventSphere } = useSelectedEventSphere();
|
||||
const { deletableEventSphere, setDeletableEventSphere, clearDeletableEventSphere } = useDeletableEventSphere();
|
||||
const { toolMode } = useToolMode();
|
||||
const { productStore } = useSceneContext();
|
||||
const { getEventByModelUuid, getTriggersByTriggeredPointUuid, removeTrigger, removePoint } = productStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { projectId } = useParams();
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
productUuid: string,
|
||||
projectId: string,
|
||||
eventData: EventsSchema
|
||||
) => {
|
||||
upsertProductOrEventApi({
|
||||
productName: productName,
|
||||
productUuid: productUuid,
|
||||
projectId: projectId,
|
||||
eventDatas: eventData,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
})
|
||||
}
|
||||
|
||||
const handleEventPointDelete = () => {
|
||||
const eventModel = getEventByModelUuid(selectedProduct.productUuid, modelUuid);
|
||||
if (!eventModel || eventModel.type !== 'transfer' || eventModel.points.length < 2) return;
|
||||
|
||||
const triggers = getTriggersByTriggeredPointUuid(selectedProduct.productUuid, point.uuid);
|
||||
|
||||
const updatedEvents: EventsSchema[] = [];
|
||||
if (triggers.length > 0) {
|
||||
triggers.map((trigger) => {
|
||||
const event = removeTrigger(selectedProduct.productUuid, trigger.triggerUuid);
|
||||
if (event) {
|
||||
updatedEvents.push(event);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const event = removePoint(selectedProduct.productUuid, modelUuid, point.uuid)
|
||||
|
||||
if (event) {
|
||||
updatedEvents.push(event);
|
||||
}
|
||||
|
||||
if (updatedEvents.length > 0) {
|
||||
updatedEvents.map((updatedEvent) => {
|
||||
updateBackend(
|
||||
selectedProduct.productName,
|
||||
selectedProduct.productUuid,
|
||||
projectId || '',
|
||||
updatedEvent
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<mesh
|
||||
{...meshProps}
|
||||
ref={ref}
|
||||
name="Event-Sphere"
|
||||
uuid={point.uuid}
|
||||
position={new THREE.Vector3(...point.position)}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (toolMode === 'cursor') {
|
||||
setSelectedEventSphere(ref.current);
|
||||
} else if (toolMode === '3D-Delete') {
|
||||
handleEventPointDelete()
|
||||
}
|
||||
}}
|
||||
onPointerOver={(e) => {
|
||||
e.stopPropagation();
|
||||
if (toolMode === '3D-Delete' && (!deletableEventSphere || deletableEventSphere.uuid !== point.uuid)) {
|
||||
setDeletableEventSphere(ref.current);
|
||||
}
|
||||
}}
|
||||
onPointerOut={(e) => {
|
||||
e.stopPropagation();
|
||||
if (toolMode === '3D-Delete' && deletableEventSphere && deletableEventSphere.uuid === point.uuid) {
|
||||
clearDeletableEventSphere();
|
||||
}
|
||||
}}
|
||||
userData={{ modelUuid, pointUuid: point.uuid }}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color={color} />
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
|
||||
import PointInstance from "./instance/pointInstance";
|
||||
|
||||
function PointInstances() {
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
|
||||
const { eventStore, productStore } = useSceneContext();
|
||||
const { events } = eventStore();
|
||||
const { getEventByModelUuid } = productStore();
|
||||
|
||||
const colorByType: Record<string, string> = {
|
||||
transfer: "orange",
|
||||
vehicle: "blue",
|
||||
roboticArm: "green",
|
||||
machine: "purple",
|
||||
storageUnit: "red",
|
||||
human: "white",
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{events.map((event, index) => {
|
||||
const updatedEvent = selectedProduct.productUuid !== '' ? getEventByModelUuid(selectedProduct.productUuid, event.modelUuid) : null;
|
||||
|
||||
const usedEvent = updatedEvent || event;
|
||||
const color = colorByType[usedEvent.type];
|
||||
|
||||
if (!color) return null;
|
||||
|
||||
const points = usedEvent.type === "transfer" ? usedEvent.points : [usedEvent.point];
|
||||
|
||||
return (
|
||||
<group
|
||||
key={`${index}-${usedEvent.modelUuid}`}
|
||||
position={usedEvent.position}
|
||||
rotation={usedEvent.rotation}
|
||||
>
|
||||
{points.map((point) => (
|
||||
<PointInstance
|
||||
key={point.uuid}
|
||||
point={point}
|
||||
modelUuid={usedEvent.modelUuid}
|
||||
color={color}
|
||||
/>
|
||||
))}
|
||||
</group>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default PointInstances;
|
||||
@@ -24,6 +24,28 @@ export const useSelectedEventSphere = create<SelectedEventSphereState>()(
|
||||
}))
|
||||
);
|
||||
|
||||
interface DeletableEventSphereState {
|
||||
deletableEventSphere: THREE.Mesh | null;
|
||||
setDeletableEventSphere: (mesh: THREE.Mesh | null) => void;
|
||||
clearDeletableEventSphere: () => void;
|
||||
}
|
||||
|
||||
export const useDeletableEventSphere = create<DeletableEventSphereState>()(
|
||||
immer((set) => ({
|
||||
deletableEventSphere: null,
|
||||
setDeletableEventSphere: (mesh) => {
|
||||
set((state) => {
|
||||
state.deletableEventSphere = mesh;
|
||||
});
|
||||
},
|
||||
clearDeletableEventSphere: () => {
|
||||
set((state) => {
|
||||
state.deletableEventSphere = null;
|
||||
});
|
||||
},
|
||||
}))
|
||||
);
|
||||
|
||||
interface SelectedEventDataState {
|
||||
selectedEventData: { data: EventsSchema; selectedPoint: string } | undefined;
|
||||
setSelectedEventData: (data: EventsSchema, selectedPoint: string) => void;
|
||||
|
||||
Reference in New Issue
Block a user