[REF] web: remove some attributes/functions from model

In this commit, we will remove:
- groupedBy because the api is weird, we don't want to handle type abbreviations.
- getAggregableRecords because it is only used in one place.

In this commit, we will also convert canQuickCreate to utils and we will
move it to kanban because it is the only view that uses it.

Part of Task: 3179751

closes odoo/odoo#114459

Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
FrancoisGe
2023-03-07 09:03:01 +01:00
parent 8c5e250b30
commit 0e22069503
4 changed files with 49 additions and 86 deletions
@@ -8,7 +8,7 @@ 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 { useSetupView } from "@web/views/view_hook";
import { KanbanRenderer } from "./kanban_renderer";
import { canQuickCreate, KanbanRenderer } from "./kanban_renderer";
import { Component, useRef } from "@odoo/owl";
@@ -94,7 +94,7 @@ export class KanbanController extends Component {
async createRecord(group) {
const { activeActions, onCreate } = this.props.archInfo;
const { root } = this.model;
if (activeActions.quickCreate && onCreate === "quick_create" && root.canQuickCreate()) {
if (activeActions.quickCreate && onCreate === "quick_create" && canQuickCreate(root)) {
await root.quickCreate(group);
} else if (onCreate && onCreate !== "quick_create") {
const options = {
@@ -213,7 +213,8 @@ export class KanbanRecord extends Component {
this.record = getFormattedRecord(this.props.record);
// Widget
const deletable = activeActions.delete && (!list.groupedBy || !list.groupedBy("m2m"));
const deletable =
activeActions.delete && (!list.groupByField || list.groupByField.type !== "many2many");
const editable = activeActions.edit;
this.widget = {
deletable,
@@ -10,19 +10,46 @@ import { useBus, useService } from "@web/core/utils/hooks";
import { useSortable } from "@web/core/utils/sortable";
import { sprintf } from "@web/core/utils/strings";
import { session } from "@web/session";
import { isAllowedDateField } from "@web/views/relational_model";
import { isNull, isRelational } from "@web/views/utils";
import { archParseBoolean, isNull, isRelational } from "@web/views/utils";
import { ColumnProgress } from "@web/views/view_components/column_progress";
import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog";
import { useBounceButton } from "@web/views/view_hook";
import { ColumnProgress } from "@web/views/view_components/column_progress";
import { KanbanColumnQuickCreate } from "./kanban_column_quick_create";
import { KanbanRecord } from "./kanban_record";
import { KanbanRecordQuickCreate } from "./kanban_record_quick_create";
import { Component, useState, useRef, onWillDestroy } from "@odoo/owl";
import { Component, onWillDestroy, useRef, useState } from "@odoo/owl";
const DRAGGABLE_GROUP_TYPES = ["many2one"];
const MOVABLE_RECORD_TYPES = ["char", "boolean", "integer", "selection", "many2one"];
const QUICK_CREATE_FIELD_TYPES = ["char", "boolean", "many2one", "selection", "many2many"];
/**
* @param {Object} groupByField
* @returns {boolean}
*/
export function isAllowedDateField(groupByField) {
return (
["date", "datetime"].includes(groupByField.type) &&
archParseBoolean(groupByField.attrs.allow_group_range_value)
);
}
/**
* @param {DynamicList} list
* @returns {boolean}
*/
export function canQuickCreate(list) {
if (list.groups && !list.groups.length) {
return false;
}
return (
list.groupByField &&
(isAllowedDateField(list.groupByField) ||
QUICK_CREATE_FIELD_TYPES.includes(list.groupByField.type))
);
}
export class KanbanRenderer extends Component {
static template = "web.KanbanRenderer";
@@ -225,7 +252,7 @@ export class KanbanRenderer extends Component {
}
get showNoContentHelper() {
const { model, isGrouped, groups } = this.props.list;
const { model, isGrouped, groupByField, groups } = this.props.list;
if (model.useSampleModel) {
return true;
}
@@ -234,7 +261,7 @@ export class KanbanRenderer extends Component {
return false;
}
if (groups.length === 0) {
return !this.props.list.groupedBy("m2o");
return groupByField.type !== "many2one";
}
}
return !model.hasData();
@@ -307,7 +334,7 @@ export class KanbanRenderer extends Component {
getGroupUnloadedCount(group) {
const progressBar = group.activeProgressBar;
const records = group.getAggregableRecords();
const records = group.list.records.filter((r) => !r.isInQuickCreation);
return (progressBar ? progressBar.count : group.count) - records.length;
}
@@ -350,12 +377,16 @@ export class KanbanRenderer extends Component {
canArchiveGroup(group) {
const { activeActions } = this.props.archInfo;
const hasActiveField = "active" in group.fields;
return activeActions.archiveGroup && hasActiveField && !this.props.list.groupedBy("m2m");
return (
activeActions.archiveGroup &&
hasActiveField &&
this.props.list.groupByField.type !== "many2many"
);
}
canCreateGroup() {
const { activeActions } = this.props.archInfo;
return activeActions.createGroup && this.props.list.groupedBy("m2o");
return activeActions.createGroup && this.props.list.groupByField.type === "many2one";
}
canDeleteGroup(group) {
@@ -366,10 +397,7 @@ export class KanbanRenderer extends Component {
canDeleteRecord() {
const { activeActions } = this.props.archInfo;
return (
activeActions.delete &&
(!this.props.list.groupedBy || !this.props.list.groupedBy("m2m"))
);
return activeActions.delete && this.props.list.groupByField.type !== "many2many";
}
canEditGroup(group) {
@@ -383,7 +411,7 @@ export class KanbanRenderer extends Component {
}
canQuickCreate() {
return this.props.archInfo.activeActions.quickCreate && this.props.list.canQuickCreate();
return this.props.archInfo.activeActions.quickCreate && canQuickCreate(this.props.list);
}
// ------------------------------------------------------------------------
@@ -20,25 +20,17 @@ import { memoize } from "@web/core/utils/functions";
import { pick } from "@web/core/utils/objects";
import { escape } from "@web/core/utils/strings";
import { session } from "@web/session";
import { getFieldFromRegistry } from "@web/views/fields/field";
import { FormArchParser } from "@web/views/form/form_arch_parser";
import { ListConfirmationDialog } from "@web/views/list/list_confirmation_dialog";
import { Model } from "@web/views/model";
import {
archParseBoolean,
evalDomain,
isNumeric,
isRelational,
isX2Many,
orderByToString,
} from "@web/views/utils";
import { getFieldFromRegistry } from "@web/views/fields/field";
import { evalDomain, isNumeric, isRelational, isX2Many, orderByToString } from "@web/views/utils";
const { DateTime } = luxon;
const preloadedDataRegistry = registry.category("preloadedData");
const { CREATE, UPDATE, DELETE, FORGET, LINK_TO, DELETE_ALL, REPLACE_WITH } = x2ManyCommands;
const QUICK_CREATE_FIELD_TYPES = ["char", "boolean", "many2one", "selection", "many2many"];
const AGGREGATABLE_FIELD_TYPES = ["float", "integer", "monetary"]; // types that can be aggregated in grouped views
const DEFAULT_HANDLE_FIELD = "sequence";
const DEFAULT_QUICK_CREATE_FIELDS = {
@@ -64,17 +56,6 @@ const DEFAULT_QUICK_CREATE_VIEW = {
* }} RawContext
*/
/**
* @param {Object} groupByField
* @returns {boolean}
*/
export function isAllowedDateField(groupByField) {
return (
["date", "datetime"].includes(groupByField.type) &&
archParseBoolean(groupByField.attrs.allow_group_range_value)
);
}
/**
* @param {RawContext} rawContext
* @param {Context} defaultContext
@@ -1674,14 +1655,6 @@ class DynamicList extends DataPoint {
return resIds;
}
canQuickCreate() {
return (
this.groupByField &&
(isAllowedDateField(this.groupByField) ||
QUICK_CREATE_FIELD_TYPES.includes(this.groupByField.type))
);
}
canResequence() {
return this.model.handleField || DEFAULT_HANDLE_FIELD in this.fields;
}
@@ -2326,10 +2299,6 @@ export class DynamicGroupList extends DynamicList {
return group;
}
canQuickCreate() {
return super.canQuickCreate() && this.groups.length;
}
/**
* @see {_createGroup}
*/
@@ -2381,37 +2350,6 @@ export class DynamicGroupList extends DynamicList {
return state;
}
/**
* @param {string} shortType
* @returns {boolean}
*/
groupedBy(shortType) {
const { type } = this.groupByField;
switch (shortType) {
case "m2o":
case "many2one": {
return type === "many2one";
}
case "o2m":
case "one2many": {
return type === "one2many";
}
case "m2m":
case "many2many": {
return type === "many2many";
}
case "m2x":
case "many2x": {
return ["many2one", "many2many"].includes(type);
}
case "x2m":
case "x2many": {
return ["one2many", "many2many"].includes(type);
}
}
return false;
}
hasAggregate(fieldName) {
const group = this.groups[0];
return group && fieldName in group.aggregates;
@@ -2601,7 +2539,7 @@ export class DynamicGroupList extends DynamicList {
} else {
groupParams.displayName = Array.isArray(value) ? value[1] : value;
}
if (this.groupedBy("m2x")) {
if (["many2one", "many2many"].includes(this.groupByField.type)) {
groupParams.recordParams = this.groupByInfo[this.firstGroupBy];
}
break;
@@ -2813,10 +2751,6 @@ export class Group extends DataPoint {
};
}
getAggregableRecords() {
return this.list.records.filter((r) => !r.isInQuickCreation);
}
getAggregates(fieldName) {
return fieldName ? this.aggregates[fieldName] || 0 : this.count;
}