mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-18 12:14:07 +00:00
feat(ui): add shared table controls and multi-select filters
Introduce x-table toolbar/search/filter/sort/loading components and multi-select deployment history filters with OR within groups and AND across groups. Add live database/service status for breadcrumbs, shared variables layout controls, logs viewer toolbar polish, and infrastructure list filter consistency. Document patterns in UI_REDESIGN.md and cover with feature tests.
This commit is contained in:
1 parent
66b202adfe
commit
2a5197fb30
57 files changed
+1415
-579
No files matched your search
@@ -18,6 +18,7 @@
|
||||
->values();
|
||||
@endphp
|
||||
|
||||
<x-shared-variables.layout>
|
||||
<div class="application-settings-form w-full" x-data="{
|
||||
sharedSearch: '',
|
||||
sharedSort: 'alphabetical',
|
||||
@@ -29,9 +30,6 @@
|
||||
return this.rows.filter(row => [row.key, row.comment, row.scope].some(value => value.includes(query))).length;
|
||||
}
|
||||
}">
|
||||
<x-dashboard.navbar section="shared-variables" title="Shared variables"
|
||||
subtitle="Reusable environment variables across resources" :titleOnDesktop="false" />
|
||||
|
||||
<x-application.settings-section :title="$title" flush>
|
||||
<x-slot:actions>
|
||||
<x-forms.button type="button" wire:click="switch" class="whitespace-nowrap">
|
||||
@@ -136,3 +134,4 @@
|
||||
@endif
|
||||
</x-application.settings-section>
|
||||
</div>
|
||||
</x-shared-variables.layout>
|
||||
@@ -0,0 +1,36 @@
|
||||
@php
|
||||
$sharedVariablesMenuItems = [
|
||||
['label' => 'Overview', 'route' => 'shared-variables.index', 'icon' => 'dashboard', 'active' => request()->routeIs('shared-variables.index')],
|
||||
['label' => 'Team', 'route' => 'shared-variables.team.index', 'icon' => 'teams', 'active' => request()->routeIs('shared-variables.team.*')],
|
||||
['label' => 'Projects', 'route' => 'shared-variables.project.index', 'icon' => 'projects', 'active' => request()->routeIs('shared-variables.project.*')],
|
||||
['label' => 'Environments', 'route' => 'shared-variables.environment.index', 'icon' => 'layers', 'active' => request()->routeIs('shared-variables.environment.*')],
|
||||
['label' => 'Servers', 'route' => 'shared-variables.server.index', 'icon' => 'servers', 'active' => request()->routeIs('shared-variables.server.*')],
|
||||
];
|
||||
@endphp
|
||||
|
||||
<section class="w-full max-w-[1180px]">
|
||||
<header class="mb-6 xl:hidden">
|
||||
<h1 class="text-[24px]! leading-7! font-semibold! tracking-tight!">Shared variables</h1>
|
||||
<p class="mt-1 text-[13px] text-neutral-500 dark:text-fg-dim">Reusable environment variables across resources</p>
|
||||
</header>
|
||||
|
||||
<div class="grid min-w-0 gap-8 xl:grid-cols-[210px_minmax(0,1fr)] xl:gap-10">
|
||||
<aside class="min-w-0 xl:self-start">
|
||||
<nav aria-label="Shared variables"
|
||||
class="grid grid-cols-2 gap-0.5 border-y border-neutral-200 py-3 sm:grid-cols-3 lg:grid-cols-5 xl:grid-cols-1 xl:border-y-0 xl:py-0 dark:border-white/[0.06]">
|
||||
@foreach ($sharedVariablesMenuItems as $menuItem)
|
||||
<a wire:key="shared-variables-{{ str($menuItem['label'])->slug() }}"
|
||||
@class(['menu-item', 'menu-item-active' => $menuItem['active']])
|
||||
{{ wireNavigate() }} href="{{ route($menuItem['route']) }}">
|
||||
<x-reicon :name="$menuItem['icon']" class="menu-item-icon" />
|
||||
<span class="menu-item-label">{{ $menuItem['label'] }}</span>
|
||||
</a>
|
||||
@endforeach
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
<div class="min-w-0">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,31 @@
|
||||
@props(['label', 'storageKey'])
|
||||
|
||||
<div class="mb-4 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div class="relative w-full sm:max-w-sm">
|
||||
<x-reicon name="search"
|
||||
class="pointer-events-none absolute top-1/2 left-2.5 z-10 size-3.5 -translate-y-1/2 text-neutral-400 dark:text-fg-faint" />
|
||||
<input x-model.debounce.150ms="search" type="search" placeholder="Search {{ strtolower($label) }}"
|
||||
class="h-8! w-full rounded-lg! border-neutral-200! bg-white! py-0! pr-8! pl-8! text-[12px]! shadow-none! placeholder:text-neutral-400 focus:border-accent! focus:ring-0! dark:border-white/[0.08]! dark:bg-white/[0.035]! dark:text-fg! dark:placeholder:text-fg-faint">
|
||||
<button x-cloak x-show="search" @click="search = ''" type="button"
|
||||
class="absolute top-1/2 right-2 flex size-5 -translate-y-1/2 items-center justify-center rounded text-neutral-400 transition-colors hover:bg-neutral-100 hover:text-black dark:text-fg-faint dark:hover:bg-white/[0.07] dark:hover:text-fg"
|
||||
aria-label="Clear search">
|
||||
<x-reicon name="x" class="size-3" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex h-8 w-fit items-center rounded-lg border border-neutral-200 bg-white p-0.5 dark:border-white/[0.08] dark:bg-white/[0.035]">
|
||||
<button type="button" @click="viewMode = 'list'; localStorage.setItem('{{ $storageKey }}', 'list')"
|
||||
class="flex size-6.5 items-center justify-center rounded-md transition-colors"
|
||||
:class="viewMode === 'list' ? 'control-selected' : 'text-neutral-400 hover:bg-neutral-100 hover:text-black dark:text-fg-faint dark:hover:bg-white/[0.06] dark:hover:text-fg'"
|
||||
aria-label="List view" title="List view">
|
||||
<x-reicon name="unordered-list" class="size-3.5" />
|
||||
</button>
|
||||
<button type="button" @click="viewMode = 'grid'; localStorage.setItem('{{ $storageKey }}', 'grid')"
|
||||
class="flex size-6.5 items-center justify-center rounded-md transition-colors"
|
||||
:class="viewMode === 'grid' ? 'control-selected' : 'text-neutral-400 hover:bg-neutral-100 hover:text-black dark:text-fg-faint dark:hover:bg-white/[0.06] dark:hover:text-fg'"
|
||||
aria-label="Grid view" title="Grid view">
|
||||
<x-reicon name="grid" class="size-3.5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
Reference in new issue
Block a user