From 636bf6b8b377820fb18b47cfbeafdd6616d67e31 Mon Sep 17 00:00:00 2001 From: jelveh Date: Mon, 4 Aug 2025 23:18:01 -0700 Subject: [PATCH] Implement shift-click functionality for checkbox selection in apps, websites, and workers; improve UI responsiveness by updating row activation based on checkbox state. --- src/dev-center/js/apps.js | 24 +++++++++++++++++++++++- src/dev-center/js/websites.js | 24 +++++++++++++++++++++++- src/dev-center/js/workers.js | 25 ++++++++++++++++++++++++- 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/dev-center/js/apps.js b/src/dev-center/js/apps.js index f107e1518..eb0821c51 100644 --- a/src/dev-center/js/apps.js +++ b/src/dev-center/js/apps.js @@ -2171,7 +2171,26 @@ $(document).on('click', '.search-clear-apps', function (e) { $('.search-apps').removeClass('has-value'); }) -$(document).on('change', '.app-checkbox', function (e) { +$(document).on('click', '.app-checkbox', function (e) { + // was shift key pressed? + if (e.originalEvent && e.originalEvent.shiftKey) { + // select all checkboxes in range + const currentIndex = $('.app-checkbox').index(this); + const startIndex = Math.min(window.last_clicked_app_checkbox_index, currentIndex); + const endIndex = Math.max(window.last_clicked_app_checkbox_index, currentIndex); + + // set all checkboxes in range to the same state as current checkbox + for (let i = startIndex; i <= endIndex; i++) { + const checkbox = $('.app-checkbox').eq(i); + checkbox.prop('checked', $(this).is(':checked')); + // activate row + if ($(checkbox).is(':checked')) + $(checkbox).closest('tr').addClass('active'); + else + $(checkbox).closest('tr').removeClass('active'); + } + } + // determine if select-all checkbox should be checked, indeterminate, or unchecked if ($('.app-checkbox:checked').length === $('.app-checkbox').length) { $('.select-all-apps').prop('indeterminate', false); @@ -2196,6 +2215,9 @@ $(document).on('change', '.app-checkbox', function (e) { $('.delete-apps-btn').removeClass('disabled'); else $('.delete-apps-btn').addClass('disabled'); + + // store the index of the last clicked checkbox + window.last_clicked_app_checkbox_index = $('.app-checkbox').index(this); }) $(document).on('click', '.delete-apps-btn', async function (e) { diff --git a/src/dev-center/js/websites.js b/src/dev-center/js/websites.js index 16075dd3d..d83708fdf 100644 --- a/src/dev-center/js/websites.js +++ b/src/dev-center/js/websites.js @@ -73,7 +73,26 @@ $(document).on('click', '.create-a-website-btn', async function (e) { } }) -$(document).on('change', '.website-checkbox', function (e) { +$(document).on('click', '.website-checkbox', function (e) { + // was shift key pressed? + if (e.originalEvent && e.originalEvent.shiftKey) { + // select all checkboxes in range + const currentIndex = $('.website-checkbox').index(this); + const startIndex = Math.min(window.last_clicked_website_checkbox_index, currentIndex); + const endIndex = Math.max(window.last_clicked_website_checkbox_index, currentIndex); + + // set all checkboxes in range to the same state as current checkbox + for (let i = startIndex; i <= endIndex; i++) { + const checkbox = $('.website-checkbox').eq(i); + checkbox.prop('checked', $(this).is(':checked')); + // activate row + if ($(checkbox).is(':checked')) + $(checkbox).closest('tr').addClass('active'); + else + $(checkbox).closest('tr').removeClass('active'); + } + } + // determine if select-all checkbox should be checked, indeterminate, or unchecked if ($('.website-checkbox:checked').length === $('.website-checkbox').length) { $('.select-all-websites').prop('indeterminate', false); @@ -98,6 +117,9 @@ $(document).on('change', '.website-checkbox', function (e) { $('.delete-websites-btn').removeClass('disabled'); else $('.delete-websites-btn').addClass('disabled'); + + // store the index of the last clicked checkbox + window.last_clicked_website_checkbox_index = $('.website-checkbox').index(this); }) $(document).on('change', '.select-all-websites', function (e) { diff --git a/src/dev-center/js/workers.js b/src/dev-center/js/workers.js index d8642417d..e1a8a1bd5 100644 --- a/src/dev-center/js/workers.js +++ b/src/dev-center/js/workers.js @@ -116,7 +116,27 @@ return new Response(\`Page \${params.page} not found\`, {status: 404}); } -$(document).on('change', '.worker-checkbox', function (e) { +$(document).on('click', '.worker-checkbox', function (e) { + // was shift key pressed? + if (e.originalEvent && e.originalEvent.shiftKey) { + // select all checkboxes in range + const currentIndex = $('.worker-checkbox').index(this); + const startIndex = Math.min(window.last_clicked_worker_checkbox_index, currentIndex); + const endIndex = Math.max(window.last_clicked_worker_checkbox_index, currentIndex); + + // set all checkboxes in range to the same state as current checkbox + for (let i = startIndex; i <= endIndex; i++) { + const checkbox = $('.worker-checkbox').eq(i); + checkbox.prop('checked', $(this).is(':checked')); + + // activate row + if ($(checkbox).is(':checked')) + $(checkbox).closest('tr').addClass('active'); + else + $(checkbox).closest('tr').removeClass('active'); + } + } + // determine if select-all checkbox should be checked, indeterminate, or unchecked if ($('.worker-checkbox:checked').length === $('.worker-checkbox').length) { $('.select-all-workers').prop('indeterminate', false); @@ -141,6 +161,9 @@ $(document).on('change', '.worker-checkbox', function (e) { $('.delete-workers-btn').removeClass('disabled'); else $('.delete-workers-btn').addClass('disabled'); + + // store the index of the last clicked checkbox + window.last_clicked_worker_checkbox_index = $('.worker-checkbox').index(this); }) $(document).on('change', '.select-all-workers', function (e) {