Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Added SessionGuard component to manage session expiration and online status. - Updated AuthProvider to streamline session fetching and handling. - Introduced IdentityProvidersSection for managing OAuth, SAML, and LDAP identity providers. - Implemented identity provider guides for easier configuration. - Enhanced mail settings with infinite scroll option for improved user experience. - Updated global styles and layout components for better consistency across the application.
114 lines
3.2 KiB
TypeScript
114 lines
3.2 KiB
TypeScript
'use client'
|
|
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
|
import { apiClient } from '../client'
|
|
import { useAuthReady } from '../use-auth-ready'
|
|
import type { ApiFolder, ApiLabel, ApiIdentity } from '../types'
|
|
|
|
export function useFolders(accountId?: string) {
|
|
const { ready, authenticated } = useAuthReady()
|
|
|
|
return useQuery({
|
|
queryKey: ['folders', accountId],
|
|
queryFn: async () => {
|
|
const res = await apiClient.get<ApiFolder[] | { folders: ApiFolder[] }>(
|
|
'/mail/folders',
|
|
{ account_id: accountId }
|
|
)
|
|
return Array.isArray(res) ? res : (res.folders ?? [])
|
|
},
|
|
enabled: ready && authenticated && !!accountId,
|
|
staleTime: 5 * 60_000,
|
|
})
|
|
}
|
|
|
|
export function useLabels() {
|
|
const { ready, authenticated } = useAuthReady()
|
|
|
|
return useQuery({
|
|
queryKey: ['labels'],
|
|
queryFn: async () => {
|
|
const res = await apiClient.get<ApiLabel[] | { labels: ApiLabel[] }>(
|
|
'/mail/labels'
|
|
)
|
|
return Array.isArray(res) ? res : (res.labels ?? [])
|
|
},
|
|
staleTime: 5 * 60_000,
|
|
enabled: ready && authenticated,
|
|
retry: 1,
|
|
})
|
|
}
|
|
|
|
export function useCreateLabel() {
|
|
const queryClient = useQueryClient()
|
|
|
|
return useMutation({
|
|
mutationFn: (data: { name: string; color: string }) =>
|
|
apiClient.post<ApiLabel>('/mail/labels', data),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ['labels'] })
|
|
},
|
|
})
|
|
}
|
|
|
|
export function useUpdateLabel() {
|
|
const queryClient = useQueryClient()
|
|
|
|
return useMutation({
|
|
mutationFn: ({ id, ...data }: { id: string; name?: string; color?: string }) =>
|
|
apiClient.put<ApiLabel>(`/mail/labels/${id}`, data),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ['labels'] })
|
|
},
|
|
})
|
|
}
|
|
|
|
export function useDeleteLabel() {
|
|
const queryClient = useQueryClient()
|
|
|
|
return useMutation({
|
|
mutationFn: (id: string) => apiClient.delete(`/mail/labels/${id}`),
|
|
onMutate: async (id) => {
|
|
await queryClient.cancelQueries({ queryKey: ['labels'] })
|
|
const previous = queryClient.getQueryData<ApiLabel[]>(['labels'])
|
|
queryClient.setQueryData<ApiLabel[]>(['labels'], (old) =>
|
|
old?.filter((l) => l.id !== id),
|
|
)
|
|
return { previous }
|
|
},
|
|
onError: (_err, _id, context) => {
|
|
if (context?.previous) {
|
|
queryClient.setQueryData(['labels'], context.previous)
|
|
}
|
|
},
|
|
onSettled: () => {
|
|
queryClient.invalidateQueries({ queryKey: ['labels'] })
|
|
},
|
|
})
|
|
}
|
|
|
|
export function useReorderLabels() {
|
|
const queryClient = useQueryClient()
|
|
|
|
return useMutation({
|
|
mutationFn: (items: { id: string; sort_order: number }[]) =>
|
|
apiClient.post<void>('/mail/labels/reorder', { items }),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ['labels'] })
|
|
},
|
|
})
|
|
}
|
|
|
|
export function useIdentities(accountId?: string) {
|
|
return useQuery({
|
|
queryKey: ['identities', accountId],
|
|
queryFn: async () => {
|
|
const res = await apiClient.get<ApiIdentity[] | { identities: ApiIdentity[] }>(
|
|
`/mail/accounts/${accountId}/identities`
|
|
)
|
|
return Array.isArray(res) ? res : (res.identities ?? [])
|
|
},
|
|
enabled: !!accountId,
|
|
})
|
|
}
|