This repository has been archived on 2026-07-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
DataMigration/files/client/custom/modules/data-migration/res/templates/admin/data-migration.tpl
T
chaim 6d6f5d571a feat: add admin UI for export/import data migration
- 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>
2026-03-29 19:45:20 +00:00

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>