File size: 2,457 Bytes
0f8b3a0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from abc import ABC
from dataclasses import dataclass
from typing import Any, Generic, TypeVar

from velai.nodes.actions.node_action_decorator import register_annotated_actions
from velai.nodes.actions.node_action_models import AsyncNodeActionResultIterator, NodeActionArguments
from velai.nodes.actions.node_action_registry import NodeActionNotFoundError, NodeActionRegistry
from velai.nodes.base_node import BaseNode, logger
from velai.nodes.vue_nodes import VueNodeData, VueNodeRenderable

T_BASE_NODE = TypeVar("T_BASE_NODE", bound=BaseNode)


@dataclass
class NodeRenderableConfig:
    resizable: bool = True
    min_width: int = 250
    min_height: int = 200
    max_width: int = 720
    max_height: int = 720


class BaseNodeRenderable(VueNodeRenderable[T_BASE_NODE], Generic[T_BASE_NODE], ABC):
    def __init__(self):
        super().__init__()
        self.config = NodeRenderableConfig()

        # create registry and automatically find registered actions
        self.action_registry = NodeActionRegistry()
        register_annotated_actions(self.action_registry, self)

    async def run_custom_action(self, args: NodeActionArguments) -> AsyncNodeActionResultIterator:
        try:
            async for result in self.action_registry.run_action(args):
                yield result
        except NodeActionNotFoundError:
            logger.exception()

    # todo: create actual renderable fields that correspond to the vue components
    def get_header_buttons(self, node: T_BASE_NODE) -> list[dict[str, Any]]:
        return []

    def get_fields(self, node: T_BASE_NODE) -> list[dict[str, Any]]:
        return []

    def get_settings(self, node: T_BASE_NODE) -> list[dict[str, Any]]:
        return []

    def to_vue_node_data(self, node: T_BASE_NODE) -> VueNodeData:
        data = VueNodeData()

        data.title = node.get_display_title()
        data.defaultTitle = node.node_type.display_name
        data.kind = node.node_type.kind.value

        data.headerButtons += self.get_header_buttons(node)
        data.fields += self.get_fields(node)
        data.settings += self.get_settings(node)

        state = node.get_state()
        data.values.update(**state)

        data.resizable = self.config.resizable
        data.min_width = self.config.min_width
        data.min_height_px = self.config.min_height
        data.max_width = self.config.max_width
        data.max_height = self.config.max_height

        return data