mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 21:00:41 +00:00
feat: add backup recommendations and update backup strategy UI
- Introduced new backup recommendations feature with interfaces for recommended storage providers. - Updated i18n translations for backup strategy to reflect new terminology and improved descriptions. - Enhanced types with optional private and public keys in user profiles. - Redesigned backup-related styles for better layout and responsiveness. - Updated TypeScript configuration to include shared modules. - Configured Vite to resolve shared modules and allow filesystem access. - Added cron triggers for periodic tasks in Wrangler configuration.
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
import { Download, FileUp } from 'lucide-preact';
|
||||
import type { RecommendedProvider } from '@/lib/backup-recommendations';
|
||||
import { hasLinkedStorages } from '@/lib/backup-recommendations';
|
||||
import { t } from '@/lib/i18n';
|
||||
|
||||
interface BackupOperationsSidebarProps {
|
||||
disableWhileBusy: boolean;
|
||||
exporting: boolean;
|
||||
importing: boolean;
|
||||
selectedProviderId: string | null;
|
||||
recommendedWebDavProviders: RecommendedProvider[];
|
||||
recommendedS3Providers: RecommendedProvider[];
|
||||
onExport: () => void;
|
||||
onImport: () => void;
|
||||
onSelectProvider: (providerId: string) => void;
|
||||
}
|
||||
|
||||
export function BackupOperationsSidebar(props: BackupOperationsSidebarProps) {
|
||||
return (
|
||||
<aside className="backup-operations-sidebar">
|
||||
<div className="section-head">
|
||||
<h3>{t('txt_backup_manual')}</h3>
|
||||
</div>
|
||||
<div className="backup-actions-stack">
|
||||
<button type="button" className="btn btn-primary" disabled={props.disableWhileBusy} onClick={props.onExport}>
|
||||
<Download size={14} className="btn-icon" />
|
||||
{props.exporting ? t('txt_backup_exporting') : t('txt_backup_export')}
|
||||
</button>
|
||||
<button type="button" className="btn btn-secondary" disabled={props.disableWhileBusy} onClick={props.onImport}>
|
||||
<FileUp size={14} className="btn-icon" />
|
||||
{props.importing ? t('txt_backup_restoring') : t('txt_backup_import')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="backup-divider" />
|
||||
|
||||
<div className="section-head">
|
||||
<h3>{t('txt_backup_recommend_title')}</h3>
|
||||
</div>
|
||||
<div className="backup-recommendation-group">
|
||||
<h4 className="backup-recommendation-group-title">{t('txt_backup_recommend_group_webdav')}</h4>
|
||||
<div className="backup-recommendation-list">
|
||||
{props.recommendedWebDavProviders.map((provider) => (
|
||||
<button
|
||||
key={provider.id}
|
||||
type="button"
|
||||
className={`backup-destination-item ${props.selectedProviderId === provider.id ? 'active' : ''}`}
|
||||
onClick={() => props.onSelectProvider(provider.id)}
|
||||
>
|
||||
<span className="backup-recommendation-row">
|
||||
<span className="backup-destination-name">{provider.name}</span>
|
||||
<span className="backup-destination-meta">{provider.capacity}</span>
|
||||
</span>
|
||||
{hasLinkedStorages(provider) && provider.linkedStorages.length ? (
|
||||
<span className="backup-recommendation-linked">
|
||||
{provider.linkedStorages.map((storage) => (
|
||||
<span key={`${provider.id}-${storage.name}`} className="backup-recommendation-linked-item">
|
||||
<span>{storage.name}</span>
|
||||
<span>{storage.capacity}</span>
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
) : null}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="backup-recommendation-group">
|
||||
<h4 className="backup-recommendation-group-title">{t('txt_backup_recommend_group_s3')}</h4>
|
||||
{props.recommendedS3Providers.length ? (
|
||||
<div className="backup-recommendation-list">
|
||||
{props.recommendedS3Providers.map((provider) => (
|
||||
<button
|
||||
key={provider.id}
|
||||
type="button"
|
||||
className={`backup-destination-item ${props.selectedProviderId === provider.id ? 'active' : ''}`}
|
||||
onClick={() => props.onSelectProvider(provider.id)}
|
||||
>
|
||||
<span className="backup-recommendation-row">
|
||||
<span className="backup-destination-name">{provider.name}</span>
|
||||
<span className="backup-destination-meta">{provider.capacity}</span>
|
||||
</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="backup-browser-empty">{t('txt_backup_recommend_empty')}</div>
|
||||
)}
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user