forked from clan/clan-core
API: add abstract open_file method, implement open_file
This commit is contained in:
parent
6e99beb335
commit
6adcd1fdf2
@ -10,10 +10,11 @@ from typing import Any
|
||||
|
||||
import gi
|
||||
from clan_cli.api import API
|
||||
from clan_cli.api.directory import FileRequest
|
||||
|
||||
gi.require_version("WebKit", "6.0")
|
||||
|
||||
from gi.repository import GLib, WebKit
|
||||
from gi.repository import Gio, GLib, Gtk, WebKit
|
||||
|
||||
site_index: Path = (
|
||||
Path(sys.argv[0]).absolute() / Path("../..") / Path("clan_app/.webui/index.html")
|
||||
@ -39,6 +40,84 @@ def dataclass_to_dict(obj: Any) -> Any:
|
||||
return obj
|
||||
|
||||
|
||||
# Implement the abstract open_file function
|
||||
def open_file(file_request: FileRequest) -> str | None:
|
||||
# Function to handle the response and stop the loop
|
||||
selected_path = None
|
||||
|
||||
def on_file_select(
|
||||
file_dialog: Gtk.FileDialog, task: Gio.Task, main_loop: GLib.MainLoop
|
||||
) -> None:
|
||||
try:
|
||||
gfile = file_dialog.open_finish(task)
|
||||
if gfile:
|
||||
nonlocal selected_path
|
||||
selected_path = gfile.get_path()
|
||||
except Exception as e:
|
||||
print(f"Error getting selected file or directory: {e}")
|
||||
finally:
|
||||
main_loop.quit()
|
||||
|
||||
def on_folder_select(
|
||||
file_dialog: Gtk.FileDialog, task: Gio.Task, main_loop: GLib.MainLoop
|
||||
) -> None:
|
||||
try:
|
||||
gfile = file_dialog.select_folder_finish(task)
|
||||
if gfile:
|
||||
nonlocal selected_path
|
||||
selected_path = gfile.get_path()
|
||||
except Exception as e:
|
||||
print(f"Error getting selected directory: {e}")
|
||||
finally:
|
||||
main_loop.quit()
|
||||
|
||||
dialog = Gtk.FileDialog()
|
||||
|
||||
if file_request.title:
|
||||
dialog.set_title(file_request.title)
|
||||
|
||||
if file_request.filters:
|
||||
filters = Gio.ListStore.new(Gtk.FileFilter)
|
||||
file_filters = Gtk.FileFilter()
|
||||
|
||||
if file_request.filters.title:
|
||||
file_filters.set_name(file_request.filters.title)
|
||||
|
||||
# Create and configure a filter for image files
|
||||
if file_request.filters.mime_types:
|
||||
for mime in file_request.filters.mime_types:
|
||||
file_filters.add_mime_type(mime)
|
||||
filters.append(file_filters)
|
||||
|
||||
if file_request.filters.patterns:
|
||||
for pattern in file_request.filters.patterns:
|
||||
file_filters.add_pattern(pattern)
|
||||
|
||||
if file_request.filters.suffixes:
|
||||
for suffix in file_request.filters.suffixes:
|
||||
file_filters.add_suffix(suffix)
|
||||
|
||||
filters.append(file_filters)
|
||||
dialog.set_filters(filters)
|
||||
|
||||
main_loop = GLib.MainLoop()
|
||||
|
||||
# if select_folder
|
||||
if file_request.mode == "select_folder":
|
||||
dialog.select_folder(
|
||||
callback=lambda dialog, task: on_folder_select(dialog, task, main_loop)
|
||||
)
|
||||
elif file_request.mode == "open_file":
|
||||
dialog.open(
|
||||
callback=lambda dialog, task: on_file_select(dialog, task, main_loop)
|
||||
)
|
||||
|
||||
# Wait for the user to select a file or directory
|
||||
main_loop.run() # type: ignore
|
||||
|
||||
return selected_path
|
||||
|
||||
|
||||
class WebView:
|
||||
def __init__(self, methods: dict[str, Callable]) -> None:
|
||||
self.method_registry: dict[str, Callable] = methods
|
||||
|
@ -12,7 +12,7 @@ from clan_app.singletons.use_vms import ClanStore
|
||||
from clan_app.views.details import Details
|
||||
from clan_app.views.list import ClanList
|
||||
from clan_app.views.logs import Logs
|
||||
from clan_app.views.webview import WebView
|
||||
from clan_app.views.webview import WebView, open_file
|
||||
|
||||
gi.require_version("Adw", "1")
|
||||
|
||||
@ -51,7 +51,11 @@ class MainWindow(Adw.ApplicationWindow):
|
||||
stack_view.add_named(Details(), "details")
|
||||
stack_view.add_named(Logs(), "logs")
|
||||
|
||||
# Override platform specific functions
|
||||
API.register(open_file)
|
||||
|
||||
webview = WebView(methods=API._registry)
|
||||
|
||||
stack_view.add_named(webview.get_webview(), "webview")
|
||||
stack_view.set_visible_child_name(config.initial_view)
|
||||
|
||||
|
@ -8,6 +8,33 @@ from clan_cli.errors import ClanError
|
||||
from . import API
|
||||
|
||||
|
||||
@dataclass
|
||||
class FileFilter:
|
||||
title: str | None
|
||||
mime_types: list[str] | None
|
||||
patterns: list[str] | None
|
||||
suffixes: list[str] | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class FileRequest:
|
||||
# Mode of the os dialog window
|
||||
mode: Literal["open_file", "select_folder"]
|
||||
# Title of the os dialog window
|
||||
title: str | None = None
|
||||
# Pre-applied filters for the file dialog
|
||||
filters: FileFilter | None = None
|
||||
|
||||
|
||||
@API.register
|
||||
def open_file(file_request: FileRequest) -> str | None:
|
||||
"""
|
||||
Abstract api method to open a file dialog window.
|
||||
It must return the name of the selected file or None if no file was selected.
|
||||
"""
|
||||
raise NotImplementedError("Each specific platform should implement this function.")
|
||||
|
||||
|
||||
@dataclass
|
||||
class File:
|
||||
path: str
|
||||
|
991
pkgs/clan-cli/out.ts
Normal file
991
pkgs/clan-cli/out.ts
Normal file
@ -0,0 +1,991 @@
|
||||
export const schema = {
|
||||
"$comment": "An object containing API methods. ",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"open_file",
|
||||
"get_directory",
|
||||
"create_machine",
|
||||
"list_machines",
|
||||
"show_machine",
|
||||
"create_clan"
|
||||
],
|
||||
"properties": {
|
||||
"open_file": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"arguments",
|
||||
"return"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"return": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success"
|
||||
],
|
||||
"description": "The status of the response."
|
||||
},
|
||||
"data": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"errors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"location": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"errors"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"arguments": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"file_request"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"file_request": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mode": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"open_file",
|
||||
"select_folder"
|
||||
]
|
||||
},
|
||||
"title": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"filters": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mime_types": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"patterns": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"suffixes": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mode"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get_directory": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"arguments",
|
||||
"return"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"return": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success"
|
||||
],
|
||||
"description": "The status of the response."
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"files": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"file_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"file",
|
||||
"directory",
|
||||
"symlink"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"file_type"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"files"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"data"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"errors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"location": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"errors"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"arguments": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"current_path"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"current_path": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"create_machine": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"arguments",
|
||||
"return"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"return": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success"
|
||||
],
|
||||
"description": "The status of the response."
|
||||
},
|
||||
"data": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"errors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"location": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"errors"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"arguments": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"flake_dir",
|
||||
"machine"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"flake_dir": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"machine": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"config": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"config"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"list_machines": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"arguments",
|
||||
"return"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"return": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success"
|
||||
],
|
||||
"description": "The status of the response."
|
||||
},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"data"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"errors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"location": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"errors"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"arguments": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"flake_url",
|
||||
"debug"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"flake_url": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"debug": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"show_machine": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"arguments",
|
||||
"return"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"return": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success"
|
||||
],
|
||||
"description": "The status of the response."
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"machine_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"machine_description": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"machine_icon": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"machine_name"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"data"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"errors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"location": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"errors"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"arguments": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"flake_url",
|
||||
"machine_name",
|
||||
"debug"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"flake_url": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"machine_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"debug": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"create_clan": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"arguments",
|
||||
"return"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"return": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success"
|
||||
],
|
||||
"description": "The status of the response."
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"git_init": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"stdout": {
|
||||
"type": "string"
|
||||
},
|
||||
"stderr": {
|
||||
"type": "string"
|
||||
},
|
||||
"cwd": {
|
||||
"type": "string"
|
||||
},
|
||||
"command": {
|
||||
"type": "string"
|
||||
},
|
||||
"returncode": {
|
||||
"type": "integer"
|
||||
},
|
||||
"msg": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"stdout",
|
||||
"stderr",
|
||||
"cwd",
|
||||
"command",
|
||||
"returncode"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"git_add": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"stdout": {
|
||||
"type": "string"
|
||||
},
|
||||
"stderr": {
|
||||
"type": "string"
|
||||
},
|
||||
"cwd": {
|
||||
"type": "string"
|
||||
},
|
||||
"command": {
|
||||
"type": "string"
|
||||
},
|
||||
"returncode": {
|
||||
"type": "integer"
|
||||
},
|
||||
"msg": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"stdout",
|
||||
"stderr",
|
||||
"cwd",
|
||||
"command",
|
||||
"returncode"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"git_config": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"stdout": {
|
||||
"type": "string"
|
||||
},
|
||||
"stderr": {
|
||||
"type": "string"
|
||||
},
|
||||
"cwd": {
|
||||
"type": "string"
|
||||
},
|
||||
"command": {
|
||||
"type": "string"
|
||||
},
|
||||
"returncode": {
|
||||
"type": "integer"
|
||||
},
|
||||
"msg": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"stdout",
|
||||
"stderr",
|
||||
"cwd",
|
||||
"command",
|
||||
"returncode"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"flake_update": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"stdout": {
|
||||
"type": "string"
|
||||
},
|
||||
"stderr": {
|
||||
"type": "string"
|
||||
},
|
||||
"cwd": {
|
||||
"type": "string"
|
||||
},
|
||||
"command": {
|
||||
"type": "string"
|
||||
},
|
||||
"returncode": {
|
||||
"type": "integer"
|
||||
},
|
||||
"msg": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"stdout",
|
||||
"stderr",
|
||||
"cwd",
|
||||
"command",
|
||||
"returncode"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"git_init",
|
||||
"git_add",
|
||||
"git_config",
|
||||
"flake_update"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"data"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"errors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"location": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status",
|
||||
"errors"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"arguments": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"directory",
|
||||
"template_url"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"directory": {
|
||||
"type": "string"
|
||||
},
|
||||
"template_url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} as const;
|
||||
|
@ -12,11 +12,12 @@ export type SuccessData<T extends OperationNames> = Extract<
|
||||
{ status: "success" }
|
||||
>;
|
||||
|
||||
export type ClanOperations = {
|
||||
[K in OperationNames]: (str: string) => void;
|
||||
};
|
||||
declare global {
|
||||
interface Window {
|
||||
clan: {
|
||||
[K in OperationNames]: (str: string) => void;
|
||||
};
|
||||
clan: ClanOperations;
|
||||
webkit: {
|
||||
messageHandlers: {
|
||||
gtk: {
|
||||
@ -29,6 +30,8 @@ declare global {
|
||||
};
|
||||
}
|
||||
}
|
||||
// Make sure window.webkit is defined although the type is not correctly filled yet.
|
||||
window.clan = {} as ClanOperations;
|
||||
|
||||
function createFunctions<K extends OperationNames>(
|
||||
operationName: K
|
||||
@ -84,4 +87,11 @@ operationNames.forEach((opName) => {
|
||||
pyApi[name] = createFunctions(name);
|
||||
});
|
||||
|
||||
pyApi.open_file.receive((r) => {
|
||||
const { status } = r;
|
||||
if (status === "error") return console.error(r.errors);
|
||||
console.log(r.data);
|
||||
alert(r.data);
|
||||
});
|
||||
|
||||
export { pyApi };
|
||||
|
@ -34,6 +34,6 @@ if (import.meta.env.DEV) {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
postMessage;
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
render(() => <App />, root!);
|
||||
|
@ -48,7 +48,12 @@ export const MachineListView: Component = () => {
|
||||
<button
|
||||
class="btn btn-ghost"
|
||||
onClick={() =>
|
||||
pyApi.get_directory.dispatch({ current_path: "/home/" })
|
||||
pyApi.open_file.dispatch({
|
||||
file_request: {
|
||||
title: "Open Clan",
|
||||
mode: "select_folder",
|
||||
},
|
||||
})
|
||||
}
|
||||
>
|
||||
<span class="material-icons ">folder_open</span>
|
||||
|
Loading…
Reference in New Issue
Block a user