Przeglądaj źródła

add select all button

tuanchris 5 miesięcy temu
rodzic
commit
9163da1cd9
2 zmienionych plików z 83 dodań i 2 usunięć
  1. 58 0
      static/js/playlists.js
  2. 25 2
      templates/playlists.html

+ 58 - 0
static/js/playlists.js

@@ -820,6 +820,57 @@ async function loadAvailablePatterns(forceRefresh = false) {
     }
     }
 }
 }
 
 
+// Update selection count display
+function updateSelectionCount() {
+    const countElement = document.getElementById('selectionCount');
+    if (countElement) {
+        const count = selectedPatterns.size;
+        countElement.textContent = `${count} selected`;
+    }
+}
+
+// Select all visible patterns
+function selectAllPatterns() {
+    const patterns = filteredPatterns.length > 0 ? filteredPatterns : availablePatterns;
+    patterns.forEach(pattern => {
+        selectedPatterns.add(pattern);
+    });
+    updatePatternSelection();
+    updateSelectionCount();
+}
+
+// Deselect all patterns
+function deselectAllPatterns() {
+    selectedPatterns.clear();
+    updatePatternSelection();
+    updateSelectionCount();
+}
+
+// Update visual selection state for all pattern cards
+function updatePatternSelection() {
+    const cards = document.querySelectorAll('#availablePatternsGrid .group');
+    cards.forEach(card => {
+        const patternName = card.dataset.pattern;
+        const addBtn = card.querySelector('.absolute.top-2.right-2');
+        
+        if (selectedPatterns.has(patternName)) {
+            card.classList.add('ring-2', 'ring-blue-500');
+            if (addBtn) {
+                addBtn.classList.remove('opacity-0', 'bg-white', 'dark:bg-gray-700');
+                addBtn.classList.add('opacity-100', 'bg-blue-500', 'text-white');
+                addBtn.querySelector('.material-icons').textContent = 'check';
+            }
+        } else {
+            card.classList.remove('ring-2', 'ring-blue-500');
+            if (addBtn) {
+                addBtn.classList.remove('opacity-100', 'bg-blue-500', 'text-white');
+                addBtn.classList.add('opacity-0', 'bg-white', 'dark:bg-gray-700');
+                addBtn.querySelector('.material-icons').textContent = 'add';
+            }
+        }
+    });
+}
+
 // Display available patterns in modal
 // Display available patterns in modal
 function displayAvailablePatterns() {
 function displayAvailablePatterns() {
     const grid = document.getElementById('availablePatternsGrid');
     const grid = document.getElementById('availablePatternsGrid');
@@ -881,6 +932,7 @@ function displayAvailablePatterns() {
                 addBtn.classList.add('opacity-100', 'bg-blue-500', 'text-white');
                 addBtn.classList.add('opacity-100', 'bg-blue-500', 'text-white');
                 addBtn.querySelector('.material-icons').textContent = 'check';
                 addBtn.querySelector('.material-icons').textContent = 'check';
             }
             }
+            updateSelectionCount();
         });
         });
 
 
         // Show add button on hover
         // Show add button on hover
@@ -1217,6 +1269,7 @@ function setupEventListeners() {
     // Add patterns button
     // Add patterns button
     document.getElementById('addPatternsBtn').addEventListener('click', async () => {
     document.getElementById('addPatternsBtn').addEventListener('click', async () => {
         await loadAvailablePatterns();
         await loadAvailablePatterns();
+        updateSelectionCount();
         document.getElementById('addPatternsModal').classList.remove('hidden');
         document.getElementById('addPatternsModal').classList.remove('hidden');
         // Focus search input when modal opens
         // Focus search input when modal opens
         setTimeout(() => {
         setTimeout(() => {
@@ -1248,10 +1301,15 @@ function setupEventListeners() {
     document.getElementById('cancelAddPatternsBtn').addEventListener('click', () => {
     document.getElementById('cancelAddPatternsBtn').addEventListener('click', () => {
         selectedPatterns.clear();
         selectedPatterns.clear();
         clearSearch();
         clearSearch();
+        updateSelectionCount();
         document.getElementById('addPatternsModal').classList.add('hidden');
         document.getElementById('addPatternsModal').classList.add('hidden');
     });
     });
 
 
     document.getElementById('confirmAddPatternsBtn').addEventListener('click', addSelectedPatternsToPlaylist);
     document.getElementById('confirmAddPatternsBtn').addEventListener('click', addSelectedPatternsToPlaylist);
+    
+    // Select All and Deselect All buttons
+    document.getElementById('selectAllBtn').addEventListener('click', selectAllPatterns);
+    document.getElementById('deselectAllBtn').addEventListener('click', deselectAllPatterns);
 
 
     // Handle Enter key in new playlist name input
     // Handle Enter key in new playlist name input
     document.getElementById('newPlaylistName').addEventListener('keypress', (e) => {
     document.getElementById('newPlaylistName').addEventListener('keypress', (e) => {

+ 25 - 2
templates/playlists.html

@@ -294,8 +294,8 @@ html:not(.dark) #availablePatternsGrid .text-xs {
       <h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Add Patterns to Playlist</h3>
       <h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Add Patterns to Playlist</h3>
     </div>
     </div>
     
     
-    <!-- Search Bar -->
-    <div class="mb-4 flex-shrink-0">
+    <!-- Search Bar and Select All -->
+    <div class="mb-4 flex-shrink-0 space-y-3">
       <div class="relative">
       <div class="relative">
         <span class="material-icons absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 dark:text-gray-500 text-lg">search</span>
         <span class="material-icons absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 dark:text-gray-500 text-lg">search</span>
         <input 
         <input 
@@ -308,6 +308,29 @@ html:not(.dark) #availablePatternsGrid .text-xs {
           <span class="material-icons text-lg">clear</span>
           <span class="material-icons text-lg">clear</span>
         </button>
         </button>
       </div>
       </div>
+      
+      <!-- Select All / Deselect All buttons -->
+      <div class="flex items-center justify-between">
+        <div class="flex gap-2">
+          <button 
+            id="selectAllBtn" 
+            class="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-lg transition-colors duration-150"
+          >
+            <span class="material-icons text-base">check_box</span>
+            <span>Select All</span>
+          </button>
+          <button 
+            id="deselectAllBtn" 
+            class="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-lg transition-colors duration-150"
+          >
+            <span class="material-icons text-base">check_box_outline_blank</span>
+            <span>Deselect All</span>
+          </button>
+        </div>
+        <span id="selectionCount" class="text-xs text-gray-500 dark:text-gray-400">
+          0 selected
+        </span>
+      </div>
     </div>
     </div>
     
     
     <div class="flex-1 overflow-y-auto">
     <div class="flex-1 overflow-y-auto">