feat: Data management
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
<div class="space-y-6">
|
||||
<section class="rounded-lg border border-border bg-card/60 p-5">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
|
||||
<div>
|
||||
<div class="flex items-center gap-2 text-primary">
|
||||
<ng-icon
|
||||
name="lucideDatabase"
|
||||
class="h-5 w-5"
|
||||
/>
|
||||
<h4 class="text-base font-semibold text-foreground">Local data</h4>
|
||||
</div>
|
||||
<p class="mt-2 text-sm text-muted-foreground">
|
||||
Manage the folder that contains local messages, rooms, attachments, avatars, saved themes, and desktop storage.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@if (restartRequired()) {
|
||||
<button
|
||||
type="button"
|
||||
(click)="restartApp()"
|
||||
[disabled]="busyAction() !== null"
|
||||
class="inline-flex items-center gap-2 rounded-lg bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideRefreshCw"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
Restart app
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@if (!isElectron) {
|
||||
<section class="rounded-lg border border-border bg-secondary/30 p-5">
|
||||
<p class="text-sm text-muted-foreground">Data management is only available in the packaged Electron desktop app.</p>
|
||||
</section>
|
||||
} @else {
|
||||
<section class="space-y-4 rounded-lg border border-border bg-card/60 p-5">
|
||||
<div>
|
||||
<h5 class="text-sm font-semibold text-foreground">Current data folder</h5>
|
||||
<p class="mt-2 break-all rounded-lg border border-border bg-secondary/20 px-3 py-2 text-sm text-muted-foreground">
|
||||
{{ dataPath() || 'Resolving data folder...' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
(click)="openDataFolder()"
|
||||
[disabled]="busyAction() !== null"
|
||||
class="inline-flex items-center gap-2 rounded-lg border border-border bg-secondary px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-secondary/80 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideFolderOpen"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
{{ busyAction() === 'open' ? 'Opening...' : 'Open folder' }}
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<section class="grid gap-4 md:grid-cols-2">
|
||||
<div class="space-y-4 rounded-lg border border-border bg-card/60 p-5">
|
||||
<div>
|
||||
<h5 class="text-sm font-semibold text-foreground">Export data</h5>
|
||||
<p class="mt-1 text-sm text-muted-foreground">Create a portable .dat archive that can be imported on another client.</p>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
(click)="exportData()"
|
||||
[disabled]="busyAction() !== null"
|
||||
class="inline-flex items-center gap-2 rounded-lg bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideDownload"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
{{ busyAction() === 'export' ? 'Exporting...' : 'Export data' }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="space-y-4 rounded-lg border border-border bg-card/60 p-5">
|
||||
<div>
|
||||
<h5 class="text-sm font-semibold text-foreground">Import all data</h5>
|
||||
<p class="mt-1 text-sm text-muted-foreground">Restore a .dat archive. Existing local data is moved to a backup folder first.</p>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
(click)="importData()"
|
||||
[disabled]="busyAction() !== null"
|
||||
class="inline-flex items-center gap-2 rounded-lg border border-border bg-secondary px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-secondary/80 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideUpload"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
{{ busyAction() === 'import' ? 'Importing...' : 'Import data' }}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="space-y-4 rounded-lg border border-destructive/30 bg-destructive/10 p-5">
|
||||
<div>
|
||||
<h5 class="text-sm font-semibold text-foreground">Erase user data</h5>
|
||||
<p class="mt-1 text-sm text-muted-foreground">Remove local app data from this device and recreate an empty database.</p>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
(click)="eraseData()"
|
||||
[disabled]="busyAction() !== null"
|
||||
class="inline-flex items-center gap-2 rounded-lg border border-destructive/30 bg-destructive px-4 py-2 text-sm font-medium text-destructive-foreground transition-colors hover:bg-destructive/90 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideTrash2"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
{{ busyAction() === 'erase' ? 'Erasing...' : 'Erase user data' }}
|
||||
</button>
|
||||
</section>
|
||||
|
||||
@if (statusMessage()) {
|
||||
<section class="rounded-lg border border-primary/30 bg-primary/10 p-4">
|
||||
<p class="break-words text-sm text-foreground">{{ statusMessage() }}</p>
|
||||
</section>
|
||||
}
|
||||
|
||||
@if (errorMessage()) {
|
||||
<section class="rounded-lg border border-destructive/30 bg-destructive/10 p-4">
|
||||
<p class="break-words text-sm text-foreground">{{ errorMessage() }}</p>
|
||||
</section>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
Reference in New Issue
Block a user