[#7759] added shift+click bulk selection

This commit is contained in:
Gani Georgiev committed 2026-07-18 10:17:38 +03:00
1 parent 09af56b342
commit 7964a8ce43
11 files changed
+113 -29

No files matched your search

+18 -3
View File
@@ -359,10 +359,25 @@ export function logsList(logsSettings) {
id: "cb_" + log.id,
type: "checkbox",
checked: () => !!data.bulkSelected[log.id],
onclick: (e) => {
e.target.__shiftKey = e.shiftKey;
},
onchange: (e) => {
const bulkSelected = JSON.parse(
JSON.stringify(data.bulkSelected),
);
let bulkSelected = Object.assign({}, data.bulkSelected);
// range select
if (e.target.__shiftKey) {
e.target.__shiftKey = false;
app.utils.bulkSelectRange(
data.logs,
bulkSelected,
log,
e.target.checked,
);
}
// toggle current log
if (e.target.checked) {
bulkSelected[log.id] = log;
} else {
+19 -2
View File
@@ -548,7 +548,7 @@ window.app.components.recordsList = function(propsArg = {}) {
);
}
return data.records.map((record, i) => {
return data.records.map((record) => {
return t.tr(
{
rid: recordRid(record),
@@ -593,8 +593,25 @@ window.app.components.recordsList = function(propsArg = {}) {
type: "checkbox",
id: () => uniqueId + record.id,
checked: () => !!data.bulkSelected[record.id],
onclick: (e) => {
e.target.__shiftKey = e.shiftKey;
},
onchange: (e) => {
const bulkSelected = JSON.parse(JSON.stringify(data.bulkSelected));
let bulkSelected = Object.assign({}, data.bulkSelected);
// range select
if (e.target.__shiftKey) {
e.target.__shiftKey = false;
app.utils.bulkSelectRange(
data.records,
bulkSelected,
record,
e.target.checked,
);
}
// toggle current record
if (e.target.checked) {
bulkSelected[record.id] = record;
} else {
+27 -14
View File
@@ -78,18 +78,6 @@ export function pageExportCollections(route) {
}
}
function toggleSelectCollection(collection) {
const bulkSelected = JSON.parse(JSON.stringify(data.bulkSelected));
if (!data.bulkSelected[collection.id]) {
bulkSelected[collection.id] = collection;
} else {
delete bulkSelected[collection.id];
}
// reassign to trigger the getter's Object.keys
data.bulkSelected = bulkSelected;
}
return t.div(
{
pbEvent: "pageExportCollections",
@@ -150,8 +138,33 @@ export function pageExportCollections(route) {
id: checkboxId,
type: "checkbox",
checked: () => !!data.bulkSelected[collection.id],
onchange: () => {
toggleSelectCollection(collection);
onclick: (e) => {
e.target.__shiftKey = e.shiftKey;
},
onchange: (e) => {
let bulkSelected = Object.assign({}, data.bulkSelected);
// range select
if (e.target.__shiftKey) {
e.target.__shiftKey = false;
app.utils.bulkSelectRange(
data.collections,
bulkSelected,
collection,
e.target.checked,
);
}
// toggle current collection
if (e.target.checked) {
bulkSelected[collection.id] = collection;
} else {
delete bulkSelected[collection.id];
}
// reassign to trigger the getter's Object.keys
data.bulkSelected = bulkSelected;
},
}),
t.label({ htmlFor: checkboxId }, collection.name),
+39
View File
@@ -1251,6 +1251,45 @@ const utils = {
return yiq < 128;
},
/**
* Applies a bulk selection from the last bulkSelected model entry
* to the specified current one (used for "Shift + Click" selection).
*
* The bulkSelected argument is changed in place.
*
* @param {Array} models
* @param {Object} bulkSelected
* @param {Object} currentModel
* @param {boolean} checked
*/
bulkSelectRange(models, bulkSelected, currentModel, checked) {
const currentSelectedIndex = models.findIndex((m) => m.id == currentModel.id);
if (currentSelectedIndex == -1) {
return;
}
const bulkSelectedKeys = Object.keys(bulkSelected);
const lastSelectedId = bulkSelectedKeys[bulkSelectedKeys.length - 1];
const lastSelectedIndex = models.findIndex((m) => m.id == lastSelectedId);
if (lastSelectedIndex == -1) {
return;
}
let start = lastSelectedIndex;
let end = currentSelectedIndex;
if (start > end) {
[start, end] = [end, start];
}
for (let i = start; i <= end; i++) {
if (checked) {
bulkSelected[models[i].id] = models[i];
} else {
delete bulkSelected[models[i].id];
}
}
},
// ---------------------------------------------------------------
imageExtensions: [".jpg", ".jpeg", ".png", ".svg", ".gif", ".jfif", ".webp", ".avif"],
videoExtensions: [".mp4", ".avi", ".mov", ".3gp", ".wmv"],