Improve files page design and accessibility
This commit is contained in:
parent
6e58023429
commit
b5e038ebe7
|
@ -21,6 +21,11 @@
|
||||||
.button.is-danger {
|
.button.is-danger {
|
||||||
--bulma-button-background-l-delta: 35%;
|
--bulma-button-background-l-delta: 35%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.panel.is-danger {
|
||||||
|
--bulma-panel-heading-background-l: 65%;
|
||||||
|
--bulma-panel-s: 80%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
|
@ -32,16 +32,13 @@ const updateSelection = (event) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const purgeExpired = () => {
|
const purgeExpired = () => {
|
||||||
const files = JSON.parse(localStorage.getItem(`${prefix}files`));
|
const deletedItemsDOM = document.getElementById("deleted-items-table");
|
||||||
|
|
||||||
files.forEach((file) => {
|
for (let i = 0; i < deletedItemsDOM.children.length; i++) {
|
||||||
const fileDOM = document.querySelector(`.item-${file.short}`);
|
deleteFromStorage(deletedItemsDOM.children[i].dataset.serverKey);
|
||||||
|
}
|
||||||
|
|
||||||
if (fileDOM?.classList.contains("deleted")) {
|
deletedItemsDOM.replaceChildren();
|
||||||
deleteFromStorage(file.short);
|
|
||||||
fileDOM.remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportStorage = () => {
|
const exportStorage = () => {
|
||||||
|
@ -135,6 +132,35 @@ const deleteSelection = () => {
|
||||||
|
|
||||||
const populateFilesTable = () => {
|
const populateFilesTable = () => {
|
||||||
const itemsTableDOM = document.getElementById("items-table");
|
const itemsTableDOM = document.getElementById("items-table");
|
||||||
|
const deletedItemsDOM = document.getElementById("deleted-items-table");
|
||||||
|
|
||||||
|
const addDeletedItem = (file) => {
|
||||||
|
const deletedItemDOM = document
|
||||||
|
.querySelector("template#deleted-item")
|
||||||
|
.content.cloneNode(true).children[0];
|
||||||
|
|
||||||
|
deletedItemDOM.dataset.serverKey = file.short;
|
||||||
|
deletedItemDOM.querySelector(".name").innerText = file.name;
|
||||||
|
deletedItemDOM
|
||||||
|
.querySelector(".delete-at-first-view .icon")
|
||||||
|
.classList.add(file.del_at_first_view ? "fa-eraser" : "fa-close");
|
||||||
|
deletedItemDOM
|
||||||
|
.querySelector(".delete-at-first-view .icon")
|
||||||
|
.setAttribute("title", file.del_at_first_view ? i18n.yes : i18n.no);
|
||||||
|
|
||||||
|
deletedItemDOM.querySelector(".created-at").innerText = formatDate(
|
||||||
|
file.created_at
|
||||||
|
);
|
||||||
|
deletedItemDOM.querySelector(".expires-at").innerText =
|
||||||
|
file.delay == 0
|
||||||
|
? i18n.noExpiration
|
||||||
|
: formatDate(file.delay * 86400 + file.created_at);
|
||||||
|
|
||||||
|
deletedItemDOM.querySelector(".counter").innerText = file.counter;
|
||||||
|
|
||||||
|
deletedItemsDOM.append(deletedItemDOM);
|
||||||
|
};
|
||||||
|
|
||||||
itemsTableDOM.replaceChildren();
|
itemsTableDOM.replaceChildren();
|
||||||
|
|
||||||
let files = localStorage.getItem(`${prefix}files`);
|
let files = localStorage.getItem(`${prefix}files`);
|
||||||
|
@ -175,6 +201,9 @@ const populateFilesTable = () => {
|
||||||
itemDOM
|
itemDOM
|
||||||
.querySelector(".delete-at-first-view .icon")
|
.querySelector(".delete-at-first-view .icon")
|
||||||
.classList.add(file.del_at_first_view ? "fa-eraser" : "fa-close");
|
.classList.add(file.del_at_first_view ? "fa-eraser" : "fa-close");
|
||||||
|
itemDOM
|
||||||
|
.querySelector(".delete-at-first-view .icon")
|
||||||
|
.setAttribute("title", file.del_at_first_view ? i18n.yes : i18n.no);
|
||||||
itemDOM.querySelector(".created-at").innerText = formatDate(
|
itemDOM.querySelector(".created-at").innerText = formatDate(
|
||||||
file.created_at
|
file.created_at
|
||||||
);
|
);
|
||||||
|
@ -220,13 +249,19 @@ const populateFilesTable = () => {
|
||||||
countDOM.innerText = data.counter;
|
countDOM.innerText = data.counter;
|
||||||
|
|
||||||
if (data.deleted) {
|
if (data.deleted) {
|
||||||
countDOM.parentElement.classList.add("deleted");
|
file.counter = data.counter;
|
||||||
|
|
||||||
|
addDeletedItem(file);
|
||||||
|
countDOM.parentElement.remove();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert(data.msg);
|
|
||||||
countDOM.parentElement.remove();
|
countDOM.parentElement.remove();
|
||||||
|
|
||||||
if (data.missing) {
|
if (data.missing) {
|
||||||
|
console.log(
|
||||||
|
`$(data.name) ($(data.short)) is missing. Removing it from Storage.`
|
||||||
|
);
|
||||||
|
|
||||||
deleteFromStorage(data.short);
|
deleteFromStorage(data.short);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,48 +9,74 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="buttons">
|
<article class="panel is-info">
|
||||||
|
<h2 class="panel-heading"><%= l('Uploaded files') %></h2>
|
||||||
|
|
||||||
|
<div class="buttons panel-block">
|
||||||
<button id="action-delete-selection" type="button" class="button is-danger" disabled="disabled">
|
<button id="action-delete-selection" type="button" class="button is-danger" disabled="disabled">
|
||||||
<span class="icon-text">
|
<span class="icon-text">
|
||||||
<span class="icon fas fa-trash"></span>
|
<span class="icon fas fa-trash"></span>
|
||||||
<span><%= l('Delete selected files') %></span>
|
<span><%= l('Delete selected files') %></span>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button id="action-purge-expired" type="button" class="button">
|
|
||||||
<span class="icon-text">
|
|
||||||
<span class="icon fas fa-recycle"></span>
|
|
||||||
<span><%= l('Purge expired files') %></span>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-container">
|
<div class="panel-block table-container files-table mb-6">
|
||||||
<table class="table is-stripped is-hoverable">
|
<table class="table is-stripped is-hoverable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="has-text-centered">
|
<th class="has-text-centered">
|
||||||
<div><%= l('Selection') %></div>
|
<div><%= l('Selection') %></div>
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<input type="checkbox" id="action-select-all">
|
<input type="checkbox" id="action-select-all" aria-label="<%= l('Select All')%>">
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="has-text-centered"><%= l('File name') %></th>
|
<th class="has-text-centered is-vcentered"><%= l('File name') %></th>
|
||||||
<th class="has-text-centered"><%= l('Access nb') %></th>
|
<th class="has-text-centered is-vcentered is-narrow"><%= l('Access nb') %></th>
|
||||||
<th class="has-text-centered"><%= l('Delete at first download?') %></th>
|
<th class="has-text-centered is-vcentered is-narrow"><abbr title="<%= l('Delete at first download?') %>"><%= l('Delete after download') %></abbr></th>
|
||||||
<th class="has-text-centered"><%= l('Uploaded at') %></th>
|
<th class="has-text-centered is-vcentered"><%= l('Uploaded at') %></th>
|
||||||
<th class="has-text-centered"><%= l('Expires at') %></th>
|
<th class="has-text-centered is-vcentered"><%= l('Expires at') %></th>
|
||||||
<th class="has-text-centered"><%= l('Download link') %></th>
|
<th class="has-text-centered is-vcentered"><%= l('Download') %></th>
|
||||||
<th class="has-text-centered"><%= l('Share link') %></th>
|
<th class="has-text-centered is-vcentered"><%= l('Share') %></th>
|
||||||
<th class="has-text-centered"><%= l('Deletion link') %></th>
|
<th class="has-text-centered is-vcentered"><%= l('Delete') %></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody id="items-table"></tbody>
|
<tbody id="items-table" class="has-text-centered"></tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
<div class="buttons">
|
<article class="panel is-danger">
|
||||||
|
<h2 class="panel-heading"><%= l('Expired files') %></h2>
|
||||||
|
|
||||||
|
<div class="panel-block buttons">
|
||||||
|
<button id="action-purge-expired" type="button" class="button">
|
||||||
|
<span class="icon-text">
|
||||||
|
<span class="icon fas fa-recycle"></span>
|
||||||
|
<span><%= l('Remore expired files from browser history') %></span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-block table-container deleted-files-table mb-6">
|
||||||
|
<table class="table is-stripped is-hoverable is-fullwidth">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="has-text-centered is-vcentered"><%= l('File name') %></th>
|
||||||
|
<th class="has-text-centered is-vcentered"><%= l('Access nb') %></th>
|
||||||
|
<th class="has-text-centered is-vcentered is-narrow"><abbr title="<%= l('Delete at first download?') %>"><%= l('Delete at first download') %></abbr></th>
|
||||||
|
<th class="has-text-centered is-vcentered"><%= l('Uploaded at') %></th>
|
||||||
|
<th class="has-text-centered is-vcentered"><%= l('Expires at') %></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody id="deleted-items-table" class="has-text-centered"></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<div class="buttons is-justify-content-center">
|
||||||
<a id="action-export-storage" href="#" class="button">
|
<a id="action-export-storage" href="#" class="button">
|
||||||
<span class="icon-text">
|
<span class="icon-text">
|
||||||
<span class="icon fas fa-download"></span>
|
<span class="icon fas fa-download"></span>
|
||||||
|
@ -89,7 +115,7 @@
|
||||||
<td class="created-at is-vcentered"></td>
|
<td class="created-at is-vcentered"></td>
|
||||||
<td class="expires-at is-vcentered"></td>
|
<td class="expires-at is-vcentered"></td>
|
||||||
<td class="download is-vcentered">
|
<td class="download is-vcentered">
|
||||||
<a title="<%= l('Download') %>" href="#">
|
<a href="#">
|
||||||
<span class="icon-text is-justify-content-center">
|
<span class="icon-text is-justify-content-center">
|
||||||
<span class="icon fas fa-download" aria-hidden="true"></span>
|
<span class="icon fas fa-download" aria-hidden="true"></span>
|
||||||
<span><%= l('Download') %></span>
|
<span><%= l('Download') %></span>
|
||||||
|
@ -105,7 +131,7 @@
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="deletion is-vcentered">
|
<td class="deletion is-vcentered">
|
||||||
<a class="action-delete-item" title="<%= l('Delete') %>" href="#">
|
<a class="action-delete-item" href="#">
|
||||||
<span class="icon-text is-justify-content-center">
|
<span class="icon-text is-justify-content-center">
|
||||||
<span class="icon fas fa-trash" aria-hidden="true"></span>
|
<span class="icon fas fa-trash" aria-hidden="true"></span>
|
||||||
<span><%= l('Delete') %></span>
|
<span><%= l('Delete') %></span>
|
||||||
|
@ -115,6 +141,21 @@
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template id="deleted-item">
|
||||||
|
<tr class="item">
|
||||||
|
<td class="name is-vcentered"></td>
|
||||||
|
<td class="counter is-vcentered"></td>
|
||||||
|
<td class="delete-at-first-view is-vcentered has-text-centered">
|
||||||
|
<span class="icon-text is-justify-content-center">
|
||||||
|
<span class="icon fas"></span>
|
||||||
|
<span class="text"></span>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="created-at is-vcentered"></td>
|
||||||
|
<td class="expires-at is-vcentered"></td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
% if (defined($self->config('fixed_domain')) && $self->config('fixed_domain')) {
|
% if (defined($self->config('fixed_domain')) && $self->config('fixed_domain')) {
|
||||||
const baseURL = '<%= url_for('/')->host($self->config('fixed_domain'))->to_abs() %>';
|
const baseURL = '<%= url_for('/')->host($self->config('fixed_domain'))->to_abs() %>';
|
||||||
|
@ -126,9 +167,11 @@ const actionURL = '<%= url_for('/')->to_abs() %>';
|
||||||
const counterURL = '<%== url_for('counter') %>';
|
const counterURL = '<%== url_for('counter') %>';
|
||||||
|
|
||||||
const i18n = {
|
const i18n = {
|
||||||
|
no: '<%= l('No') %>',
|
||||||
noExpiration: '<%= l('No expiration delay') %>',
|
noExpiration: '<%= l('No expiration delay') %>',
|
||||||
importProcessed: '<%= l('The data has been successfully imported.') %>',
|
importProcessed: '<%= l('The data has been successfully imported.') %>',
|
||||||
importFilesWithoutPrefix: "<%= l('Lufi recently changed its way to store files information.\n\nNo files have been found in the new localStorage location but we found files in the old one.\nDo you want to import those informations?\n\nPlease note that this is the only time that we will ask you this.') %>",
|
importFilesWithoutPrefix: "<%= l('Lufi recently changed its way to store files information.\n\nNo files have been found in the new localStorage location but we found files in the old one.\nDo you want to import those informations?\n\nPlease note that this is the only time that we will ask you this.') %>",
|
||||||
|
yes: '<%= l('yes') %>'
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
%= javascript '/js/minified/files.min.js', type => "module", defer => "true"
|
%= javascript '/js/minified/files.min.js', type => "module", defer => "true"
|
||||||
|
|
Loading…
Reference in New Issue