6d6f5d571a
- Admin panel page at #Admin/dataMigration with two-column layout - Export: filter by case status, skip attachments option, progress + log - Import: select backup, preserve IDs / skip duplicates, dry run support - List/delete existing backups with full manifest details - 5 API endpoints (status, export, import, listBackups, deleteBackup) - BufferedIO adapter to capture CLI output for API responses - Admin-only access on all endpoints - i18n: English + Hebrew (fa_IR) translations Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
180 lines
8.0 KiB
Smarty
180 lines
8.0 KiB
Smarty
<div class="page-header">
|
|
<h3>
|
|
<a href="#Admin">{{translate 'Administration'}}</a>
|
|
<span class="breadcrumb-separator"><span class="chevron-right"></span></span>
|
|
{{translate 'Data Migration' scope='DataMigration'}}
|
|
</h3>
|
|
</div>
|
|
|
|
<div class="row">
|
|
{{! ========== LEFT COLUMN: Status + Export ========== }}
|
|
<div class="col-md-6">
|
|
|
|
{{! === Database Status === }}
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<div class="pull-right">
|
|
<button class="btn btn-default btn-xs" data-action="refreshStatus" title="{{translate 'Refresh'}}">
|
|
<i class="fas fa-sync-alt"></i>
|
|
</button>
|
|
</div>
|
|
<h4 class="panel-title">
|
|
<i class="fas fa-database"></i>
|
|
{{translate 'Database Status' scope='DataMigration'}}
|
|
</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="status-spinner" style="text-align: center; padding: 20px;">
|
|
<i class="fas fa-spinner fa-spin fa-2x text-muted"></i>
|
|
</div>
|
|
<div class="status-content" style="display: none;"></div>
|
|
</div>
|
|
</div>
|
|
|
|
{{! === Export === }}
|
|
<div class="panel panel-primary">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">
|
|
<i class="fas fa-upload"></i>
|
|
{{translate 'Export / Backup' scope='DataMigration'}}
|
|
</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<p class="text-muted" style="margin-bottom: 15px;">
|
|
{{translate 'exportDescription' category='messages' scope='DataMigration'}}
|
|
</p>
|
|
|
|
{{! Status filter }}
|
|
<div class="form-group">
|
|
<label class="control-label">
|
|
{{translate 'Filter by Case Status' scope='DataMigration'}}
|
|
<span class="text-muted" style="font-weight: normal;"> ({{translate 'optional' scope='DataMigration'}})</span>
|
|
</label>
|
|
<div class="export-status-checkboxes" style="columns: 2;">
|
|
{{#each caseStatuses}}
|
|
<div class="checkbox" style="margin-top: 2px; margin-bottom: 2px;">
|
|
<label>
|
|
<input type="checkbox" value="{{this}}"> {{this}}
|
|
</label>
|
|
</div>
|
|
{{/each}}
|
|
</div>
|
|
</div>
|
|
|
|
{{! No files option }}
|
|
<div class="form-group">
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" name="noFiles">
|
|
{{translate 'Skip attachment files' scope='DataMigration'}}
|
|
<span class="text-muted"> — {{translate 'noFilesHint' category='messages' scope='DataMigration'}}</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<button class="btn btn-primary" data-action="export">
|
|
<i class="fas fa-download"></i>
|
|
{{translate 'Start Export' scope='DataMigration'}}
|
|
</button>
|
|
</div>
|
|
|
|
<div class="export-progress" style="display: none; margin-top: 15px;">
|
|
<div class="progress">
|
|
<div class="progress-bar progress-bar-striped active" style="width: 100%;">
|
|
{{translate 'Exporting...' scope='DataMigration'}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="export-log-container" style="display: none;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{! ========== RIGHT COLUMN: Backups + Import ========== }}
|
|
<div class="col-md-6">
|
|
|
|
{{! === Backup List === }}
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<div class="pull-right">
|
|
<button class="btn btn-default btn-xs" data-action="refreshBackups" title="{{translate 'Refresh'}}">
|
|
<i class="fas fa-sync-alt"></i>
|
|
</button>
|
|
</div>
|
|
<h4 class="panel-title">
|
|
<i class="fas fa-archive"></i>
|
|
{{translate 'Available Backups' scope='DataMigration'}}
|
|
</h4>
|
|
</div>
|
|
<div class="panel-body" style="padding: 0;">
|
|
<div class="backups-spinner" style="text-align: center; padding: 20px;">
|
|
<i class="fas fa-spinner fa-spin fa-2x text-muted"></i>
|
|
</div>
|
|
<div class="backups-list list-group" style="margin-bottom: 0;"></div>
|
|
</div>
|
|
</div>
|
|
|
|
{{! === Import === }}
|
|
<div class="import-section" style="display: none;">
|
|
<div class="panel panel-warning">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">
|
|
<i class="fas fa-download"></i>
|
|
{{translate 'Import / Restore' scope='DataMigration'}}
|
|
</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="alert alert-info" style="margin-bottom: 15px;">
|
|
<i class="fas fa-info-circle"></i>
|
|
{{translate 'Selected backup' scope='DataMigration'}}: <strong class="selected-backup-name"></strong>
|
|
</div>
|
|
|
|
{{! Import options }}
|
|
<div class="form-group">
|
|
<label class="control-label">{{translate 'Import Options' scope='DataMigration'}}</label>
|
|
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" name="preserveIds" checked>
|
|
{{translate 'Preserve original IDs' scope='DataMigration'}}
|
|
<span class="text-muted"> — {{translate 'preserveIdsHint' category='messages' scope='DataMigration'}}</span>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" name="skipDuplicates" checked>
|
|
{{translate 'Skip duplicates' scope='DataMigration'}}
|
|
<span class="text-muted"> — {{translate 'skipDuplicatesHint' category='messages' scope='DataMigration'}}</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="btn-group">
|
|
<button class="btn btn-warning" data-action="dryRunImport">
|
|
<i class="fas fa-vial"></i>
|
|
{{translate 'Dry Run' scope='DataMigration'}}
|
|
</button>
|
|
<button class="btn btn-danger" data-action="import">
|
|
<i class="fas fa-play"></i>
|
|
{{translate 'Import Now' scope='DataMigration'}}
|
|
</button>
|
|
</div>
|
|
|
|
<div class="import-progress" style="display: none; margin-top: 15px;">
|
|
<div class="progress">
|
|
<div class="progress-bar progress-bar-warning progress-bar-striped active" style="width: 100%;">
|
|
{{translate 'Importing...' scope='DataMigration'}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="import-log-container" style="display: none;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|