mirror of
https://github.com/stan-smith/FossFLOW.git
synced 2025-12-24 06:58:48 -05:00
refactor: propagates all naming of groups to rectangles
This commit is contained in:
10
README.md
10
README.md
@@ -16,19 +16,19 @@ MIT licence | Source available on [Github](https://github.com/markmanx/isoflow)
|
||||
- **Real-time:** Display real-time data on diagrams.
|
||||
- **Customizable:** Use your own isometric icon packs, or use our free set of networking icons (also under MIT).
|
||||
- **Export options:** Export diagrams as images, JSON or YAML.
|
||||
- **Powerful annotation tools:** Annotate nodes, groups and connectors.
|
||||
- **Powerful annotation tools:** Annotate nodes, rectangles and connectors.
|
||||
- **Step-by-step walkthroughs:** Create interactive tours of large diagrams to help viewers easily digest information.
|
||||
|
||||
## Roadmap
|
||||
|
||||
Migration to open-source: ██░░░░░░░░░
|
||||
Version 1: ██████████░░
|
||||
|
||||
- [x] Set up automated publishing to NPM registry
|
||||
- [ ] Migrate private JS project to public Typescript project
|
||||
- [x] Pan / Select / Zoom modes
|
||||
- [x] Display icons in itemControls
|
||||
- [ ] Node controls
|
||||
- [ ] Group controls
|
||||
- [x] Node controls
|
||||
- [ ] Rectangle controls
|
||||
- [ ] Connector controls
|
||||
- [ ] Publish icons as separate importable package
|
||||
|
||||
@@ -62,7 +62,7 @@ const scene = {
|
||||
},
|
||||
],
|
||||
connectors: [],
|
||||
groups: []
|
||||
rectangles: []
|
||||
}
|
||||
|
||||
const App = () => (
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
IconInput,
|
||||
NodeInput,
|
||||
ConnectorInput,
|
||||
GroupInput,
|
||||
RectangleInput,
|
||||
Scene
|
||||
} from 'src/types';
|
||||
import { sceneToSceneInput } from 'src/utils';
|
||||
@@ -47,8 +47,8 @@ const App = ({
|
||||
const prevInitialScene = useRef<SceneInput>(EMPTY_SCENE);
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
useWindowUtils();
|
||||
const scene = useSceneStore(({ nodes, connectors, groups, icons }) => {
|
||||
return { nodes, connectors, groups, icons };
|
||||
const scene = useSceneStore(({ nodes, connectors, rectangles, icons }) => {
|
||||
return { nodes, connectors, rectangles, icons };
|
||||
}, shallow);
|
||||
const sceneActions = useSceneStore((state) => {
|
||||
return state.actions;
|
||||
@@ -144,7 +144,7 @@ export {
|
||||
SceneInput,
|
||||
IconInput,
|
||||
NodeInput,
|
||||
GroupInput,
|
||||
RectangleInput,
|
||||
ConnectorInput,
|
||||
useIsoflow,
|
||||
LabelContainer,
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from 'react';
|
||||
import { useSceneStore } from 'src/stores/sceneStore';
|
||||
import { useUiStateStore } from 'src/stores/uiStateStore';
|
||||
import { DEFAULT_COLOR } from 'src/config';
|
||||
import { Group } from './Group/Group';
|
||||
|
||||
export const Groups = () => {
|
||||
const groups = useSceneStore((state) => {
|
||||
return state.groups;
|
||||
});
|
||||
const mode = useUiStateStore((state) => {
|
||||
return state.mode;
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{groups.map((group) => {
|
||||
return <Group key={group.id} {...group} />;
|
||||
})}
|
||||
{mode.type === 'RECTANGLE.DRAW' && mode.area && (
|
||||
<Group from={mode.area.from} to={mode.area.to} color={DEFAULT_COLOR} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
// import { useRef, useCallback } from 'react';
|
||||
// import { Group, Shape } from 'paper';
|
||||
// import { Rectangle, Shape } from 'paper';
|
||||
// import gsap from 'gsap';
|
||||
// import { Coords } from 'src/types';
|
||||
// import { UNPROJECTED_TILE_SIZE, PIXEL_UNIT } from 'src/renderer/utils/constants';
|
||||
@@ -11,7 +11,7 @@
|
||||
// import { applyProjectionMatrix } from 'src/renderer/utils/projection';
|
||||
|
||||
// export const useLasso = () => {
|
||||
// const containerRef = useRef(new Group());
|
||||
// const containerRef = useRef(new Rectangle());
|
||||
// const shapeRef = useRef<paper.Shape.Rectangle>();
|
||||
|
||||
// const setSelection = useCallback((startTile: Coords, endTile: Coords) => {
|
||||
|
||||
@@ -10,7 +10,7 @@ interface Props {
|
||||
color: string;
|
||||
}
|
||||
|
||||
export const Group = ({ from, to, color }: Props) => {
|
||||
export const Rectangle = ({ from, to, color }: Props) => {
|
||||
const zoom = useUiStateStore((state) => {
|
||||
return state.zoom;
|
||||
});
|
||||
29
src/components/Rectangles/Rectangles.tsx
Normal file
29
src/components/Rectangles/Rectangles.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import { useSceneStore } from 'src/stores/sceneStore';
|
||||
import { useUiStateStore } from 'src/stores/uiStateStore';
|
||||
import { DEFAULT_COLOR } from 'src/config';
|
||||
import { Rectangle } from './Rectangle/Rectangle';
|
||||
|
||||
export const Rectangles = () => {
|
||||
const rectangles = useSceneStore((state) => {
|
||||
return state.rectangles;
|
||||
});
|
||||
const mode = useUiStateStore((state) => {
|
||||
return state.mode;
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{rectangles.map((rectangle) => {
|
||||
return <Rectangle key={rectangle.id} {...rectangle} />;
|
||||
})}
|
||||
{mode.type === 'RECTANGLE.DRAW' && mode.area && (
|
||||
<Rectangle
|
||||
from={mode.area.from}
|
||||
to={mode.area.to}
|
||||
color={DEFAULT_COLOR}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -5,7 +5,7 @@ import { useInteractionManager } from 'src/interaction/useInteractionManager';
|
||||
import { Grid } from 'src/components/Grid/Grid';
|
||||
import { Cursor } from 'src/components/Cursor/Cursor';
|
||||
import { Nodes } from 'src/components/Nodes/Nodes';
|
||||
import { Groups } from 'src/components/Groups/Groups';
|
||||
import { Rectangles } from 'src/components/Rectangles/Rectangles';
|
||||
import { Connectors } from 'src/components/Connectors/Connectors';
|
||||
import { DebugUtils } from 'src/components/DebugUtils/DebugUtils';
|
||||
import { useResizeObserver } from 'src/hooks/useResizeObserver';
|
||||
@@ -59,7 +59,7 @@ export const Renderer = () => {
|
||||
</SceneLayer>
|
||||
)}
|
||||
<SceneLayer>
|
||||
<Groups />
|
||||
<Rectangles />
|
||||
</SceneLayer>
|
||||
<SceneLayer>
|
||||
<Connectors />
|
||||
|
||||
@@ -31,5 +31,5 @@ export const EMPTY_SCENE: SceneInput = {
|
||||
icons: [],
|
||||
nodes: [],
|
||||
connectors: [],
|
||||
groups: []
|
||||
rectangles: []
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ export const BasicEditor = () => {
|
||||
icons,
|
||||
nodes: [],
|
||||
connectors: [],
|
||||
groups: []
|
||||
rectangles: []
|
||||
}}
|
||||
height="100%"
|
||||
/>
|
||||
|
||||
@@ -27,7 +27,7 @@ export const Callbacks = () => {
|
||||
}
|
||||
],
|
||||
connectors: [],
|
||||
groups: []
|
||||
rectangles: []
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ export const DebugTools = () => {
|
||||
initialScene={{
|
||||
icons,
|
||||
connectors: [],
|
||||
groups: [
|
||||
rectangles: [
|
||||
{
|
||||
id: 'group1',
|
||||
id: 'rectangle1',
|
||||
from: {
|
||||
x: 5,
|
||||
y: 5
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useSceneStore } from 'src/stores/sceneStore';
|
||||
import { useUiStateStore } from 'src/stores/uiStateStore';
|
||||
import { Size, Coords, Node, Group, Connector } from 'src/types';
|
||||
import { Size, Coords, Node, Rectangle, Connector } from 'src/types';
|
||||
import {
|
||||
getBoundingBox,
|
||||
getBoundingBoxSize,
|
||||
@@ -16,10 +16,10 @@ import { MAX_ZOOM } from 'src/config';
|
||||
const BOUNDING_BOX_PADDING = 3;
|
||||
|
||||
export const useDiagramUtils = () => {
|
||||
const scene = useSceneStore(({ nodes, groups, connectors, icons }) => {
|
||||
const scene = useSceneStore(({ nodes, rectangles, connectors, icons }) => {
|
||||
return {
|
||||
nodes,
|
||||
groups,
|
||||
rectangles,
|
||||
connectors,
|
||||
icons
|
||||
};
|
||||
@@ -34,7 +34,7 @@ export const useDiagramUtils = () => {
|
||||
const { getTilePosition } = useGetTilePosition();
|
||||
|
||||
const getProjectBounds = useCallback(
|
||||
(items: (Node | Group | Connector)[]): Coords[] => {
|
||||
(items: (Node | Rectangle | Connector)[]): Coords[] => {
|
||||
const positions = items.reduce<Coords[]>((acc, item) => {
|
||||
switch (item.type) {
|
||||
case 'NODE':
|
||||
@@ -46,7 +46,7 @@ export const useDiagramUtils = () => {
|
||||
return getAnchorPosition({ anchor, nodes: scene.nodes });
|
||||
})
|
||||
];
|
||||
case 'GROUP':
|
||||
case 'RECTANGLE':
|
||||
return [...acc, item.from, item.to];
|
||||
default:
|
||||
return acc;
|
||||
@@ -67,7 +67,7 @@ export const useDiagramUtils = () => {
|
||||
const projectBounds = getProjectBounds([
|
||||
...scene.nodes,
|
||||
...scene.connectors,
|
||||
...scene.groups
|
||||
...scene.rectangles
|
||||
]);
|
||||
|
||||
const cornerPositions = projectBounds.map((corner) => {
|
||||
|
||||
@@ -3,10 +3,10 @@ import { useSceneStore } from 'src/stores/sceneStore';
|
||||
import { useDiagramUtils } from 'src/hooks/useDiagramUtils';
|
||||
|
||||
export const useWindowUtils = () => {
|
||||
const scene = useSceneStore(({ nodes, groups, connectors, icons }) => {
|
||||
const scene = useSceneStore(({ nodes, rectangles, connectors, icons }) => {
|
||||
return {
|
||||
nodes,
|
||||
groups,
|
||||
rectangles,
|
||||
connectors,
|
||||
icons
|
||||
};
|
||||
|
||||
@@ -43,20 +43,19 @@ export const Cursor: ModeActions = {
|
||||
mouseup: ({ uiState, scene, isRendererInteraction }) => {
|
||||
if (uiState.mode.type !== 'CURSOR' || !isRendererInteraction) return;
|
||||
|
||||
if (
|
||||
uiState.mode.mousedownItem &&
|
||||
uiState.mode.mousedownItem.type === 'NODE'
|
||||
) {
|
||||
const { item: node } = getItemById(
|
||||
scene.nodes,
|
||||
uiState.mode.mousedownItem.id
|
||||
);
|
||||
if (uiState.mode.mousedownItem) {
|
||||
if (uiState.mode.mousedownItem.type === 'NODE') {
|
||||
const { item: node } = getItemById(
|
||||
scene.nodes,
|
||||
uiState.mode.mousedownItem.id
|
||||
);
|
||||
|
||||
uiState.actions.setContextMenu(node);
|
||||
uiState.actions.setItemControls({
|
||||
type: ItemControlsTypeEnum.SINGLE_NODE,
|
||||
nodeId: node.id
|
||||
});
|
||||
uiState.actions.setContextMenu(node);
|
||||
uiState.actions.setItemControls({
|
||||
type: ItemControlsTypeEnum.SINGLE_NODE,
|
||||
nodeId: node.id
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Empty tile selected
|
||||
uiState.actions.setContextMenu({
|
||||
|
||||
@@ -34,11 +34,14 @@ export const DragItems: ModeActions = {
|
||||
scene.actions.updateNode(item.id, {
|
||||
position: uiState.mouse.position.tile
|
||||
});
|
||||
} else if (item.type === 'GROUP' && uiState.mouse.delta?.tile) {
|
||||
const { item: group } = getItemById(scene.groups, item.id);
|
||||
const newFrom = CoordsUtils.add(group.from, uiState.mouse.delta.tile);
|
||||
const newTo = CoordsUtils.add(group.to, uiState.mouse.delta.tile);
|
||||
// const bounds = getBoundingBox([group.from, group.to]);
|
||||
} else if (item.type === 'RECTANGLE' && uiState.mouse.delta?.tile) {
|
||||
const { item: rectangle } = getItemById(scene.rectangles, item.id);
|
||||
const newFrom = CoordsUtils.add(
|
||||
rectangle.from,
|
||||
uiState.mouse.delta.tile
|
||||
);
|
||||
const newTo = CoordsUtils.add(rectangle.to, uiState.mouse.delta.tile);
|
||||
// const bounds = getBoundingBox([rectangle.from, rectangle.to]);
|
||||
|
||||
// scene.nodes.forEach((node) => {
|
||||
// if (isWithinBounds(node.position, bounds)) {
|
||||
@@ -48,7 +51,7 @@ export const DragItems: ModeActions = {
|
||||
// }
|
||||
// });
|
||||
|
||||
scene.actions.updateGroup(item.id, { from: newFrom, to: newTo });
|
||||
scene.actions.updateRectangle(item.id, { from: newFrom, to: newTo });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ export const DrawRectangle: ModeActions = {
|
||||
)
|
||||
return;
|
||||
|
||||
scene.actions.createGroup({
|
||||
scene.actions.createRectangle({
|
||||
id: generateId(),
|
||||
color: DEFAULT_COLOR,
|
||||
from: uiState.mode.area.from,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { sceneInput } from 'src/validation/scene';
|
||||
import {
|
||||
getItemById,
|
||||
getConnectorPath,
|
||||
groupInputToGroup,
|
||||
rectangleInputToRectangle,
|
||||
connectorInputToConnector,
|
||||
sceneInputtoScene,
|
||||
nodeInputToNode
|
||||
@@ -17,7 +17,7 @@ const initialState = () => {
|
||||
return {
|
||||
nodes: [],
|
||||
connectors: [],
|
||||
groups: [],
|
||||
rectangles: [],
|
||||
icons: [],
|
||||
actions: {
|
||||
setScene: (scene) => {
|
||||
@@ -32,7 +32,7 @@ const initialState = () => {
|
||||
set({
|
||||
nodes: scene.nodes,
|
||||
connectors: scene.connectors,
|
||||
groups: scene.groups
|
||||
rectangles: scene.rectangles
|
||||
});
|
||||
},
|
||||
|
||||
@@ -86,17 +86,20 @@ const initialState = () => {
|
||||
set({ connectors: newScene.connectors });
|
||||
},
|
||||
|
||||
updateGroup: (id, updates) => {
|
||||
updateRectangle: (id, updates) => {
|
||||
const newScene = produce(get(), (draftState) => {
|
||||
const { item: group, index } = getItemById(draftState.groups, id);
|
||||
const { item: rectangle, index } = getItemById(
|
||||
draftState.rectangles,
|
||||
id
|
||||
);
|
||||
|
||||
draftState.groups[index] = {
|
||||
...group,
|
||||
draftState.rectangles[index] = {
|
||||
...rectangle,
|
||||
...updates
|
||||
};
|
||||
});
|
||||
|
||||
set({ groups: newScene.groups });
|
||||
set({ rectangles: newScene.rectangles });
|
||||
},
|
||||
|
||||
createConnector: (connector) => {
|
||||
@@ -109,12 +112,12 @@ const initialState = () => {
|
||||
set({ connectors: newScene.connectors });
|
||||
},
|
||||
|
||||
createGroup: (group) => {
|
||||
createRectangle: (rectangle) => {
|
||||
const newScene = produce(get(), (draftState) => {
|
||||
draftState.groups.push(groupInputToGroup(group));
|
||||
draftState.rectangles.push(rectangleInputToRectangle(rectangle));
|
||||
});
|
||||
|
||||
set({ groups: newScene.groups });
|
||||
set({ rectangles: newScene.rectangles });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
2
src/tests/fixtures/scene.ts
vendored
2
src/tests/fixtures/scene.ts
vendored
@@ -52,5 +52,5 @@ export const scene: SceneInput = {
|
||||
anchors: [{ nodeId: 'node2' }, { nodeId: 'node3' }]
|
||||
}
|
||||
],
|
||||
groups: [{ id: 'group1', from: { x: 0, y: 0 }, to: { x: 2, y: 2 } }]
|
||||
rectangles: [{ id: 'rectangle1', from: { x: 0, y: 0 }, to: { x: 2, y: 2 } }]
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
nodeInput,
|
||||
connectorAnchorInput,
|
||||
connectorInput,
|
||||
groupInput
|
||||
rectangleInput
|
||||
} from 'src/validation/sceneItems';
|
||||
import { sceneInput } from 'src/validation/scene';
|
||||
|
||||
@@ -12,5 +12,5 @@ export type IconInput = z.infer<typeof iconInput>;
|
||||
export type NodeInput = z.infer<typeof nodeInput>;
|
||||
export type ConnectorAnchorInput = z.infer<typeof connectorAnchorInput>;
|
||||
export type ConnectorInput = z.infer<typeof connectorInput>;
|
||||
export type GroupInput = z.infer<typeof groupInput>;
|
||||
export type RectangleInput = z.infer<typeof rectangleInput>;
|
||||
export type SceneInput = z.infer<typeof sceneInput>;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Coords, Size } from './common';
|
||||
import {
|
||||
IconInput,
|
||||
SceneInput,
|
||||
GroupInput,
|
||||
RectangleInput,
|
||||
ConnectorInput,
|
||||
NodeInput
|
||||
} from './inputs';
|
||||
@@ -18,7 +18,7 @@ export enum TileOriginEnum {
|
||||
export enum SceneItemTypeEnum {
|
||||
NODE = 'NODE',
|
||||
CONNECTOR = 'CONNECTOR',
|
||||
GROUP = 'GROUP'
|
||||
RECTANGLE = 'RECTANGLE'
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
@@ -54,15 +54,15 @@ export interface Connector {
|
||||
};
|
||||
}
|
||||
|
||||
export interface Group {
|
||||
type: SceneItemTypeEnum.GROUP;
|
||||
export interface Rectangle {
|
||||
type: SceneItemTypeEnum.RECTANGLE;
|
||||
id: string;
|
||||
color: string;
|
||||
from: Coords;
|
||||
to: Coords;
|
||||
}
|
||||
|
||||
export type SceneItem = Node | Connector | Group;
|
||||
export type SceneItem = Node | Connector | Rectangle;
|
||||
export type SceneItemReference = {
|
||||
type: SceneItemTypeEnum;
|
||||
id: string;
|
||||
@@ -75,16 +75,16 @@ export interface SceneActions {
|
||||
updateScene: (scene: Scene) => void;
|
||||
updateNode: (id: string, updates: Partial<Node>) => void;
|
||||
updateConnector: (id: string, updates: Partial<Connector>) => void;
|
||||
updateGroup: (id: string, updates: Partial<Group>) => void;
|
||||
updateRectangle: (id: string, updates: Partial<Rectangle>) => void;
|
||||
createNode: (node: NodeInput) => void;
|
||||
createConnector: (connector: ConnectorInput) => void;
|
||||
createGroup: (group: GroupInput) => void;
|
||||
createRectangle: (rectangle: RectangleInput) => void;
|
||||
}
|
||||
|
||||
export type Scene = {
|
||||
nodes: Node[];
|
||||
connectors: Connector[];
|
||||
groups: Group[];
|
||||
rectangles: Rectangle[];
|
||||
icons: IconInput[];
|
||||
};
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@ import {
|
||||
SceneInput,
|
||||
NodeInput,
|
||||
ConnectorInput,
|
||||
GroupInput,
|
||||
RectangleInput,
|
||||
SceneItemTypeEnum,
|
||||
Scene,
|
||||
Node,
|
||||
Connector,
|
||||
Group,
|
||||
Rectangle,
|
||||
ConnectorAnchorInput,
|
||||
ConnectorAnchor,
|
||||
Coords
|
||||
@@ -28,13 +28,15 @@ export const nodeInputToNode = (nodeInput: NodeInput): Node => {
|
||||
};
|
||||
};
|
||||
|
||||
export const groupInputToGroup = (groupInput: GroupInput): Group => {
|
||||
export const rectangleInputToRectangle = (
|
||||
rectangleInput: RectangleInput
|
||||
): Rectangle => {
|
||||
return {
|
||||
type: SceneItemTypeEnum.GROUP,
|
||||
id: groupInput.id,
|
||||
from: groupInput.from,
|
||||
to: groupInput.to,
|
||||
color: groupInput.color ?? DEFAULT_COLOR
|
||||
type: SceneItemTypeEnum.RECTANGLE,
|
||||
id: rectangleInput.id,
|
||||
from: rectangleInput.from,
|
||||
to: rectangleInput.to,
|
||||
color: rectangleInput.color ?? DEFAULT_COLOR
|
||||
};
|
||||
};
|
||||
|
||||
@@ -80,8 +82,8 @@ export const sceneInputtoScene = (sceneInput: SceneInput): Scene => {
|
||||
return nodeInputToNode(nodeInput);
|
||||
});
|
||||
|
||||
const groups = sceneInput.groups.map((groupInput) => {
|
||||
return groupInputToGroup(groupInput);
|
||||
const rectangles = sceneInput.rectangles.map((rectangleInput) => {
|
||||
return rectangleInputToRectangle(rectangleInput);
|
||||
});
|
||||
|
||||
const connectors = sceneInput.connectors.map((connectorInput) => {
|
||||
@@ -91,7 +93,7 @@ export const sceneInputtoScene = (sceneInput: SceneInput): Scene => {
|
||||
return {
|
||||
...sceneInput,
|
||||
nodes,
|
||||
groups,
|
||||
rectangles,
|
||||
connectors,
|
||||
icons: sceneInput.icons
|
||||
} as Scene;
|
||||
@@ -143,12 +145,14 @@ export const connectorToConnectorInput = (
|
||||
};
|
||||
};
|
||||
|
||||
export const groupToGroupInput = (group: Group): GroupInput => {
|
||||
export const rectangleToRectangleInput = (
|
||||
rectangle: Rectangle
|
||||
): RectangleInput => {
|
||||
return {
|
||||
id: group.id,
|
||||
color: group.color,
|
||||
from: group.from,
|
||||
to: group.to
|
||||
id: rectangle.id,
|
||||
color: rectangle.color,
|
||||
from: rectangle.from,
|
||||
to: rectangle.to
|
||||
};
|
||||
};
|
||||
|
||||
@@ -158,12 +162,14 @@ export const sceneToSceneInput = (scene: Scene): SceneInput => {
|
||||
connectorToConnectorInput,
|
||||
nodes
|
||||
);
|
||||
const groups: GroupInput[] = scene.groups.map(groupToGroupInput);
|
||||
const rectangles: RectangleInput[] = scene.rectangles.map(
|
||||
rectangleToRectangleInput
|
||||
);
|
||||
|
||||
return {
|
||||
nodes,
|
||||
connectors,
|
||||
groups,
|
||||
rectangles,
|
||||
icons: scene.icons
|
||||
} as SceneInput;
|
||||
};
|
||||
|
||||
@@ -220,11 +220,11 @@ export const getItemAtTile = ({
|
||||
|
||||
if (node) return node;
|
||||
|
||||
const group = scene.groups.find(({ from, to }) => {
|
||||
const rectangle = scene.rectangles.find(({ from, to }) => {
|
||||
return isWithinBounds(tile, [from, to]);
|
||||
});
|
||||
|
||||
if (group) return group;
|
||||
if (rectangle) return rectangle;
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// TODO: Split into individual files
|
||||
import { z } from 'zod';
|
||||
import { iconInput, nodeInput, connectorInput, groupInput } from './sceneItems';
|
||||
import {
|
||||
iconInput,
|
||||
nodeInput,
|
||||
connectorInput,
|
||||
rectangleInput
|
||||
} from './sceneItems';
|
||||
import { findInvalidConnector, findInvalidNode } from './utils';
|
||||
|
||||
export const sceneInput = z
|
||||
@@ -8,7 +13,7 @@ export const sceneInput = z
|
||||
icons: z.array(iconInput),
|
||||
nodes: z.array(nodeInput),
|
||||
connectors: z.array(connectorInput),
|
||||
groups: z.array(groupInput)
|
||||
rectangles: z.array(rectangleInput)
|
||||
})
|
||||
.superRefine((scene, ctx) => {
|
||||
const invalidNode = findInvalidNode(scene.nodes, scene.icons);
|
||||
|
||||
@@ -43,7 +43,7 @@ export const connectorInput = z.object({
|
||||
anchors: z.array(connectorAnchorInput)
|
||||
});
|
||||
|
||||
export const groupInput = z.object({
|
||||
export const rectangleInput = z.object({
|
||||
id: z.string(),
|
||||
color: z.string().optional(),
|
||||
from: coords,
|
||||
|
||||
Reference in New Issue
Block a user