darabos commited on
Commit
960efe0
·
1 Parent(s): db436f7

Box resizing - not perfect yet.

Browse files
server/ops.py CHANGED
@@ -39,7 +39,7 @@ class BaseConfig(pydantic.BaseModel):
39
  class Parameter(BaseConfig):
40
  '''Defines a parameter for an operation.'''
41
  name: str
42
- default: any
43
  type: Type = None
44
 
45
  @staticmethod
@@ -77,7 +77,7 @@ def basic_outputs(*names):
77
 
78
 
79
  class Op(BaseConfig):
80
- func: callable = pydantic.Field(exclude=True)
81
  name: str
82
  params: dict[str, Parameter]
83
  inputs: dict[str, Input]
 
39
  class Parameter(BaseConfig):
40
  '''Defines a parameter for an operation.'''
41
  name: str
42
+ default: typing.Any
43
  type: Type = None
44
 
45
  @staticmethod
 
77
 
78
 
79
  class Op(BaseConfig):
80
+ func: typing.Callable = pydantic.Field(exclude=True)
81
  name: str
82
  params: dict[str, Parameter]
83
  inputs: dict[str, Input]
web/package-lock.json CHANGED
@@ -13,6 +13,7 @@
13
  "@sveltestack/svelte-query": "^1.6.0",
14
  "@xyflow/svelte": "^0.1.3",
15
  "bootstrap": "^5.3.3",
 
16
  "echarts": "^5.5.0",
17
  "fuse.js": "^7.0.0",
18
  "svelte-echarts": "^1.0.0-rc1",
@@ -1423,6 +1424,11 @@
1423
  }
1424
  }
1425
  },
 
 
 
 
 
1426
  "node_modules/deepmerge": {
1427
  "version": "4.3.1",
1428
  "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
 
13
  "@sveltestack/svelte-query": "^1.6.0",
14
  "@xyflow/svelte": "^0.1.3",
15
  "bootstrap": "^5.3.3",
16
+ "deep-object-diff": "^1.1.9",
17
  "echarts": "^5.5.0",
18
  "fuse.js": "^7.0.0",
19
  "svelte-echarts": "^1.0.0-rc1",
 
1424
  }
1425
  }
1426
  },
1427
+ "node_modules/deep-object-diff": {
1428
+ "version": "1.1.9",
1429
+ "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.9.tgz",
1430
+ "integrity": "sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA=="
1431
+ },
1432
  "node_modules/deepmerge": {
1433
  "version": "4.3.1",
1434
  "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
web/package.json CHANGED
@@ -26,6 +26,7 @@
26
  "@sveltestack/svelte-query": "^1.6.0",
27
  "@xyflow/svelte": "^0.1.3",
28
  "bootstrap": "^5.3.3",
 
29
  "echarts": "^5.5.0",
30
  "fuse.js": "^7.0.0",
31
  "svelte-echarts": "^1.0.0-rc1",
 
26
  "@sveltestack/svelte-query": "^1.6.0",
27
  "@xyflow/svelte": "^0.1.3",
28
  "bootstrap": "^5.3.3",
29
+ "deep-object-diff": "^1.1.9",
30
  "echarts": "^5.5.0",
31
  "fuse.js": "^7.0.0",
32
  "svelte-echarts": "^1.0.0-rc1",
web/src/LynxKiteFlow.svelte CHANGED
@@ -1,5 +1,5 @@
1
  <script lang="ts">
2
- import { setContext } from 'svelte';
3
  import { writable, derived } from 'svelte/store';
4
  import {
5
  SvelteFlow,
@@ -131,16 +131,34 @@
131
  if (doNotSave) return;
132
  const dragging = g.nodes.find((n) => n.dragging);
133
  if (dragging) return;
 
 
 
 
 
 
 
 
 
 
 
134
  g = JSON.parse(JSON.stringify(g));
135
  for (const node of g.nodes) {
136
- delete node.computed;
 
 
 
 
 
 
137
  delete node.selected;
138
  }
139
  const ws = orderedJSON(g);
140
  const bd = orderedJSON($backendWorkspace.data);
141
  if (ws === bd) return;
 
142
  $mutation.mutate({ path, ws: g });
143
- });
144
  function onconnect(connection: Connection) {
145
  edges.update((edges) => {
146
  // Only one source can connect to a given target.
 
1
  <script lang="ts">
2
+ import { diff } from 'deep-object-diff';
3
  import { writable, derived } from 'svelte/store';
4
  import {
5
  SvelteFlow,
 
131
  if (doNotSave) return;
132
  const dragging = g.nodes.find((n) => n.dragging);
133
  if (dragging) return;
134
+ const resizing = g.nodes.find((n) => n.data?.beingResized);
135
+ if (resizing) return;
136
+ scheduleSave(g);
137
+ });
138
+ let saveTimeout;
139
+ function scheduleSave(g) {
140
+ // A slight delay, so we don't send a million requests when a node is resized, for example.
141
+ clearTimeout(saveTimeout);
142
+ saveTimeout = setTimeout(() => save(g), 500);
143
+ }
144
+ function save(g) {
145
  g = JSON.parse(JSON.stringify(g));
146
  for (const node of g.nodes) {
147
+ delete node.measured;
148
+ delete node.selected;
149
+ delete node.dragging;
150
+ delete node.beingResized;
151
+ }
152
+ for (const node of g.edges) {
153
+ delete node.markerEnd;
154
  delete node.selected;
155
  }
156
  const ws = orderedJSON(g);
157
  const bd = orderedJSON($backendWorkspace.data);
158
  if (ws === bd) return;
159
+ console.log('changed', JSON.stringify(diff(g, $backendWorkspace.data), null, 2));
160
  $mutation.mutate({ path, ws: g });
161
+ }
162
  function onconnect(connection: Connection) {
163
  edges.update((edges) => {
164
  // Only one source can connect to a given target.
web/src/LynxKiteNode.svelte CHANGED
@@ -1,6 +1,9 @@
1
  <script lang="ts">
2
- import { Handle, type NodeProps } from '@xyflow/svelte';
 
3
 
 
 
4
  type $$Props = NodeProps;
5
 
6
  export let nodeStyle = '';
@@ -21,10 +24,12 @@
21
  export let positionAbsoluteY: $$Props['positionAbsoluteY'] = undefined; positionAbsoluteY;
22
  export let onToggle = () => {};
23
 
24
- let expanded = true;
25
  function titleClicked() {
26
- expanded = !expanded;
 
27
  onToggle({ expanded });
 
28
  }
29
  function asPx(n: number | undefined) {
30
  return n ? n + 'px' : undefined;
@@ -34,7 +39,8 @@
34
  const handleOffsetDirection = { top: 'left', bottom: 'left', left: 'top', right: 'top' };
35
  </script>
36
 
37
- <div class="node-container" style:width={asPx(width)} style:height={asPx(height)} style={containerStyle}>
 
38
  <div class="lynxkite-node" style={nodeStyle}>
39
  <div class="title" on:click={titleClicked}>
40
  {data.title}
@@ -62,6 +68,17 @@
62
  </Handle>
63
  {/each}
64
  </div>
 
 
 
 
 
 
 
 
 
 
 
65
  </div>
66
 
67
  <style>
@@ -76,15 +93,15 @@
76
  }
77
  .node-container {
78
  padding: 8px;
79
- min-width: 200px;
80
- max-width: 400px;
81
- max-height: 400px;
82
  }
83
  .lynxkite-node {
84
  box-shadow: 0px 5px 50px 0px rgba(0, 0, 0, 0.3);
 
85
  background: white;
 
 
86
  overflow-y: auto;
87
- border-radius: 4px;
88
  height: 100%;
89
  }
90
  .title {
@@ -120,4 +137,11 @@
120
  .node-container:hover .handle-name {
121
  visibility: visible;
122
  }
 
 
 
 
 
 
 
123
  </style>
 
1
  <script lang="ts">
2
+ import { Handle, useSvelteFlow, useUpdateNodeInternals, type NodeProps, NodeResizeControl } from '@xyflow/svelte';
3
+ import ChevronDownRight from 'virtual:icons/tabler/chevron-down-right';
4
 
5
+ const { updateNodeData } = useSvelteFlow();
6
+ const updateNodeInternals = useUpdateNodeInternals();
7
  type $$Props = NodeProps;
8
 
9
  export let nodeStyle = '';
 
24
  export let positionAbsoluteY: $$Props['positionAbsoluteY'] = undefined; positionAbsoluteY;
25
  export let onToggle = () => {};
26
 
27
+ $: expanded = !data.collapsed;
28
  function titleClicked() {
29
+ updateNodeData(id, { collapsed: expanded });
30
+ data = data;
31
  onToggle({ expanded });
32
+ updateNodeInternals();
33
  }
34
  function asPx(n: number | undefined) {
35
  return n ? n + 'px' : undefined;
 
39
  const handleOffsetDirection = { top: 'left', bottom: 'left', left: 'top', right: 'top' };
40
  </script>
41
 
42
+ <div class="node-container" class:expanded={expanded}
43
+ style:width={asPx(width)} style:height={asPx(expanded ? height : undefined)} style={containerStyle}>
44
  <div class="lynxkite-node" style={nodeStyle}>
45
  <div class="title" on:click={titleClicked}>
46
  {data.title}
 
68
  </Handle>
69
  {/each}
70
  </div>
71
+ {#if expanded}
72
+ <NodeResizeControl
73
+ minWidth={100}
74
+ minHeight={50}
75
+ style="background: transparent; border: none;"
76
+ onResizeStart={() => updateNodeData(id, { beingResized: true })}
77
+ onResizeEnd={() => updateNodeData(id, { beingResized: false })}
78
+ >
79
+ <ChevronDownRight class="node-resizer" />
80
+ </NodeResizeControl>
81
+ {/if}
82
  </div>
83
 
84
  <style>
 
93
  }
94
  .node-container {
95
  padding: 8px;
96
+ position: relative;
 
 
97
  }
98
  .lynxkite-node {
99
  box-shadow: 0px 5px 50px 0px rgba(0, 0, 0, 0.3);
100
+ border-radius: 4px;
101
  background: white;
102
+ }
103
+ .expanded .lynxkite-node {
104
  overflow-y: auto;
 
105
  height: 100%;
106
  }
107
  .title {
 
137
  .node-container:hover .handle-name {
138
  visibility: visible;
139
  }
140
+ :global(.node-resizer) {
141
+ position: absolute;
142
+ bottom: 8px;
143
+ right: 8px;
144
+ cursor: nwse-resize;
145
+ color: var(--bs-border-color);
146
+ }
147
  </style>