Open deploy progress immediately and improve delete row glass overlay.
Track in-progress deploys in the client store so the progress modal opens on click without waiting for the applications list refetch. Show deleting state as a blurred glass overlay on table rows and service cards instead of replacing row content. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,9 +2,19 @@
|
||||
|
||||
import { create } from 'zustand';
|
||||
|
||||
export type TrackedDeploy = {
|
||||
appId: string;
|
||||
appName: string;
|
||||
startedAt: number;
|
||||
};
|
||||
|
||||
interface DeployProgressState {
|
||||
minimized: boolean;
|
||||
focusedAppId: string | null;
|
||||
/** Optimistic deploy tracking — modal opens before applications list refetches */
|
||||
tracked: TrackedDeploy[];
|
||||
startDeploy: (appId: string, appName?: string) => void;
|
||||
stopTracking: (appId: string) => void;
|
||||
minimize: (appId: string) => void;
|
||||
expand: (appId?: string) => void;
|
||||
}
|
||||
@@ -12,6 +22,25 @@ interface DeployProgressState {
|
||||
export const useDeployProgressStore = create<DeployProgressState>((set) => ({
|
||||
minimized: false,
|
||||
focusedAppId: null,
|
||||
tracked: [],
|
||||
startDeploy: (appId, appName) =>
|
||||
set((state) => ({
|
||||
minimized: false,
|
||||
focusedAppId: appId,
|
||||
tracked: [
|
||||
...state.tracked.filter((t) => t.appId !== appId),
|
||||
{ appId, appName: appName?.trim() || 'Application', startedAt: Date.now() },
|
||||
],
|
||||
})),
|
||||
stopTracking: (appId) =>
|
||||
set((state) => {
|
||||
const tracked = state.tracked.filter((t) => t.appId !== appId);
|
||||
const focusedAppId =
|
||||
state.focusedAppId === appId
|
||||
? tracked[0]?.appId ?? null
|
||||
: state.focusedAppId;
|
||||
return { tracked, focusedAppId };
|
||||
}),
|
||||
minimize: (appId) => set({ minimized: true, focusedAppId: appId }),
|
||||
expand: (appId) =>
|
||||
set((state) => ({
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
'use client';
|
||||
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import api from '@/lib/api';
|
||||
import type { BuildProgress } from '@/components/build-progress-modal';
|
||||
import { useDeployProgressStore } from '@/lib/deploy-progress-store';
|
||||
|
||||
/** Open deploy progress UI immediately and warm build-progress cache. */
|
||||
export function useDeployProgressActions() {
|
||||
const queryClient = useQueryClient();
|
||||
const startDeploy = useDeployProgressStore((s) => s.startDeploy);
|
||||
|
||||
const notifyDeployStarted = (appId: string, appName?: string) => {
|
||||
startDeploy(appId, appName);
|
||||
void queryClient.invalidateQueries({ queryKey: ['applications'] });
|
||||
void queryClient.invalidateQueries({ queryKey: ['application', appId] });
|
||||
void queryClient.invalidateQueries({ queryKey: ['deployments', appId] });
|
||||
void queryClient.prefetchQuery({
|
||||
queryKey: ['build-progress', appId],
|
||||
queryFn: () =>
|
||||
api
|
||||
.get<{ progress: BuildProgress | null }>(`/deployments/applications/${appId}/build-progress`)
|
||||
.then((r) => r.data.progress),
|
||||
staleTime: 0,
|
||||
});
|
||||
};
|
||||
|
||||
return { notifyDeployStarted };
|
||||
}
|
||||
Reference in New Issue
Block a user