diff --git a/src/routes/dashboard/[machineId]/system/hostname/+page.svelte b/src/routes/dashboard/[machineId]/system/hostname/+page.svelte
index 851e119..3c0c78b 100644
--- a/src/routes/dashboard/[machineId]/system/hostname/+page.svelte
+++ b/src/routes/dashboard/[machineId]/system/hostname/+page.svelte
@@ -1,5 +1,6 @@
+
{m.nav_system_hostname()}
@@ -48,10 +51,11 @@
if (v === h.hostname) return;
saving = true;
try {
- await setHostname({hostname:v,machineId,});
+ await setHostname({ hostname: v, machineId });
toast.success(m.saved());
} catch (err) {
- toast.error((err as Error).message || 'Error');
+ console.log(err);
+ toast.error((err as { body?: { message?: string } })?.body?.message || m.errors_generic());
} finally {
saving = false;
}
@@ -64,7 +68,7 @@
name="hostname"
value={h.hostname}
required
- pattern="[A-Za-z0-9.-]+"
+ pattern="[A-Za-z0-9.\-]+"
maxlength={253}
/>
diff --git a/src/routes/dashboard/[machineId]/system/localization/+page.svelte b/src/routes/dashboard/[machineId]/system/localization/+page.svelte
index ddfbb49..9bbd892 100644
--- a/src/routes/dashboard/[machineId]/system/localization/+page.svelte
+++ b/src/routes/dashboard/[machineId]/system/localization/+page.svelte
@@ -4,6 +4,7 @@
import PlusIcon from '@lucide/svelte/icons/plus';
import XIcon from '@lucide/svelte/icons/x';
import { page } from '$app/state';
+ import PageMeta from '$lib/components/seo/page-meta.svelte';
import { Badge } from '$lib/components/ui/badge';
import { Button } from '$lib/components/ui/button';
import * as Card from '$lib/components/ui/card';
@@ -57,7 +58,7 @@
await fn();
toast.success(m.saved());
} catch (e) {
- toast.error((e as Error).message || 'Error');
+ toast.error((e as { body?: { message?: string } })?.body?.message || m.errors_generic());
} finally {
saving = false;
}
@@ -65,7 +66,7 @@
async function handleSetLanguage() {
const l = await locale;
- await setLocale({ lang: l.lang,language: langList.join(':'), machineId });
+ await setLocale({ lang: l.lang, language: langList.join(':'), machineId });
serverLanguage = '';
}
@@ -75,11 +76,15 @@
toast.error(m.system_locale_generate_invalid());
return;
}
- await generateLocale({locale:loc,machineId});
+ await generateLocale({ locale: loc, machineId });
newLocale = '';
}
+
{m.nav_system_localization()}
@@ -125,7 +130,9 @@
onSelect={() => {
open = false;
if (loc !== l.lang)
- pick(() => setLocale({ lang: loc, language: l.language || undefined,machineId }));
+ pick(() =>
+ setLocale({ lang: loc, language: l.language || undefined, machineId })
+ );
}}
>
{
kmOpen = false;
- if (km !== l.vc_keymap) pick(() => setKeymap({keymap:km,machineId}));
+ if (km !== l.vc_keymap) pick(() => setKeymap({ keymap: km, machineId }));
}}
>
+ import ArrowLeftIcon from '@lucide/svelte/icons/arrow-left';
+ import CheckIcon from '@lucide/svelte/icons/check';
+ import CompassIcon from '@lucide/svelte/icons/compass';
+ import CpuIcon from '@lucide/svelte/icons/cpu';
+ import FingerprintIcon from '@lucide/svelte/icons/fingerprint';
+ import HardDriveIcon from '@lucide/svelte/icons/hard-drive';
+ import Loader2Icon from '@lucide/svelte/icons/loader-2';
+ import MonitorCogIcon from '@lucide/svelte/icons/monitor-cog';
+ import NetworkIcon from '@lucide/svelte/icons/network';
+ import PackageIcon from '@lucide/svelte/icons/package';
+ import RefreshCwIcon from '@lucide/svelte/icons/refresh-cw';
+ import ShieldAlertIcon from '@lucide/svelte/icons/shield-alert';
+ import ShieldCheckIcon from '@lucide/svelte/icons/shield-check';
+ import UsersIcon from '@lucide/svelte/icons/users';
+ import XIcon from '@lucide/svelte/icons/x';
+ import { resolve } from '$app/paths';
+ import { page } from '$app/state';
+ import PageMeta from '$lib/components/seo/page-meta.svelte';
+ import { Badge } from '$lib/components/ui/badge';
+ import { Button } from '$lib/components/ui/button';
+ import * as Card from '$lib/components/ui/card';
+ import { m } from '$lib/paraglide/messages';
+ import { getModules, getWhoami } from '$lib/remotes/system.remote';
+
+ const machineId = $derived(page.params.machineId!);
+
+ const modulesResource = $derived(getModules(machineId));
+ const whoamiResource = $derived(getWhoami(machineId));
+ const dataPromise = $derived(Promise.all([modulesResource, whoamiResource]));
+
+ let refreshing = $state(false);
+
+ async function handleRefresh() {
+ refreshing = true;
+ try {
+ await Promise.all([modulesResource.refresh(), whoamiResource.refresh()]);
+ } finally {
+ refreshing = false;
+ }
+ }
+
+ function getModuleIcon(id: string) {
+ switch (id) {
+ case 'networking':
+ return NetworkIcon;
+ case 'packages':
+ return PackageIcon;
+ case 'services':
+ return CpuIcon;
+ case 'storage':
+ return HardDriveIcon;
+ case 'system':
+ return MonitorCogIcon;
+ case 'users':
+ return UsersIcon;
+ default:
+ return CompassIcon;
+ }
+ }
+
+ function hasPermission(
+ moduleId: string,
+ perm: string,
+ userPerms: Record
+ ) {
+ if (userPerms['*']) return true;
+ const modPerms = userPerms[moduleId];
+ if (!modPerms) return false;
+ return modPerms.includes('*') || modPerms.includes(perm);
+ }
+
+
+
+
+
+
+
+
+
+
{m.seo_title_system_nadir()}
+
{m.nav_system_nadir_desc()}
+
+
+
+
+
+
+
+ {#snippet failed(err)}
+
+
+ {(err as Error).message || m.errors_generic()}
+
+
+ {/snippet}
+
+ {#await dataPromise}
+
+
+
+ {:then [modulesData, whoamiData]}
+ {@const hasGlobalWildcard = !!whoamiData.permissions['*']}
+
+
+
+
+
+
+
+
+
+ {m.system_nadir_username()}
+
+
+
+
+ {whoamiData.username}
+ Agent Identity
+
+
+
+
{m.system_nadir_permissions()}
+ {#if hasGlobalWildcard}
+
+
+ Administrator (Full Access)
+
+ {:else}
+
+
+ Restricted Module Access
+
+ {/if}
+
+
+
+
+
+
+
+ {m.system_nadir_modules()}
+ {modulesData?.modules?.length ?? 0}
+
+
+
+ {#each modulesData?.modules ?? [] as mod (mod.id)}
+ {@const Icon = getModuleIcon(mod.id)}
+ {@const hasModuleWildcard = !hasGlobalWildcard && whoamiData.permissions[mod.id]?.includes('*')}
+
+
+
+
+
+
+
+ {mod.name}
+ {mod.id}
+
+
+ {#if hasGlobalWildcard || hasModuleWildcard}
+
+
+
+ {/if}
+
+
+
+ {#if mod.permissions && mod.permissions.length > 0}
+ {#each mod.permissions as perm (perm)}
+ {@const ok = hasPermission(mod.id, perm, whoamiData.permissions)}
+
+ {#if ok}
+
+ {:else}
+
+ {/if}
+ {perm}
+
+ {/each}
+ {:else}
+ {m.system_nadir_no_permissions()}
+ {/if}
+
+
+
+ {/each}
+
+
+
+ {/await}
+
+
diff --git a/src/routes/dashboard/[machineId]/system/power/+page.svelte b/src/routes/dashboard/[machineId]/system/power/+page.svelte
index 4f15ec8..5594808 100644
--- a/src/routes/dashboard/[machineId]/system/power/+page.svelte
+++ b/src/routes/dashboard/[machineId]/system/power/+page.svelte
@@ -2,6 +2,7 @@
import PowerIcon from '@lucide/svelte/icons/power';
import RotateCcwIcon from '@lucide/svelte/icons/rotate-ccw';
import { page } from '$app/state';
+ import PageMeta from '$lib/components/seo/page-meta.svelte';
import * as AlertDialog from '$lib/components/ui/alert-dialog';
import { Button } from '$lib/components/ui/button';
import { buttonVariants } from '$lib/components/ui/button';
@@ -13,14 +14,16 @@
let pending = $state<'off' | 'reboot' | null>(null);
let busy = $state(false);
- const machineId = $derived(page.params.machineId!)
+ const machineId = $derived(page.params.machineId!);
async function run(action: 'off' | 'reboot') {
busy = true;
try {
- await (action === 'off' ? powerOff({machineId,when:''}) : reboot({machineId,when:''}));
+ await (action === 'off'
+ ? powerOff({ machineId, when: '' })
+ : reboot({ machineId, when: '' }));
toast.success(m.saved());
} catch (e) {
- toast.error((e as Error).message || 'Error');
+ toast.error((e as { body?: { message?: string } })?.body?.message || m.errors_generic());
} finally {
busy = false;
pending = null;
@@ -28,6 +31,7 @@
}
+
{m.nav_system_power()}
@@ -58,7 +62,9 @@
- {pending === 'off' ? m.system_power_confirm_poweroff_title() : m.system_power_confirm_reboot_title()}
+ {pending === 'off'
+ ? m.system_power_confirm_poweroff_title()
+ : m.system_power_confirm_reboot_title()}
{m.system_power_confirm_description()}
diff --git a/src/routes/dashboard/[machineId]/users/+page.svelte b/src/routes/dashboard/[machineId]/users/+page.svelte
index ba3c116..d861636 100644
--- a/src/routes/dashboard/[machineId]/users/+page.svelte
+++ b/src/routes/dashboard/[machineId]/users/+page.svelte
@@ -1,6 +1,4 @@
+
{m.users_nav_title()}
@@ -220,10 +226,10 @@
@@ -449,10 +453,7 @@
{m.users_create_field_create_home()}
@@ -468,7 +469,8 @@
- {m.users_set_password_title({ username: pwUser?.username ?? '' })}
+ {m.users_set_password_title({ username: pwUser?.username ?? '' })}
{m.users_set_password_description()}