simplifications and refactorings

This commit is contained in:
2026-05-04 16:59:06 +02:00
parent e14cb8a654
commit 4cdb4b144c
18 changed files with 30 additions and 456 deletions
+2 -2
View File
@@ -56,7 +56,7 @@ function Shell({
<AppBar position="sticky" color="inherit" elevation={0}>
<Toolbar sx={{ display: "flex", gap: 2, minHeight: 68 }}>
<Typography variant="h6" sx={{ mr: 2, fontWeight: 700 }}>
Media Library Viewer
Manage
</Typography>
<Tabs
value={current}
@@ -147,7 +147,7 @@ function SignInScreen({ onSignIn }: { onSignIn: () => void }) {
<Stack spacing={2} sx={{ alignItems: "center", textAlign: "center" }}>
<Typography variant="h5">Sign in required</Typography>
<Typography variant="body2" color="text.secondary">
Use your Authentik account to access the media library viewer.
Use your Authentik account to access Manage.
</Typography>
<Button variant="contained" onClick={onSignIn}>
Sign in with OIDC
-4
View File
@@ -9,7 +9,6 @@ import type {
UserDirectoryResponse,
UserMessageResponse,
UserMessageQueueStatus,
SmtpTestResponse,
NowPlayingSession,
MonitoringStatus,
MonitoringMetrics,
@@ -189,8 +188,5 @@ export const runJob = (jobKey: string, path: string) =>
export const fetchUserMessageQueueStatus = () =>
get<UserMessageQueueStatus>("/api/users/message/status");
export const testUserSmtpConnection = () =>
post<SmtpTestResponse>("/api/users/message/test-smtp");
export const sendUserMessage = (formData: FormData) =>
postForm<UserMessageResponse>("/api/users/message", formData);
-8
View File
@@ -1,8 +0,0 @@
import { useMutation } from "@tanstack/react-query";
import { testUserSmtpConnection } from "../api/client";
export function useTestUserSmtp() {
return useMutation({
mutationFn: testUserSmtpConnection,
});
}
+2 -90
View File
@@ -26,7 +26,6 @@ import {
IconButton,
LinearProgress,
Paper,
CircularProgress,
Stack,
Table,
TableBody,
@@ -43,7 +42,6 @@ import { SessionActivityPanel } from "../components/SessionActivityPanel";
import { useUsers } from "../hooks/useUsers";
import { useActivity } from "../hooks/useDashboard";
import { useSendUserMessage } from "../hooks/useSendUserMessage";
import { useTestUserSmtp } from "../hooks/useTestUserSmtp";
import { useUserMessageQueueStatus } from "../hooks/useUserMessageQueueStatus";
import type { UserDirectoryItem } from "../types";
import { buildUserDrawerModel } from "../users";
@@ -57,15 +55,13 @@ function userLabel(user: UserDirectoryItem) {
return user.display_name || user.username || user.jellyfin_id;
}
const DEFAULT_HTML_BODY =
"<p>Hello,</p><p> </p><p>Best,<br />Media Library Viewer</p>";
const DEFAULT_HTML_BODY = "<p>Hello,</p><p> </p><p>Best,<br />Manage</p>";
export function UsersPage() {
const { data, isError, error } = useUsers();
const { data: activity } = useActivity();
const queueStatusQuery = useUserMessageQueueStatus();
const sendUserMessage = useSendUserMessage();
const testUserSmtp = useTestUserSmtp();
const [search, setSearch] = useState("");
const [searchParams, setSearchParams] = useSearchParams();
const [selectedUserIds, setSelectedUserIds] = useState<string[]>([]);
@@ -236,7 +232,7 @@ export function UsersPage() {
sendUserMessage.reset();
if (!subject.trim()) {
setSubject(
`Media Library Viewer update for ${selectedDeliverableRows.length} user${selectedDeliverableRows.length === 1 ? "" : "s"}`,
`Manage update for ${selectedDeliverableRows.length} user${selectedDeliverableRows.length === 1 ? "" : "s"}`,
);
}
if (!htmlBody.trim()) {
@@ -389,76 +385,6 @@ export function UsersPage() {
</Alert>
) : null}
{testUserSmtp.isPending ? (
<Alert severity="info" variant="outlined">
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<CircularProgress size={16} />
<Typography variant="body2" sx={{ fontWeight: 600 }}>
Testing SMTP connection...
</Typography>
</Box>
</Alert>
) : testUserSmtp.isSuccess ? (
testUserSmtp.data.status === "ok" ? (
<Alert severity="success" variant="outlined">
SMTP connection succeeded: {testUserSmtp.data.smtp_host}:
{testUserSmtp.data.smtp_port} using{" "}
{testUserSmtp.data.use_ssl
? "SSL"
: testUserSmtp.data.use_tls
? "STARTTLS"
: "plain SMTP"}
.
<Typography
variant="caption"
component="div"
color="text.secondary"
>
{testUserSmtp.data.message}
</Typography>
{testUserSmtp.data.selected_mode ? (
<Typography
variant="caption"
component="div"
color="text.secondary"
>
Selected mode: {testUserSmtp.data.selected_mode.label}
</Typography>
) : null}
</Alert>
) : (
<Alert severity="warning" variant="outlined">
<Typography variant="body2" sx={{ fontWeight: 600 }}>
{testUserSmtp.data.message}
</Typography>
<Typography
variant="caption"
component="div"
color="text.secondary"
>
Tried {testUserSmtp.data.attempts.length} mode
{testUserSmtp.data.attempts.length === 1 ? "" : "s"}.
</Typography>
<Stack spacing={0.5} sx={{ mt: 1 }}>
{testUserSmtp.data.attempts.map((attempt) => (
<Typography
key={`${attempt.label}-${attempt.smtp_port}`}
variant="caption"
color="text.secondary"
>
{attempt.label}: {attempt.error || "failed"}
</Typography>
))}
</Stack>
</Alert>
)
) : testUserSmtp.isError ? (
<Alert severity="error" variant="outlined">
SMTP test failed:{" "}
{(testUserSmtp.error as Error)?.message || "Unknown error"}
</Alert>
) : null}
<Box
sx={{
display: "grid",
@@ -520,20 +446,6 @@ export function UsersPage() {
>
Message selected
</Button>
<Button
startIcon={
testUserSmtp.isPending ? (
<CircularProgress size={16} color="inherit" />
) : (
<SendIcon />
)
}
variant="outlined"
disabled={testUserSmtp.isPending}
onClick={() => testUserSmtp.mutate()}
>
{testUserSmtp.isPending ? "Testing SMTP..." : "Test SMTP"}
</Button>
<Button
variant="text"
disabled={!selectedRows.length}
-32
View File
@@ -78,38 +78,6 @@ export interface UserMessageQueueStatus {
failed_count: number;
}
export interface SmtpTestAttempt {
label: string;
smtp_host: string;
smtp_port: number;
use_tls: boolean;
use_ssl: boolean;
status: "ok" | "failed";
error?: string;
}
export interface SmtpTestSelectedMode {
label: string;
smtp_host: string;
smtp_port: number;
use_tls: boolean;
use_ssl: boolean;
}
export interface SmtpTestResponse {
status: "ok" | "error";
message: string;
from_address: string;
from_name: string;
smtp_host: string;
smtp_port: number;
use_tls: boolean;
use_ssl: boolean;
authenticated: boolean;
selected_mode: SmtpTestSelectedMode | null;
attempts: SmtpTestAttempt[];
}
export interface NowPlayingSession {
user: string;
title: string;