Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Service Server Visual Diagram #1099

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 0 additions & 3 deletions .changeset/odd-rules-accept.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
---
"design-system": patch
"studio-next": patch
"@asyncapi/studio": patch
"@asyncapi/studio-ui": patch
---

- Use PNPM instead of NPM.
50 changes: 50 additions & 0 deletions apps/design-system/src/components/Server.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { StoryObj, Meta } from '@storybook/react'

import { Server } from '@asyncapi/studio-ui'

const meta: Meta<typeof Server> = {
component: Server,
parameters: {
layout: 'centered',
backgrounds: {
default: 'dark'
}
},
}

export default meta
type Story = StoryObj<typeof Server>
export const Default: Story = {
args: {
name: 'KAFKA Production',
icon: 'kafka',
url: 'my.kafka.broker.com',
},
}


export const Active: Story = {
args: {
...Default.args,
isActive: true,
},
};


export const MissingURL: Story = {
args: {
...Default.args,
name: 'KAFKA Production',
icon: 'websocket',
url: '',
},
};

export const Faded: Story = {
args: {
...Default.args,
isFaded: true,
icon: 'websocket',
url: '',
},
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { StoryObj, Meta } from '@storybook/react'

import { AppCard } from '@asyncapi/studio-ui'
import { Service } from '@asyncapi/studio-ui'

const meta: Meta<typeof AppCard> = {
component: AppCard,
const meta: Meta<typeof Service> = {
component: Service,
parameters: {
layout: 'centered',
backgrounds: {
Expand All @@ -13,8 +13,8 @@ const meta: Meta<typeof AppCard> = {
}

export default meta
type Story = StoryObj<typeof AppCard>
export const CodeEditor: Story = {
type Story = StoryObj<typeof Service>
export const Default: Story = {
args: {
isActive: true,
name: 'User Registration',
Expand All @@ -23,4 +23,6 @@ export const CodeEditor: Story = {
isServer: true,
isClient: false
},
}
}


114 changes: 114 additions & 0 deletions apps/design-system/src/components/ServiceFlowDiagram.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { StoryObj, Meta } from "@storybook/react"

import { ServiceFlowDiagram, Server, Service, OperationAction } from "@asyncapi/studio-ui"

const meta: Meta<typeof ServiceFlowDiagram> = {
component: ServiceFlowDiagram,
parameters: {
layout: "centered",
backgrounds: {
default: "dark",
},
},
argTypes: {
onAddOperation: { action: "onAddOperation" },
onAddServer: { action: "onAddServer" },
onOperationClick: { action: "onOperationClick" },
onServerClick: { action: "onServerClick" },
onServiceClick: { action: "onServiceClick" },
},
}

export default meta

type Story = StoryObj<typeof ServiceFlowDiagram>

const operations = [
{ id: "sendUserHasBeenRemoved", action: OperationAction.SEND, source: "Production Kafka Broker" },
{ id: "sendUserSignedUp", action: OperationAction.SEND, source: "Production Kafka Broker" },
{ id: "onUserSignedUp", action: OperationAction.SEND, source: "A WebSocket Client" },
{ id: "POST /users", action: OperationAction.RECEIVE, source: "An HTTP Client" },
]

const service = {
position: { x: 300, y: 400 },
component: (
<Service
name={"User Registration"}
isActive={true}
description={
"ucondimentum mauris. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque posuere fermentumurna, eu condimentum mauris. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque posuerefermentum urna, eu condimentum maur"
}
badges={["http", "kafka", "websocket"]}
isClient={true}
isServer={false}
/>
),
}

const servers = [
{
id: "Production Kafka Broker",
position: { x: service.position.x - 20, y: service.position.y - 300 },
component: <Server name={"Production Kafka Broker"} icon={"kafka"} url={"kafka.in.mycompany.com/production"} />,
},
{
id: "A Yet Unused Server",
position: { x: service.position.x + 300, y: service.position.y - 300 },
component: <Server name={"A Yet Unused Server"} icon={"kafka"} url={"kafka.in.mycompany.com/unused"} />,
},
{
id: "A WebSocket Client",
position: { x: service.position.x - 20, y: service.position.y + 500 },
component: <Server name={"A WebSocket Client"} icon={"websocket"} isFaded />,
},
{
id: "An HTTP Client",
position: { x: service.position.x + 300, y: service.position.y + 500 },
component: <Server name={"An HTTP Client"} icon={"http"} isFaded />,
},
]

const addServerButtonPosition = { x: service.position.x + 600, y: service.position.y - 300 }

export const Default: Story = {
args: {
service,
operations,
addServerButtonPosition,
servers,
},
}

export const WithOneServer: Story = {
args: {
service,
addServerButtonPosition,
operations,
servers: [servers[0]],
},
}

const withOperationSelected = [
{ id: "sendUserHasBeenRemoved", action: OperationAction.SEND, source: "Production Kafka Broker", selected: true },
{ id: "sendUserSignedUp", action: OperationAction.SEND, source: "Production Kafka Broker" },
]

export const WithOperationSelected: Story = {
args: {
service,
addServerButtonPosition,
operations: withOperationSelected,
servers: [servers[0]],
},
}

const operationsTooMany = new Array(20).fill("").map((_, i) => ({ id: `${i% 3 === 0 ? "receive": "send"}Operation${i}`, action: i% 3 === 0 ? OperationAction.RECEIVE : OperationAction.SEND, source: 'Production Kafka Broker' }));
export const WithTooManyOperations: Story = {
args: {
service,
operations: operationsTooMany,
addServerButtonPosition,
servers: [servers[0]],
},
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"name": "studio",
"private": true,
"repository": {
"type": "git",
Expand Down
20 changes: 20 additions & 0 deletions packages/ui/components/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'

import { cn } from '@asyncapi/studio-utils'

const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
' bg-gray-800 border-gray-700 rounded-lg border-2',
className
)}
{...props}
/>
))
Card.displayName = 'Card'

export { Card }
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

// THIS FILE IS COPY-PASTED FROM: https://reactflow.dev/examples/edges/floating-edges


import React from 'react';
import { getBezierPath } from 'reactflow';

import { getEdgeParams } from '../Edges/Utils';

type FloatingConnectionLineProps = {
toX: number;
toY: number;
fromPosition: string;
toPosition: string;
fromNode?: any;
};
function FloatingConnectionLine({ toX, toY, fromPosition, toPosition, fromNode }: FloatingConnectionLineProps) {
if (!fromNode) {
return null;
}

const targetNode = {
id: 'connection-target',
width: 1,
height: 1,
positionAbsolute: { x: toX, y: toY }
};

const { sx, sy } = getEdgeParams(fromNode, targetNode);
const [edgePath] = getBezierPath({
sourceX: sx,
sourceY: sy,
// @ts-ignore
sourcePosition: fromPosition,
// @ts-ignore
targetPosition: toPosition,
targetX: toX,
targetY: toY
});

return (
<g>
<path
fill="none"
stroke="#222"
strokeWidth={1.5}
className="animated"
d={edgePath}
/>
<circle
cx={toX}
cy={toY}
fill="#fff"
r={3}
stroke="#222"
strokeWidth={1.5}
/>
</g>
);

}

export default FloatingConnectionLine;
Loading
Loading