apps/blobs/templates/browse.html 3.3 K raw
1
{{define "browse.html"}}{{template "base.html" .}}{{end}}
2
{{define "title"}}{{.Bucket}}/{{.Prefix}}{{end}}
3
{{define "content"}}
4
  <nav class="crumbs">
5
    <a href="/buckets">buckets</a>
6
    {{range .Crumbs}}<span class="crumb-sep">/</span><a href="{{.Href}}">{{.Label}}</a>{{end}}
7
    <span class="crumb-sep">/</span>
8
  </nav>
9
10
  {{if .Error}}<p class="error">{{.Error}}</p>{{end}}
11
  {{if .Success}}<p class="success">{{.Success}}</p>{{end}}
12
13
  <div class="search-row">
14
    <input type="search" id="filter" placeholder="filter folders + files in this view…" autocomplete="off">
15
    <span class="filter-count" id="filter-count"></span>
16
  </div>
17
18
  <div class="actions-row">
19
    <form method="POST" action="/b/{{.Bucket}}/upload" enctype="multipart/form-data" class="form inline-actions">
20
      <input type="hidden" name="prefix" value="{{.Prefix}}">
21
      <label for="file">upload (max {{.MaxUploadMB}}MB, multiple allowed)</label>
22
      <input type="file" id="file" name="file" multiple required>
23
      <button type="submit">upload</button>
24
    </form>
25
26
    <form method="POST" action="/b/{{.Bucket}}/mkdir" class="form inline-actions">
27
      <input type="hidden" name="prefix" value="{{.Prefix}}">
28
      <label for="name">new folder</label>
29
      <input type="text" id="name" name="name" placeholder="folder-name" required>
30
      <button type="submit">create</button>
31
    </form>
32
  </div>
33
34
  {{if and (not .Folders) (not .Files) (not .ParentHref)}}
35
    <p class="empty">empty bucket</p>
36
  {{end}}
37
38
  <div class="admin-list" id="entry-list">
39
    {{if .ParentHref}}
40
      <a href="{{.ParentHref}}" class="admin-list-item" data-parent="1">
41
        <div class="admin-list-info">
42
          <span class="admin-list-title">../</span>
43
        </div>
44
      </a>
45
    {{end}}
46
    {{range .Folders}}
47
      <a href="{{.Href}}" class="admin-list-item" data-name="{{.Name}}">
48
        <div class="admin-list-info">
49
          <span class="admin-list-title">{{.Name}}/</span>
50
        </div>
51
      </a>
52
    {{end}}
53
    {{range .Files}}
54
      <a href="{{.DetailHref}}" class="admin-list-item" data-name="{{.Name}}">
55
        {{if .IsImage}}<img src="{{.PreviewSrc}}" class="file-thumbnail" alt="{{.Name}}" loading="lazy">{{end}}
56
        <div class="admin-list-info">
57
          <span class="admin-list-title">{{.Name}}</span>
58
          <div class="admin-list-meta">
59
            <span class="admin-list-date">{{.SizeHuman}}</span>
60
            <span class="admin-list-date">{{.LastModified}}</span>
61
          </div>
62
        </div>
63
      </a>
64
    {{end}}
65
  </div>
66
67
  <script>
68
    (function () {
69
      var input = document.getElementById('filter');
70
      var list = document.getElementById('entry-list');
71
      var count = document.getElementById('filter-count');
72
      if (!input || !list) return;
73
      var items = list.querySelectorAll('.admin-list-item[data-name]');
74
      var total = items.length;
75
      function apply() {
76
        var q = input.value.trim().toLowerCase();
77
        var shown = 0;
78
        items.forEach(function (el) {
79
          var name = (el.getAttribute('data-name') || '').toLowerCase();
80
          var match = q === '' || name.indexOf(q) !== -1;
81
          el.style.display = match ? '' : 'none';
82
          if (match) shown++;
83
        });
84
        count.textContent = q ? shown + ' / ' + total : '';
85
      }
86
      input.addEventListener('input', apply);
87
    })();
88
  </script>
89
{{end}}