aboutsummaryrefslogtreecommitdiff
path: root/internal/admin/templates/files.html
blob: b89a142bdb29603859b7c5602ed9d38ad7c07dfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
{{define "body-files"}}
<div class="editor-container">
  <div class="editor-list" id="fileList">
    <div class="search-bar"><input placeholder="Filter files..." oninput="filterFiles(this.value)"></div>
    <div id="listEntries"></div>
  </div>
  <div class="editor-main" id="editorMain">
    <p style="color:#888;text-align:center;margin-top:60px">Select a file to edit</p>
  </div>
</div>
<script>
var currentPath = '';
window._allFiles = [];

function loadFiles(path) {
  currentPath = path || '';
  API.get('/api/files' + (path ? '?path=' + encodeURIComponent(path) : '')).then(function(r){
    var files = r.files || r || [];
    window._allFiles = files;
    renderFileList('');
  }).catch(function(e){notify('Failed: '+e.message,'error')});
}

function renderFileList(filter){
  var el = $('#listEntries');
  var f = filter.toLowerCase();
  var items = window._allFiles.filter(function(x){ return !f || x.name.toLowerCase().indexOf(f) >= 0; });
  var html = '<div class="item" onclick="loadFiles(\'\')" style="color:#6cf">[root]</div>';
  if (currentPath) {
    var parent = currentPath.split('/').slice(0,-1).join('/');
    html += '<div class="item" onclick="loadFiles(\''+escJs(parent)+'\')" style="color:#6cf">[..]</div>';
  }
  items.forEach(function(x){
    if (x.dir) {
      var sub = currentPath ? currentPath + '/' + x.name : x.name;
      html += '<div class="item" onclick="loadFiles(\''+escJs(sub)+'\')" style="color:#fc6">'+escHtml(x.name)+'/</div>';
    } else {
      var fp = currentPath ? currentPath + '/' + x.name : x.name;
      html += '<div class="item" onclick="loadFileContent(\''+escJs(fp)+'\',\''+escJs(x.name)+'\')">'+escHtml(x.name)+'</div>';
    }
  });
  el.innerHTML = html;
}

function filterFiles(val) { renderFileList(val); }

function loadFileContent(path, name) {
  currentPath = path;
  API.get('/api/files?path=' + encodeURIComponent(path)).then(function(r){
    var content = r.content || r.raw || JSON.stringify(r,null,2);
    var html = '<h2>'+escHtml(name)+'</h2>';
    html += '<div class="form-group"><label>Path</label><span style="font-size:11px;color:#888">'+escHtml(path)+'</span></div>';
    html += '<textarea id="fileContent" rows="20" style="width:100%;font-family:monospace;font-size:12px;background:var(--input-bg);color:var(--text);border:1px solid var(--input-border);padding:8px">'+escHtml(content)+'</textarea>';
    html += '<div class="btn-row"><button class="btn btn-primary" onclick="saveFile(\''+escJs(path)+'\')">Save</button></div>';
    $('#editorMain').innerHTML = html;
  }).catch(function(e){notify('Failed: '+e.message,'error')});
}

function saveFile(path) {
  var content = $('#fileContent').value;
  fetch('/api/files?path=' + encodeURIComponent(path), {
    method: 'PUT',
    headers: {'Content-Type': 'text/plain'},
    body: content,
    credentials: 'same-origin'
  }).then(function(r) {
    if (!r.ok) throw new Error('Save failed');
    return r.json();
  }).then(function() {
    notify('File saved', 'success');
    updateUndoBar();
  }).catch(function(e) { notify('Save failed: '+e.message, 'error'); });
}

window.refreshPage = function() { loadFiles(currentPath); };
function escHtml(s) { return String(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;'); }
function escJs(s) { return String(s||'').replace(/\\/g,'\\\\').replace(/'/g,"\\'").replace(/"/g,'\\"'); }

loadFiles('');
</script>
{{end}}