diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 0a7216f5..a665f45e 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2511,6 +2511,7 @@ dependencies = [ "sysinfo", "tauri", "tauri-build", + "tauri-plugin-store", "thiserror", "tokio", ] @@ -3727,6 +3728,18 @@ dependencies = [ "tauri-utils", ] +[[package]] +name = "tauri-plugin-store" +version = "0.0.0" +source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#8d6045421a553330e9da8b9e1e4405d419c5ea88" +dependencies = [ + "log", + "serde", + "serde_json", + "tauri", + "thiserror", +] + [[package]] name = "tauri-runtime" version = "0.14.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 26096d6c..b5853e02 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -15,6 +15,7 @@ sys-info = "0.9.1" sysinfo = "0.29.10" thiserror = "1.0.49" + tauri-plugin-store = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } [dependencies.futures] default-features = false diff --git a/src-tauri/src/controller_binaries.rs b/src-tauri/src/controller_binaries.rs index 4a51ffd0..3c427273 100644 --- a/src-tauri/src/controller_binaries.rs +++ b/src-tauri/src/controller_binaries.rs @@ -7,7 +7,7 @@ use crate::{ errors::{Context, Result}, logerr, swarm::{create_environment, Config}, - Service, SharedState, + utils, Registry, Service, SharedState, }; use std::path::PathBuf; @@ -20,6 +20,7 @@ use sys_info::mem_info; use sysinfo::{Pid, ProcessExt, ProcessRefreshKind, RefreshKind, SystemExt}; use tauri::{AppHandle, Runtime, State, Window}; +use tauri_plugin_store::StoreBuilder; use tokio::process::{Child, Command}; use tokio::time::interval; @@ -495,3 +496,143 @@ pub async fn add_service(service: Service, state: State<'_, Arc>) - services_guard.insert(service.get_id()?, service); Ok(()) } + +#[tauri::command(async)] +pub async fn add_registry( + registry: Registry, + app_handle: AppHandle, + state: State<'_, Arc>, +) -> Result<()> { + let store_path = app_handle + .path_resolver() + .app_data_dir() + .with_context(|| "Failed to resolve app data dir")? + .join("store.json"); + let mut store = StoreBuilder::new(app_handle, store_path).build(); + store.load().with_context(|| "Failed to load store")?; + if let Some(registries) = store.get("registries").cloned() { + match serde_json::from_value::>(registries) { + Ok(mut registries) => { + registries.push(registry); + store + .insert( + "registries".to_string(), + serde_json::to_value(®istries).unwrap(), + ) + .with_context(|| "Failed to insert into store")?; + utils::fetch_all_services_manifests(®istries, &state) + .await + .expect("failed to fetch services") + } + Err(e) => println!("Error unwrapping registries: {:?}", e), + } + } else { + let new_registry = [registry]; + store + .insert( + "registries".to_string(), + serde_json::to_value(&new_registry).unwrap(), + ) + .with_context(|| "Failed to insert into store")?; + utils::fetch_all_services_manifests(&new_registry, &state) + .await + .expect("failed to fetch services") + } + store.save().expect("failed to save store"); + Ok(()) +} + +#[tauri::command(async)] +pub async fn delete_registry( + registry: Registry, + app_handle: AppHandle, + state: State<'_, Arc>, +) -> Result<()> { + let store_path = app_handle + .path_resolver() + .app_data_dir() + .with_context(|| "Failed to resolve app data dir")? + .join("store.json"); + let mut store = StoreBuilder::new(app_handle, store_path).build(); + store.load().with_context(|| "Failed to load store")?; + if let Some(registries) = store.get("registries").cloned() { + let mut registries = serde_json::from_value::>(registries) + .with_context(|| "Failed to deserialize")?; + registries.retain(|r| r.url != registry.url); + store + .insert( + "registries".to_string(), + serde_json::to_value(registries).with_context(|| "Failed to serialize")?, + ) + .with_context(|| "Failed to insert into store")?; + store.save().with_context(|| "Failed to save store")?; + + // Reset services state and refetch all registries + let mut services_guard = state.services.lock().await; + services_guard.clear(); + drop(services_guard); + if let Some(registries) = store.get("registries").cloned() { + match serde_json::from_value::>(registries) { + Ok(registries) => utils::fetch_all_services_manifests(®istries, &state) + .await + .with_context(|| "Failed to fetch services")?, + Err(e) => log::error!("Error unwrapping registries: {:?}", e), + } + } else { + println!("No registries found"); + } + } + Ok(()) +} + +#[tauri::command(async)] +pub async fn fetch_registries(app_handle: AppHandle) -> Result> { + let store_path = app_handle + .path_resolver() + .app_data_dir() + .with_context(|| "Failed to resolve app data dir")? + .join("store.json"); + let mut store = StoreBuilder::new(app_handle, store_path).build(); + match store.load() { + Ok(_) => { + if let Some(registries) = store.get("registries").cloned() { + match serde_json::from_value::>(registries) { + Ok(registries) => Ok(registries), + Err(e) => { + log::error!("Error unwrapping registries: {:?}", e); + Ok(Vec::new()) + } + } + } else { + log::error!("No registries found"); + Ok(Vec::new()) + } + } + Err(e) => { + log::error!("Error loading store: {:?}", e); + Ok(Vec::new()) + } + } +} + +#[tauri::command(async)] +pub async fn reset_default_registry( + app_handle: AppHandle, + state: State<'_, Arc>, +) -> Result<()> { + let store_path = app_handle + .path_resolver() + .app_data_dir() + .with_context(|| "Failed to resolve app data dir")? + .join("store.json"); + let mut store = StoreBuilder::new(app_handle.clone(), store_path).build(); + store.load().with_context(|| "Failed to load store")?; + store + .delete("registries") + .with_context(|| "Failed to delete registries")?; + store.save().with_context(|| "Failed to save store")?; + add_registry(Registry::default(), app_handle.clone(), state) + .await + .with_context(|| "Failed to add default registry")?; + Ok(()) +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 36bcbd72..99250cbd 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -17,6 +17,7 @@ use tauri::{ AboutMetadata, CustomMenuItem, Manager, Menu, MenuItem, RunEvent, Submenu, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem, WindowEvent, }; +use tauri_plugin_store::StoreBuilder; use tokio::process::Child; use tokio::sync::Mutex; @@ -28,6 +29,32 @@ pub struct SharedState { services: Mutex>, } +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct Registry { + url: String, +} + +impl Default for Registry { + fn default() -> Self { + // Determine the URL based on whether the app is in debug or release mode + let url = if cfg!(debug_assertions) { + // Debug mode URL + "https://raw.githubusercontent.com/premAI-io/prem-registry/dev/manifests.json" + } else { + // Release mode URL + "https://raw.githubusercontent.com/premAI-io/prem-registry/v1/manifests.json" + }; + Registry { + url: url.to_string(), + } + } +} + +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct Store { + registries: Vec, +} + #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Service { // Static state from registry manifest @@ -193,6 +220,7 @@ fn main() { let app = tauri::Builder::default() .plugin(sentry_tauri::plugin()) + .plugin(tauri_plugin_store::Builder::default().build()) .manage(state.clone()) .invoke_handler(tauri::generate_handler![ controller_binaries::start_service, @@ -207,6 +235,10 @@ fn main() { controller_binaries::get_service_stats, controller_binaries::get_gpu_stats, controller_binaries::add_service, + controller_binaries::add_registry, + controller_binaries::delete_registry, + controller_binaries::fetch_registries, + controller_binaries::reset_default_registry, swarm::is_swarm_supported, swarm::get_username, swarm::get_petals_models, @@ -259,21 +291,40 @@ fn main() { }) .setup(|app| { tauri::async_runtime::block_on(async move { - // Determine the URL based on whether the app is in debug or release mode - let url = if cfg!(debug_assertions) { - // Debug mode URL - "https://raw.githubusercontent.com/premAI-io/prem-registry/dev/manifests.json" - } else { - // Release mode URL - "https://raw.githubusercontent.com/premAI-io/prem-registry/v1/manifests.json" - }; - - utils::fetch_services_manifests( - url, - app.state::>().deref().clone(), - ) - .await - .expect("Failed to fetch and save services manifests"); + //Create a store with default registry if doesn't exist + let store_path = app + .path_resolver() + .app_data_dir() + .expect("failed to resolve app data dir") + .join("store.json"); + if !store_path.exists() { + let mut registries: Vec = Vec::new(); + registries.push(Registry::default()); + let mut default_store = HashMap::new(); + default_store.insert( + "registries".to_string(), + serde_json::to_value(registries).unwrap(), + ); + let store = StoreBuilder::new(app.handle(), store_path.clone()) + .defaults(default_store) + .build(); + store.save().expect("failed to save store"); + log::info!("Store created"); + } + // Fetch all registries + let mut store = StoreBuilder::new(app.handle(), store_path.clone()).build(); + store.load().expect("Failed to load store"); + if let Some(registries) = store.get("registries").cloned() { + match serde_json::from_value::>(registries) { + Ok(registries) => utils::fetch_all_services_manifests( + ®istries, + &app.state::>().clone(), + ) + .await + .expect("failed to fetch services"), + Err(e) => println!("Error unwrapping registries: {:?}", e), + } + } }); Ok(()) }) diff --git a/src-tauri/src/utils.rs b/src-tauri/src/utils.rs index 43a2fd71..2a10a545 100644 --- a/src-tauri/src/utils.rs +++ b/src-tauri/src/utils.rs @@ -1,10 +1,31 @@ use crate::errors::{Context, Result}; -use crate::{err, Service, SharedState}; +use crate::{err, Registry, Service, SharedState}; +use futures::future; use reqwest::get; use std::collections::HashMap; use std::sync::Arc; -pub async fn fetch_services_manifests(url: &str, state: Arc) -> Result<()> { +pub async fn fetch_all_services_manifests( + registries: &[Registry], + state: &Arc, +) -> Result<()> { + let mut handlers = vec![]; + for registry in registries { + let handler = async move { + if let Err(err) = fetch_services_manifests(registry.url.as_str(), state).await { + println!( + "Failed to fetch {} and save services manifests: {}", + registry.url, err + ); + } + }; + handlers.push(handler); + } + future::join_all(handlers).await; + Ok(()) +} + +async fn fetch_services_manifests(url: &str, state: &Arc) -> Result<()> { let response = get(url) .await .with_context(|| format!("Couldn't fetch the manifest from {url:?}"))?; @@ -13,13 +34,15 @@ pub async fn fetch_services_manifests(url: &str, state: Arc) -> Res .await .with_context(|| "Failed to parse response to list of services")?; let mut services_guard = state.services.lock().await; - // TODO: discuss why do we need global ids, why not use uuids and generate them on each load - *services_guard = services - .into_iter() - // removes services without id - .filter_map(|x| Some((x.id.clone()?, x))) - // removes duplicate services - .collect(); + for service in services { + if !service + .get_id_ref() + .map(|id| services_guard.contains_key(id)) + .unwrap_or_default() + { + services_guard.insert(service.get_id()?, service); + } + } Ok(()) } diff --git a/src/controller/abstractServiceController.ts b/src/controller/abstractServiceController.ts index 98b93e04..8c09d9f0 100644 --- a/src/controller/abstractServiceController.ts +++ b/src/controller/abstractServiceController.ts @@ -1,4 +1,5 @@ import type { Service } from "../modules/service/types"; +import type { Registry } from "../modules/settings/types"; import type { Interface } from "../shared/helpers/interfaces"; import type { DownloadArgs } from "./serviceController"; @@ -23,6 +24,10 @@ abstract class AbstractServiceController { abstract getGPUStats(): Promise>; abstract getInterfaces(): Promise; abstract addService(service: Service): Promise; + abstract addRegistry(registry: Registry): Promise; + abstract deleteRegistry(registry: Registry): Promise; + abstract fetchRegistries(): Promise; + abstract resetDefaultRegistry(): Promise; } export default AbstractServiceController; diff --git a/src/controller/binariesController.ts b/src/controller/binariesController.ts index 8ebca0af..46dfd8de 100644 --- a/src/controller/binariesController.ts +++ b/src/controller/binariesController.ts @@ -1,4 +1,5 @@ import { invoke } from "@tauri-apps/api/tauri"; +import type { Registry } from "modules/settings/types"; import type { Service, ServiceBinary } from "../modules/service/types"; import type { Interface } from "../shared/helpers/interfaces"; @@ -77,6 +78,22 @@ class BinariesController extends AbstractServiceController { async addService(service: Service): Promise { await invoke("add_service", { service }); } + + async addRegistry(registry: Registry): Promise { + await invoke("add_registry", { registry }); + } + + async deleteRegistry(registry: Registry): Promise { + await invoke("delete_registry", { registry }); + } + + async fetchRegistries(): Promise { + return await invoke("fetch_registries"); + } + + async resetDefaultRegistry(): Promise { + return await invoke("reset_default_registry"); + } } export default BinariesController; diff --git a/src/controller/dockerController.ts b/src/controller/dockerController.ts index 839730bd..fd0aa663 100644 --- a/src/controller/dockerController.ts +++ b/src/controller/dockerController.ts @@ -1,3 +1,5 @@ +import type { Registry } from "modules/settings/types"; + import downloadServiceStream from "../modules/service/api/downloadServiceStream"; import type { Service, ServiceDocker } from "../modules/service/types"; import api from "../shared/api/v1"; @@ -94,6 +96,22 @@ class DockerController extends AbstractServiceController { async addService(service: Service): Promise { await api().post("v1/services/", service); } + + async addRegistry(registry: Registry): Promise { + await api().post(`v1/registries/`, registry); + } + + async deleteRegistry(registry: Registry): Promise { + await api().delete(`v1/registries/?url=${registry.url}`); + } + + async fetchRegistries(): Promise { + return await api().get(`v1/registries/`); + } + + async resetDefaultRegistry(): Promise { + throw new Error("Method not implemented."); + } } export default DockerController; diff --git a/src/controller/serviceController.ts b/src/controller/serviceController.ts index 6a61ceec..aaa3a9d6 100644 --- a/src/controller/serviceController.ts +++ b/src/controller/serviceController.ts @@ -1,4 +1,5 @@ import type { Service } from "../modules/service/types"; +import type { Registry } from "../modules/settings/types"; import type { Interface } from "../shared/helpers/interfaces"; import useSettingStore from "../shared/store/setting"; @@ -33,6 +34,10 @@ interface IServiceController { getGPUStats(serviceType: Service["serviceType"]): Promise; getInterfaces(serviceType: Service["serviceType"]): Promise; addService(service: Service, serviceType: Service["serviceType"]): Promise; + addRegistry(registry: Registry, serviceType: Service["serviceType"]): Promise; + deleteRegistry(registry: Registry, serviceType: Service["serviceType"]): Promise; + fetchRegistries(serviceType: Service["serviceType"]): Promise; + resetDefaultRegistry(serviceType: Service["serviceType"]): Promise; } class ServiceController implements IServiceController { @@ -207,6 +212,40 @@ class ServiceController implements IServiceController { await this.binariesController.addService(service); } } + + async addRegistry(registry: Registry, serviceType: Service["serviceType"]): Promise { + if (serviceType === "docker") { + await this.dockerController.addRegistry(registry); + } else if (serviceType === "binary") { + await this.binariesController.addRegistry(registry); + } + } + + async deleteRegistry(registry: Registry, serviceType: Service["serviceType"]): Promise { + if (serviceType === "docker") { + await this.dockerController.deleteRegistry(registry); + } else if (serviceType === "binary") { + await this.binariesController.deleteRegistry(registry); + } + } + + async fetchRegistries(serviceType: Service["serviceType"]): Promise { + if (serviceType === "docker") { + return await this.dockerController.fetchRegistries(); + } else if (serviceType === "binary") { + return await this.binariesController.fetchRegistries(); + } else { + return []; + } + } + + async resetDefaultRegistry(serviceType: Service["serviceType"]): Promise { + if (serviceType === "docker") { + return await this.dockerController.resetDefaultRegistry(); + } else if (serviceType === "binary") { + return await this.binariesController.resetDefaultRegistry(); + } + } } export default ServiceController; diff --git a/src/modules/service/components/Service.tsx b/src/modules/service/components/Service.tsx index f0c0804d..5de10c41 100644 --- a/src/modules/service/components/Service.tsx +++ b/src/modules/service/components/Service.tsx @@ -139,6 +139,7 @@ const Service = () => { // eslint-disable-next-line react-hooks/exhaustive-deps JSON.stringify(progresses), isServicesLoading, + services, ]); return ( diff --git a/src/modules/settings/api/addRegistry.ts b/src/modules/settings/api/addRegistry.ts deleted file mode 100644 index 8caf6927..00000000 --- a/src/modules/settings/api/addRegistry.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { AxiosResponse } from "axios"; -import type { Message } from "modules/service/types"; - -import api from "../../../shared/api/v1"; -import type { Registries } from "../types"; - -const addRegistry = async (data: Registries): Promise> => { - return api().post(`v1/registries/`, data); -}; - -export default addRegistry; diff --git a/src/modules/settings/api/deleteRegistry.ts b/src/modules/settings/api/deleteRegistry.ts deleted file mode 100644 index e7f944fc..00000000 --- a/src/modules/settings/api/deleteRegistry.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { AxiosResponse } from "axios"; -import type { Message } from "modules/service/types"; - -import api from "../../../shared/api/v1"; -import type { Registries } from "../types"; - -const deleteRegistry = async (data: Registries): Promise> => { - return api().delete(`v1/registries/?url=${data.url}`); -}; - -export default deleteRegistry; diff --git a/src/modules/settings/api/fetchRegistries.ts b/src/modules/settings/api/fetchRegistries.ts deleted file mode 100644 index ddba66d6..00000000 --- a/src/modules/settings/api/fetchRegistries.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { AxiosResponse } from "axios"; - -import api from "../../../shared/api/v1"; -import type { Registries } from "../types"; - -const fetchRegistries = async (): Promise> => { - return api().get(`v1/registries/`); -}; - -export default fetchRegistries; diff --git a/src/modules/settings/components/Registries.tsx b/src/modules/settings/components/Registries.tsx index 22b7a084..3cdad051 100644 --- a/src/modules/settings/components/Registries.tsx +++ b/src/modules/settings/components/Registries.tsx @@ -1,79 +1,92 @@ -import { useMutation, useQuery } from "@tanstack/react-query"; import type { FormEvent } from "react"; import { useState } from "react"; import { toast } from "react-toastify"; import MinusArrow from "shared/components/MinusArrow"; -import PlusArrow from "shared/components/PlusArrow"; import PrimaryButton from "shared/components/PrimaryButton"; import Spinner from "shared/components/Spinner"; -import addRegistry from "../api/addRegistry"; -import deleteRegistry from "../api/deleteRegistry"; -import fetchRegistries from "../api/fetchRegistries"; +import useAddRegistry from "../../../shared/hooks/useAddRegistry"; +import useDeleteRegistry from "../../../shared/hooks/useDeleteRegistry"; +import useFetchRegistries from "../../../shared/hooks/useFetchRegistries"; +import useResetDefaultRegistry from "../../../shared/hooks/useResetDefaultRegistry"; const Registries = () => { const [registryUrl, setRegistryUrl] = useState(""); - + const { mutate: addRegistry, isPending: isAddRegistryPending } = useAddRegistry(); + const { mutate: deleteRegistry } = useDeleteRegistry(); + const { mutateAsync: resetDefaultRegistry } = useResetDefaultRegistry(); const { - isLoading, - data: response, - refetch, - } = useQuery({ queryKey: ["registries"], queryFn: fetchRegistries }); - - const { mutate: mutateAddRegistry, isPending: isPendingAddRegistry } = useMutation({ - mutationFn: addRegistry, - }); - const { mutate: mutateDeleteRegistry } = useMutation({ mutationFn: deleteRegistry }); - - const registries = response?.data || []; + data: registries, + refetch: refetchRegistries, + isLoading: isFetchRegistriesLoading, + } = useFetchRegistries(); const onSubmit = (e: FormEvent) => { e.preventDefault(); - mutateAddRegistry( + addRegistry( { url: registryUrl }, { - onSuccess: () => { + onSuccess: async () => { setRegistryUrl(""); - refetch(); - toast.success("Registry added successfully"); + await refetchRegistries(); + toast.success("Registry added successfully", { toastId: "add-registry-success" }); }, - onError: () => { - toast.error("Something went wrong while adding registry"); + onError: (err) => { + console.error("err", err); + toast.error("Something went wrong while adding registry", { + toastId: "add-registry-error", + }); }, }, ); }; const handleDelete = (url: string) => { - mutateDeleteRegistry( + deleteRegistry( { url }, { - onSuccess: () => { - refetch(); - toast.success("Registry deleted successfully"); + onSuccess: async () => { + await refetchRegistries(); + toast.success("Registry deleted successfully", { toastId: "delete-registry-success" }); }, onError: () => { - toast.error("Something went wrong while deleting registry"); + toast.error("Something went wrong while deleting registry", { + toastId: "delete-registry-error", + }); }, }, ); }; + const handleRegistryDefaultReset = async (e: React.MouseEvent) => { + e.preventDefault(); + try { + await resetDefaultRegistry(); + await refetchRegistries(); + toast.success("Registry reset successful", { toastId: "delete-reset-success" }); + } catch (err) { + console.error("err", err); + toast.error("Something went wrong while resetting registry", { + toastId: "delete-reset-error", + }); + } + }; + return (
-
- -
+
+

Registries

+
- {isLoading && ( + {isFetchRegistriesLoading && (
)} - {registries.map((registry, index) => { + {registries?.map((registry, index) => { return ( -
+
{ @@ -98,16 +111,17 @@ const Registries = () => { onChange={(e) => setRegistryUrl(e.target.value)} required /> - +
- - {isPendingAddRegistry ? "Updating..." : "Add Registry"} + + Reset + + + {isAddRegistryPending ? "Updating..." : "Add Registry"}
diff --git a/src/modules/settings/types.ts b/src/modules/settings/types.ts index a8b51149..5f9d3756 100644 --- a/src/modules/settings/types.ts +++ b/src/modules/settings/types.ts @@ -2,6 +2,6 @@ export type Health = { status: boolean; }; -export type Registries = { +export type Registry = { url: string; }; diff --git a/src/shared/hooks/useAddRegistry.ts b/src/shared/hooks/useAddRegistry.ts new file mode 100644 index 00000000..d0044ea8 --- /dev/null +++ b/src/shared/hooks/useAddRegistry.ts @@ -0,0 +1,21 @@ +import { useMutation } from "@tanstack/react-query"; + +import ServiceController from "../../controller/serviceController"; +import type { Service } from "../../modules/service/types"; +import type { Registry } from "../../modules/settings/types"; +import { isDesktopEnv } from "../helpers/utils"; + +const useAddRegistry = () => { + const controller = ServiceController.getInstance(); + let serviceType: Service["serviceType"]; + if (isDesktopEnv()) { + serviceType = "binary"; + } else { + serviceType = "docker"; + } + return useMutation({ + mutationFn: (registry: Registry) => controller.addRegistry(registry, serviceType), + }); +}; + +export default useAddRegistry; diff --git a/src/shared/hooks/useDeleteRegistry.ts b/src/shared/hooks/useDeleteRegistry.ts new file mode 100644 index 00000000..f7fafb96 --- /dev/null +++ b/src/shared/hooks/useDeleteRegistry.ts @@ -0,0 +1,21 @@ +import { useMutation } from "@tanstack/react-query"; + +import ServiceController from "../../controller/serviceController"; +import type { Service } from "../../modules/service/types"; +import type { Registry } from "../../modules/settings/types"; +import { isDesktopEnv } from "../helpers/utils"; + +const useDeleteRegistry = () => { + const controller = ServiceController.getInstance(); + let serviceType: Service["serviceType"]; + if (isDesktopEnv()) { + serviceType = "binary"; + } else { + serviceType = "docker"; + } + return useMutation({ + mutationFn: (registry: Registry) => controller.deleteRegistry(registry, serviceType), + }); +}; + +export default useDeleteRegistry; diff --git a/src/shared/hooks/useFetchRegistries.ts b/src/shared/hooks/useFetchRegistries.ts new file mode 100644 index 00000000..458427ab --- /dev/null +++ b/src/shared/hooks/useFetchRegistries.ts @@ -0,0 +1,23 @@ +import { useQuery } from "@tanstack/react-query"; + +import ServiceController from "../../controller/serviceController"; +import type { Service } from "../../modules/service/types"; +import { isDesktopEnv } from "../helpers/utils"; + +export const SERVICE_KEY = "fetchRegistries"; + +const useFetchRegistries = () => { + let serviceType: Service["serviceType"]; + if (isDesktopEnv()) { + serviceType = "binary"; + } else { + serviceType = "docker"; + } + const controller = ServiceController.getInstance(); + return useQuery({ + queryKey: [SERVICE_KEY], + queryFn: () => controller.fetchRegistries(serviceType), + }); +}; + +export default useFetchRegistries; diff --git a/src/shared/hooks/useGetServices.ts b/src/shared/hooks/useGetServices.ts index bee04a93..c9792a82 100644 --- a/src/shared/hooks/useGetServices.ts +++ b/src/shared/hooks/useGetServices.ts @@ -10,7 +10,6 @@ const useGetServices = () => { const controller = ServiceController.getInstance(); // Here we check the env to determine if we should use the binary or docker service // and fetch the services accordingly - // TODO: Is it ok? let serviceType: Service["serviceType"]; if (isDesktopEnv()) { serviceType = "binary"; diff --git a/src/shared/hooks/useResetDefaultRegistry.ts b/src/shared/hooks/useResetDefaultRegistry.ts new file mode 100644 index 00000000..023bbe02 --- /dev/null +++ b/src/shared/hooks/useResetDefaultRegistry.ts @@ -0,0 +1,20 @@ +import { useMutation } from "@tanstack/react-query"; + +import ServiceController from "../../controller/serviceController"; +import type { Service } from "../../modules/service/types"; +import { isDesktopEnv } from "../helpers/utils"; + +const useResetDefaultRegistry = () => { + const controller = ServiceController.getInstance(); + let serviceType: Service["serviceType"]; + if (isDesktopEnv()) { + serviceType = "binary"; + } else { + serviceType = "docker"; + } + return useMutation({ + mutationFn: () => controller.resetDefaultRegistry(serviceType), + }); +}; + +export default useResetDefaultRegistry;