mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-18 11:56:01 +02:00
Merge pull request #31 from cadtoolbox/copilot/update-static-text-for-i18n
Internationalize Advanced Authentication strings
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { useMutation, useQueryClient, useQuery } from '@tanstack/react-query';
|
||||
import { X, Save, Loader2, Wifi, WifiOff, CheckCircle, Bell, Clock, LayoutGrid, Search, Plug, Power, Home, Radio, Eye } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { api } from '../api/client';
|
||||
import type { SmartPlug, SmartPlugCreate, SmartPlugUpdate, DiscoveredTasmotaDevice } from '../api/client';
|
||||
import { Button } from './Button';
|
||||
@@ -11,6 +12,7 @@ interface AddSmartPlugModalProps {
|
||||
}
|
||||
|
||||
export function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) {
|
||||
const { t } = useTranslation();
|
||||
const queryClient = useQueryClient();
|
||||
const isEditing = !!plug;
|
||||
|
||||
@@ -469,7 +471,7 @@ export function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) {
|
||||
{isScanning && scanProgress.total > 0 && (
|
||||
<div className="space-y-1">
|
||||
<div className="flex justify-between text-xs text-bambu-gray">
|
||||
<span>Scanning network...</span>
|
||||
<span>{t('smartPlugs.addSmartPlug.scanningNetwork')}</span>
|
||||
<span>{scanProgress.scanned} / {scanProgress.total}</span>
|
||||
</div>
|
||||
<div className="w-full bg-bambu-dark-tertiary rounded-full h-2">
|
||||
@@ -538,7 +540,7 @@ export function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) {
|
||||
disabled
|
||||
className="w-full px-3 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-bambu-gray cursor-not-allowed opacity-50"
|
||||
>
|
||||
<option>Choose an entity...</option>
|
||||
<option>{t('smartPlugs.addSmartPlug.chooseEntity')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -585,7 +587,7 @@ export function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) {
|
||||
setIsEntityDropdownOpen(true);
|
||||
setHaEntitySearch('');
|
||||
}}
|
||||
placeholder="Search entities..."
|
||||
placeholder={t('smartPlugs.addSmartPlug.placeholders.searchEntities')}
|
||||
className="w-full pl-9 pr-8 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none"
|
||||
/>
|
||||
{haEntityId && !isEntityDropdownOpen && (
|
||||
@@ -697,7 +699,7 @@ export function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) {
|
||||
setIsPowerDropdownOpen(true);
|
||||
setPowerSensorSearch('');
|
||||
}}
|
||||
placeholder="Search power sensors..."
|
||||
placeholder={t('smartPlugs.addSmartPlug.placeholders.searchPowerSensors')}
|
||||
className="w-full pl-9 pr-8 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none"
|
||||
/>
|
||||
{haPowerEntity && !isPowerDropdownOpen && (
|
||||
@@ -781,7 +783,7 @@ export function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) {
|
||||
setIsEnergyTodayDropdownOpen(true);
|
||||
setEnergyTodaySearch('');
|
||||
}}
|
||||
placeholder="Search energy sensors..."
|
||||
placeholder={t('smartPlugs.addSmartPlug.placeholders.searchEnergySensors')}
|
||||
className="w-full pl-9 pr-8 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none"
|
||||
/>
|
||||
{haEnergyTodayEntity && !isEnergyTodayDropdownOpen && (
|
||||
@@ -865,7 +867,7 @@ export function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) {
|
||||
setIsEnergyTotalDropdownOpen(true);
|
||||
setEnergyTotalSearch('');
|
||||
}}
|
||||
placeholder="Search energy sensors..."
|
||||
placeholder={t('smartPlugs.addSmartPlug.placeholders.searchEnergySensors')}
|
||||
className="w-full pl-9 pr-8 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none"
|
||||
/>
|
||||
{haEnergyTotalEntity && !isEnergyTotalDropdownOpen && (
|
||||
@@ -1060,7 +1062,7 @@ export function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) {
|
||||
type="text"
|
||||
value={mqttStateOnValue}
|
||||
onChange={(e) => setMqttStateOnValue(e.target.value)}
|
||||
placeholder="ON, true, 1"
|
||||
placeholder={t('smartPlugs.addSmartPlug.placeholders.mqttStateOnValue')}
|
||||
className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
@@ -1128,7 +1130,7 @@ export function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) {
|
||||
) : (
|
||||
<>
|
||||
<WifiOff className="w-5 h-5" />
|
||||
<span>Connection failed</span>
|
||||
<span>{t('smartPlugs.addSmartPlug.connectionFailed')}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@@ -1141,7 +1143,7 @@ export function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) {
|
||||
type="text"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
placeholder="Living Room Plug"
|
||||
placeholder={t('smartPlugs.addSmartPlug.placeholders.plugName')}
|
||||
className="w-full px-3 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white focus:border-bambu-green focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useState, useMemo, useEffect, useCallback } from 'react';
|
||||
import { useQuery, useMutation } from '@tanstack/react-query';
|
||||
import { X, Loader2, Settings2, ChevronDown, CheckCircle2, RotateCcw } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { api } from '../api/client';
|
||||
import type { KProfile } from '../api/client';
|
||||
import { Button } from './Button';
|
||||
@@ -216,6 +217,7 @@ export function ConfigureAmsSlotModal({
|
||||
nozzleDiameter = '0.4',
|
||||
onSuccess,
|
||||
}: ConfigureAmsSlotModalProps) {
|
||||
const { t } = useTranslation();
|
||||
const [selectedPresetId, setSelectedPresetId] = useState<string>('');
|
||||
const [selectedKProfile, setSelectedKProfile] = useState<KProfile | null>(null);
|
||||
const [colorHex, setColorHex] = useState<string>(''); // Just the 6-char hex, no alpha
|
||||
@@ -569,7 +571,7 @@ export function ConfigureAmsSlotModal({
|
||||
<div className="text-center space-y-3">
|
||||
<CheckCircle2 className="w-16 h-16 text-bambu-green mx-auto" />
|
||||
<p className="text-lg font-semibold text-white">Slot Configured!</p>
|
||||
<p className="text-sm text-bambu-gray">Settings sent to printer</p>
|
||||
<p className="text-sm text-bambu-gray">{t('configureAmsSlot.settingsSentToPrinter')}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -607,7 +609,7 @@ export function ConfigureAmsSlotModal({
|
||||
<div className="relative">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search presets..."
|
||||
placeholder={t('configureAmsSlot.searchPresets')}
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full px-3 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white placeholder:text-bambu-gray focus:border-bambu-green focus:outline-none mb-2"
|
||||
@@ -634,7 +636,7 @@ export function ConfigureAmsSlotModal({
|
||||
<span className="text-white text-sm truncate">{preset.name}</span>
|
||||
{isUserPreset(preset.setting_id) && (
|
||||
<span className="text-xs px-1.5 py-0.5 rounded bg-bambu-blue/20 text-bambu-blue">
|
||||
Custom
|
||||
{t('configureAmsSlot.custom')}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -750,7 +752,7 @@ export function ConfigureAmsSlotModal({
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Color name or hex (e.g., brown, FF8800)"
|
||||
placeholder={t('configureAmsSlot.colorPlaceholder')}
|
||||
value={colorInput}
|
||||
onChange={(e) => {
|
||||
const input = e.target.value;
|
||||
@@ -780,7 +782,7 @@ export function ConfigureAmsSlotModal({
|
||||
setColorInput('');
|
||||
}}
|
||||
className="px-2 py-1 text-xs text-bambu-gray hover:text-white bg-bambu-dark-tertiary rounded"
|
||||
title="Clear custom color"
|
||||
title={t('configureAmsSlot.clearCustomColor')}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
|
||||
@@ -54,7 +54,7 @@ export function EmailSettings() {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['smtpSettings'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['advancedAuthStatus'] });
|
||||
showToast('SMTP settings saved successfully', 'success');
|
||||
showToast(t('settings.email.success.settingsSaved'), 'success');
|
||||
},
|
||||
onError: (error: Error) => {
|
||||
showToast(error.message, 'error');
|
||||
@@ -88,12 +88,12 @@ export function EmailSettings() {
|
||||
const handleSave = () => {
|
||||
// Validate required fields
|
||||
if (!smtpSettings.smtp_host || !smtpSettings.smtp_from_email) {
|
||||
showToast('Please fill in all required fields', 'error');
|
||||
showToast(t('settings.email.errors.requiredFields'), 'error');
|
||||
return;
|
||||
}
|
||||
// Validate auth fields when authentication is enabled
|
||||
if (smtpSettings.smtp_auth_enabled && (!smtpSettings.smtp_username)) {
|
||||
showToast('Username is required when authentication is enabled', 'error');
|
||||
showToast(t('settings.email.errors.usernameRequired'), 'error');
|
||||
return;
|
||||
}
|
||||
saveMutation.mutate(smtpSettings);
|
||||
@@ -101,16 +101,16 @@ export function EmailSettings() {
|
||||
|
||||
const handleTest = () => {
|
||||
if (!testEmail) {
|
||||
showToast('Please enter a test email address', 'error');
|
||||
showToast(t('settings.email.errors.enterTestEmail'), 'error');
|
||||
return;
|
||||
}
|
||||
if (!smtpSettings.smtp_host || !smtpSettings.smtp_from_email) {
|
||||
showToast('Please fill in SMTP Server and From Email before testing', 'error');
|
||||
showToast(t('settings.email.errors.smtpServerAndEmail'), 'error');
|
||||
return;
|
||||
}
|
||||
// Validate auth fields when authentication is enabled
|
||||
if (smtpSettings.smtp_auth_enabled && (!smtpSettings.smtp_username || !smtpSettings.smtp_password)) {
|
||||
showToast('Username and Password are required when authentication is enabled', 'error');
|
||||
showToast(t('settings.email.errors.usernamePasswordRequired'), 'error');
|
||||
return;
|
||||
}
|
||||
testMutation.mutate({
|
||||
@@ -127,7 +127,7 @@ export function EmailSettings() {
|
||||
|
||||
const handleToggleAdvancedAuth = () => {
|
||||
if (!advancedAuthStatus?.advanced_auth_enabled && !advancedAuthStatus?.smtp_configured) {
|
||||
showToast('Please configure and test SMTP settings first', 'error');
|
||||
showToast(t('settings.email.errors.configureSmtpFirst'), 'error');
|
||||
return;
|
||||
}
|
||||
toggleAdvancedAuthMutation.mutate(!advancedAuthStatus?.advanced_auth_enabled);
|
||||
@@ -189,9 +189,9 @@ export function EmailSettings() {
|
||||
onChange={(e) => setSMTPSettings({ ...smtpSettings, smtp_security: e.target.value as 'starttls' | 'ssl' | 'none' })}
|
||||
className="w-full px-4 py-3 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-bambu-green/50 focus:border-bambu-green transition-colors"
|
||||
>
|
||||
<option value="starttls">STARTTLS (Port 587)</option>
|
||||
<option value="ssl">SSL/TLS (Port 465)</option>
|
||||
<option value="none">None (Port 25)</option>
|
||||
<option value="starttls">{t('settings.email.securityOptions.starttls')}</option>
|
||||
<option value="ssl">{t('settings.email.securityOptions.ssl')}</option>
|
||||
<option value="none">{t('settings.email.securityOptions.none')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
@@ -203,8 +203,8 @@ export function EmailSettings() {
|
||||
onChange={(e) => setSMTPSettings({ ...smtpSettings, smtp_auth_enabled: e.target.value === 'true' })}
|
||||
className="w-full px-4 py-3 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-bambu-green/50 focus:border-bambu-green transition-colors"
|
||||
>
|
||||
<option value="true">Enabled</option>
|
||||
<option value="false">Disabled</option>
|
||||
<option value="true">{t('settings.email.authOptions.enabled')}</option>
|
||||
<option value="false">{t('settings.email.authOptions.disabled')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useState } from 'react';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { Link2, Plus, Pencil, Trash2, GripVertical, Loader2, ExternalLink as ExternalLinkIcon } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { api } from '../api/client';
|
||||
import type { ExternalLink } from '../api/client';
|
||||
import { Card, CardContent, CardHeader } from './Card';
|
||||
@@ -10,6 +11,7 @@ import { ConfirmModal } from './ConfirmModal';
|
||||
import { getIconByName } from './IconPicker';
|
||||
|
||||
export function ExternalLinksSettings() {
|
||||
const { t } = useTranslation();
|
||||
const queryClient = useQueryClient();
|
||||
const [showAddModal, setShowAddModal] = useState(false);
|
||||
const [editingLink, setEditingLink] = useState<ExternalLink | null>(null);
|
||||
@@ -132,7 +134,7 @@ export function ExternalLinksSettings() {
|
||||
<button
|
||||
onClick={() => setEditingLink(link)}
|
||||
className="p-2 rounded-lg hover:bg-bambu-dark-tertiary text-bambu-gray hover:text-white transition-colors"
|
||||
title="Edit"
|
||||
title={t('common.edit')}
|
||||
>
|
||||
<Pencil className="w-4 h-4" />
|
||||
</button>
|
||||
@@ -140,7 +142,7 @@ export function ExternalLinksSettings() {
|
||||
onClick={() => handleDelete(link)}
|
||||
disabled={deleteMutation.isPending}
|
||||
className="p-2 rounded-lg hover:bg-red-500/20 text-bambu-gray hover:text-red-400 transition-colors disabled:opacity-50"
|
||||
title="Delete"
|
||||
title={t('externalLinks.deleteLink')}
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</button>
|
||||
@@ -152,7 +154,7 @@ export function ExternalLinksSettings() {
|
||||
) : (
|
||||
<div className="text-center py-8 text-bambu-gray">
|
||||
<Link2 className="w-8 h-8 mx-auto mb-2 opacity-50" />
|
||||
<p>No external links configured</p>
|
||||
<p>{t('externalLinks.noLinksConfigured')}</p>
|
||||
<p className="text-sm">Click "Add Link" to add one</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
Link as LinkIcon,
|
||||
Unlink,
|
||||
} from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface RichTextEditorProps {
|
||||
content: string;
|
||||
@@ -26,6 +27,7 @@ interface RichTextEditorProps {
|
||||
}
|
||||
|
||||
export function RichTextEditor({ content, onChange, placeholder }: RichTextEditorProps) {
|
||||
const { t } = useTranslation();
|
||||
const editor = useEditor({
|
||||
extensions: [
|
||||
StarterKit.configure({
|
||||
@@ -105,21 +107,21 @@ export function RichTextEditor({ content, onChange, placeholder }: RichTextEdito
|
||||
<ToolbarButton
|
||||
onClick={() => editor.chain().focus().toggleBold().run()}
|
||||
isActive={editor.isActive('bold')}
|
||||
title="Bold"
|
||||
title={t('richTextEditor.bold')}
|
||||
>
|
||||
<Bold className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
<ToolbarButton
|
||||
onClick={() => editor.chain().focus().toggleItalic().run()}
|
||||
isActive={editor.isActive('italic')}
|
||||
title="Italic"
|
||||
title={t('richTextEditor.italic')}
|
||||
>
|
||||
<Italic className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
<ToolbarButton
|
||||
onClick={() => editor.chain().focus().toggleUnderline().run()}
|
||||
isActive={editor.isActive('underline')}
|
||||
title="Underline"
|
||||
title={t('richTextEditor.underline')}
|
||||
>
|
||||
<UnderlineIcon className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
@@ -129,14 +131,14 @@ export function RichTextEditor({ content, onChange, placeholder }: RichTextEdito
|
||||
<ToolbarButton
|
||||
onClick={() => editor.chain().focus().toggleBulletList().run()}
|
||||
isActive={editor.isActive('bulletList')}
|
||||
title="Bullet List"
|
||||
title={t('richTextEditor.bulletList')}
|
||||
>
|
||||
<List className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
<ToolbarButton
|
||||
onClick={() => editor.chain().focus().toggleOrderedList().run()}
|
||||
isActive={editor.isActive('orderedList')}
|
||||
title="Numbered List"
|
||||
title={t('richTextEditor.numberedList')}
|
||||
>
|
||||
<ListOrdered className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
@@ -146,21 +148,21 @@ export function RichTextEditor({ content, onChange, placeholder }: RichTextEdito
|
||||
<ToolbarButton
|
||||
onClick={() => editor.chain().focus().setTextAlign('left').run()}
|
||||
isActive={editor.isActive({ textAlign: 'left' })}
|
||||
title="Align Left"
|
||||
title={t('richTextEditor.alignLeft')}
|
||||
>
|
||||
<AlignLeft className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
<ToolbarButton
|
||||
onClick={() => editor.chain().focus().setTextAlign('center').run()}
|
||||
isActive={editor.isActive({ textAlign: 'center' })}
|
||||
title="Align Center"
|
||||
title={t('richTextEditor.alignCenter')}
|
||||
>
|
||||
<AlignCenter className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
<ToolbarButton
|
||||
onClick={() => editor.chain().focus().setTextAlign('right').run()}
|
||||
isActive={editor.isActive({ textAlign: 'right' })}
|
||||
title="Align Right"
|
||||
title={t('richTextEditor.alignRight')}
|
||||
>
|
||||
<AlignRight className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
@@ -170,14 +172,14 @@ export function RichTextEditor({ content, onChange, placeholder }: RichTextEdito
|
||||
<ToolbarButton
|
||||
onClick={setLink}
|
||||
isActive={editor.isActive('link')}
|
||||
title="Add Link"
|
||||
title={t('richTextEditor.addLink')}
|
||||
>
|
||||
<LinkIcon className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
{editor.isActive('link') && (
|
||||
<ToolbarButton
|
||||
onClick={() => editor.chain().focus().unsetLink().run()}
|
||||
title="Remove Link"
|
||||
title={t('richTextEditor.removeLink')}
|
||||
>
|
||||
<Unlink className="w-4 h-4" />
|
||||
</ToolbarButton>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useState } from 'react';
|
||||
import { useMutation, useQueryClient, useQuery } from '@tanstack/react-query';
|
||||
import { Plug, Power, PowerOff, Loader2, Trash2, Settings2, Thermometer, Clock, Wifi, WifiOff, Edit2, Bell, Calendar, LayoutGrid, ExternalLink, Home, Radio, Eye } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { api } from '../api/client';
|
||||
import type { SmartPlug, SmartPlugUpdate } from '../api/client';
|
||||
import { Card, CardContent } from './Card';
|
||||
@@ -14,6 +15,7 @@ interface SmartPlugCardProps {
|
||||
}
|
||||
|
||||
export function SmartPlugCard({ plug, onEdit }: SmartPlugCardProps) {
|
||||
const { t } = useTranslation();
|
||||
const queryClient = useQueryClient();
|
||||
const { showToast } = useToast();
|
||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
||||
@@ -171,7 +173,7 @@ export function SmartPlugCard({ plug, onEdit }: SmartPlugCardProps) {
|
||||
) : (
|
||||
<div className="flex items-center gap-1 text-sm text-status-error">
|
||||
<WifiOff className="w-4 h-4" />
|
||||
<span>Offline</span>
|
||||
<span>{t('smartPlugs.offline')}</span>
|
||||
</div>
|
||||
)}
|
||||
{/* Admin page link - only for Tasmota */}
|
||||
@@ -181,10 +183,10 @@ export function SmartPlugCard({ plug, onEdit }: SmartPlugCardProps) {
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1 px-2 py-0.5 bg-bambu-dark hover:bg-bambu-dark-tertiary text-bambu-gray hover:text-white text-xs rounded-full transition-colors"
|
||||
title="Open plug admin page"
|
||||
title={t('smartPlugs.openPlugAdminPage')}
|
||||
>
|
||||
<ExternalLink className="w-3 h-3" />
|
||||
Admin
|
||||
{t('smartPlugs.admin')}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
@@ -449,7 +451,7 @@ export function SmartPlugCard({ plug, onEdit }: SmartPlugCardProps) {
|
||||
{/* Delete Confirmation */}
|
||||
{showDeleteConfirm && (
|
||||
<ConfirmModal
|
||||
title="Delete Smart Plug"
|
||||
title={t('smartPlugs.deleteSmartPlug')}
|
||||
message={`Are you sure you want to delete "${plug.name}"? This cannot be undone.`}
|
||||
confirmText="Delete"
|
||||
variant="danger"
|
||||
@@ -464,9 +466,9 @@ export function SmartPlugCard({ plug, onEdit }: SmartPlugCardProps) {
|
||||
{/* Power On Confirmation */}
|
||||
{showPowerOnConfirm && (
|
||||
<ConfirmModal
|
||||
title="Turn On Smart Plug"
|
||||
title={t('smartPlugs.turnOnSmartPlug')}
|
||||
message={`Are you sure you want to turn on "${plug.name}"?`}
|
||||
confirmText="Turn On"
|
||||
confirmText={t('smartPlugs.turnOn')}
|
||||
variant="default"
|
||||
onConfirm={() => {
|
||||
controlMutation.mutate('on');
|
||||
@@ -479,9 +481,9 @@ export function SmartPlugCard({ plug, onEdit }: SmartPlugCardProps) {
|
||||
{/* Power Off Confirmation */}
|
||||
{showPowerOffConfirm && (
|
||||
<ConfirmModal
|
||||
title="Turn Off Smart Plug"
|
||||
title={t('smartPlugs.turnOffSmartPlug')}
|
||||
message={`Are you sure you want to turn off "${plug.name}"? This will cut power to the connected device.`}
|
||||
confirmText="Turn Off"
|
||||
confirmText={t('smartPlugs.turnOff')}
|
||||
variant="danger"
|
||||
onConfirm={() => {
|
||||
controlMutation.mutate('off');
|
||||
|
||||
@@ -1030,6 +1030,30 @@ export default {
|
||||
feature2: 'Benutzer können sich mit Benutzername oder E-Mail anmelden',
|
||||
feature3: 'Passwort vergessen Funktion ist verfügbar',
|
||||
feature4: 'Administratoren können Benutzerpasswörter per E-Mail zurücksetzen',
|
||||
// Error messages
|
||||
errors: {
|
||||
requiredFields: 'Bitte füllen Sie alle Pflichtfelder aus',
|
||||
usernameRequired: 'Benutzername ist erforderlich, wenn Authentifizierung aktiviert ist',
|
||||
enterTestEmail: 'Bitte geben Sie eine Test-E-Mail-Adresse ein',
|
||||
smtpServerAndEmail: 'Bitte füllen Sie SMTP-Server und Absender-E-Mail aus, bevor Sie testen',
|
||||
usernamePasswordRequired: 'Benutzername und Passwort sind erforderlich, wenn Authentifizierung aktiviert ist',
|
||||
configureSmtpFirst: 'Bitte konfigurieren und testen Sie zuerst die SMTP-Einstellungen',
|
||||
},
|
||||
// Success messages
|
||||
success: {
|
||||
settingsSaved: 'SMTP-Einstellungen erfolgreich gespeichert',
|
||||
},
|
||||
// Security options
|
||||
securityOptions: {
|
||||
starttls: 'STARTTLS (Port 587)',
|
||||
ssl: 'SSL/TLS (Port 465)',
|
||||
none: 'Keine (Port 25)',
|
||||
},
|
||||
// Authentication options
|
||||
authOptions: {
|
||||
enabled: 'Aktiviert',
|
||||
disabled: 'Deaktiviert',
|
||||
},
|
||||
},
|
||||
appearance: 'Erscheinungsbild',
|
||||
notifications: 'Benachrichtigungen',
|
||||
@@ -2286,6 +2310,9 @@ export default {
|
||||
noPrintersAvailable: 'Keine Drucker verfügbar',
|
||||
printerBusy: 'Drucker ist beschäftigt',
|
||||
printerOffline: 'Drucker ist offline',
|
||||
sameTypeDifferentColor: 'Gleicher Typ, andere Farbe',
|
||||
filamentTypeNotLoaded: 'Filamenttyp nicht geladen',
|
||||
openCalendar: 'Kalender öffnen',
|
||||
},
|
||||
|
||||
// Backup
|
||||
@@ -2640,4 +2667,348 @@ export default {
|
||||
replaceCarbonFilter: 'Aktivkohlefilter ersetzen',
|
||||
lubricateLeftNozzleRail: 'Linke Düsenschiene schmieren (H2-Serie)',
|
||||
},
|
||||
|
||||
// Smart Plugs
|
||||
smartPlugs: {
|
||||
offline: 'Offline',
|
||||
admin: 'Admin',
|
||||
openPlugAdminPage: 'Plug-Admin-Seite öffnen',
|
||||
deleteSmartPlug: 'Smart Plug löschen',
|
||||
turnOnSmartPlug: 'Smart Plug einschalten',
|
||||
turnOffSmartPlug: 'Smart Plug ausschalten',
|
||||
turnOn: 'Einschalten',
|
||||
turnOff: 'Ausschalten',
|
||||
addSmartPlug: {
|
||||
scanningNetwork: 'Netzwerk wird durchsucht...',
|
||||
chooseEntity: 'Entität auswählen...',
|
||||
connectionFailed: 'Verbindung fehlgeschlagen',
|
||||
searchEntities: 'Entitäten suchen...',
|
||||
searchPowerSensors: 'Leistungssensoren suchen...',
|
||||
searchEnergySensors: 'Energiesensoren suchen...',
|
||||
placeholders: {
|
||||
plugName: 'Wohnzimmer Steckdose',
|
||||
mqttStateOnValue: 'ON, true, 1',
|
||||
mqttSameAsPower: 'Gleich wie Leistungs-Topic oder anders',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Rich Text Editor
|
||||
richTextEditor: {
|
||||
bold: 'Fett',
|
||||
italic: 'Kursiv',
|
||||
underline: 'Unterstrichen',
|
||||
bulletList: 'Aufzählungsliste',
|
||||
numberedList: 'Nummerierte Liste',
|
||||
alignLeft: 'Linksbündig',
|
||||
alignCenter: 'Zentriert',
|
||||
alignRight: 'Rechtsbündig',
|
||||
addLink: 'Link hinzufügen',
|
||||
removeLink: 'Link entfernen',
|
||||
},
|
||||
|
||||
// External Links
|
||||
externalLinks: {
|
||||
noLinksConfigured: 'Keine externen Links konfiguriert',
|
||||
deleteLink: 'Link löschen',
|
||||
removeCustomIcon: 'Benutzerdefiniertes Symbol entfernen',
|
||||
placeholders: {
|
||||
linkName: 'Mein Link',
|
||||
},
|
||||
},
|
||||
|
||||
// Keyboard Shortcuts Modal
|
||||
keyboardShortcuts: {
|
||||
title: 'Tastaturkürzel',
|
||||
navigation: 'Navigation',
|
||||
archivesSection: 'Archive',
|
||||
kProfilesSection: 'K-Profile',
|
||||
generalSection: 'Allgemein',
|
||||
shortcuts: {
|
||||
goToPrinters: 'Zu Drucker gehen',
|
||||
goToArchives: 'Zu Archiv gehen',
|
||||
goToQueue: 'Zur Warteschlange gehen',
|
||||
goToStats: 'Zu Statistiken gehen',
|
||||
goToProfiles: 'Zu Cloud-Profilen gehen',
|
||||
goToSettings: 'Zu Einstellungen gehen',
|
||||
focusSearch: 'Suche fokussieren',
|
||||
openUploadModal: 'Upload-Modal öffnen',
|
||||
clearSelection: 'Auswahl löschen / Eingabe aufheben',
|
||||
contextMenu: 'Kontextmenü auf Karten',
|
||||
refreshProfiles: 'Profile aktualisieren',
|
||||
newProfile: 'Neues Profil',
|
||||
exitSelectionMode: 'Auswahlmodus beenden',
|
||||
showHelp: 'Diese Hilfe anzeigen',
|
||||
},
|
||||
footer: 'Drücken Sie Esc oder klicken Sie außerhalb, um zu schließen',
|
||||
},
|
||||
|
||||
// Notification Log
|
||||
notificationLog: {
|
||||
title: 'Benachrichtigungsprotokoll',
|
||||
events: {
|
||||
printStarted: 'Druck gestartet',
|
||||
printComplete: 'Druck abgeschlossen',
|
||||
printFailed: 'Druck fehlgeschlagen',
|
||||
printStopped: 'Druck gestoppt',
|
||||
progress: 'Fortschritt',
|
||||
printerOffline: 'Drucker offline',
|
||||
printerError: 'Druckerfehler',
|
||||
lowFilament: 'Wenig Filament',
|
||||
maintenanceDue: 'Wartung fällig',
|
||||
test: 'Test',
|
||||
},
|
||||
timeAgo: {
|
||||
justNow: 'Gerade eben',
|
||||
minutesAgo: 'vor {{minutes}}m',
|
||||
hoursAgo: 'vor {{hours}}h',
|
||||
},
|
||||
},
|
||||
|
||||
// Restore/Backup Modal
|
||||
restoreBackup: {
|
||||
title: 'Backup wiederherstellen',
|
||||
restoring: 'Wird wiederhergestellt...',
|
||||
restoreComplete: 'Wiederherstellung abgeschlossen',
|
||||
restoreFailed: 'Wiederherstellung fehlgeschlagen',
|
||||
importSettings: 'Einstellungen aus Backup-Datei importieren',
|
||||
pleaseWait: 'Bitte warten Sie, während Ihre Daten wiederhergestellt werden',
|
||||
clickToSelect: 'Klicken Sie, um Backup-Datei auszuwählen (.json oder .zip)',
|
||||
howDuplicateHandling: 'So funktioniert die Duplikatbehandlung:',
|
||||
categories: {
|
||||
printers: 'Drucker',
|
||||
smartPlugs: 'Smart Plugs',
|
||||
notificationProviders: 'Benachrichtigungsanbieter',
|
||||
filaments: 'Filamente',
|
||||
archives: 'Archive',
|
||||
pendingUploads: 'Ausstehende Uploads',
|
||||
settingsTemplates: 'Einstellungen & Vorlagen',
|
||||
},
|
||||
matchingInfo: {
|
||||
printers: 'abgeglichen nach Seriennummer',
|
||||
smartPlugs: 'abgeglichen nach IP-Adresse',
|
||||
notificationProviders: 'abgeglichen nach Name',
|
||||
filaments: 'abgeglichen nach Name + Typ + Marke',
|
||||
archives: 'abgeglichen nach Inhalts-Hash',
|
||||
pendingUploads: 'abgeglichen nach Dateiname',
|
||||
settingsTemplates: 'immer überschrieben',
|
||||
},
|
||||
replaceExisting: 'Vorhandene Daten ersetzen',
|
||||
keepExisting: 'Vorhandene Daten behalten',
|
||||
replaceDescription: 'Bereits vorhandene Elemente mit Backup-Daten überschreiben',
|
||||
keepDescription: 'Nur Elemente wiederherstellen, die noch nicht existieren',
|
||||
caution: 'Vorsicht:',
|
||||
cautionText: 'Das Überschreiben ersetzt Ihre aktuellen Konfigurationen durch Backup-Daten. Drucker-Zugangscodes werden aus Sicherheitsgründen niemals überschrieben.',
|
||||
itemsRestored: 'Wiederhergestellte Elemente',
|
||||
itemsSkipped: 'Übersprungene Elemente',
|
||||
restored: 'Wiederhergestellt',
|
||||
skipped: 'Übersprungen (existieren bereits)',
|
||||
filesLabel: 'Dateien (3MF, Thumbnails, etc.)',
|
||||
newApiKeysGenerated: 'Neue API-Schlüssel generiert',
|
||||
newApiKeysWarning: 'Diese Schlüssel werden nur einmal angezeigt. Kopieren Sie sie jetzt!',
|
||||
processingBackup: 'Backup-Datei wird verarbeitet...',
|
||||
noDataFound: 'In der Backup-Datei wurden keine wiederherzustellenden Daten gefunden.',
|
||||
failedToRestore: 'Backup konnte nicht wiederhergestellt werden. Bitte überprüfen Sie das Dateiformat.',
|
||||
},
|
||||
|
||||
// Backup Export Modal
|
||||
backupExport: {
|
||||
title: 'Backup exportieren',
|
||||
selectData: 'Zu exportierende Daten auswählen',
|
||||
selectAll: 'Alle auswählen',
|
||||
selectNone: 'Keine auswählen',
|
||||
categoryDescriptions: {
|
||||
settings: 'Sprache, Theme, Update-Einstellungen',
|
||||
notifications: 'ntfy, Pushover, Discord, usw.',
|
||||
templates: 'Benutzerdefinierte Nachrichtenvorlagen',
|
||||
smartPlugs: 'Tasmota-Plug-Konfigurationen',
|
||||
externalLinks: 'Seitenleiste Links zu externen Diensten',
|
||||
printers: 'Druckerinformationen (Zugangscodes ausgeschlossen)',
|
||||
plateDetection: 'Leere Platten-Referenzbilder',
|
||||
filaments: 'Filamenttypen und -kosten',
|
||||
maintenance: 'Benutzerdefinierte Wartungspläne',
|
||||
archives: 'Alle Druckdaten + Dateien (3MF, Thumbnails, Fotos)',
|
||||
projects: 'Projekte, BOM-Elemente und Anhänge',
|
||||
pendingUploads: 'Virtueller Drucker-Uploads zur Überprüfung',
|
||||
apiKeys: 'Webhook-API-Schlüssel (neue Schlüssel bei Import generiert)',
|
||||
},
|
||||
requiresPrinters: 'Drucker müssen ausgewählt sein',
|
||||
zipFileWarning: 'ZIP-Datei wird erstellt.',
|
||||
zipFileDescription: 'Enthält alle 3MF-Dateien, Thumbnails, Zeitraffer und Fotos. Dies kann eine Weile dauern und zu einer großen Datei führen.',
|
||||
includeAccessCodes: 'Zugangscodes einschließen',
|
||||
includeAccessCodesDescription: 'Für die Übertragung auf eine andere Maschine',
|
||||
includeAccessCodesWarning: 'Zugangscodes werden im Klartext eingeschlossen. Bewahren Sie diese Backup-Datei sicher auf!',
|
||||
categoriesSelected: '{{selectedCount}} Kategorien ausgewählt',
|
||||
},
|
||||
|
||||
// Pending Uploads Panel
|
||||
pendingUploads: {
|
||||
placeholders: {
|
||||
notes: 'Notizen zu diesem Druck hinzufügen...',
|
||||
},
|
||||
discardUpload: 'Upload verwerfen',
|
||||
archiveAllUploads: 'Alle Uploads archivieren',
|
||||
discardAllUploads: 'Alle Uploads verwerfen',
|
||||
archive: 'Archivieren',
|
||||
timeAgo: {
|
||||
justNow: 'Gerade eben',
|
||||
minutesAgo: 'vor {{minutes}}m',
|
||||
hoursAgo: 'vor {{hours}}h',
|
||||
daysAgo: 'vor {{days}}d',
|
||||
},
|
||||
},
|
||||
|
||||
// API Browser
|
||||
apiBrowser: {
|
||||
placeholders: {
|
||||
requestBody: 'JSON-Anforderungstext...',
|
||||
searchEndpoints: 'Endpunkte suchen...',
|
||||
},
|
||||
},
|
||||
|
||||
// Configure AMS Slot Modal
|
||||
configureAmsSlot: {
|
||||
searchPresets: 'Voreinstellungen suchen...',
|
||||
colorPlaceholder: 'Farbname oder Hex (z.B. braun, FF8800)',
|
||||
clearCustomColor: 'Benutzerdefinierte Farbe löschen',
|
||||
noCloudPresets: 'Keine Cloud-Voreinstellungen. Melden Sie sich bei Bambu Cloud an, um zu synchronisieren.',
|
||||
noMatchingPresets: 'Keine passenden Voreinstellungen gefunden.',
|
||||
custom: 'Benutzerdefiniert',
|
||||
settingsSentToPrinter: 'Einstellungen an Drucker gesendet',
|
||||
filamentProfile: 'Filamentprofil',
|
||||
},
|
||||
|
||||
// GitHub Backup Settings
|
||||
githubBackup: {
|
||||
title: 'GitHub-Backup',
|
||||
history: 'Verlauf',
|
||||
downloadBackup: 'Backup herunterladen',
|
||||
restoreBackup: 'Backup wiederherstellen',
|
||||
noBackupsYet: 'Noch keine Backups',
|
||||
},
|
||||
|
||||
// Email Settings
|
||||
emailSettings: {
|
||||
placeholders: {
|
||||
fromName: 'BamBuddy',
|
||||
},
|
||||
},
|
||||
|
||||
// Tag Management Modal
|
||||
tagManagement: {
|
||||
searchTags: 'Tags suchen...',
|
||||
renameTag: 'Tag umbenennen',
|
||||
deleteTag: 'Tag löschen',
|
||||
},
|
||||
|
||||
// Notification Template Editor
|
||||
notificationTemplates: {
|
||||
placeholders: {
|
||||
title: 'Benachrichtigungstitel...',
|
||||
body: 'Benachrichtigungstext...',
|
||||
},
|
||||
},
|
||||
|
||||
// Batch Tag Modal
|
||||
batchTag: {
|
||||
placeholders: {
|
||||
newTag: 'Neuen Tag eingeben...',
|
||||
},
|
||||
},
|
||||
|
||||
// Photo Gallery Modal
|
||||
photoGallery: {
|
||||
deletePhoto: 'Foto löschen',
|
||||
},
|
||||
|
||||
// Filament Hover Card
|
||||
filamentHoverCard: {
|
||||
copySpoolUuid: 'Spulen-UUID kopieren',
|
||||
},
|
||||
|
||||
// K Profiles View
|
||||
kProfilesView: {
|
||||
hasNote: 'Hat Notiz',
|
||||
copyProfile: 'Profil kopieren',
|
||||
},
|
||||
|
||||
// Layout/Navigation
|
||||
layout: {
|
||||
openMenu: 'Menü öffnen',
|
||||
noPermissionSystemInfo: 'Sie haben keine Berechtigung zum Anzeigen von Systeminformationen',
|
||||
},
|
||||
|
||||
// Dashboard
|
||||
dashboard: {
|
||||
dragToReorder: 'Ziehen zum Neuordnen',
|
||||
hideWidget: 'Widget ausblenden',
|
||||
},
|
||||
|
||||
// Notification Provider Card
|
||||
notificationProviderCard: {
|
||||
deleteNotificationProvider: 'Benachrichtigungsanbieter löschen',
|
||||
},
|
||||
|
||||
// File Manager Modal
|
||||
fileManagerModal: {
|
||||
closeFileManager: 'Dateimanager schließen',
|
||||
sortFiles: 'Dateien sortieren',
|
||||
goToParentFolder: 'Zum übergeordneten Ordner gehen',
|
||||
threeView: '3D-Ansicht',
|
||||
},
|
||||
|
||||
// Embedded Camera Viewer
|
||||
embeddedCameraViewer: {
|
||||
refreshStream: 'Stream aktualisieren',
|
||||
close: 'Schließen',
|
||||
zoomOut: 'Verkleinern',
|
||||
resetZoom: 'Zoom zurücksetzen',
|
||||
zoomIn: 'Vergrößern',
|
||||
dragToResize: 'Ziehen zum Größe ändern',
|
||||
},
|
||||
|
||||
// Timelapse Viewer
|
||||
timelapseViewer: {
|
||||
skipBack5s: '5s zurückspringen',
|
||||
skipForward5s: '5s vorspringen',
|
||||
},
|
||||
|
||||
// Notification Providers
|
||||
notificationProviders: {
|
||||
descriptions: {
|
||||
email: 'SMTP-E-Mail-Benachrichtigungen',
|
||||
telegram: 'Benachrichtigungen über Telegram-Bot',
|
||||
discord: 'An Discord-Kanal über Webhook senden',
|
||||
ntfy: 'Kostenlose, selbst hostbare Push-Benachrichtigungen',
|
||||
pushover: 'Einfache, zuverlässige Push-Benachrichtigungen',
|
||||
callmebot: 'Kostenlose WhatsApp-Benachrichtigungen über CallMeBot',
|
||||
webhook: 'Generischer HTTP POST zu beliebiger URL',
|
||||
},
|
||||
},
|
||||
|
||||
// Log Viewer
|
||||
logViewer: {
|
||||
searchPlaceholder: 'Nachricht oder Logger-Name suchen...',
|
||||
noLogEntries: 'Keine Logeinträge gefunden',
|
||||
},
|
||||
|
||||
// Switchbar Popover
|
||||
switchbarPopover: {
|
||||
noSwitchesInSwitchbar: 'Keine Schalter in Schalterleiste',
|
||||
},
|
||||
|
||||
// Project Page Modal
|
||||
projectPageModal: {
|
||||
placeholders: {
|
||||
title: 'Titel',
|
||||
designer: 'Designer',
|
||||
license: 'Lizenz',
|
||||
description: 'Beschreibung eingeben...',
|
||||
profileTitle: 'Profil-Titel',
|
||||
profileDescription: 'Profilbeschreibung...',
|
||||
},
|
||||
},
|
||||
|
||||
// Spoolman Settings
|
||||
spoolmanSettings: {},
|
||||
};
|
||||
|
||||
@@ -1030,6 +1030,30 @@ export default {
|
||||
feature2: 'Users can login with username or email',
|
||||
feature3: 'Forgot password feature is available',
|
||||
feature4: 'Admins can reset user passwords via email',
|
||||
// Error messages
|
||||
errors: {
|
||||
requiredFields: 'Please fill in all required fields',
|
||||
usernameRequired: 'Username is required when authentication is enabled',
|
||||
enterTestEmail: 'Please enter a test email address',
|
||||
smtpServerAndEmail: 'Please fill in SMTP Server and From Email before testing',
|
||||
usernamePasswordRequired: 'Username and Password are required when authentication is enabled',
|
||||
configureSmtpFirst: 'Please configure and test SMTP settings first',
|
||||
},
|
||||
// Success messages
|
||||
success: {
|
||||
settingsSaved: 'SMTP settings saved successfully',
|
||||
},
|
||||
// Security options
|
||||
securityOptions: {
|
||||
starttls: 'STARTTLS (Port 587)',
|
||||
ssl: 'SSL/TLS (Port 465)',
|
||||
none: 'None (Port 25)',
|
||||
},
|
||||
// Authentication options
|
||||
authOptions: {
|
||||
enabled: 'Enabled',
|
||||
disabled: 'Disabled',
|
||||
},
|
||||
},
|
||||
appearance: 'Appearance',
|
||||
notifications: 'Notifications',
|
||||
@@ -2286,6 +2310,9 @@ export default {
|
||||
noPrintersAvailable: 'No printers available',
|
||||
printerBusy: 'Printer is busy',
|
||||
printerOffline: 'Printer is offline',
|
||||
sameTypeDifferentColor: 'Same type, different color',
|
||||
filamentTypeNotLoaded: 'Filament type not loaded',
|
||||
openCalendar: 'Open calendar',
|
||||
},
|
||||
|
||||
// Backup
|
||||
@@ -2338,6 +2365,7 @@ export default {
|
||||
},
|
||||
|
||||
// Edit archive modal
|
||||
// Edit Archive Modal
|
||||
editArchive: {
|
||||
title: 'Edit Archive',
|
||||
name: 'Name',
|
||||
@@ -2640,4 +2668,348 @@ export default {
|
||||
replaceCarbonFilter: 'Replace activated carbon filter',
|
||||
lubricateLeftNozzleRail: 'Lubricate left nozzle rail (H2 series)',
|
||||
},
|
||||
|
||||
// Smart Plugs
|
||||
smartPlugs: {
|
||||
offline: 'Offline',
|
||||
admin: 'Admin',
|
||||
openPlugAdminPage: 'Open plug admin page',
|
||||
deleteSmartPlug: 'Delete Smart Plug',
|
||||
turnOnSmartPlug: 'Turn On Smart Plug',
|
||||
turnOffSmartPlug: 'Turn Off Smart Plug',
|
||||
turnOn: 'Turn On',
|
||||
turnOff: 'Turn Off',
|
||||
addSmartPlug: {
|
||||
scanningNetwork: 'Scanning network...',
|
||||
chooseEntity: 'Choose an entity...',
|
||||
connectionFailed: 'Connection failed',
|
||||
searchEntities: 'Search entities...',
|
||||
searchPowerSensors: 'Search power sensors...',
|
||||
searchEnergySensors: 'Search energy sensors...',
|
||||
placeholders: {
|
||||
plugName: 'Living Room Plug',
|
||||
mqttStateOnValue: 'ON, true, 1',
|
||||
mqttSameAsPower: 'Same as power topic, or different',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Rich Text Editor
|
||||
richTextEditor: {
|
||||
bold: 'Bold',
|
||||
italic: 'Italic',
|
||||
underline: 'Underline',
|
||||
bulletList: 'Bullet List',
|
||||
numberedList: 'Numbered List',
|
||||
alignLeft: 'Align Left',
|
||||
alignCenter: 'Align Center',
|
||||
alignRight: 'Align Right',
|
||||
addLink: 'Add Link',
|
||||
removeLink: 'Remove Link',
|
||||
},
|
||||
|
||||
// External Links
|
||||
externalLinks: {
|
||||
noLinksConfigured: 'No external links configured',
|
||||
deleteLink: 'Delete Link',
|
||||
removeCustomIcon: 'Remove custom icon',
|
||||
placeholders: {
|
||||
linkName: 'My Link',
|
||||
},
|
||||
},
|
||||
|
||||
// Keyboard Shortcuts Modal
|
||||
keyboardShortcuts: {
|
||||
title: 'Keyboard Shortcuts',
|
||||
navigation: 'Navigation',
|
||||
archivesSection: 'Archives',
|
||||
kProfilesSection: 'K-Profiles',
|
||||
generalSection: 'General',
|
||||
shortcuts: {
|
||||
goToPrinters: 'Go to Printers',
|
||||
goToArchives: 'Go to Archives',
|
||||
goToQueue: 'Go to Queue',
|
||||
goToStats: 'Go to Statistics',
|
||||
goToProfiles: 'Go to Cloud Profiles',
|
||||
goToSettings: 'Go to Settings',
|
||||
focusSearch: 'Focus search',
|
||||
openUploadModal: 'Open upload modal',
|
||||
clearSelection: 'Clear selection / blur input',
|
||||
contextMenu: 'Context menu on cards',
|
||||
refreshProfiles: 'Refresh profiles',
|
||||
newProfile: 'New profile',
|
||||
exitSelectionMode: 'Exit selection mode',
|
||||
showHelp: 'Show this help',
|
||||
},
|
||||
footer: 'Press Esc or click outside to close',
|
||||
},
|
||||
|
||||
// Notification Log
|
||||
notificationLog: {
|
||||
title: 'Notification Log',
|
||||
events: {
|
||||
printStarted: 'Print Started',
|
||||
printComplete: 'Print Complete',
|
||||
printFailed: 'Print Failed',
|
||||
printStopped: 'Print Stopped',
|
||||
progress: 'Progress',
|
||||
printerOffline: 'Printer Offline',
|
||||
printerError: 'Printer Error',
|
||||
lowFilament: 'Low Filament',
|
||||
maintenanceDue: 'Maintenance Due',
|
||||
test: 'Test',
|
||||
},
|
||||
timeAgo: {
|
||||
justNow: 'Just now',
|
||||
minutesAgo: '{{minutes}}m ago',
|
||||
hoursAgo: '{{hours}}h ago',
|
||||
},
|
||||
},
|
||||
|
||||
// Restore/Backup Modal
|
||||
restoreBackup: {
|
||||
title: 'Restore Backup',
|
||||
restoring: 'Restoring...',
|
||||
restoreComplete: 'Restore Complete',
|
||||
restoreFailed: 'Restore Failed',
|
||||
importSettings: 'Import settings from a backup file',
|
||||
pleaseWait: 'Please wait while your data is being restored',
|
||||
clickToSelect: 'Click to select backup file (.json or .zip)',
|
||||
howDuplicateHandling: 'How duplicate handling works:',
|
||||
categories: {
|
||||
printers: 'Printers',
|
||||
smartPlugs: 'Smart Plugs',
|
||||
notificationProviders: 'Notification Providers',
|
||||
filaments: 'Filaments',
|
||||
archives: 'Archives',
|
||||
pendingUploads: 'Pending Uploads',
|
||||
settingsTemplates: 'Settings & Templates',
|
||||
},
|
||||
matchingInfo: {
|
||||
printers: 'matched by serial number',
|
||||
smartPlugs: 'matched by IP address',
|
||||
notificationProviders: 'matched by name',
|
||||
filaments: 'matched by name + type + brand',
|
||||
archives: 'matched by content hash',
|
||||
pendingUploads: 'matched by filename',
|
||||
settingsTemplates: 'always overwritten',
|
||||
},
|
||||
replaceExisting: 'Replace existing data',
|
||||
keepExisting: 'Keep existing data',
|
||||
replaceDescription: 'Overwrite items that already exist with backup data',
|
||||
keepDescription: 'Only restore items that don\'t already exist',
|
||||
caution: 'Caution:',
|
||||
cautionText: 'Overwriting will replace your current configurations with backup data. Printer access codes are never overwritten for security.',
|
||||
itemsRestored: 'Items Restored',
|
||||
itemsSkipped: 'Items Skipped',
|
||||
restored: 'Restored',
|
||||
skipped: 'Skipped (already exist)',
|
||||
filesLabel: 'Files (3MF, thumbnails, etc.)',
|
||||
newApiKeysGenerated: 'New API Keys Generated',
|
||||
newApiKeysWarning: 'These keys are only shown once. Copy them now!',
|
||||
processingBackup: 'Processing backup file...',
|
||||
noDataFound: 'No data was found to restore in the backup file.',
|
||||
failedToRestore: 'Failed to restore backup. Please check the file format.',
|
||||
},
|
||||
|
||||
// Backup Export Modal
|
||||
backupExport: {
|
||||
title: 'Export Backup',
|
||||
selectData: 'Select data to include',
|
||||
selectAll: 'Select All',
|
||||
selectNone: 'Select None',
|
||||
categoryDescriptions: {
|
||||
settings: 'Language, theme, update preferences',
|
||||
notifications: 'ntfy, Pushover, Discord, etc.',
|
||||
templates: 'Custom message templates',
|
||||
smartPlugs: 'Tasmota plug configurations',
|
||||
externalLinks: 'Sidebar links to external services',
|
||||
printers: 'Printer info (access codes excluded)',
|
||||
plateDetection: 'Empty plate reference images',
|
||||
filaments: 'Filament types and costs',
|
||||
maintenance: 'Custom maintenance schedules',
|
||||
archives: 'All print data + files (3MF, thumbnails, photos)',
|
||||
projects: 'Projects, BOM items, and attachments',
|
||||
pendingUploads: 'Virtual printer uploads awaiting review',
|
||||
apiKeys: 'Webhook API keys (new keys generated on import)',
|
||||
},
|
||||
requiresPrinters: 'Requires Printers to be selected',
|
||||
zipFileWarning: 'ZIP file will be created.',
|
||||
zipFileDescription: 'Includes all 3MF files, thumbnails, timelapses, and photos. This may take a while and result in a large file.',
|
||||
includeAccessCodes: 'Include Access Codes',
|
||||
includeAccessCodesDescription: 'For transferring to another machine',
|
||||
includeAccessCodesWarning: 'Access codes will be included in plain text. Keep this backup file secure!',
|
||||
categoriesSelected: '{{selectedCount}} categories selected',
|
||||
},
|
||||
|
||||
// Pending Uploads Panel
|
||||
pendingUploads: {
|
||||
placeholders: {
|
||||
notes: 'Add notes about this print...',
|
||||
},
|
||||
discardUpload: 'Discard Upload',
|
||||
archiveAllUploads: 'Archive All Uploads',
|
||||
discardAllUploads: 'Discard All Uploads',
|
||||
archive: 'Archive',
|
||||
timeAgo: {
|
||||
justNow: 'Just now',
|
||||
minutesAgo: '{{minutes}}m ago',
|
||||
hoursAgo: '{{hours}}h ago',
|
||||
daysAgo: '{{days}}d ago',
|
||||
},
|
||||
},
|
||||
|
||||
// API Browser
|
||||
apiBrowser: {
|
||||
placeholders: {
|
||||
requestBody: 'JSON request body...',
|
||||
searchEndpoints: 'Search endpoints...',
|
||||
},
|
||||
},
|
||||
|
||||
// Configure AMS Slot Modal
|
||||
configureAmsSlot: {
|
||||
searchPresets: 'Search presets...',
|
||||
colorPlaceholder: 'Color name or hex (e.g., brown, FF8800)',
|
||||
clearCustomColor: 'Clear custom color',
|
||||
noCloudPresets: 'No cloud presets. Login to Bambu Cloud to sync.',
|
||||
noMatchingPresets: 'No matching presets found.',
|
||||
custom: 'Custom',
|
||||
settingsSentToPrinter: 'Settings sent to printer',
|
||||
filamentProfile: 'Filament Profile',
|
||||
},
|
||||
|
||||
// GitHub Backup Settings
|
||||
githubBackup: {
|
||||
title: 'GitHub Backup',
|
||||
history: 'History',
|
||||
downloadBackup: 'Download Backup',
|
||||
restoreBackup: 'Restore Backup',
|
||||
noBackupsYet: 'No backups yet',
|
||||
},
|
||||
|
||||
// Email Settings
|
||||
emailSettings: {
|
||||
placeholders: {
|
||||
fromName: 'BamBuddy',
|
||||
},
|
||||
},
|
||||
|
||||
// Tag Management Modal
|
||||
tagManagement: {
|
||||
searchTags: 'Search tags...',
|
||||
renameTag: 'Rename tag',
|
||||
deleteTag: 'Delete tag',
|
||||
},
|
||||
|
||||
// Notification Template Editor
|
||||
notificationTemplates: {
|
||||
placeholders: {
|
||||
title: 'Notification title...',
|
||||
body: 'Notification body...',
|
||||
},
|
||||
},
|
||||
|
||||
// Batch Tag Modal
|
||||
batchTag: {
|
||||
placeholders: {
|
||||
newTag: 'Enter new tag...',
|
||||
},
|
||||
},
|
||||
|
||||
// Photo Gallery Modal
|
||||
photoGallery: {
|
||||
deletePhoto: 'Delete Photo',
|
||||
},
|
||||
|
||||
// Filament Hover Card
|
||||
filamentHoverCard: {
|
||||
copySpoolUuid: 'Copy spool UUID',
|
||||
},
|
||||
|
||||
// K Profiles View
|
||||
kProfilesView: {
|
||||
hasNote: 'Has note',
|
||||
copyProfile: 'Copy profile',
|
||||
},
|
||||
|
||||
// Layout/Navigation
|
||||
layout: {
|
||||
openMenu: 'Open menu',
|
||||
noPermissionSystemInfo: 'You do not have permission to view system information',
|
||||
},
|
||||
|
||||
// Dashboard
|
||||
dashboard: {
|
||||
dragToReorder: 'Drag to reorder',
|
||||
hideWidget: 'Hide widget',
|
||||
},
|
||||
|
||||
// Notification Provider Card
|
||||
notificationProviderCard: {
|
||||
deleteNotificationProvider: 'Delete Notification Provider',
|
||||
},
|
||||
|
||||
// File Manager Modal
|
||||
fileManagerModal: {
|
||||
closeFileManager: 'Close file manager',
|
||||
sortFiles: 'Sort files',
|
||||
goToParentFolder: 'Go to parent folder',
|
||||
threeView: '3D View',
|
||||
},
|
||||
|
||||
// Embedded Camera Viewer
|
||||
embeddedCameraViewer: {
|
||||
refreshStream: 'Refresh stream',
|
||||
close: 'Close',
|
||||
zoomOut: 'Zoom out',
|
||||
resetZoom: 'Reset zoom',
|
||||
zoomIn: 'Zoom in',
|
||||
dragToResize: 'Drag to resize',
|
||||
},
|
||||
|
||||
// Timelapse Viewer
|
||||
timelapseViewer: {
|
||||
skipBack5s: 'Skip back 5s',
|
||||
skipForward5s: 'Skip forward 5s',
|
||||
},
|
||||
|
||||
// Notification Providers
|
||||
notificationProviders: {
|
||||
descriptions: {
|
||||
email: 'SMTP email notifications',
|
||||
telegram: 'Notifications via Telegram bot',
|
||||
discord: 'Send to Discord channel via webhook',
|
||||
ntfy: 'Free, self-hostable push notifications',
|
||||
pushover: 'Simple, reliable push notifications',
|
||||
callmebot: 'Free WhatsApp notifications via CallMeBot',
|
||||
webhook: 'Generic HTTP POST to any URL',
|
||||
},
|
||||
},
|
||||
|
||||
// Log Viewer
|
||||
logViewer: {
|
||||
searchPlaceholder: 'Search message or logger name...',
|
||||
noLogEntries: 'No log entries found',
|
||||
},
|
||||
|
||||
// Switchbar Popover
|
||||
switchbarPopover: {
|
||||
noSwitchesInSwitchbar: 'No switches in switchbar',
|
||||
},
|
||||
|
||||
// Project Page Modal
|
||||
projectPageModal: {
|
||||
placeholders: {
|
||||
title: 'Title',
|
||||
designer: 'Designer',
|
||||
license: 'License',
|
||||
description: 'Enter description...',
|
||||
profileTitle: 'Profile Title',
|
||||
profileDescription: 'Profile description...',
|
||||
},
|
||||
},
|
||||
|
||||
// Spoolman Settings
|
||||
spoolmanSettings: {},
|
||||
};
|
||||
|
||||
@@ -1182,6 +1182,30 @@ export default {
|
||||
feature2: 'ユーザーはユーザー名またはメールでログインできます',
|
||||
feature3: 'パスワード忘れ機能が利用可能です',
|
||||
feature4: '管理者はメールでユーザーパスワードをリセットできます',
|
||||
// Error messages
|
||||
errors: {
|
||||
requiredFields: 'すべての必須フィールドに入力してください',
|
||||
usernameRequired: '認証が有効な場合、ユーザー名は必須です',
|
||||
enterTestEmail: 'テストメールアドレスを入力してください',
|
||||
smtpServerAndEmail: 'テストする前にSMTPサーバーと送信元メールを入力してください',
|
||||
usernamePasswordRequired: '認証が有効な場合、ユーザー名とパスワードは必須です',
|
||||
configureSmtpFirst: '最初にSMTP設定を構成してテストしてください',
|
||||
},
|
||||
// Success messages
|
||||
success: {
|
||||
settingsSaved: 'SMTP設定を保存しました',
|
||||
},
|
||||
// Security options
|
||||
securityOptions: {
|
||||
starttls: 'STARTTLS (ポート 587)',
|
||||
ssl: 'SSL/TLS (ポート 465)',
|
||||
none: 'なし (ポート 25)',
|
||||
},
|
||||
// Authentication options
|
||||
authOptions: {
|
||||
enabled: '有効',
|
||||
disabled: '無効',
|
||||
},
|
||||
},
|
||||
|
||||
// General - Date/Time
|
||||
@@ -1801,6 +1825,20 @@ export default {
|
||||
ams_humidity_high: 'AMS湿度高',
|
||||
ams_temperature_high: 'AMS温度高',
|
||||
test: 'テスト',
|
||||
printStarted: '印刷開始',
|
||||
printComplete: '印刷完了',
|
||||
printFailed: '印刷失敗',
|
||||
printStopped: '印刷停止',
|
||||
progress: '進捗',
|
||||
printerOffline: 'プリンターオフライン',
|
||||
printerError: 'プリンターエラー',
|
||||
lowFilament: 'フィラメント残量少',
|
||||
maintenanceDue: 'メンテナンス期限',
|
||||
},
|
||||
timeAgo: {
|
||||
justNow: 'たった今',
|
||||
minutesAgo: '{{minutes}}分前',
|
||||
hoursAgo: '{{hours}}時間前',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -2078,6 +2116,7 @@ export default {
|
||||
selectAModel: 'モデルを選択...',
|
||||
locationFilterLabel: 'ロケーションフィルター(任意)',
|
||||
anyLocation: 'すべてのロケーション',
|
||||
openCalendar: 'カレンダーを開く',
|
||||
},
|
||||
|
||||
// ログインページ
|
||||
@@ -2514,6 +2553,19 @@ export default {
|
||||
discardedCount: '{{count}}ファイルを破棄しました',
|
||||
archiveAllFailed: 'すべてのアーカイブに失敗しました',
|
||||
discardAllFailed: 'すべての破棄に失敗しました',
|
||||
placeholders: {
|
||||
tags: '例: 機能的、プロトタイプ、ギフト',
|
||||
notes: 'この印刷についてのメモを追加...',
|
||||
},
|
||||
discardUpload: 'アップロードを破棄',
|
||||
archiveAllUploads: 'すべてのアップロードをアーカイブ',
|
||||
discardAllUploads: 'すべてのアップロードを破棄',
|
||||
timeAgo: {
|
||||
justNow: 'たった今',
|
||||
minutesAgo: '{{minutes}}分前',
|
||||
hoursAgo: '{{hours}}時間前',
|
||||
daysAgo: '{{days}}日前',
|
||||
},
|
||||
},
|
||||
|
||||
// キーボードショートカット
|
||||
@@ -2558,6 +2610,7 @@ export default {
|
||||
emptyLog: 'ログファイルが空またはクリアされています',
|
||||
autoRefreshing: '2秒ごとに自動更新中',
|
||||
clickStart: '開始をクリックしてライブログストリーミングを有効にする',
|
||||
noLogEntries: 'ログエントリが見つかりません',
|
||||
},
|
||||
|
||||
// アーカイブ編集モーダル
|
||||
@@ -3097,6 +3150,10 @@ export default {
|
||||
collapseAll: 'すべて折りたたむ',
|
||||
swaggerUI: 'Swagger UI',
|
||||
endpointCount: '{{categories}}カテゴリー内{{count}}エンドポイント',
|
||||
placeholders: {
|
||||
requestBody: 'JSONリクエストボディ...',
|
||||
searchEndpoints: 'エンドポイントを検索...',
|
||||
},
|
||||
},
|
||||
githubBackup: {
|
||||
title: 'GitHubバックアップ',
|
||||
@@ -3190,4 +3247,285 @@ export default {
|
||||
unsupportedFormat: 'サポートされていないファイル形式です',
|
||||
},
|
||||
},
|
||||
|
||||
// Maintenance type descriptions (built-in)
|
||||
maintenanceDescriptions: {
|
||||
lubricateRails: 'リニアレールに潤滑剤を塗布してスムーズな動きを実現',
|
||||
cleanNozzle: 'ホットエンドとノズルを清掃して詰まりを防止',
|
||||
checkBelts: 'ベルトの張力を確認して正確な印刷を実現',
|
||||
cleanBuildPlate: 'ビルドプレートを清掃して接着力を向上',
|
||||
checkExtruder: 'エクストルーダーギアの摩耗を検査',
|
||||
checkCooling: '冷却ファンが正常に動作していることを確認',
|
||||
generalInspection: 'プリンターの一般的な点検',
|
||||
cleanCarbonRods: 'カーボンロッドを清掃して摩擦を軽減',
|
||||
checkPtfeTube: 'PTFEチューブの摩耗や損傷を検査',
|
||||
replaceHepaFilter: 'HEPAフィルターを交換して空気品質を向上',
|
||||
replaceCarbonFilter: '活性炭フィルターを交換',
|
||||
lubricateLeftNozzleRail: '左ノズルレールに潤滑剤を塗布(H2シリーズ)',
|
||||
},
|
||||
|
||||
// Smart Plugs
|
||||
smartPlugs: {
|
||||
offline: 'オフライン',
|
||||
admin: '管理',
|
||||
openPlugAdminPage: 'プラグ管理ページを開く',
|
||||
deleteSmartPlug: 'スマートプラグを削除',
|
||||
turnOnSmartPlug: 'スマートプラグをオンにする',
|
||||
turnOffSmartPlug: 'スマートプラグをオフにする',
|
||||
turnOn: 'オンにする',
|
||||
turnOff: 'オフにする',
|
||||
addSmartPlug: {
|
||||
scanningNetwork: 'ネットワークをスキャン中...',
|
||||
chooseEntity: 'エンティティを選択...',
|
||||
connectionFailed: '接続失敗',
|
||||
searchEntities: 'エンティティを検索...',
|
||||
searchPowerSensors: '電力センサーを検索...',
|
||||
searchEnergySensors: 'エネルギーセンサーを検索...',
|
||||
placeholders: {
|
||||
plugName: 'リビングルームプラグ',
|
||||
mqttStateOnValue: 'ON, true, 1',
|
||||
mqttSameAsPower: '電力トピックと同じ、または異なる',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// External Links
|
||||
externalLinks: {
|
||||
noLinksConfigured: '外部リンクが設定されていません',
|
||||
deleteLink: 'リンクを削除',
|
||||
removeCustomIcon: 'カスタムアイコンを削除',
|
||||
placeholders: {
|
||||
linkName: 'マイリンク',
|
||||
},
|
||||
},
|
||||
|
||||
// Keyboard Shortcuts Modal
|
||||
keyboardShortcuts: {
|
||||
title: 'キーボードショートカット',
|
||||
navigation: 'ナビゲーション',
|
||||
archivesSection: 'アーカイブ',
|
||||
kProfilesSection: 'Kプロファイル',
|
||||
generalSection: '全般',
|
||||
shortcuts: {
|
||||
goToPrinters: 'プリンターへ移動',
|
||||
goToArchives: 'アーカイブへ移動',
|
||||
goToQueue: 'キューへ移動',
|
||||
goToStats: '統計へ移動',
|
||||
goToProfiles: 'クラウドプロファイルへ移動',
|
||||
goToSettings: '設定へ移動',
|
||||
focusSearch: '検索にフォーカス',
|
||||
openUploadModal: 'アップロードモーダルを開く',
|
||||
clearSelection: '選択をクリア / 入力をぼかす',
|
||||
contextMenu: 'カードのコンテキストメニュー',
|
||||
refreshProfiles: 'プロファイルを更新',
|
||||
newProfile: '新しいプロファイル',
|
||||
exitSelectionMode: '選択モードを終了',
|
||||
showHelp: 'このヘルプを表示',
|
||||
},
|
||||
footer: 'Escキーを押すか外側をクリックして閉じます',
|
||||
},
|
||||
|
||||
// Keyboard Shortcuts Modal
|
||||
restoreBackup: {
|
||||
title: 'バックアップを復元',
|
||||
restoring: '復元中...',
|
||||
restoreComplete: '復元完了',
|
||||
restoreFailed: '復元失敗',
|
||||
importSettings: 'バックアップファイルから設定をインポート',
|
||||
pleaseWait: 'データの復元中です。しばらくお待ちください',
|
||||
clickToSelect: 'クリックしてバックアップファイルを選択(.jsonまたは.zip)',
|
||||
howDuplicateHandling: '重複の処理方法:',
|
||||
categories: {
|
||||
printers: 'プリンター',
|
||||
smartPlugs: 'スマートプラグ',
|
||||
notificationProviders: '通知プロバイダー',
|
||||
filaments: 'フィラメント',
|
||||
archives: 'アーカイブ',
|
||||
pendingUploads: '保留中のアップロード',
|
||||
settingsTemplates: '設定とテンプレート',
|
||||
},
|
||||
matchingInfo: {
|
||||
printers: 'シリアル番号で照合',
|
||||
smartPlugs: 'IPアドレスで照合',
|
||||
notificationProviders: '名前で照合',
|
||||
filaments: '名前+タイプ+ブランドで照合',
|
||||
archives: 'コンテンツハッシュで照合',
|
||||
pendingUploads: 'ファイル名で照合',
|
||||
settingsTemplates: '常に上書き',
|
||||
},
|
||||
replaceExisting: '既存データを置き換え',
|
||||
keepExisting: '既存データを保持',
|
||||
replaceDescription: '既に存在するアイテムをバックアップデータで上書き',
|
||||
keepDescription: 'まだ存在しないアイテムのみを復元',
|
||||
caution: '注意:',
|
||||
cautionText: '上書きすると現在の構成がバックアップデータに置き換えられます。セキュリティ上の理由から、プリンターのアクセスコードは上書きされません。',
|
||||
itemsRestored: '復元されたアイテム',
|
||||
itemsSkipped: 'スキップされたアイテム',
|
||||
restored: '復元済み',
|
||||
skipped: 'スキップ(既に存在)',
|
||||
filesLabel: 'ファイル(3MF、サムネイルなど)',
|
||||
newApiKeysGenerated: '新しいAPIキーが生成されました',
|
||||
newApiKeysWarning: 'これらのキーは一度だけ表示されます。今すぐコピーしてください!',
|
||||
processingBackup: 'バックアップファイルを処理中...',
|
||||
noDataFound: 'バックアップファイルに復元するデータが見つかりませんでした。',
|
||||
failedToRestore: 'バックアップの復元に失敗しました。ファイル形式を確認してください。',
|
||||
},
|
||||
|
||||
// Backup Export Modal
|
||||
backupExport: {
|
||||
title: 'バックアップをエクスポート',
|
||||
selectData: '含めるデータを選択',
|
||||
selectAll: 'すべて選択',
|
||||
selectNone: 'なし',
|
||||
categoryDescriptions: {
|
||||
settings: '言語、テーマ、更新設定',
|
||||
notifications: 'ntfy、Pushover、Discordなど',
|
||||
templates: 'カスタムメッセージテンプレート',
|
||||
smartPlugs: 'Tasmotaプラグ設定',
|
||||
externalLinks: 'サイドバーの外部サービスへのリンク',
|
||||
printers: 'プリンター情報(アクセスコード除外)',
|
||||
plateDetection: '空プレート参照画像',
|
||||
filaments: 'フィラメントの種類とコスト',
|
||||
maintenance: 'カスタムメンテナンススケジュール',
|
||||
archives: 'すべての印刷データ+ファイル(3MF、サムネイル、写真)',
|
||||
projects: 'プロジェクト、BOMアイテム、添付ファイル',
|
||||
pendingUploads: '仮想プリンターアップロード待機中',
|
||||
apiKeys: 'Webhook APIキー(インポート時に新しいキーが生成されます)',
|
||||
},
|
||||
requiresPrinters: 'プリンターを選択する必要があります',
|
||||
zipFileWarning: 'ZIPファイルが作成されます。',
|
||||
zipFileDescription: 'すべての3MFファイル、サムネイル、タイムラプス、写真が含まれます。これには時間がかかり、大きなファイルになる可能性があります。',
|
||||
includeAccessCodes: 'アクセスコードを含める',
|
||||
includeAccessCodesDescription: '別のマシンへの転送用',
|
||||
includeAccessCodesWarning: 'アクセスコードはプレーンテキストで含まれます。このバックアップファイルを安全に保管してください!',
|
||||
categoriesSelected: '{{selectedCount}}カテゴリー選択済み',
|
||||
},
|
||||
|
||||
// Configure AMS Slot Modal
|
||||
configureAmsSlot: {
|
||||
searchPresets: 'プリセットを検索...',
|
||||
colorPlaceholder: '色名またはHex(例: 茶色、FF8800)',
|
||||
clearCustomColor: 'カスタム色をクリア',
|
||||
noCloudPresets: 'クラウドプリセットがありません。Bambu Cloudにログインして同期してください。',
|
||||
noMatchingPresets: '一致するプリセットが見つかりません。',
|
||||
custom: 'カスタム',
|
||||
settingsSentToPrinter: '設定をプリンターに送信しました',
|
||||
filamentProfile: 'フィラメントプロファイル',
|
||||
},
|
||||
|
||||
// GitHub Backup Settings (additional keys)
|
||||
githubBackupSettings: {},
|
||||
|
||||
// Email Settings
|
||||
emailSettings: {
|
||||
placeholders: {
|
||||
fromName: 'BamBuddy',
|
||||
},
|
||||
},
|
||||
|
||||
// Tag Management Modal
|
||||
tagManagement: {
|
||||
searchTags: 'タグを検索...',
|
||||
renameTag: 'タグ名を変更',
|
||||
deleteTag: 'タグを削除',
|
||||
},
|
||||
|
||||
// Notification Template Editor
|
||||
notificationTemplates: {
|
||||
placeholders: {
|
||||
title: '通知タイトル...',
|
||||
body: '通知本文...',
|
||||
},
|
||||
},
|
||||
|
||||
// Batch Tag Modal
|
||||
batchTag: {
|
||||
placeholders: {
|
||||
newTag: '新しいタグを入力...',
|
||||
},
|
||||
},
|
||||
|
||||
// Photo Gallery Modal
|
||||
photoGallery: {
|
||||
deletePhoto: '写真を削除',
|
||||
},
|
||||
|
||||
// Filament Hover Card
|
||||
filamentHoverCard: {
|
||||
copySpoolUuid: 'スプールUUIDをコピー',
|
||||
},
|
||||
|
||||
// K Profiles View
|
||||
kProfilesView: {
|
||||
hasNote: 'メモあり',
|
||||
copyProfile: 'プロファイルをコピー',
|
||||
},
|
||||
|
||||
// Layout/Navigation
|
||||
layout: {
|
||||
openMenu: 'メニューを開く',
|
||||
noPermissionSystemInfo: 'システム情報を表示する権限がありません',
|
||||
},
|
||||
|
||||
// Notification Provider Card
|
||||
notificationProviderCard: {
|
||||
deleteNotificationProvider: '通知プロバイダーを削除',
|
||||
},
|
||||
|
||||
// File Manager Modal
|
||||
fileManagerModal: {
|
||||
closeFileManager: 'ファイルマネージャーを閉じる',
|
||||
sortFiles: 'ファイルを並べ替え',
|
||||
goToParentFolder: '親フォルダーへ移動',
|
||||
threeView: '3Dビュー',
|
||||
},
|
||||
|
||||
// Embedded Camera Viewer
|
||||
embeddedCameraViewer: {
|
||||
refreshStream: 'ストリームを更新',
|
||||
close: '閉じる',
|
||||
zoomOut: 'ズームアウト',
|
||||
resetZoom: 'ズームをリセット',
|
||||
zoomIn: 'ズームイン',
|
||||
dragToResize: 'ドラッグしてサイズ変更',
|
||||
},
|
||||
|
||||
// Timelapse Viewer
|
||||
timelapseViewer: {
|
||||
skipBack5s: '5秒戻る',
|
||||
skipForward5s: '5秒進む',
|
||||
},
|
||||
|
||||
// Notification Providers
|
||||
notificationProviders: {
|
||||
descriptions: {
|
||||
email: 'SMTP電子メール通知',
|
||||
telegram: 'Telegramボット経由の通知',
|
||||
discord: 'Webhookを介してDiscordチャンネルに送信',
|
||||
ntfy: '無料でセルフホスト可能なプッシュ通知',
|
||||
pushover: 'シンプルで信頼性の高いプッシュ通知',
|
||||
callmebot: 'CallMeBot経由の無料WhatsApp通知',
|
||||
webhook: '任意のURLへのジェネリックHTTP POST',
|
||||
},
|
||||
},
|
||||
|
||||
// Switchbar Popover
|
||||
switchbarPopover: {
|
||||
noSwitchesInSwitchbar: 'スイッチバーにスイッチがありません',
|
||||
},
|
||||
|
||||
// Project Page Modal
|
||||
projectPageModal: {
|
||||
placeholders: {
|
||||
title: 'タイトル',
|
||||
designer: 'デザイナー',
|
||||
license: 'ライセンス',
|
||||
description: '説明を入力...',
|
||||
profileTitle: 'プロファイルタイトル',
|
||||
profileDescription: 'プロファイルの説明...',
|
||||
},
|
||||
},
|
||||
|
||||
// Spoolman Settings
|
||||
spoolmanSettings: {},
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -23,7 +23,7 @@
|
||||
|
||||
<!-- Splash screens for iOS -->
|
||||
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
|
||||
<script type="module" crossorigin src="/assets/index-HOR_-s_H.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-QQNcmTSY.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-BwfbnBQ9.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user