diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/expandable.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/expandable.js new file mode 100644 index 0000000000000..0874a9d32c8e9 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/expandable.js @@ -0,0 +1,102 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + './column' +], function (Column) { + 'use strict'; + + return Column.extend({ + defaults: { + bodyTmpl: 'ui/grid/cells/expandable', + tooltipTmpl: 'ui/grid/cells/expandable/content', + visibeItemsLimit: 5, + tooltipTitle: '' + }, + + /** + * Gets label from full options array. + * + * @param {Object} record - Record object. + * @returns {String} + */ + getFullLabel: function (record) { + return this.getLabelsArray(record).join(', '); + }, + + /** + * Gets label from options array limited by 'visibeItemsLimit'. + * + * @param {Object} record - Record object. + * @returns {String} + */ + getShortLabel: function (record) { + return this.getLabelsArray(record).slice(0, this.visibeItemsLimit).join(', '); + }, + + /** + * Extracts array of labels associated with provided values and sort it alphabetically. + * + * @param {Object} record - Record object. + * @returns {Array} + */ + getLabelsArray: function (record) { + var values = this.getLabel(record), + options = this.options || [], + labels = []; + + if (_.isString(values)) { + values = values.split(','); + } + + if (!Array.isArray(values)) { + values = [values]; + } + + values = values.map(function (value) { + return value + ''; + }); + + options = this.flatOptions(options); + + options.forEach(function (item) { + if (_.contains(values, item.value + '')) { + labels.push(item.label); + } + }); + + return labels.sort(); + }, + + /** + * Transformation tree options structure to liner array. + * + * @param {Array} options + * @returns {Array} + */ + flatOptions: function (options) { + var self = this; + + return options.reduce(function (options, option) { + if (_.isArray(option.value)) { + options = options.concat(self.flatOptions(option.value)); + } else { + options.push(option); + } + + return options; + }, []); + }, + + /** + * Checks if amount of options is more than limit value. + * + * @param {Object} record - Data to be preprocessed. + * @returns {Boolean} + */ + isExpandable: function (record) { + return this.getLabel(record).length > this.visibeItemsLimit; + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/tooltip.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/tooltip.js index 4600ec08a5392..cfd898b61e5e7 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/tooltip.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/tooltip.js @@ -43,10 +43,12 @@ define([ closeButton: false, showed: false, strict: true, - center: false + center: false, + closeOnScroll: true }; tooltipData = { + tooltipClasses: '', trigger: false, timeout: 0, element: false, @@ -578,9 +580,12 @@ define([ $('.' + config.closeButtonClass).on('click.closeButton', tooltip.destroy.bind(null, id)); } - document.addEventListener('scroll', tooltip.destroy, true); + if (config.closeOnScroll) { + document.addEventListener('scroll', tooltip.destroy, true); + $(window).on('scroll.tooltip', tooltip.outerClick.bind(null, id)); + } + $(window).on('keydown.tooltip', tooltip.keydownHandler); - $(window).on('scroll.tooltip', tooltip.outerClick.bind(null, id)); $(window).on('resize.outerClick', tooltip.outerClick.bind(null, id)); }, @@ -666,6 +671,7 @@ define([ $('.' + defaults.closeButtonClass).off('click.closeButton'); tooltipData.trigger.off('mousemove.track'); document.removeEventListener('scroll', tooltip.destroy, true); + $(window).off('scroll.tooltip'); $(window).off(CLICK_EVENT + '.outerClick'); $(window).off('keydown.tooltip'); $(window).off('resize.outerClick'); diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/cells/expandable.html b/app/code/Magento/Ui/view/base/web/templates/grid/cells/expandable.html new file mode 100644 index 0000000000000..f4de78f71e238 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/cells/expandable.html @@ -0,0 +1,27 @@ + +
+ + +
+ diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/cells/expandable/content.html b/app/code/Magento/Ui/view/base/web/templates/grid/cells/expandable/content.html new file mode 100644 index 0000000000000..88731f412a7a9 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/grid/cells/expandable/content.html @@ -0,0 +1,14 @@ + +
+ +
+
    +
  • + +
  • +
diff --git a/app/code/Magento/Ui/view/base/web/templates/tooltip/tooltip.html b/app/code/Magento/Ui/view/base/web/templates/tooltip/tooltip.html index 0f4f964dc1bdf..98c659a5349b0 100644 --- a/app/code/Magento/Ui/view/base/web/templates/tooltip/tooltip.html +++ b/app/code/Magento/Ui/view/base/web/templates/tooltip/tooltip.html @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ --> -
+
<% if(data.closeButton){ %> diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less index 906d7c1f89753..8ab2d928406fd 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less +++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/_data-grid.less @@ -15,6 +15,12 @@ @data-grid-row-changed__icon: @icon-edit__content; @data-grid-row-changed-tooltip__background: @color-white-fog2; +@data-grid-tooltip__background-color: @color-lazy-sun; +@data-grid-tooltip__border-color: @color-dark-grayish-orange; +@data-grid-tooltip__box-shadow: 0 2px 8px 0 rgba(0, 0, 0, .3); +@data-grid-tooltip-content__width: 24rem; +@data-grid-tooltip__z-index: @z-index-1; + // // Components // --------------------------------------------- @@ -1002,6 +1008,57 @@ body._in-resize { } } +// Column with tooltip +.data-grid-column-tooltip { + z-index: @data-grid-tooltip__z-index; + + .data-tooltip { + background-color: @data-grid-tooltip__background-color; + border-color: @data-grid-tooltip__border-color; + box-shadow: @data-grid-tooltip__box-shadow; + min-width: @data-grid-tooltip-content__width; + padding: 1.5rem; + + .action-close { + padding: 1.5rem; + right: 0; + top: 0; + } + } + + .data-tooltip-tail { + &:before { + background-color: @data-grid-tooltip__background-color; + border-color: @data-grid-tooltip__border-color; + box-shadow: @data-grid-tooltip__box-shadow; + } + + &:after { + background-color: @data-grid-tooltip__background-color; + } + } + + .data-tooltip-content { + .items { + max-height: 24rem; + overflow-y: auto; + + .item { + margin-bottom: .5rem; + } + } + } + + .admin__tooltip-title { + font-weight: @font-weight__bold; + margin-bottom: 1rem; + } +} + +.admin__control-short-label { + margin-bottom: @indent__s; +} + // Fix for Not whole column area is clickable in data-grid. // Purpose to expand clickable area for new data-grids. .admin__data-grid-outer-wrap { diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/expandable.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/expandable.test.js new file mode 100644 index 0000000000000..a9d393980eb66 --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/expandable.test.js @@ -0,0 +1,72 @@ +/** + * Copyright © 2013-2017 Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'Magento_Ui/js/grid/columns/expandable' +], function (Expandable) { + 'use strict'; + + describe('Ui/js/grid/columns/expandable', function () { + var expandable, record; + + beforeEach(function () { + expandable = new Expandable({ + index: 'shared_catalog', + visibeItemsLimit: 1, + options: [] + }); + record = { + 'entity_id': '3', + 'row_id': '3', + 'shared_catalog': [] + }; + }); + + describe('getFullLabel method', function () { + it('get label while options are empty', function () { + expect(expandable.getFullLabel(record)).toBe(''); + }); + + it('get label after options are set', function () { + record['shared_catalog'].push(1); + expandable.options.push({ + label: 'Default', + value: '1' + }); + expect(expandable.getFullLabel(record)).toBe('Default'); + }); + + it('check if getLabelsArray have been called', function () { + spyOn(expandable, 'getLabelsArray').and.returnValues(['Default', 'Custom']); + expandable.getFullLabel(record); + expect(expandable.getLabelsArray).toHaveBeenCalled(); + }); + }); + + describe('getShortLabel method', function () { + it('get label while options are empty', function () { + expect(expandable.getShortLabel(record)).toBe(''); + }); + }); + + describe('isExpandable method', function () { + it('check if label is not expandable', function () { + expect(expandable.isExpandable(record)).toBe(false); + }); + + it('check if label is expandable', function () { + record['shared_catalog'].push(1); + record['shared_catalog'].push(2); + expect(expandable.isExpandable(record)).toBe(true); + }); + + it('check if getLabel have been called', function () { + spyOn(expandable, 'getLabel').and.returnValues('1', '2'); + expandable.isExpandable(record); + expect(expandable.getLabel).toHaveBeenCalled(); + }); + }); + }); +});