mirror of
https://github.com/ublue-os/forge.git
synced 2025-04-21 22:13:45 +03:00
wip - nicegui progress spinner
This commit is contained in:
parent
75095a841f
commit
dd001f4fe5
|
@ -1,14 +1,15 @@
|
||||||
import ansible_runner
|
import ansible_runner
|
||||||
import re
|
import re
|
||||||
|
import asyncio
|
||||||
|
import time
|
||||||
from nicegui import ui
|
from nicegui import ui
|
||||||
from utils import get_project_root, local_file_picker
|
from utils import get_project_root, local_file_picker, progress_spinner
|
||||||
from multiprocessing import Manager, Queue
|
|
||||||
|
|
||||||
ANSIBLE_EXTRA_VARS = None
|
ANSIBLE_EXTRA_VARS = None
|
||||||
|
|
||||||
|
|
||||||
# Ansible integration
|
# Ansible integration
|
||||||
@ui.refreshable #https://www.reddit.com/r/nicegui/comments/1bphjk5/comment/kx7l5kj/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button
|
@ui.refreshable # https://www.reddit.com/r/nicegui/comments/1bphjk5/comment/kx7l5kj/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button
|
||||||
async def load_configuration_file() -> None:
|
async def load_configuration_file() -> None:
|
||||||
result = await local_file_picker(
|
result = await local_file_picker(
|
||||||
directory="/data", multiple=False, file_name_filter=".yml"
|
directory="/data", multiple=False, file_name_filter=".yml"
|
||||||
|
@ -23,7 +24,15 @@ async def load_configuration_file() -> None:
|
||||||
## Preserve configuration file path for ansible-playbook --extra-vars
|
## Preserve configuration file path for ansible-playbook --extra-vars
|
||||||
ANSIBLE_EXTRA_VARS = f'"@{file_path}"'
|
ANSIBLE_EXTRA_VARS = f'"@{file_path}"'
|
||||||
|
|
||||||
async def run_ansible_playbook(playbook_name: str, ngui_log: ui.log):
|
|
||||||
|
async def run_ansible_playbook(
|
||||||
|
playbook_name: str,
|
||||||
|
ngui_log: ui.log,
|
||||||
|
ngui_spinner: progress_spinner,
|
||||||
|
) -> None:
|
||||||
|
ngui_spinner.enable_progress()
|
||||||
|
# make sure spinner is displayed
|
||||||
|
await asyncio.sleep(1)
|
||||||
project_root = str(get_project_root())
|
project_root = str(get_project_root())
|
||||||
playbook_path = project_root + "/ansible/playbooks/"
|
playbook_path = project_root + "/ansible/playbooks/"
|
||||||
inventory_path = project_root + "/ansible/inventory.yml"
|
inventory_path = project_root + "/ansible/inventory.yml"
|
||||||
|
@ -36,7 +45,7 @@ async def run_ansible_playbook(playbook_name: str, ngui_log: ui.log):
|
||||||
inventory_path,
|
inventory_path,
|
||||||
"--extra-vars",
|
"--extra-vars",
|
||||||
extra_vars_file,
|
extra_vars_file,
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
# clear log
|
# clear log
|
||||||
ngui_log.clear()
|
ngui_log.clear()
|
||||||
|
@ -45,16 +54,18 @@ async def run_ansible_playbook(playbook_name: str, ngui_log: ui.log):
|
||||||
# show log from asynchronous job
|
# show log from asynchronous job
|
||||||
while runner.rc is None:
|
while runner.rc is None:
|
||||||
for event in runner.events:
|
for event in runner.events:
|
||||||
ansible_log = format(ansi_escape.sub("", event['stdout']))
|
ansible_log = format(ansi_escape.sub("", event["stdout"]))
|
||||||
ngui_log.push(ansible_log)
|
ngui_log.push(ansible_log)
|
||||||
|
ngui_spinner.disable_progress()
|
||||||
|
|
||||||
|
|
||||||
# Page content
|
# Page content
|
||||||
def content() -> None:
|
def content() -> None:
|
||||||
with ui.row().classes("w-full"):
|
with ui.row().classes("w-full"):
|
||||||
with ui.row().classes("w-full"):
|
with ui.row().classes("w-full"):
|
||||||
with ui.card().classes("h-full"):
|
with ui.card().classes("h-full"):
|
||||||
ui.button(text=
|
ui.button(
|
||||||
"Load configuration file",
|
text="Load configuration file",
|
||||||
on_click=lambda: load_configuration_file.refresh(),
|
on_click=lambda: load_configuration_file.refresh(),
|
||||||
icon="folder",
|
icon="folder",
|
||||||
)
|
)
|
||||||
|
@ -63,22 +74,30 @@ def content() -> None:
|
||||||
with ui.row().classes("w-full"):
|
with ui.row().classes("w-full"):
|
||||||
# First Row
|
# First Row
|
||||||
with ui.card().classes("h-full"):
|
with ui.card().classes("h-full"):
|
||||||
ui.label("Build").classes("text-h6")
|
with ui.row().classes("no-wrap"):
|
||||||
|
ui.label("Build").classes("text-h5")
|
||||||
|
build_progress = progress_spinner()
|
||||||
ui.button(
|
ui.button(
|
||||||
text="Clone project",
|
text="Clone project",
|
||||||
on_click=lambda: run_ansible_playbook(
|
on_click=lambda: run_ansible_playbook(
|
||||||
playbook_name="project_clone.yml", ngui_log=playbook_log
|
playbook_name="project_clone.yml",
|
||||||
|
ngui_log=playbook_log,
|
||||||
|
ngui_spinner=build_progress,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
ui.button(
|
ui.button(
|
||||||
text="Build project",
|
text="Build project",
|
||||||
on_click=lambda: run_ansible_playbook(
|
on_click=lambda: run_ansible_playbook(
|
||||||
"project_build.yml", ngui_log=playbook_log
|
"project_build.yml",
|
||||||
|
ngui_log=playbook_log,
|
||||||
|
ngui_spinner=build_progress,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
# Second Row
|
# Second Row
|
||||||
with ui.card().classes("h-full"):
|
with ui.card().classes("h-full"):
|
||||||
|
with ui.row().classes("no-wrap"):
|
||||||
ui.label("Deploy").classes("text-h6")
|
ui.label("Deploy").classes("text-h6")
|
||||||
|
deploy_progress = progress_spinner()
|
||||||
ui.button(
|
ui.button(
|
||||||
"Deploy VM",
|
"Deploy VM",
|
||||||
on_click=lambda: ui.notify("This playbook is not implemented yet"),
|
on_click=lambda: ui.notify("This playbook is not implemented yet"),
|
||||||
|
@ -88,4 +107,5 @@ def content() -> None:
|
||||||
with ui.card().classes("w-full"):
|
with ui.card().classes("w-full"):
|
||||||
ui.label("Playbook Log").classes("text-h6")
|
ui.label("Playbook Log").classes("text-h6")
|
||||||
ui.button("Clear Log", on_click=lambda: playbook_log.clear())
|
ui.button("Clear Log", on_click=lambda: playbook_log.clear())
|
||||||
|
|
||||||
playbook_log = ui.log().classes("w-full h-full")
|
playbook_log = ui.log().classes("w-full h-full")
|
||||||
|
|
|
@ -74,7 +74,9 @@ class local_file_picker(ui.dialog):
|
||||||
if not self.show_hidden_files:
|
if not self.show_hidden_files:
|
||||||
paths = [p for p in paths if not p.name.startswith(".")]
|
paths = [p for p in paths if not p.name.startswith(".")]
|
||||||
if self.file_name_filter: # Add this condition
|
if self.file_name_filter: # Add this condition
|
||||||
paths = [p for p in paths if p.is_file() and p.suffix == self.file_name_filter]
|
paths = [
|
||||||
|
p for p in paths if p.is_file() and p.suffix == self.file_name_filter
|
||||||
|
]
|
||||||
paths.sort(key=lambda p: p.name.lower())
|
paths.sort(key=lambda p: p.name.lower())
|
||||||
paths.sort(key=lambda p: not p.is_dir())
|
paths.sort(key=lambda p: not p.is_dir())
|
||||||
|
|
||||||
|
@ -114,5 +116,25 @@ class local_file_picker(ui.dialog):
|
||||||
self.submit([r["path"] for r in rows])
|
self.submit([r["path"] for r in rows])
|
||||||
|
|
||||||
|
|
||||||
|
class progress_spinner(ui.spinner):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
type: str = "dots",
|
||||||
|
size: str = "lg",
|
||||||
|
color: str | None = "red",
|
||||||
|
thickness: float = 5,
|
||||||
|
) -> None:
|
||||||
|
super().__init__(type, size=size, color=color, thickness=thickness)
|
||||||
|
with self, ui.spinner():
|
||||||
|
self.visible = False
|
||||||
|
|
||||||
|
def enable_progress(self) -> None:
|
||||||
|
self.set_visibility(True)
|
||||||
|
|
||||||
|
def disable_progress(self) -> None:
|
||||||
|
self.set_visibility(False)
|
||||||
|
|
||||||
|
|
||||||
def get_project_root() -> Path:
|
def get_project_root() -> Path:
|
||||||
return Path(__file__).parent.parent
|
return Path(__file__).parent.parent
|
||||||
|
|
Loading…
Reference in a new issue