fix: instance link includes domain, project delete cleans up containers and proxies
- InstanceCard appends settings domain to subdomain link (stage-dev-app.example.com instead of just stage-dev-app) - Project deletion now removes Docker containers and proxy routes before deleting DB records - Pass domain from settings to InstanceCard via project detail page
This commit is contained in:
@@ -169,6 +169,26 @@ func (s *Server) updateProject(w http.ResponseWriter, r *http.Request) {
|
|||||||
// deleteProject handles DELETE /api/projects/{id}.
|
// deleteProject handles DELETE /api/projects/{id}.
|
||||||
func (s *Server) deleteProject(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) deleteProject(w http.ResponseWriter, r *http.Request) {
|
||||||
id := chi.URLParam(r, "id")
|
id := chi.URLParam(r, "id")
|
||||||
|
|
||||||
|
// Clean up Docker containers and proxy routes before deleting the project.
|
||||||
|
ctx := r.Context()
|
||||||
|
stages, _ := s.store.GetStagesByProjectID(id)
|
||||||
|
for _, stage := range stages {
|
||||||
|
instances, _ := s.store.GetInstancesByStageID(stage.ID)
|
||||||
|
for _, inst := range instances {
|
||||||
|
if inst.ContainerID != "" {
|
||||||
|
if err := s.docker.RemoveContainer(ctx, inst.ContainerID, true); err != nil {
|
||||||
|
slog.Warn("delete project: remove container", "container", inst.ContainerID, "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if inst.ProxyRouteID != "" {
|
||||||
|
if err := s.proxyProvider.DeleteRoute(ctx, inst.ProxyRouteID); err != nil {
|
||||||
|
slog.Warn("delete project: delete proxy route", "route", inst.ProxyRouteID, "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.store.DeleteProject(id); err != nil {
|
if err := s.store.DeleteProject(id); err != nil {
|
||||||
if errors.Is(err, store.ErrNotFound) {
|
if errors.Is(err, store.ErrNotFound) {
|
||||||
respondNotFound(w, "project")
|
respondNotFound(w, "project")
|
||||||
|
|||||||
@@ -13,17 +13,20 @@
|
|||||||
interface Props {
|
interface Props {
|
||||||
instance: Instance;
|
instance: Instance;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
|
domain?: string;
|
||||||
onchange?: () => void;
|
onchange?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { instance, projectId, onchange }: Props = $props();
|
const { instance, projectId, domain = '', onchange }: Props = $props();
|
||||||
|
|
||||||
let loading = $state(false);
|
let loading = $state(false);
|
||||||
let error = $state('');
|
let error = $state('');
|
||||||
let confirmAction = $state<'stop' | 'restart' | 'remove' | null>(null);
|
let confirmAction = $state<'stop' | 'restart' | 'remove' | null>(null);
|
||||||
|
|
||||||
const subdomainUrl = $derived(
|
const subdomainUrl = $derived(
|
||||||
instance.subdomain ? `https://${instance.subdomain}` : ''
|
instance.subdomain && domain
|
||||||
|
? `https://${instance.subdomain}.${domain}`
|
||||||
|
: instance.subdomain ? `https://${instance.subdomain}` : ''
|
||||||
);
|
);
|
||||||
|
|
||||||
const timeSinceCreated = $derived(() => {
|
const timeSinceCreated = $derived(() => {
|
||||||
|
|||||||
@@ -106,6 +106,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let tagsLoading = $state(false);
|
let tagsLoading = $state(false);
|
||||||
|
let settingsDomain = $state('');
|
||||||
|
|
||||||
let showDeleteConfirm = $state(false);
|
let showDeleteConfirm = $state(false);
|
||||||
|
|
||||||
@@ -142,6 +143,11 @@
|
|||||||
} catch {
|
} catch {
|
||||||
deploys = [];
|
deploys = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const settings = await api.getSettings();
|
||||||
|
settingsDomain = settings.domain ?? '';
|
||||||
|
} catch { /* non-critical */ }
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e instanceof Error ? e.message : $t('projectDetail.loadFailed');
|
error = e instanceof Error ? e.message : $t('projectDetail.loadFailed');
|
||||||
} finally {
|
} finally {
|
||||||
@@ -486,6 +492,7 @@
|
|||||||
<InstanceCard
|
<InstanceCard
|
||||||
{instance}
|
{instance}
|
||||||
{projectId}
|
{projectId}
|
||||||
|
domain={settingsDomain}
|
||||||
onchange={loadProject}
|
onchange={loadProject}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
Reference in New Issue
Block a user