Skip to content

Commit

Permalink
better actions
Browse files Browse the repository at this point in the history
  • Loading branch information
LucaRickli committed Nov 23, 2024
1 parent 8d73391 commit c561422
Show file tree
Hide file tree
Showing 11 changed files with 215 additions and 75 deletions.
4 changes: 2 additions & 2 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@
}

& > li {
& a,
& button {
& > a,
& > button {
@apply grid w-full items-center gap-2 rounded px-2 py-1.5 text-left text-sm hover:bg-muted disabled:text-muted-foreground;
grid-template-columns: 16px 1fr auto;

Expand Down
24 changes: 20 additions & 4 deletions src/lib/components/data/machine/DeleteMachine.svelte
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
<script lang="ts">
import { defaults, superForm } from 'sveltekit-superforms';
import { zod } from 'sveltekit-superforms/adapters';
import { createEventDispatcher } from 'svelte';
import { z } from 'zod';
import * as Dialog from '$lib/components/ui/dialog';
import { Checkbox } from '$lib/components/ui/checkbox';
import * as Form from '$lib/components/form';
import { errorToast, successToast } from '$lib/utils/toast';
import { formatError } from '$lib/utils/error';
import type { Machine } from '$lib/api';
export let machine: Machine;
const dispatch = createEventDispatcher<{ submit: undefined }>();
let open: boolean;
const schema = z.object({
confirm: z.literal(true, {
errorMap: (issue) => ({ ...issue, message: 'Acknowledgement required to proceed' })
Expand All @@ -25,16 +32,25 @@
validators: zod(schema),
async onUpdate(ev) {
if (ev.form.valid) {
console.debug('Form is valid', ev);
// const {} = await machine.delete()
try {
const { error } = await machine.delete();
if (error) throw error;
successToast(`Deleted machine "${machine.givenName || machine.name}"`);
dispatch('submit');
open = false;
} catch (err) {
console.error(err);
errorToast(formatError(err));
}
}
}
});
const { form: formData, constraints } = form;
</script>

<Dialog.Root>
<Dialog.Root bind:open>
<Dialog.Trigger asChild let:builder>
<slot name="trigger" {builder} />
</Dialog.Trigger>
Expand All @@ -44,7 +60,7 @@
<Dialog.Title>Delete machine</Dialog.Title>
</Dialog.Header>

<Form.Root {form} destructive hasRequired class="mt-4">
<Form.Root {form} destructive hasRequired class="mt-4" disabled={!$formData.confirm}>
<Form.Field {form} name="confirm">
<Form.Control let:attrs>
<div class="flex flex-row-reverse items-center justify-end gap-2.5">
Expand Down
80 changes: 80 additions & 0 deletions src/lib/components/data/machine/ExpireSession.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<script lang="ts">
import { defaults, superForm } from 'sveltekit-superforms';
import { zod } from 'sveltekit-superforms/adapters';
import { createEventDispatcher } from 'svelte';
import { z } from 'zod';
import * as Dialog from '$lib/components/ui/dialog';
import { Checkbox } from '$lib/components/ui/checkbox';
import * as Form from '$lib/components/form';
import { errorToast, successToast } from '$lib/utils/toast';
import { formatError } from '$lib/utils/error';
import type { Machine } from '$lib/api';
export let machine: Machine;
const dispatch = createEventDispatcher<{ submit: undefined }>();
let open: boolean;
const schema = z.object({
confirm: z.literal(true, {
errorMap: (issue) => ({ ...issue, message: 'Acknowledgement required to proceed' })
})
});
const form = superForm(defaults(zod(schema)), {
SPA: true,
dataType: 'json',
invalidateAll: true,
validators: zod(schema),
async onUpdate(ev) {
if (ev.form.valid) {
try {
const { error } = await machine.expire();
if (error) throw error;
successToast(`Expired session of machine "${machine.givenName || machine.name}"`);
dispatch('submit');
open = false;
} catch (err) {
console.error(err);
errorToast(formatError(err));
}
}
}
});
const { form: formData, constraints } = form;
</script>

<Dialog.Root bind:open>
<Dialog.Trigger asChild let:builder>
<slot name="trigger" {builder} />
</Dialog.Trigger>

<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Expire machine session</Dialog.Title>
</Dialog.Header>

<Form.Root {form} destructive hasRequired class="mt-4" disabled={!$formData.confirm}>
<Form.Field {form} name="confirm">
<Form.Control let:attrs>
<div class="flex flex-row-reverse items-center justify-end gap-2.5">
<Form.Label for={attrs.id}>I understand that this action can not be undone</Form.Label>
<Checkbox
class="border-current"
{...attrs}
{...$constraints.confirm || {}}
bind:checked={$formData.confirm}
/>
</div>
<Form.FieldErrors />
</Form.Control>
</Form.Field>
</Form.Root>
</Dialog.Content>
</Dialog.Root>
37 changes: 12 additions & 25 deletions src/lib/components/data/machine/MachineActions.svelte
Original file line number Diff line number Diff line change
@@ -1,40 +1,23 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import MonitorCog from 'lucide-svelte/icons/monitor-cog';
import EyeClosed from 'lucide-svelte/icons/eye-closed';
import ShieldOff from 'lucide-svelte/icons/shield-off';
import Telescope from 'lucide-svelte/icons/telescope';
import Trash from 'lucide-svelte/icons/trash-2';
import X from 'lucide-svelte/icons/x';
import type { Machine } from '$lib/api';
import MachineStatus from './MachineStatus.svelte';
import { createEventDispatcher } from 'svelte';
import DeleteMachine from './DeleteMachine.svelte';
import EditMachine from './EditMachine.svelte';
import ExpireSession from './ExpireSession.svelte';
export let machine: Machine;
const dispatch = createEventDispatcher<{ close: undefined; focus: undefined }>();
</script>

<div class="grid items-center gap-2" style="grid-template-columns: auto 1fr auto;">
<MachineStatus online={machine.online} lastSeen={machine.lastSeen} />

<div>
<span>{machine.givenName}</span>
<span class="text-muted-foreground">#{machine.id}</span>
</div>

<button
class="-my-1.5 -mr-2 h-8 w-8 rounded p-2 hover:bg-muted"
on:click={() => dispatch('close')}
>
<X class="h-4 w-4" />
</button>
</div>
<hr />

<li>
<button on:click={() => dispatch('focus')}>
<span>
Expand Down Expand Up @@ -65,14 +48,18 @@
</li>

<li class="destructive">
<button disabled>
<ShieldOff />
<span>Expire session</span>
</button>
<ExpireSession {machine} on:submit={() => dispatch('close')}>
<svelte:fragment slot="trigger" let:builder>
<button {...builder} use:builder.action>
<ShieldOff />
<span>Expire session</span>
</button>
</svelte:fragment>
</ExpireSession>
</li>

<li class="destructive">
<DeleteMachine {machine}>
<DeleteMachine {machine} on:submit={() => dispatch('close')}>
<svelte:fragment slot="trigger" let:builder>
<button {...builder} use:builder.action>
<Trash />
Expand Down
29 changes: 21 additions & 8 deletions src/lib/components/data/machine/MachineInfo.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<script lang="ts">
import { Address4, Address6 } from 'ip-address';
import { createEventDispatcher } from 'svelte';
import EllipsisVertical from 'lucide-svelte/icons/ellipsis-vertical';
import ToggleRight from 'lucide-svelte/icons/toggle-right';
import MonitorCog from 'lucide-svelte/icons/monitor-cog';
import ToggleLeft from 'lucide-svelte/icons/toggle-left';
import Trash from 'lucide-svelte/icons/trash-2';
// import MonitorCog from 'lucide-svelte/icons/monitor-cog';
// import Trash from 'lucide-svelte/icons/trash-2';
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import * as Sheet from '$lib/components/ui/sheet';
Expand All @@ -17,20 +18,28 @@
import Secret from '$lib/components/utils/Secret.svelte';
import { GraphMachine, isLinkNode, type GraphDataLink } from '$lib/utils/networkGraph';
import {
focusOnNode,
GraphMachine,
isLinkNode,
type GraphDataLink
} from '$lib/utils/networkGraph';
import { formatDuration, isExpired, neverExpires } from '$lib/utils/time';
import { Acl, User, type AclData, type Route } from '$lib/api';
import MachineActions from './MachineActions.svelte';
import MachineStatus from './MachineStatus.svelte';
import DeleteMachine from './DeleteMachine.svelte';
import EditMachine from './EditMachine.svelte';
// import DeleteMachine from './DeleteMachine.svelte';
// import EditMachine from './EditMachine.svelte';
export let machine: GraphMachine;
export let routes: Route[] | undefined;
export let links: GraphDataLink[];
export let users: User[];
export let acl: Acl;
const dispatch = createEventDispatcher<{ close: undefined; focus: undefined }>();
const rawAclRules = new Set<AclData['acls'][0]>();
const rulePrefixes: { [id: string]: { in: Set<string>; out: Set<string> } } = {};
Expand Down Expand Up @@ -72,7 +81,7 @@

<Sheet.Header>
<Sheet.Title class="flex items-center gap-1.5 font-normal">
<DropdownMenu.Root>
<!-- <DropdownMenu.Root>
<DropdownMenu.Trigger asChild let:builder>
<Button builders={[builder]} variant="ghost" class="h-7 w-7 p-1.5">
<EllipsisVertical class="h-4 w-4" />
Expand Down Expand Up @@ -104,7 +113,7 @@
</DropdownMenu.Item>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu.Root>
</DropdownMenu.Root> -->

<span class="font-semibold">
{machine.givenName}
Expand Down Expand Up @@ -157,7 +166,11 @@
</div>
</Sheet.Header>

<div style="height: 1px;"></div>
<ul class="menu">
<MachineActions {machine} on:close={() => dispatch('close')} on:focus={() => dispatch('focus')} />
</ul>

<!-- <div style="height: 1px;"></div> -->

<div class="space-y-2">
<div class="text-sm font-medium">Disco Key</div>
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/data/user/DeleteUser.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
<Dialog.Title>Delete user</Dialog.Title>
</Dialog.Header>

<Form.Root {form} destructive hasRequired class="mt-4">
<Form.Root {form} destructive hasRequired class="mt-4" disabled={!$formData.confirm}>
<Form.Field {form} name="confirm">
<Form.Control let:attrs>
<div class="flex flex-row-reverse items-center justify-end gap-2.5">
Expand Down
16 changes: 0 additions & 16 deletions src/lib/components/data/user/UserActions.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import EyeClosed from 'lucide-svelte/icons/eye-closed';
import Telescope from 'lucide-svelte/icons/telescope';
import Trash from 'lucide-svelte/icons/trash-2';
import X from 'lucide-svelte/icons/x';
import type { Acl, User } from '$lib/api';
import EditUser from './EditUser.svelte';
Expand All @@ -17,21 +16,6 @@
const dispatch = createEventDispatcher<{ close: undefined; focus: undefined }>();
</script>

<div class="grid items-center gap-2" style="grid-template-columns: 1fr auto;">
<div>
<span>{user.name}</span>
<span class="text-muted-foreground">#{user.id}</span>
</div>

<button
class="-my-1.5 -mr-2 h-8 w-8 rounded p-2 hover:bg-muted"
on:click={() => dispatch('close')}
>
<X class="h-4 w-4" />
</button>
</div>
<hr />

<li>
<button on:click={() => dispatch('focus')}>
<span>
Expand Down
Loading

0 comments on commit c561422

Please sign in to comment.