fix(260928-ujj): Biome-Formatierung der mit Design Mosaik eingebrachten Dateien
- Nur Formatierung und Importreihenfolge, keine Verhaltensaenderung - Betrifft ausschliesslich Befunde, die der Merge neu eingebracht hat Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -113,11 +113,7 @@ export function DeleteGroupDialog({ group, onClose, onDeleted }: DeleteGroupDial
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex justify-end gap-3">
|
<div className="flex justify-end gap-3">
|
||||||
<button
|
<button type="button" onClick={onClose} className="btn btn-secondary">
|
||||||
type="button"
|
|
||||||
onClick={onClose}
|
|
||||||
className="btn btn-secondary"
|
|
||||||
>
|
|
||||||
{tCommon('cancel')}
|
{tCommon('cancel')}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -249,11 +249,7 @@ export function GroupMembersModal({ group, onClose, onChanged }: GroupMembersMod
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex justify-between items-center gap-3">
|
<div className="flex justify-between items-center gap-3">
|
||||||
<button
|
<button type="button" onClick={onClose} className="btn btn-secondary">
|
||||||
type="button"
|
|
||||||
onClick={onClose}
|
|
||||||
className="btn btn-secondary"
|
|
||||||
>
|
|
||||||
{tCommon('close')}
|
{tCommon('close')}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { getTranslations } from 'next-intl/server';
|
import { getTranslations } from 'next-intl/server';
|
||||||
import { PageHeader } from '@/components/layout/page-header';
|
|
||||||
import { ChangelogView } from '@/components/changelog/changelog-view';
|
import { ChangelogView } from '@/components/changelog/changelog-view';
|
||||||
|
import { PageHeader } from '@/components/layout/page-header';
|
||||||
import { appVersion } from '@/lib/app-version';
|
import { appVersion } from '@/lib/app-version';
|
||||||
import { changelogMarkdown, filterChangelogForChannel } from '@/lib/changelog';
|
import { changelogMarkdown, filterChangelogForChannel } from '@/lib/changelog';
|
||||||
|
|
||||||
|
|||||||
@@ -116,11 +116,7 @@ export default function ProxmoxSettingsPage() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h1 className="text-2xl font-semibold tracking-tight">{t('settings.title')}</h1>
|
<h1 className="text-2xl font-semibold tracking-tight">{t('settings.title')}</h1>
|
||||||
{editingId === null && (
|
{editingId === null && (
|
||||||
<button
|
<button type="button" onClick={() => setEditingId('new')} className="btn btn-primary">
|
||||||
type="button"
|
|
||||||
onClick={() => setEditingId('new')}
|
|
||||||
className="btn btn-primary"
|
|
||||||
>
|
|
||||||
{t('settings.addServer')}
|
{t('settings.addServer')}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -112,11 +112,7 @@ export function BugReportDialog({ screenshot, isAdmin, onClose }: BugReportDialo
|
|||||||
<>
|
<>
|
||||||
<p className="text-sm text-foreground mb-4">{t('sent')}</p>
|
<p className="text-sm text-foreground mb-4">{t('sent')}</p>
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
<button
|
<button type="button" onClick={onClose} className="btn btn-primary">
|
||||||
type="button"
|
|
||||||
onClick={onClose}
|
|
||||||
className="btn btn-primary"
|
|
||||||
>
|
|
||||||
{t('close')}
|
{t('close')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -179,12 +175,7 @@ export function BugReportDialog({ screenshot, isAdmin, onClose }: BugReportDialo
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="mt-4 flex justify-end gap-3">
|
<div className="mt-4 flex justify-end gap-3">
|
||||||
<button
|
<button type="button" onClick={onClose} disabled={busy} className="btn btn-secondary">
|
||||||
type="button"
|
|
||||||
onClick={onClose}
|
|
||||||
disabled={busy}
|
|
||||||
className="btn btn-secondary"
|
|
||||||
>
|
|
||||||
{t('cancel')}
|
{t('cancel')}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ export function greetingPeriod(date: Date): 'morning' | 'day' | 'evening' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Vorname aus dem Anzeigenamen (erstes Wort), sonst der Benutzername. */
|
/** Vorname aus dem Anzeigenamen (erstes Wort), sonst der Benutzername. */
|
||||||
export function greetingName(displayName: string | null | undefined, username: string | undefined): string {
|
export function greetingName(
|
||||||
|
displayName: string | null | undefined,
|
||||||
|
username: string | undefined,
|
||||||
|
): string {
|
||||||
const first = displayName?.trim().split(/\s+/)[0];
|
const first = displayName?.trim().split(/\s+/)[0];
|
||||||
return first || username || '';
|
return first || username || '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { WidgetIcon } from './widget-icon';
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useLocale, useTranslations } from 'next-intl';
|
import { useLocale, useTranslations } from 'next-intl';
|
||||||
import { type ChangeEvent, type ReactNode, useEffect, useMemo, useRef, useState } from 'react';
|
import { type ChangeEvent, type ReactNode, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
@@ -30,6 +29,7 @@ import {
|
|||||||
selectServers,
|
selectServers,
|
||||||
widgetKeyFigure,
|
widgetKeyFigure,
|
||||||
} from './proxmox-widget-model';
|
} from './proxmox-widget-model';
|
||||||
|
import { WidgetIcon } from './widget-icon';
|
||||||
|
|
||||||
/** Minutentakt: so oft liest die Kachel das Zwischenlager neu. */
|
/** Minutentakt: so oft liest die Kachel das Zwischenlager neu. */
|
||||||
const REFRESH_MS = 60_000;
|
const REFRESH_MS = 60_000;
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ const PATHS: Record<string, ReactNode> = {
|
|||||||
<path d="M14 2v4a2 2 0 0 0 2 2h4M10 13h6M10 17h6M8 13h.01M8 17h.01" />
|
<path d="M14 2v4a2 2 0 0 0 2 2h4M10 13h6M10 17h6M8 13h.01M8 17h.01" />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
favorites: <path d="m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />,
|
favorites: (
|
||||||
|
<path d="m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
|
||||||
|
),
|
||||||
clock: (
|
clock: (
|
||||||
<>
|
<>
|
||||||
<circle cx="12" cy="12" r="10" />
|
<circle cx="12" cy="12" r="10" />
|
||||||
@@ -67,7 +69,13 @@ const PATHS: Record<string, ReactNode> = {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export function WidgetIcon({ type, variant = 'chip' }: { type: string; variant?: 'chip' | 'plain' }) {
|
export function WidgetIcon({
|
||||||
|
type,
|
||||||
|
variant = 'chip',
|
||||||
|
}: {
|
||||||
|
type: string;
|
||||||
|
variant?: 'chip' | 'plain';
|
||||||
|
}) {
|
||||||
const paths = PATHS[type];
|
const paths = PATHS[type];
|
||||||
if (!paths) return null;
|
if (!paths) return null;
|
||||||
const svg = (
|
const svg = (
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import type { CSSProperties } from 'react';
|
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
|
import type { CSSProperties } from 'react';
|
||||||
import { WIDGET_REGISTRY, type WidgetType } from '../widget-registry';
|
import { WIDGET_REGISTRY, type WidgetType } from '../widget-registry';
|
||||||
import { WidgetIcon } from './widget-icon';
|
import { WidgetIcon } from './widget-icon';
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,13 @@ interface PageHeaderProps {
|
|||||||
* 24/32 px halbfett, optionale Beschreibung 14 px gedaempft, Aktionen rechts.
|
* 24/32 px halbfett, optionale Beschreibung 14 px gedaempft, Aktionen rechts.
|
||||||
* Modulseiten tragen ihre App-Kachel (36 px) links vom Titel.
|
* Modulseiten tragen ihre App-Kachel (36 px) links vom Titel.
|
||||||
*/
|
*/
|
||||||
export function PageHeader({ title, description, actions, moduleSlug, className = '' }: PageHeaderProps) {
|
export function PageHeader({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
actions,
|
||||||
|
moduleSlug,
|
||||||
|
className = '',
|
||||||
|
}: PageHeaderProps) {
|
||||||
return (
|
return (
|
||||||
<div className={`flex flex-wrap items-start justify-between gap-x-6 gap-y-3 ${className}`}>
|
<div className={`flex flex-wrap items-start justify-between gap-x-6 gap-y-3 ${className}`}>
|
||||||
<div className="flex min-w-0 items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
|
|||||||
@@ -212,11 +212,7 @@ export function ReleaseNoticeDialog({ notice, onClose }: ReleaseNoticeDialogProp
|
|||||||
>
|
>
|
||||||
{t('showAll')}
|
{t('showAll')}
|
||||||
</Link>
|
</Link>
|
||||||
<button
|
<button type="button" onClick={close} className="btn btn-primary">
|
||||||
type="button"
|
|
||||||
onClick={close}
|
|
||||||
className="btn btn-primary"
|
|
||||||
>
|
|
||||||
{t('confirm')}
|
{t('confirm')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
import { DARK_ON_ACCENT, LIGHT_ON_ACCENT, normalizeHexColor, readableOnAccent, relativeLuminance } from './color';
|
import {
|
||||||
|
DARK_ON_ACCENT,
|
||||||
|
LIGHT_ON_ACCENT,
|
||||||
|
normalizeHexColor,
|
||||||
|
readableOnAccent,
|
||||||
|
relativeLuminance,
|
||||||
|
} from './color';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* color.test — Normalisierung der Hex-Eingabe der Akzentfarbe
|
* color.test — Normalisierung der Hex-Eingabe der Akzentfarbe
|
||||||
@@ -61,7 +67,15 @@ describe('readableOnAccent (Design „Mosaik“)', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('haelt fuer eine Reihe von Akzenten mindestens 3:1 (Symbol auf der Kachel)', () => {
|
it('haelt fuer eine Reihe von Akzenten mindestens 3:1 (Symbol auf der Kachel)', () => {
|
||||||
for (const accent of ['#ffed00', '#123456', '#e11d48', '#0ea5e9', '#16a34a', '#777777', '#f97316']) {
|
for (const accent of [
|
||||||
|
'#ffed00',
|
||||||
|
'#123456',
|
||||||
|
'#e11d48',
|
||||||
|
'#0ea5e9',
|
||||||
|
'#16a34a',
|
||||||
|
'#777777',
|
||||||
|
'#f97316',
|
||||||
|
]) {
|
||||||
expect(contrast(accent, readableOnAccent(accent))).toBeGreaterThanOrEqual(3);
|
expect(contrast(accent, readableOnAccent(accent))).toBeGreaterThanOrEqual(3);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user