mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 11:23:10 +02:00
co-authored by
Claude Haiku 4.5
parent
8b25db37ad
commit
012bd1af92
+8
-10
@@ -10,7 +10,6 @@ import {
|
||||
Loader,
|
||||
Group,
|
||||
TextInput,
|
||||
PasswordInput,
|
||||
Select,
|
||||
Badge,
|
||||
Table,
|
||||
@@ -29,6 +28,7 @@ import { useAdminSettings } from "@app/hooks/useAdminSettings";
|
||||
import PendingBadge from "@app/components/shared/config/PendingBadge";
|
||||
import { useLoginRequired } from "@app/hooks/useLoginRequired";
|
||||
import LoginRequiredBanner from "@app/components/shared/config/LoginRequiredBanner";
|
||||
import EditableSecretField from "@app/components/shared/EditableSecretField";
|
||||
import apiClient from "@app/services/apiClient";
|
||||
import LocalIcon from "@app/components/shared/LocalIcon";
|
||||
import databaseManagementService, { DatabaseBackupFile } from "@app/services/databaseManagementService";
|
||||
@@ -515,17 +515,15 @@ export default function AdminDatabaseSection() {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<PasswordInput
|
||||
label={
|
||||
<Group gap="xs">
|
||||
<span>{t("admin.settings.database.password.label", "Password")}</span>
|
||||
<PendingBadge show={isFieldPending("password")} />
|
||||
</Group>
|
||||
}
|
||||
<Group gap="xs" align="center" mb={4}>
|
||||
<span style={{ fontWeight: 500, fontSize: "0.875rem" }}>{t("admin.settings.database.password.label", "Password")}</span>
|
||||
<PendingBadge show={isFieldPending("password")} />
|
||||
</Group>
|
||||
<EditableSecretField
|
||||
description={t("admin.settings.database.password.description", "Database authentication password")}
|
||||
value={settings?.password || ""}
|
||||
onChange={(e) => setSettings({ ...settings, password: e.target.value })}
|
||||
placeholder="••••••••"
|
||||
onChange={(value) => setSettings({ ...settings, password: value })}
|
||||
placeholder="Enter database password"
|
||||
disabled={!loginEnabled}
|
||||
/>
|
||||
</div>
|
||||
|
||||
+9
-9
@@ -1,12 +1,13 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { TextInput, NumberInput, Switch, Button, Stack, Paper, Text, Loader, Group, PasswordInput, Anchor } from '@mantine/core';
|
||||
import { TextInput, NumberInput, Switch, Button, Stack, Paper, Text, Loader, Group, Anchor } from '@mantine/core';
|
||||
import { alert } from '@app/components/toast';
|
||||
import RestartConfirmationModal from '@app/components/shared/config/RestartConfirmationModal';
|
||||
import { useRestartServer } from '@app/components/shared/config/useRestartServer';
|
||||
import { useAdminSettings } from '@app/hooks/useAdminSettings';
|
||||
import PendingBadge from '@app/components/shared/config/PendingBadge';
|
||||
import EditableSecretField from '@app/components/shared/EditableSecretField';
|
||||
import apiClient from '@app/services/apiClient';
|
||||
|
||||
interface MailSettingsData {
|
||||
@@ -174,16 +175,15 @@ export default function AdminMailSection() {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<PasswordInput
|
||||
label={
|
||||
<Group gap="xs">
|
||||
<span>{t('admin.settings.mail.password.label', 'SMTP Password')}</span>
|
||||
<PendingBadge show={isFieldPending('password')} />
|
||||
</Group>
|
||||
}
|
||||
<Group gap="xs" align="center" mb={4}>
|
||||
<span style={{ fontWeight: 500, fontSize: '0.875rem' }}>{t('admin.settings.mail.password.label', 'SMTP Password')}</span>
|
||||
<PendingBadge show={isFieldPending('password')} />
|
||||
</Group>
|
||||
<EditableSecretField
|
||||
description={t('admin.settings.mail.password.description', 'SMTP authentication password')}
|
||||
value={settings.password || ''}
|
||||
onChange={(e) => setSettings({ ...settings, password: e.target.value })}
|
||||
onChange={(value) => setSettings({ ...settings, password: value })}
|
||||
placeholder="Enter SMTP password"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -18,11 +18,29 @@ export default function ApiKeys() {
|
||||
|
||||
const copy = async (text: string, tag: string) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
setCopied(tag);
|
||||
setTimeout(() => setCopied(null), 1600);
|
||||
// Try modern Clipboard API first (requires HTTPS)
|
||||
if (navigator.clipboard?.writeText) {
|
||||
await navigator.clipboard.writeText(text);
|
||||
setCopied(tag);
|
||||
setTimeout(() => setCopied(null), 1600);
|
||||
} else {
|
||||
// Fallback for HTTP: use old execCommand method
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = text;
|
||||
textarea.style.position = 'fixed';
|
||||
textarea.style.opacity = '0';
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
|
||||
if (document.execCommand('copy')) {
|
||||
setCopied(tag);
|
||||
setTimeout(() => setCopied(null), 1600);
|
||||
}
|
||||
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error('Failed to copy:', e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user