nova-trame 0.19.1__py3-none-any.whl → 0.20.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nova/trame/view/components/execution_buttons.py +109 -0
- nova/trame/view/components/input_field.py +1 -1
- nova/trame/view/components/progress_bar.py +62 -0
- nova/trame/view/components/tool_outputs.py +60 -0
- nova/trame/view/theme/assets/core_style.scss +11 -3
- nova/trame/view_model/execution_buttons.py +87 -0
- nova/trame/view_model/progress_bar.py +75 -0
- nova/trame/view_model/tool_outputs.py +23 -0
- {nova_trame-0.19.1.dist-info → nova_trame-0.20.0.dist-info}/METADATA +3 -1
- {nova_trame-0.19.1.dist-info → nova_trame-0.20.0.dist-info}/RECORD +13 -7
- {nova_trame-0.19.1.dist-info → nova_trame-0.20.0.dist-info}/WHEEL +1 -1
- {nova_trame-0.19.1.dist-info → nova_trame-0.20.0.dist-info}/LICENSE +0 -0
- {nova_trame-0.19.1.dist-info → nova_trame-0.20.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,109 @@
|
|
1
|
+
"""Module for the Progress Tab."""
|
2
|
+
|
3
|
+
from trame.app import get_server
|
4
|
+
from trame.widgets import client
|
5
|
+
from trame.widgets import vuetify3 as vuetify
|
6
|
+
from trame_client.widgets import html
|
7
|
+
|
8
|
+
from nova.mvvm.trame_binding import TrameBinding
|
9
|
+
from nova.trame.view_model.execution_buttons import ExecutionButtonsViewModel
|
10
|
+
|
11
|
+
|
12
|
+
class ExecutionButtons:
|
13
|
+
"""Execution buttons class. Adds Run/Stop/Cancel/Download buttons to the view."""
|
14
|
+
|
15
|
+
def __init__(self, id: str, stop_btn: bool = False, download_btn: bool = False) -> None:
|
16
|
+
"""Constructor for ExecutionButtons.
|
17
|
+
|
18
|
+
Parameters
|
19
|
+
----------
|
20
|
+
id : str
|
21
|
+
Component id. Should be used consistently with ToolRunner and other components
|
22
|
+
stop_btn: bool
|
23
|
+
Display stop button.
|
24
|
+
download_btn : bool
|
25
|
+
Display download button.
|
26
|
+
|
27
|
+
Returns
|
28
|
+
-------
|
29
|
+
None
|
30
|
+
"""
|
31
|
+
self.id = f"execution_{id}"
|
32
|
+
|
33
|
+
self.server = get_server(None, client_type="vue3")
|
34
|
+
binding = TrameBinding(self.server.state)
|
35
|
+
self.ctrl = self.server.controller
|
36
|
+
self.stop_btn = stop_btn
|
37
|
+
self.download_btn = download_btn
|
38
|
+
self.view_model = ExecutionButtonsViewModel(id, binding)
|
39
|
+
self.view_model.buttons_state_bind.connect(self.id)
|
40
|
+
self._download = client.JSEval(
|
41
|
+
exec=(
|
42
|
+
"async ($event) => {"
|
43
|
+
" const blob = new window.Blob([$event], {type: 'application/zip'});"
|
44
|
+
" const url = window.URL.createObjectURL(blob);"
|
45
|
+
" const anchor = window.document.createElement('a');"
|
46
|
+
" anchor.setAttribute('href', url);"
|
47
|
+
" anchor.setAttribute('download', 'results.zip');"
|
48
|
+
" window.document.body.appendChild(anchor);"
|
49
|
+
" anchor.click();"
|
50
|
+
" window.document.body.removeChild(anchor);"
|
51
|
+
" setTimeout(() => window.URL.revokeObjectURL(url), 1000);"
|
52
|
+
"}"
|
53
|
+
)
|
54
|
+
).exec
|
55
|
+
|
56
|
+
self.create_ui()
|
57
|
+
|
58
|
+
def create_ui(self) -> None:
|
59
|
+
with html.Div(classes="d-flex justify-center my-4 w-100"):
|
60
|
+
vuetify.VBtn(
|
61
|
+
"Run",
|
62
|
+
disabled=(f"{self.id}.run_disabled",),
|
63
|
+
prepend_icon="mdi-play",
|
64
|
+
classes="mr-4",
|
65
|
+
id=f"{self.id}_run",
|
66
|
+
click=self.run,
|
67
|
+
)
|
68
|
+
if self.stop_btn:
|
69
|
+
vuetify.VBtn(
|
70
|
+
"Stop",
|
71
|
+
disabled=(f"{self.id}.stop_disabled",),
|
72
|
+
loading=(f"{self.id}.stop_in_progress",),
|
73
|
+
classes="mr-4",
|
74
|
+
id=f"{self.id}_stop",
|
75
|
+
prepend_icon="mdi-stop",
|
76
|
+
click=self.stop,
|
77
|
+
)
|
78
|
+
vuetify.VBtn(
|
79
|
+
"Cancel",
|
80
|
+
disabled=(f"{self.id}.cancel_disabled",),
|
81
|
+
color="error",
|
82
|
+
loading=(f"{self.id}.cancel_in_progress",),
|
83
|
+
prepend_icon="mdi-cancel",
|
84
|
+
classes="mr-4",
|
85
|
+
id=f"{self.id}_cancel",
|
86
|
+
click=self.cancel,
|
87
|
+
)
|
88
|
+
if self.download_btn:
|
89
|
+
vuetify.VBtn(
|
90
|
+
"Download Results",
|
91
|
+
disabled=(f"{self.id}.download_disabled",),
|
92
|
+
loading=(f"{self.id}.download_in_progress",),
|
93
|
+
id=f"{self.id}.download",
|
94
|
+
click=self.download,
|
95
|
+
)
|
96
|
+
|
97
|
+
async def download(self) -> None:
|
98
|
+
content = await self.view_model.prepare_results()
|
99
|
+
if content:
|
100
|
+
self._download(content)
|
101
|
+
|
102
|
+
async def run(self) -> None:
|
103
|
+
await self.view_model.run()
|
104
|
+
|
105
|
+
async def cancel(self) -> None:
|
106
|
+
await self.view_model.cancel()
|
107
|
+
|
108
|
+
async def stop(self) -> None:
|
109
|
+
await self.view_model.stop()
|
@@ -0,0 +1,62 @@
|
|
1
|
+
"""Module for the Progress Tab."""
|
2
|
+
|
3
|
+
from trame.app import get_server
|
4
|
+
from trame.widgets import vuetify3 as vuetify
|
5
|
+
from trame_client.widgets import html
|
6
|
+
|
7
|
+
from nova.mvvm.trame_binding import TrameBinding
|
8
|
+
from nova.trame.view_model.progress_bar import ProgressBarViewModel
|
9
|
+
|
10
|
+
|
11
|
+
class ProgressBar:
|
12
|
+
"""Progress bar class. Adds progress bar that displays job status to the view."""
|
13
|
+
|
14
|
+
def __init__(self, id: str) -> None:
|
15
|
+
"""Constructor for ProgressBar.
|
16
|
+
|
17
|
+
Parameters
|
18
|
+
----------
|
19
|
+
id : str
|
20
|
+
Component id. Should be used consistently with ToolRunner and other components
|
21
|
+
|
22
|
+
Returns
|
23
|
+
-------
|
24
|
+
None
|
25
|
+
"""
|
26
|
+
self.id = f"progress_bar_{id}"
|
27
|
+
self.create_viewmodel(id)
|
28
|
+
self.view_model.progress_state_bind.connect(self.id)
|
29
|
+
self.create_ui()
|
30
|
+
|
31
|
+
def create_viewmodel(self, id: str) -> None:
|
32
|
+
server = get_server(None, client_type="vue3")
|
33
|
+
binding = TrameBinding(server.state)
|
34
|
+
self.view_model = ProgressBarViewModel(id, binding)
|
35
|
+
|
36
|
+
def create_ui(self) -> None:
|
37
|
+
with vuetify.VProgressLinear(
|
38
|
+
height="25",
|
39
|
+
model_value=(f"{self.id}.progress", "0"),
|
40
|
+
striped=True,
|
41
|
+
id=f"{self.id}_show_progress",
|
42
|
+
v_show=(f"{self.id}.show_progress",),
|
43
|
+
):
|
44
|
+
html.H5(v_text=f"{self.id}.details")
|
45
|
+
with vuetify.VProgressLinear(
|
46
|
+
height="25",
|
47
|
+
model_value="100",
|
48
|
+
striped=False,
|
49
|
+
color="error",
|
50
|
+
id=f"{self.id}_show_failed",
|
51
|
+
v_show=(f"{self.id}.show_failed",),
|
52
|
+
):
|
53
|
+
html.H5(v_text=f"{self.id}.details", classes="text-white")
|
54
|
+
with vuetify.VProgressLinear(
|
55
|
+
height="25",
|
56
|
+
model_value="100",
|
57
|
+
striped=False,
|
58
|
+
color="primary",
|
59
|
+
id=f"{self.id}_show_ok",
|
60
|
+
v_show=(f"{self.id}.show_ok",),
|
61
|
+
):
|
62
|
+
html.H5(v_text=f"{self.id}.details", classes="text-white")
|
@@ -0,0 +1,60 @@
|
|
1
|
+
"""Module for the Tool outputs."""
|
2
|
+
|
3
|
+
from trame.app import get_server
|
4
|
+
from trame.widgets import vuetify3 as vuetify
|
5
|
+
|
6
|
+
from nova.mvvm.trame_binding import TrameBinding
|
7
|
+
from nova.trame.view.components import InputField
|
8
|
+
from nova.trame.view.layouts import HBoxLayout
|
9
|
+
from nova.trame.view_model.tool_outputs import ToolOutputsViewModel
|
10
|
+
|
11
|
+
|
12
|
+
class ToolOutputWindows:
|
13
|
+
"""Tool outputs class. Displays windows with tool stdout/stderr."""
|
14
|
+
|
15
|
+
def __init__(self, id: str) -> None:
|
16
|
+
"""Constructor for ToolOutputWindows.
|
17
|
+
|
18
|
+
Parameters
|
19
|
+
----------
|
20
|
+
id : str
|
21
|
+
Component id. Should be used consistently with ToolRunner and other components
|
22
|
+
|
23
|
+
Returns
|
24
|
+
-------
|
25
|
+
None
|
26
|
+
"""
|
27
|
+
self.id = f"tool_outputs_{id}"
|
28
|
+
self.create_viewmodel(id)
|
29
|
+
self.view_model.tool_outputs_bind.connect(self.id)
|
30
|
+
self.create_ui()
|
31
|
+
|
32
|
+
def create_viewmodel(self, id: str) -> None:
|
33
|
+
server = get_server(None, client_type="vue3")
|
34
|
+
binding = TrameBinding(server.state)
|
35
|
+
self.view_model = ToolOutputsViewModel(id, binding)
|
36
|
+
|
37
|
+
def create_ui(self) -> None:
|
38
|
+
with HBoxLayout(classes="d-flex", width="100%"):
|
39
|
+
with vuetify.VTabs(v_model=(f"{self.id}_active_output_tab", "1"), direction="vertical"):
|
40
|
+
vuetify.VTab("Console output", value=1)
|
41
|
+
vuetify.VTab("Console error", value=2)
|
42
|
+
with HBoxLayout(classes="flex-grow-1"):
|
43
|
+
InputField(
|
44
|
+
v_show=f"{self.id}_active_output_tab === '1'",
|
45
|
+
v_model=f"{self.id}.stdout",
|
46
|
+
id=f"{self.id}_outputs",
|
47
|
+
type="autoscroll",
|
48
|
+
auto_grow=True,
|
49
|
+
readonly=True,
|
50
|
+
max_rows="30",
|
51
|
+
)
|
52
|
+
InputField(
|
53
|
+
v_show=f"{self.id}_active_output_tab === '2'",
|
54
|
+
v_model=f"{self.id}.stderr",
|
55
|
+
id=f"{self.id}_errors",
|
56
|
+
type="autoscroll",
|
57
|
+
auto_grow=True,
|
58
|
+
readonly=True,
|
59
|
+
max_rows="30",
|
60
|
+
)
|
@@ -130,10 +130,14 @@ html {
|
|
130
130
|
min-width: 0px !important;
|
131
131
|
padding: 5px 5px !important;
|
132
132
|
box-shadow: none !important;
|
133
|
-
}
|
134
133
|
|
135
|
-
|
136
|
-
|
134
|
+
.v-btn__content {
|
135
|
+
text-transform: none;
|
136
|
+
}
|
137
|
+
|
138
|
+
.v-btn__prepend {
|
139
|
+
margin-left: 1px;
|
140
|
+
}
|
137
141
|
}
|
138
142
|
|
139
143
|
.v-label {
|
@@ -145,6 +149,10 @@ html {
|
|
145
149
|
padding: 5px;
|
146
150
|
}
|
147
151
|
|
152
|
+
textarea.v-field__input {
|
153
|
+
mask-image: none !important;
|
154
|
+
}
|
155
|
+
|
148
156
|
.v-field {
|
149
157
|
margin: 8px 4px 8px 4px;
|
150
158
|
}
|
@@ -0,0 +1,87 @@
|
|
1
|
+
"""Module for the JobProgress ViewModel."""
|
2
|
+
|
3
|
+
import asyncio
|
4
|
+
from typing import Any, Optional
|
5
|
+
|
6
|
+
import blinker
|
7
|
+
from pydantic import BaseModel
|
8
|
+
|
9
|
+
from nova.common.job import WorkState
|
10
|
+
from nova.common.signals import Signal, ToolCommand, get_signal_id
|
11
|
+
from nova.mvvm.interface import BindingInterface
|
12
|
+
|
13
|
+
|
14
|
+
def job_running(status: WorkState) -> bool:
|
15
|
+
"""A helper function to check if job is doing something in Galaxy."""
|
16
|
+
return status in [
|
17
|
+
WorkState.UPLOADING_DATA,
|
18
|
+
WorkState.QUEUED,
|
19
|
+
WorkState.RUNNING,
|
20
|
+
WorkState.STOPPING,
|
21
|
+
WorkState.CANCELING,
|
22
|
+
]
|
23
|
+
|
24
|
+
|
25
|
+
class ButtonsState(BaseModel):
|
26
|
+
"""Class that manages start/stop/cancel button states."""
|
27
|
+
|
28
|
+
run_disabled: bool = False
|
29
|
+
cancel_disabled: bool = True
|
30
|
+
stop_disabled: bool = True
|
31
|
+
download_disabled: bool = True
|
32
|
+
|
33
|
+
stop_in_progress: bool = False
|
34
|
+
cancel_in_progress: bool = False
|
35
|
+
download_in_progress: bool = False
|
36
|
+
|
37
|
+
def update_from_workstate(self, status: WorkState) -> None:
|
38
|
+
running = job_running(status)
|
39
|
+
self.run_disabled = running
|
40
|
+
self.cancel_disabled = not running
|
41
|
+
self.stop_disabled = status not in [WorkState.RUNNING, WorkState.STOPPING]
|
42
|
+
self.stop_in_progress = status == WorkState.STOPPING
|
43
|
+
self.cancel_in_progress = status == WorkState.CANCELING
|
44
|
+
self.download_disabled = status != WorkState.FINISHED
|
45
|
+
|
46
|
+
|
47
|
+
class ExecutionButtonsViewModel:
|
48
|
+
"""A viewmodel responsible for execution buttons."""
|
49
|
+
|
50
|
+
def __init__(self, id: str, binding: BindingInterface):
|
51
|
+
self.sender_id = f"ExecutionButtonsViewModel_{id}"
|
52
|
+
self.button_states = ButtonsState()
|
53
|
+
self.buttons_state_bind = binding.new_bind(self.button_states)
|
54
|
+
self.execution_signal = blinker.signal(get_signal_id(id, Signal.TOOL_COMMAND))
|
55
|
+
self.progress_signal = blinker.signal(get_signal_id(id, Signal.PROGRESS))
|
56
|
+
self.progress_signal.connect(self.update_state, weak=False)
|
57
|
+
|
58
|
+
async def update_state(self, _sender: Any, state: WorkState, details: str) -> None:
|
59
|
+
self.button_states.update_from_workstate(state)
|
60
|
+
self.buttons_state_bind.update_in_view(self.button_states)
|
61
|
+
|
62
|
+
async def run(self) -> None:
|
63
|
+
# disable run now since it might take some time before the client updates the status
|
64
|
+
self.button_states.run_disabled = True
|
65
|
+
self.buttons_state_bind.update_in_view(self.button_states)
|
66
|
+
await self.execution_signal.send_async(self.sender_id, command=ToolCommand.START)
|
67
|
+
|
68
|
+
async def cancel(self) -> None:
|
69
|
+
await self.execution_signal.send_async(self.sender_id, command=ToolCommand.CANCEL)
|
70
|
+
|
71
|
+
async def stop(self) -> None:
|
72
|
+
await self.execution_signal.send_async(self.sender_id, command=ToolCommand.CANCEL)
|
73
|
+
|
74
|
+
async def prepare_results(self) -> Optional[bytes]:
|
75
|
+
self.button_states.download_in_progress = True
|
76
|
+
self.buttons_state_bind.update_in_view(self.button_states)
|
77
|
+
await asyncio.sleep(0.5) # to give Trame time to update view
|
78
|
+
responses = await self.execution_signal.send_async(self.sender_id, command=ToolCommand.GET_RESULTS)
|
79
|
+
res = None
|
80
|
+
for response in responses: # responses can come from multiple places
|
81
|
+
if response[1] is None:
|
82
|
+
continue
|
83
|
+
if response[1]["sender"] == self.sender_id and response[1]["command"] == ToolCommand.GET_RESULTS:
|
84
|
+
res = response[1]["results"]
|
85
|
+
self.button_states.download_in_progress = False
|
86
|
+
self.buttons_state_bind.update_in_view(self.button_states)
|
87
|
+
return res
|
@@ -0,0 +1,75 @@
|
|
1
|
+
"""Module for the JobProgress ViewModel."""
|
2
|
+
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
import blinker
|
6
|
+
from pydantic import BaseModel
|
7
|
+
|
8
|
+
from nova.common.job import WorkState
|
9
|
+
from nova.common.signals import Signal, get_signal_id
|
10
|
+
from nova.mvvm.interface import BindingInterface
|
11
|
+
|
12
|
+
|
13
|
+
def details_from_state(state: WorkState) -> str:
|
14
|
+
work_state_map = {
|
15
|
+
WorkState.NOT_STARTED: "job not started",
|
16
|
+
WorkState.UPLOADING_DATA: "uploading data",
|
17
|
+
WorkState.QUEUED: "job is queued",
|
18
|
+
WorkState.RUNNING: "job is running",
|
19
|
+
WorkState.FINISHED: "job finished",
|
20
|
+
WorkState.ERROR: "job produced an error",
|
21
|
+
WorkState.DELETED: "job deleted",
|
22
|
+
WorkState.CANCELED: "job canceled",
|
23
|
+
WorkState.STOPPING: "stopping job",
|
24
|
+
WorkState.CANCELING: "canceling job",
|
25
|
+
}
|
26
|
+
if state in work_state_map:
|
27
|
+
return work_state_map[state]
|
28
|
+
else:
|
29
|
+
return state.value
|
30
|
+
|
31
|
+
|
32
|
+
class ProgressState(BaseModel):
|
33
|
+
"""Class that manages progress bars states."""
|
34
|
+
|
35
|
+
progress: str = ""
|
36
|
+
details: str = ""
|
37
|
+
show_progress: bool = False
|
38
|
+
show_failed: bool = False
|
39
|
+
show_ok: bool = False
|
40
|
+
|
41
|
+
def update_from_workstate(self, state: WorkState) -> None:
|
42
|
+
progress = "0"
|
43
|
+
match state:
|
44
|
+
case WorkState.UPLOADING_DATA:
|
45
|
+
progress = "10"
|
46
|
+
case WorkState.QUEUED:
|
47
|
+
progress = "20"
|
48
|
+
case WorkState.RUNNING:
|
49
|
+
progress = "50"
|
50
|
+
|
51
|
+
self.show_progress = state in [
|
52
|
+
WorkState.UPLOADING_DATA,
|
53
|
+
WorkState.QUEUED,
|
54
|
+
WorkState.RUNNING,
|
55
|
+
WorkState.CANCELING,
|
56
|
+
WorkState.STOPPING,
|
57
|
+
]
|
58
|
+
self.show_failed = state == WorkState.ERROR
|
59
|
+
self.show_ok = state == WorkState.FINISHED
|
60
|
+
self.progress = progress
|
61
|
+
self.details = details_from_state(state)
|
62
|
+
|
63
|
+
|
64
|
+
class ProgressBarViewModel:
|
65
|
+
"""A viewmodel responsible for progress bar."""
|
66
|
+
|
67
|
+
def __init__(self, id: str, binding: BindingInterface):
|
68
|
+
self.progress_state = ProgressState()
|
69
|
+
self.progress_state_bind = binding.new_bind(self.progress_state)
|
70
|
+
self.progress_signal = blinker.signal(get_signal_id(id, Signal.PROGRESS))
|
71
|
+
self.progress_signal.connect(self.update_state, weak=False)
|
72
|
+
|
73
|
+
async def update_state(self, _sender: Any, state: WorkState, details: str) -> None:
|
74
|
+
self.progress_state.update_from_workstate(state)
|
75
|
+
self.progress_state_bind.update_in_view(self.progress_state)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"""Module for the Tool ouputs ViewModel."""
|
2
|
+
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
import blinker
|
6
|
+
|
7
|
+
from nova.common.job import ToolOutputs
|
8
|
+
from nova.common.signals import Signal, get_signal_id
|
9
|
+
from nova.mvvm.interface import BindingInterface
|
10
|
+
|
11
|
+
|
12
|
+
class ToolOutputsViewModel:
|
13
|
+
"""A viewmodel responsible for tool stdout and stderr."""
|
14
|
+
|
15
|
+
def __init__(self, id: str, binding: BindingInterface):
|
16
|
+
self.tool_outputs = ToolOutputs()
|
17
|
+
self.tool_outputs_bind = binding.new_bind(self.tool_outputs)
|
18
|
+
self.outputs_signal = blinker.signal(get_signal_id(id, Signal.OUTPUTS))
|
19
|
+
self.outputs_signal.connect(self.on_outputs_update, weak=False)
|
20
|
+
|
21
|
+
async def on_outputs_update(self, _sender: Any, outputs: ToolOutputs) -> None:
|
22
|
+
self.tool_outputs = outputs
|
23
|
+
self.tool_outputs_bind.update_in_view(self.tool_outputs)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: nova-trame
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.20.0
|
4
4
|
Summary: A Python Package for injecting curated themes and custom components into Trame applications
|
5
5
|
License: MIT
|
6
6
|
Keywords: NDIP,Python,Trame,Vuetify
|
@@ -14,8 +14,10 @@ Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
16
16
|
Requires-Dist: altair
|
17
|
+
Requires-Dist: blinker (>=1.9.0,<2.0.0)
|
17
18
|
Requires-Dist: libsass
|
18
19
|
Requires-Dist: mergedeep
|
20
|
+
Requires-Dist: nova-common (>=0.2.0)
|
19
21
|
Requires-Dist: nova-mvvm
|
20
22
|
Requires-Dist: pydantic
|
21
23
|
Requires-Dist: tomli
|
@@ -4,9 +4,12 @@ nova/trame/model/data_selector.py,sha256=sCLU0YIMCccC1BH8dKZPmajaft6WgwuM_zOr3NP
|
|
4
4
|
nova/trame/model/remote_file_input.py,sha256=9KAf31ZHzpsh_aXUrNcF81Q5jvUZDWCzW1QATKls-Jk,3675
|
5
5
|
nova/trame/view/components/__init__.py,sha256=u8yzshFp_TmuC1g9TRxKjy_BdGWMIzPQouI52hzcr2U,234
|
6
6
|
nova/trame/view/components/data_selector.py,sha256=UFQriSH25wk3F4s6EnP5Dfrt3MFbisJTrzmRxH0ME8U,8831
|
7
|
+
nova/trame/view/components/execution_buttons.py,sha256=wXpgF6osuAivKKnby8yCevoFa4PbRlCtUgEymjiugzE,3857
|
7
8
|
nova/trame/view/components/file_upload.py,sha256=7VcpfA6zmiqMDLkwVPlb35Tf0IUTBN1xsHpoUFnSr1w,3111
|
8
|
-
nova/trame/view/components/input_field.py,sha256=
|
9
|
+
nova/trame/view/components/input_field.py,sha256=q6WQ_N-BOlimUL9zgazDlsDfK28FrrKjH4he8e_HzRA,16088
|
10
|
+
nova/trame/view/components/progress_bar.py,sha256=vva_blYZwF1xJt72sCBSbJB5HloyTy39UoVOP_ixs_E,1995
|
9
11
|
nova/trame/view/components/remote_file_input.py,sha256=ByrBFj8svyWezcardCWrS_4Ag3fgTYNg_11lDW1FIA8,9669
|
12
|
+
nova/trame/view/components/tool_outputs.py,sha256=IlpvJJuVZ6o9WMXW1Hpsvca7Xw1AxO83fdr_JFcYnbA,2146
|
10
13
|
nova/trame/view/components/visualization/__init__.py,sha256=reqkkbhD5uSksHHlhVMy1qNUCwSekS5HlXk6wCREYxU,152
|
11
14
|
nova/trame/view/components/visualization/interactive_2d_plot.py,sha256=foZCMoqbuahT5dtqIQvm8C4ZJcY9P211eJEcpQJltmM,3421
|
12
15
|
nova/trame/view/components/visualization/matplotlib_figure.py,sha256=0iWCXB8i7Tut1gA66hY9cGrhZPaHC7p-XdADDNy_UVY,12042
|
@@ -16,7 +19,7 @@ nova/trame/view/layouts/hbox.py,sha256=qlOMp_iOropIkC9Jxa6D89b7OPv0pNvJ73tUEzddy
|
|
16
19
|
nova/trame/view/layouts/utils.py,sha256=Hg34VQWTG3yHBsgNvmfatR4J-uL3cko7UxSJpT-h3JI,376
|
17
20
|
nova/trame/view/layouts/vbox.py,sha256=hzhzPu99R2fAclMe-FwHZseJWk7iailZ31bKdGhi1hk,3514
|
18
21
|
nova/trame/view/theme/__init__.py,sha256=70_marDlTigIcPEOGiJb2JTs-8b2sGM5SlY7XBPtBDM,54
|
19
|
-
nova/trame/view/theme/assets/core_style.scss,sha256=
|
22
|
+
nova/trame/view/theme/assets/core_style.scss,sha256=5i2cZQbmaQTpcNgsaVRdcubh0HHidqPnnLj8McHNkbY,3367
|
20
23
|
nova/trame/view/theme/assets/favicon.png,sha256=Xbp1nUmhcBDeObjsebEbEAraPDZ_M163M_ZLtm5AbQc,1927
|
21
24
|
nova/trame/view/theme/assets/js/delay_manager.js,sha256=vmb34DZ5YCQIlRW9Tf2M_uvJW6HFCmtlKZ5e_TPR8yg,536
|
22
25
|
nova/trame/view/theme/assets/js/lodash.debounce.min.js,sha256=GLzlQH04WDUNYN7i39ttHHejSdu-CpAvfWgDgKDn-OY,4448
|
@@ -25,9 +28,12 @@ nova/trame/view/theme/assets/vuetify_config.json,sha256=a0FSgpLYWGFlRGSMhMq61MyD
|
|
25
28
|
nova/trame/view/theme/theme.py,sha256=HUeuVfzEgeYW65W-LcvXzfYNRHu6aQibGwwgHGyh3OA,11765
|
26
29
|
nova/trame/view/utilities/local_storage.py,sha256=vD8f2VZIpxhIKjZwEaD7siiPCTZO4cw9AfhwdawwYLY,3218
|
27
30
|
nova/trame/view_model/data_selector.py,sha256=FM1Xe-f-gi1jVwA9nDf2KE1UDvsAvmMKlp78slIpX58,2418
|
31
|
+
nova/trame/view_model/execution_buttons.py,sha256=MfKSp95D92EqpD48C15cBo6dLO0Yld4FeRZMJNxJf7Y,3551
|
32
|
+
nova/trame/view_model/progress_bar.py,sha256=L7ED6TDn5v2142iu-qt3i-jUg_5JEhLyC476t2OtohU,2467
|
28
33
|
nova/trame/view_model/remote_file_input.py,sha256=ojEOJ8ZPkajpbAaZi9VLj7g-uBjhb8BMrTdMmwf_J6A,3367
|
29
|
-
|
30
|
-
nova_trame-0.
|
31
|
-
nova_trame-0.
|
32
|
-
nova_trame-0.
|
33
|
-
nova_trame-0.
|
34
|
+
nova/trame/view_model/tool_outputs.py,sha256=ev6LY7fJ0H2xAJn9f5ww28c8Kpom2SYc2FbvFcoN4zg,829
|
35
|
+
nova_trame-0.20.0.dist-info/LICENSE,sha256=Iu5QiDbwNbREg75iYaxIJ_V-zppuv4QFuBhAW-qiAlM,1061
|
36
|
+
nova_trame-0.20.0.dist-info/METADATA,sha256=0URjV5ll_dfW8d0kB_EnpCa0ttbNEObIsk0J8HevEu0,1523
|
37
|
+
nova_trame-0.20.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
38
|
+
nova_trame-0.20.0.dist-info/entry_points.txt,sha256=J2AmeSwiTYZ4ZqHHp9HO6v4MaYQTTBPbNh6WtoqOT58,42
|
39
|
+
nova_trame-0.20.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|