OWL
data_display
Kanban Controller
Odoo 19 OWL component — Kanban Controller (views)
Live preview
Interactive
Source excerpt
web/static/src/views/kanban/kanban_controller.js
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
import { _t } from "@web/core/l10n/translation";
import { user } from "@web/core/user";
import { useService } from "@web/core/utils/hooks";
import { omit } from "@web/core/utils/objects";
import { evaluateBooleanExpr } from "@web/core/py_js/py";
import { useSetupAction } from "@web/search/action_hook";
import { ActionMenus, STATIC_ACTIONS_GROUP_NUMBER } from "@web/search/action_menus/action_menus";
import { Layout } from "@web/search/layout";
import { usePager } from "@web/search/pager_hook";
import { SearchBar } from "@web/search/search_bar/search_bar";
import { useSearchBarToggler } from "@web/search/search_bar/search_bar_toggler";
import { session } from "@web/session";
import { useModelWithSampleData } from "@web/model/model";
import { standardViewProps } from "@web/views/standard_view_props";
import { MultiRecordViewButton } from "@web/views/view_button/multi_record_view_button";
import { useViewButtons } from "@web/views/view_button/view_button_hook";
import { useExportRecords, useDeleteRecords } from "@web/views/view_hook";
import { addFieldDependencies, extractFieldsFromArchInfo } from "@web/model/relational_model/utils";
import { KanbanCogMenu } from "./kanban_cog_menu";
import { KanbanRenderer } from "./kanban_renderer";
import { useProgressBar } from "./progress_bar_hook";
import { SelectionBox } from "@web/views/view_components/selection_box";
import {
Component,
onMounted,
onWillStart,
reactive,
useEffect,
useRef,
useState,
useSubEnv,
} from "@odoo/owl";
const QUICK_CREATE_FIELD_TYPES = ["char", "boolean", "many2one", "selection", "many2many"];
// -----------------------------------------------------------------------------
export class KanbanController extends Component {
static template = `web.KanbanView`;
static components = {
ActionMenus,
DropdownItem,
Layout,
KanbanRenderer,
MultiRecordViewButton,
SearchBar,
CogMenu: KanbanCogMenu,
SelectionBox,
};
static props = {
...standardViewProps,
editable: { type: Boolean, optional: true },
forceGlobalClick: { type: Boolean, optional: true },
onSelectionChanged: { type: Function, optional: true },
readonly: { type: Boolean, optional: true },
showButtons: { type: Boolean, optional: true },
Compiler: Function,
Model: Function,
Renderer: Function,
buttonTemplate: String,
archInfo: Object,
};
static defaultProps = {
createRecord: () => {},
forceGlobalClick: false,
selectRecord: () => {},
showButtons: true,
};
setup() {
this.actionService = useService("action");
this.dialog = useService("dialog");
const { Model, archInfo } = this.props;
class KanbanSampleModel extends Model {
/**
* @override
*/
hasData() {
if (this.root.groups && !this.root.groups.length) {
// While we don't have any data, we want to display the column quick create and
// example background. Return true so that we don't get sample data instead
return true;
}
return super.hasData();
}
removeSampleDataInGroups() {
if (this.useSampleModel) {
for (const group of this.root.groups) {
const list = group.list;
group.count = 0;
list.count = 0;
if (list.records) {
list.records = [];
} else {
list.groups = [];
}
}
}
}
}
this.model = useState(
useModelWithSampleData(KanbanSampleModel, this.modelParams, this.modelOptions)
);
if (archInfo.progressAttributes) {
const { activeBars } = this.props.state || {};
this.progressBarState = useProgressBar(
archInfo.progressAttributes,
this.model,
this.progressBarAggregateFields,
activeBars
);
}
this.headerButtons = archInfo.headerButtons;
Registry / API
- Registry name
KanbanController- Category
—- Module
web- Slug
kanban-controller- Nav group
data_display