[REF] web: introduce Field component
A simple High Order component that is able to get the actual Field class in the category "fields" registry It takes as minimal props: - record: an object containing the fields key: a meta description of fields - name: the field name - type: the widget type name that xould select the right key in the registry closes odoo-dev/odoo#1018 Related: odoo-dev/enterprise#206 Signed-off-by: Mathieu Duckerts-Antoine <Polymorphe57@users.noreply.github.com> Part-of: odoo/odoo#73311
This commit is contained in:
committed by
Aaron Bohy
parent
82588c57ea
commit
37ac2ec86b
@@ -0,0 +1,115 @@
|
||||
/** @odoo-module **/
|
||||
import { registry } from "@web/core/registry";
|
||||
import legacyFieldRegistry from "web.field_registry";
|
||||
import owlFieldRegistry from "web.field_registry_owl";
|
||||
import { ComponentAdapter } from "web.OwlCompatibility";
|
||||
import { useEffect } from "@web/core/utils/hooks";
|
||||
|
||||
const { Component, tags, hooks } = owl;
|
||||
|
||||
const fieldRegistry = registry.category("fields");
|
||||
|
||||
function getFieldFromRegistry(registry, { fieldType, viewType, fieldName, fieldsDescription }) {
|
||||
if (viewType && fieldType) {
|
||||
const specificType = `${viewType}.${fieldType}`;
|
||||
if (registry.contains(specificType)) {
|
||||
return registry.get(specificType);
|
||||
}
|
||||
}
|
||||
if (!registry.contains(fieldType)) {
|
||||
const field = fieldsDescription[fieldName];
|
||||
fieldType = field && field.type;
|
||||
}
|
||||
return registry.get(fieldType, null);
|
||||
}
|
||||
|
||||
class Field extends Component {
|
||||
static getTangibleField({ record, type, name }) {
|
||||
const FieldClass = getFieldFromRegistry(fieldRegistry, {
|
||||
fieldName: name,
|
||||
fieldType: type,
|
||||
viewType: record.viewtype,
|
||||
fieldsDescription: record.fields,
|
||||
});
|
||||
return { FieldClass };
|
||||
}
|
||||
|
||||
setup() {
|
||||
const { record, type, name } = this.props;
|
||||
this.fieldRef = hooks.useRef("fieldRef");
|
||||
this.FieldComponent = Field.getTangibleField({ record, type, name }).FieldClass;
|
||||
}
|
||||
}
|
||||
|
||||
Field.template = tags.xml/* xml */ `
|
||||
<t t-component="FieldComponent" t-props="props" class="o-field" t-key="props.record.id" t-ref="fieldRef"/>
|
||||
`;
|
||||
|
||||
class FieldSupportsLegacy extends Field {
|
||||
static getTangibleField({ record, type, fieldName }) {
|
||||
let { FieldClass } = super.getTangibleField(...arguments);
|
||||
if (!FieldClass) {
|
||||
FieldClass = getFieldFromRegistry(owlFieldRegistry, {
|
||||
fieldName,
|
||||
fieldType: type,
|
||||
viewType: record.viewType,
|
||||
fieldsDescription: record.fields,
|
||||
});
|
||||
if (FieldClass) {
|
||||
return { FieldClass, isOwlLegacy: true };
|
||||
} else {
|
||||
FieldClass = getFieldFromRegistry(legacyFieldRegistry, {
|
||||
fieldName,
|
||||
fieldType: type,
|
||||
viewType: record.viewType,
|
||||
fieldsDescription: record.fields,
|
||||
});
|
||||
return { FieldClass, isLegacy: true };
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
setup() {
|
||||
super.setup();
|
||||
this.renderId = 0;
|
||||
useEffect(() => {
|
||||
this.renderId++;
|
||||
});
|
||||
if (!this.FieldComponent) {
|
||||
this.env = owl.Component.env;
|
||||
const { record, type, name } = this.props;
|
||||
const { FieldClass, isOwlLegacy, isLegacy } = FieldSupportsLegacy.getTangibleField({
|
||||
record,
|
||||
type,
|
||||
name,
|
||||
});
|
||||
this.FieldComponent = FieldClass;
|
||||
this.isOwlLegacy = isOwlLegacy;
|
||||
this.isLegacy = isLegacy;
|
||||
}
|
||||
}
|
||||
|
||||
get legacyProps() {
|
||||
const legacyRecord = Object.assign({}, this.props.model._legacyRecord_);
|
||||
legacyRecord.data = Object.assign({}, legacyRecord.data, this.props.record.data);
|
||||
return {
|
||||
fieldName: this.props.name,
|
||||
record: legacyRecord,
|
||||
};
|
||||
}
|
||||
|
||||
get widgetArgs() {
|
||||
const { fieldName, record } = this.legacyProps;
|
||||
return [fieldName, record];
|
||||
}
|
||||
}
|
||||
FieldSupportsLegacy.template = tags.xml/* xml */ `<t>
|
||||
<t t-if="!isOwlLegacy and !isLegacy" t-call="${Field.template}" />
|
||||
<t t-elif="isOwlLegacy" t-component="FieldComponent" t-props="legacyProps" />
|
||||
<t t-elif="isLegacy" t-component="ComponentAdapter" widgetArgs="widgetArgs" Component="FieldComponent" t-key="renderId" />
|
||||
</t>
|
||||
`;
|
||||
FieldSupportsLegacy.components = { ComponentAdapter };
|
||||
|
||||
export { FieldSupportsLegacy as Field };
|
||||
@@ -49,6 +49,7 @@ export function prepareRegistriesWithCleanup() {
|
||||
cloneRegistryWithCleanup(registry.category("error_handlers"));
|
||||
cloneRegistryWithCleanup(registry.category("command_provider"));
|
||||
cloneRegistryWithCleanup(registry.category("view_widgets"));
|
||||
cloneRegistryWithCleanup(registry.category("fields"));
|
||||
|
||||
cloneRegistryWithCleanup(registry.category("main_components"));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user