Skip to content

Commit

Permalink
Merge pull request #553 from Gencaster/vue-flow-multi
Browse files Browse the repository at this point in the history
Node doors
  • Loading branch information
capital-G authored Sep 10, 2023
2 parents 326527d + 3b59e43 commit a2edff7
Show file tree
Hide file tree
Showing 43 changed files with 3,857 additions and 677 deletions.
7 changes: 6 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ repos:
- id: check-added-large-files
args: ['--maxkb=1024']
- id: check-json
exclude: caster-editor/tsconfig.json
exclude: |
(?x)^(
caster-editor/tsconfig.json|
.vscode/settings.json|
.vscode/extensions.json
)$
- id: check-merge-conflict
- repo: https://github.com/psf/black
rev: 22.3.0
Expand Down
4 changes: 3 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"recommendations": [
"Vue.volar",
"Vue.vscode-typescript-vue-plugin"
"Vue.vscode-typescript-vue-plugin",
"ms-python.mypy-type-checker",
"ms-python.python",
]
}
8 changes: 6 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"python.analysis.typeCheckingMode": "basic",
// "python.analysis.typeCheckingMode": "basic",
"mypy-type-checker.args": [
"--config-file=${workspaceFolder}/caster-back/setup.cfg"
],
"cSpell.words": [
"Gencaster",
"pythonosc",
Expand All @@ -14,5 +17,6 @@
"javascript",
"javascriptreact",
"vue"
]
],
"python.analysis.typeCheckingMode": "basic"
}
102 changes: 82 additions & 20 deletions caster-back/gencaster/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,22 @@
from story_graph.types import (
AddGraphInput,
AudioCellInput,
Edge,
EdgeInput,
Graph,
GraphFilter,
InvalidPythonCode,
Node,
NodeCreate,
NodeDoor,
NodeDoorInputCreate,
NodeDoorInputUpdate,
NodeDoorResponse,
NodeUpdate,
ScriptCell,
ScriptCellInputCreate,
ScriptCellInputUpdate,
create_python_highlight_string,
)
from stream.exceptions import NoStreamAvailableException
from stream.frontend_types import Dialog
Expand Down Expand Up @@ -275,29 +282,27 @@ async def update_node(self, info: Info, node_update: NodeUpdate) -> None:
return None

@strawberry.mutation
async def add_edge(self, info: Info, new_edge: EdgeInput) -> None:
async def add_edge(self, info: Info, new_edge: EdgeInput) -> Edge:
"""Creates a :class:`~story_graph.models.Edge` for a given
:class:`~story_graph.models.Graph`.
It does not return the created edge.
It returns the created edge.
"""
await graphql_check_authenticated(info)
in_node: story_graph_models.Node = (
await story_graph_models.Node.objects.select_related("graph").aget(
uuid=new_edge.node_in_uuid
)
)
out_node: story_graph_models.Node = await story_graph_models.Node.objects.aget(
uuid=new_edge.node_out_uuid
in_node_door = await story_graph_models.NodeDoor.objects.select_related(
"node__graph"
).aget(uuid=new_edge.node_door_in_uuid)
out_node_door = await story_graph_models.NodeDoor.objects.aget(
uuid=new_edge.node_door_out_uuid
)
edge: story_graph_models.Edge = await story_graph_models.Edge.objects.acreate(
in_node=in_node,
out_node=out_node,
edge = await story_graph_models.Edge.objects.acreate(
in_node_door=in_node_door,
out_node_door=out_node_door,
)
await GenCasterChannel.send_graph_update(
layer=info.context.channel_layer,
graph_uuid=in_node.graph.uuid,
graph_uuid=in_node_door.node.graph.uuid,
)
return None
return edge # type: ignore

@strawberry.mutation
async def delete_edge(self, info, edge_uuid: uuid.UUID) -> None:
Expand All @@ -306,16 +311,17 @@ async def delete_edge(self, info, edge_uuid: uuid.UUID) -> None:
try:
edge: story_graph_models.Edge = (
await story_graph_models.Edge.objects.select_related(
"in_node__graph"
"in_node_door__node__graph"
).aget(uuid=edge_uuid)
)
await story_graph_models.Edge.objects.filter(uuid=edge_uuid).adelete()
except Exception:
raise Exception(f"Could not delete edge {edge_uuid}")
await GenCasterChannel.send_graph_update(
layer=info.context.channel_layer,
graph_uuid=edge.in_node.graph.uuid,
)
if edge.in_node_door:
await GenCasterChannel.send_graph_update(
layer=info.context.channel_layer,
graph_uuid=edge.in_node_door.node.graph.uuid,
)
return None

@strawberry.mutation
Expand Down Expand Up @@ -528,6 +534,62 @@ async def create_update_stream_variable(

return stream_vars # type: ignore

@strawberry.mutation
async def create_node_door(
self,
info,
node_door_input: NodeDoorInputCreate,
node_uuid: uuid.UUID,
) -> NodeDoor:
await graphql_check_authenticated(info)
node = await story_graph_models.Node.objects.aget(uuid=node_uuid)
return await story_graph_models.NodeDoor.objects.acreate(
door_type=node_door_input.door_type,
node=node,
name=node_door_input.name,
order=node_door_input.order,
code=node_door_input.code,
) # type: ignore

@strawberry.mutation
async def update_node_door(
self,
info,
node_door_input: NodeDoorInputUpdate,
) -> NodeDoorResponse:
await graphql_check_authenticated(info)
node_door = await story_graph_models.NodeDoor.objects.aget(
uuid=node_door_input.uuid
)
node_door.door_type = node_door_input.door_type
if node_door_input.code:
node_door.code = node_door_input.code
if node_door_input.name:
node_door.name = node_door_input.name
if node_door_input.order:
node_door.order = node_door_input.order
try:
await node_door.asave()
except SyntaxError as e:
return InvalidPythonCode(
error_type=e.msg,
error_code=e.text if e.text else "",
error_message=create_python_highlight_string(e),
)
return node_door # type: ignore

@strawberry.mutation
async def delete_node_door(self, info, node_door_uuid: uuid.UUID) -> bool:
"""Allows to delete a non-default NodeDoor.
If a node door was deleted it will return ``True``, otherwise ``False``.
"""
await graphql_check_authenticated(info)
deleted_objects, _ = await story_graph_models.NodeDoor.objects.filter(
is_default=False,
uuid=node_door_uuid,
).adelete()
return deleted_objects >= 1


@strawberry.type
class Subscription:
Expand Down Expand Up @@ -656,7 +718,7 @@ async def get_streams() -> List[Stream]:
async for stream in stream_models.Stream.objects.order_by("-created_date")[
0:limit
]:
streams_db.append(stream)
streams_db.append(stream) # type: ignore
return streams_db

yield await get_streams()
Expand Down
14 changes: 8 additions & 6 deletions caster-back/gencaster/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,18 @@ async def test_add_edge(self):
out_node: Node = await sync_to_async(NodeTestCase.get_node)(graph=graph)

mutation = """
mutation TestMutation($nodeInUuid:UUID!, $nodeOutUuid:UUID!) {
addEdge(newEdge: {nodeInUuid: $nodeInUuid, nodeOutUuid: $nodeOutUuid})
mutation TestMutation($nodeDoorInUuid:UUID!, $nodeDoorOutUuid:UUID!) {
addEdge(newEdge: {nodeDoorInUuid: $nodeDoorInUuid, nodeDoorOutUuid: $nodeDoorOutUuid}) {
uuid
}
}
"""

resp = await schema.execute(
mutation,
variable_values={
"nodeInUuid": str(in_node.uuid),
"nodeOutUuid": str(out_node.uuid),
"nodeDoorInUuid": str((await in_node.aget_default_in_door()).uuid),
"nodeDoorOutUuid": str((await out_node.aget_default_out_door()).uuid),
},
context_value=self.get_login_context(),
)
Expand All @@ -137,8 +139,8 @@ async def test_add_edge(self):
self.assertEqual(await Edge.objects.all().acount(), 1)

edge: Edge = await Edge.objects.all().afirst() # type: ignore
self.assertEqual(await sync_to_async(lambda: edge.in_node)(), in_node)
self.assertEqual(await sync_to_async(lambda: edge.out_node)(), out_node)
self.assertEqual((await sync_to_async(lambda: edge.in_node_door.node)()).uuid, in_node.uuid) # type: ignore
self.assertEqual((await sync_to_async(lambda: edge.out_node_door.node)()).uuid, out_node.uuid) # type: ignore

GRAPH_QUERY = """
query TestQuery {
Expand Down
3 changes: 1 addition & 2 deletions caster-back/gencaster/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.http import HttpRequest
from django.shortcuts import HttpResponse
from django.http import HttpRequest, HttpResponse
from django.urls import path
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
Expand Down
75 changes: 69 additions & 6 deletions caster-back/operations.gql
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ query GetGraphsMeta($slug: String!) {
}
}

mutation createEdge($nodeInUuid:UUID!, $nodeOutUuid:UUID!) {
addEdge(newEdge: {nodeInUuid: $nodeInUuid, nodeOutUuid: $nodeOutUuid})
mutation createEdge($nodeDoorInUuid:UUID!, $nodeDoorOutUuid:UUID!) {
addEdge(newEdge: {nodeDoorInUuid: $nodeDoorInUuid, nodeDoorOutUuid: $nodeDoorOutUuid}) {
uuid
}
}

mutation createNode($name: String!, $graphUuid: UUID!, $color: String, $positionX: Float, $positionY: Float) {
Expand Down Expand Up @@ -112,18 +114,28 @@ mutation deleteScriptCell($scriptCellUuid:UUID!) {
deleteScriptCell(scriptCellUuid: $scriptCellUuid)
}

fragment NodeDoorBasic on NodeDoor {
uuid
name
order
isDefault
node {
uuid
}
}

subscription graph($uuid: UUID!) {
graph(graphUuid: $uuid) {
name
slugName
uuid
edges {
uuid
outNode {
uuid
inNodeDoor {
...NodeDoorBasic
}
inNode {
uuid
outNodeDoor {
...NodeDoorBasic
}
}
nodes {
Expand All @@ -138,12 +150,33 @@ subscription graph($uuid: UUID!) {
positionX
positionY
color
inNodeDoors {
...NodeDoorBasic
}
outNodeDoors {
...NodeDoorBasic
}
}
}
}

fragment NodeDoorDetail on NodeDoor {
uuid
name
order
isDefault
code
doorType
}

subscription node($uuid: UUID!) {
node(nodeUuid: $uuid) {
inNodeDoors {
...NodeDoorDetail
}
outNodeDoors {
...NodeDoorDetail
}
color
name
positionX
Expand Down Expand Up @@ -356,3 +389,33 @@ subscription StreamLogs($streamUuid: UUID, $streamPointUuid: UUID) {
}
}
}

mutation createNodeDoor($nodeUuid: UUID!, $name: String!, $code: String! = "", $doorType: DoorType = OUTPUT, $order: Int) {
createNodeDoor(
nodeDoorInput: {name: $name, code: $code, doorType: $doorType, order: $order}
nodeUuid: $nodeUuid
) {
uuid
}
}

mutation deleteNodeDoor($nodeDoorUuid: UUID!) {
deleteNodeDoor(nodeDoorUuid: $nodeDoorUuid)
}

mutation updateNodeDoor($uuid: UUID!, $name: String, $code: String, $order: Int) {
updateNodeDoor(
nodeDoorInput: {name: $name, code: $code, order: $order, uuid: $uuid}
) {
... on NodeDoor {
__typename
uuid
}
... on InvalidPythonCode {
__typename
errorCode
errorMessage
errorType
}
}
}
1 change: 1 addition & 0 deletions caster-back/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ mistletoe==1.0.1
pydantic==1.10.7
channels-redis==4.1.0
sentry-sdk==1.29.0
django-stubs-ext==4.2.2
Loading

0 comments on commit a2edff7

Please sign in to comment.