|
|
@@ -80,13 +80,18 @@
|
|
|
{% set db_cfg = (job.config_json | fromjson) if job and job.config_json else {} %}
|
|
|
<div id="cfg-mysql" class="type-cfg hidden space-y-3">
|
|
|
<div>
|
|
|
- <label class="block text-sm font-medium text-gray-700 mb-1">Nom de la base de données</label>
|
|
|
- <input type="text" name="db_database"
|
|
|
- value="{{ db_cfg.get('database', '') if job and job.type == 'mysql' else '' }}"
|
|
|
- placeholder="ex: nextcloud"
|
|
|
- class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
|
+ <label class="block text-sm font-medium text-gray-700 mb-1">Base de données</label>
|
|
|
+ <select id="db-select-mysql" name="db_database"
|
|
|
+ class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
|
+ {% set cur_db = db_cfg.get('database', '') if job and job.type == 'mysql' else '' %}
|
|
|
+ {% if cur_db %}
|
|
|
+ <option value="{{ cur_db }}" selected>{{ cur_db }}</option>
|
|
|
+ {% else %}
|
|
|
+ <option value="">Chargement…</option>
|
|
|
+ {% endif %}
|
|
|
+ </select>
|
|
|
<p class="text-xs text-gray-400 mt-1">
|
|
|
- Le dump est exécuté avec <code class="bg-gray-100 px-1 rounded">sudo mysqldump</code> — aucun mot de passe requis.
|
|
|
+ Dump via <code class="bg-gray-100 px-1 rounded">sudo mysqldump</code> — aucun mot de passe requis.
|
|
|
</p>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -94,13 +99,18 @@
|
|
|
{# Type-specific config : postgresql #}
|
|
|
<div id="cfg-postgresql" class="type-cfg hidden space-y-3">
|
|
|
<div>
|
|
|
- <label class="block text-sm font-medium text-gray-700 mb-1">Nom de la base de données</label>
|
|
|
- <input type="text" name="db_database"
|
|
|
- value="{{ db_cfg.get('database', '') if job and job.type == 'postgresql' else '' }}"
|
|
|
- placeholder="ex: gitea"
|
|
|
- class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
|
+ <label class="block text-sm font-medium text-gray-700 mb-1">Base de données</label>
|
|
|
+ <select id="db-select-postgresql" name="db_database"
|
|
|
+ class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
|
+ {% set cur_db = db_cfg.get('database', '') if job and job.type == 'postgresql' else '' %}
|
|
|
+ {% if cur_db %}
|
|
|
+ <option value="{{ cur_db }}" selected>{{ cur_db }}</option>
|
|
|
+ {% else %}
|
|
|
+ <option value="">Chargement…</option>
|
|
|
+ {% endif %}
|
|
|
+ </select>
|
|
|
<p class="text-xs text-gray-400 mt-1">
|
|
|
- Le dump est exécuté avec <code class="bg-gray-100 px-1 rounded">sudo -u postgres pg_dump</code> — aucun mot de passe requis.
|
|
|
+ Dump via <code class="bg-gray-100 px-1 rounded">sudo -u postgres pg_dump</code> — aucun mot de passe requis.
|
|
|
</p>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -230,9 +240,9 @@
|
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Mode</label>
|
|
|
<select name="retention_mode"
|
|
|
class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
|
- {% for val, label in [('count','Count — N dernières archives'),
|
|
|
- ('daily','Daily — 1 par jour sur N jours'),
|
|
|
- ('gfs','GFS — Grand/Père/Fils (Phase 4)')] %}
|
|
|
+ {% for val, label in [('count','Garder les N dernières archives'),
|
|
|
+ ('daily','1 archive par jour sur N jours glissants'),
|
|
|
+ ('gfs','Grand-Père-Fils (non disponible)')] %}
|
|
|
<option value="{{ val }}"
|
|
|
{% if job and job.retention_mode == val %}selected{% endif %}
|
|
|
{% if val == 'gfs' %}disabled class="text-gray-400"{% endif %}>
|
|
|
@@ -242,12 +252,13 @@
|
|
|
</select>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <label class="block text-sm font-medium text-gray-700 mb-1">Valeur</label>
|
|
|
+ <label class="block text-sm font-medium text-gray-700 mb-1">Valeur (N)</label>
|
|
|
<input type="number" name="retention_value" min="1" max="365" required
|
|
|
value="{{ job.retention_value if job else 7 }}"
|
|
|
class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
|
</div>
|
|
|
</div>
|
|
|
+ <p id="retention-help" class="text-xs text-gray-400"></p>
|
|
|
</div>
|
|
|
|
|
|
{# ── Destination ── #}
|
|
|
@@ -296,13 +307,64 @@
|
|
|
</div>
|
|
|
|
|
|
<script>
|
|
|
+ const retentionHelp = {
|
|
|
+ count: "Ex : N=7 → conserve les 7 dernières archives, supprime les plus anciennes.",
|
|
|
+ daily: "Ex : N=30 → conserve 1 archive par jour sur les 30 derniers jours. Les doublons du même jour sont supprimés.",
|
|
|
+ gfs: "Mode non encore disponible."
|
|
|
+ };
|
|
|
+
|
|
|
+ const dbCache = {};
|
|
|
+
|
|
|
+ function loadDatabases(dbType) {
|
|
|
+ const sel = document.getElementById('db-select-' + dbType);
|
|
|
+ if (!sel) return;
|
|
|
+ if (dbCache[dbType]) {
|
|
|
+ populateSelect(sel, dbCache[dbType]);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ fetch("{{ url_for('internal_databases', db_type='__TYPE__') }}".replace('__TYPE__', dbType))
|
|
|
+ .then(r => r.json())
|
|
|
+ .then(dbs => {
|
|
|
+ dbCache[dbType] = dbs;
|
|
|
+ populateSelect(sel, dbs);
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ sel.innerHTML = '<option value="">Impossible de charger les bases</option>';
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function populateSelect(sel, dbs) {
|
|
|
+ const current = sel.querySelector('option[selected]')?.value || '';
|
|
|
+ sel.innerHTML = '';
|
|
|
+ if (!dbs.length) {
|
|
|
+ sel.innerHTML = '<option value="">Aucune base trouvée</option>';
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ dbs.forEach(db => {
|
|
|
+ const opt = document.createElement('option');
|
|
|
+ opt.value = db;
|
|
|
+ opt.textContent = db;
|
|
|
+ if (db === current) opt.selected = true;
|
|
|
+ sel.appendChild(opt);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
function showTypeConfig() {
|
|
|
document.querySelectorAll('.type-cfg').forEach(el => el.classList.add('hidden'));
|
|
|
const type = document.getElementById('job-type').value;
|
|
|
const el = document.getElementById('cfg-' + type);
|
|
|
if (el) el.classList.remove('hidden');
|
|
|
+ if (type === 'mysql' || type === 'postgresql') loadDatabases(type);
|
|
|
}
|
|
|
+
|
|
|
+ function updateRetentionHelp() {
|
|
|
+ const mode = document.querySelector('[name=retention_mode]').value;
|
|
|
+ document.getElementById('retention-help').textContent = retentionHelp[mode] || '';
|
|
|
+ }
|
|
|
+
|
|
|
document.getElementById('job-type').addEventListener('change', showTypeConfig);
|
|
|
+ document.querySelector('[name=retention_mode]').addEventListener('change', updateRetentionHelp);
|
|
|
showTypeConfig();
|
|
|
+ updateRetentionHelp();
|
|
|
</script>
|
|
|
{% endblock %}
|