- Add comprehensive database migrations (001-024) for schema evolution - Enhance API schema with expanded type definitions and resolvers - Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth - Implement new services: AI optimization, billing, blockchain, compliance, marketplace - Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage) - Update Crossplane provider with enhanced VM management capabilities - Add comprehensive test suite for API endpoints and services - Update frontend components with improved GraphQL subscriptions and real-time updates - Enhance security configurations and headers (CSP, CORS, etc.) - Update documentation and configuration files - Add new CI/CD workflows and validation scripts - Implement design system improvements and UI enhancements
111 lines
2.7 KiB
TypeScript
111 lines
2.7 KiB
TypeScript
'use client'
|
|
|
|
import { useSubscription } from '@apollo/client'
|
|
import { gql } from 'graphql-tag'
|
|
import { useEffect } from 'react'
|
|
import { useQueryClient } from '@tanstack/react-query'
|
|
|
|
const RESOURCE_CREATED_SUBSCRIPTION = gql`
|
|
subscription ResourceCreated {
|
|
resourceCreated {
|
|
id
|
|
name
|
|
type
|
|
status
|
|
site {
|
|
id
|
|
name
|
|
}
|
|
createdAt
|
|
}
|
|
}
|
|
`
|
|
|
|
const RESOURCE_UPDATED_SUBSCRIPTION = gql`
|
|
subscription ResourceUpdated($id: ID!) {
|
|
resourceUpdated(id: $id) {
|
|
id
|
|
name
|
|
type
|
|
status
|
|
metadata
|
|
updatedAt
|
|
}
|
|
}
|
|
`
|
|
|
|
const RESOURCE_DELETED_SUBSCRIPTION = gql`
|
|
subscription ResourceDeleted($id: ID!) {
|
|
resourceDeleted(id: $id)
|
|
}
|
|
`
|
|
|
|
export function useResourceCreated() {
|
|
const queryClient = useQueryClient()
|
|
|
|
const { data, error } = useSubscription(RESOURCE_CREATED_SUBSCRIPTION)
|
|
|
|
useEffect(() => {
|
|
if (data?.resourceCreated) {
|
|
// Invalidate queries to refetch updated data
|
|
queryClient.invalidateQueries({ queryKey: ['resources'] })
|
|
|
|
// Optionally show toast notification
|
|
if (typeof window !== 'undefined' && (window as any).toast) {
|
|
;(window as any).toast({
|
|
title: 'New Resource Created',
|
|
description: `${data.resourceCreated.name} has been created`,
|
|
})
|
|
}
|
|
}
|
|
}, [data, queryClient])
|
|
|
|
return { data: data?.resourceCreated, error }
|
|
}
|
|
|
|
export function useResourceUpdated(resourceId: string) {
|
|
const queryClient = useQueryClient()
|
|
|
|
const { data, error } = useSubscription(RESOURCE_UPDATED_SUBSCRIPTION, {
|
|
variables: { id: resourceId },
|
|
skip: !resourceId,
|
|
})
|
|
|
|
useEffect(() => {
|
|
if (data?.resourceUpdated) {
|
|
// Invalidate specific resource and list queries
|
|
queryClient.invalidateQueries({ queryKey: ['resources'] })
|
|
queryClient.invalidateQueries({ queryKey: ['resource', resourceId] })
|
|
}
|
|
}, [data, queryClient, resourceId])
|
|
|
|
return { data: data?.resourceUpdated, error }
|
|
}
|
|
|
|
export function useResourceDeleted(resourceId: string) {
|
|
const queryClient = useQueryClient()
|
|
|
|
const { data, error } = useSubscription(RESOURCE_DELETED_SUBSCRIPTION, {
|
|
variables: { id: resourceId },
|
|
skip: !resourceId,
|
|
})
|
|
|
|
useEffect(() => {
|
|
if (data?.resourceDeleted) {
|
|
// Remove from cache and invalidate queries
|
|
queryClient.removeQueries({ queryKey: ['resource', resourceId] })
|
|
queryClient.invalidateQueries({ queryKey: ['resources'] })
|
|
|
|
if (typeof window !== 'undefined' && (window as any).toast) {
|
|
;(window as any).toast({
|
|
title: 'Resource Deleted',
|
|
description: 'Resource has been deleted',
|
|
})
|
|
}
|
|
}
|
|
}, [data, queryClient, resourceId])
|
|
|
|
return { deletedId: data?.resourceDeleted, error }
|
|
}
|
|
|