101 lines
4.0 KiB
HTML
101 lines
4.0 KiB
HTML
{{template "base" .}}
|
|
{{define "content"}}
|
|
<div style="max-width:1400px">
|
|
|
|
<div style="margin-bottom:16px">
|
|
<div class="page-title">Config Editor</div>
|
|
<div class="page-sub">Edit CrowdSec YAML files — config is tested before applying, reverted on failure</div>
|
|
</div>
|
|
|
|
{{if .FetchErr}}
|
|
<div class="panel">
|
|
<div class="panel-body">
|
|
<div class="empty-text">Config directory unavailable</div>
|
|
<div class="empty-sub">{{.FetchErr}}</div>
|
|
</div>
|
|
</div>
|
|
{{else}}
|
|
|
|
<div style="display:grid;grid-template-columns:220px 1fr;gap:16px">
|
|
|
|
<div class="panel" style="align-self:start">
|
|
<div class="panel-header"><span class="panel-title">Files</span></div>
|
|
<div style="padding:8px 0">
|
|
{{if .Files}}
|
|
{{range .Files}}
|
|
<a href="/config-editor?file={{.}}"
|
|
style="display:block;padding:6px 16px;font-family:'JetBrains Mono',monospace;font-size:12px;
|
|
color:{{if eq . $.File}}var(--accent){{else}}var(--text){{end}};
|
|
background:{{if eq . $.File}}rgba(0,212,255,0.08){{else}}transparent{{end}};
|
|
text-decoration:none;word-break:break-all"
|
|
title="{{.}}">{{.}}</a>
|
|
{{end}}
|
|
{{else}}
|
|
<div style="padding:12px 16px;font-size:12px;color:var(--muted)">No YAML files found</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
{{if .File}}
|
|
<div class="panel">
|
|
<div class="panel-header">
|
|
<span class="panel-title" style="font-family:'JetBrains Mono',monospace;font-size:13px">{{.File}}</span>
|
|
<span style="font-size:12px;color:var(--muted)">Write saves and runs crowdsec -t; reverts on failure</span>
|
|
</div>
|
|
{{if .TestOut}}
|
|
<div style="padding:12px 16px;background:rgba(255,59,59,0.08);border-bottom:1px solid var(--border)">
|
|
<div style="font-size:12px;color:var(--threat);margin-bottom:4px">Config test failed — file was reverted</div>
|
|
<pre style="font-size:11px;color:var(--muted);margin:0;white-space:pre-wrap">{{.TestOut}}</pre>
|
|
</div>
|
|
{{end}}
|
|
<div class="panel-body">
|
|
<form method="POST" action="/config-editor/save">
|
|
<input type="hidden" name="_csrf" value="{{.CSRFToken}}">
|
|
<input type="hidden" name="file" value="{{.File}}">
|
|
<textarea name="content" id="editor"
|
|
style="width:100%;min-height:500px;font-family:'JetBrains Mono',monospace;font-size:13px;
|
|
background:var(--surface);color:var(--text);border:1px solid var(--border);
|
|
border-radius:4px;padding:12px;resize:vertical;box-sizing:border-box;line-height:1.5"
|
|
spellcheck="false">{{.Content}}</textarea>
|
|
<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:12px">
|
|
<a href="/config-editor?file={{.File}}" class="btn-ghost">Reset</a>
|
|
<button type="submit" class="btn-primary"
|
|
data-confirm="Save {{.File}}?\n\nThe config will be tested with crowdsec -t before applying. If the test fails, the file will be reverted automatically."
|
|
data-confirm-label="Save">Save</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{{else}}
|
|
<div class="panel">
|
|
<div class="empty-state">
|
|
<div class="empty-text">Select a file</div>
|
|
<div class="empty-sub">Choose a YAML file from the list to view and edit it</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
|
|
{{define "scripts"}}
|
|
<script>
|
|
// Tab key inserts spaces in textarea instead of focusing next element
|
|
var ed = document.getElementById('editor');
|
|
if (ed) {
|
|
ed.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Tab') {
|
|
e.preventDefault();
|
|
var s = ed.selectionStart, en = ed.selectionEnd;
|
|
ed.value = ed.value.substring(0, s) + ' ' + ed.value.substring(en);
|
|
ed.selectionStart = ed.selectionEnd = s + 2;
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
{{end}}
|