diff --git a/app/code/Magento/Catalog/Model/Category/DataProvider.php b/app/code/Magento/Catalog/Model/Category/DataProvider.php index 8fa599af1ce77ed01a652551a81d89aae857245d..862e68206e9e19e1518127239c18d73cfd4263c9 100644 --- a/app/code/Magento/Catalog/Model/Category/DataProvider.php +++ b/app/code/Magento/Catalog/Model/Category/DataProvider.php @@ -384,9 +384,11 @@ class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider $result['use_config.default_sort_by']['default'] = true; $result['use_config.filter_price_range']['default'] = true; if ($this->request->getParam('store') && $this->request->getParam('id')) { + $result['use_default.url_key']['checked'] = true; $result['use_default.url_key']['default'] = true; $result['use_default.url_key']['visible'] = true; } else { + $result['use_default.url_key']['checked'] = false; $result['use_default.url_key']['default'] = false; $result['use_default.url_key']['visible'] = false; } diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/components/url-key-handle-changes.js b/app/code/Magento/Catalog/view/adminhtml/web/js/components/url-key-handle-changes.js index b05f278f7055195d82a058f05fa70b2c759e9139..6259918f6b5e30f356cafa715409b91d631d21b0 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/components/url-key-handle-changes.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/components/url-key-handle-changes.js @@ -4,35 +4,36 @@ */ define([ - 'Magento_Ui/js/form/element/abstract' -], function (Abstract) { + 'Magento_Ui/js/form/element/single-checkbox' +], function (Checkbox) { 'use strict'; - return Abstract.extend({ + return Checkbox.extend({ + defaults: { + imports: { + handleUseDefault: '${ $.parentName }.use_default.url_key:checked', + urlKey: '${ $.provider }:data.url_key' + }, + listens: { + urlKey: 'handleChanges' + }, + modules: { + useDefault: '${ $.parentName }.use_default.url_key' + } + }, /** - * Disable checkbox field, when 'url_key' field without changes + * Disable checkbox field, when 'url_key' field without changes or 'use default' field is checked */ handleChanges: function (newValue) { - if (newValue !== this.getInitialValue()) { - this.disabled(false); - } else { - this.disabled(true); - } + this.disabled(newValue === this.valueMap['true'] || this.useDefault.checked); }, /** - * Set real 'url_key' to 'url_key_create_redirect' when field is checked + * Disable checkbox field, when 'url_key' field without changes or 'use default' field is checked */ - onUpdate: function () { - this._super(); - - if (this.value()) { - this.value(this.initialValue); - } else { - this.value(0); - } - this._super(); + handleUseDefault: function (checkedUseDefault) { + this.disabled(this.urlKey === this.valueMap['true'] || checkedUseDefault); } }); }); diff --git a/app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Category/Tab/Attributes.php b/app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Category/Tab/Attributes.php index 23454e092b7189204772a93975c4ec17d2f3918f..6fdca8c7ff8931e549b1a93327594f37449ffda0 100644 --- a/app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Category/Tab/Attributes.php +++ b/app/code/Magento/CatalogUrlRewrite/Plugin/Catalog/Block/Adminhtml/Category/Tab/Attributes.php @@ -25,15 +25,14 @@ class Attributes if (isset($result['url_key'])) { if ($category && $category->getId()) { if ($category->getLevel() == 1) { - $result['url_key']['arguments']['data']['config']['visible'] = false; - $result['url_key_create_redirect']['arguments']['data']['config']['visible'] = false; - $result['url_key_group']['arguments']['data']['disabled'] = true; + $result['url_key_group']['componentDisabled'] = true; } else { - $result['url_key_create_redirect']['arguments']['data']['config']['value'] = $category->getUrlKey(); - $result['url_key_create_redirect']['arguments']['data']['config']['disabled'] = true; + $result['url_key_create_redirect']['valueMap']['true'] = $category->getUrlKey(); + $result['url_key_create_redirect']['value'] = $category->getUrlKey(); + $result['url_key_create_redirect']['disabled'] = true; } } else { - $result['url_key_create_redirect']['arguments']['data']['config']['visible'] = false; + $result['url_key_create_redirect']['visible'] = false; } } return $result; diff --git a/app/code/Magento/CatalogUrlRewrite/Ui/DataProvider/Product/Form/Modifier/ProductUrlRewrite.php b/app/code/Magento/CatalogUrlRewrite/Ui/DataProvider/Product/Form/Modifier/ProductUrlRewrite.php index 0c68bb1c5d2a8c133eff8330bdb719332002fdc9..b7ea21884908aa8b5fb1702563e3673b112ae504 100644 --- a/app/code/Magento/CatalogUrlRewrite/Ui/DataProvider/Product/Form/Modifier/ProductUrlRewrite.php +++ b/app/code/Magento/CatalogUrlRewrite/Ui/DataProvider/Product/Form/Modifier/ProductUrlRewrite.php @@ -5,11 +5,11 @@ */ namespace Magento\CatalogUrlRewrite\Ui\DataProvider\Product\Form\Modifier; -use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Store\Model\ScopeInterface; use Magento\Catalog\Model\Locator\LocatorInterface; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Catalog\Api\Data\ProductAttributeInterface as AC; use Magento\Ui\Component\Form\Element\Checkbox; use Magento\Ui\Component\Form\Element\DataType\Text; use Magento\Ui\Component\Form\Field; @@ -80,7 +80,7 @@ class ProductUrlRewrite extends AbstractModifier */ protected function addUrlRewriteCheckbox(array $meta) { - $urlPath = $this->getElementArrayPath($meta, ProductAttributeInterface::CODE_SEO_FIELD_URL_KEY); + $urlPath = $this->getElementArrayPath($meta, AC::CODE_SEO_FIELD_URL_KEY); if ($urlPath) { $containerPath = $this->arrayManager->slicePath($urlPath, 0, -2); @@ -105,14 +105,16 @@ class ProductUrlRewrite extends AbstractModifier 'componentType' => Field::NAME, 'formElement' => Checkbox::NAME, 'dataType' => Text::NAME, - 'component' => 'Magento_CatalogUrlRewrite/js/components/url-key-handle-changes', + 'component' => 'Magento_Catalog/js/components/url-key-handle-changes', 'valueMap' => [ 'false' => '', 'true' => $urlKey ], 'imports' => [ + 'urlKey' => '${ $.provider }:data.product.' . AC::CODE_SEO_FIELD_URL_KEY, + 'handleUseDefault' => '${ $.parentName }.url_key:isUseDefault', 'handleChanges' => '${ $.provider }:data.product.' - . ProductAttributeInterface::CODE_SEO_FIELD_URL_KEY, + . AC::CODE_SEO_FIELD_URL_KEY, ], 'description' => __('Create Permanent Redirect for old URL'), 'dataScope' => 'url_key_create_redirect', diff --git a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/ui_component/category_form.xml b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/ui_component/category_form.xml index 1c63bb1d9b7a25ca85b3f10d56b4dd247c623b74..f39d49eb105b3010bc9fd437c376948048c0ea06 100644 --- a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/ui_component/category_form.xml +++ b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/ui_component/category_form.xml @@ -15,8 +15,11 @@ <item name="description" xsi:type="string" translate="true">Create Permanent Redirect for old URL</item> <item name="dataType" xsi:type="string">boolean</item> <item name="formElement" xsi:type="string">checkbox</item> - <item name="disabled" xsi:type="boolean">true</item> <item name="sortOrder" xsi:type="number">15</item> + <item name="component" xsi:type="string">Magento_Catalog/js/components/url-key-handle-changes</item> + <item name="valueMap" xsi:type="array"> + <item name="false" xsi:type="number">0</item> + </item> </item> </argument> </field> diff --git a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/web/js/components/url-key-handle-changes.js b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/web/js/components/url-key-handle-changes.js deleted file mode 100644 index fe963c9a6e306f2ffc2a8faa6e3ff1f6a55a29d7..0000000000000000000000000000000000000000 --- a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/web/js/components/url-key-handle-changes.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -define([ - 'Magento_Ui/js/form/element/single-checkbox' -], function (Abstract) { - 'use strict'; - - return Abstract.extend({ - defaults: { - checkedState: false - }, - - /** - * Extends with checkedState property. - * - * @returns {Element} - */ - initObservable: function () { - this._super(); - - this.checkedState = this.checked.peek(); - this.on('checked', function (checkedState) { - this.checkedState = checkedState; - }.bind(this)); - - return this; - }, - - /** - * Disable checkbox field, when 'url_key' field without changes - * - * @param {String} newValue - user-input value - */ - handleChanges: function (newValue) { - var localCheckedState; - - if (this.getReverseValueMap(newValue)) { // changed UrlKeyValue is equal stored UrlKeyValue - localCheckedState = this.checked.peek(); - - this.disabled(true); - - this.checked(false); - this.checkedState = localCheckedState; - } else { // UrlKeyValue was changed and is needed a rewrite - localCheckedState = this.checkedState; - - this.disabled(false); - - if (localCheckedState !== this.checked.peek()) { - this.checked(localCheckedState); - this.checkedState = localCheckedState; - } - } - } - }); -}); diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/button.js b/app/code/Magento/Ui/view/base/web/js/form/components/button.js index 9fbd07790a30e813a2b30bead14377f619ced490..94db70db5f49d02161c543831d39cfd983f0adca 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/button.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/button.js @@ -56,7 +56,7 @@ define([ */ applyAction: function (action) { var targetName = action.targetName, - params = action.params, + params = action.params || [], actionName = action.actionName, target; @@ -66,7 +66,8 @@ define([ target = registry.async(targetName); if (target && typeof target === 'function' && actionName) { - target(actionName, params); + params.unshift(actionName); + target.apply(target, params); } }, diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js b/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js index 26d0458d3f0fb77d98fa8dc3def4da731deb4e17..f882d407165d6d4bc5081de4bdbf462b5ad8052a 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js @@ -14,35 +14,39 @@ define([ * Get page actions element. * * @param {String} elem - * @param {String} actionsSelector + * @param {String} actionsClass * @returns {String} */ - function getPageActions(elem, actionsSelector) { - var $el = $('<div/>').html(elem), - $wrapper = $('<div/>').addClass('page-main-actions'); + function getPageActions(elem, actionsClass) { + var el = document.createElement('div'); - return $wrapper.html($el.find(actionsSelector)).get(0).outerHTML; + el.innerHTML = elem; + + return el.getElementsByClassName(actionsClass)[0]; } /** * Return element without page actions toolbar * * @param {String} elem - * @param {String} actionsSelector + * @param {String} actionsClass * @returns {String} */ - function removePageActions(elem, actionsSelector) { - var $el = $('<div/>').html(elem); + function removePageActions(elem, actionsClass) { + var el = document.createElement('div'), + actions; - $el.find(actionsSelector).remove(); + el.innerHTML = elem; + actions = el.getElementsByClassName(actionsClass)[0]; + el.removeChild(actions); - return $el.html(); + return el.innerHTML; } return Insert.extend({ defaults: { externalFormName: '${ $.ns }.${ $.ns }', - pageActionsSelector: '.page-actions', + pageActionsClass: 'page-actions', exports: { prefix: '${ $.externalFormName }:selectorPrefix' }, @@ -96,12 +100,12 @@ define([ /** @inheritdoc */ onRender: function (data) { - var actions = getPageActions(data, this.pageActionsSelector); + var actions = getPageActions(data, this.pageActionsClass); if (!data.length) { return this; } - data = removePageActions(data, this.pageActionsSelector); + data = removePageActions(data, this.pageActionsClass); this.renderActions(actions); this._super(data); }, diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/insert.js b/app/code/Magento/Ui/view/base/web/js/form/components/insert.js index c95d93ad7089eaf69b6d686beccc829b1a977dab..820b6612e728ee009ff15a5279d4f8f6a7ab7be4 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/insert.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/insert.js @@ -126,7 +126,8 @@ define([ self.previousParams = params || {}; $.async({ - component: this.name + component: this.name, + ctx: '.' + this.contentSelector }, function (el) { self.contentEl = $(el); self.startRender = true; @@ -235,8 +236,6 @@ define([ onRender: function (data) { this.loading(false); this.set('content', data); - this.contentEl.children().applyBindings(); - this.contentEl.trigger('contentUpdated'); this.isRendered = true; this.startRender = false; }, diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/date.js b/app/code/Magento/Ui/view/base/web/js/form/element/date.js index 7cb870f53fd27ec2d254a0baf32771170729b99b..9d6a5e9045d7e396cab3674f0fe68e872e99a996 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/date.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/date.js @@ -23,9 +23,7 @@ define([ */ initConfig: function () { this._super(); - - //this.dateFormat = utils.normalizeDate(this.dateFormat); - this.dateFormat = utils.normalizeDate('MM/dd/YYYY'); + this.dateFormat = utils.normalizeDate(this.dateFormat); return this; }, diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/date.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/date.js index 88de82b87366f6c045486bf29ac6a37b2da11417..21b9c51a6e75d47c746894aab7034073ecd3c7b1 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/columns/date.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/date.js @@ -32,11 +32,11 @@ define([ * * @returns {String} Formatted date. */ - getLabel: function () { + getLabel: function (value, format) { var date = moment(this._super()); date = date.isValid() ? - date.format(this.dateFormat) : + date.format(format || this.dateFormat) : ''; return date; diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bind-html.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bind-html.js new file mode 100644 index 0000000000000000000000000000000000000000..353b5bb348b81e48ef723bc1ae12a398dd05873d --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bind-html.js @@ -0,0 +1,74 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'ko', + 'underscore', + 'mage/apply/main', + '../template/renderer' +], function (ko, _, mage, renderer) { + 'use strict'; + + /** + * Set html to node element. + * + * @param {HTMLElement} el - Element to apply bindings to. + * @param {Function} html - Observable html content. + */ + function setHtml(el, html) { + ko.utils.emptyDomNode(el); + html = ko.utils.unwrapObservable(html); + + if (!_.isNull(html) && !_.isUndefined(html)) { + if (!_.isString(html)) { + html = html.toString(); + } + + el.innerHTML = html; + } + } + + /** + * Apply bindings and call magento attributes parser. + * + * @param {HTMLElement} el - Element to apply bindings to. + * @param {ko.bindingContext} ctx - Instance of ko.bindingContext, passed to binding initially. + */ + function applyComponents(el, ctx) { + ko.utils.arrayForEach(el.childNodes, ko.cleanNode); + ko.applyBindingsToDescendants(ctx, el); + mage.apply(); + } + + ko.bindingHandlers.bindHtml = { + /** + * Scope binding's init method. + * + * @returns {Object} - Knockout declaration for it to let binding control descendants. + */ + init: function () { + return { + controlsDescendantBindings: true + }; + }, + + /** + * Reads params passed to binding. + * Set html to node element, apply bindings and call magento attributes parser. + * + * @param {HTMLElement} el - Element to apply bindings to. + * @param {Function} valueAccessor - Function that returns value, passed to binding. + * @param {Object} allBindings - Object, which represents all bindings applied to element. + * @param {Object} viewModel - Object, which represents view model binded to el. + * @param {ko.bindingContext} bindingContext - Instance of ko.bindingContext, passed to binding initially. + */ + update: function (el, valueAccessor, allBindings, viewModel, bindingContext) { + setHtml(el, valueAccessor()); + applyComponents(el, bindingContext); + } + }; + + renderer.addAttribute('bindHtml'); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bootstrap.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bootstrap.js index 7d5a95346cf02f2d29555c4a4c2191c5c3cac0c3..634d487613ad3586f67cf5bfdd0881bd6e428248 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bootstrap.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/bootstrap.js @@ -19,6 +19,7 @@ define(function (require) { .addNode('fastForEach'); return { + resizable: require('./resizable'), i18n: require('./i18n'), scope: require('./scope'), range: require('./range'), @@ -33,6 +34,7 @@ define(function (require) { collapsible: require('./collapsible'), staticChecked: require('./staticChecked'), simpleChecked: require('./simple-checked'), + bindHtml: require('./bind-html'), tooltip: require('./tooltip'), repeat: require('knockoutjs/knockout-repeat'), fastForEach: require('knockoutjs/knockout-fast-foreach') diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/resizable.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/resizable.js new file mode 100644 index 0000000000000000000000000000000000000000..c74f89e37df94c6f8ace68568748d225bf190120 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/resizable.js @@ -0,0 +1,147 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'ko', + 'jquery', + 'Magento_Ui/js/lib/view/utils/async', + 'uiRegistry', + 'underscore', + '../template/renderer', + 'jquery/ui' +], function (ko, $, async, registry, _, renderer) { + 'use strict'; + + var sizeOptions = [ + 'minHeight', + 'maxHeight', + 'minWidth', + 'maxWidth' + ], + + handles = { + height: '.ui-resizable-s, .ui-resizable-n', + width: '.ui-resizable-w, .ui-resizable-e' + }; + + /** + * Recalcs visibility of handles, width and height of resizable based on content + * @param {HTMLElement} element + */ + function adjustSize(element) { + var maxHeight, + maxWidth; + + element = $(element); + maxHeight = element.resizable('option').maxHeight; + maxWidth = element.resizable('option').maxWidth; + + if (maxHeight && element.height() > maxHeight) { + element.height(maxHeight + 1); + $(handles.height).hide(); + } else { + $(handles.height).show(); + } + + if (maxWidth && element.width() > maxWidth) { + element.width(maxWidth + 1); + $(handles.width).hide(); + } else { + $(handles.width).show(); + } + } + + /** + * Recalcs allowed min, max width and height based on configured selectors + * @param {Object} sizeConstraints + * @param {String} componentName + * @param {HTMLElement} element + * @param {Boolean} hasWidthUpdate + */ + function recalcAllowedSize(sizeConstraints, componentName, element, hasWidthUpdate) { + var size; + + element = $(element); + + if (!element.data('resizable')) { + return; + } + + if (!hasWidthUpdate) { + element.css('width', 'auto'); + } + + _.each(sizeConstraints, function (selector, key) { + async.async({ + component: componentName, + selector: selector + }, function (elem) { + size = key.indexOf('Height') !== -1 ? $(elem).outerHeight(true) : $(elem).outerWidth(true); + + if (element.data('resizable')) { + element.resizable('option', key, size + 1); + } + }); + }, this); + + adjustSize(element); + } + + /** + * Preprocess config to separate options, + * which must be processed further before applying + * + * @param {Object} config + * @param {Object} viewModel + * @param {*} element + * @return {Object} config + */ + function processConfig(config, viewModel, element) { + var sizeConstraint, + sizeConstraints = {}, + recalc, + hasWidthUpdate; + + if (_.isEmpty(config)) { + return {}; + } + _.each(sizeOptions, function (key) { + sizeConstraint = config[key]; + + if (sizeConstraint && !_.isNumber(sizeConstraint)) { + sizeConstraints[key] = sizeConstraint; + delete config[key]; + } + }); + hasWidthUpdate = _.some(sizeConstraints, function (value, key) { + return key.indexOf('Width') !== -1; + }); + + recalc = recalcAllowedSize.bind(null, sizeConstraints, viewModel.name, element, hasWidthUpdate); + config.start = recalc; + $(window).on('resize.resizable', recalc); + registry.get(viewModel.provider).on('reloaded', recalc); + + return config; + } + + ko.bindingHandlers.resizable = { + + /** + * Binding init callback. + * + * @param {*} element + * @param {Function} valueAccessor + * @param {Function} allBindings + * @param {Object} viewModel + */ + init: function (element, valueAccessor, allBindings, viewModel) { + var config = processConfig(valueAccessor(), viewModel, element); + + $(element).resizable(config); + } + }; + + renderer.addAttribute('resizable'); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/extender/bound-nodes.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/extender/bound-nodes.js index 62a13e52add7a587a9aad83fb0f8397296ea0e35..7d2def3d0bd145e774d6579fa7973f7e3010c74f 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/extender/bound-nodes.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/extender/bound-nodes.js @@ -83,6 +83,27 @@ define([ } } + /** + * Returns node's first sibling of 'element' type within the common component scope + * + * @param {HTMLElement} node + * @returns {HTMLElement} + */ + function getElement(node, data) { + var elem; + + while (node.nextElementSibling) { + node = node.nextElementSibling; + + if (node.nodeType === 1 && ko.dataFor(node) === data) { + elem = node; + break; + } + } + + return elem; + } + wrapper.extend(ko, { /** @@ -93,14 +114,16 @@ define([ */ applyBindings: function (orig, ctx, node) { var result = orig(), - data; + data = ctx && (ctx.$data || ctx); + + if (node && node.nodeType === 8) { + node = getElement(node, data); + } if (!node || node.nodeType !== 1) { return result; } - data = ctx && (ctx.$data || ctx); - if (data && data.registerNodes) { addBounded(data, node); } diff --git a/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js b/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js index 581a596b4217fa7689a07368b1bc1d47e8156044..74fa46f9df3d85a2c80b1960ae5a70af8452cb18 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js @@ -173,6 +173,7 @@ define([ requests: [] }; + this._updateRequests = _.debounce(this._updateRequests.bind(this), 50); privateData.set(this, data); } diff --git a/app/code/Magento/Ui/view/base/web/js/modal/modal-component.js b/app/code/Magento/Ui/view/base/web/js/modal/modal-component.js index 2279526aca4a22d10e36c4da9451e31ea2bf0787..e67c5403fb5af97878b6707b6ba0609a110cb51a 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/modal-component.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/modal-component.js @@ -286,14 +286,15 @@ define([ */ triggerAction: function (action) { var targetName = action.targetName, - params = action.params, + params = action.params || [], actionName = action.actionName, target; target = registry.async(targetName); if (target && typeof target === 'function' && actionName) { - target(actionName, params); + params.unshift(actionName); + target.apply(target, params); } }, diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/split-button.html b/app/code/Magento/Ui/view/base/web/templates/form/element/split-button.html new file mode 100644 index 0000000000000000000000000000000000000000..7b3ed597ccd97a50eb8e9f4e30033b6d4cd1adbd --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/form/element/split-button.html @@ -0,0 +1,19 @@ +<!-- +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<div class="action-select-wrap" > + <div each="getRegion('button')" render=""/> + <button type="button" class="action-select" click="$data.toggleOpened"></button> + <ul class="action-menu" css="_active: $data.opened" > + <!-- ko foreach: $data.elems() --> + <li> + <!--ko template: getTemplate()--> + <!-- /ko --> + </li> + <!-- /ko --> + </ul> +</div> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/form/insert.html b/app/code/Magento/Ui/view/base/web/templates/form/insert.html index edc1c0e7870040c09bcf106d90401875fb6de06d..698eba6a383e43d040e52aa73863da6020a17398 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/insert.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/insert.html @@ -5,7 +5,7 @@ */ --> -<div data-bind="html: content, +<div data-bind="bindHtml: content, attr: { class: element.cssclass ? element.cssclass : 'admin__scope-old' }, diff --git a/app/design/adminhtml/Magento/backend/Magento_Staging/web/css/source/module/_scheduled-changes.less b/app/design/adminhtml/Magento/backend/Magento_Staging/web/css/source/module/_scheduled-changes.less index 7e4faad2a1919186a2c647235bc797edf5740073..a38df900961dce1cf30dcc0163ca6e1858cc9b70 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Staging/web/css/source/module/_scheduled-changes.less +++ b/app/design/adminhtml/Magento/backend/Magento_Staging/web/css/source/module/_scheduled-changes.less @@ -79,18 +79,6 @@ min-height: 0; } - .block-content { - border-top: 1px solid @scheduled-changes-block__border-color; - height: 15rem; - margin-bottom: @indent__base; - min-height: 15rem; - overflow: auto; - padding: @indent__m; - position: relative; - resize: vertical; - z-index: 1; - } - .admin__data-grid-outer-wrap { position: relative; } @@ -112,6 +100,25 @@ } } +// Block with Schedule table +.block-schedule-table { + &:extend(.abs-block-resizable all); + + .block-content { + &:extend(.abs-block-resizable-content all); + border-top: 1px solid @scheduled-changes-block__border-color; + + .schedule-table-wrapper { + margin: @indent__m; + } + } + + .ui-resizable-s { + &:extend(.abs-block-resizable-handle-bottom all); + cursor: ns-resize; + } +} + .schedule-table { border-collapse: collapse; width: 100%; @@ -259,30 +266,6 @@ font-size: 1.2rem; } -// Resizer - -.block-resizer { - background: @scheduled-changes-block-resizer__background-color; - border: 1px solid @scheduled-changes-block__border-color; - color: @scheduled-changes-block-resizer__color; - cursor: ns-resize; - display: block; - font-size: 1.6rem; - font-weight: @font-weight__bold; - left: -1px; - letter-spacing: .1rem; - line-height: 1.7rem; - padding-bottom: .3rem; - position: absolute; - right: -1px; - text-align: center; - top: 100%; - - &:before { - content: ':::::'; - } -} - .block-nodata { padding: @indent__m; } diff --git a/app/design/adminhtml/Magento/backend/web/css/source/_components.less b/app/design/adminhtml/Magento/backend/web/css/source/_components.less index a3c0be3a5c52a91def110952529b264a1268ea3f..18cb7de399100f699df34abc4aa640974b5b43b5 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/_components.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/_components.less @@ -17,5 +17,6 @@ @import 'components/_timeline.less'; @import 'components/_file-insertion.less'; @import 'components/_media-gallery.less'; +@import 'components/_resizable-block.less'; @import 'components/_file-uploader.less'; @import 'components/_slider.less'; diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_resizable-block.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_resizable-block.less new file mode 100644 index 0000000000000000000000000000000000000000..5abc4e935f47f94e3b8ebfaf083f6a614294d8cb --- /dev/null +++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_resizable-block.less @@ -0,0 +1,159 @@ +// /** +// * Copyright © 2015 Magento. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// Components -> Resizable Block +// _____________________________________________ + +// +// Variables +// --------------------------------------------- + +@resizable-block-angle-handle__default__height: 12px; +@resizable-block-angle-handle__default__width: 12px; + +@resizable-block-side-handle__default__size: 7px; + +@resizable-block-side-handle__custom__background-color: @color-gray89; +@resizable-block-side-handle__custom__border-color: @color-gray-light2; +@resizable-block-side-handle__custom__color: @color-gray40; +@resizable-block-side-handle__custom__font-size: 1.6rem; + +// +// Extends +// _____________________________________________ + +.abs-block-resizable { + height: 15rem; + min-height: 15rem; +} + +// Resizable Block Content +.abs-block-resizable-content { + height: 100%; + margin-bottom: @indent__base; + min-height: 15rem; + overflow: auto; + position: relative; + z-index: 1; +} + +// Bottom handle +.abs-block-resizable-handle-bottom { + background: @resizable-block-side-handle__custom__background-color; + border: 1px solid @resizable-block-side-handle__custom__border-color; + bottom: auto; + color: @resizable-block-side-handle__custom__color; + font-size: @resizable-block-side-handle__custom__font-size; + font-weight: @font-weight__bold; + height: auto; + left: -1px; + letter-spacing: .1rem; + line-height: @resizable-block-side-handle__custom__font-size; + padding-bottom: .3rem; + right: -1px; + text-align: center; + top: 100%; + width: auto; + + &:before { + content: ':::::'; + } +} + +// +// Default Resizable Styles +// --------------------------------------------- + +.ui-resizable { + position: relative; +} + +.ui-resizable-handle { + display: block; + font-size: 0.1px; + position: absolute; + touch-action: none; +} + +.ui-resizable-n { + cursor: n-resize; + height: @resizable-block-side-handle__default__size; + left: 0; + top: -@resizable-block-side-handle__default__size/2; + width: 100%; +} + +.ui-resizable-s { + bottom: -@resizable-block-side-handle__default__size/2; + cursor: s-resize; + height: @resizable-block-side-handle__default__size; + left: 0; + width: 100%; +} + +.ui-resizable-e { + cursor: e-resize; + height: 100%; + right: -@resizable-block-side-handle__default__size/2; + top: 0; + width: @resizable-block-side-handle__default__size; +} + +.ui-resizable-w { + cursor: w-resize; + height: 100%; + left: -@resizable-block-side-handle__default__size/2; + top: 0; + width: @resizable-block-side-handle__default__size; +} + +.ui-resizable-se { + bottom: -@resizable-block-angle-handle__default__height/2; + cursor: se-resize; + height: @resizable-block-angle-handle__default__height; + right: -@resizable-block-angle-handle__default__width/2; + width: @resizable-block-angle-handle__default__width; +} + +.ui-resizable-sw { + bottom: -@resizable-block-angle-handle__default__height/2; + cursor: sw-resize; + height: @resizable-block-angle-handle__default__height; + left: -@resizable-block-angle-handle__default__width/2; + width: @resizable-block-angle-handle__default__width; +} + +.ui-resizable-nw { + cursor: nw-resize; + height: @resizable-block-angle-handle__default__height; + left: -@resizable-block-angle-handle__default__width/2; + top: -@resizable-block-angle-handle__default__height/2; + width: @resizable-block-angle-handle__default__width; +} + +.ui-resizable-ne { + cursor: ne-resize; + height: @resizable-block-angle-handle__default__height; + right: -@resizable-block-angle-handle__default__width/2; + top: -@resizable-block-angle-handle__default__height/2; + width: @resizable-block-angle-handle__default__width; +} + +// +// Container +// --------------------------------------------- + +.block-resizable { + &:extend(.abs-block-resizable all); + + .block-content { + &:extend(.abs-block-resizable-content all); + } + + .ui-resizable-s { + &:extend(.abs-block-resizable-handle-bottom all); + } +} diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc-magento b/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc-magento index 0e517ccbee93f9804a954c6c59b3653d8959b611..231b00c230a33c0581830055b2c70392c9cbda4b 100644 --- a/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc-magento +++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc-magento @@ -12,7 +12,9 @@ "lines-around-comment": [ 2, { - "beforeBlockComment": true + "beforeBlockComment": true, + "allowBlockStart": true, + "allowObjectStart": true } ], "max-depth": [2, 2],