| 
 | 1 | +diff --git a/vendor/magento/module-visual-merchandiser/Model/Product/DataProvider.php b/vendor/magento/module-visual-merchandiser/Model/Product/DataProvider.php  | 
 | 2 | +index 579db812bb5a..9b55ed9553ea 100755  | 
 | 3 | +--- a/vendor/magento/module-visual-merchandiser/Model/Product/DataProvider.php  | 
 | 4 | ++++ b/vendor/magento/module-visual-merchandiser/Model/Product/DataProvider.php  | 
 | 5 | +@@ -1,7 +1,21 @@  | 
 | 6 | + <?php  | 
 | 7 | +-/**  | 
 | 8 | +- * Copyright © Magento, Inc. All rights reserved.  | 
 | 9 | +- * See COPYING.txt for license details.  | 
 | 10 | ++/************************************************************************  | 
 | 11 | ++ *  | 
 | 12 | ++ * ADOBE CONFIDENTIAL  | 
 | 13 | ++ * ___________________  | 
 | 14 | ++ *  | 
 | 15 | ++ * Copyright 2015 Adobe  | 
 | 16 | ++ * All Rights Reserved.  | 
 | 17 | ++ *  | 
 | 18 | ++ * NOTICE: All information contained herein is, and remains  | 
 | 19 | ++ * the property of Adobe and its suppliers, if any. The intellectual  | 
 | 20 | ++ * and technical concepts contained herein are proprietary to Adobe  | 
 | 21 | ++ * and its suppliers and are protected by all applicable intellectual  | 
 | 22 | ++ * property laws, including trade secret and copyright laws.  | 
 | 23 | ++ * Dissemination of this information or reproduction of this material  | 
 | 24 | ++ * is strictly forbidden unless prior written permission is obtained  | 
 | 25 | ++ * from Adobe.  | 
 | 26 | ++ * ************************************************************************  | 
 | 27 | +  */  | 
 | 28 | + namespace Magento\VisualMerchandiser\Model\Product;  | 
 | 29 | +   | 
 | 30 | +@@ -198,6 +212,7 @@ public function getData()  | 
 | 31 | +         $positions = $this->cache->getPositions($this->positionCacheKey);  | 
 | 32 | +         $categoryId = $this->request->getParam('category_id');  | 
 | 33 | +         $arrItems = [];  | 
 | 34 | ++        $arrItems['totalRecords'] = $this->collection->getSize();  | 
 | 35 | +         $arrItems['items'] = [];  | 
 | 36 | +         if ($positions === false && $categoryId !== null) {  | 
 | 37 | +             $arrItems['selectedData'] = $this->positionResolver->getPositions((int) $categoryId);  | 
 | 38 | +diff --git a/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/add_products.js b/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/add_products.js  | 
 | 39 | +index f840a4d8cfae..4169c094f68a 100644  | 
 | 40 | +--- a/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/add_products.js  | 
 | 41 | ++++ b/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/add_products.js  | 
 | 42 | +@@ -1,6 +1,20 @@  | 
 | 43 | +-/**  | 
 | 44 | +- * Copyright © Magento, Inc. All rights reserved.  | 
 | 45 | +- * See COPYING.txt for license details.  | 
 | 46 | ++/************************************************************************  | 
 | 47 | ++ *  | 
 | 48 | ++ * ADOBE CONFIDENTIAL  | 
 | 49 | ++ * ___________________  | 
 | 50 | ++ *  | 
 | 51 | ++ * Copyright 2015 Adobe  | 
 | 52 | ++ * All Rights Reserved.  | 
 | 53 | ++ *  | 
 | 54 | ++ * NOTICE: All information contained herein is, and remains  | 
 | 55 | ++ * the property of Adobe and its suppliers, if any. The intellectual  | 
 | 56 | ++ * and technical concepts contained herein are proprietary to Adobe  | 
 | 57 | ++ * and its suppliers and are protected by all applicable intellectual  | 
 | 58 | ++ * property laws, including trade secret and copyright laws.  | 
 | 59 | ++ * Dissemination of this information or reproduction of this material  | 
 | 60 | ++ * is strictly forbidden unless prior written permission is obtained  | 
 | 61 | ++ * from Adobe.  | 
 | 62 | ++ * ************************************************************************  | 
 | 63 | +  */  | 
 | 64 | +   | 
 | 65 | + /*global setLocation:true*/  | 
 | 66 | +@@ -224,16 +238,87 @@ define([  | 
 | 67 | +          * @private  | 
 | 68 | +          */  | 
 | 69 | +         _save: function () {  | 
 | 70 | +-            var idColumn = this  | 
 | 71 | ++            const idColumn = this  | 
 | 72 | +                 .registry  | 
 | 73 | +                 .get('merchandiser_product_listing.merchandiser_product_listing.merchandiser_product_columns.ids');  | 
 | 74 | +   | 
 | 75 | +             this._invalidateCache();  | 
 | 76 | ++            this._saveAll(idColumn)  | 
 | 77 | ++                .then((selected) => {  | 
 | 78 | ++                    this._trigger('dialogSave', null, [selected, this]);  | 
 | 79 | ++                })  | 
 | 80 | ++                .catch((error) => {  | 
 | 81 | ++                    console.error('Error saving data:', error);  | 
 | 82 | ++                });  | 
 | 83 | ++        },  | 
 | 84 | ++  | 
 | 85 | ++        /**  | 
 | 86 | ++         * @private  | 
 | 87 | ++         */  | 
 | 88 | ++        _saveAll: async function (idColumn) {  | 
 | 89 | ++            let selected = idColumn.selected();  | 
 | 90 | ++  | 
 | 91 | ++            // Proceed if all items are selected or if exclusions are in play  | 
 | 92 | ++            if (idColumn.allSelected() || idColumn.excludeMode()) {  | 
 | 93 | ++                const vmGrid = this  | 
 | 94 | ++                        .registry  | 
 | 95 | ++                        .get('merchandiser_product_listing.merchandiser_product_listing_data_source'),  | 
 | 96 | ++                    { paging, namespace, search, keywordUpdated, filters } = vmGrid.params,  | 
 | 97 | ++                    currentPageSize = paging.pageSize,  | 
 | 98 | ++                    totalRecords = idColumn.totalRecords(),  | 
 | 99 | ++                    excludedIds = idColumn.excluded() || [];  | 
 | 100 | ++  | 
 | 101 | ++                // If page size is less than total records, adjust the page size temporarily  | 
 | 102 | ++                if (currentPageSize >= totalRecords) {  | 
 | 103 | ++                    return selected;  | 
 | 104 | ++                }  | 
 | 105 | ++  | 
 | 106 | ++                paging.pageSize = totalRecords;  | 
 | 107 | ++  | 
 | 108 | ++                try {  | 
 | 109 | ++                    const response = await $.ajax({  | 
 | 110 | ++                        type: 'GET',  | 
 | 111 | ++                        url: vmGrid.update_url,  | 
 | 112 | ++                        dataType: 'json',  | 
 | 113 | ++                        showLoader: true,  | 
 | 114 | ++                        data: { namespace, search, keywordUpdated, filters, paging }  | 
 | 115 | ++                    });  | 
 | 116 | ++  | 
 | 117 | ++                    // Filter and reorder selected based on exclusion IDs  | 
 | 118 | ++                    selected = this._reorderArrayBasedOnGivenOrder(  | 
 | 119 | ++                        selected,  | 
 | 120 | ++                        response.allIds.filter(id => !excludedIds.includes(id))  | 
 | 121 | ++                    );  | 
 | 122 | ++  | 
 | 123 | ++                } catch (error) {  | 
 | 124 | ++                    console.error('Error fetching data for saving:', error);  | 
 | 125 | ++                    selected = [];  | 
 | 126 | ++                }  | 
 | 127 | ++  | 
 | 128 | ++                // Restore the original page size if it was changed  | 
 | 129 | ++                if (currentPageSize < totalRecords) {  | 
 | 130 | ++                    paging.pageSize = currentPageSize;  | 
 | 131 | ++                }  | 
 | 132 | ++            }  | 
 | 133 | ++  | 
 | 134 | ++            return selected;  | 
 | 135 | ++        },  | 
 | 136 | ++  | 
 | 137 | ++        /**  | 
 | 138 | ++         * @private  | 
 | 139 | ++         */  | 
 | 140 | ++        _reorderArrayBasedOnGivenOrder: function (selectedIds, allIds) {  | 
 | 141 | ++            const selectedSet = new Set(selectedIds),  | 
 | 142 | ++                sortedSelections = [...selectedIds];  | 
 | 143 | ++  | 
 | 144 | ++            // Filter out items in givenArray from evaluatedArray and preserve order  | 
 | 145 | ++            for (let item of allIds) {  | 
 | 146 | ++                if (!selectedSet.has(item)) {  | 
 | 147 | ++                    sortedSelections.push(item);  | 
 | 148 | ++                }  | 
 | 149 | ++            }  | 
 | 150 | +   | 
 | 151 | +-            this._trigger('dialogSave', null, [  | 
 | 152 | +-                idColumn.selected(),  | 
 | 153 | +-                this  | 
 | 154 | +-            ]);  | 
 | 155 | ++            return sortedSelections;  | 
 | 156 | +         }  | 
 | 157 | +     });  | 
 | 158 | +   | 
 | 159 | +diff --git a/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/grid/columns/onoff.js b/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/grid/columns/onoff.js  | 
 | 160 | +index 9e46181c97ca..764c8357a692 100644  | 
 | 161 | +--- a/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/grid/columns/onoff.js  | 
 | 162 | ++++ b/vendor/magento/module-visual-merchandiser/view/adminhtml/web/js/grid/columns/onoff.js  | 
 | 163 | +@@ -1,7 +1,22 @@  | 
 | 164 | +-/**  | 
 | 165 | +- * Copyright © Magento, Inc. All rights reserved.  | 
 | 166 | +- * See COPYING.txt for license details.  | 
 | 167 | ++/************************************************************************  | 
 | 168 | ++ *  | 
 | 169 | ++ * ADOBE CONFIDENTIAL  | 
 | 170 | ++ * ___________________  | 
 | 171 | ++ *  | 
 | 172 | ++ * Copyright 2016 Adobe  | 
 | 173 | ++ * All Rights Reserved.  | 
 | 174 | ++ *  | 
 | 175 | ++ * NOTICE: All information contained herein is, and remains  | 
 | 176 | ++ * the property of Adobe and its suppliers, if any. The intellectual  | 
 | 177 | ++ * and technical concepts contained herein are proprietary to Adobe  | 
 | 178 | ++ * and its suppliers and are protected by all applicable intellectual  | 
 | 179 | ++ * property laws, including trade secret and copyright laws.  | 
 | 180 | ++ * Dissemination of this information or reproduction of this material  | 
 | 181 | ++ * is strictly forbidden unless prior written permission is obtained  | 
 | 182 | ++ * from Adobe.  | 
 | 183 | ++ * ************************************************************************  | 
 | 184 | +  */  | 
 | 185 | ++  | 
 | 186 | + define([  | 
 | 187 | +     'underscore',  | 
 | 188 | +     'mage/translate',  | 
 | 189 | +@@ -26,7 +41,9 @@ define([  | 
 | 190 | +             },  | 
 | 191 | +             listens: {  | 
 | 192 | +                 '${ $.provider }:reloaded': 'setDefaultSelections'  | 
 | 193 | +-            }  | 
 | 194 | ++            },  | 
 | 195 | ++            isInSelectAll: false,  | 
 | 196 | ++            preventReset: false  | 
 | 197 | +         },  | 
 | 198 | +   | 
 | 199 | +         /**  | 
 | 200 | +@@ -104,13 +121,13 @@ define([  | 
 | 201 | +             var relevant = true;  | 
 | 202 | +   | 
 | 203 | +             switch (actionId) {  | 
 | 204 | +-                case 'selectPage':  | 
 | 205 | +-                    relevant = !this.isPageSelected(true);  | 
 | 206 | +-                    break;  | 
 | 207 | ++            case 'selectPage':  | 
 | 208 | ++                relevant = !this.isPageSelected(true);  | 
 | 209 | ++                break;  | 
 | 210 | +   | 
 | 211 | +-                case 'deselectPage':  | 
 | 212 | +-                    relevant =  this.isPageSelected();  | 
 | 213 | +-                    break;  | 
 | 214 | ++            case 'deselectPage':  | 
 | 215 | ++                relevant =  this.isPageSelected();  | 
 | 216 | ++                break;  | 
 | 217 | +             }  | 
 | 218 | +   | 
 | 219 | +             return relevant;  | 
 | 220 | +@@ -123,55 +140,37 @@ define([  | 
 | 221 | +          * @returns {Object} Chainable.  | 
 | 222 | +          */  | 
 | 223 | +         updateState: function () {  | 
 | 224 | +-            var positionCacheValid = registry.get('position_cache_valid'),  | 
 | 225 | +-                totalRecords    = this.totalRecords(),  | 
 | 226 | +-                totalSelected   = this.totalSelected(),  | 
 | 227 | ++            const positionCacheValid = registry.get('position_cache_valid'),  | 
 | 228 | ++                filtering = this.getFiltering();  | 
 | 229 | ++            let totalRecords = this.totalRecords(),  | 
 | 230 | ++                totalSelected = this.totalSelected(),  | 
 | 231 | ++                selected = this.selected(),  | 
 | 232 | +                 allSelected;  | 
 | 233 | +   | 
 | 234 | +-            if (positionCacheValid && this.selected().length > 0) {  | 
 | 235 | ++            if (positionCacheValid && (!this.preventReset || this.preventReset && selected.length > 0)) {  | 
 | 236 | ++                this.preventReset = false;  | 
 | 237 | +                 registry.set('position_cache_valid', true);  | 
 | 238 | +-                registry.set('selected_cache', JSON.stringify(this.selected()));  | 
 | 239 | ++                registry.set('selected_cache', JSON.stringify(selected));  | 
 | 240 | +             }  | 
 | 241 | +   | 
 | 242 | +             // When filters are enabled then totalRecords is unknown  | 
 | 243 | +-            if (this.getFiltering()) {  | 
 | 244 | +-                if (this.getFiltering().search !== '') {  | 
 | 245 | +-                    totalRecords = -1;  | 
 | 246 | +-                }  | 
 | 247 | ++            if (filtering?.search || Object.keys(filtering?.filters || {}).length > 1) {  | 
 | 248 | ++                totalRecords = -1;  | 
 | 249 | +             }  | 
 | 250 | +   | 
 | 251 | +             allSelected = totalRecords && totalSelected === totalRecords;  | 
 | 252 | +-  | 
 | 253 | +             this.allSelected(allSelected);  | 
 | 254 | +-            this.indetermine(totalSelected && !allSelected);  | 
 | 255 | ++            this.indetermine(totalSelected > 0 && !allSelected);  | 
 | 256 | +   | 
 | 257 | +             return this;  | 
 | 258 | +         },  | 
 | 259 | +   | 
 | 260 | +         /**  | 
 | 261 | +-         * Selects all records, even those that  | 
 | 262 | +-         * are not visible on the page.  | 
 | 263 | +-         *  | 
 | 264 | +-         * @returns {Object} Chainable.  | 
 | 265 | ++         * Is invoked when filtration is applied or removed  | 
 | 266 | +          */  | 
 | 267 | +-        selectAll: function () {  | 
 | 268 | +-            var newSelected = [],  | 
 | 269 | +-                $selected = $H(),  | 
 | 270 | +-                i;  | 
 | 271 | +-  | 
 | 272 | +-            for (i = 0; i < this.selected().length; i++) {  | 
 | 273 | +-                $selected.set(this.selected()[i], i);  | 
 | 274 | +-            }  | 
 | 275 | +-  | 
 | 276 | +-            for (i = 0; i < this.allIds.length; i++) {  | 
 | 277 | +-                if ($selected.get(this.allIds[i]) === undefined) {  | 
 | 278 | +-                    newSelected.push(this.allIds[i]);  | 
 | 279 | +-                }  | 
 | 280 | +-            }  | 
 | 281 | +-  | 
 | 282 | +-            this.selected(this.selected().concat(newSelected));  | 
 | 283 | +-  | 
 | 284 | +-            return this;  | 
 | 285 | ++        onFilter: function () {  | 
 | 286 | ++            this.preventReset = true;  | 
 | 287 | ++            this._super();  | 
 | 288 | +         }  | 
 | 289 | +     });  | 
 | 290 | + });  | 
0 commit comments