flowstudio 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +7 -7
  2. package/dist/components/app_layout.d.ts +3 -0
  3. package/dist/components/app_layout.jsx +15 -0
  4. package/dist/components/app_settings/data_sources.d.ts +1 -0
  5. package/dist/components/app_settings/data_sources.jsx +119 -0
  6. package/dist/components/app_settings/deploy.d.ts +1 -0
  7. package/dist/components/app_settings/deploy.jsx +22 -0
  8. package/dist/components/app_settings/index.d.ts +1 -0
  9. package/dist/components/app_settings/index.jsx +41 -0
  10. package/dist/components/app_settings/service_providers.d.ts +1 -0
  11. package/dist/components/app_settings/service_providers.jsx +84 -0
  12. package/dist/components/app_settings/simulator.d.ts +1 -0
  13. package/dist/components/app_settings/simulator.jsx +55 -0
  14. package/dist/components/combo_box/index.d.ts +3 -0
  15. package/dist/components/combo_box/index.jsx +104 -0
  16. package/dist/components/context.d.ts +1 -0
  17. package/dist/components/context.jsx +24 -0
  18. package/dist/components/dock_panel.d.ts +2 -0
  19. package/dist/components/dock_panel.jsx +55 -0
  20. package/dist/components/end.d.ts +1 -0
  21. package/dist/components/end.jsx +4 -0
  22. package/dist/components/input.d.ts +1 -0
  23. package/dist/components/input.jsx +19 -0
  24. package/dist/components/normal.d.ts +1 -0
  25. package/dist/components/normal.jsx +4 -0
  26. package/dist/components/sheet/index.d.ts +1 -0
  27. package/dist/components/sheet/index.jsx +32 -0
  28. package/dist/components/simulator/index.d.ts +1 -0
  29. package/dist/components/simulator/index.jsx +11 -0
  30. package/dist/components/start.d.ts +1 -0
  31. package/dist/components/start.jsx +37 -0
  32. package/dist/components/studio/index.d.ts +1 -1
  33. package/dist/components/studio/index.jsx +87 -12
  34. package/dist/components/xnode.d.ts +2 -0
  35. package/dist/components/xnode.jsx +84 -0
  36. package/dist/index.d.ts +2 -1
  37. package/dist/index.js +3 -8
  38. package/dist/zustand/store.d.ts +414 -0
  39. package/dist/zustand/store.js +47 -0
  40. package/package.json +14 -3
@@ -0,0 +1,4 @@
1
+ import XNode from "./xnode";
2
+ export default function NormalNode({ data }) {
3
+ return (<XNode id={data.id} type={'normal'} data={{ message: data.message }} inputs={data.inputs}/>);
4
+ }
@@ -0,0 +1 @@
1
+ export default function Sheet({ children, open, setOpen, onClose, title, showCloseBtn, maxWidth, side, ...rest }: any): import("react").JSX.Element;
@@ -0,0 +1,32 @@
1
+ 'use client';
2
+ import { useEffect, useState } from 'react';
3
+ import { Dialog, IconButton, Flex, Text, Separator } from '@radix-ui/themes';
4
+ import { Cross1Icon } from '@radix-ui/react-icons';
5
+ // import './style.css'
6
+ export default function Sheet({ children, open, setOpen, onClose, title = '', showCloseBtn = true, maxWidth = '500px', side = 'right', ...rest }) {
7
+ const [animationClass, setAnimationClass] = useState('');
8
+ useEffect(() => {
9
+ if (open) {
10
+ setAnimationClass(`slide-in-${side}`);
11
+ }
12
+ else {
13
+ setAnimationClass(`slide-out-${side}`);
14
+ onClose?.();
15
+ }
16
+ }, [open, side]);
17
+ return (<Dialog.Root open={open} onOpenChange={setOpen}>
18
+ <Dialog.Content className={`dialog-content ${animationClass}`} width={'100%'} maxWidth={maxWidth} style={{ padding: 4 }} {...rest}>
19
+ <Flex direction={'column'} height={'100%'} overflow={'hidden'}>
20
+ <Flex flexShrink={'0'} justify={'between'} align={'center'} p={(title || showCloseBtn) ? '4' : '0'}>
21
+ <Dialog.Title style={{ fontWeight: 'normal', marginBottom: 0 }}>{title && <Text>{title}</Text>}</Dialog.Title>
22
+ {showCloseBtn && <Dialog.Close><IconButton highContrast size={'1'}><Cross1Icon /></IconButton></Dialog.Close>}
23
+ </Flex>
24
+ {title && <Separator size={'4'}/>}
25
+
26
+ <Flex flexGrow={'1'} overflow={'auto'} p={'5'}>
27
+ {children}
28
+ </Flex>
29
+ </Flex>
30
+ </Dialog.Content>
31
+ </Dialog.Root>);
32
+ }
@@ -0,0 +1 @@
1
+ export default function Simulator(): import("react").JSX.Element;
@@ -0,0 +1,11 @@
1
+ // import { Card } from '@radix-ui/themes'
2
+ // import ThemeLayout from '../layouts/ThemeLayout'
3
+ export default function Simulator() {
4
+ return (
5
+ // <ThemeLayout>
6
+ <>
7
+ simulator content
8
+ </>
9
+ // </ThemeLayout>
10
+ );
11
+ }
@@ -0,0 +1 @@
1
+ export default function StartNode({ data }: any): import("react").JSX.Element;
@@ -0,0 +1,37 @@
1
+ import { Button, Card, TextArea, Flex, Badge, Text, Popover, Box, } from "@radix-ui/themes";
2
+ import InputNode from "./input";
3
+ import { CiMenuKebab } from "react-icons/ci";
4
+ import XNode from "./xnode";
5
+ export default function StartNode({ data }) {
6
+ return (<XNode id={data.id} type={'start'} data={{ message: data.message }} inputs={data.inputs} fns={[
7
+ { type: 'system', functions: ['Source Finder', 'Session GET'] },
8
+ { type: 'custom', functions: ['Account Checker'] }
9
+ ]}/>);
10
+ return (<Card>
11
+ <Box>
12
+ <Flex width={'100%'} align={'center'} justify={'between'}>
13
+ <Text>Start</Text>
14
+ <Popover.Root>
15
+ <Popover.Trigger>
16
+ <Button size={'1'} aria-label='Options' variant={'outline'}><CiMenuKebab /></Button>
17
+ </Popover.Trigger>
18
+ <Popover.Content maxWidth={'150px'}>
19
+
20
+ </Popover.Content>
21
+ </Popover.Root>
22
+ </Flex>
23
+ </Box>
24
+ <Box>
25
+ <Flex direction={'column'}>
26
+ <TextArea rows={6} size={'1'} className="nodrag" placeholder={'Message'} defaultValue={data.message}></TextArea>
27
+ <Flex direction={'column'}>
28
+ <InputNode id={1} y={50}/>
29
+ <InputNode id={2} y={130}/>
30
+ </Flex>
31
+ <Flex wrap={'wrap'}>
32
+ <Badge size={'1'} color={'green'}>fn (1)</Badge>
33
+ </Flex>
34
+ </Flex>
35
+ </Box>
36
+ </Card>);
37
+ }
@@ -1 +1 @@
1
- export default function Studio(): import("react").JSX.Element;
1
+ export default function Studio({ theme, accent }: any): import("react").JSX.Element;
@@ -1,14 +1,89 @@
1
- "use strict";
2
- // import { Card } from '@radix-ui/themes'
1
+ import { Box } from '@radix-ui/themes';
3
2
  // import ThemeLayout from '../layouts/ThemeLayout'
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.default = Studio;
6
- function Studio() {
7
- return (
8
- // <ThemeLayout>
9
- <>
10
- studio content
11
- </>
12
- // </ThemeLayout>
13
- );
3
+ import { ReactFlow, useNodesState, useEdgesState, addEdge, MiniMap, Controls, Background, Panel, SmoothStepEdge } from '@xyflow/react';
4
+ import DockPanel from '../../components/dock_panel';
5
+ import StartNode from '../../components/start';
6
+ import EndNode from '../../components/end';
7
+ import NormalNode from '../../components/normal';
8
+ import InputNode from '../../components/input';
9
+ import { useConfigStore } from '../../zustand/store';
10
+ import AppLayout from "../app_layout";
11
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
12
+ export default function Studio({ theme, accent }) {
13
+ const identifier = '987654321';
14
+ const { appTheme } = useConfigStore();
15
+ ////////////////// Nodes Management (React Flow) /////////////////////////////
16
+ const { nodesData, setNodesData, edgesData, setEdgesData } = useConfigStore();
17
+ const nodeTypes = useMemo(() => ({ startNode: StartNode, normalNode: NormalNode, endNode: EndNode, inputNode: InputNode }), []);
18
+ const [nodes, setNodes, onNodesChange] = useNodesState(nodesData);
19
+ const [edges, setEdges, onEdgesChange] = useEdgesState(edgesData);
20
+ const onConnect = useCallback((params) => setEdges((eds) => addEdge(params, eds)), [setEdges]);
21
+ const CustomSmoothstepEdge = ({ data, ...props }) => {
22
+ return <SmoothStepEdge {...props} data={data}/>;
23
+ };
24
+ const edgeUpdateSuccessful = useRef(true);
25
+ const onEdgeUpdateStart = useCallback(() => {
26
+ edgeUpdateSuccessful.current = false;
27
+ }, []);
28
+ const onEdgeUpdate = useCallback((oldEdge, newConnection) => {
29
+ edgeUpdateSuccessful.current = true;
30
+ // setEdges((els:any) => updateEdge(oldEdge, newConnection, els));
31
+ }, []);
32
+ const onEdgeUpdateEnd = useCallback((_, edge) => {
33
+ if (!edgeUpdateSuccessful.current) {
34
+ setEdges((eds) => eds.filter((e) => e.id !== edge.id));
35
+ }
36
+ edgeUpdateSuccessful.current = true;
37
+ }, []);
38
+ useEffect(() => {
39
+ if (nodes) {
40
+ setNodesData(nodes);
41
+ }
42
+ }, [onNodesChange]);
43
+ useEffect(() => {
44
+ if (edges) {
45
+ setEdgesData(edges);
46
+ }
47
+ }, [onEdgesChange]);
48
+ // const getNodeId = () => `randomnode_${+new Date()}`;
49
+ // const onAdd = useCallback(() => {
50
+ // const newNode = {
51
+ // id: getNodeId(),
52
+ // data: { label: 'Added node' },
53
+ // position: {
54
+ // x: Math.random() * window.innerWidth - 100,
55
+ // y: Math.random() * window.innerHeight,
56
+ // },
57
+ // };
58
+ // setNodes((nds) => nds.concat(newNode));
59
+ // }, [setNodes]);
60
+ ////////////////// For Context Menu /////////////////////////////
61
+ const [showContextMenu, setShowContextMenu] = useState(false);
62
+ const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
63
+ const handleContextMenu = (event) => {
64
+ event.preventDefault(); // Prevent default context menu
65
+ const clickX = event.clientX;
66
+ const clickY = event.clientY;
67
+ setContextMenuPosition({ x: clickX, y: clickY });
68
+ setShowContextMenu(true);
69
+ };
70
+ // const cardBackground = useColorModeValue('rgba(255,255,255,.8)', 'hsla(0,0%,0%,.80)')
71
+ return (<AppLayout theme={theme} accent={accent}>
72
+ <Box position={'absolute'} top={'0'} right={'0'} bottom={'0'} left={'0'} style={{}}>
73
+ <Box position={'relative'} style={{ width: '100%', height: '100%', contain: 'paint', willChange: 'transform', transform: 'translate(0)' }}>
74
+
75
+ <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} nodeTypes={nodeTypes} snapToGrid={true}
76
+ // onEdgeUpdate={onEdgeUpdate}
77
+ // onEdgeUpdateStart={onEdgeUpdateStart}
78
+ // onEdgeUpdateEnd={onEdgeUpdateEnd}
79
+ attributionPosition={"top-right"} edgeTypes={{ default: CustomSmoothstepEdge }} fitView minZoom={0.2} maxZoom={1} colorMode={appTheme}>
80
+ <Controls />
81
+ <MiniMap />
82
+ <Background gap={12} size={1}/>
83
+ <Panel position="top-center"> <DockPanel projectIdentifier={identifier}/></Panel>
84
+ </ReactFlow>
85
+
86
+ </Box>
87
+ </Box>
88
+ </AppLayout>);
14
89
  }
@@ -0,0 +1,2 @@
1
+ export default function XNode({ id, data, fns, inputs, type }: any): import("react").JSX.Element;
2
+ export declare function InputNode({ identifier, id, parentType, type, text, inputType, allowDrag, allowInsert }: any): import("react").JSX.Element;
@@ -0,0 +1,84 @@
1
+ import { useState } from "react";
2
+ import { Button, Card, Flex, Badge, Text, Popover, TextField, TextArea, Inset, } from "@radix-ui/themes";
3
+ import { CiMenuKebab } from "react-icons/ci";
4
+ import { Handle, Position } from "@xyflow/react";
5
+ import { BiPlus, BiTrash } from "react-icons/bi";
6
+ import { useConfigStore } from "../zustand/store";
7
+ // Constants
8
+ const color_start = '#009688';
9
+ const color_normal = '#2196f3';
10
+ const color_end = '#ff5c4d';
11
+ export default function XNode({ id = 0, data, fns = [], inputs = [], type = 'normal' }) {
12
+ const { stateType, setStateType } = useConfigStore();
13
+ return (<Card style={{ overflow: 'unset', contain: 'layout' }}>
14
+ <Inset style={{ overflow: 'unset' }}>
15
+ <Flex direction={'column'} gap={'3'}>
16
+ <Flex width={'100%'} align={'center'} justify={'between'} p={'1'} className="drag-handle" style={{ backgroundColor: type == 'start' ? color_start : type == 'normal' ? color_normal : type == 'end' ? color_end : color_normal, borderTopLeftRadius: 7, borderTopRightRadius: 7 }}>
17
+ <Text size={'2'} ml={'1'}>{type == 'start' ? 'Start' : type == 'normal' ? 'Normal' : type == 'end' ? 'End' : 'Normal'}</Text>
18
+ <Popover.Root>
19
+ <Popover.Trigger>
20
+ <Button size={'1'} variant={'soft'} aria-label='Options'><CiMenuKebab /></Button>
21
+ </Popover.Trigger>
22
+ <Popover.Content size={'1'} align="end">
23
+ <Flex direction={'column'} gap={'3'}>
24
+ <Button variant={'ghost'} size={'1'} onClick={() => { }}>Change Node</Button>
25
+ <Button variant={'ghost'} size={'1'} onClick={() => { }} color={'red'}>Delete Node</Button>
26
+ </Flex>
27
+ </Popover.Content>
28
+ </Popover.Root>
29
+ </Flex>
30
+
31
+ <Flex direction={'column'} gap={'3'} px={'3'}>
32
+ {stateType == 'build' ?
33
+ <TextArea size={'1'} className="nodrag" placeholder={'Message'} defaultValue={data?.message || ''}></TextArea>
34
+ : <Text size={'1'} color={'gray'} style={{ maxWidth: '180px', textWrap: 'wrap' }}>{data?.message}</Text>}
35
+ {/* <TextArea size={'1'} className="nodrag" placeholder={'Message'} defaultValue={data?.message || ''}></TextArea> */}
36
+ {type != 'end' && inputs.length > 0 &&
37
+ <Flex direction={'column'} gap={'2'}>
38
+ {inputs.map((val, ind) => (<InputNode key={ind} identifier={ind} id={val.id} parentType={type} type={val.type} text={val.text} inputType={val.inputType} allowDrag={inputs.length > 1} allowInsert={inputs.length == (ind + 1)}/>))}
39
+ </Flex>}
40
+ </Flex>
41
+
42
+ <Flex width={'100%'} align={'center'} px={'2'} pb={'2'}>
43
+ <Flex flexGrow={'1'}>
44
+ {fns.length > 0 &&
45
+ <Flex wrap={'wrap'} gap={'2'}>
46
+ {fns.map((val, ind) => (<Badge key={ind} size={'1'} color={val.type == 'system' ? 'green' : 'purple'}>fn ({val.functions.length})</Badge>))}
47
+ </Flex>}
48
+ </Flex>
49
+ <Flex flexShrink={'0'}>
50
+ <Text size={'1'}>1pg (50)</Text>
51
+ </Flex>
52
+ </Flex>
53
+
54
+ {type != 'start' &&
55
+ <Handle type="target" position={Position.Left} id="g" style={{ left: -6, background: type == 'normal' ? color_normal : type == 'end' ? color_end : color_normal, borderColor: '#fff', borderWidth: 1, width: 10, height: 15, borderRadius: 3, zIndex: 10 }}/>}
56
+ </Flex>
57
+ </Inset>
58
+ </Card>);
59
+ }
60
+ export function InputNode({ identifier, id = 0, parentType, type = 'choice', text = '', inputType = 'text', allowDrag = false, allowInsert = false }) {
61
+ const [show, setShow] = useState(false);
62
+ const handleClick = () => setShow(!show);
63
+ return (<Flex position={'relative'} gap={'0'} align={'center'} style={{ zIndex: 20 }}>
64
+ <Flex width={'100%'} direction={'column'} align={'end'}>
65
+ <Flex width={'100%'} align={'center'}>
66
+ {allowDrag && <Flex gap={'1'}>
67
+ {/* <Button aria-label={'Drag'} color={parentType == 'start'?'green':parentType == 'normal'?'blue':'blue'} size={'1'} ><AiOutlineDrag/></Button> */}
68
+ <Button size={'1'} variant={'soft'} style={{ borderTopRightRadius: 0, borderBottomRightRadius: 0 }}>{id}</Button>
69
+ </Flex>}
70
+ <TextField.Root type={inputType} defaultValue={text} id={'text_value'} placeholder={type == 'choice' ? 'Option Text' : inputType == 'number' ? '0' : 'User Input'} autoComplete={'off'} style={{ width: '100%' }}>
71
+ {identifier != 0 &&
72
+ <TextField.Slot side={'right'} pr={'1'}>
73
+ <Button color={'red'} aria-label={'close'} size={'1'} variant={'soft'} onClick={handleClick} style={{ width: 20, padding: 4 }}><BiTrash size={20}/></Button>
74
+ </TextField.Slot>}
75
+
76
+ </TextField.Root>
77
+ </Flex>
78
+ {allowInsert &&
79
+ <Button aria-label={'Add'} size={'1'} style={{ borderTopLeftRadius: 0, borderTopRightRadius: 0, marginRight: 5 }}><BiPlus /></Button>}
80
+ </Flex>
81
+
82
+ <Handle type="source" position={Position.Right} isConnectable={true} id={id} style={{ right: -19, background: parentType == 'start' ? color_start : parentType == 'normal' ? color_normal : parentType == 'end' ? color_end : color_normal, borderColor: '#fff', borderWidth: 1, width: 10, height: 15, borderRadius: 3, position: 'absolute', top: 16, zIndex: 20 }}/>
83
+ </Flex>);
84
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
+ import Simulator from './components/simulator';
1
2
  import Studio from './components/studio';
2
- export { Studio };
3
+ export { Studio, Simulator };
package/dist/index.js CHANGED
@@ -1,8 +1,3 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Studio = void 0;
7
- const studio_1 = __importDefault(require("./components/studio"));
8
- exports.Studio = studio_1.default;
1
+ import Simulator from './components/simulator';
2
+ import Studio from './components/studio';
3
+ export { Studio, Simulator };