release: v0.15.0 (#585)

Eighteen changes since v0.14.0. See CHANGELOG.md for the full list and the upgrade notes (bump IMAGE_CACHE_VERSION).
This commit is contained in:
Ralksta
2026-09-19 22:24:10 +02:00
committed by GitHub
parent e99d3f2f1b
commit c3f92ca4ec
74 changed files with 4791 additions and 2146 deletions

View File

@@ -4,9 +4,8 @@ import { useState, useEffect, useCallback, type ReactNode } from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import BackupManagerModal from './BackupManagerModal';
import DoctorModal from './DoctorModal';
import type { DoctorLevel } from '@/lib/admin/doctor';
import { systemHealth } from './systemHealth';
import { DOCTOR_LEVEL_EVENT, systemHealth } from './systemHealth';
import * as Icons from './Icons';
interface Props {
@@ -30,7 +29,6 @@ export default function AdminDashboard({ onLogout, children }: Props) {
// Diagnostics & Backup state
const [showStatus, setShowStatus] = useState(false);
const [showBackupModal, setShowBackupModal] = useState(false);
const [showDoctor, setShowDoctor] = useState(false);
// The badge's job is "does anything need me?", and the doctor is the only
// check that can answer that beyond "is Immich up" (#491).
const [doctorLevel, setDoctorLevel] = useState<DoctorLevel | null>(null);
@@ -104,6 +102,14 @@ export default function AdminDashboard({ onLogout, children }: Props) {
fetchDoctor();
}, [fetchDoctor]);
// The diagnostics page runs the doctor itself; take its answer rather than
// asking Immich the same three questions again.
useEffect(() => {
const onLevel = (e: Event) => setDoctorLevel((e as CustomEvent<DoctorLevel>).detail);
window.addEventListener(DOCTOR_LEVEL_EVENT, onLevel);
return () => window.removeEventListener(DOCTOR_LEVEL_EVENT, onLevel);
}, []);
const immichIndicator = indicator(
status?.immich?.status === 'connected',
'Connected',
@@ -242,15 +248,13 @@ export default function AdminDashboard({ onLogout, children }: Props) {
</div>
</div>
<div className="status-dropdown-footer">
<button
<Link
href="/admin/diagnostics"
className="admin-btn admin-btn-sm"
onClick={() => {
setShowStatus(false);
setShowDoctor(true);
}}
onClick={() => setShowStatus(false)}
>
<Icons.IconShieldCheck size={14} /> Diagnostics
</button>
</Link>
<button
className="admin-btn admin-btn-sm"
onClick={() => {
@@ -300,14 +304,6 @@ export default function AdminDashboard({ onLogout, children }: Props) {
<main className="admin-main">{children}</main>
<DoctorModal
isOpen={showDoctor}
onClose={() => {
setShowDoctor(false);
fetchDoctor();
}}
/>
<BackupManagerModal
isOpen={showBackupModal}
onClose={() => setShowBackupModal(false)}