feat(boxstore): add retention options and box deletion support
Introduce configurable retention options and default selection, store retention when creating manifests, and add a helper to delete box directories to enable expiring/cleanup workflows. Update login and upload styles (new login layout, taller upload window) to support the new UI.feat(boxstore): add retention options and box deletion support Introduce configurable retention options and default selection, store retention when creating manifests, and add a helper to delete box directories to enable expiring/cleanup workflows. Update login and upload styles (new login layout, taller upload window) to support the new UI.
This commit is contained in:
@@ -59,6 +59,7 @@ label[for],
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="file"],
|
||||
textarea,
|
||||
[contenteditable="true"] {
|
||||
|
||||
@@ -27,6 +27,19 @@
|
||||
line-height: 13px;
|
||||
}
|
||||
|
||||
.box-meta {
|
||||
display: grid;
|
||||
grid-template-columns: 58px minmax(0, 1fr);
|
||||
align-items: center;
|
||||
height: 24px;
|
||||
box-sizing: border-box;
|
||||
padding: 0 8px 6px;
|
||||
gap: 6px;
|
||||
color: #333333;
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
.box-address code {
|
||||
min-width: 0;
|
||||
height: 22px;
|
||||
|
||||
127
static/css/login.css
Normal file
127
static/css/login.css
Normal file
@@ -0,0 +1,127 @@
|
||||
.login-window {
|
||||
width: 420px;
|
||||
height: 248px;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.login-panel {
|
||||
flex: 1;
|
||||
margin: 8px;
|
||||
padding: 12px;
|
||||
background: #c0c0c0;
|
||||
}
|
||||
|
||||
.login-alert {
|
||||
display: grid;
|
||||
grid-template-columns: 34px minmax(0, 1fr);
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
min-height: 48px;
|
||||
margin-bottom: 12px;
|
||||
font-size: 13px;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
.login-alert img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
object-fit: contain;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
.login-alert p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.login-row {
|
||||
display: grid;
|
||||
grid-template-columns: 82px minmax(0, 1fr);
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 13px;
|
||||
line-height: 13px;
|
||||
}
|
||||
|
||||
.login-input {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
box-sizing: border-box;
|
||||
padding: 2px 5px;
|
||||
color: #000000;
|
||||
background: #ffffff;
|
||||
border-top: 1px solid #808080;
|
||||
border-left: 1px solid #808080;
|
||||
border-right: 1px solid #ffffff;
|
||||
border-bottom: 1px solid #ffffff;
|
||||
font-family: inherit;
|
||||
font-size: 13px;
|
||||
line-height: 13px;
|
||||
}
|
||||
|
||||
.login-input[readonly] {
|
||||
color: #555555;
|
||||
background: #dfdfdf;
|
||||
}
|
||||
|
||||
.login-error {
|
||||
margin: 2px 0 0 90px;
|
||||
color: #800000;
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
.login-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
height: 40px;
|
||||
box-sizing: border-box;
|
||||
padding: 0 8px 8px;
|
||||
}
|
||||
|
||||
.login-actions .win98-button {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.login-statusbar {
|
||||
grid-template-columns: 1fr 96px;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
main {
|
||||
display: block;
|
||||
min-height: 100dvh;
|
||||
}
|
||||
|
||||
.login-window {
|
||||
width: 100vw;
|
||||
height: 100dvh;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.login-titlebar {
|
||||
height: 24px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.login-panel {
|
||||
margin: 8px 6px;
|
||||
}
|
||||
|
||||
.login-row {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.login-error {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
.upload-window {
|
||||
width: 520px;
|
||||
height: 486px;
|
||||
height: 566px;
|
||||
}
|
||||
|
||||
.upload-form {
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
.upload-dropzone {
|
||||
flex: 0 0 auto;
|
||||
height: 118px;
|
||||
height: 88px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -34,6 +34,76 @@
|
||||
border: 1px dotted #000000;
|
||||
}
|
||||
|
||||
.upload-options {
|
||||
flex: 0 0 auto;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 6px 10px;
|
||||
box-sizing: border-box;
|
||||
margin: 10px 0 0;
|
||||
padding: 8px 8px 10px;
|
||||
background: #dfdfdf;
|
||||
border-top: 1px solid #ffffff;
|
||||
border-left: 1px solid #ffffff;
|
||||
border-right: 1px solid #808080;
|
||||
border-bottom: 1px solid #808080;
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
.upload-options legend {
|
||||
padding: 0 4px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.upload-option-row {
|
||||
grid-column: 1 / 3;
|
||||
display: grid;
|
||||
grid-template-columns: 76px minmax(0, 1fr);
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.upload-check-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
gap: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.upload-check-row input {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.upload-select,
|
||||
.upload-text-input {
|
||||
width: 100%;
|
||||
height: 22px;
|
||||
box-sizing: border-box;
|
||||
padding: 1px 4px;
|
||||
color: #000000;
|
||||
background: #ffffff;
|
||||
border-top: 1px solid #808080;
|
||||
border-left: 1px solid #808080;
|
||||
border-right: 1px solid #ffffff;
|
||||
border-bottom: 1px solid #ffffff;
|
||||
font-family: inherit;
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
}
|
||||
|
||||
.upload-text-input {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.upload-text-input:disabled {
|
||||
color: #808080;
|
||||
background: #c0c0c0;
|
||||
}
|
||||
|
||||
.upload-dropzone.is-dragging {
|
||||
background: #c7d8f2;
|
||||
outline: 2px solid #000078;
|
||||
@@ -119,7 +189,6 @@
|
||||
min-height: 0;
|
||||
margin-top: 8px;
|
||||
overflow-y: auto;
|
||||
color: #fff;
|
||||
border-top: 2px solid #808080;
|
||||
border-left: 2px solid #808080;
|
||||
border-right: 2px solid #ffffff;
|
||||
@@ -367,11 +436,20 @@
|
||||
}
|
||||
|
||||
.upload-dropzone {
|
||||
height: 126px;
|
||||
min-height: 126px;
|
||||
height: 96px;
|
||||
min-height: 96px;
|
||||
}
|
||||
|
||||
.upload-result {
|
||||
grid-template-columns: 64px minmax(0, 1fr) 68px;
|
||||
}
|
||||
|
||||
.upload-options {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.upload-option-row,
|
||||
.upload-text-input {
|
||||
grid-column: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@ const boxLink = document.querySelector("#upload-box-link");
|
||||
const shareButton = document.querySelector("#upload-share-button");
|
||||
const overallProgressBar = document.querySelector(".upload-overall-bar");
|
||||
const overallProgressPercent = document.querySelector(".upload-overall-percent");
|
||||
const retentionSelect = document.querySelector("#upload-retention");
|
||||
const passwordEnabled = document.querySelector("#upload-password-enabled");
|
||||
const passwordInput = document.querySelector("#upload-password");
|
||||
const zipEnabled = document.querySelector("#upload-zip-enabled");
|
||||
|
||||
let selectedFiles = [];
|
||||
let statusTimer = null;
|
||||
@@ -194,6 +198,9 @@ async function createBox() {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
retention_key: retentionSelect ? retentionSelect.value : "10s",
|
||||
password: passwordEnabled && passwordEnabled.checked && passwordInput ? passwordInput.value : "",
|
||||
allow_zip: !zipEnabled || zipEnabled.checked,
|
||||
files: selectedFiles.map((selectedFile) => ({
|
||||
name: selectedFile.file.name,
|
||||
size: selectedFile.file.size,
|
||||
@@ -307,6 +314,18 @@ if (fileInput) {
|
||||
});
|
||||
}
|
||||
|
||||
if (passwordEnabled && passwordInput) {
|
||||
passwordEnabled.addEventListener("change", () => {
|
||||
passwordInput.disabled = !passwordEnabled.checked;
|
||||
if (!passwordEnabled.checked) {
|
||||
passwordInput.value = "";
|
||||
return;
|
||||
}
|
||||
|
||||
passwordInput.focus();
|
||||
});
|
||||
}
|
||||
|
||||
if (fileInput && dropzone) {
|
||||
dropzone.addEventListener("dragover", (event) => {
|
||||
event.preventDefault();
|
||||
@@ -340,6 +359,12 @@ if (uploadForm) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (passwordEnabled && passwordEnabled.checked && passwordInput && !passwordInput.value.trim()) {
|
||||
updateStatus("Enter password");
|
||||
passwordInput.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
let completedCount = 0;
|
||||
const totalCount = selectedFiles.length;
|
||||
const statusPrefix = () => `${completedCount}/${totalCount}`;
|
||||
|
||||
Reference in New Issue
Block a user