99 lines
7.5 KiB
PHP
99 lines
7.5 KiB
PHP
<?php require __DIR__ . '/settings_nav.php'; ?>
|
|
<?php if ($error): ?><div class="alert alert-danger"><?= h($error) ?></div><?php endif; ?>
|
|
<?php if ($success === 'analyzed'): ?><div class="alert alert-success"><?= h(t('asm3.analyzed_success')) ?></div>
|
|
<?php elseif ($success === 'imported'): ?><div class="alert alert-success"><?= h(t('asm3.imported_success')) ?></div>
|
|
<?php endif; ?>
|
|
<div class="card mb-4">
|
|
<div class="card-status-top bg-blue"></div>
|
|
<div class="card-header">
|
|
<div>
|
|
<h3 class="card-title"><?= h(t('asm3.new')) ?></h3>
|
|
<div class="text-muted small"><?= h(t('asm3.new_help')) ?></div>
|
|
</div>
|
|
</div>
|
|
<form method="post" action="/settings/asm3/upload" enctype="multipart/form-data"><input type="hidden" name="csrf"
|
|
value="<?= h(Auth::csrf()) ?>">
|
|
<div class="card-body row g-3 align-items-end">
|
|
<div class="col-md"><label class="form-label"><?= h(t('asm3.dump')) ?></label><input class="form-control"
|
|
type="file" name="dump" accept=".sql,.pgsql,text/plain,application/sql" required>
|
|
<div class="form-hint">
|
|
<?= h(t('asm3.upload_help', ['limit' => (string)ini_get('upload_max_filesize')])) ?></div>
|
|
<?php if ((int)ini_get('upload_max_filesize') < 250): ?><div
|
|
class="alert alert-warning py-2 mt-2 mb-0 small"> <?= h(t('asm3.php_limit')) ?><br><code>php -d
|
|
upload_max_filesize=250M -d post_max_size=260M -d max_execution_time=600 -S 127.0.0.1:8000 -t
|
|
public</code></div><?php endif; ?>
|
|
</div>
|
|
<div class="col-md-auto"><button class="btn btn-primary"><?= h(t('asm3.analyze')) ?></button></div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="vstack gap-3"><?php foreach ($jobs as $job):$r = json_decode($job['analysis_json'], true) ?: [];
|
|
$result = json_decode((string)$job['result_json'], true) ?: []; ?><div class="card">
|
|
<div class="card-header">
|
|
<div class="me-auto">
|
|
<h3 class="card-title"><?= h($job['original_name']) ?></h3>
|
|
<div class="text-muted small">
|
|
<?= h(t('asm3.analyzed_at', ['date' => date('d/m/Y H:i', strtotime($job['created_at']))])) ?><?= $job['actor'] ? ' ' . h(t('asm3.by', ['name' => $job['actor']])) : '' ?>
|
|
</div>
|
|
</div><span
|
|
class="badge <?= $job['status'] === 'completed' ? 'bg-green-lt' : ($job['status'] === 'failed' ? 'bg-red-lt' : 'bg-blue-lt') ?>"><?= h(['analyzed' => t('asm3.status.analyzed'),'completed' => t('asm3.status.completed'),'failed' => t('asm3.status.failed')][$job['status']] ?? $job['status']) ?></span>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row g-2 mb-3">
|
|
<?php foreach ([[t('asm3.animals'),$r['animals']['create'] ?? 0,$r['animals']['review'] ?? 0],[t('asm3.contacts'),$r['contacts']['create'] ?? 0,$r['contacts']['review'] ?? 0],[t('asm3.movements'),$r['movements']['events'] ?? 0,$r['movements']['unsupported_movements'] ?? 0],[t('asm3.vaccinations'),$r['clinical']['vaccinations'] ?? 0,0],[t('asm3.medical_notes'),$r['clinical']['medical_notes'] ?? 0,0],[t('asm3.weights'),$r['clinical']['weights'] ?? 0,0],[t('asm3.litters'),$r['litters']['litters'] ?? 0,$r['litters']['unresolved'] ?? 0]] as [$label,$count,$warning]):?>
|
|
<div class="col-6 col-md-3">
|
|
<div class="border rounded p-2 h-100">
|
|
<div class="text-muted small"><?= h($label) ?></div>
|
|
<div class="h2 mb-0"><?= (int)$count ?></div><?php if ($warning):?><span
|
|
class="text-orange small"><?= h(t('asm3.to_review', ['count' => (int)$warning])) ?></span><?php endif;?>
|
|
</div>
|
|
</div><?php endforeach;?></div>
|
|
<div class="alert alert-info py-2 small">
|
|
<?= h(t('asm3.media', ['count' => (int)($r['media']['metadata'] ?? 0)])) ?></div>
|
|
<?php if ($job['status'] === 'analyzed'): ?><form method="post" action="/settings/asm3/apply"
|
|
class="border-top pt-3" id="asm3Form<?= (int)$job['id'] ?>"><input type="hidden" name="csrf"
|
|
value="<?= h(Auth::csrf()) ?>"><input type="hidden" name="id" value="<?= (int)$job['id'] ?>">
|
|
<div class="row g-3">
|
|
<div class="col-md-6"><label class="form-label"><?= h(t('asm3.mode')) ?></label><label
|
|
class="form-selectgroup-item d-block mb-2"><input type="radio" name="mode" value="merge"
|
|
class="form-selectgroup-input" checked><span
|
|
class="form-selectgroup-label"><strong><?= h(t('asm3.merge')) ?></strong><br><span
|
|
class="text-muted small"><?= h(t('asm3.merge_help')) ?></span></span></label><label
|
|
class="form-selectgroup-item d-block"><input type="radio" name="mode" value="replace"
|
|
class="form-selectgroup-input"><span
|
|
class="form-selectgroup-label border-danger"><strong
|
|
class="text-danger"><?= h(t('asm3.replace')) ?></strong><br><span
|
|
class="text-muted small"><?= h(t('asm3.replace_help')) ?></span></span></label>
|
|
</div>
|
|
<div class="col-md-6"><label class="form-label"><?= h(t('asm3.confirmation')) ?></label><input
|
|
class="form-control" name="confirmation" placeholder="<?= h(t('asm3.type_import')) ?>"
|
|
autocomplete="off" required>
|
|
<div class="form-hint confirmation-hint"><?= h(t('asm3.expected')) ?>
|
|
<strong><?= h(t('asm3.confirm_import_phrase')) ?></strong></div>
|
|
<div class="alert alert-warning py-2 mt-3 small"><?= h(t('asm3.transaction_help')) ?></div>
|
|
<button class="btn btn-danger w-100"><?= h(t('asm3.backup_import')) ?></button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<script>
|
|
document.querySelectorAll('#asm3Form<?= (int)$job['
|
|
id '] ?> input[name="mode"]').forEach(el => el.addEventListener('change', () => {
|
|
const replace = el.form.mode.value === 'replace';
|
|
el.form.confirmation.placeholder = replace ? < ? = json_encode(t('asm3.type_replace'),
|
|
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ? > : < ? = json_encode(t(
|
|
'asm3.type_import'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ? > ;
|
|
el.form.querySelector('.confirmation-hint strong').textContent = replace ? < ? =
|
|
json_encode(t('asm3.confirm_replace_phrase'), JSON_UNESCAPED_UNICODE |
|
|
JSON_UNESCAPED_SLASHES) ? > : < ? = json_encode(t('asm3.confirm_import_phrase'),
|
|
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ? > ;
|
|
}));
|
|
|
|
</script><?php elseif ($result):?><details>
|
|
<summary><?= h(t('asm3.technical_report')) ?></summary>
|
|
<pre
|
|
class="mt-2 p-2 bg-muted-lt rounded small"><?= h(json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)) ?></pre>
|
|
</details><?php endif;?>
|
|
</div>
|
|
</div><?php endforeach;?><?php if (!$jobs):?><div class="card">
|
|
<div class="card-body text-muted"><?= h(t('asm3.none')) ?></div>
|
|
</div><?php endif;?></div>
|