diff options
| author | qsm-odoo <qsm@odoo.com> | 2020-07-09 11:09:56 +0000 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2020-07-14 14:43:16 +0000 |
| commit | bb0cd4d5c82a9c2311f8c45ced0e9fdc0397d292 (patch) | |
| tree | 80520cf8ff73d5e1fc0ee1fcbd74421394ac93ab /addons/web_editor | |
| parent | d23a9c1954a79c4a9b49ad1319f4cf30514a9230 (diff) | |
[IMP] web_editor, *: review background color/image options UI
*: website, mass_mailing, website_blog, doc
Part of https://github.com/odoo/odoo/pull/53930
task-2157252
Diffstat (limited to 'addons/web_editor')
| -rw-r--r-- | addons/web_editor/static/src/js/editor/snippets.options.js | 125 | ||||
| -rw-r--r-- | addons/web_editor/static/src/scss/wysiwyg_snippets.scss | 15 | ||||
| -rw-r--r-- | addons/web_editor/static/tests/test_utils.js | 2 | ||||
| -rw-r--r-- | addons/web_editor/views/snippets.xml | 64 |
4 files changed, 134 insertions, 72 deletions
diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index cc0a154a08d..7ebf45964b5 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -130,6 +130,8 @@ function createPropertyProxy(obj, propertyName, value) { //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +const NULL_ID = '__NULL__'; + /** * Base class for components to be used in snippet options widgets to retrieve * user values. @@ -304,7 +306,7 @@ const UserValueWidget = Widget.extend({ * @returns {boolean} */ isActive: function () { - return !!this._value; + return this._value && this._value !== NULL_ID; }, /** * Indicates if the widget can contain sub user value widgets or not. @@ -719,7 +721,7 @@ const BaseSelectionUserValueWidget = UserValueWidget.extend({ */ setValue(value, methodName) { this._userValueWidgets.forEach(widget => { - widget.setValue('__NULL__', methodName); + widget.setValue(NULL_ID, methodName); }); for (const widget of [...this._userValueWidgets].reverse()) { widget.setValue(value, methodName); @@ -1304,10 +1306,9 @@ const ColorpickerUserValueWidget = SelectUserValueWidget.extend({ }); const ImagepickerUserValueWidget = UserValueWidget.extend({ - tagName: 'we-imagepicker', + tagName: 'we-button', events: { - 'click .o_we_edit_image': '_onEditImage', - 'click .o_we_remove_image': '_onRemoveImage', + 'click': '_onEditImage', }, /** @@ -1315,18 +1316,13 @@ const ImagepickerUserValueWidget = UserValueWidget.extend({ */ start: async function () { await this._super(...arguments); + const allowedSelector = this.el.dataset.allowVideos; this.allowVideos = allowedSelector ? this.$target.is(allowedSelector) : false; - this.editImageButton = document.createElement('we-button'); - this.editImageButton.classList.add('o_we_edit_image', 'fa', 'fa-fw', 'fa-edit'); - - this.removeImageButton = document.createElement('we-button'); - this.removeImageButton.classList.add('o_we_remove_image', 'fa', 'fa-fw', 'fa-times'); - this.removeImageButton.title = _t("Remove"); - - this.containerEl.appendChild(this.editImageButton); - this.containerEl.appendChild(this.removeImageButton); + const iconEl = document.createElement('i'); + iconEl.classList.add('fa', 'fa-fw', 'fa-camera'); + this.containerEl.appendChild(iconEl); }, /** * @override @@ -1342,9 +1338,9 @@ const ImagepickerUserValueWidget = UserValueWidget.extend({ /** * @override */ - _updateUI: async function () { + async _updateUI() { await this._super(...arguments); - this.removeImageButton.classList.toggle('d-none', !this.isActive()); + this.el.classList.toggle('active', this.isActive()); }, //-------------------------------------------------------------------------- @@ -1370,8 +1366,8 @@ const ImagepickerUserValueWidget = UserValueWidget.extend({ noDocuments: true, noVideos: !this.allowVideos, isForBgVideo: true, - res_model: $editable.data('oe-model'), - res_id: $editable.data('oe-id'), + 'res_model': $editable.data('oe-model'), + 'res_id': $editable.data('oe-id'), }, dummyEl).open(); mediaDialog.on('save', this, data => { if (data.bgVideoSrc) { @@ -1387,16 +1383,6 @@ const ImagepickerUserValueWidget = UserValueWidget.extend({ this._onUserValueChange(); }); }, - /** - * Called when the remove background button is clicked. - * - * @private - */ - _onRemoveImage: function (ev) { - this._value = ''; - this.isVideo = false; - this._onUserValueChange(ev); - }, }); const DatetimePickerUserValueWidget = InputUserValueWidget.extend({ @@ -2543,44 +2529,6 @@ const registry = {}; //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -/** - * Marks color levels of any element that may get or has a color classes. This - * is done for the specific main colorpicker option so that those are marked on - * snippet drop (so that base snippet definition do not need to care about that) - * and on first focus (for compatibility). - */ -registry.MainColorpicker = SnippetOptionWidget.extend({ - /** - * @override - */ - start: function () { - this._markColorLevel(); - return this._super(...arguments); - }, - /** - * @override - */ - onBuilt: function () { - this._markColorLevel(); - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * Adds a specific class indicating the element is colored so that nested - * color classes work (we support one-level). Removing it is not useful, - * technically the class can be added on anything that *may* receive a color - * class: this does not come with any CSS rule. - * - * @private - */ - _markColorLevel: function () { - this.$target.addClass('o_colored_level'); - }, -}); - registry.sizing = SnippetOptionWidget.extend({ /** * @override @@ -2975,7 +2923,9 @@ const ImageHandlerOption = SnippetOptionWidget.extend({ } const dataURL = await applyModifications(img); const weight = dataURL.split(',')[1].length / 4 * 3; - this.$el.find('.o_we_image_weight').text(`${(weight / 1024).toFixed(1)}kb`); + const $weight = this.$el.find('.o_we_image_weight'); + $weight.find('> span').text(`${(weight / 1024).toFixed(1)}kb`); + $weight.removeClass('d-none'); img.classList.add('o_modified_image_to_save'); return loadImage(dataURL, img); }, @@ -3220,7 +3170,7 @@ registry.BackgroundOptimize = ImageHandlerOption.extend({ /** * Handles the edition of snippet's background image. */ -registry.background = SnippetOptionWidget.extend({ +registry.BackgroundImage = SnippetOptionWidget.extend({ /** * @override */ @@ -3649,6 +3599,44 @@ registry.BackgroundPosition = SnippetOptionWidget.extend({ }); /** + * Marks color levels of any element that may get or has a color classes. This + * is done for the specific main colorpicker option so that those are marked on + * snippet drop (so that base snippet definition do not need to care about that) + * and on first focus (for compatibility). + */ +registry.ColoredLevelBackground = registry.BackgroundImage.extend({ + /** + * @override + */ + start: function () { + this._markColorLevel(); + return this._super(...arguments); + }, + /** + * @override + */ + onBuilt: function () { + this._markColorLevel(); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * Adds a specific class indicating the element is colored so that nested + * color classes work (we support one-level). Removing it is not useful, + * technically the class can be added on anything that *may* receive a color + * class: this does not come with any CSS rule. + * + * @private + */ + _markColorLevel: function () { + this.$target.addClass('o_colored_level'); + }, +}); + +/** * Allows to replace a text value with the name of a database record. * @todo replace this mechanism with real backend m2o field ? */ @@ -3889,6 +3877,7 @@ return { SnippetOptionWidget: SnippetOptionWidget, snippetOptionRegistry: registry, + NULL_ID: NULL_ID, UserValueWidget: UserValueWidget, userValueWidgetsRegistry: userValueWidgetsRegistry, diff --git a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss index 28cff34a1de..c82fb464f6d 100644 --- a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss +++ b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss @@ -841,6 +841,10 @@ body.editor_enable.editor_has_snippets { we-select.o_we_user_value_widget { position: static; } + + &.o_we_full_row > div { + flex: 1 1 auto; + } } %o-we-inline { @@ -871,6 +875,17 @@ body.editor_enable.editor_has_snippets { } } } + + .o_we_image_weight { + margin-top: $o-we-sidebar-content-field-spacing; + text-align: right; + color: $o-we-color-success; + line-height: $o-we-sidebar-content-field-height; + + > .fa { + margin-right: $o-we-sidebar-content-field-label-spacing; + } + } } > .o_we_invisible_el_panel { diff --git a/addons/web_editor/static/tests/test_utils.js b/addons/web_editor/static/tests/test_utils.js index 8ea0f5c70f5..59b1c38e38b 100644 --- a/addons/web_editor/static/tests/test_utils.js +++ b/addons/web_editor/static/tests/test_utils.js @@ -66,7 +66,7 @@ const SNIPPETS_TEMPLATE = ` <div data-selector=".test_option_all"> <we-colorpicker string="Background Color" data-select-style="true" data-css-property="background-color" data-color-prefix="bg-"/> </div> - <div data-js="background" data-selector=".test_option_all"> + <div data-js="BackgroundImage" data-selector=".test_option_all"> <we-button data-choose-image="true" data-no-preview="true"> <i class="fa fa-picture-o"/> Background Image </we-button> diff --git a/addons/web_editor/views/snippets.xml b/addons/web_editor/views/snippets.xml index 98396f98002..36c47ebd1f7 100644 --- a/addons/web_editor/views/snippets.xml +++ b/addons/web_editor/views/snippets.xml @@ -33,17 +33,75 @@ </div> </template> -<template id="image_optimization_controls"> +<template id="snippet_options_image_optimization_widgets"> <we-range string="Quality" data-set-quality=""/> <!-- Select filled in JS --> <we-select string="Width" data-name="width_select_opt" data-no-preview="true"/> - <span class="o_we_image_weight text-right"/> <we-colorpicker string="Color filter" data-set-filter="" data-no-preview="true" data-excluded="common, theme"/> <div class="o_we_external_warning d-none"> <we-title title="Quality options are unavailable for external images. If you want to change this image's quality, please first download it from the original source and upload it in Odoo."> <i class="fa fa-warning" /> External Image </we-title> </div> + <div class="o_we_image_weight d-none"><i class="fa fa-long-arrow-right"/><span/></div> +</template> + +<template id="snippet_options_background_selection_widgets"> + <we-row t-if="with_colors or with_images" string="Background" class="o_we_full_row"> + <we-colorpicker t-if="with_colors" + title="Color" + data-name="bg_color_opt" + data-select-style="" + data-css-property="background-color" + data-color-prefix="bg-" + t-att-data-with-combinations="with_color_combinations and 'true' or None" + t-att-data-css-compatible="css_compatible and 'true' or None"/> + <we-button-group t-if="with_images" + class="ml-auto" + t-att-data-dependencies="images_dependencies" + data-no-preview="true"> + <we-imagepicker title="Image" + data-background="" + data-allow-videos=":not(.parallax, .s_parallax_bg)"/> + <we-button title="None" + data-background=""><i class="fa fa-fw fa-ban"/></we-button> + </we-button-group> + </we-row> +</template> + +<template id="snippet_options_background_options"> + <div t-att-data-js="with_colors and with_color_combinations and 'ColoredLevelBackground' or 'BackgroundImage'" + t-att-data-selector="selector" + t-att-data-exclude="exclude" + t-att-data-target="target"> + <t t-call="web_editor.snippet_options_background_selection_widgets"/> + </div> + <t t-if="with_images"> + <div data-js="BackgroundPosition" + t-att-data-selector="selector" + t-att-data-exclude="exclude" + t-att-data-target="target"> + <we-row> + <we-select data-no-preview="true"> + <we-button data-background-type="cover">Cover</we-button> + <we-button data-background-type="repeat-pattern" data-name="background_repeat_opt">Repeat pattern</we-button> + </we-select> + <we-button class="fa fa-fw fa-crosshairs" title="Background Position" + data-background-position-overlay="true" data-no-preview="true"/> + </we-row> + <we-multi data-css-property="background-size" data-dependencies="background_repeat_opt"> + <we-input string="Width" data-select-style="auto" placeholder="auto" data-unit="px"/> + <we-input string="Height" data-select-style="auto" placeholder="auto" data-unit="px"/> + </we-multi> + </div> + + <div data-js="BackgroundOptimize" + t-att-data-selector="selector" + t-att-data-exclude="exclude" + t-att-data-target="target"> + <t t-call="web_editor.snippet_options_image_optimization_widgets"/> + </div> + </t> </template> <!-- options (data-selector, data-drop-in, data-drop-near, data-js to link js object ) --> @@ -61,7 +119,7 @@ <div data-js="ImageOptimize" data-selector="img"> - <t t-call="web_editor.image_optimization_controls"/> + <t t-call="web_editor.snippet_options_image_optimization_widgets"/> </div> </template> |
