[IMP] web_editor, website, *: introduce popover as edit system for links
*: website_form This commit introduces a simple & light popover/tooltip (as in Google Doc) when editing a link. It will be used: 1. (web_editor) On every page links. 2. (website) In the website navbar, when clicking on a menu, it will replace the popup shown to ask the user what he wants to do (edit the menu or go to the link or do nothing). That popup was a bit invasive and old-fashioned. Part of https://github.com/odoo/odoo/pull/64756 task-2439860 closes odoo/odoo#64756 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
@@ -6,6 +6,7 @@ var concurrency = require('web.concurrency');
|
||||
var core = require('web.core');
|
||||
var Widget = require('web.Widget');
|
||||
var weContext = require('web_editor.context');
|
||||
const weWidgets = require('wysiwyg.widgets');
|
||||
var summernote = require('web_editor.summernote');
|
||||
var summernoteCustomColors = require('web_editor.rte.summernote_custom_colors');
|
||||
|
||||
@@ -676,6 +677,10 @@ var RTEWidget = Widget.extend({
|
||||
if (this && this.$last && this.$last.length && this.$last[0] !== $target[0]) {
|
||||
$('.o_editable_date_field_linked').removeClass('o_editable_date_field_linked');
|
||||
}
|
||||
// Keep popover open if clicked inside it, but not on a button
|
||||
if (!($target.parents('.o_edit_menu_popover').length && !$target.parent('a').addBack('a').length)) {
|
||||
$('.o_edit_menu_popover').popover('hide');
|
||||
}
|
||||
if (!$editable.length || (!isLink && $.summernote.core.dom.isContentEditableFalse($target))) {
|
||||
return;
|
||||
}
|
||||
@@ -689,6 +694,11 @@ var RTEWidget = Widget.extend({
|
||||
});
|
||||
|
||||
if (isLink) {
|
||||
if (!$target.data('popover-widget-initialized')) {
|
||||
weWidgets.LinkPopoverWidget.createFor(this, ev.target);
|
||||
$target.data('popover-widget-initialized', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove content editable everywhere and add it on the link only so that characters can be added
|
||||
* and removed at the start and at the end of it.
|
||||
@@ -702,7 +712,17 @@ var RTEWidget = Widget.extend({
|
||||
|
||||
// Once clicked outside, remove contenteditable on link and reactive all
|
||||
$(document).on('mousedown.reactivate_contenteditable', function (e) {
|
||||
if ($target.is(e.target)) return;
|
||||
// Keep popover open if clicked inside it, but not on a button
|
||||
const $currTarget = $(e.target);
|
||||
if (!($currTarget.parents('.o_edit_menu_popover').length && !$currTarget.parent('a').addBack('a').length)) {
|
||||
$('.o_edit_menu_popover').popover('hide');
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($target.is(e.target)) {
|
||||
return;
|
||||
}
|
||||
if (!hasContentEditable) {
|
||||
$target.removeAttr('contenteditable');
|
||||
}
|
||||
|
||||
@@ -883,14 +883,6 @@ eventHandler.attach = function (oLayoutInfo, options) {
|
||||
eventHandler.modules.imageDialog.show(oLayoutInfo);
|
||||
});
|
||||
|
||||
/**
|
||||
* Open Link Dialog on double click on a link/button.
|
||||
* Shows a tooltip on click to say to the user he can double click.
|
||||
*/
|
||||
create_dblclick_feature("a[href], a.btn, button.btn", function () {
|
||||
eventHandler.modules.linkDialog.show(oLayoutInfo);
|
||||
});
|
||||
|
||||
oLayoutInfo.editable().on('mousedown', function (e) {
|
||||
if (dom.isImg(e.target) && dom.isContentEditable(e.target)) {
|
||||
range.createFromNode(e.target).select();
|
||||
|
||||
@@ -1076,12 +1076,16 @@ var SnippetsMenu = Widget.extend({
|
||||
if (!srcElement || lastElement === srcElement) {
|
||||
return;
|
||||
}
|
||||
var $target = $(srcElement);
|
||||
// Keep popover open if clicked inside it, but not on a button
|
||||
if ($target.parents('.o_edit_menu_popover').length && !$target.parent('a').addBack('a').length) {
|
||||
return;
|
||||
}
|
||||
lastElement = srcElement;
|
||||
_.defer(function () {
|
||||
lastElement = false;
|
||||
});
|
||||
|
||||
var $target = $(srcElement);
|
||||
if (!$target.closest('we-button, we-toggler, .o_we_color_preview').length) {
|
||||
this._closeWidgets();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import Widget from 'web.Widget';
|
||||
import {_t} from 'web.core';
|
||||
|
||||
const LinkPopoverWidget = Widget.extend({
|
||||
template: 'wysiwyg.widgets.link.edit.tooltip',
|
||||
xmlDependencies: ['/web_editor/static/src/xml/wysiwyg.xml'],
|
||||
events: {
|
||||
'click .o_we_remove_link': '_onRemoveLinkClick',
|
||||
'click .o_we_edit_link': '_onEditLinkClick',
|
||||
},
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {Element} target: target Element for which we display a popover
|
||||
*/
|
||||
init(parent, target) {
|
||||
this._super(...arguments);
|
||||
this.target = target;
|
||||
this.$target = $(target);
|
||||
this.href = this.$target.attr('href'); // for template
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
start() {
|
||||
this.$urlLink = this.$('.o_we_url_link');
|
||||
this.$previewFaviconImg = this.$('.o_we_preview_favicon img');
|
||||
this.$previewFaviconFa = this.$('.o_we_preview_favicon .fa');
|
||||
this.$copyLink = this.$('.o_we_copy_link');
|
||||
this.$fullUrl = this.$('.o_we_full_url');
|
||||
|
||||
// Copy onclick handler
|
||||
const clipboard = new ClipboardJS(
|
||||
this.$copyLink[0],
|
||||
{text: () => this.target.href} // Absolute href
|
||||
);
|
||||
clipboard.on('success', () => {
|
||||
this.$copyLink.tooltip('hide');
|
||||
this.displayNotification({
|
||||
type: 'success',
|
||||
message: _t("Link copied to clipboard."),
|
||||
});
|
||||
});
|
||||
|
||||
// init tooltips & popovers
|
||||
this.$('[data-toggle="tooltip"]').tooltip({delay: 0, placement: 'bottom'});
|
||||
this.$target.popover({
|
||||
html: true,
|
||||
content: this.$el,
|
||||
placement: 'bottom',
|
||||
trigger: 'click',
|
||||
})
|
||||
.on('show.bs.popover', () => {
|
||||
this._loadAsyncLinkPreview();
|
||||
})
|
||||
.popover('show')
|
||||
.data('bs.popover').tip.classList.add('o_edit_menu_popover');
|
||||
|
||||
return this._super(...arguments);
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
destroy() {
|
||||
this.$target.popover('dispose');
|
||||
return this._super(...arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetches and gets the link preview data (title, description..).
|
||||
* For external URL, only the favicon will be loaded.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_loadAsyncLinkPreview() {
|
||||
let url;
|
||||
try {
|
||||
url = new URL(this.target.href); // relative to absolute
|
||||
} catch (e) {
|
||||
// Invalid URL, might happen with editor unsuported protocol. eg type
|
||||
// `geo:37.786971,-122.399677`, become `http://geo:37.786971,-122.399677`
|
||||
this.displayNotification({
|
||||
type: 'danger',
|
||||
message: _t("This URL is invalid. Preview couldn't be updated."),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this._resetPreview(url);
|
||||
const protocol = url.protocol;
|
||||
if (!protocol.startsWith('http')) {
|
||||
const faMap = {'mailto:': 'fa-envelope-o', 'tel:': 'fa-phone'};
|
||||
const icon = faMap[protocol];
|
||||
if (icon) {
|
||||
this.$previewFaviconFa.toggleClass(`fa-globe ${icon}`);
|
||||
}
|
||||
} else if (window.location.hostname !== url.hostname) {
|
||||
// Preview pages from current website only. External website will
|
||||
// most of the time raise a CORS error. To avoid that error, we
|
||||
// would need to fetch the page through the server (s2s), involving
|
||||
// enduser fetching problematic pages such as illicit content.
|
||||
this.$previewFaviconImg.attr({
|
||||
'src': `https://www.google.com/s2/favicons?sz=16&domain=${url}`
|
||||
}).removeClass('d-none');
|
||||
this.$previewFaviconFa.addClass('d-none');
|
||||
} else {
|
||||
$.get(this.target.href).then(content => {
|
||||
const parser = new window.DOMParser();
|
||||
const doc = parser.parseFromString(content, "text/html");
|
||||
|
||||
// Get
|
||||
const favicon = doc.querySelector("link[rel~='icon']");
|
||||
const ogTitle = doc.querySelector("[property='og:title']");
|
||||
const title = doc.querySelector("title");
|
||||
|
||||
// Set
|
||||
if (favicon) {
|
||||
this.$previewFaviconImg.attr({'src': favicon.href}).removeClass('d-none');
|
||||
this.$previewFaviconFa.addClass('d-none');
|
||||
}
|
||||
if (ogTitle || title) {
|
||||
this.$urlLink.text(ogTitle ? ogTitle.getAttribute('content') : title.text.trim());
|
||||
}
|
||||
this.$fullUrl.removeClass('d-none').addClass('o_we_webkit_box');
|
||||
this.$target.popover('update');
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Resets the preview elements visibility. Particularly useful when changing
|
||||
* the link url from an internal to an external one and vice versa.
|
||||
*
|
||||
* @private
|
||||
* @param {string} url
|
||||
*/
|
||||
_resetPreview(url) {
|
||||
this.$previewFaviconImg.addClass('d-none');
|
||||
this.$previewFaviconFa.removeClass('d-none').addClass('fa-globe');
|
||||
this.$urlLink.text(url).attr('href', url);
|
||||
this.$fullUrl.text(url).addClass('d-none').removeClass('o_we_webkit_box');
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Opens the Link Dialog.
|
||||
*
|
||||
* TODO Call business methods once new editor is released instead of click
|
||||
*
|
||||
* @private
|
||||
* @param {Event} ev
|
||||
*/
|
||||
_onEditLinkClick(ev) {
|
||||
$('.note-link-popover [data-event="showLinkDialog"]').click();
|
||||
},
|
||||
/**
|
||||
* Removes the link/anchor.
|
||||
*
|
||||
* TODO Call business methods once new editor is released instead of click
|
||||
*
|
||||
* @private
|
||||
* @param {Event} ev
|
||||
*/
|
||||
_onRemoveLinkClick(ev) {
|
||||
$('.note-link-popover [data-event="unlink"]').click();
|
||||
},
|
||||
});
|
||||
|
||||
LinkPopoverWidget.createFor = async function (parent, targetEl) {
|
||||
// Target might already have a popover, eg cart icon in navbar
|
||||
if ($(targetEl).data('bs.popover')) {
|
||||
return null;
|
||||
}
|
||||
const popoverWidget = new this(parent, targetEl);
|
||||
return popoverWidget.appendTo(targetEl).then(() => popoverWidget);
|
||||
};
|
||||
|
||||
export default LinkPopoverWidget;
|
||||
@@ -6,6 +6,7 @@ var AltDialog = require('wysiwyg.widgets.AltDialog');
|
||||
var MediaDialog = require('wysiwyg.widgets.MediaDialog');
|
||||
var LinkDialog = require('wysiwyg.widgets.LinkDialog');
|
||||
var ImageCropWidget = require('wysiwyg.widgets.ImageCropWidget');
|
||||
const LinkPopoverWidget = require('@web_editor/js/wysiwyg/widgets/link_popover_widget')[Symbol.for("default")];
|
||||
const {ColorpickerDialog} = require('web.Colorpicker');
|
||||
|
||||
var media = require('wysiwyg.widgets.media');
|
||||
@@ -16,6 +17,7 @@ return {
|
||||
MediaDialog: MediaDialog,
|
||||
LinkDialog: LinkDialog,
|
||||
ImageCropWidget: ImageCropWidget,
|
||||
LinkPopoverWidget: LinkPopoverWidget,
|
||||
ColorpickerDialog: ColorpickerDialog,
|
||||
|
||||
MediaWidget: media.MediaWidget,
|
||||
|
||||
@@ -470,6 +470,26 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Link Edition : Popover -->
|
||||
<div t-name="wysiwyg.widgets.link.edit.tooltip" class="d-flex">
|
||||
<span class="mr-2 o_we_preview_favicon"><i class="fa fa-globe"/><img class="align-baseline d-none"/></span>
|
||||
<div class="w-100">
|
||||
<div class="d-flex">
|
||||
<a href="#" target="_blank" class="o_we_url_link font-weight-bold flex-grow-1" t-esc="widget.href" title="Open in a new tab"/>
|
||||
<a href="#" class="mx-2 o_we_copy_link text-dark" data-toggle="tooltip" data-placement="top" title="Copy Link">
|
||||
<i class="fa fa-clone"/>
|
||||
</a>
|
||||
<a href="#" class="mx-2 o_we_edit_link text-dark" data-toggle="tooltip" data-placement="top" title="Edit Link">
|
||||
<i class="fa fa-edit"/>
|
||||
</a>
|
||||
<a href="#" class="ml-2 o_we_remove_link text-dark" data-toggle="tooltip" data-placement="top" title="Remove Link">
|
||||
<i class="fa fa-chain-broken"/>
|
||||
</a>
|
||||
</div>
|
||||
<a href="#" target="_blank" class="o_we_full_url mt-1 text-muted d-none" t-esc="widget.href" title="Open in a new tab"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ImageCropWidget controls (allows to crop images on the page) -->
|
||||
<div t-name="wysiwyg.widgets.crop" class="o_we_crop_widget" contenteditable="false">
|
||||
<div class="o_we_cropper_wrapper">
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
'website/static/src/js/editor/wysiwyg_multizone_translate.js',
|
||||
'website/static/src/js/editor/widget_link.js',
|
||||
'website/static/src/js/widgets/media.js',
|
||||
'website/static/src/js/widgets/link_popover_widget.js',
|
||||
],
|
||||
'website.assets_editor': [
|
||||
('include', 'web._assets_helpers'),
|
||||
|
||||
@@ -166,7 +166,7 @@ class Menu(models.Model):
|
||||
menu['id'] = new_id
|
||||
if menu['parent_id'] == old_id:
|
||||
menu['parent_id'] = new_id
|
||||
to_delete = data['to_delete']
|
||||
to_delete = data.get('to_delete')
|
||||
if to_delete:
|
||||
self.browse(to_delete).unlink()
|
||||
for menu in data['data']:
|
||||
|
||||
@@ -8,6 +8,7 @@ var Dialog = require('web.Dialog');
|
||||
const dom = require('web.dom');
|
||||
const weUtils = require('web_editor.utils');
|
||||
var options = require('web_editor.snippets.options');
|
||||
const wLinkPopoverWidget = require('@website/js/widgets/link_popover_widget')[Symbol.for("default")];
|
||||
const wUtils = require('website.utils');
|
||||
require('website.s_popup_options');
|
||||
|
||||
@@ -1184,45 +1185,27 @@ options.registry.ThemeColors = options.registry.OptionsTab.extend({
|
||||
|
||||
options.registry.menu_data = options.Class.extend({
|
||||
/**
|
||||
* When the users selects a menu, a dialog is opened to ask him if he wants
|
||||
* to follow the link (and leave editor), edit the menu or do nothing.
|
||||
* When the users selects a menu, a popover is shown with 4 possible
|
||||
* actions: follow the link in a new tab, copy the menu link, edit the menu,
|
||||
* or edit the menu tree.
|
||||
* The popover shows a preview of the menu link. Remote URL only show the
|
||||
* favicon.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
onFocus: function () {
|
||||
var self = this;
|
||||
(new Dialog(this, {
|
||||
title: _t("Confirmation"),
|
||||
$content: $(core.qweb.render('website.leaving_current_page_edition')),
|
||||
buttons: [
|
||||
{text: _t("Go to Link"), classes: 'btn-primary', click: function () {
|
||||
self.trigger_up('request_save', {
|
||||
reload: false,
|
||||
onSuccess: function () {
|
||||
window.location.href = self.$target.attr('href');
|
||||
},
|
||||
});
|
||||
}},
|
||||
{text: _t("Edit the menu"), classes: 'btn-primary', close: true, click: function () {
|
||||
this.trigger_up('action_demand', {
|
||||
actionName: 'edit_menu',
|
||||
params: [
|
||||
function () {
|
||||
var prom = new Promise(function (resolve, reject) {
|
||||
self.trigger_up('request_save', {
|
||||
onSuccess: resolve,
|
||||
onFailure: reject,
|
||||
});
|
||||
});
|
||||
return prom;
|
||||
},
|
||||
],
|
||||
});
|
||||
}},
|
||||
{text: _t("Stay on this page"), close: true}
|
||||
]
|
||||
})).open();
|
||||
start: function () {
|
||||
wLinkPopoverWidget.createFor(this, this.$target[0]);
|
||||
return this._super(...arguments);
|
||||
},
|
||||
/**
|
||||
* When the users selects another element on the page, makes sure the
|
||||
* popover is closed.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
onBlur: function () {
|
||||
this.$target.popover('hide');
|
||||
},
|
||||
});
|
||||
|
||||
options.registry.company_data = options.Class.extend({
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import contentMenu from 'website.contentMenu';
|
||||
import weWidgets from 'wysiwyg.widgets';
|
||||
import {_t} from 'web.core';
|
||||
|
||||
const NavbarLinkPopoverWidget = weWidgets.LinkPopoverWidget.extend({
|
||||
events: _.extend({}, weWidgets.LinkPopoverWidget.prototype.events, {
|
||||
'click .js_edit_menu': '_onEditMenuClick',
|
||||
}),
|
||||
/**
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
start() {
|
||||
// remove link has no sense on navbar menu links, instead show edit menu
|
||||
const $anchor = $('<a/>', {
|
||||
href: '#', class: 'ml-2 js_edit_menu', title: _t('Edit Menu'),
|
||||
'data-placement': 'top', 'data-toggle': 'tooltip',
|
||||
}).append($('<i/>', {class: 'fa fa-sitemap text-secondary'}));
|
||||
this.$('.o_we_remove_link').replaceWith($anchor);
|
||||
return this._super(...arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Opens the menu item editor.
|
||||
*
|
||||
* @override
|
||||
* @param {Event} ev
|
||||
*/
|
||||
_onEditLinkClick(ev) {
|
||||
var self = this;
|
||||
var $menu = this.$target.find('[data-oe-id]');
|
||||
var dialog = new contentMenu.MenuEntryDialog(this, {}, null, {
|
||||
name: $menu.text(),
|
||||
url: $menu.parent().attr('href'),
|
||||
});
|
||||
dialog.on('save', this, link => {
|
||||
let websiteId;
|
||||
this.trigger_up('context_get', {
|
||||
callback: function (ctx) {
|
||||
websiteId = ctx['website_id'];
|
||||
},
|
||||
});
|
||||
const data = {
|
||||
id: $menu.data('oe-id'),
|
||||
name: link.text,
|
||||
url: link.url,
|
||||
};
|
||||
return this._rpc({
|
||||
model: 'website.menu',
|
||||
method: 'save',
|
||||
args: [websiteId, {'data': [data]}],
|
||||
}).then(function () {
|
||||
self.$target.attr('href', link.url);
|
||||
$menu.text(link.text);
|
||||
self._loadAsyncLinkPreview();
|
||||
});
|
||||
});
|
||||
dialog.open();
|
||||
},
|
||||
/**
|
||||
* Opens the menu tree editor. On menu editor save, current page changes
|
||||
* will also be saved.
|
||||
*
|
||||
* @private
|
||||
* @param {Event} ev
|
||||
*/
|
||||
_onEditMenuClick(ev) {
|
||||
this.trigger_up('action_demand', {
|
||||
actionName: 'edit_menu',
|
||||
params: [
|
||||
() => {
|
||||
const prom = new Promise((resolve, reject) => {
|
||||
this.trigger_up('request_save', {
|
||||
onSuccess: resolve,
|
||||
onFailure: reject,
|
||||
});
|
||||
});
|
||||
return prom;
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Exact same static method but instantiating the specialized class.
|
||||
NavbarLinkPopoverWidget.createFor = weWidgets.LinkPopoverWidget.createFor;
|
||||
|
||||
export default NavbarLinkPopoverWidget;
|
||||
@@ -111,3 +111,30 @@ $o-we-switch-inactive-color: #F7F7F7 !default;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.o_edit_menu_popover {
|
||||
max-width: $popover-max-width * 1.2;
|
||||
// Prevent UI glitch after fetching page preview (size might change)
|
||||
width: $popover-max-width * 1.2;
|
||||
|
||||
.o_we_url_link {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.o_we_full_url {
|
||||
word-break: break-all;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
// clamp (`-webkit-box` display toggle in js)
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
|
||||
&.o_we_webkit_box {
|
||||
display: -webkit-box;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
-webkit-line-clamp: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
<h2 class="mt0">Welcome to your <b>Homepage</b>!</h2>
|
||||
<p class="lead d-none d-md-block">Click on <b>Edit</b> in the top right corner to start designing.</p>
|
||||
</div>
|
||||
<div t-name="website.leaving_current_page_edition">
|
||||
<p>What do you want to do?</p>
|
||||
<p class="text-muted">Your current changes will be saved automatically.</p>
|
||||
</div>
|
||||
|
||||
<!-- Editor top bar which contains the summernote tools and save/discard buttons -->
|
||||
<t t-name="website.editorbar">
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
odoo.define("website.tour.edit_link_popover", function (require) {
|
||||
"use strict";
|
||||
|
||||
const tour = require('web_tour.tour');
|
||||
const wTourUtils = require('website.tour_utils');
|
||||
|
||||
tour.register('edit_link_popover', {
|
||||
test: true,
|
||||
url: '/?enable_editor=1',
|
||||
}, [
|
||||
// 1. Test links in page content (web_editor)
|
||||
wTourUtils.dragNDrop({
|
||||
id: 's_text_image',
|
||||
name: 'Text - Image',
|
||||
}),
|
||||
{
|
||||
content: "Click on a paragraph",
|
||||
trigger: '#wrap .s_text_image p:nth-child(2)',
|
||||
},
|
||||
{
|
||||
content: "Click on 'Link' to open Link Dialog",
|
||||
extra_trigger: '#wrap .s_text_image p:nth-child(2)',
|
||||
trigger: ".note-air-popover [data-event='showLinkDialog']",
|
||||
},
|
||||
{
|
||||
content: "Type the link URL",
|
||||
trigger: '#o_link_dialog_url_input',
|
||||
run: 'text /contactus'
|
||||
},
|
||||
{
|
||||
content: "Save the Link Dialog modal",
|
||||
trigger: '.modal-footer .btn-primary',
|
||||
},
|
||||
{
|
||||
content: "Click on newly created link",
|
||||
trigger: '#wrap .s_text_image p:nth-child(2) a',
|
||||
},
|
||||
{
|
||||
content: "Popover should be shown",
|
||||
trigger: '.o_edit_menu_popover .o_we_url_link:contains("Contact Us")',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
{
|
||||
content: "Click on Edit Link in Popover",
|
||||
trigger: '.o_edit_menu_popover .o_we_edit_link',
|
||||
},
|
||||
{
|
||||
content: "Type the link URL",
|
||||
trigger: '#o_link_dialog_url_input',
|
||||
run: "text /"
|
||||
},
|
||||
{
|
||||
content: "Save the Link Dialog modal",
|
||||
trigger: '.modal-footer .btn-primary',
|
||||
},
|
||||
{
|
||||
content: "Click on link",
|
||||
trigger: '#wrap .s_text_image p:nth-child(2) a',
|
||||
},
|
||||
{
|
||||
content: "Popover should be shown with updated preview data",
|
||||
trigger: '.o_edit_menu_popover .o_we_url_link:contains("Home")',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
{
|
||||
content: "Click on Remove Link in Popover",
|
||||
trigger: '.o_edit_menu_popover .o_we_remove_link',
|
||||
},
|
||||
{
|
||||
content: "Link should be removed",
|
||||
trigger: '#wrap .s_text_image p:nth-child(2):not(:has(a))',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
// 2. Test links in navbar (website)
|
||||
{
|
||||
content: "Click navbar menu Home",
|
||||
trigger: '#top_menu a:contains("Home")',
|
||||
},
|
||||
{
|
||||
content: "Popover should be shown",
|
||||
trigger: '.o_edit_menu_popover .o_we_url_link:contains("Home")',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
{
|
||||
content: "Click on Edit Link in Popover",
|
||||
trigger: '.o_edit_menu_popover .o_we_edit_link',
|
||||
},
|
||||
{
|
||||
content: "Change the URL",
|
||||
trigger: '#o_link_dialog_url_input',
|
||||
run: "text /contactus"
|
||||
},
|
||||
{
|
||||
content: "Save the Link Dialog modal",
|
||||
trigger: '.modal-footer .btn-primary',
|
||||
},
|
||||
{
|
||||
content: "Click on the Home menu again",
|
||||
trigger: '#top_menu a:contains("Home")',
|
||||
},
|
||||
{
|
||||
content: "Popover should be shown with updated preview data",
|
||||
extra_trigger: '#top_menu a:contains("Home")[href="/contactus"]', // href should be changed
|
||||
trigger: '.o_edit_menu_popover .o_we_url_link:contains("Contact Us")',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
{
|
||||
content: "Click on Edit Menu in Popover",
|
||||
trigger: '.o_edit_menu_popover .js_edit_menu',
|
||||
},
|
||||
{
|
||||
content: "Edit Menu (tree) should open",
|
||||
trigger: '.js_add_menu',
|
||||
run: function () {}, // it's a check
|
||||
},
|
||||
]);
|
||||
});
|
||||
@@ -199,3 +199,6 @@ class TestUi(odoo.tests.HttpCase):
|
||||
|
||||
def test_08_website_style_custo(self):
|
||||
self.start_tour("/", "website_style_edition", login="admin")
|
||||
|
||||
def test_09_website_edit_link_popover(self):
|
||||
self.start_tour("/", "edit_link_popover", login="admin")
|
||||
|
||||
@@ -228,9 +228,11 @@ odoo.define('website_form_editor.tour', function (require) {
|
||||
|
||||
// Edit the submit button using linkDialog.
|
||||
{
|
||||
content: "Double click submit button to edit it",
|
||||
content: "Click submit button to show edit popover",
|
||||
trigger: '.s_website_form_send',
|
||||
run: 'dblclick',
|
||||
}, {
|
||||
content: "Click on Edit Link in Popover",
|
||||
trigger: '.o_edit_menu_popover .o_we_edit_link',
|
||||
}, {
|
||||
content: "Check that no URL field is suggested",
|
||||
trigger: 'form:has(#o_link_dialog_label_input:hidden)',
|
||||
|
||||
Reference in New Issue
Block a user