Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import "./ActionBlock.css";
export function ActionBlockHtml({ graph, block }: { graph: Graph; block: TGravityActionBlock }) {
return (
<GraphBlock graph={graph} block={block} className="action-block-wrapper">
{block.anchors.map((anchor) => {
{block.anchors?.map((anchor) => {
return (
<GraphBlockAnchor
className="action-block-achor"
Expand All @@ -28,7 +28,7 @@ export function ActionBlockHtml({ graph, block }: { graph: Graph; block: TGravit
{block.name}
</Text>
<Text as="div" ellipsis variant="caption-1" color="secondary">
{block.meta.description}
{block.meta?.description}
</Text>
</Flex>
<Flex>
Expand Down
4 changes: 2 additions & 2 deletions apps/storybook/src/stories/Playground/ActionBlock/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ActionBlockHtml } from "./ActionBlockHtml";

import "./ActionBlock.css";

function getAnchorY(index) {
function getAnchorY(index: number): number {
let y = 18 * index;
if (index >= 1) {
y += 8 * index;
Expand Down Expand Up @@ -65,7 +65,7 @@ export class ActionBlock extends CanvasBlock<TGravityActionBlock> {
}

protected getAnchorsYOffter(type: EAnchorType) {
const anchors = this.connectedState.$state.value.anchors.filter((a) => a.type === type);
const anchors = (this.connectedState.$state.value.anchors ?? []).filter((a) => a.type === type);
const { height } = this.getContentRect();
return (height - getAnchorY(anchors.length - 1)) / 2;
}
Expand Down
20 changes: 15 additions & 5 deletions apps/storybook/src/stories/Playground/Editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,21 @@ export const ConfigEditor = React.forwardRef(function ConfigEditor(
props: ConfigEditorProps,
ref: Ref<ConfigEditorController>
) {
const [errorMarker, setErrorMarker] = useState<ExtractTypeFromArray<Parameters<OnValidate>[0]>>(null);
const [errorMarker, setErrorMarker] = useState<ExtractTypeFromArray<Parameters<OnValidate>[0]> | null>(null);

const monacoRef = useRef<Parameters<OnMount>[0]>(null);
const monacoRef = useRef<Parameters<OnMount>[0] | null>(null);

const valueRef = useRef<{ blocks: TBlock[]; connections: TConnection[] }>({ blocks: [], connections: [] });

useImperativeHandle(ref, () => ({
scrollTo: (blockId: string) => {
scrollTo: (blockId: TBlockId) => {
if (!monacoRef.current) {
return;
}
const model = monacoRef.current.getModel();
if (!model) {
return;
}
const range = findBlockPositionsMonaco(model, blockId);

if (range?.start.column) {
Expand All @@ -66,6 +69,9 @@ export const ConfigEditor = React.forwardRef(function ConfigEditor(
return;
}
const model = monacoRef.current.getModel();
if (!model) {
return;
}
const edits = blocks.map((block) => {
const range = findBlockPositionsMonaco(model, block.id);
const text = JSON.stringify({ block: [block] }, null, 2);
Expand Down Expand Up @@ -96,7 +102,11 @@ export const ConfigEditor = React.forwardRef(function ConfigEditor(

const applyChanges = useFn(() => {
try {
const data = JSON.parse(monacoRef.current.getModel().getValue());
const model = monacoRef.current?.getModel();
if (!model) {
return;
}
const data = JSON.parse(model.getValue());
props?.onChange?.({ blocks: data.blocks, connections: data.conections });
} catch (e) {
console.error(e);
Expand Down Expand Up @@ -147,7 +157,7 @@ export const ConfigEditor = React.forwardRef(function ConfigEditor(
onClick={() => {
monacoRef.current?.revealLinesInCenter(errorMarker.startLineNumber, errorMarker.endLineNumber, 0);

monacoRef.current.setSelection({
monacoRef.current?.setSelection({
startColumn: errorMarker.startColumn,
startLineNumber: errorMarker.startLineNumber,
endColumn: errorMarker.endColumn,
Expand Down
8 changes: 7 additions & 1 deletion apps/storybook/src/stories/Playground/Editor/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
export function findBlockPositionsMonaco(model, blockId) {
import type { TBlockId } from "@gravity-ui/graph";
import type { IPosition, editor } from "monaco-editor/esm/vs/editor/editor.api";

export function findBlockPositionsMonaco(
model: editor.ITextModel,
blockId: TBlockId
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Resolved
): { start: IPosition; end: IPosition } {
const configString = model.getValue();
const blockSearchStr = `"id": "${blockId}"`;
const startIndex = configString.indexOf(blockSearchStr);
Expand Down
36 changes: 19 additions & 17 deletions apps/storybook/src/stories/Playground/GraphPlayground.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";

import { ConnectionLayer, ECanDrag, Graph, GraphState, TBlock, TGraphConfig } from "@gravity-ui/graph";
import { ConnectionLayer, ECanDrag, Graph, GraphState, TBlock, TGraphConfig, TPoint } from "@gravity-ui/graph";
import { GraphBlock, GraphCanvas, HookGraphParams, useGraph, useGraphEvent, useLayer } from "@gravity-ui/graph-react";
import {
Flex,
Expand All @@ -25,6 +25,7 @@ import {
GravityActionBlockIS,
GravityTextBlockIS,
TGravityActionBlock,
TGravityActionBlockWithAnchors,
TGravityTextBlock,
createActionBlock,
createTextBlock,
Expand Down Expand Up @@ -119,7 +120,7 @@ const pointIcon = {
};

// Function for drawing connection line
const drawLine = (start, end) => {
const drawLine = (start: TPoint, end: TPoint) => {
const path = new Path2D();
path.moveTo(start.x, start.y);
path.lineTo(end.x, end.y);
Expand Down Expand Up @@ -149,7 +150,7 @@ export function GraphPLayground() {

const updateVisibleConfig = useFn(() => {
const config = graph.rootStore.getAsConfig();
editorRef?.current.setContent({
editorRef.current?.setContent({
blocks: config.blocks || [],
connections: config.connections || [],
});
Expand All @@ -170,15 +171,13 @@ export function GraphPLayground() {
});

useGraphEvent(graph, "blocks-selection-change", ({ changes }) => {
editorRef?.current.updateBlocks([
...changes.add.map((id) => ({
...graph.rootStore.blocksList.getBlock(id),
selected: true,
})),
...changes.removed.map((id) => ({
...graph.rootStore.blocksList.getBlock(id),
selected: false,
})),
const withSelection = (id: TBlock["id"], selected: boolean): TBlock[] => {
const block = graph.rootStore.blocksList.getBlock(id);
return block ? [{ ...block, selected }] : [];
};
editorRef.current?.updateBlocks([
...changes.add.flatMap((id) => withSelection(id, true)),
...changes.removed.flatMap((id) => withSelection(id, false)),
]);
});

Expand Down Expand Up @@ -215,7 +214,7 @@ export function GraphPLayground() {
if (targetBlockId) {
return;
}
let block: TBlock;
let block: TGravityActionBlockWithAnchors;
const pullSourceAnchor =
sourceAnchorId === undefined
? undefined
Expand All @@ -242,7 +241,7 @@ export function GraphPLayground() {
}
graph.zoomTo([block.id], { transition: 250 });
updateVisibleConfig();
editorRef?.current.scrollTo(block.id);
editorRef.current?.scrollTo(block.id);
});

useLayoutEffect(() => {
Expand All @@ -266,7 +265,7 @@ export function GraphPLayground() {
graph.api.addBlock(block);
graph.zoomTo([block.id], { transition: 250 });
updateVisibleConfig();
editorRef?.current.scrollTo(block.id);
editorRef.current?.scrollTo(block.id);
});

const renderBlockFn = useFn((graph: Graph, block: TBlock) => {
Expand All @@ -286,7 +285,7 @@ export function GraphPLayground() {

useGraphEvent(graph, "blocks-selection-change", ({ list }) => {
if (list.length === 1) {
editorRef?.current.scrollTo(list[0]);
editorRef.current?.scrollTo(list[0]);
}
});

Expand All @@ -301,7 +300,7 @@ export function GraphPLayground() {
return () => document.body.removeEventListener("keydown", fn);
});

const updateGraphSize = useFn<Parameters<SegmentedRadioGroupProps["onUpdate"]>, void>((value) => {
const updateGraphSize = useFn<Parameters<NonNullable<SegmentedRadioGroupProps["onUpdate"]>>, void>((value) => {
let config: TGraphConfig<TGravityActionBlock | TGravityTextBlock>;
setGraphSize(value);

Expand All @@ -325,6 +324,9 @@ export function GraphPLayground() {
config = generatePlaygroundActionBlocks(50, 150);
break;
}
default: {
return;
}
}
setEntities(config);
graph.zoomTo("center", { transition: 500 });
Expand Down
2 changes: 1 addition & 1 deletion apps/storybook/src/stories/Playground/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const ConnectionArrowsVariants: SegmentedRadioGroupOptionProps[] = [

export function GraphSettings({ className, graph }: { className: string; graph: Graph }) {
const rerender = useRerender();
const settingBtnRef = useRef();
const settingBtnRef = useRef<HTMLButtonElement>(null);
const [settingsOpened, setSettingsOpened] = useState(false);
return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function TextBlockHtml({ graph, block }: { graph: Graph; block: TGravityT
<Flex direction={"row"} gap={2} alignItems="center" grow={1}>
<Icon className="icon" data={CircleInfo} size={18} />
<Text className="text-block-text" as="div" ellipsis variant="body-1">
{block.meta.text}
{block.meta?.text}
</Text>
{/* <Icon className="icon" data={Xmark} size={18}/> */}
</Flex>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class TextBlock extends CanvasBlock<TGravityTextBlock> {
protected renderName(ctx: CanvasRenderingContext2D) {
ctx.fillStyle = "rgba(189, 142, 75, 1)";
ctx.textAlign = "center";
this.renderText(this.state.meta.text, ctx);
this.renderText(this.state.meta?.text ?? "", ctx);
}

public renderHTML() {
Expand Down
16 changes: 10 additions & 6 deletions apps/storybook/src/stories/Playground/generateLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { EAnchorType, TBlock, TGraphConfig } from "@gravity-ui/graph";
import { EAnchorType, TAnchor, TBlock, TConnection } from "@gravity-ui/graph";

export const GravityActionBlockIS = "block-action";
export type TGravityActionBlock = TBlock<{ description: string }> & { is: typeof GravityActionBlockIS };
/** Action block created by `createActionBlock`: anchors are always `[in, out]`. */
export type TGravityActionBlockWithAnchors = TGravityActionBlock & { anchors: [TAnchor, TAnchor] };

export const GravityTextBlockIS = "block-text";
export type TGravityTextBlock = TBlock<{ text: string }> & { is: typeof GravityTextBlockIS };
Expand All @@ -10,7 +12,7 @@ function getActionBlockId(num: number): string {
return `action_${num}`;
}

export function createActionBlock(x: number, y: number, index: number): TGravityActionBlock {
export function createActionBlock(x: number, y: number, index: number): TGravityActionBlockWithAnchors {
const blockId = getActionBlockId(index);

return {
Expand Down Expand Up @@ -40,7 +42,7 @@ export function createActionBlock(x: number, y: number, index: number): TGravity
};
}

export function createTextBlock(x: number, y: number, width: number, index: number, text): TGravityTextBlock {
export function createTextBlock(x: number, y: number, width: number, index: number, text: string): TGravityTextBlock {
const blockId = `text_${index}`;

return {
Expand All @@ -59,12 +61,14 @@ export function createTextBlock(x: number, y: number, width: number, index: numb
};
}

function getRandomArbitrary(min, max) {
function getRandomArbitrary(min: number, max: number): number {
return (Math.random() * (max - min) + min) | 0;
}

export function generatePlaygroundActionBlocks(layersCount: number, connectionsPerLayer: number) {
const config: TGraphConfig<TGravityActionBlock> = {
type TPlaygroundConfig = { blocks: TGravityActionBlock[]; connections: TConnection[] };

export function generatePlaygroundActionBlocks(layersCount: number, connectionsPerLayer: number): TPlaygroundConfig {
const config: TPlaygroundConfig = {
blocks: [],
connections: [],
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const GraphApp = () => {
const [height, setHeight] = useState(blockConfig.height.toString());

const onClick: ButtonButtonProps["onClick"] = useCallback(() => {
graphRef.current.api.updateBlock({
graphRef.current?.api.updateBlock({
...blockConfig,
x: Number(x),
y: Number(y),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const GraphApp = () => {
const graphRef = useRef<Graph | undefined>(undefined);

const onConnectionChange: TOnConnectionChange = useCallback((connection) => {
graphRef.current.api.updateConnection("OneLeft:TwoRight", connection);
graphRef.current?.api.updateConnection("OneLeft:TwoRight", connection);
}, []);

const onSourceBlockUpdate: SelectProps<string>["onUpdate"] = useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,24 @@ const GraphApp = () => {
const [colors, setColors] = useState<TGraphColorsPatch>();
const graphRef = useRef<Graph | undefined>(undefined);

const updateReactComponentsColors = useCallback((colors) => {
const updateReactComponentsColors = useCallback((colors: TGraphColorsPatch) => {
setColors(colors);
}, []);

const onRedClick: ButtonButtonProps["onClick"] = useCallback(() => {
graphRef.current.api.updateGraphColors({ block: { background: "#febcb8" } });
graphRef.current?.api.updateGraphColors({ block: { background: "#febcb8" } });

updateReactComponentsColors({ block: { background: "#febcb8" } });
}, [updateReactComponentsColors]);

const onGreenClick: ButtonButtonProps["onClick"] = useCallback(() => {
graphRef.current.api.updateGraphColors({ block: { background: "#b7e6b0" } });
graphRef.current?.api.updateGraphColors({ block: { background: "#b7e6b0" } });

updateReactComponentsColors({ block: { background: "#b7e6b0" } });
}, [updateReactComponentsColors]);

const onYellowClick: ButtonButtonProps["onClick"] = useCallback(() => {
graphRef.current.api.updateGraphColors({ block: { background: "#fee0b0" } });
graphRef.current?.api.updateGraphColors({ block: { background: "#fee0b0" } });

updateReactComponentsColors({ block: { background: "#fee0b0" } });
}, [updateReactComponentsColors]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const GraphApp = () => {
const graphRef = useRef<Graph | undefined>(undefined);

const onApplyZoom: ButtonButtonProps["onClick"] = useCallback(() => {
graphRef.current.setConstants({
graphRef.current?.setConstants({
camera: {
SPEED: Number(speed),
STEP: Number(step),
Expand All @@ -28,7 +28,7 @@ const GraphApp = () => {
}, [speed, step]);

const onApplyPan: ButtonButtonProps["onClick"] = useCallback(() => {
graphRef.current.setConstants({
graphRef.current?.setConstants({
camera: {
PAN_SPEED: Number(panSpeed),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const GraphApp = () => {
const graphRef = useRef<Graph | undefined>(undefined);

const onClick: ButtonButtonProps["onClick"] = useCallback(() => {
graphRef.current.api.zoomToBlocks(blocksId.split(/,\s?/g), {
graphRef.current?.api.zoomToBlocks(blocksId.split(/,\s?/g), {
transition: Number(transition),
padding: Number(padding),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const GraphApp = () => {
const graphRef = useRef<Graph | undefined>(undefined);

const onClick: ButtonButtonProps["onClick"] = useCallback(() => {
graphRef.current.api.zoomToRect(
graphRef.current?.api.zoomToRect(
{ height: Number(height), width: Number(width), x: Number(x), y: Number(y) },
{ transition: Number(transition), padding: Number(padding) }
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const GraphApp = () => {
const graphRef = useRef<Graph | undefined>(undefined);

const onClick: ButtonButtonProps["onClick"] = useCallback(() => {
graphRef.current.api.zoomToViewPort({ transition: Number(transition), padding: Number(padding) });
graphRef.current?.api.zoomToViewPort({ transition: Number(transition), padding: Number(padding) });
}, [transition, padding]);

return (
Expand Down
Loading