Loading poetry.lock +933 −901 File changed.Preview size limit exceeded, changes collapsed. Show changes pyproject.toml +4 −2 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ Changelog = "https://code.ornl.gov/ndip/public-packages/nova-trame/blob/main/CHA [tool.poetry] name = "nova-trame" version = "0.19.2" version = "0.20.0" description = "A Python Package for injecting curated themes and custom components into Trame applications" authors = ["Duggan, John <dugganjw@ornl.gov>"] readme = "README.md" Loading @@ -28,6 +28,8 @@ trame-vega = "*" trame-vuetify = "*" nova-mvvm = "*" pydantic = "*" nova-common = ">=0.2.0" blinker = "^1.9.0" [build-system] requires = ["poetry-core"] Loading Loading @@ -84,7 +86,7 @@ omit = [ command_line = "-m pytest --junit-xml=reports/junit.xml" data_file = "reports/.coverage" [tool.poetry.dev-dependencies] [tool.poetry.group.dev.dependencies] mypy = "^1.10.0" pre-commit = "^2.20.0" coverage = "^6.4.3" Loading src/nova/trame/view/components/execution_buttons.py 0 → 100644 +105 −0 Original line number Diff line number Diff line """Module for the Progress Tab.""" from nova.mvvm.trame_binding import TrameBinding from trame.app import get_server from trame.widgets import client from trame.widgets import vuetify3 as vuetify from trame_client.widgets import html from nova.trame.view_model.execution_buttons import ExecutionButtonsViewModel class ExecutionButtons: """Execution buttons class. Adds Run/Stop/Cancel/Download buttons to the view.""" def __init__(self, id: str, stop_btn: bool = False, download_btn: bool = False) -> None: """Constructor for ExecutionButtons. Parameters ---------- id : str Component id. Should be used consistently with ToolRunner and other components stop_btn: bool Display stop button. download_btn : bool Display download button. Returns ------- None """ self.id = f"execution_{id}" self.server = get_server(None, client_type="vue3") binding = TrameBinding(self.server.state) self.ctrl = self.server.controller self.stop_btn = stop_btn self.download_btn = download_btn self.view_model = ExecutionButtonsViewModel(id, binding) self.view_model.buttons_state_bind.connect(self.id) self._download = client.JSEval( exec=( "async ($event) => {" " const blob = new window.Blob([$event], {type: 'application/zip'});" " const url = window.URL.createObjectURL(blob);" " const anchor = window.document.createElement('a');" " anchor.setAttribute('href', url);" " anchor.setAttribute('download', 'results.zip');" " window.document.body.appendChild(anchor);" " anchor.click();" " window.document.body.removeChild(anchor);" " setTimeout(() => window.URL.revokeObjectURL(url), 1000);" "}" ) ).exec self.create_ui() def create_ui(self) -> None: with html.Div(classes="d-flex justify-center my-4 w-100"): vuetify.VBtn( "Run", disabled=(f"{self.id}.run_disabled",), prepend_icon="mdi-play", classes="mr-4", click=self.run, ) if self.stop_btn: vuetify.VBtn( "Stop", disabled=(f"{self.id}.stop_disabled",), loading=(f"{self.id}.stop_in_progress",), classes="mr-4", prepend_icon="mdi-stop", click=self.stop, ) vuetify.VBtn( "Cancel", disabled=(f"{self.id}.cancel_disabled",), color="error", loading=(f"{self.id}.cancel_in_progress",), prepend_icon="mdi-cancel", classes="mr-4", click=self.cancel, ) if self.download_btn: vuetify.VBtn( "Download Results", disabled=(f"{self.id}.download_disabled",), loading=(f"{self.id}.download_in_progress",), click=self.download, ) async def download(self) -> None: content = await self.view_model.prepare_results() if content: self._download(content) async def run(self) -> None: await self.view_model.run() async def cancel(self) -> None: await self.view_model.cancel() async def stop(self) -> None: await self.view_model.stop() src/nova/trame/view/components/progress_bar.py 0 → 100644 +59 −0 Original line number Diff line number Diff line """Module for the Progress Tab.""" from nova.mvvm.trame_binding import TrameBinding from trame.app import get_server from trame.widgets import vuetify3 as vuetify from trame_client.widgets import html from nova.trame.view_model.progress_bar import ProgressBarViewModel class ProgressBar: """Progress bar class. Adds progress bar that displays job status to the view.""" def __init__(self, id: str) -> None: """Constructor for ProgressBar. Parameters ---------- id : str Component id. Should be used consistently with ToolRunner and other components Returns ------- None """ self.id = f"progress_bar_{id}" self.create_viewmodel(id) self.view_model.progress_state_bind.connect(self.id) self.create_ui() def create_viewmodel(self, id: str) -> None: server = get_server(None, client_type="vue3") binding = TrameBinding(server.state) self.view_model = ProgressBarViewModel(id, binding) def create_ui(self) -> None: with vuetify.VProgressLinear( height="25", model_value=(f"{self.id}.progress", "0"), striped=True, v_show=(f"{self.id}.show_progress",), ): html.H5(v_text=f"{self.id}.details") with vuetify.VProgressLinear( height="25", model_value="100", striped=False, color="error", v_show=(f"{self.id}.show_failed",), ): html.H5(v_text=f"{self.id}.details", classes="text-white") with vuetify.VProgressLinear( height="25", model_value="100", striped=False, color="primary", v_show=(f"{self.id}.show_ok",), ): html.H5(v_text=f"{self.id}.details", classes="text-white") src/nova/trame/view/components/tool_outputs.py 0 → 100644 +57 −0 Original line number Diff line number Diff line """Module for the Tool outputs.""" from nova.mvvm.trame_binding import TrameBinding from nova.trame.view.components import InputField from trame.app import get_server from trame.widgets import vuetify3 as vuetify from nova.trame.view_model.tool_outputs import ToolOutputsViewModel class ToolOutputWindows: """Tool outputs class. Displays windows with tool stdout/stderr.""" def __init__(self, id: str) -> None: """Constructor for ToolOutputWindows. Parameters ---------- id : str Component id. Should be used consistently with ToolRunner and other components Returns ------- None """ self.id = f"tool_outputs_{id}" self.create_viewmodel(id) self.view_model.tool_outputs_bind.connect(self.id) self.create_ui() def create_viewmodel(self, id: str) -> None: server = get_server(None, client_type="vue3") binding = TrameBinding(server.state) self.view_model = ToolOutputsViewModel(id, binding) def create_ui(self) -> None: with vuetify.VContainer(classes="d-flex", fluid=True): with vuetify.VTabs(v_model=(f"{self.id}_active_output_tab", "0"), direction="vertical"): vuetify.VTab("Console output", value=1) vuetify.VTab("Console error", value=2) with vuetify.VWindow(v_model=f"{self.id}_active_output_tab", classes="flex-grow-1"): with vuetify.VWindowItem(value=1, reverse_transition="false", transition="false"): InputField( v_model=f"{self.id}.stdout", type="autoscroll", auto_grow=True, readonly=True, max_rows="30", ) with vuetify.VWindowItem(value=2, reverse_transition="false", transition="false"): InputField( v_model=f"{self.id}.stderr", type="autoscroll", auto_grow=True, readonly=True, max_rows="30", ) Loading
pyproject.toml +4 −2 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ Changelog = "https://code.ornl.gov/ndip/public-packages/nova-trame/blob/main/CHA [tool.poetry] name = "nova-trame" version = "0.19.2" version = "0.20.0" description = "A Python Package for injecting curated themes and custom components into Trame applications" authors = ["Duggan, John <dugganjw@ornl.gov>"] readme = "README.md" Loading @@ -28,6 +28,8 @@ trame-vega = "*" trame-vuetify = "*" nova-mvvm = "*" pydantic = "*" nova-common = ">=0.2.0" blinker = "^1.9.0" [build-system] requires = ["poetry-core"] Loading Loading @@ -84,7 +86,7 @@ omit = [ command_line = "-m pytest --junit-xml=reports/junit.xml" data_file = "reports/.coverage" [tool.poetry.dev-dependencies] [tool.poetry.group.dev.dependencies] mypy = "^1.10.0" pre-commit = "^2.20.0" coverage = "^6.4.3" Loading
src/nova/trame/view/components/execution_buttons.py 0 → 100644 +105 −0 Original line number Diff line number Diff line """Module for the Progress Tab.""" from nova.mvvm.trame_binding import TrameBinding from trame.app import get_server from trame.widgets import client from trame.widgets import vuetify3 as vuetify from trame_client.widgets import html from nova.trame.view_model.execution_buttons import ExecutionButtonsViewModel class ExecutionButtons: """Execution buttons class. Adds Run/Stop/Cancel/Download buttons to the view.""" def __init__(self, id: str, stop_btn: bool = False, download_btn: bool = False) -> None: """Constructor for ExecutionButtons. Parameters ---------- id : str Component id. Should be used consistently with ToolRunner and other components stop_btn: bool Display stop button. download_btn : bool Display download button. Returns ------- None """ self.id = f"execution_{id}" self.server = get_server(None, client_type="vue3") binding = TrameBinding(self.server.state) self.ctrl = self.server.controller self.stop_btn = stop_btn self.download_btn = download_btn self.view_model = ExecutionButtonsViewModel(id, binding) self.view_model.buttons_state_bind.connect(self.id) self._download = client.JSEval( exec=( "async ($event) => {" " const blob = new window.Blob([$event], {type: 'application/zip'});" " const url = window.URL.createObjectURL(blob);" " const anchor = window.document.createElement('a');" " anchor.setAttribute('href', url);" " anchor.setAttribute('download', 'results.zip');" " window.document.body.appendChild(anchor);" " anchor.click();" " window.document.body.removeChild(anchor);" " setTimeout(() => window.URL.revokeObjectURL(url), 1000);" "}" ) ).exec self.create_ui() def create_ui(self) -> None: with html.Div(classes="d-flex justify-center my-4 w-100"): vuetify.VBtn( "Run", disabled=(f"{self.id}.run_disabled",), prepend_icon="mdi-play", classes="mr-4", click=self.run, ) if self.stop_btn: vuetify.VBtn( "Stop", disabled=(f"{self.id}.stop_disabled",), loading=(f"{self.id}.stop_in_progress",), classes="mr-4", prepend_icon="mdi-stop", click=self.stop, ) vuetify.VBtn( "Cancel", disabled=(f"{self.id}.cancel_disabled",), color="error", loading=(f"{self.id}.cancel_in_progress",), prepend_icon="mdi-cancel", classes="mr-4", click=self.cancel, ) if self.download_btn: vuetify.VBtn( "Download Results", disabled=(f"{self.id}.download_disabled",), loading=(f"{self.id}.download_in_progress",), click=self.download, ) async def download(self) -> None: content = await self.view_model.prepare_results() if content: self._download(content) async def run(self) -> None: await self.view_model.run() async def cancel(self) -> None: await self.view_model.cancel() async def stop(self) -> None: await self.view_model.stop()
src/nova/trame/view/components/progress_bar.py 0 → 100644 +59 −0 Original line number Diff line number Diff line """Module for the Progress Tab.""" from nova.mvvm.trame_binding import TrameBinding from trame.app import get_server from trame.widgets import vuetify3 as vuetify from trame_client.widgets import html from nova.trame.view_model.progress_bar import ProgressBarViewModel class ProgressBar: """Progress bar class. Adds progress bar that displays job status to the view.""" def __init__(self, id: str) -> None: """Constructor for ProgressBar. Parameters ---------- id : str Component id. Should be used consistently with ToolRunner and other components Returns ------- None """ self.id = f"progress_bar_{id}" self.create_viewmodel(id) self.view_model.progress_state_bind.connect(self.id) self.create_ui() def create_viewmodel(self, id: str) -> None: server = get_server(None, client_type="vue3") binding = TrameBinding(server.state) self.view_model = ProgressBarViewModel(id, binding) def create_ui(self) -> None: with vuetify.VProgressLinear( height="25", model_value=(f"{self.id}.progress", "0"), striped=True, v_show=(f"{self.id}.show_progress",), ): html.H5(v_text=f"{self.id}.details") with vuetify.VProgressLinear( height="25", model_value="100", striped=False, color="error", v_show=(f"{self.id}.show_failed",), ): html.H5(v_text=f"{self.id}.details", classes="text-white") with vuetify.VProgressLinear( height="25", model_value="100", striped=False, color="primary", v_show=(f"{self.id}.show_ok",), ): html.H5(v_text=f"{self.id}.details", classes="text-white")
src/nova/trame/view/components/tool_outputs.py 0 → 100644 +57 −0 Original line number Diff line number Diff line """Module for the Tool outputs.""" from nova.mvvm.trame_binding import TrameBinding from nova.trame.view.components import InputField from trame.app import get_server from trame.widgets import vuetify3 as vuetify from nova.trame.view_model.tool_outputs import ToolOutputsViewModel class ToolOutputWindows: """Tool outputs class. Displays windows with tool stdout/stderr.""" def __init__(self, id: str) -> None: """Constructor for ToolOutputWindows. Parameters ---------- id : str Component id. Should be used consistently with ToolRunner and other components Returns ------- None """ self.id = f"tool_outputs_{id}" self.create_viewmodel(id) self.view_model.tool_outputs_bind.connect(self.id) self.create_ui() def create_viewmodel(self, id: str) -> None: server = get_server(None, client_type="vue3") binding = TrameBinding(server.state) self.view_model = ToolOutputsViewModel(id, binding) def create_ui(self) -> None: with vuetify.VContainer(classes="d-flex", fluid=True): with vuetify.VTabs(v_model=(f"{self.id}_active_output_tab", "0"), direction="vertical"): vuetify.VTab("Console output", value=1) vuetify.VTab("Console error", value=2) with vuetify.VWindow(v_model=f"{self.id}_active_output_tab", classes="flex-grow-1"): with vuetify.VWindowItem(value=1, reverse_transition="false", transition="false"): InputField( v_model=f"{self.id}.stdout", type="autoscroll", auto_grow=True, readonly=True, max_rows="30", ) with vuetify.VWindowItem(value=2, reverse_transition="false", transition="false"): InputField( v_model=f"{self.id}.stderr", type="autoscroll", auto_grow=True, readonly=True, max_rows="30", )