mirror of
https://github.com/System-End/cdn.git
synced 2026-04-19 16:18:17 +00:00
plz no lookie shit
This commit is contained in:
parent
cec596e620
commit
6567d71ce8
3 changed files with 77 additions and 43 deletions
|
|
@ -26,7 +26,7 @@ class Components::Uploads::Row < Components::Base
|
|||
|
||||
def compact_content
|
||||
div(style: "flex: 1; min-width: 0;") do
|
||||
div(style: "font-size: 14px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;") do
|
||||
div(style: "font-size: 14px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer;", data: { batch_select_toggle: upload.id }) do
|
||||
render Primer::Beta::Octicon.new(icon: file_icon_for(upload.content_type), size: :small, mr: 1)
|
||||
plain upload.filename.to_s
|
||||
end
|
||||
|
|
@ -50,7 +50,7 @@ class Components::Uploads::Row < Components::Base
|
|||
div(style: "flex: 1; min-width: 0;") do
|
||||
div(style: "display: flex; align-items: center; gap: 8px; margin-bottom: 8px; min-width: 0;") do
|
||||
render Primer::Beta::Octicon.new(icon: file_icon_for(upload.content_type), size: :small)
|
||||
div(style: "flex: 1; min-width: 0; font-size: 14px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;") do
|
||||
div(style: "flex: 1; min-width: 0; font-size: 14px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer;", data: { batch_select_toggle: upload.id }) do
|
||||
plain upload.filename.to_s
|
||||
end
|
||||
render(Primer::Beta::Label.new(scheme: :secondary)) { plain upload.provenance.titleize }
|
||||
|
|
@ -99,20 +99,13 @@ class Components::Uploads::Row < Components::Base
|
|||
|
||||
def file_icon_for(content_type)
|
||||
case content_type
|
||||
when /image/
|
||||
:image
|
||||
when /video/
|
||||
:video
|
||||
when /audio/
|
||||
:unmute
|
||||
when /pdf/
|
||||
:file
|
||||
when /zip|rar|tar|gz/
|
||||
:"file-zip"
|
||||
when /text|json|xml/
|
||||
:code
|
||||
else
|
||||
:file
|
||||
when /image/ then :image
|
||||
when /video/ then :video
|
||||
when /audio/ then :unmute
|
||||
when /pdf/ then :file
|
||||
when /zip|rar|tar|gz/ then :"file-zip"
|
||||
when /text|json|xml/ then :code
|
||||
else :file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ class Components::Uploads::Index < Components::Base
|
|||
|
||||
def uploads_list
|
||||
if uploads.any?
|
||||
# Select all toggle
|
||||
div(style: "display: flex; align-items: center; gap: 8px; margin-bottom: 8px; padding: 4px 0;") do
|
||||
input(
|
||||
type: "checkbox",
|
||||
|
|
@ -88,8 +87,7 @@ class Components::Uploads::Index < Components::Base
|
|||
name: "ids[]",
|
||||
value: upload.id,
|
||||
form: "batch-delete-form",
|
||||
class: "batch-select-checkbox",
|
||||
data: { batch_select_item: true },
|
||||
data: { batch_select_item: true, upload_id: upload.id },
|
||||
style: "margin-top: 6px; cursor: pointer;"
|
||||
)
|
||||
div(style: "flex: 1; min-width: 0;") do
|
||||
|
|
@ -133,16 +131,15 @@ class Components::Uploads::Index < Components::Base
|
|||
end
|
||||
|
||||
def batch_delete_bar
|
||||
div(id: "batch-delete-bar", data: { batch_bar: true }, style: "display: none; position: fixed; bottom: 0; left: 0; right: 0; background: var(--bgColor-danger-muted, #FFEBE9); border-top: 1px solid var(--borderColor-danger-muted, #ffcecb); padding: 12px 24px; z-index: 100;") do
|
||||
div(style: "max-width: 1200px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center;") do
|
||||
span(data: { batch_count: true }, style: "font-size: 14px; font-weight: 500;") { "0 files selected" }
|
||||
div(style: "display: flex; gap: 8px;") do
|
||||
button(type: "button", data: { batch_deselect: true }, class: "btn btn-sm") { "Deselect all" }
|
||||
form_with url: destroy_batch_uploads_path, method: :delete, id: "batch-delete-form", data: { turbo_confirm: "Are you sure you want to delete the selected files? This cannot be undone." } do
|
||||
button(type: "submit", class: "btn btn-sm btn-danger") do
|
||||
render Primer::Beta::Octicon.new(icon: :trash, mr: 1)
|
||||
plain "Delete selected"
|
||||
end
|
||||
div(id: "batch-delete-bar", data: { batch_bar: true }, style: "display: none; position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); background: var(--bgColor-default, #fff); border: 1px solid var(--borderColor-default, #d0d7de); border-radius: 12px; padding: 12px 20px; z-index: 100; box-shadow: 0 8px 24px rgba(0,0,0,0.12); min-width: 320px; max-width: 600px;") do
|
||||
div(style: "display: flex; align-items: center; gap: 16px;") do
|
||||
span(data: { batch_count: true }, style: "font-size: 14px; font-weight: 600; white-space: nowrap;") { "0 selected" }
|
||||
div(style: "flex: 1;")
|
||||
button(type: "button", data: { batch_deselect: true }, class: "btn btn-sm", style: "white-space: nowrap;") { "Deselect" }
|
||||
form_with url: destroy_batch_uploads_path, method: :delete, id: "batch-delete-form", data: { batch_delete_form: true } do
|
||||
button(type: "submit", class: "btn btn-sm btn-danger", style: "white-space: nowrap;") do
|
||||
render Primer::Beta::Octicon.new(icon: :trash, mr: 1)
|
||||
plain "Delete"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
const bar = document.querySelector("[data-batch-bar]");
|
||||
const countLabel = document.querySelector("[data-batch-count]");
|
||||
const deselectBtn = document.querySelector("[data-batch-deselect]");
|
||||
const deleteForm = document.querySelector("[data-batch-delete-form]");
|
||||
|
||||
if (!bar) return;
|
||||
|
||||
|
|
@ -11,20 +12,19 @@
|
|||
return document.querySelectorAll("[data-batch-select-item]");
|
||||
}
|
||||
|
||||
function getChecked() {
|
||||
return Array.from(getCheckboxes()).filter((cb) => cb.checked);
|
||||
}
|
||||
|
||||
function updateBar() {
|
||||
const checkboxes = getCheckboxes();
|
||||
const checked = Array.from(checkboxes).filter((cb) => cb.checked);
|
||||
const checked = getChecked();
|
||||
const count = checked.length;
|
||||
|
||||
if (count > 0) {
|
||||
bar.style.display = "block";
|
||||
countLabel.textContent =
|
||||
count + (count === 1 ? " file selected" : " files selected");
|
||||
} else {
|
||||
bar.style.display = "none";
|
||||
}
|
||||
bar.style.display = count > 0 ? "block" : "none";
|
||||
countLabel.textContent =
|
||||
count + (count === 1 ? " file selected" : " files selected");
|
||||
|
||||
// Sync "select all" checkbox
|
||||
if (selectAll) {
|
||||
selectAll.checked =
|
||||
checkboxes.length > 0 && checked.length === checkboxes.length;
|
||||
|
|
@ -33,14 +33,29 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Listen for individual checkbox changes
|
||||
// Individual checkbox changes
|
||||
document.addEventListener("change", (e) => {
|
||||
if (e.target.matches("[data-batch-select-item]")) {
|
||||
updateBar();
|
||||
}
|
||||
});
|
||||
|
||||
// Select all / deselect all toggle
|
||||
// Click filename to toggle its checkbox
|
||||
document.addEventListener("click", (e) => {
|
||||
const toggle = e.target.closest("[data-batch-select-toggle]");
|
||||
if (!toggle) return;
|
||||
|
||||
const uploadId = toggle.dataset.batchSelectToggle;
|
||||
const checkbox = document.querySelector(
|
||||
'[data-batch-select-item][data-upload-id="' + uploadId + '"]',
|
||||
);
|
||||
if (checkbox) {
|
||||
checkbox.checked = !checkbox.checked;
|
||||
updateBar();
|
||||
}
|
||||
});
|
||||
|
||||
// Select all toggle
|
||||
if (selectAll) {
|
||||
selectAll.addEventListener("change", () => {
|
||||
const checkboxes = getCheckboxes();
|
||||
|
|
@ -51,17 +66,46 @@
|
|||
});
|
||||
}
|
||||
|
||||
// Deselect all button in the bar
|
||||
// Deselect all button
|
||||
if (deselectBtn) {
|
||||
deselectBtn.addEventListener("click", () => {
|
||||
const checkboxes = getCheckboxes();
|
||||
checkboxes.forEach((cb) => {
|
||||
getCheckboxes().forEach((cb) => {
|
||||
cb.checked = false;
|
||||
});
|
||||
if (selectAll) selectAll.checked = false;
|
||||
updateBar();
|
||||
});
|
||||
}
|
||||
|
||||
// Confirmation before batch delete
|
||||
if (deleteForm) {
|
||||
deleteForm.addEventListener("submit", (e) => {
|
||||
const checked = getChecked();
|
||||
if (checked.length === 0) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
// Build a list of filenames from the row next to each checkbox
|
||||
const names = checked.map((cb) => {
|
||||
const row = cb.closest("[class*='BorderBox']") || cb.parentElement;
|
||||
const nameEl = row.querySelector("[data-batch-select-toggle]");
|
||||
return nameEl ? nameEl.textContent.trim() : cb.value;
|
||||
});
|
||||
|
||||
const message =
|
||||
"Delete " +
|
||||
checked.length +
|
||||
(checked.length === 1 ? " file" : " files") +
|
||||
"?\n\n" +
|
||||
names.map((n) => " • " + n).join("\n") +
|
||||
"\n\nThis cannot be undone.";
|
||||
|
||||
if (!confirm(message)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue