From 0e22069503a0981d476a31484990d7ae6ade663a Mon Sep 17 00:00:00 2001 From: FrancoisGe Date: Mon, 6 Mar 2023 15:09:24 +0000 Subject: [PATCH] [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) --- .../src/views/kanban/kanban_controller.js | 4 +- .../static/src/views/kanban/kanban_record.js | 3 +- .../src/views/kanban/kanban_renderer.js | 56 +++++++++++---- .../web/static/src/views/relational_model.js | 72 +------------------ 4 files changed, 49 insertions(+), 86 deletions(-) diff --git a/addons/web/static/src/views/kanban/kanban_controller.js b/addons/web/static/src/views/kanban/kanban_controller.js index a770039deb7..9c010366fb8 100644 --- a/addons/web/static/src/views/kanban/kanban_controller.js +++ b/addons/web/static/src/views/kanban/kanban_controller.js @@ -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 = { diff --git a/addons/web/static/src/views/kanban/kanban_record.js b/addons/web/static/src/views/kanban/kanban_record.js index 18b92744cac..b82f5297dd6 100644 --- a/addons/web/static/src/views/kanban/kanban_record.js +++ b/addons/web/static/src/views/kanban/kanban_record.js @@ -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, diff --git a/addons/web/static/src/views/kanban/kanban_renderer.js b/addons/web/static/src/views/kanban/kanban_renderer.js index 3037250ea60..ad59cf0b8be 100644 --- a/addons/web/static/src/views/kanban/kanban_renderer.js +++ b/addons/web/static/src/views/kanban/kanban_renderer.js @@ -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); } // ------------------------------------------------------------------------ diff --git a/addons/web/static/src/views/relational_model.js b/addons/web/static/src/views/relational_model.js index e4b56b3683d..16ded49f821 100644 --- a/addons/web/static/src/views/relational_model.js +++ b/addons/web/static/src/views/relational_model.js @@ -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; }