Skip to content

Commit 03fa4c2

Browse files
committed
Working add/update UI for file requests
1 parent c31b147 commit 03fa4c2

File tree

8 files changed

+145
-25
lines changed

8 files changed

+145
-25
lines changed

internal/webserver/web/static/apidocumentation/openapi.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@
10571057
{
10581058
"name": "id",
10591059
"in": "header",
1060-
"description": "The request to be saved. If 0, a new request will be created",
1060+
"description": "The request to be saved. If 0 or empty, a new request will be created",
10611061
"required": false,
10621062
"style": "simple",
10631063
"explode": false,

internal/webserver/web/static/js/admin_ui_allPages.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,15 @@ function handleEditCheckboxChange(checkbox) {
6464
targetElement.setAttribute("disabled", true);
6565
}
6666
}
67+
68+
69+
function getReadableSize(bytes) {
70+
if (!bytes) return "0 B";
71+
const units = ["B", "KB", "MB", "GB", "TB"];
72+
let i = 0;
73+
while (bytes >= 1024 && i < units.length - 1) {
74+
bytes /= 1024;
75+
i++;
76+
}
77+
return `${bytes.toFixed(2)} ${units[i]}`;
78+
}

internal/webserver/web/static/js/admin_ui_filerequest.js

Lines changed: 107 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ function saveFileRequestDefaults() {
7272
function loadFileRequestDefaults() {
7373
const defaultMaxFiles = localStorage.getItem("fr_maxfiles");
7474
const defaultMaxSize = localStorage.getItem("fr_maxsize");
75-
const defaultExpiry = localStorage.getItem("fr_expiry");
75+
let defaultExpiry = localStorage.getItem("fr_expiry");
76+
77+
let defaultDate = new Date(Date.now() + Number((defaultExpiry) * 1000));
78+
defaultDate.setHours(12, 0, 0, 0);
79+
defaultExpiry = Math.floor(defaultDate.getTime() / 1000);
7680

7781
setModalValues(0, "", defaultMaxFiles, defaultMaxSize, defaultExpiry);
7882
}
@@ -113,12 +117,10 @@ function setModalValues(id, name, maxFiles, maxSize, expiry) {
113117
document.getElementById("mi_expiry").value = defaultDate;
114118
createCalendar("mi_expiry", defaultDate);
115119
} else {
116-
let defaultDate = new Date(Date.now() + (expiry * 1000));
117-
defaultDate.setHours(12, 0, 0, 0);
118-
document.getElementById("mi_expiry").value = defaultDate;
120+
document.getElementById("mi_expiry").value = expiry;
119121
document.getElementById("mi_expiry").disabled = false;
120122
document.getElementById("mc_expiry").checked = true;
121-
createCalendar("mi_expiry", Math.floor(defaultDate.getTime() / 1000));
123+
createCalendar("mi_expiry", expiry);
122124
}
123125
}
124126

@@ -156,11 +158,110 @@ function saveFileRequest() {
156158
apiURequestSave(id, name, maxFiles, maxSize, expiry)
157159
.then(data => {
158160
document.getElementById("b_fr_save").disabled = false;
159-
//TODO
161+
insertOrReplaceFileRequest(data);
160162
})
161163
.catch(error => {
162164
alert("Unable to save file request: " + error);
163165
console.error('Error:', error);
164166
document.getElementById("b_fr_save").disabled = false;
165167
});
166168
}
169+
170+
function insertOrReplaceFileRequest(jsonResult) {
171+
const tbody = document.getElementById("filerequesttable");
172+
let row = document.getElementById(`row-${jsonResult.id}`);
173+
174+
if (row) {
175+
const user = document.getElementById(`cell-username-${jsonResult.id}`).innerText;
176+
row.replaceWith(createFileRequestRow(jsonResult, user));
177+
} else {
178+
tbody.appendChild(createFileRequestRow(jsonResult, userName));
179+
}
180+
}
181+
182+
183+
function createFileRequestRow(jsonResult, user) {
184+
185+
function tdText(text) {
186+
const td = document.createElement("td");
187+
td.textContent = text;
188+
return td;
189+
}
190+
191+
function icon(classes) {
192+
const i = document.createElement("i");
193+
i.className = `bi ${classes}`;
194+
return i;
195+
}
196+
197+
198+
const tr = document.createElement("tr");
199+
tr.id = `row-${jsonResult.id}`;
200+
201+
// Name
202+
tr.appendChild(tdText(jsonResult.name));
203+
// Uploaded files / Max files
204+
if (jsonResult.maxfiles == 0) {
205+
tr.appendChild(tdText(jsonResult.uploadedfiles));
206+
} else {
207+
tr.appendChild(tdText(`${jsonResult.uploadedfiles} / ${jsonResult.maxfiles}`));
208+
}
209+
// Total size
210+
tr.appendChild(tdText(getReadableSize(jsonResult.totalfilesize)));
211+
// Last upload
212+
tr.appendChild(tdText(formatTimestampWithNegative(jsonResult.lastupload, "None")));
213+
// Expiry
214+
tr.appendChild(tdText(formatFileRequestExpiry(jsonResult.expiry)));
215+
// Optional user column
216+
if (canViewOtherRequests) {
217+
let userTd = tdText(user);
218+
userTd.id = `cell-username-${jsonResult.id}`;
219+
tr.appendChild(userTd);
220+
}
221+
// Buttons
222+
const td = document.createElement("td");
223+
224+
const group = document.createElement("div");
225+
group.className = "btn-group";
226+
group.role = "group";
227+
228+
// Download
229+
const downloadBtn = document.createElement("button");
230+
downloadBtn.id = `download-${jsonResult.id}`;
231+
downloadBtn.type = "button";
232+
downloadBtn.className = "btn btn-outline-light btn-sm";
233+
downloadBtn.title = "Download all";
234+
235+
if (jsonResult.uploadedfiles == 0) {
236+
downloadBtn.classList.add("disabled");
237+
}
238+
239+
downloadBtn.appendChild(icon("bi-download"));
240+
241+
// Edit
242+
const editBtn = document.createElement("button");
243+
editBtn.id = `edit-${jsonResult.id}`;
244+
editBtn.type = "button";
245+
editBtn.className = "btn btn-outline-light btn-sm";
246+
editBtn.title = "Edit request";
247+
editBtn.onclick = () =>
248+
editFileRequest(jsonResult.id, jsonResult.name, jsonResult.maxfiles, jsonResult.maxsize, jsonResult.expiry);
249+
250+
editBtn.appendChild(icon("bi-pencil"));
251+
252+
// Delete
253+
const deleteBtn = document.createElement("button");
254+
deleteBtn.id = `delete-${jsonResult.id}`;
255+
deleteBtn.type = "button";
256+
deleteBtn.className = "btn btn-outline-danger btn-sm";
257+
deleteBtn.title = "Delete";
258+
deleteBtn.onclick = () =>
259+
deleteOrShowModal(jsonResult.id, jsonResult.name, jsonResult.uploadedfiles);
260+
261+
deleteBtn.appendChild(icon("bi-trash3"));
262+
263+
group.append(downloadBtn, editBtn, deleteBtn);
264+
td.appendChild(group);
265+
tr.appendChild(td);
266+
return tr;
267+
}

internal/webserver/web/static/js/dateformat.js

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,22 @@ function formatUnixTimestamp(unixTimestamp) {
1111
return `${year}-${month}-${day} ${hours}:${minutes}`;
1212
}
1313

14-
function insertFormattedDate(unixTimestamp, id) {
15-
document.getElementById(id).innerText = formatUnixTimestamp(unixTimestamp);
16-
}
17-
18-
function insertDateWithNegative(unixTimestamp, id, negative) {
14+
function formatTimestampWithNegative(unixTimestamp, negative) {
1915
if (negative === undefined) {
2016
negative = "Never";
2117
}
2218
if (unixTimestamp == 0) {
23-
document.getElementById(id).innerText = negative;
24-
return;
19+
return negative;
2520
}
26-
insertFormattedDate(unixTimestamp, id);
21+
return formatUnixTimestamp(unixTimestamp);
22+
}
23+
24+
function insertFormattedDate(unixTimestamp, id) {
25+
document.getElementById(id).innerText = formatUnixTimestamp(unixTimestamp);
26+
}
27+
28+
function insertDateWithNegative(unixTimestamp, id, negative) {
29+
document.getElementById(id).innerText = formatTimestampWithNegative(unixTimestamp, negative);
2730
}
2831

2932
function insertLastOnlineDate(unixTimestamp, id) {
@@ -34,14 +37,17 @@ function insertLastOnlineDate(unixTimestamp, id) {
3437
insertDateWithNegative(unixTimestamp, id);
3538
}
3639

37-
function insertFileRequestExpiry(unixTimestamp, id) {
40+
function formatFileRequestExpiry(unixTimestamp) {
3841
if (unixTimestamp == 0) {
39-
document.getElementById(id).innerText = "Never";
40-
return;
42+
return "Never";
4143
}
4244
if ((Date.now() / 1000) > unixTimestamp) {
43-
document.getElementById(id).innerText = "Expired";
44-
return;
45+
return "Expired";
4546
}
46-
insertFormattedDate(unixTimestamp, id);
47+
return formatUnixTimestamp(unixTimestamp);
48+
}
49+
50+
function insertFileRequestExpiry(unixTimestamp, id) {
51+
document.getElementById(id).innerText = formatFileRequestExpiry(unixTimestamp);
52+
4753
}

internal/webserver/web/static/js/min/admin.min.15.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/webserver/web/static/js/min/dateformat.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/webserver/web/templates/html_uploadrequest.tmpl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
<script>insertFileRequestExpiry({{ .Expiry }}, "cell-expiry-{{ .Id }}");</script>
5252

5353
{{ if $.ActiveUser.HasPermissionListOtherUploads }}
54-
<td>{{(index $.UserMap .UserId).Name}}</td>
54+
<td id="cell-username-{{ .Id }}">{{(index $.UserMap .UserId).Name}}</td>
5555
{{ end }}
5656
<td>
5757
<div class="btn-group" role="group">
@@ -77,6 +77,7 @@
7777
<script src="./js/min/admin.min.{{ template "js_admin_version"}}.js"></script>
7878
<script>
7979
var userName = "{{.ActiveUser.Name}}";
80+
var canViewOtherRequests = {{.ActiveUser.HasPermissionListOtherUploads }};
8081
</script>
8182

8283

openapi.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@
10571057
{
10581058
"name": "id",
10591059
"in": "header",
1060-
"description": "The request to be saved. If 0, a new request will be created",
1060+
"description": "The request to be saved. If 0 or empty, a new request will be created",
10611061
"required": false,
10621062
"style": "simple",
10631063
"explode": false,

0 commit comments

Comments
 (0)