refactor: minor fixes for better mobile view.

This commit is contained in:
arabcoders 2026-03-26 17:13:58 +03:00
parent 218832a493
commit cdca27d4b9
13 changed files with 208 additions and 77 deletions

View file

@ -16,7 +16,7 @@
{{ selectedElms.length }} {{ selectedElms.length }}
</UBadge> </UBadge>
<UDropdownMenu :items="bulkActionGroups"> <UDropdownMenu :items="bulkActionGroups" :modal="false">
<UButton <UButton
color="neutral" color="neutral"
variant="outline" variant="outline"
@ -52,7 +52,7 @@
class="w-full min-w-0 max-w-full overflow-hidden rounded-lg border border-default bg-default" class="w-full min-w-0 max-w-full overflow-hidden rounded-lg border border-default bg-default"
> >
<div class="w-full max-w-full overflow-x-auto overscroll-x-contain"> <div class="w-full max-w-full overflow-x-auto overscroll-x-contain">
<table class="min-w-325 w-full text-sm"> <table class="min-w-325 max-w-455 table-fixed w-full text-sm">
<thead class="bg-muted/40 text-xs uppercase tracking-wide text-toned"> <thead class="bg-muted/40 text-xs uppercase tracking-wide text-toned">
<tr class="text-center [&>th]:px-3 [&>th]:py-3 [&>th]:font-semibold"> <tr class="text-center [&>th]:px-3 [&>th]:py-3 [&>th]:font-semibold">
<th class="w-[5%]"> <th class="w-[5%]">
@ -63,11 +63,11 @@
/> />
</button> </button>
</th> </th>
<th class="w-full text-left">Title</th> <th class="text-left">Title</th>
<th class="w-[15%]">Status</th> <th class="w-[7%]">Status</th>
<th class="w-[15%]">Created</th> <th class="w-[7%]">Created</th>
<th class="w-[10%]">Size/Starts</th> <th class="w-[7%]">Size/Starts</th>
<th class="w-[1%]">Actions</th> <th class="w-[8%]">Actions</th>
</tr> </tr>
</thead> </thead>
@ -85,8 +85,8 @@
</label> </label>
</td> </td>
<td class="px-3 py-3 align-top"> <td class="w-0 px-3 py-3 align-top">
<div class="flex items-start justify-between gap-3"> <div class="flex min-w-0 items-start justify-between gap-3">
<div class="min-w-0 flex-1"> <div class="min-w-0 flex-1">
<UTooltip <UTooltip
:text=" :text="
@ -159,16 +159,16 @@
<p <p
v-if="item.error" v-if="item.error"
class="is-text-overflow mt-2 cursor-pointer text-sm text-error" :class="messageClass(item._id, 'error', 'list', 'mt-2')"
@click="toggle_class($event)" @click="toggleMessage(item._id, 'error', 'list')"
> >
{{ item.error }} {{ item.error }}
</p> </p>
<p <p
v-if="showMessage(item)" v-if="showMessage(item)"
class="is-text-overflow mt-1 cursor-pointer text-sm text-error" :class="messageClass(item._id, 'msg', 'list', 'mt-1')"
@click="toggle_class($event)" @click="toggleMessage(item._id, 'msg', 'list')"
> >
{{ item.msg }} {{ item.msg }}
</p> </p>
@ -244,7 +244,7 @@
@click="() => void removeItem(item)" @click="() => void removeItem(item)"
/> />
<UDropdownMenu v-if="item.url" :items="itemActionGroups(item)"> <UDropdownMenu v-if="item.url" :items="itemActionGroups(item)" :modal="false">
<UButton <UButton
color="neutral" color="neutral"
variant="outline" variant="outline"
@ -389,7 +389,7 @@
</figure> </figure>
</div> </div>
<div class="grid gap-2 text-sm sm:auto-cols-fr sm:grid-flow-col"> <div class="flex flex-wrap gap-2 text-sm *:min-w-32 *:flex-1">
<div <div
class="rounded-md border border-default bg-muted/20 px-3 py-2 text-center text-default" class="rounded-md border border-default bg-muted/20 px-3 py-2 text-center text-default"
> >
@ -440,7 +440,7 @@
</div> </div>
</div> </div>
<div class="grid gap-2 sm:grid-cols-3"> <div class="flex flex-wrap gap-2 *:min-w-32 *:flex-1">
<UButton <UButton
v-if="!item.filename" v-if="!item.filename"
color="warning" color="warning"
@ -475,7 +475,7 @@
{{ config.app.remove_files ? 'Remove' : 'Clear' }} {{ config.app.remove_files ? 'Remove' : 'Clear' }}
</UButton> </UButton>
<UDropdownMenu :items="itemActionGroups(item)" class="w-full"> <UDropdownMenu :items="itemActionGroups(item)" :modal="false" class="w-full">
<UButton <UButton
color="neutral" color="neutral"
variant="outline" variant="outline"
@ -494,16 +494,16 @@
> >
<p <p
v-if="item.error" v-if="item.error"
class="is-text-overflow cursor-pointer text-sm text-error" :class="messageClass(item._id, 'error', 'card')"
@click="toggle_class($event)" @click="toggleMessage(item._id, 'error', 'card')"
> >
{{ item.error }} {{ item.error }}
</p> </p>
<p <p
v-if="showMessage(item)" v-if="showMessage(item)"
class="is-text-overflow cursor-pointer text-sm text-error" :class="messageClass(item._id, 'msg', 'card')"
@click="toggle_class($event)" @click="toggleMessage(item._id, 'msg', 'card')"
> >
{{ item.msg }} {{ item.msg }}
</p> </p>
@ -652,6 +652,7 @@ const masterSelectAll = ref(false);
const embed_url = ref(''); const embed_url = ref('');
const video_item = ref<StoreItem | null>(null); const video_item = ref<StoreItem | null>(null);
const loadMoreTrigger = ref<HTMLElement | null>(null); const loadMoreTrigger = ref<HTMLElement | null>(null);
const expandedMessages = reactive<Record<string, Set<string>>>({});
const paginationInfo = computed(() => stateStore.getPagination()); const paginationInfo = computed(() => stateStore.getPagination());
@ -1277,10 +1278,45 @@ const downloadSelected = async () => {
} }
}; };
const toggle_class = (e: Event) => const toggleMessage = (itemId: string, field: 'error' | 'msg', view: 'list' | 'card') => {
['is-text-overflow', 'is-word-break'].forEach((c) => const key = `${itemId}:${view}`;
(e.currentTarget as HTMLElement).classList.toggle(c),
); if (!expandedMessages[key]) {
expandedMessages[key] = new Set();
}
if (expandedMessages[key].has(field)) {
expandedMessages[key].delete(field);
return;
}
expandedMessages[key].add(field);
};
const isMessageExpanded = (itemId: string, field: 'error' | 'msg', view: 'list' | 'card') =>
expandedMessages[`${itemId}:${view}`]?.has(field) ?? false;
const messageClass = (
itemId: string,
field: 'error' | 'msg',
view: 'list' | 'card',
spacingClass = '',
) => {
const expanded = isMessageExpanded(itemId, field, view);
const base = ['cursor-pointer', 'text-sm', 'text-error'];
if (spacingClass) {
base.push(spacingClass);
}
if ('card' === view) {
base.push(expanded ? 'whitespace-pre-wrap break-words' : 'line-clamp-2 break-words');
return base;
}
base.push(expanded ? 'whitespace-pre-wrap break-words' : 'block max-w-full truncate');
return base;
};
const removeFromArchiveDialog = async (item: StoreItem): Promise<void> => { const removeFromArchiveDialog = async (item: StoreItem): Promise<void> => {
const options = [ const options = [

View file

@ -375,7 +375,7 @@
<div <div
class="flex flex-wrap items-center justify-between gap-2 border-t border-default pt-4" class="flex flex-wrap items-center justify-between gap-2 border-t border-default pt-4"
> >
<UDropdownMenu class="sm:hidden" :items="mobileActionGroups"> <UDropdownMenu class="sm:hidden" :items="mobileActionGroups" :modal="false">
<UButton <UButton
color="neutral" color="neutral"
variant="outline" variant="outline"

View file

@ -29,7 +29,7 @@
{{ selectedElms.length }} {{ selectedElms.length }}
</UBadge> </UBadge>
<UDropdownMenu :items="bulkActionGroups"> <UDropdownMenu :items="bulkActionGroups" :modal="false">
<UButton <UButton
color="neutral" color="neutral"
variant="outline" variant="outline"
@ -225,7 +225,7 @@
@click="() => void pauseItem(item)" @click="() => void pauseItem(item)"
/> />
<UDropdownMenu :items="itemActionGroups(item)"> <UDropdownMenu :items="itemActionGroups(item)" :modal="false">
<UButton <UButton
color="neutral" color="neutral"
variant="outline" variant="outline"
@ -380,7 +380,7 @@
</div> </div>
</div> </div>
<div class="grid gap-2 text-sm sm:auto-cols-fr sm:grid-flow-col"> <div class="flex flex-wrap gap-2 text-sm *:min-w-32 *:flex-1">
<div <div
class="rounded-md border border-default bg-muted/20 px-3 py-2 text-center text-default" class="rounded-md border border-default bg-muted/20 px-3 py-2 text-center text-default"
> >
@ -417,7 +417,7 @@
</div> </div>
</div> </div>
<div class="grid gap-2 sm:auto-cols-fr sm:grid-flow-col"> <div class="flex flex-wrap gap-2 *:min-w-32 *:flex-1">
<UButton <UButton
color="warning" color="warning"
variant="outline" variant="outline"
@ -450,7 +450,7 @@
Pause Pause
</UButton> </UButton>
<UDropdownMenu :items="itemActionGroups(item)" class="w-full"> <UDropdownMenu :items="itemActionGroups(item)" :modal="false" class="w-full">
<UButton <UButton
color="neutral" color="neutral"
variant="outline" variant="outline"

View file

@ -8,11 +8,21 @@
@update:open="(open) => !open && emitter('close')" @update:open="(open) => !open && emitter('close')"
> >
<template #header> <template #header>
<div class="flex items-center justify-between gap-3"> <div class="flex w-full items-start gap-3">
<div> <div class="min-w-0 flex-1">
<p class="text-base font-semibold text-highlighted">WebUI Settings</p> <p class="text-base font-semibold text-highlighted">WebUI Settings</p>
<p class="text-sm text-toned">Adjust interface behavior and download defaults.</p> <p class="text-sm text-toned">Adjust interface behavior.</p>
</div> </div>
<UButton
color="neutral"
variant="ghost"
size="sm"
square
icon="i-lucide-x"
class="ml-auto shrink-0 sm:hidden"
@click="emitter('close')"
/>
</div> </div>
</template> </template>

View file

@ -27,7 +27,7 @@ const DOCS_ENTRIES: DocsEntry[] = [
{ {
id: 'faq', id: 'faq',
title: 'FAQ', title: 'FAQ',
description: 'Answers for setup details, task handlers, and common issues.', description: 'Frequently asked questions about the project and troubleshooting.',
file: 'FAQ.md', file: 'FAQ.md',
route: '/docs/faq', route: '/docs/faq',
slug: ['faq'], slug: ['faq'],
@ -77,6 +77,7 @@ const getDocsNavigationEntries = () =>
DOCS_ENTRIES.map((entry) => ({ DOCS_ENTRIES.map((entry) => ({
id: entry.id, id: entry.id,
label: entry.navLabel, label: entry.navLabel,
description: entry.description,
icon: entry.icon, icon: entry.icon,
to: entry.route, to: entry.route,
})); }));

View file

@ -139,6 +139,16 @@
<template #left> <template #left>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<UDashboardSidebarToggle class="lg:hidden" /> <UDashboardSidebarToggle class="lg:hidden" />
<UButton
to="/"
color="neutral"
variant="ghost"
size="sm"
icon="i-lucide-house"
class="lg:hidden"
>
Home
</UButton>
<UDashboardSidebarCollapse class="hidden lg:inline-flex" /> <UDashboardSidebarCollapse class="hidden lg:inline-flex" />
</div> </div>
</template> </template>
@ -480,6 +490,7 @@ import type { version_check } from '~/types';
type NavEntry = { type NavEntry = {
id: string; id: string;
label: string; label: string;
description?: string;
icon: string; icon: string;
to?: string; to?: string;
children?: NavEntry[]; children?: NavEntry[];
@ -544,21 +555,65 @@ const makeNavigationItem = (item: NavEntry): NavigationMenuItem => ({
const docsNavigationEntries = getDocsNavigationEntries(); const docsNavigationEntries = getDocsNavigationEntries();
const allNavItems = computed<NavEntry[]>(() => [ const allNavItems = computed<NavEntry[]>(() => [
{ id: 'downloads', label: 'Downloads', icon: 'i-lucide-download', to: '/' }, {
{ id: 'files', label: 'Files', icon: 'i-lucide-folder-tree', to: '/browser' }, id: 'downloads',
{ id: 'presets', label: 'Presets', icon: 'i-lucide-sliders-horizontal', to: '/presets' }, label: 'Downloads',
{ id: 'custom-fields', label: 'Custom Fields', icon: 'i-lucide-braces', to: '/dl_fields' }, description: 'Queued and completed downloads list.',
{ id: 'conditions', label: 'Conditions', icon: 'i-lucide-filter', to: '/conditions' }, icon: 'i-lucide-download',
{ id: 'notifications', label: 'Notifications', icon: 'i-lucide-bell', to: '/notifications' }, to: '/',
},
{
id: 'files',
label: 'Files',
description: 'Browse downloaded files.',
icon: 'i-lucide-folder-tree',
to: '/browser',
},
{
id: 'presets',
label: 'Presets',
description:
'Presets are pre-defined command options for yt-dlp that you want to apply to given download.',
icon: 'i-lucide-sliders-horizontal',
to: '/presets',
},
{
id: 'custom-fields',
label: 'Custom Fields',
description: 'Custom fields allow you to add new fields to the download form.',
icon: 'i-lucide-braces',
to: '/dl_fields',
},
{
id: 'conditions',
label: 'Conditions',
description: 'Run yt-dlp custom match filter on returned info and apply options.',
icon: 'i-lucide-filter',
to: '/conditions',
},
{
id: 'notifications',
label: 'Notifications',
description: 'Send notifications to your webhooks based on specified events or presets.',
icon: 'i-lucide-bell',
to: '/notifications',
},
{ {
id: 'tasks', id: 'tasks',
label: 'Tasks', label: 'Tasks',
icon: 'i-lucide-list-todo', icon: 'i-lucide-list-todo',
children: [ children: [
{ id: 'tasks-list', label: 'Tasks', icon: 'i-lucide-list-todo', to: '/tasks' }, {
id: 'tasks-list',
label: 'Tasks',
description: 'Queue playlist/channels for automatic download at specified intervals.',
icon: 'i-lucide-list-todo',
to: '/tasks',
},
{ {
id: 'task-definitions', id: 'task-definitions',
label: 'Task Definitions', label: 'Task Definitions',
description: 'Create definitions to turn any website into a downloadable feed of links.',
icon: 'i-lucide-workflow', icon: 'i-lucide-workflow',
to: '/task_definitions', to: '/task_definitions',
}, },
@ -570,10 +625,26 @@ const allNavItems = computed<NavEntry[]>(() => [
icon: 'i-lucide-wrench', icon: 'i-lucide-wrench',
children: [ children: [
...(config.app?.file_logging ...(config.app?.file_logging
? [{ id: 'logs', label: 'Logs', icon: 'i-lucide-file-text', to: '/logs' }] ? [
{
id: 'logs',
label: 'Logs',
description: 'Scroll near the top to load older logs.',
icon: 'i-lucide-file-text',
to: '/logs',
},
]
: []), : []),
...(config.app.console_enabled ...(config.app.console_enabled
? [{ id: 'console', label: 'Console', icon: 'i-lucide-terminal', to: '/console' }] ? [
{
id: 'console',
label: 'Console',
description: 'Run yt-dlp commands directly in a non-interactive session.',
icon: 'i-lucide-terminal',
to: '/console',
},
]
: []), : []),
], ],
}, },
@ -583,7 +654,14 @@ const allNavItems = computed<NavEntry[]>(() => [
icon: 'i-lucide-book-open', icon: 'i-lucide-book-open',
children: [ children: [
...docsNavigationEntries, ...docsNavigationEntries,
{ id: 'changelog', label: 'Changelog', icon: 'i-lucide-list', to: '/changelog' }, {
id: 'changelog',
label: 'Changelog',
description:
'Latest project changes, loaded remotely when available and falling back to the bundled changelog file.',
icon: 'i-lucide-list',
to: '/changelog',
},
], ],
}, },
]); ]);
@ -674,6 +752,7 @@ const routeSearchGroups = computed(() => [
? [ ? [
{ {
label: item.label, label: item.label,
description: item.description,
icon: item.icon, icon: item.icon,
suffix: item.to, suffix: item.to,
onSelect: () => handleRouteSelect(item), onSelect: () => handleRouteSelect(item),
@ -683,6 +762,7 @@ const routeSearchGroups = computed(() => [
const children = (item.children || []).map((child) => ({ const children = (item.children || []).map((child) => ({
label: child.label, label: child.label,
description: child.description,
icon: child.icon, icon: child.icon,
suffix: child.to || '', suffix: child.to || '',
onSelect: () => handleRouteSelect(child), onSelect: () => handleRouteSelect(child),
@ -698,18 +778,30 @@ const routeSearchGroups = computed(() => [
config.paused config.paused
? { ? {
label: 'Resume Downloads', label: 'Resume Downloads',
description: 'Resume the global download queue so pending items can start again.', description: 'Resume globally paused downloads.',
icon: 'i-lucide-play', icon: 'i-lucide-play',
onSelect: () => void resumeDownloads(), onSelect: () => void resumeDownloads(),
} }
: { : {
label: 'Pause Downloads', label: 'Pause Downloads',
description: 'Pause pending downloads without stopping items already in progress.', description: 'Globally pause all non-active downloads.',
icon: 'i-lucide-pause', icon: 'i-lucide-pause',
onSelect: () => void pauseDownloads(), onSelect: () => void pauseDownloads(),
}, },
], ],
}, },
{
id: 'preferences',
label: 'Preferences',
items: [
{
label: 'WebUI Settings',
description: 'Adjust interface behavior and download defaults.',
icon: 'i-lucide-settings-2',
onSelect: () => void openSettings(),
},
],
},
]); ]);
const closeRouteSearch = async (): Promise<void> => { const closeRouteSearch = async (): Promise<void> => {
@ -723,19 +815,6 @@ const closeRouteSearch = async (): Promise<void> => {
const pauseDownloads = async (): Promise<void> => { const pauseDownloads = async (): Promise<void> => {
await closeRouteSearch(); await closeRouteSearch();
const { status } = await confirmDialog({
title: 'Pause Downloads',
confirmText: 'Pause',
cancelText: 'Cancel',
confirmColor: 'warning',
message: 'Are you sure you want to pause all non-active downloads?',
});
if (!status) {
return;
}
await request('/api/system/pause', { method: 'POST' }); await request('/api/system/pause', { method: 'POST' });
}; };
@ -744,6 +823,11 @@ const resumeDownloads = async (): Promise<void> => {
await request('/api/system/resume', { method: 'POST' }); await request('/api/system/resume', { method: 'POST' });
}; };
const openSettings = async (): Promise<void> => {
await closeRouteSearch();
show_settings.value = true;
};
const syncShellModeClass = () => { const syncShellModeClass = () => {
const html = document.documentElement; const html = document.documentElement;
html.classList.toggle('simple-mode', simpleMode.value); html.classList.toggle('simple-mode', simpleMode.value);

View file

@ -84,7 +84,7 @@
<span v-if="!isMobile">{{ display_style === 'list' ? 'List' : 'Grid' }}</span> <span v-if="!isMobile">{{ display_style === 'list' ? 'List' : 'Grid' }}</span>
</UButton> </UButton>
<UDropdownMenu v-if="hasItems" :items="sortGroups"> <UDropdownMenu v-if="hasItems" :items="sortGroups" :modal="false">
<UButton <UButton
color="neutral" color="neutral"
variant="outline" variant="outline"
@ -364,7 +364,7 @@
</div> </div>
</template> </template>
<div class="grid grid-cols-3 gap-2 text-sm"> <div class="flex flex-wrap gap-2 text-sm *:min-w-32 *:flex-1">
<div <div
class="min-w-0 rounded-md border border-default bg-muted/20 px-3 py-2 text-center text-default" class="min-w-0 rounded-md border border-default bg-muted/20 px-3 py-2 text-center text-default"
> >
@ -386,7 +386,7 @@
</div> </div>
</div> </div>
<div v-if="controlEnabled" class="mt-auto grid grid-cols-3 gap-2 pt-1"> <div v-if="controlEnabled" class="mt-auto flex flex-wrap gap-2 pt-1 *:min-w-32 *:flex-1">
<UButton <UButton
color="warning" color="warning"
variant="outline" variant="outline"

View file

@ -203,7 +203,7 @@
<span :class="expandClass(cond.id, 'name')">{{ cond.name }}</span> <span :class="expandClass(cond.id, 'name')">{{ cond.name }}</span>
</button> </button>
<div class="flex flex-wrap items-center gap-2 text-xs text-toned"> <div class="flex flex-wrap gap-2 text-xs text-toned *:min-w-32 *:flex-1">
<button <button
type="button" type="button"
class="inline-flex items-center gap-1 rounded-md border border-default px-2 py-1 transition hover:border-primary hover:text-default" class="inline-flex items-center gap-1 rounded-md border border-default px-2 py-1 transition hover:border-primary hover:text-default"
@ -293,7 +293,7 @@
</button> </button>
</div> </div>
<div class="mt-auto grid gap-2 pt-2 sm:grid-cols-2"> <div class="mt-auto flex flex-wrap gap-2 pt-2 *:min-w-32 *:flex-1">
<UButton <UButton
color="warning" color="warning"
variant="outline" variant="outline"

View file

@ -177,7 +177,7 @@
<div class="min-w-0 flex-1 space-y-2"> <div class="min-w-0 flex-1 space-y-2">
<div class="truncate text-sm font-semibold text-highlighted">{{ field.name }}</div> <div class="truncate text-sm font-semibold text-highlighted">{{ field.name }}</div>
<div class="flex flex-wrap items-center gap-2 text-xs text-toned"> <div class="flex flex-wrap gap-2 text-xs text-toned *:min-w-32 *:flex-1">
<span <span
class="inline-flex items-center gap-1 rounded-md border border-default px-2 py-1" class="inline-flex items-center gap-1 rounded-md border border-default px-2 py-1"
> >
@ -227,7 +227,7 @@
</div> </div>
</div> </div>
<div class="mt-auto grid gap-2 pt-2 sm:grid-cols-2"> <div class="mt-auto flex flex-wrap gap-2 pt-2 *:min-w-32 *:flex-1">
<UButton <UButton
color="warning" color="warning"
variant="outline" variant="outline"

View file

@ -275,7 +275,7 @@
</div> </div>
</div> </div>
<div class="mt-auto grid gap-2 pt-2 sm:grid-cols-2"> <div class="mt-auto flex flex-wrap gap-2 pt-2 *:min-w-32 *:flex-1">
<UButton <UButton
color="warning" color="warning"
variant="outline" variant="outline"

View file

@ -186,7 +186,7 @@
/> />
</div> </div>
<div class="flex flex-wrap items-center gap-2 text-xs text-toned"> <div class="flex flex-wrap gap-2 text-xs text-toned *:min-w-32 *:flex-1">
<span <span
class="inline-flex items-center gap-1 rounded-md border border-default px-2 py-1" class="inline-flex items-center gap-1 rounded-md border border-default px-2 py-1"
:class="item.cookies ? 'border-info/40 text-info' : ''" :class="item.cookies ? 'border-info/40 text-info' : ''"
@ -247,7 +247,7 @@
</button> </button>
</div> </div>
<div class="mt-auto grid gap-2 pt-2 sm:grid-cols-2"> <div class="mt-auto flex flex-wrap gap-2 pt-2 *:min-w-32 *:flex-1">
<UButton <UButton
color="warning" color="warning"
variant="outline" variant="outline"

View file

@ -214,7 +214,7 @@
{{ definition.name || '(Unnamed definition)' }} {{ definition.name || '(Unnamed definition)' }}
</div> </div>
<div class="flex flex-wrap items-center gap-2 text-xs text-toned"> <div class="flex flex-wrap gap-2 text-xs text-toned *:min-w-32 *:flex-1">
<button <button
type="button" type="button"
class="inline-flex items-center gap-1 rounded-md border border-default px-2 py-1 transition hover:border-primary hover:text-default" class="inline-flex items-center gap-1 rounded-md border border-default px-2 py-1 transition hover:border-primary hover:text-default"
@ -283,7 +283,7 @@
</div> </div>
</div> </div>
<div class="mt-auto grid gap-2 pt-2 sm:grid-cols-2"> <div class="mt-auto flex flex-wrap gap-2 pt-2 *:min-w-32 *:flex-1">
<UButton <UButton
color="warning" color="warning"
variant="outline" variant="outline"

View file

@ -95,7 +95,7 @@
{{ selectedElms.length }} {{ selectedElms.length }}
</UBadge> </UBadge>
<UDropdownMenu :items="bulkActionGroups"> <UDropdownMenu :items="bulkActionGroups" :modal="false">
<UButton <UButton
color="neutral" color="neutral"
variant="outline" variant="outline"
@ -308,7 +308,7 @@
<span v-if="!isMobile">Delete</span> <span v-if="!isMobile">Delete</span>
</UButton> </UButton>
<UDropdownMenu :items="itemActionGroups(item)"> <UDropdownMenu :items="itemActionGroups(item)" :modal="false">
<UButton <UButton
color="neutral" color="neutral"
variant="outline" variant="outline"
@ -391,7 +391,7 @@
</template> </template>
<div class="space-y-2 text-sm text-default"> <div class="space-y-2 text-sm text-default">
<div class="flex flex-wrap items-center gap-2 text-xs text-toned"> <div class="flex flex-wrap gap-2 text-xs text-toned *:min-w-32 *:flex-1">
<button <button
type="button" type="button"
class="inline-flex items-center gap-1 rounded-md border border-default px-2 py-1 transition hover:border-primary hover:text-default" class="inline-flex items-center gap-1 rounded-md border border-default px-2 py-1 transition hover:border-primary hover:text-default"
@ -500,7 +500,7 @@
</div> </div>
</div> </div>
<div class="mt-auto grid gap-2 pt-2 sm:grid-cols-3"> <div class="mt-auto flex flex-wrap gap-2 pt-2 *:min-w-32 *:flex-1">
<UButton <UButton
color="warning" color="warning"
variant="outline" variant="outline"
@ -521,7 +521,7 @@
Delete Delete
</UButton> </UButton>
<UDropdownMenu :items="itemActionGroups(item)"> <UDropdownMenu :items="itemActionGroups(item)" :modal="false">
<UButton <UButton
color="neutral" color="neutral"
variant="outline" variant="outline"