[IMP] web: add always_range option to daterange widget
always_range option on the daterange widget allows to always display this widget as a range (two inputs separated by an arrow) even if both start/end date are empty and not required. task-3628069 Part-of: odoo/odoo#145167
This commit is contained in:
@@ -40,6 +40,7 @@ export class DateTimeField extends Component {
|
|||||||
endDateField: { type: String, optional: true },
|
endDateField: { type: String, optional: true },
|
||||||
maxDate: { type: String, optional: true },
|
maxDate: { type: String, optional: true },
|
||||||
minDate: { type: String, optional: true },
|
minDate: { type: String, optional: true },
|
||||||
|
alwaysRange: { type: Boolean, optional: true },
|
||||||
placeholder: { type: String, optional: true },
|
placeholder: { type: String, optional: true },
|
||||||
required: { type: Boolean, optional: true },
|
required: { type: Boolean, optional: true },
|
||||||
rounding: { type: Number, optional: true },
|
rounding: { type: Number, optional: true },
|
||||||
@@ -198,7 +199,11 @@ export class DateTimeField extends Component {
|
|||||||
if (!this.relatedField) {
|
if (!this.relatedField) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this.props.required || ensureArray(value).filter(Boolean).length === 2;
|
return (
|
||||||
|
this.props.alwaysRange ||
|
||||||
|
this.props.required ||
|
||||||
|
ensureArray(value).filter(Boolean).length === 2
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -216,9 +221,10 @@ export class DateTimeField extends Component {
|
|||||||
*/
|
*/
|
||||||
shouldShowSeparator() {
|
shouldShowSeparator() {
|
||||||
return (
|
return (
|
||||||
this.state.range &&
|
this.props.alwaysRange ||
|
||||||
(this.props.required ||
|
(this.state.range &&
|
||||||
(!this.isEmpty(this.startDateField) && !this.isEmpty(this.endDateField)))
|
(this.props.required ||
|
||||||
|
(!this.isEmpty(this.startDateField) && !this.isEmpty(this.endDateField))))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,6 +281,7 @@ export const dateField = {
|
|||||||
endDateField: options[END_DATE_FIELD_OPTION],
|
endDateField: options[END_DATE_FIELD_OPTION],
|
||||||
maxDate: options.max_date,
|
maxDate: options.max_date,
|
||||||
minDate: options.min_date,
|
minDate: options.min_date,
|
||||||
|
alwaysRange: archParseBoolean(options.always_range),
|
||||||
placeholder: attrs.placeholder,
|
placeholder: attrs.placeholder,
|
||||||
required: dynamicInfo.required,
|
required: dynamicInfo.required,
|
||||||
rounding: options.rounding && parseInt(options.rounding, 10),
|
rounding: options.rounding && parseInt(options.rounding, 10),
|
||||||
@@ -342,6 +349,15 @@ export const dateRangeField = {
|
|||||||
type: "field",
|
type: "field",
|
||||||
availableTypes: ["date", "datetime"],
|
availableTypes: ["date", "datetime"],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: _t("Always range"),
|
||||||
|
name: "always_range",
|
||||||
|
type: "boolean",
|
||||||
|
default: false,
|
||||||
|
help: _t(
|
||||||
|
`Set to true the full range input has to be display by default, even if empty.`
|
||||||
|
),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
supportedTypes: ["date", "datetime"],
|
supportedTypes: ["date", "datetime"],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<t t-if="props.readonly">
|
<t t-if="props.readonly">
|
||||||
<span class="text-truncate" t-esc="getFormattedValue(0)" />
|
<span class="text-truncate" t-esc="getFormattedValue(0)" />
|
||||||
</t>
|
</t>
|
||||||
<t t-elif="!props.required and isEmpty(startDateField) and !isEmpty(endDateField)">
|
<t t-elif="!props.required and !props.alwaysRange and isEmpty(startDateField) and !isEmpty(endDateField)">
|
||||||
<button
|
<button
|
||||||
class="o_add_date o_add_start_date btn btn-secondary btn-sm w-100"
|
class="o_add_date o_add_start_date btn btn-secondary btn-sm w-100"
|
||||||
t-on-click="() => this.addDate(0)"
|
t-on-click="() => this.addDate(0)"
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
Add start date
|
Add start date
|
||||||
</button>
|
</button>
|
||||||
</t>
|
</t>
|
||||||
<t t-elif="props.required or !isEmpty(startDateField) or startDateField === props.name">
|
<t t-elif="props.required or props.alwaysRange or !isEmpty(startDateField) or startDateField === props.name">
|
||||||
<input
|
<input
|
||||||
t-ref="start-date"
|
t-ref="start-date"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<t t-if="props.readonly">
|
<t t-if="props.readonly">
|
||||||
<span class="text-truncate" t-esc="getFormattedValue(1)" />
|
<span class="text-truncate" t-esc="getFormattedValue(1)" />
|
||||||
</t>
|
</t>
|
||||||
<t t-elif="!props.required and !isEmpty(startDateField) and isEmpty(endDateField)">
|
<t t-elif="!props.required and !props.alwaysRange and !isEmpty(startDateField) and isEmpty(endDateField)">
|
||||||
<button
|
<button
|
||||||
class="o_add_date o_add_end_date btn btn-secondary btn-sm w-100"
|
class="o_add_date o_add_end_date btn btn-secondary btn-sm w-100"
|
||||||
t-on-click="() => this.addDate(1)"
|
t-on-click="() => this.addDate(1)"
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
Add end date
|
Add end date
|
||||||
</button>
|
</button>
|
||||||
</t>
|
</t>
|
||||||
<t t-elif="props.required or !isEmpty(endDateField) or endDateField === props.name">
|
<t t-elif="props.required or props.alwaysRange or !isEmpty(endDateField) or endDateField === props.name">
|
||||||
<input
|
<input
|
||||||
t-ref="end-date"
|
t-ref="end-date"
|
||||||
type="text"
|
type="text"
|
||||||
|
|||||||
@@ -1167,4 +1167,56 @@ QUnit.module("Fields", (hooks) => {
|
|||||||
|
|
||||||
assert.deepEqual(textSiblings, ["->", "02/03/2017"]);
|
assert.deepEqual(textSiblings, ["->", "02/03/2017"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test(
|
||||||
|
"always range: related end date, both start date and end date empty",
|
||||||
|
async (assert) => {
|
||||||
|
serverData.models.partner.records[0].datetime = false;
|
||||||
|
|
||||||
|
await makeView({
|
||||||
|
type: "form",
|
||||||
|
resModel: "partner",
|
||||||
|
serverData,
|
||||||
|
arch: /* xml */ `
|
||||||
|
<form>
|
||||||
|
<field name="datetime" widget="daterange" options="{'end_date_field': 'datetime_end', 'always_range': '1'}"/>
|
||||||
|
</form>`,
|
||||||
|
resId: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(getInputs().length, 2);
|
||||||
|
assert.hasAttrValue(getInputs()[0], "data-field", "datetime");
|
||||||
|
assert.strictEqual(getInputs()[0].value, "");
|
||||||
|
assert.hasAttrValue(getInputs()[1], "data-field", "datetime_end");
|
||||||
|
assert.strictEqual(getInputs()[1].value, "");
|
||||||
|
assert.containsNone(target, ".o_add_date");
|
||||||
|
|
||||||
|
await editInput(getInputs()[0], null, "06/06/2023 12:00:00");
|
||||||
|
|
||||||
|
assert.strictEqual(getInputs().length, 2);
|
||||||
|
assert.hasAttrValue(getInputs()[0], "data-field", "datetime");
|
||||||
|
assert.strictEqual(getInputs()[0].value, "06/06/2023 12:00:00");
|
||||||
|
assert.hasAttrValue(getInputs()[1], "data-field", "datetime_end");
|
||||||
|
assert.strictEqual(getInputs()[1].value, "");
|
||||||
|
assert.containsNone(target, ".o_add_date");
|
||||||
|
|
||||||
|
await editInput(getInputs()[1], null, "07/07/2023 13:00:00");
|
||||||
|
|
||||||
|
assert.strictEqual(getInputs().length, 2);
|
||||||
|
assert.hasAttrValue(getInputs()[0], "data-field", "datetime");
|
||||||
|
assert.strictEqual(getInputs()[0].value, "06/06/2023 12:00:00");
|
||||||
|
assert.hasAttrValue(getInputs()[1], "data-field", "datetime_end");
|
||||||
|
assert.strictEqual(getInputs()[1].value, "07/07/2023 13:00:00");
|
||||||
|
assert.containsNone(target, ".o_add_date");
|
||||||
|
|
||||||
|
await editInput(getInputs()[0], null, "");
|
||||||
|
|
||||||
|
assert.strictEqual(getInputs().length, 2);
|
||||||
|
assert.hasAttrValue(getInputs()[0], "data-field", "datetime");
|
||||||
|
assert.strictEqual(getInputs()[0].value, "");
|
||||||
|
assert.hasAttrValue(getInputs()[1], "data-field", "datetime_end");
|
||||||
|
assert.strictEqual(getInputs()[1].value, "07/07/2023 13:00:00");
|
||||||
|
assert.containsNone(target, ".o_add_date");
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user