A focused Docker Compose management web application.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: confirm project deletion popup

Brooke 6d32a5bf 414100b0

+79 -13
+2 -2
packages/panel/src/lib/component/LoaderButton.svelte
··· 16 16 disabled, 17 17 onclick, 18 18 }: { 19 - style?: "button" | "a" | "outline"; 19 + style?: "button" | "a" | "outline" | "danger"; 20 20 children: Snippet<[boolean]> | string; 21 - onclick?: () => Promise<void>; 22 21 "aria-label"?: string; 22 + onclick?: () => any; 23 23 disabled?: boolean; 24 24 loading?: boolean; 25 25 fit?: boolean;
+10 -1
packages/panel/src/lib/style.scss
··· 81 81 background-color: var(--mauve); 82 82 } 83 83 84 + &.danger { 85 + background-color: var(--red); 86 + 87 + &:hover { 88 + background-color: var(--red); 89 + opacity: 0.8; 90 + } 91 + } 92 + 84 93 &:disabled { 85 - background-color: var(--overlay1); 94 + background-color: var(--overlay1) !important; 86 95 cursor: not-allowed; 87 96 } 88 97
+67 -10
packages/panel/src/routes/(authenticated)/projects/[project]/ProjectStatus.svelte
··· 1 1 <script lang="ts"> 2 - import { faArrowsRotate, faBan, faPlay, faRocket, faStop } from "@fortawesome/free-solid-svg-icons"; 3 2 import PromiseButton from "$lib/component/PromiseButton.svelte"; 4 3 import StatusIcon from "$lib/component/StatusIcon.svelte"; 5 4 import Tooltip from "$lib/component/Tooltip.svelte"; 6 5 import { goto } from "$app/navigation"; 6 + import { api, closeDialog, openDialog } from "$lib"; 7 7 import Fa from "svelte-fa"; 8 - import { api } from "$lib"; 8 + import { 9 + faArrowsRotate, 10 + faBan, 11 + faCircleExclamation, 12 + faPlay, 13 + faRocket, 14 + faStop, 15 + } from "@fortawesome/free-solid-svg-icons"; 9 16 10 17 let { project }: { project: api.LuminaryProject } = $props(); 18 + let confirmation = $state(""); 11 19 12 20 let allAction = $derived.by(() => { 13 21 let services = Object.values(project.services); ··· 17 25 return action; 18 26 }); 19 27 28 + function clickDelete() { 29 + openDialog({ title: deletionTitle, content: deletionContent, parameters: project.name }); 30 + confirmation = ""; 31 + } 32 + 20 33 async function deleteProject() { 21 34 await api.client.DELETE("/api/project/{project}", { params: { path: { project: project.name } } }); 22 35 await goto("/projects"); 36 + closeDialog(); 23 37 } 24 38 </script> 25 39 40 + {#snippet deletionTitle()} 41 + <span style:color="var(--red)" style="padding-right: 5px;"> 42 + <Fa icon={faCircleExclamation} /> 43 + </span> 44 + <span>Delete Project</span> 45 + {/snippet} 46 + 47 + {#snippet deletionContent(name: string)} 48 + <p> 49 + Are you sure that you want to delete <span style="font-weight: bold">{name}</span>? 50 + <br /> 51 + This will delete the entire project directory and its contents. 52 + </p> 53 + <p style="color: var(--red); font-weight: bold; text-align: center">THIS ACTION IS IRREVERSIBLE</p> 54 + <br /> 55 + <p> 56 + <label for="confirmation"> 57 + Enter <span style="color: var(--red); font-weight: bold">delete {name}</span> below to confirm deletion: 58 + </label> 59 + <input id="confirmation" type="text" bind:value={confirmation} /> 60 + </p> 61 + <div class="flexr gap-5"> 62 + <PromiseButton 63 + disabled={project?.busy || confirmation !== `delete ${project.name}`} 64 + onclick={deleteProject} 65 + style="danger" 66 + fit 67 + > 68 + {#snippet children(loading)} 69 + <div class="flexr center gap-10"> 70 + {#if !loading}<Fa icon={faCircleExclamation} /> Delete Project 71 + {:else} 72 + Deleting... 73 + {/if} 74 + </div> 75 + {/snippet} 76 + </PromiseButton> 77 + <button class="outline" onclick={closeDialog}> 78 + <div class="flexr center gap-10"> 79 + <Fa icon={faBan} /> Cancel 80 + </div> 81 + </button> 82 + </div> 83 + {/snippet} 84 + 26 85 <h2>Actions</h2> 27 86 {#if project.invalid} 28 87 <div>You must fix the <a href="#compose">compose file</a> to trigger actions.</div> ··· 87 146 </div> 88 147 {/snippet} 89 148 </PromiseButton> 90 - <PromiseButton fit style="outline" disabled={project.busy} onclick={deleteProject}> 91 - {#snippet children(loading)} 92 - <div class="flexr center gap-10"> 93 - {#if !loading}<Fa icon={faBan} />{/if} 94 - Delete Project 95 - </div> 96 - {/snippet} 97 - </PromiseButton> 149 + <button class="outline" disabled={project.busy} onclick={clickDelete}> 150 + <div class="flexr center gap-10"> 151 + <Fa icon={faBan} /> 152 + Delete Project 153 + </div> 154 + </button> 98 155 </div> 99 156 {/if} 100 157