v0.315.0: one app page with four tabs; the guide the catalog can carry; no Raspberry Pi badge
gates / gates (push) Failing after 47s
gates / gates (push) Failing after 47s
An app was six pages — details, install/settings, logs, export, the per-app backup panel and a
details card for moving data — and every "Vissza" on them went to the app LIST, so there was no way
back to the app you were looking at. It is now ONE page with four tab URLs under /apps/{slug}/,
one shared header and one set of banners.
settings Mukodes (Start/Restart/Stop, Stop confirms) + the cards that want something from the
household + the install-time and optional settings. The default for an installed app,
RENDERED at the bare URL and never redirected to.
data the data folders, move to another drive, the nightly copy, the 2nd-copy setting, export
guide tagline, screenshots, use cases, first steps, the catalog's guide, the FAQ, the docs
link — and the WHOLE page for an app that is not installed
logs the log, and the only tab whose poller runs
The tabs are links, not panels: a link in an alert has to land ON a tab, and the log poller must not
run on the other three. Start/Restart/Stop left the page header, where they read as menu buttons.
The old /stacks/{name}/{deploy,logs,export,backup} GETs answer 302 — never 301, which a browser
caches beyond anyone's reach — to the tab that now holds them, query string carried through, with
name->slug resolved through the stack list rather than assumed equal. Every POST on those paths is
untouched: the backup form, the app-email toggle and the reveal endpoints keep their URLs.
A value asked AFTER the app starts is now generic (D2). The catalog marks a field `after_start: true`
and supplies its label; the ACTION is Go, in a registry keyed by slug + env var. The catalog can
never declare what runs — a declared field with no registered action renders nothing, POSTs 404 and
logs one WARN with the env var KEY, never the value. A red-proof found the second half of that guard
unpinned: deleting the "the catalog must have DECLARED this field" check left the suite green, and a
POST for an undeclared field then reached Plex and opened the setup gate.
TestAfterStart_RegistryAloneIsNotAnInvitation pins it.
New catalog block app_info.guide (sections + faq + checked_version), parsed, localised field by
field and rendered with the household's own address filled in. It renders only when checked_version
names the image tag its author clicked through. No template carries one yet.
The Pi and "csak x86" badges are gone; PiCompatible and the catalog key stay this release, or a box
on 0.314.0 would read "csak x86" on every app (R-1067).
template_id_gate.py now follows {{template}} includes, with a scope decoy proving the walk did not
become vacuous.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y
This commit is contained in:
+11
-493
@@ -172,17 +172,19 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<div style="display:flex;align-items:center;gap:.5rem">
|
||||
<a href="/stacks" class="btn btn-sm btn-outline">← Vissza</a>
|
||||
<a href="/apps/privatebin" class="btn btn-sm btn-outline" data-install-back="1">← Vissza</a>
|
||||
<h2>Private Bin — Telepítés</h2>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:.5rem">
|
||||
|
||||
<a href="/apps/privatebin" class="btn btn-sm btn-outline"><svg class="ico ico-sm"><use href="#i-info"/></svg> Részletek</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="deploy-container">
|
||||
<div class="flash flash-success">A mentés sikeresen elkészült.</div>
|
||||
<div class="flash flash-error">A művelet most nem sikerült.</div>
|
||||
@@ -194,7 +196,6 @@
|
||||
<p>Egy teszt alkalmazás leírása</p>
|
||||
<div class="metarows">
|
||||
<span class="metarow"><svg class="ico"><use href="#i-memory-stick"/></svg><span class="mono">~128M</span></span>
|
||||
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Pi kompatibilis</span>
|
||||
<span class="metarow"><svg class="ico"><use href="#i-hard-drive"/></svg>HDD szükséges</span>
|
||||
<span class="metarow"><svg class="ico"><use href="#i-check"/></svg>Magyar felület</span>
|
||||
</div>
|
||||
@@ -205,395 +206,6 @@
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="app-optional-config">
|
||||
<h3>Integrációk</h3>
|
||||
<p class="config-group-desc">
|
||||
Más telepített alkalmazásokkal való összekapcsolás. Az integráció automatikusan felfüggesztődik, ha bármelyik alkalmazás leáll, és újraaktiválódik indításkor.
|
||||
</p>
|
||||
|
||||
|
||||
<div class="config-field" style="display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.75rem 0;border-bottom:1px solid var(--line)">
|
||||
<div style="flex:1">
|
||||
<strong>Integráció egy</strong>
|
||||
<p class="config-field-help" style="margin:0">Első integráció leírása</p>
|
||||
|
||||
<span class="tag tag-off" style="margin-top:.25rem"><span class="dot"></span>Nincs telepítve</span>
|
||||
|
||||
</div>
|
||||
<label class="toggle">
|
||||
<input type="checkbox"
|
||||
|
||||
disabled title="A célalkalmazás nincs telepítve"
|
||||
|
||||
onchange="toggleIntegration('privatebin', 'a', this.checked, this)">
|
||||
<span class="toggle-label"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="config-field" style="display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.75rem 0;border-bottom:1px solid var(--line)">
|
||||
<div style="flex:1">
|
||||
<strong>Integráció kettő</strong>
|
||||
<p class="config-field-help" style="margin:0">Második integráció leírása</p>
|
||||
|
||||
<span class="tag tag-neutral" style="margin-top:.25rem"><span class="dot"></span>Célalkalmazás leállítva</span>
|
||||
|
||||
</div>
|
||||
<label class="toggle">
|
||||
<input type="checkbox"
|
||||
|
||||
|
||||
disabled title="A célalkalmazás nem fut"
|
||||
onchange="toggleIntegration('privatebin', 'b', this.checked, this)">
|
||||
<span class="toggle-label"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="config-field" style="display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.75rem 0;border-bottom:1px solid var(--line)">
|
||||
<div style="flex:1">
|
||||
<strong>Integráció három</strong>
|
||||
<p class="config-field-help" style="margin:0">Harmadik integráció leírása</p>
|
||||
|
||||
<span class="tag tag-crit" style="margin-top:.25rem"><span class="dot"></span>Hiba</span>
|
||||
|
||||
</div>
|
||||
<label class="toggle">
|
||||
<input type="checkbox"
|
||||
|
||||
|
||||
|
||||
onchange="toggleIntegration('privatebin', 'c', this.checked, this)">
|
||||
<span class="toggle-label"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="config-field" style="display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.75rem 0;border-bottom:1px solid var(--line)">
|
||||
<div style="flex:1">
|
||||
<strong>Integráció négy</strong>
|
||||
<p class="config-field-help" style="margin:0">Negyedik integráció leírása</p>
|
||||
|
||||
<span class="tag tag-run" style="margin-top:.25rem"><span class="dot"></span>Aktív</span>
|
||||
|
||||
</div>
|
||||
<label class="toggle">
|
||||
<input type="checkbox"
|
||||
checked
|
||||
|
||||
|
||||
onchange="toggleIntegration('privatebin', 'd', this.checked, this)">
|
||||
<span class="toggle-label"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="config-field" style="display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.75rem 0;border-bottom:1px solid var(--line)">
|
||||
<div style="flex:1">
|
||||
<strong>Integráció öt</strong>
|
||||
<p class="config-field-help" style="margin:0">Ötödik integráció leírása</p>
|
||||
|
||||
</div>
|
||||
<label class="toggle">
|
||||
<input type="checkbox"
|
||||
|
||||
|
||||
|
||||
onchange="toggleIntegration('privatebin', 'e', this.checked, this)">
|
||||
<span class="toggle-label"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function toggleIntegration(provider, target, enable, checkbox) {
|
||||
checkbox.disabled = true;
|
||||
try {
|
||||
var resp = await fetch('/api/integrations/' + provider + '/' + target, {
|
||||
method: 'POST',
|
||||
headers: Object.assign({'Content-Type': 'application/json'}, csrfHeaders()),
|
||||
body: JSON.stringify({enabled: enable})
|
||||
});
|
||||
var data = await resp.json();
|
||||
if (!data.ok) {
|
||||
checkbox.checked = !enable;
|
||||
showAlert(data.error || 'Hiba történt');
|
||||
} else {
|
||||
setTimeout(function(){ location.reload(); }, 500);
|
||||
return;
|
||||
}
|
||||
} catch(err) {
|
||||
checkbox.checked = !enable;
|
||||
showAlert('Hálózati hiba');
|
||||
}
|
||||
checkbox.disabled = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<div class="app-optional-config">
|
||||
<h3>Földrajzi korlátozás</h3>
|
||||
<p class="config-group-desc">
|
||||
Az alkalmazás egyéni országkorlátozás nélkül a globális beállítást követi.
|
||||
</p>
|
||||
|
||||
<label class="toggle" style="margin-bottom:1rem">
|
||||
<input type="checkbox" id="app-geo-override-toggle"
|
||||
checked
|
||||
onchange="toggleAppGeoOverride(this.checked)">
|
||||
<span class="toggle-label">Egyéni országkorlátozás</span>
|
||||
</label>
|
||||
|
||||
<div id="app-geo-override-details" >
|
||||
<div class="form-group">
|
||||
<label>Engedélyezett országok ehhez az alkalmazáshoz</label>
|
||||
<div class="geo-country-selector">
|
||||
<input type="text" id="app-geo-search" class="form-control config-input"
|
||||
placeholder="Ország keresése..." autocomplete="off"
|
||||
oninput="filterAppGeoCountries(this.value)"
|
||||
onfocus="showAppGeoList()"
|
||||
onblur="setTimeout(function(){hideAppGeoList()},200)">
|
||||
<div class="geo-country-list" id="app-geo-country-list"></div>
|
||||
</div>
|
||||
<div class="geo-selected-tags" id="app-geo-tags"></div>
|
||||
</div>
|
||||
<div class="config-actions">
|
||||
<button class="btn btn-primary" onclick="saveAppGeoOverride()">Mentés</button>
|
||||
<span id="app-geo-status" class="config-save-status"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
var allCountries = [];
|
||||
var appGeoCountries = ["HU","AT"];
|
||||
var stackName = 'privatebin';
|
||||
|
||||
function loadCountries(cb) {
|
||||
if (allCountries.length > 0) { cb(); return; }
|
||||
fetch('/api/geo/countries', {headers: csrfHeaders()})
|
||||
.then(function(r){return r.json()})
|
||||
.then(function(d){ if(d.ok) allCountries = d.data; cb(); })
|
||||
.catch(function(){ cb(); });
|
||||
}
|
||||
|
||||
window.toggleAppGeoOverride = function(enabled) {
|
||||
document.getElementById('app-geo-override-details').style.display = enabled ? '' : 'none';
|
||||
if (enabled) {
|
||||
if (!appGeoCountries || appGeoCountries.length === 0) {
|
||||
appGeoCountries = ["HU"];
|
||||
}
|
||||
loadCountries(renderAppGeoTags);
|
||||
} else {
|
||||
fetch('/api/stacks/' + stackName + '/geo/override', {method:'DELETE', headers:csrfHeaders()});
|
||||
}
|
||||
};
|
||||
|
||||
window.showAppGeoList = function() { loadCountries(function(){ filterAppGeoCountries(''); }); };
|
||||
window.hideAppGeoList = function() { document.getElementById('app-geo-country-list').style.display='none'; };
|
||||
|
||||
window.filterAppGeoCountries = function(q) {
|
||||
var list = document.getElementById('app-geo-country-list');
|
||||
q = q.toLowerCase();
|
||||
var html = ''; var count = 0;
|
||||
for (var i = 0; i < allCountries.length && count < 15; i++) {
|
||||
var c = allCountries[i];
|
||||
if (appGeoCountries.indexOf(c.code) >= 0) continue;
|
||||
if (q && c.name.toLowerCase().indexOf(q) < 0 && c.code.toLowerCase().indexOf(q) < 0) continue;
|
||||
html += '<div class="geo-country-option" onmousedown="addAppGeoCountry(\'' + c.code + '\')">'
|
||||
+ esc(c.name) + ' <small>(' + c.code + ')</small></div>';
|
||||
count++;
|
||||
}
|
||||
list.innerHTML = html || '<div class="geo-country-option" style="opacity:.5">Nincs találat</div>';
|
||||
list.style.display = (count > 0 || q) ? '' : 'none';
|
||||
};
|
||||
|
||||
window.addAppGeoCountry = function(code) {
|
||||
if (appGeoCountries.indexOf(code) >= 0) return;
|
||||
appGeoCountries.push(code);
|
||||
renderAppGeoTags();
|
||||
document.getElementById('app-geo-search').value = '';
|
||||
hideAppGeoList();
|
||||
};
|
||||
|
||||
window.removeAppGeoCountry = function(code) {
|
||||
appGeoCountries = appGeoCountries.filter(function(c){return c !== code});
|
||||
renderAppGeoTags();
|
||||
};
|
||||
|
||||
function renderAppGeoTags() {
|
||||
var el = document.getElementById('app-geo-tags');
|
||||
var html = '';
|
||||
for (var i = 0; i < appGeoCountries.length; i++) {
|
||||
var code = appGeoCountries[i];
|
||||
var name = code;
|
||||
for (var j = 0; j < allCountries.length; j++) {
|
||||
if (allCountries[j].code === code) { name = allCountries[j].name; break; }
|
||||
}
|
||||
html += '<span class="geo-tag">' + esc(name) + ' (' + code + ') '
|
||||
+ '<span class="geo-tag-remove" onclick="removeAppGeoCountry(\'' + code + '\')">×</span></span>';
|
||||
}
|
||||
el.innerHTML = html;
|
||||
}
|
||||
|
||||
window.saveAppGeoOverride = function() {
|
||||
var status = document.getElementById('app-geo-status');
|
||||
fetch('/api/stacks/' + stackName + '/geo/override', {
|
||||
method: 'POST',
|
||||
headers: Object.assign({'Content-Type':'application/json'}, csrfHeaders()),
|
||||
body: JSON.stringify({allowed_countries: appGeoCountries})
|
||||
})
|
||||
.then(function(r){return r.json()})
|
||||
.then(function(d){
|
||||
status.textContent = d.ok ? (d.message || 'Mentve') : (d.error || 'Hiba');
|
||||
status.className = 'config-save-status ' + (d.ok ? 'config-save-ok' : 'config-save-err');
|
||||
setTimeout(function(){ status.textContent=''; }, 5000);
|
||||
})
|
||||
.catch(function(){
|
||||
status.textContent = 'Hálózati hiba';
|
||||
status.className = 'config-save-status config-save-err';
|
||||
});
|
||||
};
|
||||
|
||||
function esc(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }
|
||||
|
||||
if (document.getElementById('app-geo-override-toggle') && document.getElementById('app-geo-override-toggle').checked) {
|
||||
loadCountries(renderAppGeoTags);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<div class="app-optional-config">
|
||||
<h3>Opcionális beállítások</h3>
|
||||
|
||||
<div class="config-group">
|
||||
<h4>Külső szolgáltatások</h4>
|
||||
<p class="config-group-desc">Opcionális kulcsok leírása</p>
|
||||
|
||||
<div class="config-fields">
|
||||
|
||||
<div class="config-field">
|
||||
<label for="opt-API_KEY">API kulcs mező</label>
|
||||
<p class="config-field-help">Ide jön a kulcs</p>
|
||||
<p class="config-field-help"><a href="https://example.org/reg" target="_blank">Regisztrációs útmutató ↗</a></p>
|
||||
|
||||
|
||||
|
||||
<div class="input-with-button">
|
||||
<input type="password" id="opt-API_KEY" name="API_KEY" class="config-input"
|
||||
value="" placeholder="••••••••••••"
|
||||
data-secret-set="1" autocomplete="off">
|
||||
<button type="button" class="btn btn-sm btn-outline" onclick="revealAutoField('privatebin','API_KEY', this, 'opt-API_KEY')">Megjelenítés</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="config-field">
|
||||
<label for="opt-OTHER">Másik mező itt</label>
|
||||
|
||||
|
||||
|
||||
<input type="text"
|
||||
id="opt-OTHER"
|
||||
name="OTHER"
|
||||
class="config-input"
|
||||
value=""
|
||||
placeholder="Másik mező itt"
|
||||
autocomplete="off">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="config-actions">
|
||||
<button class="btn btn-primary" id="save-optional-config" onclick="saveOptionalConfig('privatebin')">
|
||||
Mentés
|
||||
</button>
|
||||
<span id="config-save-status" class="config-save-status"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function saveOptionalConfig(stackName) {
|
||||
var btn = document.getElementById('save-optional-config');
|
||||
var status = document.getElementById('config-save-status');
|
||||
var inputs = document.querySelectorAll('.config-input');
|
||||
|
||||
var values = {};
|
||||
inputs.forEach(function(input) {
|
||||
|
||||
if (input.dataset.secretSet === '1' && input.dataset.revealed !== '1' && input.value === '') return;
|
||||
values[input.name] = input.value;
|
||||
});
|
||||
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Mentés...';
|
||||
status.textContent = '';
|
||||
status.className = 'config-save-status';
|
||||
|
||||
try {
|
||||
var resp = await fetch('/api/stacks/' + stackName + '/optional-config', {
|
||||
method: 'POST',
|
||||
headers: Object.assign({'Content-Type': 'application/json'}, csrfHeaders()),
|
||||
body: JSON.stringify({values: values})
|
||||
});
|
||||
var data = await resp.json();
|
||||
|
||||
if (data.ok) {
|
||||
status.textContent = (data.message || 'Mentve');
|
||||
status.className = 'config-save-status config-save-ok';
|
||||
} else {
|
||||
status.textContent = (data.error || 'Hiba');
|
||||
status.className = 'config-save-status config-save-err';
|
||||
}
|
||||
} catch(err) {
|
||||
status.textContent = 'Hálózati hiba';
|
||||
status.className = 'config-save-status config-save-err';
|
||||
}
|
||||
|
||||
btn.disabled = false;
|
||||
btn.textContent = 'Mentés';
|
||||
|
||||
setTimeout(function() { status.textContent = ''; }, 5000);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<div class="app-optional-config">
|
||||
<h3>Email-küldés</h3>
|
||||
<p class="config-group-desc">
|
||||
Ez az alkalmazás tud emailt küldeni (pl. jelszó-visszaállítás, meghívók) a Felhom-on keresztül,
|
||||
külön szolgáltató beállítása nélkül. A feladó címe: <strong>noreply@example.hu</strong>.
|
||||
</p>
|
||||
|
||||
<p class="alert alert-warning" style="margin-bottom:1rem">
|
||||
Az alkalmazás-email jelenleg ki van kapcsolva globálisan. Kapcsold be a
|
||||
<a href="/settings">Beállítások</a> oldalon, hogy itt is működjön.
|
||||
</p>
|
||||
|
||||
<form method="POST" action="/stacks/privatebin/app-email">
|
||||
|
||||
<label style="display:flex;align-items:center;gap:.5rem;margin-bottom:1rem">
|
||||
<input type="checkbox" name="app_email_enabled" value="on" checked>
|
||||
Email-küldés engedélyezése ennél az alkalmazásnál
|
||||
</label>
|
||||
<div class="config-actions">
|
||||
<button class="btn btn-primary" type="submit">Mentés</button>
|
||||
<span class="config-group-desc" style="margin-left:.5rem">A mentés újraindítja az alkalmazást.</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="memory-summary">
|
||||
@@ -644,6 +256,8 @@
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="form-section">
|
||||
<h4>Automatikusan generált értékek</h4>
|
||||
@@ -865,10 +479,11 @@
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="deploy-actions">
|
||||
<button type="submit" class="btn btn-primary btn-lg">Telepítés indítása</button>
|
||||
<a href="/stacks" class="btn btn-outline">Mégsem</a>
|
||||
<a href="/apps/privatebin" class="btn btn-outline" data-install-cancel="1">Mégsem</a>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
@@ -1009,7 +624,7 @@ function buildPostDeployCard(stackName) {
|
||||
|
||||
|
||||
html += '<div style="display:flex;gap:.75rem;margin-top:1.5rem;flex-wrap:wrap">' +
|
||||
'<a href="/stacks/' + stackName + '/deploy" class="btn btn-outline">Beállítások és jelszavak megtekintése</a>' +
|
||||
'<a href="/apps/privatebin/settings" class="btn btn-outline">Beállítások és jelszavak megtekintése</a>' +
|
||||
'<a href="/stacks" class="btn btn-sm btn-outline">← Alkalmazások</a>' +
|
||||
'</div>';
|
||||
|
||||
@@ -1032,56 +647,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
|
||||
|
||||
function revealPasswordField(stackName, envVar, btn) {
|
||||
var el = document.getElementById('field-' + envVar);
|
||||
if (!el) return;
|
||||
if (btn.dataset.shown === '1') {
|
||||
el.value = '';
|
||||
el.type = 'password';
|
||||
btn.dataset.shown = '';
|
||||
return;
|
||||
}
|
||||
btn.disabled = true;
|
||||
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
|
||||
method: 'POST',
|
||||
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
|
||||
credentials: 'same-origin',
|
||||
body: 'env_var=' + encodeURIComponent(envVar)
|
||||
}).then(function (r) { return r.json(); }).then(function (j) {
|
||||
btn.disabled = false;
|
||||
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
|
||||
el.value = j.data.value;
|
||||
el.type = 'text';
|
||||
el.dataset.revealed = '1';
|
||||
btn.dataset.shown = '1';
|
||||
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
|
||||
}
|
||||
function revealAutoField(stackName, envVar, btn, elId) {
|
||||
var el = document.getElementById(elId || ('auto-field-' + envVar));
|
||||
if (!el) return;
|
||||
if (btn.dataset.shown === '1') {
|
||||
el.value = '';
|
||||
el.type = 'password';
|
||||
el.dataset.revealed = '';
|
||||
btn.dataset.shown = '';
|
||||
btn.textContent = 'Megjelenítés';
|
||||
return;
|
||||
}
|
||||
btn.disabled = true;
|
||||
fetch('/stacks/' + encodeURIComponent(stackName) + '/auto-field/reveal', {
|
||||
method: 'POST',
|
||||
headers: Object.assign({'Content-Type': 'application/x-www-form-urlencoded'}, csrfHeaders()),
|
||||
credentials: 'same-origin',
|
||||
body: 'env_var=' + encodeURIComponent(envVar)
|
||||
}).then(function (r) { return r.json(); }).then(function (j) {
|
||||
btn.disabled = false;
|
||||
if (!j.ok) { showAlert(j.error || 'A lekérés nem sikerült.'); return; }
|
||||
el.value = j.data.value;
|
||||
el.type = 'text';
|
||||
btn.dataset.shown = '1';
|
||||
btn.textContent = 'Elrejtés';
|
||||
}).catch(function () { btn.disabled = false; showAlert('A lekérés nem sikerült.'); });
|
||||
}
|
||||
function toggleAutoField(fieldId, btn) {
|
||||
var el = document.getElementById(fieldId);
|
||||
if (!el) return;
|
||||
@@ -1148,53 +713,6 @@ function copyPostDeployCred(btn, val) {
|
||||
}
|
||||
}
|
||||
|
||||
function deleteStaleData(stackName, stalePath, btn) {
|
||||
|
||||
felhomConfirm(btn, 'Biztosan törölni szeretnéd a korábbi adatokat? Tárhely: ' + stalePath + ' — FIGYELEM: a művelet visszavonhatatlan! Előtte győződj meg róla, hogy az alkalmazás az új tárolóról megfelelően működik.', function () {
|
||||
felhomConfirm(btn, 'UTOLSÓ FIGYELMEZTETÉS! A törlés visszavonhatatlan. Biztosan folytatod?', function () {
|
||||
deleteStaleDataRun(stackName, stalePath, btn);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deleteStaleDataRun(stackName, stalePath, btn) {
|
||||
btn.disabled = true;
|
||||
btn.textContent = 'Törlés folyamatban...';
|
||||
|
||||
fetch('/api/storage/stale-cleanup', {
|
||||
method: 'POST',
|
||||
headers: Object.assign({'Content-Type': 'application/json'}, csrfHeaders()),
|
||||
body: JSON.stringify({stack_name: stackName, stale_path: stalePath})
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (!data.ok) {
|
||||
showAlert('Hiba: ' + (data.error || 'Ismeretlen hiba'));
|
||||
btn.disabled = false;
|
||||
btn.textContent = 'Korábbi adatok törlése';
|
||||
return;
|
||||
}
|
||||
var msg = 'Korábbi adatok törölve!\n\nFelszabadított hely: ' + (data.freed_human || '?');
|
||||
if (data.errors && data.errors.length > 0) {
|
||||
msg += '\n\nNéhány hiba történt:\n' + data.errors.join('\n');
|
||||
}
|
||||
showAlert(msg);
|
||||
|
||||
var item = btn.closest('.stale-data-item');
|
||||
if (item) item.remove();
|
||||
|
||||
var container = document.querySelector('.deploy-stale-data');
|
||||
if (container && container.querySelectorAll('.stale-data-item').length === 0) {
|
||||
container.remove();
|
||||
}
|
||||
})
|
||||
.catch(function(e) {
|
||||
showAlert('Hálózati hiba: ' + e.message);
|
||||
btn.disabled = false;
|
||||
btn.textContent = 'Korábbi adatok törlése';
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('deploy-form').addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -1344,7 +862,7 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
||||
progressEl.querySelector('h3').textContent = 'Telepítés sikertelen';
|
||||
resultEl.innerHTML = '<div class="alert alert-error" style="margin-top:1rem">' +
|
||||
'A telepítés nem sikerült: ' + deployError +
|
||||
'</div><a href="/stacks/' + stackName + '/logs" class="btn btn-outline" style="margin-top:.75rem">Naplók megtekintése</a>' +
|
||||
'</div><a href="/apps/privatebin/logs" class="btn btn-outline" style="margin-top:.75rem">Naplók megtekintése</a>' +
|
||||
' <a href="/stacks" class="btn btn-primary" style="margin-top:.75rem">Alkalmazások</a>';
|
||||
resultEl.style.display = 'block';
|
||||
} else if (state === 'deploying') {
|
||||
@@ -1379,7 +897,7 @@ document.getElementById('deploy-form').addEventListener('submit', async function
|
||||
progressEl.querySelector('h3').textContent = 'Telepítés sikertelen';
|
||||
resultEl.innerHTML = '<div class="alert alert-error" style="margin-top:1rem">' +
|
||||
'A konténer leállt. Ellenőrizd a naplókat.' +
|
||||
'</div><a href="/stacks/' + stackName + '/logs" class="btn btn-outline" style="margin-top:.75rem">Naplók megtekintése</a>' +
|
||||
'</div><a href="/apps/privatebin/logs" class="btn btn-outline" style="margin-top:.75rem">Naplók megtekintése</a>' +
|
||||
' <a href="/stacks" class="btn btn-primary" style="margin-top:.75rem">Alkalmazások</a>';
|
||||
resultEl.style.display = 'block';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user