move optional config from app info page to deploy/settings page

Users couldn't find metadata provider fields (IGDB, ScreenScraper, etc.)
on the app info page. Move them to the deploy page where all other
settings (integrations, geo-restriction) already live.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 20:04:28 +01:00
parent 36afd828a1
commit 54390c456c
3 changed files with 100 additions and 92 deletions
@@ -101,84 +101,5 @@
</div>
{{end}}
{{if .HasOptionalConfig}}
<div class="app-optional-config">
<h3>Opcionális beállítások</h3>
{{range .OptionalConfig}}
<div class="config-group">
<h4>{{.Group}}</h4>
{{if .Description}}<p class="config-group-desc">{{.Description}}</p>{{end}}
<div class="config-fields">
{{range .Fields}}
<div class="config-field">
<label for="opt-{{.EnvVar}}">{{.Label}}</label>
{{if .HelpText}}<p class="config-field-help">{{.HelpText}}</p>{{end}}
{{if .HelpURL}}<p class="config-field-help"><a href="{{.HelpURL}}" target="_blank">Regisztrációs útmutató ↗</a></p>{{end}}
<input type="{{if eq .Type "secret_input"}}password{{else}}text{{end}}"
id="opt-{{.EnvVar}}"
name="{{.EnvVar}}"
class="config-input"
value="{{index $.CurrentValues .EnvVar}}"
placeholder="{{.Label}}"
autocomplete="off">
</div>
{{end}}
</div>
</div>
{{end}}
<div class="config-actions">
<button class="btn btn-primary" id="save-optional-config" onclick="saveOptionalConfig('{{.Stack.Name}}')">
Mentés
</button>
<span id="config-save-status" class="config-save-status"></span>
</div>
</div>
<script>
async function saveOptionalConfig(stackName) {
const btn = document.getElementById('save-optional-config');
const status = document.getElementById('config-save-status');
const inputs = document.querySelectorAll('.config-input');
const values = {};
inputs.forEach(function(input) {
values[input.name] = input.value;
});
btn.disabled = true;
btn.textContent = 'Mentés...';
status.textContent = '';
status.className = 'config-save-status';
try {
const resp = await fetch('/api/stacks/' + stackName + '/optional-config', {
method: 'POST',
headers: Object.assign({'Content-Type': 'application/json'}, csrfHeaders()),
body: JSON.stringify({values: values})
});
const 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>
{{end}}
{{template "layout_end" .}}
{{end}}
@@ -402,6 +402,85 @@
</script>
{{end}}
{{if .HasOptionalConfig}}
<div class="app-optional-config">
<h3>Opcionális beállítások</h3>
{{range .OptionalConfig}}
<div class="config-group">
<h4>{{.Group}}</h4>
{{if .Description}}<p class="config-group-desc">{{.Description}}</p>{{end}}
<div class="config-fields">
{{range .Fields}}
<div class="config-field">
<label for="opt-{{.EnvVar}}">{{.Label}}</label>
{{if .HelpText}}<p class="config-field-help">{{.HelpText}}</p>{{end}}
{{if .HelpURL}}<p class="config-field-help"><a href="{{.HelpURL}}" target="_blank">Regisztrációs útmutató ↗</a></p>{{end}}
<input type="{{if eq .Type "secret_input"}}password{{else}}text{{end}}"
id="opt-{{.EnvVar}}"
name="{{.EnvVar}}"
class="config-input"
value="{{index $.CurrentValues .EnvVar}}"
placeholder="{{.Label}}"
autocomplete="off">
</div>
{{end}}
</div>
</div>
{{end}}
<div class="config-actions">
<button class="btn btn-primary" id="save-optional-config" onclick="saveOptionalConfig('{{.Stack.Name}}')">
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) {
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>
{{end}}
{{if and (not .AlreadyDeployed) .MemoryInfo}}
{{with .MemoryInfo}}
{{if .Available}}