Files
cameleer-saas/ui/src/api/tenant-hooks.ts
hsiegeln e2e5c794a2
All checks were successful
CI / build (push) Successful in 1m19s
CI / docker (push) Successful in 48s
feat: add server upgrade action — force-pull latest images and re-provision
Restart only stops/starts existing containers with the same image. The new
upgrade action removes server + UI containers, force-pulls the latest
Docker images, then re-provisions (preserving app containers, volumes, and
networks). Available to both vendor (tenant detail) and tenant admin
(dashboard).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 10:45:45 +02:00

146 lines
4.6 KiB
TypeScript

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from './client';
import type { DashboardData, TenantLicenseData, TenantSettings, AuditLogPage, AuditLogFilters, SsoConnector, CreateSsoConnectorRequest, SsoTestResult } from '../types/api';
export function useTenantDashboard() {
return useQuery<DashboardData>({
queryKey: ['tenant', 'dashboard'],
queryFn: () => api.get('/tenant/dashboard'),
refetchInterval: 30_000,
});
}
export function useRestartServer() {
const qc = useQueryClient();
return useMutation<void, Error, void>({
mutationFn: () => api.post('/tenant/server/restart'),
onSuccess: () => qc.invalidateQueries({ queryKey: ['tenant', 'dashboard'] }),
});
}
export function useUpgradeServer() {
const qc = useQueryClient();
return useMutation<void, Error, void>({
mutationFn: () => api.post('/tenant/server/upgrade'),
onSuccess: () => qc.invalidateQueries({ queryKey: ['tenant', 'dashboard'] }),
});
}
export function useTenantLicense() {
return useQuery<TenantLicenseData>({
queryKey: ['tenant', 'license'],
queryFn: () => api.get('/tenant/license'),
});
}
// SSO connector hooks
export function useSsoConnectors() {
return useQuery<SsoConnector[]>({
queryKey: ['tenant', 'sso'],
queryFn: () => api.get('/tenant/sso'),
});
}
export function useSsoConnector(id: string | null) {
return useQuery<SsoConnector>({
queryKey: ['tenant', 'sso', id],
queryFn: () => api.get(`/tenant/sso/${id}`),
enabled: !!id,
});
}
export function useCreateSsoConnector() {
const qc = useQueryClient();
return useMutation<SsoConnector, Error, CreateSsoConnectorRequest>({
mutationFn: (req) => api.post('/tenant/sso', req),
onSuccess: () => qc.invalidateQueries({ queryKey: ['tenant', 'sso'] }),
});
}
export function useUpdateSsoConnector() {
const qc = useQueryClient();
return useMutation<SsoConnector, Error, { id: string; updates: Record<string, unknown> }>({
mutationFn: ({ id, updates }) => api.patch(`/tenant/sso/${id}`, updates),
onSuccess: () => qc.invalidateQueries({ queryKey: ['tenant', 'sso'] }),
});
}
export function useDeleteSsoConnector() {
const qc = useQueryClient();
return useMutation<void, Error, string>({
mutationFn: (id) => api.delete(`/tenant/sso/${id}`),
onSuccess: () => qc.invalidateQueries({ queryKey: ['tenant', 'sso'] }),
});
}
export function useTestSsoConnector() {
return useMutation<SsoTestResult, Error, string>({
mutationFn: (id) => api.post(`/tenant/sso/${id}/test`),
});
}
export function useTenantTeam() {
return useQuery<Array<Record<string, unknown>>>({
queryKey: ['tenant', 'team'],
queryFn: () => api.get('/tenant/team'),
});
}
export function useInviteTeamMember() {
const qc = useQueryClient();
return useMutation<{ userId: string }, Error, { email: string; roleId: string }>({
mutationFn: (body) => api.post('/tenant/team/invite', body),
onSuccess: () => qc.invalidateQueries({ queryKey: ['tenant', 'team'] }),
});
}
export function useRemoveTeamMember() {
const qc = useQueryClient();
return useMutation<void, Error, string>({
mutationFn: (userId) => api.delete(`/tenant/team/${userId}`),
onSuccess: () => qc.invalidateQueries({ queryKey: ['tenant', 'team'] }),
});
}
export function useResetServerAdminPassword() {
return useMutation<void, Error, string>({
mutationFn: (password) => api.post('/tenant/server/admin-password', { password }),
});
}
export function useChangeOwnPassword() {
return useMutation<void, Error, string>({
mutationFn: (password) => api.post('/tenant/password', { password }),
});
}
export function useResetTeamMemberPassword() {
return useMutation<void, Error, { userId: string; password: string }>({
mutationFn: ({ userId, password }) =>
api.post(`/tenant/team/${userId}/password`, { password }),
});
}
export function useTenantSettings() {
return useQuery<TenantSettings>({
queryKey: ['tenant', 'settings'],
queryFn: () => api.get('/tenant/settings'),
});
}
export function useTenantAuditLog(filters: Omit<AuditLogFilters, 'tenantId'>) {
const params = new URLSearchParams();
if (filters.action) params.set('action', filters.action);
if (filters.result) params.set('result', filters.result);
if (filters.search) params.set('search', filters.search);
if (filters.from) params.set('from', filters.from);
if (filters.to) params.set('to', filters.to);
params.set('page', String(filters.page ?? 0));
params.set('size', String(filters.size ?? 25));
return useQuery<AuditLogPage>({
queryKey: ['tenant', 'audit', filters],
queryFn: () => api.get(`/tenant/audit?${params.toString()}`),
});
}