tubearchivist/frontend/src/pages/SettingsActions.tsx

228 lines
7.7 KiB
TypeScript

import { useEffect, useState } from 'react';
import loadBackupList, { BackupListType } from '../api/loader/loadBackupList';
import SettingsNavigation from '../components/SettingsNavigation';
import updateTaskByName from '../api/actions/updateTaskByName';
import queueBackup from '../api/actions/queueBackup';
import restoreBackup from '../api/actions/restoreBackup';
import Notifications from '../components/Notifications';
import Button from '../components/Button';
import { ApiResponseType } from '../functions/APIClient';
const SettingsActions = () => {
const [deleteIgnored, setDeleteIgnored] = useState(false);
const [deletePending, setDeletePending] = useState(false);
const [processingImports, setProcessingImports] = useState(false);
const [reEmbed, setReEmbed] = useState(false);
const [reSyncMeta, setReSyncMeta] = useState(false);
const [backupStarted, setBackupStarted] = useState(false);
const [isRestoringBackup, setIsRestoringBackup] = useState(false);
const [reScanningFileSystem, setReScanningFileSystem] = useState(false);
const [backupListResponse, setBackupListResponse] = useState<ApiResponseType<BackupListType>>();
const { data: backupListResponseData } = backupListResponse ?? {};
const backups = backupListResponseData;
const hasBackups = !!backups && backups?.length > 0;
useEffect(() => {
(async () => {
const backupListResponse = await loadBackupList();
setBackupListResponse(backupListResponse);
})();
}, []);
return (
<>
<title>TA | Actions</title>
<div className="boxed-content">
<SettingsNavigation />
<Notifications
pageName={'all'}
update={
deleteIgnored ||
deletePending ||
processingImports ||
reEmbed ||
reSyncMeta ||
backupStarted ||
isRestoringBackup ||
reScanningFileSystem
}
setShouldRefresh={() => {
setDeleteIgnored(false);
setDeletePending(false);
setProcessingImports(false);
setReEmbed(false);
setReSyncMeta(false);
setBackupStarted(false);
setIsRestoringBackup(false);
setReScanningFileSystem(false);
}}
/>
<div className="title-bar">
<h1>Actions</h1>
</div>
<div className="settings-group">
<h2>Manual media files import.</h2>
<p>
Add files to the <span className="settings-current">cache/import</span> folder. Make
sure to follow the instructions in the Github{' '}
<a
href="https://docs.tubearchivist.com/settings/actions/#manual-media-files-import"
target="_blank"
>
Wiki
</a>
.
</p>
<div id="manual-import">
{processingImports && <p>Processing import</p>}
{!processingImports && (
<Button
label="Start import"
onClick={async () => {
await updateTaskByName('manual_import');
setProcessingImports(true);
}}
/>
)}
</div>
</div>
<div className="settings-group">
<h2>Embed thumbnails into media file.</h2>
<p>Set extracted youtube thumbnail as cover art of the media file.</p>
<div id="re-embed">
{reEmbed && <p>Processing thumbnails</p>}
{!reEmbed && (
<Button
label="Start process"
onClick={async () => {
await updateTaskByName('resync_thumbs');
setReEmbed(true);
}}
/>
)}
</div>
</div>
<div className="settings-group">
<h2>Embed metadata into media file</h2>
<p>Embed metadata into media files as mp4 tags.</p>
<div id="re-meta">
{reSyncMeta && <p>Processing video metadata</p>}
{!reSyncMeta && (
<Button
label="Start process"
onClick={async () => {
await updateTaskByName('resync_metadata');
setReSyncMeta(true);
}}
/>
)}
</div>
</div>
<div className="settings-group">
<h2>ZIP file index backup</h2>
<p>
Export your database to a zip file stored at{' '}
<span className="settings-current">cache/backup</span>.
</p>
<p>
<i>
Zip file backups are very slow for large archives and consistency is not guaranteed,
use snapshots instead. Make sure no other tasks are running when creating a Zip file
backup.
</i>
</p>
<div id="db-backup">
{backupStarted && <p>Backing up archive</p>}
{!backupStarted && (
<Button
label="Start backup"
onClick={async () => {
await queueBackup();
setBackupStarted(true);
}}
/>
)}
</div>
</div>
<div className="settings-group">
<h2>Restore from backup</h2>
<p>
<span className="danger-zone">Danger Zone</span>: This will replace your existing index
with the backup.
</p>
<p>
Restore from available backup files from{' '}
<span className="settings-current">cache/backup</span>.
</p>
{!hasBackups && <p>No backups found.</p>}
{hasBackups && (
<>
<div className="backup-grid-row">
<span></span>
<span>Timestamp</span>
<span>Source</span>
<span>Filename</span>
</div>
{isRestoringBackup && <p>Restoring from backup</p>}
{!isRestoringBackup &&
backups.map(backup => {
return (
<div key={backup.filename} id={backup.filename} className="backup-grid-row">
<Button
label="Restore"
onClick={async () => {
await restoreBackup(backup.filename);
setIsRestoringBackup(true);
}}
/>
<span>{backup.timestamp}</span>
<span>{backup.reason}</span>
<span>{backup.filename}</span>
</div>
);
})}
</>
)}
</div>
<div className="settings-group">
<h2>Rescan filesystem</h2>
<p>
<span className="danger-zone">Danger Zone</span>: This will delete the metadata of
deleted videos from the filesystem.
</p>
<p>
Rescan your media folder looking for missing videos and clean up index. More info on the
Github{' '}
<a
href="https://docs.tubearchivist.com/settings/actions/#rescan-filesystem"
target="_blank"
>
Wiki
</a>
.
</p>
<div id="fs-rescan">
{reScanningFileSystem && <p>File system scan in progress</p>}
{!reScanningFileSystem && (
<Button
label="Rescan filesystem"
onClick={async () => {
await updateTaskByName('rescan_filesystem');
setReScanningFileSystem(true);
}}
/>
)}
</div>
</div>
</div>
</>
);
};
export default SettingsActions;