OWL
forms
Kanban Many2 One
Odoo 19 OWL component — Kanban Many2 One (views)
Live preview
Interactive
Source excerpt
web/static/src/views/fields/many2one/many2one.js
import { Component, toRaw, useRef, useState } from "@odoo/owl";
import * as BarcodeScanner from "@web/core/barcode/barcode_dialog";
import { isBarcodeScannerSupported } from "@web/core/barcode/barcode_video_scanner";
import { isMobileOS } from "@web/core/browser/feature_detection";
import { makeContext } from "@web/core/context";
import { _t } from "@web/core/l10n/translation";
import { usePopover } from "@web/core/popover/popover_hook";
import { evaluateBooleanExpr } from "@web/core/py_js/py";
import { useService } from "@web/core/utils/hooks";
import { getFieldDomain } from "@web/model/relational_model/utils";
import { Many2XAutocomplete, useOpenMany2XRecord } from "../relational_utils";
///////////////////////////////////////////////////////////////////////////////
// UTILS
///////////////////////////////////////////////////////////////////////////////
function extractData(record) {
let name;
if ("display_name" in record) {
name = record.display_name;
} else if ("name" in record) {
name = record.name.id ? record.name.display_name : record.name;
}
return { id: record.id, display_name: name };
}
export function computeM2OProps(fieldProps) {
const computeLinkCssClass = () => {
const evalContext = fieldProps.record.evalContextWithVirtualIds;
for (const decorationName in fieldProps.decorations) {
if (evaluateBooleanExpr(fieldProps.decorations[decorationName], evalContext)) {
return `text-${decorationName}`;
}
}
return "";
};
return {
canCreate: fieldProps.canCreate,
canCreateEdit: fieldProps.canCreateEdit,
canOpen: fieldProps.canOpen,
canQuickCreate: fieldProps.canQuickCreate,
canScanBarcode: fieldProps.canScanBarcode,
canWrite: fieldProps.canWrite,
context: fieldProps.context,
domain: () => getFieldDomain(fieldProps.record, fieldProps.name, fieldProps.domain),
id: fieldProps.id,
linkCssClass: computeLinkCssClass(),
nameCreateField: fieldProps.nameCreateField,
openActionContext: () => {
const { context, name, openActionContext, record } = fieldProps;
return makeContext(
[openActionContext || context, record.fields[name].context],
record.evalContext
);
},
placeholder: fieldProps.placeholder,
readonly: fieldProps.readonly,
relation: fieldProps.record.fields[fieldProps.name].relation,
searchThreshold: fieldProps.searchThreshold,
preventMemoization: fieldProps.preventMemoization,
string: fieldProps.string || fieldProps.record.fields[fieldProps.name].string || "",
update: (value, options = {}) =>
fieldProps.record.update({ [fieldProps.name]: value }, options),
value: toRaw(fieldProps.record.data[fieldProps.name]),
};
}
///////////////////////////////////////////////////////////////////////////////
// Components
///////////////////////////////////////////////////////////////////////////////
export class Many2One extends Component {
static template = "web.Many2One";
static components = { Many2XAutocomplete };
static props = {
canCreate: { type: Boolean, optional: true },
canCreateEdit: { type: Boolean, optional: true },
canOpen: { type: Boolean, optional: true },
canQuickCreate: { type: Boolean, optional: true },
canScanBarcode: { type: Boolean, optional: true },
canWrite: { type: Boolean, optional: true },
context: { type: Object, optional: true },
createAction: { type: Function, optional: true },
cssClass: { type: String, optional: true },
domain: { type: Function, optional: true },
id: { type: String, optional: true },
linkCssClass: { type: String, optional: true },
nameCreateField: { type: String, optional: true },
openActionContext: { type: Function, optional: true },
openRecordAction: { type: Function, optional: true },
otherSources: { type: Array, optional: true },
placeholder: { type: String, optional: true },
readonly: { type: Boolean, optional: true },
relation: { type: String },
searchMoreLabel: { type: String, optional: true },
searchThreshold: { type: Number, optional: true },
preventMemoization: { type: Boolean, optional: true },
slots: { type: Object, optional: true },
specification: { type: Object, optional: true },
string: { type: String, optional: true },
update: { type: Function },
value: { type: [Array, Object, { value: false }], optional: true },
};
static defaultProps = {
canCreate: true,
canCreateEdit: true,
canOpen: true,
canQuickCreate: true,
canScanBarcode: false,
canWrite: true,
context: {},
domain: [],
linkCssClass: "",
nameCreateField: "name",
otherSources: [],
placeholder: "",
readonly: false,
string: "",
};
Registry / API
- Registry name
KanbanMany2One- Category
—- Module
web- Slug
kanban-many2-one- Nav group
forms