services -> domains

This commit is contained in:
2026-07-10 20:46:22 +00:00
parent 3c99d26830
commit 79c0c32b98
45 changed files with 1447 additions and 1270 deletions

View File

@@ -1,6 +1,10 @@
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '../services/api/client';
interface DaemonStatus {
active: boolean;
}
interface CentralStatus {
status: string;
version: string;
@@ -10,6 +14,7 @@ interface CentralStatus {
appsDir: string;
setupFiles: string;
pendingRestart: boolean;
daemons?: Record<string, DaemonStatus>;
}
/**

View File

@@ -1,62 +1,61 @@
import { useState, useEffect } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiService } from '../services/api-legacy';
import type { GlobalConfig, GlobalConfigResponse } from '../types';
import type { CentralState, CentralStateResponse } from '../types';
interface CreateConfigResponse {
status: string;
}
/**
* Hook for managing Wild Central global configuration
* Endpoint: /api/v1/config
* Hook for managing Wild Central runtime state
* Endpoint: /api/v1/state
* File: {dataDir}/state.yaml
*/
export const useConfig = () => {
const queryClient = useQueryClient();
const [showConfigSetup, setShowConfigSetup] = useState(false);
const configQuery = useQuery<GlobalConfigResponse>({
queryKey: ['globalConfig'],
const stateQuery = useQuery<CentralStateResponse>({
queryKey: ['state'],
queryFn: () => apiService.getConfig(),
});
// Update showConfigSetup based on query data
useEffect(() => {
if (configQuery.data) {
setShowConfigSetup(configQuery.data.configured === false);
if (stateQuery.data) {
setShowConfigSetup(stateQuery.data.configured === false);
}
}, [configQuery.data]);
}, [stateQuery.data]);
const createConfigMutation = useMutation<CreateConfigResponse, Error, GlobalConfig>({
mutationFn: (config) => apiService.createConfig(config),
const createStateMutation = useMutation<CreateConfigResponse, Error, CentralState>({
mutationFn: (state) => apiService.createConfig(state),
onSuccess: () => {
// Invalidate and refetch config after successful creation
queryClient.invalidateQueries({ queryKey: ['globalConfig'] });
queryClient.invalidateQueries({ queryKey: ['state'] });
setShowConfigSetup(false);
},
});
const updateConfigMutation = useMutation<CreateConfigResponse, Error, GlobalConfig>({
mutationFn: (config) => apiService.updateConfig(config),
const updateStateMutation = useMutation<CreateConfigResponse, Error, CentralState>({
mutationFn: (state) => apiService.updateConfig(state),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['globalConfig'] });
queryClient.invalidateQueries({ queryKey: ['state'] });
// Immediately re-check daemon status so the pending-restart banner appears
queryClient.invalidateQueries({ queryKey: ['central', 'status'] });
},
});
return {
config: configQuery.data?.config || null,
isConfigured: configQuery.data?.configured || false,
config: stateQuery.data?.state || null,
isConfigured: stateQuery.data?.configured || false,
showConfigSetup,
setShowConfigSetup,
isLoading: configQuery.isLoading,
isCreating: createConfigMutation.isPending,
isUpdating: updateConfigMutation.isPending,
error: configQuery.error || createConfigMutation.error || updateConfigMutation.error,
createConfig: createConfigMutation.mutate,
updateConfig: updateConfigMutation.mutateAsync,
refetch: configQuery.refetch,
isLoading: stateQuery.isLoading,
isCreating: createStateMutation.isPending,
isUpdating: updateStateMutation.isPending,
error: stateQuery.error || createStateMutation.error || updateStateMutation.error,
createConfig: createStateMutation.mutate,
updateConfig: updateStateMutation.mutateAsync,
refetch: stateQuery.refetch,
};
};
};

View File

@@ -14,10 +14,12 @@ export const useDdns = () => {
const triggerMutation = useMutation({
mutationFn: () => ddnsApi.trigger(),
onSuccess: () => {
// Refresh status shortly after trigger
setTimeout(() => {
queryClient.invalidateQueries({ queryKey: ['ddns', 'status'] });
}, 2000);
// Refresh status after trigger — stagger to catch async completion
for (const delay of [1000, 3000, 6000]) {
setTimeout(() => {
queryClient.invalidateQueries({ queryKey: ['ddns', 'status'] });
}, delay);
}
},
});

View File

@@ -1,16 +1,16 @@
import { useQuery } from '@tanstack/react-query';
import { servicesApi } from '../services/api/networking';
import { domainsApi } from '../services/api/networking';
export const useServices = () => {
export const useDomains = () => {
const query = useQuery({
queryKey: ['services'],
queryFn: () => servicesApi.list(),
queryKey: ['domains'],
queryFn: () => domainsApi.list(),
refetchInterval: 30000,
staleTime: 10000,
});
return {
services: query.data?.services ?? [],
domains: query.data?.domains ?? [],
isLoading: query.isLoading,
error: query.error,
};