Skip to content

Commit 5f89054

Browse files
bso-odooFrancoisGe
authored andcommitted
Version control option
1 parent 7117ab3 commit 5f89054

File tree

6 files changed

+118
-8
lines changed

6 files changed

+118
-8
lines changed

addons/html_builder/static/src/core/core_plugins.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { ReplacePlugin } from "./replace_plugin";
2121
import { SavePlugin } from "./save_plugin";
2222
import { SaveSnippetPlugin } from "./save_snippet_plugin";
2323
import { SetupEditorPlugin } from "./setup_editor_plugin";
24+
import { VersionControlPlugin } from "./version_control_plugin";
2425
import { VisibilityPlugin } from "./visibility_plugin";
2526

2627
export const CORE_PLUGINS = [
@@ -48,4 +49,5 @@ export const CORE_PLUGINS = [
4849
CachedModelPlugin,
4950
CoreBuilderActionPlugin,
5051
CustomizeTabPlugin,
52+
VersionControlPlugin,
5153
];
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { Plugin } from "@html_editor/plugin";
2+
3+
export class VersionControlPlugin extends Plugin {
4+
static id = "versionControl";
5+
static dependencies = ["builder-options"];
6+
accessPerOutdatedEl = new WeakMap();
7+
static shared = ["hasAccessToOutdatedEl", "giveAccessToOutdatedEl", "replaceWithNewVersion"];
8+
9+
hasAccessToOutdatedEl(el) {
10+
if (this.accessPerOutdatedEl.has(el)) {
11+
return this.accessPerOutdatedEl.get(el);
12+
}
13+
const snippetKey = el.dataset.snippet;
14+
const snippet = this.services["html_builder.snippets"].getOriginalSnippet(snippetKey);
15+
let isUpToDate = true;
16+
if (snippet) {
17+
const {
18+
vcss: originalVcss,
19+
vxml: originalVxml,
20+
vjs: originalVjs,
21+
} = snippet.content.dataset;
22+
const { vcss: elVcss, vxml: elVxml, vjs: elVjs } = el.dataset;
23+
isUpToDate =
24+
originalVcss === elVcss && originalVxml === elVxml && originalVjs === elVjs;
25+
}
26+
this.accessPerOutdatedEl.set(el, isUpToDate);
27+
return isUpToDate;
28+
}
29+
giveAccessToOutdatedEl(el) {
30+
this.accessPerOutdatedEl.set(el, true);
31+
}
32+
replaceWithNewVersion(el) {
33+
const snippetKey = el.dataset.snippet;
34+
const snippet = this.services["html_builder.snippets"].getOriginalSnippet(snippetKey);
35+
const cloneEl = snippet.content.cloneNode(true);
36+
el.replaceWith(cloneEl);
37+
this.dependencies["builder-options"].updateContainers(cloneEl);
38+
}
39+
}

addons/html_builder/static/src/sidebar/option_container.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { BorderConfigurator } from "@html_builder/plugins/border_configurator_op
22
import { ShadowOption } from "@html_builder/plugins/shadow_option";
33
import { getSnippetName, useOptionsSubEnv } from "@html_builder/utils/utils";
44
import { useService } from "@web/core/utils/hooks";
5+
import { useState } from "@odoo/owl";
56
import { useOperation } from "../core/operation_plugin";
67
import {
78
BaseOptionComponent,
@@ -37,6 +38,11 @@ export class OptionsContainer extends BaseOptionComponent {
3738
useVisibilityObserver("content", useApplyVisibility("root"));
3839

3940
this.callOperation = useOperation();
41+
this.state = useState({
42+
isUpToDate: this.env.editor.shared.versionControl.hasAccessToOutdatedEl(
43+
this.props.editingElement
44+
),
45+
});
4046
}
4147

4248
get title() {
@@ -79,4 +85,15 @@ export class OptionsContainer extends BaseOptionComponent {
7985
});
8086
});
8187
}
88+
89+
// Version control
90+
replaceElementWithNewVersion() {
91+
this.callOperation(() => {
92+
this.env.editor.shared.versionControl.replaceWithNewVersion(this.props.editingElement);
93+
});
94+
}
95+
accessOutdated() {
96+
this.env.editor.shared.versionControl.giveAccessToOutdatedEl(this.props.editingElement);
97+
this.state.isUpToDate = true;
98+
}
8299
}

addons/html_builder/static/src/sidebar/option_container.xml

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,25 @@
3939
</t>
4040
</div>
4141
</div>
42-
<div class="we-bg-options-container pb-3" t-ref="content">
43-
<t t-foreach="props.options" t-as="option" t-key="option.id">
44-
<BuilderContext applyTo="option.applyTo">
45-
<t t-if="option.OptionComponent" t-component="option.OptionComponent" t-props="option.props || {}"></t>
46-
<t t-else="" t-call="{{option.template}}"/>
47-
</BuilderContext>
48-
</t>
49-
</div>
42+
<t t-if="state.isUpToDate">
43+
<div class="we-bg-options-container pb-3" t-ref="content">
44+
<t t-foreach="props.options" t-as="option" t-key="option.id">
45+
<BuilderContext applyTo="option.applyTo">
46+
<t t-if="option.OptionComponent" t-component="option.OptionComponent" t-props="option.props || {}"></t>
47+
<t t-else="" t-call="{{option.template}}"/>
48+
</BuilderContext>
49+
</t>
50+
</div>
51+
</t>
52+
<t t-else="">
53+
<div class="o_we_version_control alert alert-info d-flex flex-column p-3 pt-4 align-items-center text-center text-white">
54+
<div>This block is outdated.</div>
55+
<div>You might not be able to customize it anymore.</div>
56+
<button type="button" class="btn o_we_bg_brand_primary py-2 my-4 border-0" t-on-click="() => this.replaceElementWithNewVersion()">REPLACE BY NEW VERSION</button>
57+
<div>You can still access the block options but it might be ineffective.</div>
58+
<button type="button" class="btn o_we_bg_brand_primary py-2 my-4 border-0" t-on-click="() => this.accessOutdated()">ACCESS OPTIONS ANYWAY</button>
59+
</div>
60+
</t>
5061
</div>
5162
</t>
5263

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { expect, test } from "@odoo/hoot";
2+
import { defineWebsiteModels, setupWebsiteBuilder } from "../website_helpers";
3+
import { contains } from "@web/../tests/web_test_helpers";
4+
5+
defineWebsiteModels();
6+
7+
const simpleTitleHtml = `
8+
<section class="s_title" data-snippet="s_title" data-name="Title">
9+
<h1>Title</h1>
10+
</section>`;
11+
12+
test("version control: bypass outdated", async () => {
13+
await setupWebsiteBuilder(simpleTitleHtml, { versionControl: true });
14+
await contains(":iframe .s_title").click();
15+
expect(".o_we_version_control").toHaveCount(1);
16+
expect(".we-bg-options-container:contains('Visibility'").toHaveCount(0);
17+
await contains(".o_we_version_control button:contains('ACCESS')").click();
18+
expect(".o_we_version_control").toHaveCount(0);
19+
expect(".we-bg-options-container:contains('Visibility'").toHaveCount(1);
20+
});
21+
22+
test("version control: replace outdated", async () => {
23+
await setupWebsiteBuilder(simpleTitleHtml, { versionControl: true });
24+
await contains(":iframe .s_title").click();
25+
expect(".o_we_version_control").toHaveCount(1);
26+
expect(".we-bg-options-container:contains('Visibility'").toHaveCount(0);
27+
await contains(".o_we_version_control button:contains('REPLACE')").click();
28+
expect(".o_we_version_control").toHaveCount(0);
29+
expect(".we-bg-options-container:contains('Visibility'").toHaveCount(1);
30+
expect(":iframe .s_title:contains('Your Site Title')").toHaveCount(1);
31+
});

addons/html_builder/static/tests/website_helpers.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Builder } from "@html_builder/builder";
22
import { SetupEditorPlugin } from "@html_builder/core/setup_editor_plugin";
3+
import { VersionControlPlugin } from "@html_builder/core/version_control_plugin";
34
import { EditInteractionPlugin } from "@html_builder/website_builder/plugins/edit_interaction_plugin";
45
import { WebsiteSessionPlugin } from "@html_builder/website_builder/plugins/website_session_plugin";
56
import { WebsiteBuilder } from "@html_builder/website_preview/website_builder_action";
@@ -65,6 +66,7 @@ export async function setupWebsiteBuilder(
6566
loadIframeBundles = false,
6667
loadAssetsFrontendJS = false,
6768
hasToCreateWebsite = true,
69+
versionControl = false,
6870
styleContent,
6971
headerContent = "",
7072
beforeWrapwrapContent = "",
@@ -181,6 +183,14 @@ export async function setupWebsiteBuilder(
181183
});
182184
}
183185

186+
if (!versionControl) {
187+
patchWithCleanup(VersionControlPlugin.prototype, {
188+
hasAccessToOutdatedEl() {
189+
return true;
190+
},
191+
});
192+
}
193+
184194
const iframe = queryOne("iframe[data-src^='/website/force/1']");
185195
if (isBrowserFirefox()) {
186196
await originalIframeLoaded;

0 commit comments

Comments
 (0)