feat: Redesign settings page (#4657)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@@ -119,6 +119,7 @@ declare module 'vue' {
|
||||
'Mdi:gauge': typeof import('~icons/mdi/gauge')['default']
|
||||
'Mdi:github': typeof import('~icons/mdi/github')['default']
|
||||
'Mdi:hamburgerMenu': typeof import('~icons/mdi/hamburger-menu')['default']
|
||||
'Mdi:heart': typeof import('~icons/mdi/heart')['default']
|
||||
'Mdi:hexagonMultiple': typeof import('~icons/mdi/hexagon-multiple')['default']
|
||||
'Mdi:key': typeof import('~icons/mdi/key')['default']
|
||||
'Mdi:keyboardEsc': typeof import('~icons/mdi/keyboard-esc')['default']
|
||||
@@ -131,7 +132,6 @@ declare module 'vue' {
|
||||
'Mdi:poll': typeof import('~icons/mdi/poll')['default']
|
||||
'Mdi:refresh': typeof import('~icons/mdi/refresh')['default']
|
||||
'Mdi:satelliteVariant': typeof import('~icons/mdi/satellite-variant')['default']
|
||||
'Mdi:shieldLockOutline': typeof import('~icons/mdi/shield-lock-outline')['default']
|
||||
'Mdi:textBoxOutline': typeof import('~icons/mdi/text-box-outline')['default']
|
||||
'Mdi:trashCanOutline': typeof import('~icons/mdi/trash-can-outline')['default']
|
||||
'Mdi:webhook': typeof import('~icons/mdi/webhook')['default']
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="border-base-content/15 bg-base-200/40 divide-base-content/10 divide-y rounded-lg border">
|
||||
<!-- Not linked -->
|
||||
<template v-if="!cloudConfig">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="flex items-start gap-4 p-4">
|
||||
<mdi:cloud class="text-base-content/40 mt-0.5 text-4xl" />
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="text-base-content/70 text-sm">{{ $t("cloud.description") }}</p>
|
||||
@@ -22,7 +22,7 @@
|
||||
<!-- Linked -->
|
||||
<template v-else-if="cloudConfig.linked">
|
||||
<!-- Error state -->
|
||||
<div v-if="cloudStatusError" class="space-y-3">
|
||||
<div v-if="cloudStatusError" class="space-y-3 p-4">
|
||||
<div class="alert" :class="cloudStatusError === 'auth' ? 'alert-error' : 'alert-warning'">
|
||||
<mdi:alert-circle v-if="cloudStatusError === 'auth'" class="text-lg" />
|
||||
<mdi:cloud-off-outline v-else class="text-lg" />
|
||||
@@ -47,43 +47,46 @@
|
||||
</div>
|
||||
|
||||
<!-- Loading -->
|
||||
<div v-else-if="isLoadingCloudStatus" class="flex items-center gap-2 py-2">
|
||||
<div v-else-if="isLoadingCloudStatus" class="flex items-center gap-2 p-4">
|
||||
<span class="loading loading-spinner loading-sm"></span>
|
||||
</div>
|
||||
|
||||
<!-- Healthy -->
|
||||
<div v-else-if="cloudStatus" class="space-y-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="badge badge-success">{{ $t("cloud.connected") }}</span>
|
||||
<span class="badge badge-primary capitalize">{{ cloudStatus.plan.name }}</span>
|
||||
<template v-else-if="cloudStatus">
|
||||
<div class="flex flex-wrap items-center gap-2 p-4">
|
||||
<span class="status-pill status-pill-success">
|
||||
<span class="size-1.5 rounded-full bg-current"></span>
|
||||
{{ $t("cloud.connected") }}
|
||||
</span>
|
||||
<span class="status-pill status-pill-primary">{{ cloudStatus.plan.name }}</span>
|
||||
<span class="text-base-content/50 text-sm">{{ cloudStatus.user.email }}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="mb-1 flex items-center justify-between text-sm">
|
||||
<span class="text-base-content/60">{{ $t("cloud.usage") }}</span>
|
||||
<span>
|
||||
{{ cloudStatus.usage.events_used.toLocaleString() }} /
|
||||
{{ cloudStatus.usage.events_limit.toLocaleString() }}
|
||||
<div class="flex flex-col gap-2 p-4">
|
||||
<div class="flex items-baseline justify-between">
|
||||
<span class="text-base-content/60 text-sm font-medium">{{ $t("cloud.usage") }}</span>
|
||||
<span class="font-mono text-sm">
|
||||
<span class="font-semibold">{{ cloudStatus.usage.events_used.toLocaleString() }}</span>
|
||||
<span class="text-base-content/40"> / {{ cloudStatus.usage.events_limit.toLocaleString() }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<progress
|
||||
class="progress w-full max-w-xs"
|
||||
class="progress w-full"
|
||||
:class="usagePercent > 90 ? 'progress-error' : usagePercent > 70 ? 'progress-warning' : 'progress-primary'"
|
||||
:value="cloudStatus.usage.events_used"
|
||||
:max="cloudStatus.usage.events_limit"
|
||||
></progress>
|
||||
<div class="text-base-content/40 flex justify-between font-mono text-xs">
|
||||
<span v-if="cloudStatus.usage.period">{{ cloudStatus.usage.period }}</span>
|
||||
<span v-else></span>
|
||||
<span>{{ usagePercent.toFixed(2) }}% used</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label
|
||||
class="border-base-content/10 hover:border-base-content/20 flex cursor-pointer items-start justify-between gap-4 rounded-lg border p-4 transition-colors"
|
||||
>
|
||||
<div class="flex items-start gap-3">
|
||||
<mdi:shield-lock-outline class="text-primary mt-0.5 shrink-0 text-xl" />
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<span class="text-sm font-medium">{{ $t("cloud.stream-logs") }}</span>
|
||||
<span class="text-base-content/60 text-xs">{{ $t("cloud.stream-logs-help") }}</span>
|
||||
</div>
|
||||
<label class="flex min-h-13 cursor-pointer items-center justify-between gap-4 p-4">
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<span class="text-sm font-medium">{{ $t("cloud.stream-logs") }}</span>
|
||||
<span class="text-base-content/60 text-xs">{{ $t("cloud.stream-logs-help") }}</span>
|
||||
</div>
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -94,7 +97,7 @@
|
||||
/>
|
||||
</label>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<div class="flex gap-2 p-4">
|
||||
<a :href="cloudUrl" target="_blank" rel="noreferrer noopener" class="btn btn-sm">
|
||||
{{ $t("cloud.dashboard") }}
|
||||
</a>
|
||||
@@ -102,7 +105,7 @@
|
||||
{{ $t("cloud.unlink") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- Unlink confirmation modal -->
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
@import "tailwindcss";
|
||||
@import "splitpanes/dist/splitpanes.css" layer(base);
|
||||
@import "@fontsource/jetbrains-mono/400.css";
|
||||
@import "@fontsource/jetbrains-mono/500.css";
|
||||
@import "@fontsource/jetbrains-mono/600.css";
|
||||
@import "@fontsource/jetbrains-mono/700.css";
|
||||
@plugin "daisyui";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@@ -9,6 +13,8 @@
|
||||
--color-purple: oklch(51.49% 0.215 321.03);
|
||||
--color-blue: oklch(65% 0.171 249.5);
|
||||
--color-orange: oklch(85% 0.186 48.13);
|
||||
|
||||
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
|
||||
}
|
||||
|
||||
@utility pt-safe {
|
||||
@@ -190,5 +196,21 @@ body {
|
||||
}
|
||||
|
||||
.cm-scroller {
|
||||
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.status-pill {
|
||||
@apply inline-flex items-center gap-1.5 rounded border px-2 py-0.5 font-mono text-xs font-medium tracking-wider uppercase;
|
||||
}
|
||||
.status-pill-neutral {
|
||||
@apply bg-base-100 border-base-content/15 text-base-content/70;
|
||||
}
|
||||
.status-pill-success {
|
||||
@apply text-success border-success/30 bg-success/10;
|
||||
}
|
||||
.status-pill-primary {
|
||||
@apply text-primary border-primary/30 bg-primary/10;
|
||||
}
|
||||
.status-pill-warning {
|
||||
@apply text-warning border-warning/30 bg-warning/10;
|
||||
}
|
||||
|
||||
@@ -1,160 +1,203 @@
|
||||
<template>
|
||||
<PageWithLinks>
|
||||
<div class="@container flex flex-col gap-5 px-4 py-4 md:px-8">
|
||||
<section>
|
||||
<div class="has-underline">
|
||||
<h2>{{ $t("settings.about") }}</h2>
|
||||
<Links>
|
||||
<template #more-items>
|
||||
<Tag>{{ config.version }}</Tag>
|
||||
</template>
|
||||
</Links>
|
||||
</section>
|
||||
|
||||
<!-- ABOUT -->
|
||||
<section class="flex flex-col gap-4">
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold tracking-tight">{{ $t("settings.about") }}</h2>
|
||||
<p class="text-base-content/60 mt-1 text-sm">{{ $t("settings.about-desc") }}</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row gap-2">
|
||||
<span v-html="$t('settings.using-version', { version: config.version })"></span>
|
||||
<span
|
||||
v-if="hasRelease"
|
||||
v-html="$t('settings.update-available', { nextVersion: latestRelease?.name, href: latestRelease?.htmlUrl })"
|
||||
></span>
|
||||
</div>
|
||||
<div class="border-base-content/15 bg-base-200/40 divide-base-content/10 divide-y rounded-lg border">
|
||||
<div class="flex flex-col gap-2 p-5">
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
<span class="text-2xl font-semibold tracking-tight">Dozzle</span>
|
||||
<span class="status-pill status-pill-neutral">{{ config.version }}</span>
|
||||
<a
|
||||
v-if="hasRelease"
|
||||
:href="latestRelease?.htmlUrl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="status-pill status-pill-warning hover:bg-warning/15"
|
||||
>
|
||||
<span class="size-1.5 rounded-full bg-current"></span>
|
||||
{{ latestRelease?.name }} available
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-base-content/60 font-mono text-xs">
|
||||
<template v-if="hasRelease && latestRelease?.createdAt">
|
||||
Latest release {{ latestRelease.name }} ·
|
||||
{{ new Date(latestRelease.createdAt).toLocaleDateString(undefined, dateFmt) }}
|
||||
</template>
|
||||
<template v-else> You're running the latest version. </template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
{{ $t("settings.help-support") }}
|
||||
|
||||
<ul class="mt-6 flex gap-2">
|
||||
<li>
|
||||
<a href="https://github.com/amir20/dozzle" target="_blank" rel="noopener noreferrer" class="btn">
|
||||
<div class="flex flex-col gap-3 p-4">
|
||||
<div>
|
||||
<div class="text-sm font-medium">{{ $t("settings.support-title") }}</div>
|
||||
<div class="text-base-content/60 text-xs">{{ $t("settings.help-support") }}</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<a href="https://github.com/amir20/dozzle" target="_blank" rel="noopener noreferrer" class="btn btn-sm">
|
||||
<mdi:github /> amir20/dozzle
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/sponsors/amir20"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="btn btn-primary btn-sm"
|
||||
>
|
||||
<mdi:heart /> Sponsor on GitHub
|
||||
</a>
|
||||
<a
|
||||
href="https://buymeacoffee.com/amirraminfar"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="btn btn-secondary"
|
||||
class="btn btn-secondary btn-sm"
|
||||
>
|
||||
<mdi:beer />
|
||||
Buy me a beer
|
||||
<mdi:beer /> Buy me a beer
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="has-underline">
|
||||
<h2>{{ $t("cloud.title") }}</h2>
|
||||
<!-- CLOUD -->
|
||||
<section class="flex flex-col gap-4">
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold tracking-tight">{{ $t("cloud.title") }}</h2>
|
||||
<p class="text-base-content/60 mt-1 text-sm">{{ $t("settings.cloud-desc") }}</p>
|
||||
</div>
|
||||
<CloudSettingsCard />
|
||||
</section>
|
||||
|
||||
<section class="@container flex flex-col">
|
||||
<div class="has-underline">
|
||||
<h2>{{ $t("settings.display") }}</h2>
|
||||
<!-- DISPLAY -->
|
||||
<section class="flex flex-col gap-4">
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold tracking-tight">{{ $t("settings.display") }}</h2>
|
||||
<p class="text-base-content/60 mt-1 text-sm">{{ $t("settings.display-desc") }}</p>
|
||||
</div>
|
||||
|
||||
<section class="grid-cols-2 gap-4 @3xl:grid">
|
||||
<div class="flex flex-col gap-4 text-balance @3xl:pr-8">
|
||||
<Toggle v-model="compact"> {{ $t("settings.compact") }} </Toggle>
|
||||
|
||||
<Toggle v-model="smallerScrollbars"> {{ $t("settings.small-scrollbars") }} </Toggle>
|
||||
|
||||
<Toggle v-model="showTimestamp">{{ $t("settings.show-timestamps") }}</Toggle>
|
||||
|
||||
<Toggle v-model="showStd">{{ $t("settings.show-std") }}</Toggle>
|
||||
|
||||
<Toggle v-model="softWrap">{{ $t("settings.soft-wrap") }}</Toggle>
|
||||
|
||||
<LabeledInput>
|
||||
<template #label>
|
||||
{{ $t("settings.locale") }}
|
||||
</template>
|
||||
<template #input>
|
||||
<div class="grid items-stretch gap-3 @3xl:grid-cols-2">
|
||||
<div class="border-base-content/15 bg-base-200/40 divide-base-content/10 divide-y rounded-lg border">
|
||||
<label class="flex min-h-13 items-center justify-between gap-4 p-4 text-sm font-medium">
|
||||
{{ $t("settings.compact") }}
|
||||
<input type="checkbox" class="toggle toggle-primary toggle-sm" v-model="compact" />
|
||||
</label>
|
||||
<label class="flex min-h-13 items-center justify-between gap-4 p-4 text-sm font-medium">
|
||||
{{ $t("settings.small-scrollbars") }}
|
||||
<input type="checkbox" class="toggle toggle-primary toggle-sm" v-model="smallerScrollbars" />
|
||||
</label>
|
||||
<label class="flex min-h-13 items-center justify-between gap-4 p-4 text-sm font-medium">
|
||||
{{ $t("settings.show-timestamps") }}
|
||||
<input type="checkbox" class="toggle toggle-primary toggle-sm" v-model="showTimestamp" />
|
||||
</label>
|
||||
<label class="flex min-h-13 items-center justify-between gap-4 p-4 text-sm font-medium">
|
||||
{{ $t("settings.show-std") }}
|
||||
<input type="checkbox" class="toggle toggle-primary toggle-sm" v-model="showStd" />
|
||||
</label>
|
||||
<label class="flex min-h-13 items-center justify-between gap-4 p-4 text-sm font-medium">
|
||||
{{ $t("settings.soft-wrap") }}
|
||||
<input type="checkbox" class="toggle toggle-primary toggle-sm" v-model="softWrap" />
|
||||
</label>
|
||||
<div class="flex min-h-13 flex-wrap items-center justify-between gap-3 p-4 text-sm font-medium">
|
||||
<span>{{ $t("settings.datetime-format") }}</span>
|
||||
<div class="flex gap-1.5">
|
||||
<DropdownMenu
|
||||
v-model="locale"
|
||||
v-model="dateLocale"
|
||||
:options="[
|
||||
{ label: 'Auto', value: '' },
|
||||
...availableLocales.map((l) => ({ label: l.toLocaleUpperCase(), value: l })),
|
||||
{ label: 'Auto', value: 'auto' },
|
||||
{ label: 'MM/DD/YYYY', value: 'en-US' },
|
||||
{ label: 'DD/MM/YYYY', value: 'en-GB' },
|
||||
{ label: 'DD.MM.YYYY', value: 'de-DE' },
|
||||
{ label: 'YYYY-MM-DD', value: 'en-CA' },
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</LabeledInput>
|
||||
|
||||
<LabeledInput>
|
||||
<template #label>
|
||||
{{ $t("settings.datetime-format") }}
|
||||
</template>
|
||||
<template #input>
|
||||
<div class="flex gap-4">
|
||||
<DropdownMenu
|
||||
v-model="dateLocale"
|
||||
:options="[
|
||||
{ label: 'Auto', value: 'auto' },
|
||||
{ label: 'MM/DD/YYYY', value: 'en-US' },
|
||||
{ label: 'DD/MM/YYYY', value: 'en-GB' },
|
||||
{ label: 'DD.MM.YYYY', value: 'de-DE' },
|
||||
{ label: 'YYYY-MM-DD', value: 'en-CA' },
|
||||
]"
|
||||
/>
|
||||
<DropdownMenu
|
||||
v-model="hourStyle"
|
||||
:options="[
|
||||
{ label: $t('settings.hour.auto'), value: 'auto' },
|
||||
{ label: $t('settings.hour.12'), value: '12' },
|
||||
{ label: $t('settings.hour.24'), value: '24' },
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</LabeledInput>
|
||||
|
||||
<LabeledInput>
|
||||
<template #label>
|
||||
{{ $t("settings.font-size") }}
|
||||
</template>
|
||||
<template #input>
|
||||
<DropdownMenu
|
||||
v-model="size"
|
||||
v-model="hourStyle"
|
||||
:options="[
|
||||
{ label: $t('settings.hour.auto'), value: 'auto' },
|
||||
{ label: $t('settings.hour.12'), value: '12' },
|
||||
{ label: $t('settings.hour.24'), value: '24' },
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex min-h-13 flex-wrap items-center justify-between gap-3 p-4 text-sm font-medium">
|
||||
<span>{{ $t("settings.font-size") }}</span>
|
||||
<div class="join">
|
||||
<button
|
||||
v-for="opt in [
|
||||
{ label: $t('settings.size.small'), value: 'small' },
|
||||
{ label: $t('settings.size.medium'), value: 'medium' },
|
||||
{ label: $t('settings.size.large'), value: 'large' },
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</LabeledInput>
|
||||
|
||||
<LabeledInput>
|
||||
<template #label>
|
||||
{{ $t("settings.color-scheme") }}
|
||||
</template>
|
||||
<template #input>
|
||||
<DropdownMenu
|
||||
v-model="lightTheme"
|
||||
:options="[
|
||||
{ label: $t('settings.theme.auto'), value: 'auto' },
|
||||
{ label: $t('settings.theme.dark'), value: 'dark' },
|
||||
{ label: $t('settings.theme.light'), value: 'light' },
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</LabeledInput>
|
||||
:key="opt.value"
|
||||
class="btn btn-sm join-item"
|
||||
:class="size === opt.value ? 'btn-primary' : 'btn-ghost'"
|
||||
@click="size = opt.value as typeof size"
|
||||
>
|
||||
{{ opt.label }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<LogList
|
||||
:messages="fakeMessages"
|
||||
:last-selected-item="undefined"
|
||||
:show-container-name="false"
|
||||
class="border-base-content/50 hidden overflow-hidden rounded-lg border shadow-sm @3xl:block"
|
||||
class="border-base-content/15 hidden h-full overflow-hidden rounded-lg border @3xl:block"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- OPTIONS -->
|
||||
<section class="flex flex-col gap-4">
|
||||
<div class="has-underline">
|
||||
<h2>{{ $t("settings.options") }}</h2>
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold tracking-tight">{{ $t("settings.options") }}</h2>
|
||||
<p class="text-base-content/60 mt-1 text-sm">{{ $t("settings.options-desc") }}</p>
|
||||
</div>
|
||||
|
||||
<LabeledInput>
|
||||
<template #label>
|
||||
{{ $t("settings.automatic-redirect") }}
|
||||
</template>
|
||||
<template #input>
|
||||
<div class="border-base-content/15 bg-base-200/40 divide-base-content/10 divide-y rounded-lg border">
|
||||
<div class="flex min-h-13 flex-wrap items-center justify-between gap-3 p-4 text-sm font-medium">
|
||||
<span>{{ $t("settings.locale") }}</span>
|
||||
<DropdownMenu
|
||||
v-model="locale"
|
||||
:options="[
|
||||
{ label: 'Auto', value: '' },
|
||||
...availableLocales.map((l) => ({ label: l.toLocaleUpperCase(), value: l })),
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex min-h-13 flex-wrap items-center justify-between gap-3 p-4 text-sm font-medium">
|
||||
<span>{{ $t("settings.color-scheme") }}</span>
|
||||
<div class="join">
|
||||
<button
|
||||
v-for="opt in [
|
||||
{ label: $t('settings.theme.light'), value: 'light' },
|
||||
{ label: $t('settings.theme.dark'), value: 'dark' },
|
||||
{ label: $t('settings.theme.auto'), value: 'auto' },
|
||||
]"
|
||||
:key="opt.value"
|
||||
class="btn btn-sm join-item"
|
||||
:class="lightTheme === opt.value ? 'btn-primary' : 'btn-ghost'"
|
||||
@click="lightTheme = opt.value as typeof lightTheme"
|
||||
>
|
||||
{{ opt.label }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex min-h-13 flex-wrap items-center justify-between gap-3 p-4 text-sm font-medium">
|
||||
<span>{{ $t("settings.automatic-redirect") }}</span>
|
||||
<DropdownMenu
|
||||
v-model="automaticRedirect"
|
||||
:options="[
|
||||
@@ -163,13 +206,9 @@
|
||||
{ label: $t('settings.redirect.none'), value: 'none' },
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</LabeledInput>
|
||||
<LabeledInput>
|
||||
<template #label>
|
||||
{{ $t("settings.group-containers") }}
|
||||
</template>
|
||||
<template #input>
|
||||
</div>
|
||||
<div class="flex min-h-13 flex-wrap items-center justify-between gap-3 p-4 text-sm font-medium">
|
||||
<span>{{ $t("settings.group-containers") }}</span>
|
||||
<DropdownMenu
|
||||
v-model="groupContainers"
|
||||
:options="[
|
||||
@@ -178,16 +217,18 @@
|
||||
{ label: $t('settings.grouping.never'), value: 'never' },
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</LabeledInput>
|
||||
|
||||
<Toggle v-model="search">
|
||||
{{ $t("settings.search") }} <key-shortcut char="f" class="align-top"></key-shortcut>
|
||||
</Toggle>
|
||||
|
||||
<Toggle v-model="showAllContainers">{{ $t("settings.show-stopped-containers") }}</Toggle>
|
||||
</div>
|
||||
<label class="flex min-h-13 items-center justify-between gap-4 p-4 text-sm font-medium">
|
||||
<span>{{ $t("settings.search") }} <key-shortcut char="f" class="align-top"></key-shortcut></span>
|
||||
<input type="checkbox" class="toggle toggle-primary toggle-sm" v-model="search" />
|
||||
</label>
|
||||
<label class="flex min-h-13 items-center justify-between gap-4 p-4 text-sm font-medium">
|
||||
{{ $t("settings.show-stopped-containers") }}
|
||||
<input type="checkbox" class="toggle toggle-primary toggle-sm" v-model="showAllContainers" />
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
</PageWithLinks>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -217,6 +258,8 @@ const { t } = useI18n();
|
||||
setTitle(t("title.settings"));
|
||||
const { latestRelease, hasRelease } = useAnnouncements();
|
||||
|
||||
const dateFmt: Intl.DateTimeFormatOptions = { year: "numeric", month: "short", day: "numeric" };
|
||||
|
||||
const now = new Date();
|
||||
const hoursAgo = (hours: number) => {
|
||||
const date = new Date(now);
|
||||
@@ -260,18 +303,17 @@ const fakeMessages = computedWithControl(
|
||||
],
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@reference "@/main.css";
|
||||
|
||||
.has-underline {
|
||||
@apply border-base-content/50 mb-4 border-b py-2;
|
||||
|
||||
h2 {
|
||||
@apply text-3xl;
|
||||
}
|
||||
:deep(.text-base-content\/60 a:not(.btn)),
|
||||
:deep(.text-base-content\/70 a:not(.btn)) {
|
||||
@apply text-primary;
|
||||
}
|
||||
|
||||
:deep(a:not(.menu a):not(.btn)) {
|
||||
@apply text-primary underline-offset-4 hover:underline;
|
||||
:deep(.text-base-content\/60 a:not(.btn):hover),
|
||||
:deep(.text-base-content\/70 a:not(.btn):hover) {
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@@ -106,6 +106,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Støt venligst Dozzle ved at donere eller sponsorere os på GitHub. Dine bidrag hjælper os med at forbedre Dozzle for alle. Tak! 🙏🏼
|
||||
about-desc: Information om din Dozzle-installation og hvordan du kan støtte projektet.
|
||||
display-desc: Tilpas hvordan logs og resten af appen ser ud. Forhåndsvisningen afspejler dine ændringer live.
|
||||
options-desc: Indstillinger for sprog, navigation og gruppering.
|
||||
cloud-desc: Stream logs til Dozzle Cloud for AI-drevne undersøgelser og søgning på tværs af installationer.
|
||||
support-title: Støt Dozzle
|
||||
display: Visning
|
||||
locale: Overskriv sprog
|
||||
small-scrollbars: Brug mindre scrollbarer
|
||||
|
||||
@@ -106,6 +106,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Bitte unterstützen Sie Dozzle durch Spenden oder Sponsoring auf GitHub. Ihre Beiträge helfen uns, Dozzle für alle zu verbessern. Vielen Dank! 🙏🏼
|
||||
about-desc: Informationen zu Ihrer Dozzle-Installation und wie Sie das Projekt unterstützen können.
|
||||
display-desc: Passen Sie an, wie Logs und der Rest der App aussehen. Die Vorschau zeigt Ihre Änderungen live.
|
||||
options-desc: Einstellungen für Sprache, Navigation und Gruppierung.
|
||||
cloud-desc: Streamen Sie Logs an Dozzle Cloud für KI-gestützte Analysen und Suche über Instanzen hinweg.
|
||||
support-title: Dozzle unterstützen
|
||||
display: Anzeige
|
||||
locale: Sprache überschreiben
|
||||
small-scrollbars: Verwende kleinere Scrollbars
|
||||
|
||||
@@ -114,6 +114,12 @@ settings:
|
||||
help-support: >
|
||||
Please support Dozzle by donating or sponsoring us on GitHub. Your contributions help us improve Dozzle for
|
||||
everyone. Thank you! 🙏🏼
|
||||
about-desc: Information about your Dozzle installation and how to support the project.
|
||||
display-desc: Customize how logs and the rest of the app look. The preview reflects your changes live.
|
||||
options-desc: Locale, navigation and grouping preferences.
|
||||
cloud-desc: Stream logs to Dozzle Cloud for AI-powered investigations and search across instances.
|
||||
support-title: Support Dozzle
|
||||
support-help: Donations help keep Dozzle free and maintained. Thank you 🙏
|
||||
display: Display
|
||||
locale: Override language
|
||||
small-scrollbars: Use smaller scrollbars
|
||||
|
||||
@@ -106,6 +106,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Por favor, apoya a Dozzle donando o patrocinándonos en GitHub. Tus contribuciones nos ayudan a mejorar Dozzle para todos. ¡Gracias! 🙏🏼
|
||||
about-desc: Información sobre tu instalación de Dozzle y cómo apoyar el proyecto.
|
||||
display-desc: Personaliza la apariencia de los logs y del resto de la aplicación. La vista previa refleja tus cambios en vivo.
|
||||
options-desc: Preferencias de idioma, navegación y agrupación.
|
||||
cloud-desc: Transmite logs a Dozzle Cloud para investigaciones con IA y búsqueda entre instancias.
|
||||
support-title: Apoya a Dozzle
|
||||
display: Vista
|
||||
locale: Sobrescribir idioma
|
||||
small-scrollbars: Utilizar barras de desplazamiento más pequeñas
|
||||
|
||||
@@ -106,6 +106,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Veuillez soutenir Dozzle en faisant un don ou en nous parrainant sur GitHub. Vos contributions nous aident à améliorer Dozzle pour tout le monde. Merci ! 🙏🏼
|
||||
about-desc: Informations sur votre installation de Dozzle et comment soutenir le projet.
|
||||
display-desc: Personnalisez l'apparence des logs et du reste de l'application. L'aperçu reflète vos modifications en direct.
|
||||
options-desc: Préférences de langue, de navigation et de regroupement.
|
||||
cloud-desc: Diffusez les logs vers Dozzle Cloud pour des analyses assistées par IA et la recherche entre instances.
|
||||
support-title: Soutenir Dozzle
|
||||
display: Afficher
|
||||
locale: Langue de remplacement
|
||||
small-scrollbars: Utiliser des barres de défilement plus petites
|
||||
|
||||
@@ -114,6 +114,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Silakan dukung Dozzle dengan berdonasi atau mensponsori kami di GitHub. Kontribusi Anda membantu kami meningkatkan Dozzle untuk semua orang. Terima kasih! 🙏🏼
|
||||
about-desc: Informasi tentang instalasi Dozzle Anda dan cara mendukung proyek ini.
|
||||
display-desc: Sesuaikan tampilan log dan sisa aplikasi. Pratinjau mencerminkan perubahan Anda secara langsung.
|
||||
options-desc: Preferensi bahasa, navigasi, dan pengelompokan.
|
||||
cloud-desc: Streaming log ke Dozzle Cloud untuk investigasi bertenaga AI dan pencarian lintas instans.
|
||||
support-title: Dukung Dozzle
|
||||
display: Tampilan
|
||||
locale: Ganti bahasa
|
||||
small-scrollbars: Gunakan scrollbar kecil
|
||||
|
||||
@@ -106,6 +106,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Per favore sostieni Dozzle donando o sponsorizzandoci su GitHub. I tuoi contributi ci aiutano a migliorare Dozzle per tutti. Grazie! 🙏🏼
|
||||
about-desc: Informazioni sulla tua installazione di Dozzle e su come sostenere il progetto.
|
||||
display-desc: Personalizza l'aspetto dei log e del resto dell'app. L'anteprima riflette le modifiche in tempo reale.
|
||||
options-desc: Preferenze di lingua, navigazione e raggruppamento.
|
||||
cloud-desc: Trasmetti i log a Dozzle Cloud per analisi basate su IA e ricerca tra le istanze.
|
||||
support-title: Sostieni Dozzle
|
||||
display: Visualizza
|
||||
locale: Sovrascrivi Lingua
|
||||
small-scrollbars: Usa una scrollbars più piccola
|
||||
|
||||
@@ -108,6 +108,11 @@ settings:
|
||||
help-support: >
|
||||
GitHub에서 후원하거나 기부로 Dozzle을 응원해 주세요. 여러분의 도움으로
|
||||
모두를 위한 더 나은 Dozzle을 만들 수 있습니다. 감사합니다! 🙏🏼
|
||||
about-desc: Dozzle 설치 정보와 프로젝트를 후원하는 방법입니다.
|
||||
display-desc: 로그와 앱의 나머지 부분의 모습을 사용자 지정합니다. 미리보기에 변경 사항이 실시간으로 반영됩니다.
|
||||
options-desc: 언어, 탐색 및 그룹화 환경설정.
|
||||
cloud-desc: Dozzle Cloud로 로그를 스트리밍하여 AI 기반 조사 및 인스턴스 간 검색을 수행합니다.
|
||||
support-title: Dozzle 후원
|
||||
display: 화면 설정
|
||||
locale: 언어 변경
|
||||
small-scrollbars: 작은 스크롤바 사용
|
||||
|
||||
@@ -107,6 +107,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Steun Dozzle door te doneren of door ons te sponsoren op GitHub. Jouw bijdrage helpt ons om Dozzle verder te verbeteren voor iedereen. Hartelijk dank! 🙏🏼
|
||||
about-desc: Informatie over jouw Dozzle-installatie en hoe je het project kunt ondersteunen.
|
||||
display-desc: Pas aan hoe logs en de rest van de app eruitzien. De voorbeeldweergave toont je wijzigingen live.
|
||||
options-desc: Voorkeuren voor taal, navigatie en groepering.
|
||||
cloud-desc: Stream logs naar Dozzle Cloud voor AI-gestuurde analyses en zoeken over instanties heen.
|
||||
support-title: Steun Dozzle
|
||||
display: Weergave
|
||||
locale: Taal aanpassen
|
||||
small-scrollbars: Kleinere scrollbalk gebruiken
|
||||
|
||||
@@ -112,6 +112,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Prosimy o wsparcie Dozzle poprzez darowizny lub sponsoring na GitHub. Twoje wkłady pomagają nam ulepszać Dozzle dla wszystkich. Dziękujemy! 🙏🏼
|
||||
about-desc: Informacje o Twojej instalacji Dozzle i o tym, jak wesprzeć projekt.
|
||||
display-desc: Dostosuj wygląd logów i reszty aplikacji. Podgląd odzwierciedla zmiany na żywo.
|
||||
options-desc: Preferencje języka, nawigacji i grupowania.
|
||||
cloud-desc: Przesyłaj logi do Dozzle Cloud w celu analiz wspomaganych przez AI i wyszukiwania między instancjami.
|
||||
support-title: Wesprzyj Dozzle
|
||||
display: Wyświetlanie
|
||||
locale: Nadpisz język
|
||||
small-scrollbars: Użyj mniejszych suwaków
|
||||
|
||||
@@ -110,6 +110,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Por favor, apoie o Dozzle doando ou nos patrocinando no GitHub. Suas contribuições nos ajudam a melhorar o Dozzle para todos. Obrigado! 🙏🏼
|
||||
about-desc: Informações sobre sua instalação do Dozzle e como apoiar o projeto.
|
||||
display-desc: Personalize a aparência dos logs e do restante do aplicativo. A pré-visualização reflete suas alterações ao vivo.
|
||||
options-desc: Preferências de idioma, navegação e agrupamento.
|
||||
cloud-desc: Transmita logs para o Dozzle Cloud para investigações com IA e busca entre instâncias.
|
||||
support-title: Apoiar o Dozzle
|
||||
display: Visão
|
||||
locale: Localidade
|
||||
small-scrollbars: Usar barras de rolagem mais pequenas
|
||||
|
||||
@@ -105,6 +105,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Por favor, apoie o Dozzle doando ou nos patrocinando no GitHub. Suas contribuições nos ajudam a melhorar o Dozzle para todos. Obrigado! 🙏🏼
|
||||
about-desc: Informações sobre sua instalação do Dozzle e como apoiar o projeto.
|
||||
display-desc: Personalize a aparência dos logs e do restante do aplicativo. A pré-visualização reflete suas alterações ao vivo.
|
||||
options-desc: Preferências de idioma, navegação e agrupamento.
|
||||
cloud-desc: Transmita logs para o Dozzle Cloud para investigações com IA e busca entre instâncias.
|
||||
support-title: Apoiar o Dozzle
|
||||
display: Exibição
|
||||
locale: Sobrescrever idioma
|
||||
small-scrollbars: Usar barras de rolagem menores
|
||||
|
||||
@@ -106,6 +106,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Пожалуйста, поддержите Dozzle, сделав пожертвование или спонсорство на GitHub. Ваши вклады помогают нам улучшать Dozzle для всех. Спасибо! 🙏🏼
|
||||
about-desc: Информация о вашей установке Dozzle и о том, как поддержать проект.
|
||||
display-desc: Настройте внешний вид логов и остальной части приложения. Предпросмотр отражает ваши изменения в реальном времени.
|
||||
options-desc: Настройки языка, навигации и группировки.
|
||||
cloud-desc: Передавайте логи в Dozzle Cloud для аналитики с использованием ИИ и поиска по экземплярам.
|
||||
support-title: Поддержать Dozzle
|
||||
display: Вид
|
||||
locale: Язык
|
||||
small-scrollbars: Уменьшенная полоса прокрутки
|
||||
|
||||
@@ -105,6 +105,11 @@ placeholder:
|
||||
search-containers: Iskanje zabojnikov (⌘ + k, ⌃k)
|
||||
search: Iskanje
|
||||
settings:
|
||||
about-desc: Informacije o vaši namestitvi Dozzle in kako podpreti projekt.
|
||||
display-desc: Prilagodite videz dnevnikov in preostalega dela aplikacije. Predogled v živo prikazuje vaše spremembe.
|
||||
options-desc: Nastavitve jezika, navigacije in združevanja.
|
||||
cloud-desc: Pretakajte dnevnike v Dozzle Cloud za preiskave z umetno inteligenco in iskanje med instancami.
|
||||
support-title: Podprite Dozzle
|
||||
display: Prikaz
|
||||
locale: Preglasi jezik
|
||||
small-scrollbars: Uporabite manjše drsne trakove
|
||||
|
||||
@@ -114,6 +114,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
Lütfen GitHub'da bağış yaparak veya bizi sponsor olarak destekleyerek Dozzle'ı destekleyin. Katkılarınız Dozzle'ı herkes için geliştirmemize yardımcı oluyor. Teşekkürler! 🙏🏼
|
||||
about-desc: Dozzle kurulumunuz ve projeyi nasıl destekleyebileceğiniz hakkında bilgiler.
|
||||
display-desc: Logların ve uygulamanın geri kalanının görünümünü özelleştirin. Önizleme değişikliklerinizi canlı olarak yansıtır.
|
||||
options-desc: Dil, gezinme ve gruplama tercihleri.
|
||||
cloud-desc: AI destekli incelemeler ve örnekler arasında arama için logları Dozzle Cloud'a aktarın.
|
||||
support-title: Dozzle'ı Destekle
|
||||
display: Görünüm
|
||||
locale: Dili geçersiz kıl
|
||||
small-scrollbars: Daha küçük kaydırma çubukları kullan
|
||||
|
||||
@@ -108,6 +108,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
請透過在 GitHub 上捐款或贊助我們來支持 Dozzle。您的貢獻幫助我們為所有人改進 Dozzle。謝謝! 🙏🏼
|
||||
about-desc: 關於您的 Dozzle 安裝以及如何支持本專案的資訊。
|
||||
display-desc: 自訂日誌和應用程式其餘部分的外觀。預覽會即時反映您的變更。
|
||||
options-desc: 語言、導覽和群組偏好設定。
|
||||
cloud-desc: 將日誌串流至 Dozzle Cloud,進行 AI 驅動的調查和跨實例搜尋。
|
||||
support-title: 支持 Dozzle
|
||||
display: 顯示
|
||||
locale: 變更語言
|
||||
small-scrollbars: 使用較小的捲軸
|
||||
|
||||
@@ -106,6 +106,11 @@ placeholder:
|
||||
settings:
|
||||
help-support: >
|
||||
请通过在 GitHub 上捐赠或赞助我们来支持 Dozzle。您的贡献帮助我们为所有人改进 Dozzle。谢谢! 🙏🏼
|
||||
about-desc: 关于您的 Dozzle 安装及如何支持本项目的信息。
|
||||
display-desc: 自定义日志和应用其余部分的外观。预览会实时反映您的更改。
|
||||
options-desc: 语言、导航和分组首选项。
|
||||
cloud-desc: 将日志流式传输到 Dozzle Cloud,进行 AI 驱动的调查和跨实例搜索。
|
||||
support-title: 支持 Dozzle
|
||||
display: 显示
|
||||
locale: 显示语言
|
||||
small-scrollbars: 使用较小的滚动条
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
"@codemirror/theme-one-dark": "^6.1.3",
|
||||
"@codemirror/view": "^6.41.1",
|
||||
"@duckdb/duckdb-wasm": "1.33.1-dev45.0",
|
||||
"@fontsource/jetbrains-mono": "^5.2.8",
|
||||
"@iconify-json/carbon": "^1.2.20",
|
||||
"@iconify-json/cil": "^1.2.3",
|
||||
"@iconify-json/ic": "^1.2.4",
|
||||
|
||||
@@ -32,6 +32,9 @@ importers:
|
||||
'@duckdb/duckdb-wasm':
|
||||
specifier: 1.33.1-dev45.0
|
||||
version: 1.33.1-dev45.0
|
||||
'@fontsource/jetbrains-mono':
|
||||
specifier: ^5.2.8
|
||||
version: 5.2.8
|
||||
'@iconify-json/carbon':
|
||||
specifier: ^1.2.20
|
||||
version: 1.2.20
|
||||
@@ -1108,6 +1111,9 @@ packages:
|
||||
'@noble/hashes':
|
||||
optional: true
|
||||
|
||||
'@fontsource/jetbrains-mono@5.2.8':
|
||||
resolution: {integrity: sha512-6w8/SG4kqvIMu7xd7wt6x3idn1Qux3p9N62s6G3rfldOUYHpWcc2FKrqf+Vo44jRvqWj2oAtTHrZXEP23oSKwQ==}
|
||||
|
||||
'@humanfs/core@0.19.1':
|
||||
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
|
||||
engines: {node: '>=18.18.0'}
|
||||
@@ -5213,6 +5219,8 @@ snapshots:
|
||||
|
||||
'@exodus/bytes@1.15.0': {}
|
||||
|
||||
'@fontsource/jetbrains-mono@5.2.8': {}
|
||||
|
||||
'@humanfs/core@0.19.1': {}
|
||||
|
||||
'@humanfs/node@0.16.7':
|
||||
|
||||