flojoy-ai / studio

Joyful visual programming for Python
https://docs.flojoy.ai
MIT License
205 stars 20 forks source link

capture cmd-V to draw flow chart snippets #379

Closed jackparmer closed 1 year ago

jackparmer commented 1 year ago

Thinking about the interoperability between the online docs and studio, it would be nice to support a copy-paste workflow.

What I'm imagining is that simple programs in the docs could be copy/pasted into the Flojoy Studio SCRIPT tab. The docs page would look something like this:

image

When clicking on the copy icon, the JSON spec for the flow chart snippet would be copied to the clipboard, looking something like this:

{
    "rfInstance": {
        "nodes": [
            {
                "width": 115,
                "height": 115,
                "id": "SINE-2cd08316-0a0c-4c13-9b1d-382ba4d74cbd",
                "type": "SIMULATION",
                "data": {
                    "id": "SINE-2cd08316-0a0c-4c13-9b1d-382ba4d74cbd",
                    "label": "SINE",
                    "func": "SINE",
                    "type": "SIMULATION",
                    "ctrls": {
                        "frequency": {
                            "functionName": "SINE",
                            "param": "frequency",
                            "value": "1"
                        },
                        "offset": {
                            "functionName": "SINE",
                            "param": "offset",
                            "value": "0"
                        },
                        "amplitude": {
                            "functionName": "SINE",
                            "param": "amplitude",
                            "value": "1"
                        },
                        "phase": {
                            "functionName": "SINE",
                            "param": "phase",
                            "value": "0"
                        },
                        "waveform": {
                            "functionName": "SINE",
                            "param": "waveform",
                            "value": "sine"
                        }
                    },
                    "selected": false
                },
                "position": {
                    "x": 198.57142857142856,
                    "y": 129.6723161525938
                },
                "selected": false,
                "positionAbsolute": {
                    "x": 198.57142857142856,
                    "y": 129.6723161525938
                },
                "dragging": true
            },
            {
                "width": 99,
                "height": 115,
                "id": "ADD-a586b5d7-4343-430d-89ce-3c2a3d156695",
                "type": "ARITHMETIC",
                "data": {
                    "id": "ADD-a586b5d7-4343-430d-89ce-3c2a3d156695",
                    "label": "ADD",
                    "func": "ADD",
                    "type": "ARITHMETIC",
                    "ctrls": {},
                    "inputs": [
                        {
                            "name": "y",
                            "id": "add_y",
                            "type": "target"
                        }
                    ],
                    "selected": false
                },
                "position": {
                    "x": 489.2933853490825,
                    "y": 222.51644647932966
                },
                "selected": false,
                "positionAbsolute": {
                    "x": 489.2933853490825,
                    "y": 222.51644647932966
                },
                "dragging": true
            },
            {
                "width": 150,
                "height": 135,
                "id": "LINSPACE-a43ae5d5-b602-4d45-a000-232bf9e98936",
                "type": "default",
                "data": {
                    "id": "LINSPACE-a43ae5d5-b602-4d45-a000-232bf9e98936",
                    "label": "LINSPACE",
                    "func": "LINSPACE",
                    "type": "SIMULATION",
                    "ctrls": {
                        "start": {
                            "functionName": "LINSPACE",
                            "param": "start",
                            "value": "10"
                        },
                        "end": {
                            "functionName": "LINSPACE",
                            "param": "end",
                            "value": "0"
                        },
                        "step": {
                            "functionName": "LINSPACE",
                            "param": "step",
                            "value": "1000"
                        }
                    },
                    "selected": false
                },
                "position": {
                    "x": -38.91238843430668,
                    "y": 121.34428266409577
                },
                "selected": false,
                "positionAbsolute": {
                    "x": -38.91238843430668,
                    "y": 121.34428266409577
                },
                "dragging": true
            },
            {
                "width": 115,
                "height": 115,
                "id": "CONSTANT-b25814ea-c5d5-49f7-ba92-9acc7d334515",
                "type": "SIMULATION",
                "data": {
                    "id": "CONSTANT-b25814ea-c5d5-49f7-ba92-9acc7d334515",
                    "label": "2.0",
                    "func": "CONSTANT",
                    "type": "SIMULATION",
                    "ctrls": {
                        "constant": {
                            "functionName": "CONSTANT",
                            "param": "constant",
                            "value": "2.0"
                        }
                    },
                    "selected": false
                },
                "position": {
                    "x": 207.1704968176304,
                    "y": 299.0519850943739
                },
                "selected": false,
                "positionAbsolute": {
                    "x": 207.1704968176304,
                    "y": 299.0519850943739
                },
                "dragging": true
            }
        ],
        "edges": [
            {
                "source": "SINE-2cd08316-0a0c-4c13-9b1d-382ba4d74cbd",
                "sourceHandle": "main",
                "target": "ADD-a586b5d7-4343-430d-89ce-3c2a3d156695",
                "targetHandle": "ADD",
                "id": "reactflow__edge-SINE-2cd08316-0a0c-4c13-9b1d-382ba4d74cbdmain-ADD-a586b5d7-4343-430d-89ce-3c2a3d156695ADD"
            },
            {
                "source": "LINSPACE-a43ae5d5-b602-4d45-a000-232bf9e98936",
                "sourceHandle": "main",
                "target": "SINE-2cd08316-0a0c-4c13-9b1d-382ba4d74cbd",
                "targetHandle": "SINE",
                "id": "reactflow__edge-LINSPACE-a43ae5d5-b602-4d45-a000-232bf9e98936main-SINE-2cd08316-0a0c-4c13-9b1d-382ba4d74cbdSINE"
            },
            {
                "source": "CONSTANT-b25814ea-c5d5-49f7-ba92-9acc7d334515",
                "sourceHandle": "main",
                "target": "ADD-a586b5d7-4343-430d-89ce-3c2a3d156695",
                "targetHandle": "add_y",
                "id": "reactflow__edge-CONSTANT-b25814ea-c5d5-49f7-ba92-9acc7d334515main-ADD-a586b5d7-4343-430d-89ce-3c2a3d156695add_y"
            }
        ],
        "viewport": {
            "x": 186.40493583084816,
            "y": 191.0559930301914,
            "zoom": 0.5652916931943838
        }
    },
    "ctrlsManifest": [
        {
            "type": "input",
            "name": "Slider",
            "id": "INPUT_PLACEHOLDER",
            "hidden": false,
            "minHeight": 1,
            "minWidth": 2,
            "layout": {
                "x": 0,
                "y": 0,
                "h": 2,
                "w": 2,
                "minH": 1,
                "minW": 2,
                "i": "INPUT_PLACEHOLDER"
            }
        }
    ]
}

We'd want to strip out any ctrls, ctrlsManifest, and anything else that could inadvertently add something unexpected.

Then, upon pasting in Studio, we'd pop up a dialogue with a preview of the nodes. There would be 3 options in this dialogue:

  1. Cancel
  2. Overwrite Existing Nodes
  3. Add to Existing Nodes
jackparmer commented 1 year ago

cool but not essential to an MVP