Skip to content

Commit 864a18e

Browse files
committed
Persisting node and edge updates, deleting nodes
1 parent abb2108 commit 864a18e

File tree

8 files changed

+296
-63
lines changed

8 files changed

+296
-63
lines changed

server/db/models.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import sqlalchemy as sql
22
from sqlalchemy.sql import text
33
from datetime import datetime, timezone
4-
from sqlalchemy import create_engine, MetaData, select, String, JSON, DateTime, ForeignKey, Integer, Text, inspect
4+
from sqlalchemy import create_engine, MetaData, select, String, JSON, DateTime, ForeignKey, Integer, Text, inspect, update
55
from sqlalchemy.orm import Session, DeclarativeBase, mapped_column, validates, relationship, Mapped, sessionmaker, reconstructor
66

77
from server.db import *
@@ -15,7 +15,7 @@ class Workspace(Base):
1515
description = sql.Column(sql.Text, nullable=True)
1616
icon = sql.Column(sql.String, nullable=True)
1717
created_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc))
18-
updated_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc))
18+
updated_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
1919

2020
flows = relationship('Flow', back_populates='workspace', cascade='all, delete, delete-orphan')
2121
nodes = relationship('Node', back_populates='workspace', cascade='all, delete, delete-orphan')
@@ -37,7 +37,7 @@ class Flow(Base):
3737
description = sql.Column(sql.Text, nullable=True)
3838
default = sql.Column(sql.Boolean, default=False)
3939
created_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc))
40-
updated_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc))
40+
updated_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
4141

4242
workspace_id = sql.Column(sql.Integer, sql.ForeignKey('workspaces.id'))
4343
workspace = relationship('Workspace', back_populates='flows')
@@ -83,7 +83,7 @@ class EdgeType(Base):
8383
description = sql.Column(sql.Text, nullable=True)
8484
fields = sql.Column(sql.JSON, nullable=True)
8585
created_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc))
86-
updated_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc))
86+
updated_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
8787

8888
edges = relationship('Edge', back_populates='edge_type')
8989

@@ -102,11 +102,12 @@ class Node(Base):
102102
nid = sql.Column(sql.VARCHAR, nullable=False)
103103
node = sql.Column(sql.JSON, nullable=False)
104104
created_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc))
105-
updated_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc))
105+
updated_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
106106

107107
flow_id = sql.Column(sql.Integer, sql.ForeignKey('flows.id'))
108108
flow = relationship('Flow', back_populates='nodes')
109109

110+
110111
workspace_id = sql.Column(sql.Integer, sql.ForeignKey('workspaces.id'))
111112
workspace = relationship('Workspace', back_populates='nodes')
112113

@@ -133,7 +134,7 @@ class Edge(Base):
133134
eid = sql.Column(sql.VARCHAR, nullable=False)
134135
edge = sql.Column(sql.JSON, nullable=False)
135136
created_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc))
136-
updated_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc))
137+
updated_at = sql.Column(sql.DateTime, default=datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
137138

138139
flow_id = sql.Column(sql.Integer, sql.ForeignKey('flows.id'))
139140
flow = relationship('Flow', back_populates='edges')

server/gql/functions.gql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ type Mutation {
6363
# Node
6464
createNode(node: JSON!, nid: String!, flow_id: ID!, workspace_id: ID!, node_type_id: ID!): NodeResult!
6565
updateNode(id: ID, nid: String!, node: JSON, flow_id: ID, workspace_id: ID, node_type_id: ID): NodeResult!
66-
deleteNode(nid: ID!): NodeResult!
66+
deleteNode(nid: String!): NodeResult!
6767

6868
# Edge
6969
createEdge(edge: JSON!, flow_id: ID!, workspace_id: ID!, edge_type_id: ID!): EdgeResult!
70-
updateEdge(id: ID!, edge: JSON, flow_id: ID, workspace_id: ID, edge_type_id: ID): EdgeResult!
71-
deleteEdge(id: ID!): EdgeResult!
70+
updateEdge(id: ID, eid: String!, edge: JSON, flow_id: ID, workspace_id: ID, edge_type_id: ID): EdgeResult!
71+
deleteEdge(eid: ID!): EdgeResult!
7272
}

server/resolvers.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ def getStatus(_, info, **kwargs):
1717
}
1818

1919

20+
# Updated functions
21+
def updateFlowandWorksapceTS(item):
22+
item.flow.updated_at = datetime.now(timezone.utc)
23+
item.workspace.updated_at = datetime.now(timezone.utc)
24+
2025
# Workspace resolvers
2126
@response_handler
2227
def getWorkspace(_, info, **kwargs):
@@ -118,6 +123,8 @@ def createNode(_, info, **kwargs):
118123
node.node = unquote(kwargs.get('node', '{}'))
119124
session.add(node)
120125
session.commit()
126+
updateFlowandWorksapceTS(node)
127+
session.commit()
121128
return {'node': node}
122129

123130
@response_handler
@@ -130,7 +137,9 @@ def updateNode(_, info, **kwargs):
130137

131138
for key, value in kwargs.items():
132139
setattr(node, key, value)
133-
140+
141+
updateFlowandWorksapceTS(node)
142+
134143
session.commit()
135144
return {'node': node}
136145

@@ -156,20 +165,31 @@ def getEdges(_, info, **kwargs):
156165
@response_handler
157166
def createEdge(_, info, **kwargs):
158167
edge = Edge(**kwargs)
168+
edge.edge = loads(unquote(kwargs.get('edge', '{}')))
169+
edge.eid = edge.edge['id']
159170
session.add(edge)
160171
session.commit()
172+
updateFlowandWorksapceTS(edge)
173+
session.commit()
161174
return {'edge': edge}
162175

163176
@response_handler
164177
def updateEdge(_, info, **kwargs):
165-
edge = session.query(Edge).filter_by(id=kwargs.get('id')).first()
178+
edge = session.query(Edge).filter_by(eid=kwargs.get('eid')).first()
179+
180+
if edge_data:= kwargs.pop('edge', None):
181+
edge_data = loads(unquote(edge_data))
182+
kwargs['edge'] = dumps({**loads(edge.edge), **edge_data})
183+
166184
edge.update(**kwargs)
185+
updateFlowandWorksapceTS(edge)
186+
167187
session.commit()
168188
return {'edge': edge}
169189

170190
@response_handler
171191
def deleteEdge(_, info, **kwargs):
172-
edge = session.query(Edge).filter_by(id=kwargs.get('id')).first()
192+
edge = session.query(Edge).filter_by(eid=kwargs.get('eid')).first()
173193
session.delete(edge)
174194
session.commit()
175195
return {'edge': edge}

src/app.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import 'bootstrap/dist/css/bootstrap.css';
21
import './app.css';
2+
import 'bootstrap/dist/css/bootstrap.css';
3+
import { ReactFlowProvider } from 'reactflow';
34
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
45

6+
57
import Home from './home/home';
68
import Designer from './designer/designer';
79
import useWorkspace from './services/use-workspace';
@@ -30,7 +32,11 @@ export default function App() {
3032
/>
3133
<Route
3234
path="/designer"
33-
element={<Designer activeWorkspace={activeWorkspace} flows={flows} />}
35+
element={
36+
<ReactFlowProvider>
37+
<Designer activeWorkspace={activeWorkspace} flows={flows} />
38+
</ReactFlowProvider>
39+
}
3440
/>
3541
</Routes>
3642
</Router>

src/designer/designer.css

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,19 @@ body,
1111
}
1212
.react-flow__controls-button {
1313
flex: 1;
14-
/* width: 20px;
15-
max-width: 20px; */
14+
width: 20px;
15+
height: 20px;
16+
padding: 10px;
17+
background-color: #f8f9fa;
18+
border-color: #f8f9fa;
19+
}
20+
.react-flow__controls-button:hover {
21+
background-color: #e9ecef;
22+
border-color: #dee2e6;
23+
}
24+
.react-flow__controls-button:active {
25+
background-color: #e2e6ea;
26+
border-color: #d3d9df !important;
1627
}
1728
.n-node {
1829
order: 6;
@@ -32,3 +43,39 @@ body,
3243
.react-flow__controls-interactive {
3344
order: 2;
3445
}
46+
.btn-group {
47+
margin-right: 10px;
48+
}
49+
.disabled-btn {
50+
padding: 0px;
51+
padding-left: 1px;
52+
}
53+
.crumb {
54+
/* border-left: 1px solid lightgray; */
55+
/* border-left: 1px solid #a1a5aa; */
56+
}
57+
/* Bootstrap like secondary button styling for buttons with the .modify class */
58+
.modify > .btn {
59+
background-color: #f8f9fa;
60+
border-color: #f8f9fa;
61+
color: #495057;
62+
}
63+
.modify > .btn:hover {
64+
background-color: #e9ecef;
65+
border-color: #dee2e6;
66+
color: #495057;
67+
}
68+
.modify > .btn:active {
69+
background-color: #e2e6ea;
70+
border-color: #d3d9df !important;
71+
color: #495057;
72+
}
73+
.react-flow__minimap > svg {
74+
border-radius: 0.375rem;
75+
}
76+
77+
#root > div > div > div.react-flow__panel.react-flow__controls.bottom.left {
78+
border-radius: 0.375rem;
79+
overflow: hidden;
80+
box-shadow: 0 0 0 0px rgba(0, 0, 0, 0), 0 0px 0px rgba(0, 0, 0, 0);
81+
}

0 commit comments

Comments
 (0)