diff --git a/addons/web/static/src/views/fields/properties/kanban_properties_field.js b/addons/web/static/src/views/fields/properties/kanban_properties_field.js
new file mode 100644
index 00000000000..9f1fc265d80
--- /dev/null
+++ b/addons/web/static/src/views/fields/properties/kanban_properties_field.js
@@ -0,0 +1,15 @@
+/** @odoo-module **/
+
+import { registry } from "@web/core/registry";
+import { PropertiesField } from "./properties_field";
+
+export class KanbanPropertiesField extends PropertiesField {
+ async _checkDefinitionAccess() {
+ // can not edit properties definition in the kanban view
+ this.state.canChangeDefinition = false;
+ }
+}
+
+KanbanPropertiesField.template = "web.KanbanPropertiesField";
+
+registry.category("fields").add("kanban.properties", KanbanPropertiesField);
diff --git a/addons/web/static/src/views/fields/properties/kanban_properties_field.scss b/addons/web/static/src/views/fields/properties/kanban_properties_field.scss
new file mode 100644
index 00000000000..35dbc965a04
--- /dev/null
+++ b/addons/web/static/src/views/fields/properties/kanban_properties_field.scss
@@ -0,0 +1,3 @@
+.o_kanban_property_field {
+ max-width: 300px;
+}
diff --git a/addons/web/static/src/views/fields/properties/kanban_properties_field.xml b/addons/web/static/src/views/fields/properties/kanban_properties_field.xml
new file mode 100644
index 00000000000..2d412a85f41
--- /dev/null
+++ b/addons/web/static/src/views/fields/properties/kanban_properties_field.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
diff --git a/addons/web/static/src/views/fields/properties/properties_field.js b/addons/web/static/src/views/fields/properties/properties_field.js
index 16974e31d00..e24fa581f73 100644
--- a/addons/web/static/src/views/fields/properties/properties_field.js
+++ b/addons/web/static/src/views/fields/properties/properties_field.js
@@ -154,9 +154,10 @@ export class PropertiesField extends Component {
propertiesValues[targetIndex] = propertiesValues[propertyIndex];
propertiesValues[propertyIndex] = prop;
propertiesValues[propertyIndex].definition_changed = true;
- this.props.update(propertiesValues);
- // move the popover once the DOM is updated
- this.shouldUpdatePopoverPosition = true;
+ this.props.update(propertiesValues).then(() => {
+ // move the popover once the DOM is updated
+ this.shouldUpdatePopoverPosition = true;
+ });
}
/**
@@ -320,6 +321,11 @@ export class PropertiesField extends Component {
popover,
{ position: "top", margin: 10 },
);
+
+ const arrow = popover.querySelector(".popover-arrow");
+ if (arrow) {
+ arrow.classList.add("d-none");
+ }
}
/**
diff --git a/addons/web/static/src/views/fields/properties/property_definition.js b/addons/web/static/src/views/fields/properties/property_definition.js
index 6b3fe1afb39..cff4bbf2932 100644
--- a/addons/web/static/src/views/fields/properties/property_definition.js
+++ b/addons/web/static/src/views/fields/properties/property_definition.js
@@ -280,6 +280,20 @@ export class PropertyDefinition extends Component {
this.state.propertyDefinition = propertyDefinition;
}
+ /**
+ * We activate / deactivate the property in the kanban view.
+ *
+ * @param {boolean} newValue
+ */
+ onViewInKanbanChange(newValue) {
+ const propertyDefinition = {
+ ...this.state.propertyDefinition,
+ view_in_kanban: newValue,
+ };
+ this.props.onChange(propertyDefinition);
+ this.state.propertyDefinition = propertyDefinition;
+ }
+
/* --------------------------------------------------------
* Private methods
* -------------------------------------------------------- */
diff --git a/addons/web/static/src/views/fields/properties/property_definition.scss b/addons/web/static/src/views/fields/properties/property_definition.scss
index 96e34dd3c1e..ea47d5d265f 100644
--- a/addons/web/static/src/views/fields/properties/property_definition.scss
+++ b/addons/web/static/src/views/fields/properties/property_definition.scss
@@ -44,6 +44,7 @@
td {
padding-bottom: 15px;
}
+ .o_field_property_definition_kanban,
.o_field_property_definition_value {
.form-check-input {
margin-left: 3px;
@@ -55,3 +56,20 @@
display: inline-block !important;
}
}
+
+.o_field_property_definition {
+ .o_input_dropdown {
+ .o_properties_external_button,
+ .o_dropdown_button {
+ display: none;
+ }
+
+ &:hover,
+ &:focus-within {
+ .o_properties_external_button,
+ .o_dropdown_button {
+ display: block;
+ }
+ }
+ }
+}
diff --git a/addons/web/static/src/views/fields/properties/property_definition.xml b/addons/web/static/src/views/fields/properties/property_definition.xml
index 35e4fa8f845..2551d8d5ac9 100644
--- a/addons/web/static/src/views/fields/properties/property_definition.xml
+++ b/addons/web/static/src/views/fields/properties/property_definition.xml
@@ -164,6 +164,18 @@
/>
+
+ |
+ View In Kanban
+ |
+
+
+ |
+
diff --git a/addons/web/static/src/views/fields/properties/property_tags.js b/addons/web/static/src/views/fields/properties/property_tags.js
index 3fd455f3202..763b17a4938 100644
--- a/addons/web/static/src/views/fields/properties/property_tags.js
+++ b/addons/web/static/src/views/fields/properties/property_tags.js
@@ -16,6 +16,10 @@ PropertyTagsColorListPopover.components = {
ColorList,
};
+// property tags does not really need timeout because it does not make RPC calls
+export class PropertyTagAutoComplete extends AutoComplete { };
+Object.assign(PropertyTagAutoComplete, { timeout: 0 });
+
export class PropertyTags extends Component {
setup() {
this.notification = useService("notification");
@@ -26,6 +30,15 @@ export class PropertyTags extends Component {
* Public methods / Getters
* -------------------------------------------------------- */
+ /**
+ * Return true if we should display the badges or just the tag label.
+ *
+ * @returns {array}
+ */
+ get displayBadge() {
+ return !this.env.config || this.env.config.viewType !== "kanban";
+ }
+
/**
* Return the list containing tags values and actions for the TagsList component.
*
@@ -38,7 +51,12 @@ export class PropertyTags extends Component {
// Retrieve the tags label and color
// ['a', 'b'] => [['a', 'A', 5], ['b', 'B', 6]]
- const value = this.props.tags.filter((tag) => this.props.selectedTags.indexOf(tag[0]) >= 0);
+ let value = this.props.tags.filter((tag) => this.props.selectedTags.indexOf(tag[0]) >= 0);
+
+ if (!this.displayBadge) {
+ // in kanban view e.g. to not show tag without color
+ value = value.filter(tag => tag[2]);
+ }
const canDeleteTag = !this.props.readonly && this.props.canChangeTags;
@@ -262,7 +280,7 @@ export class PropertyTags extends Component {
PropertyTags.template = "web.PropertyTags";
PropertyTags.components = {
- AutoComplete,
+ AutoComplete: PropertyTagAutoComplete,
TagsList,
ColorList,
Popover: PropertyTagsColorListPopover,
diff --git a/addons/web/static/src/views/fields/properties/property_tags.scss b/addons/web/static/src/views/fields/properties/property_tags.scss
index eb6f463a857..f9d64d257ae 100644
--- a/addons/web/static/src/views/fields/properties/property_tags.scss
+++ b/addons/web/static/src/views/fields/properties/property_tags.scss
@@ -5,8 +5,6 @@
}
.o_field_property_tag {
- border: 1px solid var(--o-input-border-color);
-
.o_tag {
margin: 1px 2px 1px 0;
}
@@ -33,3 +31,8 @@
}
}
}
+
+.o_field_property_tag:not(.readonly):hover,
+.o_field_property_tag:not(.readonly):focus-within {
+ border-bottom: 1px solid var(--o-input-border-color);
+}
diff --git a/addons/web/static/src/views/fields/properties/property_tags.xml b/addons/web/static/src/views/fields/properties/property_tags.xml
index 828bf556eb8..7f90b9f48b5 100644
--- a/addons/web/static/src/views/fields/properties/property_tags.xml
+++ b/addons/web/static/src/views/fields/properties/property_tags.xml
@@ -2,9 +2,10 @@
-