Replace Install/Remove crontab buttons with Active toggle switch

Switch checks current crontab status on mount. Toggling ON runs
schedule install, toggling OFF runs schedule remove. Show crontab
button remains for inspection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shuki
2026-03-06 04:35:59 +02:00
parent 8fc0e5a04d
commit a8d67160a5
2 changed files with 37 additions and 19 deletions

View File

@@ -256,6 +256,17 @@ Switch {
margin: 0 1; margin: 0 1;
} }
#sched-active-row {
height: auto;
align: left middle;
margin: 1 0;
}
#sched-active-label {
width: auto;
margin: 0 1 0 0;
}
.section-label { .section-label {
text-style: bold; text-style: bold;
color: #00cc00; color: #00cc00;

View File

@@ -1,7 +1,7 @@
import re import re
from textual.app import ComposeResult from textual.app import ComposeResult
from textual.screen import Screen from textual.screen import Screen
from textual.widgets import Header, Footer, Static, Button, DataTable, Input, Select, SelectionList from textual.widgets import Header, Footer, Static, Button, DataTable, Input, Select, SelectionList, Switch
from textual.containers import Vertical, Horizontal from textual.containers import Vertical, Horizontal
from textual import work from textual import work
@@ -40,12 +40,13 @@ class ScheduleScreen(Screen):
with Vertical(id="schedule-screen"): with Vertical(id="schedule-screen"):
yield Static("Schedules", id="screen-title") yield Static("Schedules", id="screen-title")
yield DataTable(id="sched-table") yield DataTable(id="sched-table")
with Horizontal(id="sched-active-row"):
yield Static("Active (crontab):", id="sched-active-label")
yield Switch(id="sched-active")
with Horizontal(id="sched-buttons"): with Horizontal(id="sched-buttons"):
yield Button("Add", variant="primary", id="btn-add") yield Button("Add", variant="primary", id="btn-add")
yield Button("Edit", id="btn-edit") yield Button("Edit", id="btn-edit")
yield Button("Delete", variant="error", id="btn-delete") yield Button("Delete", variant="error", id="btn-delete")
yield Button("Install to crontab", id="btn-install")
yield Button("Remove from crontab", id="btn-remove")
yield Button("Show crontab", id="btn-show") yield Button("Show crontab", id="btn-show")
yield Button("Back", id="btn-back") yield Button("Back", id="btn-back")
yield Static("", id="sched-divider") yield Static("", id="sched-divider")
@@ -110,6 +111,20 @@ class ScheduleScreen(Screen):
def on_mount(self) -> None: def on_mount(self) -> None:
self._refresh_table() self._refresh_table()
self._update_type_visibility() self._update_type_visibility()
self._check_crontab_status()
@work
async def _check_crontab_status(self) -> None:
rc, stdout, stderr = await run_cli("schedule", "show")
has_entries = bool(stdout.strip()) and "no gniza" not in stdout.lower()
self.query_one("#sched-active", Switch).value = has_entries
def on_switch_changed(self, event: Switch.Changed) -> None:
if event.switch.id == "sched-active":
if event.value:
self._install_schedules()
else:
self._remove_schedules()
def on_select_changed(self, event: Select.Changed) -> None: def on_select_changed(self, event: Select.Changed) -> None:
if event.select.id == "sched-type": if event.select.id == "sched-type":
@@ -167,10 +182,6 @@ class ScheduleScreen(Screen):
) )
else: else:
self.notify("Select a schedule first", severity="warning") self.notify("Select a schedule first", severity="warning")
elif event.button.id == "btn-install":
self._install_schedules()
elif event.button.id == "btn-remove":
self._remove_schedules()
elif event.button.id == "btn-show": elif event.button.id == "btn-show":
self._show_crontab() self._show_crontab()
@@ -275,23 +286,19 @@ class ScheduleScreen(Screen):
@work @work
async def _install_schedules(self) -> None: async def _install_schedules(self) -> None:
log_screen = OperationLog("Install Schedules")
self.app.push_screen(log_screen)
rc, stdout, stderr = await run_cli("schedule", "install") rc, stdout, stderr = await run_cli("schedule", "install")
if stdout: if rc == 0:
log_screen.write(stdout) self.notify("Schedules installed to crontab")
if stderr: else:
log_screen.write(stderr) self.notify(f"Failed to install: {stderr or stdout}", severity="error")
@work @work
async def _remove_schedules(self) -> None: async def _remove_schedules(self) -> None:
log_screen = OperationLog("Remove Schedules")
self.app.push_screen(log_screen)
rc, stdout, stderr = await run_cli("schedule", "remove") rc, stdout, stderr = await run_cli("schedule", "remove")
if stdout: if rc == 0:
log_screen.write(stdout) self.notify("Schedules removed from crontab")
if stderr: else:
log_screen.write(stderr) self.notify(f"Failed to remove: {stderr or stdout}", severity="error")
@work @work
async def _show_crontab(self) -> None: async def _show_crontab(self) -> None: