generated from Dicken/dickendock
Reset-Button, Service-Reorder, Port/HTTPS-Spalten, Healthcheck in Sidebar, Kategorien-Sync
This commit is contained in:
@@ -49,6 +49,17 @@ export const ServiceUpdateSchema = ServiceCreateSchema.omit({
|
||||
}).partial();
|
||||
export type ServiceUpdateInput = z.infer<typeof ServiceUpdateSchema>;
|
||||
|
||||
/** Für Drag & Drop: neue Reihenfolge mehrerer Dienste auf einmal setzen. */
|
||||
export const ServiceReorderSchema = z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.string().min(1),
|
||||
order: z.number(),
|
||||
})
|
||||
)
|
||||
.min(1, "mindestens ein Eintrag erforderlich");
|
||||
export type ServiceReorderInput = z.infer<typeof ServiceReorderSchema>;
|
||||
|
||||
export const CategoryCreateSchema = z.object({
|
||||
name: z.string().min(1, "name darf nicht leer sein"),
|
||||
});
|
||||
|
||||
47
packages/ui/src/FavoritesBar.tsx
Normal file
47
packages/ui/src/FavoritesBar.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import type { Service } from "@launchpad/shared";
|
||||
|
||||
export interface FavoritesBarProps {
|
||||
services: Service[];
|
||||
onOpen: (service: Service) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeigt Favoriten als anklickbare Chips – immer sichtbar, unabhängig vom
|
||||
* Suchfeld. Reihenfolge folgt service.order (im Adminbereich per Drag & Drop
|
||||
* änderbar).
|
||||
*/
|
||||
export function FavoritesBar({ services, onOpen }: FavoritesBarProps) {
|
||||
if (services.length === 0) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
role="toolbar"
|
||||
aria-label="Favoriten"
|
||||
className="flex flex-wrap items-center justify-center gap-2"
|
||||
>
|
||||
{services.map((service) => (
|
||||
<button
|
||||
key={service.id}
|
||||
type="button"
|
||||
onClick={() => onOpen(service)}
|
||||
title={`${service.displayName} (${service.hostname}:${service.port})`}
|
||||
className="flex items-center gap-2 rounded-full border border-black/10 bg-white/70
|
||||
px-3 py-1.5 text-sm text-black transition-colors hover:bg-black/5
|
||||
dark:border-white/10 dark:bg-white/5 dark:text-white dark:hover:bg-white/10"
|
||||
>
|
||||
{service.favicon ? (
|
||||
<img src={service.favicon} alt="" className="h-4 w-4 shrink-0 rounded" />
|
||||
) : (
|
||||
<span
|
||||
className="flex h-4 w-4 shrink-0 items-center justify-center rounded-full
|
||||
bg-black/10 text-[9px] font-medium text-black/50 dark:bg-white/10 dark:text-white/50"
|
||||
>
|
||||
{service.displayName.charAt(0).toUpperCase()}
|
||||
</span>
|
||||
)}
|
||||
<span className="max-w-[10rem] truncate">{service.displayName}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -9,3 +9,6 @@ export type { ResultsListProps } from "./ResultsList.js";
|
||||
|
||||
export { Button } from "./Button.js";
|
||||
export type { ButtonProps } from "./Button.js";
|
||||
|
||||
export { FavoritesBar } from "./FavoritesBar.js";
|
||||
export type { FavoritesBarProps } from "./FavoritesBar.js";
|
||||
|
||||
Reference in New Issue
Block a user