Skip to content

Commit 5beda1a

Browse files
robinlejdetrouxdev
authored andcommitted
[REF] website_payment, *: convert s_donation options to OWL
*: web_editor Given that the Donation options used to make a lot of modifications to the DOM of the `we-list`, all of these have been converted into OWL- compatible ways of modifying the `WeList` template. Specifically, we cannot update the UserValueComponent's DOM on the fly to add new inputs anymore, and we need a proper way to update the value of the ListUserValue according to the option and vice-versa. Both of these concerns are addressed by adapting the WeList's template and adding a new prop `doubleInput`. task-3850413
1 parent 554bae5 commit 5beda1a

File tree

5 files changed

+111
-115
lines changed

5 files changed

+111
-115
lines changed

addons/web_editor/static/src/js/editor/snippets.options.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2650,6 +2650,7 @@ class WeList extends UserValueComponent {
26502650
allowEmpty: { type: String, optional: true },
26512651
newElementsNotToggleable: { type: String, optional: true },
26522652
renderOnInputBlur: { type: String, optional: true },
2653+
doubleInput: { type: String, optional: true },
26532654
};
26542655
static defaultProps = {
26552656
inputType: "text",
@@ -2823,7 +2824,11 @@ class WeList extends UserValueComponent {
28232824
const recordToUpdate = this.state.listRecords.find((rec) =>
28242825
rec.id === this.state._toComparableId(ev.currentTarget.name)
28252826
);
2826-
recordToUpdate.display_name = ev.currentTarget.value;
2827+
if (ev.currentTarget.closest(".o_we_list_record_name")) {
2828+
recordToUpdate.display_name = ev.currentTarget.value;
2829+
} else {
2830+
recordToUpdate.secondInputText = ev.currentTarget.value;
2831+
}
28272832
const timeSinceMousedown = ev.timeStamp - this.mousedownTime;
28282833
if (timeSinceMousedown < 500) {
28292834
// Without this "setTimeOut", "click" events are not triggered when

addons/web_editor/static/src/js/editor/snippets.options.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,14 +295,20 @@
295295
<td t-if="props.unsortable !== 'true'">
296296
<we-button class="o_we_drag_handle o_we_link fa fa-fw fa-arrows" data-no-preview="true"/>
297297
</td>
298-
<td class="o_we_list_record_name">
298+
<td class="o_we_list_record_name" t-att-class="{[listRecord.firstInputClass]: props.doubleInput === 'true'}">
299299
<input t-att-type="props.inputType" t-att-value="listRecord.display_name || props.defaultValue"
300300
t-att-name="listRecord.id" t-att-placeholder="listRecord.placeholder"
301301
t-att="this.getInputDataAtts(listRecord)"
302302
t-on-input="_onListItemBlurInput"
303303
t-on-blur="_onListItemBlurInput"
304304
t-att-disabled="!state.isCustom"/>
305305
</td>
306+
<td t-if="props.doubleInput === 'true'" t-att-class="listRecord.secondInputClass">
307+
<input type="text" t-att-value="listRecord.secondInputText"
308+
t-att-name="listRecord.id"
309+
t-on-input="_onListItemBlurInput"
310+
t-on-blur="_onListItemBlurInput"/>
311+
</td>
306312
<td t-if="props.hasDefault and !listRecord.notToggleable">
307313
<we-button class="o_we_user_value_widget o_we_checkbox_wrapper"
308314
t-att-data-select="listRecord.id"

addons/website_payment/static/src/snippets/s_donation/options.js

Lines changed: 64 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,47 @@
11
/** @odoo-module **/
22

33
import { renderToElement } from "@web/core/utils/render";
4-
import options from '@web_editor/js/editor/snippets.options.legacy';
54
import { _t } from "@web/core/l10n/translation";
5+
import { SnippetOption } from "@web_editor/js/editor/snippets.options";
6+
import { registerWebsiteOption } from "@website/js/editor/snippets.registry";
67

7-
options.registry.Donation = options.Class.extend({
8+
export class Donation extends SnippetOption {
89
/**
910
* @override
1011
*/
11-
start() {
12+
constructor() {
13+
super(...arguments);
1214
this.defaultDescription = _t("Add a description here");
13-
return this._super(...arguments);
14-
},
15+
this.descriptions = [];
16+
if (this.$target[0].dataset.descriptions) {
17+
const descriptionEls = this.$target[0].querySelectorAll('#s_donation_description_inputs > input');
18+
for (const descriptionEl of descriptionEls) {
19+
this.descriptions.push(descriptionEl.value);
20+
}
21+
}
22+
}
23+
/**
24+
* @override
25+
*/
26+
async willStart() {
27+
await super.willStart(...arguments);
28+
this.renderContext.showOptionDescriptions = this.$target[0].dataset.descriptions;
29+
}
1530
/**
1631
* @override
1732
*/
1833
onBuilt() {
1934
this._rebuildPrefilledOptions();
20-
return this._super(...arguments);
21-
},
35+
return super.onBuilt(...arguments);
36+
}
2237
/**
2338
* @override
2439
*/
2540
cleanForSave() {
2641
if (!this.$target[0].dataset.descriptions) {
2742
this._updateDescriptions();
2843
}
29-
},
44+
}
3045

3146
//--------------------------------------------------------------------------
3247
// Public
@@ -36,9 +51,9 @@ options.registry.Donation = options.Class.extend({
3651
* @override
3752
*/
3853
async updateUI() {
39-
await this._super(...arguments);
40-
this._buildDescriptionsList();
41-
},
54+
await super.updateUI(...arguments);
55+
this._updateDescriptions();
56+
}
4257

4358
//--------------------------------------------------------------------------
4459
// Options
@@ -57,29 +72,29 @@ options.registry.Donation = options.Class.extend({
5772
this.$target[0].dataset.customAmount = "slider";
5873
}
5974
this._rebuildPrefilledOptions();
60-
},
75+
}
6176
/**
6277
* Add/remove prefilled buttons.
6378
*
6479
* @see this.selectClass for parameters
6580
*/
6681
togglePrefilledOptions(previewMode, widgetValue, params) {
6782
this.$target[0].dataset.prefilledOptions = widgetValue;
68-
this.$el.find('.o_we_prefilled_options_list').toggleClass('d-none', !widgetValue);
6983
if (!widgetValue && this.$target[0].dataset.displayOptions) {
7084
this.$target[0].dataset.customAmount = "slider";
7185
}
7286
this._rebuildPrefilledOptions();
73-
},
87+
}
7488
/**
7589
* Add/remove description of prefilled buttons.
7690
*
7791
* @see this.selectClass for parameters
7892
*/
7993
toggleOptionDescription(previewMode, widgetValue, params) {
8094
this.$target[0].dataset.descriptions = widgetValue;
95+
this.renderContext.showOptionDescriptions = widgetValue;
8196
this.renderListItems(false, this._buildPrefilledOptionsList());
82-
},
97+
}
8398
/**
8499
* Select an amount input
85100
*
@@ -88,7 +103,7 @@ options.registry.Donation = options.Class.extend({
88103
selectAmountInput(previewMode, widgetValue, params) {
89104
this.$target[0].dataset.customAmount = widgetValue;
90105
this._rebuildPrefilledOptions();
91-
},
106+
}
92107
/**
93108
* Apply the we-list on the target and rebuild the input(s)
94109
*
@@ -97,13 +112,17 @@ options.registry.Donation = options.Class.extend({
97112
renderListItems(previewMode, value, params) {
98113
const valueList = JSON.parse(value);
99114
const donationAmounts = [];
115+
this.descriptions = [];
100116
delete this.$target[0].dataset.donationAmounts;
101117
valueList.forEach((value) => {
102118
donationAmounts.push(value.display_name);
119+
if (value.secondInputText) {
120+
this.descriptions.push(value.secondInputText);
121+
}
103122
});
104123
this.$target[0].dataset.donationAmounts = JSON.stringify(donationAmounts);
105124
this._rebuildPrefilledOptions();
106-
},
125+
}
107126
/**
108127
* Redraws the target whenever the list changes
109128
*
@@ -112,7 +131,7 @@ options.registry.Donation = options.Class.extend({
112131
listChanged(previewMode, value, params) {
113132
this._updateDescriptions();
114133
this._rebuildPrefilledOptions();
115-
},
134+
}
116135
/**
117136
* @see this.selectClass for parameters
118137
*/
@@ -125,7 +144,7 @@ options.registry.Donation = options.Class.extend({
125144
} else if ($amountInput.length) {
126145
$amountInput[0].min = widgetValue;
127146
}
128-
},
147+
}
129148
/**
130149
* @see this.selectClass for parameters
131150
*/
@@ -138,7 +157,7 @@ options.registry.Donation = options.Class.extend({
138157
} else if ($amountInput.length) {
139158
$amountInput[0].max = widgetValue;
140159
}
141-
},
160+
}
142161
/**
143162
* @see this.selectClass for parameters
144163
*/
@@ -148,7 +167,7 @@ options.registry.Donation = options.Class.extend({
148167
if ($rangeSlider.length) {
149168
$rangeSlider[0].step = widgetValue;
150169
}
151-
},
170+
}
152171

153172
//--------------------------------------------------------------------------
154173
// Private
@@ -184,70 +203,41 @@ options.registry.Donation = options.Class.extend({
184203
return this.$target[0].dataset.sliderStep;
185204
}
186205
}
187-
return this._super(...arguments);
188-
},
206+
return super._computeWidgetState(...arguments);
207+
}
189208
/**
190209
* @override
191210
*/
192211
async _computeWidgetVisibility(widgetName, params) {
193212
if (widgetName === 'free_amount_opt') {
194213
return !(this.$target[0].dataset.displayOptions && !this.$target[0].dataset.prefilledOptions);
195214
}
196-
return this._super(...arguments);
197-
},
198-
/**
199-
* @override
200-
*/
201-
_renderCustomXML(uiFragment) {
202-
const list = document.createElement('we-list');
203-
list.dataset.dependencies = "pre_filled_opt";
204-
list.dataset.addItemTitle = _t("Add new pre-filled option");
205-
list.dataset.renderListItems = '';
206-
list.dataset.unsortable = 'true';
207-
list.dataset.inputType = 'number';
208-
list.dataset.defaultValue = 50;
209-
list.dataset.listChanged = '';
210-
$(uiFragment).find('we-checkbox[data-name="pre_filled_opt"]').after(list);
211-
},
215+
return super._computeWidgetVisibility(...arguments);
216+
}
212217
/**
213218
* Build the prefilled options list in the editor panel
214219
*
215220
* @private
216221
*/
217222
_buildPrefilledOptionsList() {
218223
const amounts = JSON.parse(this.$target[0].dataset.donationAmounts);
219-
let valueList = amounts.map(amount => {
224+
let valueList = amounts.map((amount, i) => {
225+
let doubleInput = {};
226+
if (this.$target[0].dataset.descriptions) {
227+
doubleInput = {
228+
firstInputClass: "w-25",
229+
secondInputClass: "w-auto",
230+
secondInputText: this.descriptions[i] || this.defaultDescription,
231+
}
232+
}
220233
return {
221234
id: amount,
222235
display_name: amount,
236+
...doubleInput,
223237
};
224238
});
225239
return JSON.stringify(valueList);
226-
},
227-
/**
228-
* Add descriptions in the prefilled options list of the
229-
* editor panel.
230-
*
231-
* @private
232-
*/
233-
_buildDescriptionsList() {
234-
if (this.$target[0].dataset.descriptions) {
235-
const $descriptions = this.$target.find('#s_donation_description_inputs > input');
236-
const $tableEl = this.$el.find('we-list table');
237-
$tableEl.find("tr").toArray().forEach((trEl, i) => {
238-
const $inputAmount = $(trEl).find('td').first();
239-
$inputAmount.addClass('w-25');
240-
const tdEl = document.createElement('td');
241-
const inputEl = document.createElement('input');
242-
inputEl.type = 'text';
243-
inputEl.value = $descriptions[i] ? $descriptions[i].value : this.defaultDescription;
244-
tdEl.classList.add('w-auto');
245-
tdEl.appendChild(inputEl);
246-
$(tdEl).insertAfter($inputAmount);
247-
});
248-
this._updateDescriptions();
249-
}
250-
},
240+
}
251241
/**
252242
* Update descriptions in the input hidden.
253243
*
@@ -256,16 +246,15 @@ options.registry.Donation = options.Class.extend({
256246
_updateDescriptions() {
257247
const descriptionInputs = this.$target.find('#s_donation_description_inputs');
258248
descriptionInputs.empty();
259-
const descriptions = this.$el.find('we-list input[type=text]');
260-
descriptions.toArray().forEach((description) => {
249+
this.descriptions.forEach((description) => {
261250
const inputEl = document.createElement('input');
262251
inputEl.type = 'hidden';
263252
inputEl.classList.add('o_translatable_input_hidden', 'd-block', 'mb-1', 'w-100');
264253
inputEl.name = 'donation_descriptions';
265-
inputEl.value = description.value;
254+
inputEl.value = description;
266255
descriptionInputs[0].appendChild(inputEl);
267256
});
268-
},
257+
}
269258
/**
270259
* Rebuild options in the DOM.
271260
*
@@ -311,9 +300,10 @@ options.registry.Donation = options.Class.extend({
311300
}));
312301
this.$target.find('#s_donation_description_inputs').after($prefilledButtons);
313302
}
314-
},
303+
}
304+
}
305+
registerWebsiteOption("Donation", {
306+
Class: Donation,
307+
template: "website_payment.s_donation_options",
308+
selector: ".s_donation",
315309
});
316-
317-
export default {
318-
Donation: options.registry.Donation,
319-
};

addons/website_payment/static/src/snippets/s_donation/options.xml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,38 @@
3939
<output class="s_range_bubble" contenteditable="false">25</output>
4040
</div>
4141
</t>
42+
43+
<t t-name="website_payment.s_donation_options">
44+
<WeInput title.translate="Recipient Email" class="'o_we_large'" selectDataAttribute="''"
45+
attributeName="'donationEmail'"/>
46+
<WeCheckbox title.translate="Display Options" name="'display_options_opt'"
47+
displayOptions="'true'" noPreview="'true'"/>
48+
<WeCheckbox title.translate="Pre-filled Options" name="'pre_filled_opt'" noPreview="'true'"
49+
togglePrefilledOptions="'true'" dependencies="'!no_input_opt'"/>
50+
<t t-set="addItemTitle">Add new pre-filled option</t>
51+
<WeList dependencies="'pre_filled_opt'" addItemTitle="addItemTitle" renderListItems="''"
52+
unsortable="'true'" inputType="'number'" defaultValue="'50'" listChanged="''"
53+
doubleInput="renderContext.showOptionDescriptions ? 'true' : ''"/>
54+
<WeCheckbox title.translate="Descriptions" class="'o_we_sublevel_1'" noPreview="'true'"
55+
toggleOptionDescription="'true'" dependencies="'pre_filled_opt'"/>
56+
<WeSelect title.translate="Custom Amount" noPreview="'true'">
57+
<WeButton name="'free_amount_opt'" selectAmountInput="'freeAmount'">Input</WeButton>
58+
<WeButton name="'slider_opt'" selectAmountInput="'slider'"
59+
dependencies="'display_options_opt'">
60+
Slider
61+
</WeButton>
62+
<WeButton name="'no_input_opt'" selectAmountInput="''"
63+
dependencies="'pre_filled_opt'">
64+
None
65+
</WeButton>
66+
</WeSelect>
67+
<WeInput title.translate="Minimum" class="'o_we_sublevel_1'" step="'1'" setMinimumAmount="''"
68+
dependencies="'!no_input_opt'"/>
69+
<WeInput title.translate="Maximum" class="'o_we_sublevel_1'" step="'1'" setMaximumAmount="''"
70+
dependencies="'slider_opt'"/>
71+
<WeInput title.translate="Step" class="'o_we_sublevel_1'" step="'1'" setSliderStep="''"
72+
dependencies="'slider_opt'"/>
73+
<WeInput title.translate="Default Amount" step="'1'" attributeDefaultValue="'25'"
74+
selectDataAttribute="''" attributeName="'defaultAmount'"/>
75+
</t>
4276
</templates>

0 commit comments

Comments
 (0)