19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-25 12:00:11 +01:00
parent e1d89e11e3
commit a1f02d8cc7
225 changed files with 2335 additions and 775 deletions

View file

@ -1,9 +1,7 @@
import { onWillUpdateProps, useComponent, useState } from "@odoo/owl";
import { useDateTimePicker } from "@web/core/datetime/datetime_picker_hook";
import { Domain } from "@web/core/domain";
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
import { getFieldDomain, useRecordObserver } from "@web/model/relational_model/utils";
import { statusBarField, StatusBarField } from "@web/views/fields/statusbar/statusbar_field";
import { _t } from "@web/core/l10n/translation";
@ -16,38 +14,6 @@ export class VersionsTimeline extends StatusBarField {
this.actionService = useService("action");
this.orm = useService("orm");
if (this.field.type === "many2one") {
this.specialData = useSpecialDataNoCache((orm, props) => {
const { foldField, name: fieldName, record } = props;
const { relation } = record.fields[fieldName];
const fieldNames = [
"display_name",
"contract_type_id",
"contract_date_start",
"contract_date_end",
];
if (foldField) {
fieldNames.push(foldField);
}
const value = record.data[fieldName];
let domain = getFieldDomain(record, fieldName, props.domain);
domain = Domain.and([
[["employee_id", "=", props.record.evalContext.id]],
domain,
]).toList();
if (domain.length && value) {
domain = Domain.or([[["id", "=", value.id]], domain]).toList(
record.evalContext
);
}
return orm.searchRead(
relation,
domain,
fieldNames.filter((fName) => fName in record.fields)
);
});
}
this.dateTimePicker = useDateTimePicker({
target: `datetime-picker-target-version`,
onApply: (date) => {
@ -61,6 +27,24 @@ export class VersionsTimeline extends StatusBarField {
});
}
/** @override **/
getDomain() {
return Domain.and([super.getDomain(),
[["employee_id", "=", this.props.record.evalContext.id]]]
).toList()
}
/** @override **/
getFieldNames() {
const fieldNames = super.getFieldNames();
fieldNames.push([
"contract_type_id",
"contract_date_start",
"contract_date_end",
]);
return fieldNames.filter((fName) => fName in this.props.record.fields);
}
displayContractLines() {
return ["contract_type_id", "contract_date_start", "contract_date_end"].every(
(fieldName) => fieldName in this.props.record.fields
@ -74,6 +58,10 @@ export class VersionsTimeline extends StatusBarField {
{ date_version: date },
]);
const { specialDataCaches } = this.props.record.model;
// Invalidate cache after creating new version.
Object.keys(specialDataCaches).forEach(key => delete specialDataCaches[key]);
await this.props.record.model.load({
context: {
...this.props.record.model.env.searchModel.context,
@ -132,24 +120,6 @@ export class VersionsTimeline extends StatusBarField {
}
}
export function useSpecialDataNoCache(loadFn) {
const component = useComponent();
const orm = component.env.services.orm;
/** @type {{ data: Record<string, T> }} */
const result = useState({ data: {} });
useRecordObserver(async (record, props) => {
result.data = await loadFn(orm, { ...props, record });
});
onWillUpdateProps(async (props) => {
// useRecordObserver callback is not called when the record doesn't change
if (props.record.id === component.props.record.id) {
result.data = await loadFn(orm, props);
}
});
return result;
}
export const versionsTimeline = {
...statusBarField,
component: VersionsTimeline,

View file

@ -8,7 +8,7 @@
</t>
<t t-set-slot="autoCompleteItem" t-slot-scope="autoCompleteItemScope">
<span class="o_avatar_many2x_autocomplete o_avatar d-flex align-items-center">
<img class="rounded me-1" t-attf-src="/web/image/{{relation}}/{{autoCompleteItemScope.record.id}}/avatar_128"/>
<img class="rounded me-1" t-attf-src="/web/image/{{relation}}/{{autoCompleteItemScope.record.id}}/avatar_128?unique={{autoCompleteItemScope.record.data.write_date.ts}}"/>
<span t-out="autoCompleteItemScope.label"/>
</span>
</t>