Browse Source

List menu / More / Delete duplicate lists that do not have any cards.

Thanks to xet7 !
Lauri Ojansivu 1 week ago
parent
commit
91b846e2cd

+ 10 - 0
client/components/sidebar/sidebar.jade

@@ -537,6 +537,12 @@ template(name="archiveBoardPopup")
     | 📦
     | {{_ 'archive'}}
 
+template(name="deleteDuplicateListsPopup")
+  p {{_ 'delete-duplicate-lists-confirm'}}
+  button.js-confirm.negate.full(type="submit")
+    | 🗑️
+    | {{_ 'delete'}}
+
 template(name="outgoingWebhooksPopup")
   each integrations
     form.integration-form
@@ -621,6 +627,10 @@ template(name="boardMenuPopup")
     if currentUser.isBoardAdmin
       hr
       ul.pop-over-list
+        li
+          a.js-delete-duplicate-lists
+            | 🗑️
+            | {{_ 'delete-duplicate-lists'}}
         li
           a.js-archive-board
             | ➡️📦

+ 39 - 0
client/components/sidebar/sidebar.js

@@ -275,6 +275,45 @@ Template.boardMenuPopup.events({
   'click .js-change-background-image': Popup.open('boardChangeBackgroundImage'),
   'click .js-board-info-on-my-boards': Popup.open('boardInfoOnMyBoards'),
   'click .js-change-language': Popup.open('changeLanguage'),
+  'click .js-delete-duplicate-lists': Popup.afterConfirm('deleteDuplicateLists', function() {
+    const currentBoard = Utils.getCurrentBoard();
+    if (!currentBoard) return;
+    
+    // Get all lists in the current board
+    const allLists = ReactiveCache.getLists({ boardId: currentBoard._id, archived: false });
+    
+    // Group lists by title to find duplicates
+    const listsByTitle = {};
+    allLists.forEach(list => {
+      if (!listsByTitle[list.title]) {
+        listsByTitle[list.title] = [];
+      }
+      listsByTitle[list.title].push(list);
+    });
+    
+    // Find and delete duplicate lists that have no cards
+    let deletedCount = 0;
+    Object.keys(listsByTitle).forEach(title => {
+      const listsWithSameTitle = listsByTitle[title];
+      if (listsWithSameTitle.length > 1) {
+        // Keep the first list, delete the rest if they have no cards
+        for (let i = 1; i < listsWithSameTitle.length; i++) {
+          const list = listsWithSameTitle[i];
+          const cardsInList = ReactiveCache.getCards({ listId: list._id, archived: false });
+          
+          if (cardsInList.length === 0) {
+            Lists.remove(list._id);
+            deletedCount++;
+          }
+        }
+      }
+    });
+    
+    // Show notification
+    if (deletedCount > 0) {
+      // You could add a toast notification here if available
+    }
+  }),
   'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function() {
     const currentBoard = Utils.getCurrentBoard();
     currentBoard.archive();

+ 2 - 0
imports/i18n/data/en.i18n.json

@@ -755,6 +755,8 @@
   "delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
   "boardDeletePopup-title": "Delete Board?",
   "delete-board": "Delete Board",
+  "delete-duplicate-lists": "Delete Duplicate Lists",
+  "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.",
   "default-subtasks-board": "Subtasks for __board__ board",
   "default": "Default",
   "defaultdefault": "Default",