[IMP] web: add column creation support for kanban view on mobile
On mobile, there was no way to create a new column in the kanban view. This was specifically annoying in the Project app (the user was able to create the project but couldn't set its stages). This commit enables this feature by adding a `+` icon at the end of the tabs. This button opens a quick-create column widget. If there is no existing column (for example in a newly created project), this quick-create column widget is opened by default. Finally, this commit improves the processing needed for the swipe animation between the columns. Task ID: 1893137 closes odoo/odoo#40722 Signed-off-by: Pierre Paridans <pparidans@users.noreply.github.com> Co-authored-by: Ankit Sathvara <asa@odoo.com> Co-authored-by: Mohammed Shekha <msh@openerp.com> Co-authored-by: Romain Estievenart <res@odoo.com>
This commit is contained in:
committed by
Pierre Paridans
co-authored by
Ankit Sathvara
Mohammed Shekha
parent
40e8834b00
commit
715c136cd2
@@ -6,6 +6,7 @@ odoo.define('web.kanban_column_quick_create', function (require) {
|
||||
* create kanban columns directly from the Kanban view.
|
||||
*/
|
||||
|
||||
var config = require('web.config');
|
||||
var core = require('web.core');
|
||||
var Dialog = require('web.Dialog');
|
||||
var Widget = require('web.Widget');
|
||||
@@ -34,6 +35,7 @@ var ColumnQuickCreate = Widget.extend({
|
||||
this._super.apply(this, arguments);
|
||||
this.examples = options.examples;
|
||||
this.folded = true;
|
||||
this.isMobile = config.device.isMobile;
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -101,9 +103,11 @@ var ColumnQuickCreate = Widget.extend({
|
||||
*/
|
||||
_cancel: function () {
|
||||
if (!this.folded) {
|
||||
this.folded = true;
|
||||
this.$input.val('');
|
||||
this._update();
|
||||
if (!this.isMobile) {
|
||||
this.folded = true;
|
||||
this._update();
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -238,6 +238,7 @@ var KanbanController = BasicController.extend({
|
||||
}).then(function () {
|
||||
self._updateButtons();
|
||||
self.renderer.quickCreateToggleFold();
|
||||
self.renderer.trigger_up("quick_create_column_created");
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
@@ -19,8 +19,12 @@ if (!config.device.isMobile) {
|
||||
}
|
||||
|
||||
KanbanRenderer.include({
|
||||
custom_events: _.extend({}, KanbanRenderer.prototype.custom_events || {}, {
|
||||
quick_create_column_created: '_onColumnAdded',
|
||||
}),
|
||||
events: _.extend({}, KanbanRenderer.prototype.events, {
|
||||
'click .o_kanban_mobile_tab': '_onMobileTabClicked',
|
||||
'click .o_kanban_mobile_add_column': '_onMobileQuickCreateClicked',
|
||||
}),
|
||||
ANIMATE: true, // allows to disable animations for the tests
|
||||
/**
|
||||
@@ -73,12 +77,18 @@ KanbanRenderer.include({
|
||||
|
||||
/**
|
||||
* Displays the quick create record in the active column
|
||||
* override to open quick create record in current active column
|
||||
*
|
||||
* @override
|
||||
* @returns {Promise}
|
||||
*/
|
||||
addQuickCreate: function () {
|
||||
if(this._canCreateColumn() && !this.quickCreate.folded) {
|
||||
this._onMobileQuickCreateClicked();
|
||||
}
|
||||
return this.widgets[this.activeColumnIndex].addQuickCreate();
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides to restore the left property and the scrollTop on the updated
|
||||
* column, and to enable the swipe handlers
|
||||
@@ -86,27 +96,28 @@ KanbanRenderer.include({
|
||||
* @override
|
||||
*/
|
||||
updateColumn: function (localID) {
|
||||
var self = this;
|
||||
var index = _.findIndex(this.widgets, {db_id: localID});
|
||||
var $column = this.widgets[index].$el;
|
||||
var left = $column.css('left');
|
||||
var right = $column.css('right');
|
||||
var scrollTop = $column.scrollTop();
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
$column = self.widgets[index].$el;
|
||||
if (_t.database.parameters.direction === 'rtl') {
|
||||
$column.css({right: right});
|
||||
} else {
|
||||
$column.css({left: left});
|
||||
}
|
||||
$column.scrollTop(scrollTop); // required when clicking on 'Load More'
|
||||
});
|
||||
return this._super.apply(this, arguments)
|
||||
.then(() => this._layoutUpdate(false))
|
||||
// required when clicking on 'Load More'
|
||||
.then(() => $column.scrollTop(scrollTop));
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Check if we use the quick create on mobile
|
||||
* @returns {boolean}
|
||||
* @private
|
||||
*/
|
||||
_canCreateColumn: function() {
|
||||
return this.quickCreateEnabled && this.quickCreate && this.widgets.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the columns positions
|
||||
*
|
||||
@@ -115,45 +126,28 @@ KanbanRenderer.include({
|
||||
*/
|
||||
_computeColumnPosition: function (animate) {
|
||||
if (this.widgets.length) {
|
||||
var self = this;
|
||||
var moveToIndex = this.activeColumnIndex;
|
||||
var updateFunc = animate ? 'animate' : 'css';
|
||||
var rtl = _t.database.parameters.direction === 'rtl';
|
||||
_.each(this.widgets, function (column, index) {
|
||||
var columnID = column.id || column.db_id;
|
||||
var $column = self.$('.o_kanban_group[data-id="' + columnID + '"]');
|
||||
if (index === moveToIndex - 1) {
|
||||
if (rtl) {
|
||||
$column[updateFunc]({right: '-100%'});
|
||||
} else {
|
||||
$column[updateFunc]({left: '-100%'});
|
||||
}
|
||||
} else if (index === moveToIndex + 1) {
|
||||
if (rtl) {
|
||||
$column[updateFunc]({right: '100%'});
|
||||
} else {
|
||||
$column[updateFunc]({left: '100%'});
|
||||
}
|
||||
} else if (index === moveToIndex) {
|
||||
if (rtl) {
|
||||
$column[updateFunc]({right: '0%'});
|
||||
} else {
|
||||
$column[updateFunc]({left: '0%'});
|
||||
}
|
||||
} else if (index < moveToIndex) {
|
||||
if (rtl) {
|
||||
$column.css({right: '-100%'});
|
||||
} else {
|
||||
$column.css({left: '-100%'});
|
||||
}
|
||||
} else if (index > moveToIndex) {
|
||||
if (rtl) {
|
||||
$column.css({right: '100%'});
|
||||
} else {
|
||||
$column.css({left: '100%'});
|
||||
}
|
||||
}
|
||||
});
|
||||
// check rtl to compute correct css value
|
||||
const rtl = _t.database.parameters.direction === 'rtl';
|
||||
|
||||
// display all o_kanban_group
|
||||
this.$('.o_kanban_group').show();
|
||||
|
||||
const $columnAfter = this._toNode(this.widgets.filter((widget, index) => index > this.activeColumnIndex));
|
||||
const promiseAfter = this._updateColumnCss($columnAfter, rtl ? {right: '100%'} : {left: '100%'}, animate);
|
||||
|
||||
const $columnBefore = this._toNode(this.widgets.filter((widget, index) => index < this.activeColumnIndex));
|
||||
const promiseBefore = this._updateColumnCss($columnBefore, rtl ? {right: '-100%'} : {left: '-100%'}, animate);
|
||||
|
||||
const $columnCurrent = this._toNode(this.widgets.filter((widget, index) => index === this.activeColumnIndex));
|
||||
const promiseCurrent = this._updateColumnCss($columnCurrent, rtl ? {right: '0%'} : {left: '0%'}, animate);
|
||||
|
||||
promiseAfter
|
||||
.then(promiseBefore)
|
||||
.then(promiseCurrent)
|
||||
.then(() => {
|
||||
$columnAfter.hide();
|
||||
$columnBefore.hide();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -227,7 +221,7 @@ KanbanRenderer.include({
|
||||
}, 0);
|
||||
// Apply a space around between child if the parent length is higher then the sum of the child width
|
||||
var $tabs = this.$('.o_kanban_mobile_tabs');
|
||||
$tabs.toggleClass('justify-content-around', $tabs.outerWidth() >= widthChilds);
|
||||
$tabs.toggleClass('justify-content-between', $tabs.outerWidth() >= widthChilds);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -308,14 +302,18 @@ KanbanRenderer.include({
|
||||
this._enableSwipe();
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
/**
|
||||
* override to avoid display of example background
|
||||
*/
|
||||
_renderExampleBackground: function () {},
|
||||
/**
|
||||
* @override
|
||||
* @private
|
||||
*/
|
||||
_renderGrouped: function (fragment) {
|
||||
var self = this;
|
||||
this._super.apply(this, arguments);
|
||||
var newFragment = document.createDocumentFragment();
|
||||
this._super.apply(this, [newFragment]);
|
||||
this.defs.push(Promise.all(this.defs).then(function () {
|
||||
var data = [];
|
||||
_.each(self.state.data, function (group) {
|
||||
@@ -327,8 +325,13 @@ KanbanRenderer.include({
|
||||
}
|
||||
});
|
||||
|
||||
var kanbanColumnContainer = document.createElement('div');
|
||||
kanbanColumnContainer.classList.add('o_kanban_columns_content');
|
||||
kanbanColumnContainer.appendChild(newFragment);
|
||||
fragment.appendChild(kanbanColumnContainer);
|
||||
$(qweb.render('KanbanView.MobileTabs', {
|
||||
data: data,
|
||||
quickCreateEnabled: self._canCreateColumn()
|
||||
})).prependTo(fragment);
|
||||
}));
|
||||
},
|
||||
@@ -343,19 +346,76 @@ KanbanRenderer.include({
|
||||
if (self.state.groupedBy.length) {
|
||||
// force first column for kanban view, because the groupedBy can be changed
|
||||
return self._moveToGroup(0);
|
||||
} else {
|
||||
if(self._canCreateColumn()) {
|
||||
self._onMobileQuickCreateClicked();
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the Jquery node (.o_kanban_group) for a list of a given widgets
|
||||
*
|
||||
* @private
|
||||
* @param widgets
|
||||
* @returns {jQuery} the matching .o_kanban_group widgets
|
||||
*/
|
||||
_toNode: function (widgets) {
|
||||
const selectorCss = widgets
|
||||
.map(widget => '.o_kanban_group[data-id="' + (widget.id || widget.db_id) + '"]')
|
||||
.join(', ');
|
||||
return this.$(selectorCss);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the given column to the updated positions
|
||||
*
|
||||
* @private
|
||||
* @param $column The jquery column
|
||||
* @param cssProperties Use to update column
|
||||
* @param {boolean} [animate=false] set to true to animate
|
||||
* @return {Promise}
|
||||
*/
|
||||
_updateColumnCss: function ($column, cssProperties, animate) {
|
||||
if (animate) {
|
||||
return new Promise(resolve => $column.animate(cssProperties, 'fast', resolve));
|
||||
} else {
|
||||
$column.css(cssProperties);
|
||||
return Promise.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onColumnAdded: function () {
|
||||
this._computeTabPosition();
|
||||
if(this._canCreateColumn() && !this.quickCreate.folded) {
|
||||
this.quickCreate.toggleFold();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onMobileQuickCreateClicked: function() {
|
||||
this.$('.o_kanban_group').toggle();
|
||||
this.quickCreate.toggleFold();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {MouseEvent} event
|
||||
*/
|
||||
_onMobileTabClicked: function (event) {
|
||||
if(this._canCreateColumn() && !this.quickCreate.folded) {
|
||||
this.quickCreate.toggleFold();
|
||||
}
|
||||
this._moveToGroup($(event.currentTarget).index(), true);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -61,7 +61,7 @@ var KanbanView = BasicView.extend({
|
||||
editable: activeActions.group_edit,
|
||||
deletable: activeActions.group_delete,
|
||||
archivable: archAttrs.archivable ? !!JSON.parse(archAttrs.archivable) : true,
|
||||
group_creatable: activeActions.group_create && !config.device.isMobile,
|
||||
group_creatable: activeActions.group_create,
|
||||
quickCreateView: archAttrs.quick_create_view || null,
|
||||
recordsDraggable: archAttrs.records_draggable ? !!JSON.parse(archAttrs.records_draggable) : true,
|
||||
hasProgressBar: !!progressBar,
|
||||
|
||||
@@ -4,31 +4,51 @@
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
|
||||
.o_kanban_mobile_tabs {
|
||||
display:flex;
|
||||
.o_kanban_mobile_tabs_container {
|
||||
position: sticky;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: $o-kanban-mobile-tabs-height;
|
||||
position: relative;
|
||||
overflow-x: auto;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
background-color: #5E5E5E;
|
||||
|
||||
.o_kanban_mobile_tab {
|
||||
.o_kanban_mobile_add_column {
|
||||
height: $o-kanban-mobile-tabs-height;
|
||||
padding: 10px 20px;
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
border-left: grey 1px solid;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&.o_current {
|
||||
font-weight: bold;
|
||||
border-bottom: 3px solid $o-brand-primary;
|
||||
}
|
||||
.o_column_title {
|
||||
white-space: nowrap;
|
||||
text-transform: uppercase;
|
||||
.o_kanban_mobile_tabs {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: $o-kanban-mobile-tabs-height;
|
||||
overflow-x: auto;
|
||||
|
||||
.o_kanban_mobile_tab {
|
||||
height: $o-kanban-mobile-tabs-height;
|
||||
padding: 10px 20px;
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
|
||||
&.o_current {
|
||||
font-weight: bold;
|
||||
border-bottom: 3px solid $o-brand-primary;
|
||||
}
|
||||
|
||||
.o_column_title {
|
||||
white-space: nowrap;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_columns_content {
|
||||
position: relative;
|
||||
}
|
||||
// [class] to get same specificity as elsewhere (kanban_view.less)
|
||||
&[class] .o_kanban_group:not(.o_column_folded) {
|
||||
@include o-position-absolute($top: $o-kanban-mobile-tabs-height, $left: 0, $bottom: 0);
|
||||
@@ -58,4 +78,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.o_kanban_view .o_column_quick_create {
|
||||
.o_quick_create_folded {
|
||||
display: none !important;
|
||||
}
|
||||
.o_quick_create_unfolded{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
<button class="btn btn-primary o_kanban_add" type="button">Add</button>
|
||||
</span>
|
||||
</div>
|
||||
<span class="o_discard_msg text-muted float-right">Esc to discard</span>
|
||||
<t t-if="widget.examples">
|
||||
<span t-if="!widget.isMobile" class="o_discard_msg text-muted float-right">Esc to discard</span>
|
||||
<t t-if="widget.examples && !widget.isMobile">
|
||||
<button type="button" class="btn btn-link o_kanban_examples">See examples</button>
|
||||
</t>
|
||||
</div>
|
||||
@@ -319,12 +319,17 @@
|
||||
|
||||
<!-- Mobile templates -->
|
||||
<t t-name="KanbanView.MobileTabs">
|
||||
<div class="o_kanban_mobile_tabs">
|
||||
<t t-foreach="data" t-as="group">
|
||||
<div class="o_kanban_mobile_tab" t-att-data-id="group.res_id or group.id">
|
||||
<span class="o_column_title"><t t-esc="group.value"/></span>
|
||||
<div class="o_kanban_mobile_tabs_container">
|
||||
<div class="o_kanban_mobile_tabs">
|
||||
<t t-foreach="data" t-as="group">
|
||||
<div class="o_kanban_mobile_tab" t-att-data-id="group.res_id or group.id">
|
||||
<span class="o_column_title"><t t-esc="group.value"/></span>
|
||||
</div>
|
||||
</t>
|
||||
<div class="o_kanban_mobile_add_column" t-if="quickCreateEnabled">
|
||||
<i class="fa fa-plus " role="img" aria-label="Add column" title="Add column"/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
@@ -112,11 +112,11 @@ QUnit.module('Views', {
|
||||
}).get();
|
||||
assert.deepEqual(column_ids, tab_ids, "all columns data-id should match mobile tabs data-id");
|
||||
|
||||
// kanban tabs with tab with lower width then available with have justify-content-around class
|
||||
assert.containsN(kanban, '.o_kanban_mobile_tabs.justify-content-around', 1,
|
||||
"should have justify-content-around class");
|
||||
assert.hasClass(kanban.$('.o_kanban_mobile_tabs'), 'justify-content-around',
|
||||
"the mobile tabs have the class 'justify-content-around'");
|
||||
// kanban tabs with tab with lower width then available with have justify-content-between class
|
||||
assert.containsN(kanban, '.o_kanban_mobile_tabs.justify-content-between', 1,
|
||||
"should have justify-content-between class");
|
||||
assert.hasClass(kanban.$('.o_kanban_mobile_tabs'), 'justify-content-between',
|
||||
"the mobile tabs have the class 'justify-content-between'");
|
||||
|
||||
kanban.destroy();
|
||||
});
|
||||
@@ -167,7 +167,7 @@ QUnit.module('Views', {
|
||||
|
||||
// first column should be undefined with framework unique identifier
|
||||
assert.containsN(kanban, '.o_kanban_group', 3, "should have 3 columns");
|
||||
assert.containsOnce(kanban, '.o_kanban_mobile_tabs + .o_kanban_group[data-id^="partner_"]',
|
||||
assert.containsOnce(kanban, '.o_kanban_columns_content .o_kanban_group:first-child[data-id^="partner_"]',
|
||||
"Undefined column should be first and have unique framework identifier as data-id");
|
||||
|
||||
// kanban column should match kanban mobile tabs
|
||||
@@ -179,11 +179,11 @@ QUnit.module('Views', {
|
||||
}).get();
|
||||
assert.deepEqual(column_ids, tab_ids, "all columns data-id should match mobile tabs data-id");
|
||||
|
||||
// kanban tabs with tab with lower width then available with have justify-content-around class
|
||||
assert.containsN(kanban, '.o_kanban_mobile_tabs.justify-content-around', 1,
|
||||
"should have justify-content-around class");
|
||||
assert.hasClass(kanban.$('.o_kanban_mobile_tabs'), 'justify-content-around',
|
||||
"the mobile tabs have the class 'justify-content-around'");
|
||||
// kanban tabs with tab with lower width then available with have justify-content-between class
|
||||
assert.containsN(kanban, '.o_kanban_mobile_tabs.justify-content-between', 1,
|
||||
"should have justify-content-between class");
|
||||
assert.hasClass(kanban.$('.o_kanban_mobile_tabs'), 'justify-content-between',
|
||||
"the mobile tabs have the class 'justify-content-between'");
|
||||
|
||||
kanban.destroy();
|
||||
});
|
||||
@@ -217,13 +217,88 @@ QUnit.module('Views', {
|
||||
}).get();
|
||||
assert.deepEqual(column_ids, tab_ids, "all columns data-id should match mobile tabs data-id");
|
||||
|
||||
// kanban tabs with tab with lower width then available with have justify-content-around class
|
||||
assert.containsN(kanban, '.o_kanban_mobile_tabs.justify-content-around', 1,
|
||||
"should have justify-content-around class");
|
||||
assert.hasClass(kanban.$('.o_kanban_mobile_tabs'), 'justify-content-around',
|
||||
"the mobile tabs have the class 'justify-content-around'");
|
||||
// kanban tabs with tab with lower width then available with have justify-content-between class
|
||||
assert.containsN(kanban, '.o_kanban_mobile_tabs.justify-content-between', 1,
|
||||
"should have justify-content-between class");
|
||||
assert.hasClass(kanban.$('.o_kanban_mobile_tabs'), 'justify-content-between',
|
||||
"the mobile tabs have the class 'justify-content-between'");
|
||||
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('mobile quick create column view rendering', async function (assert) {
|
||||
assert.expect(12);
|
||||
|
||||
var kanban = await createView({
|
||||
View: KanbanView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<kanban class="o_kanban_test o_kanban_small_column" on_create="quick_create">' +
|
||||
'<templates><t t-name="kanban-box">' +
|
||||
'<div><field name="foo"/></div>' +
|
||||
'</t></templates>' +
|
||||
'</kanban>',
|
||||
domain: [['product_id', '!=', false]],
|
||||
groupBy: ['product_id'],
|
||||
});
|
||||
|
||||
// basic rendering tests
|
||||
assert.containsN(kanban, '.o_kanban_group', 2, "should have 2 columns");
|
||||
assert.hasClass(kanban.$('.o_kanban_view > .o_kanban_mobile_tabs_container > .o_kanban_mobile_tabs > div:last'), 'o_kanban_mobile_add_column',
|
||||
"should have column quick create tab and should be displayed as last tab");
|
||||
assert.hasClass(kanban.$('.o_kanban_mobile_tab:first'), 'o_current',
|
||||
"should have first tab as active tab with class 'o_current'");
|
||||
assert.hasClass(kanban.$('.o_kanban_group:first'), 'o_current',
|
||||
"should have first group as active group with class 'o_current'");
|
||||
assert.hasClass(kanban.$('.o_kanban_group:first'), 'o_current',
|
||||
"should have first column as active column with left 0");
|
||||
|
||||
// quick create record in first column(tab)
|
||||
await testUtils.dom.click(kanban.$('.o-kanban-button-new'));
|
||||
assert.hasClass(kanban.$('.o_kanban_group[data-id="3"].o_current > div:nth(1)'), 'o_kanban_quick_create',
|
||||
"should open record quick create when clicking on create button in first column");
|
||||
|
||||
// quick create record not allowed in quick create column tab
|
||||
// clicking quick create record should move to first column and create record in first column
|
||||
await testUtils.dom.click(kanban.$('.o_kanban_mobile_tab:last'));
|
||||
await testUtils.dom.click(kanban.$('.o-kanban-button-new'));
|
||||
assert.hasClass(kanban.$('.o_kanban_group[data-id="5"].o_current > div:nth(1)'), 'o_kanban_quick_create',
|
||||
"should open record quick create when clicking on create button in new column quick create");
|
||||
|
||||
// new quick create column
|
||||
await testUtils.dom.click(kanban.$('.o_kanban_mobile_add_column'));
|
||||
assert.isVisible(kanban.$('.o_quick_create_unfolded'), "kanban quick create should be unfolded by default");
|
||||
assert.isVisible(kanban.$('.o_column_quick_create input'), "the quick create column input should be visible");
|
||||
assert.containsNone(kanban, '.o_kanban_examples', "Should not have See Examples link in mobile");
|
||||
assert.containsNone(kanban, '.o_discard_msg', "Should not have Esc to Discard in mobile kanban");
|
||||
kanban.$('.o_column_quick_create input').val('msh');
|
||||
await testUtils.dom.click(kanban.$('.o_column_quick_create button.o_kanban_add'));
|
||||
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:last span:contains(msh)').length, 1,
|
||||
"the last column(tab) should be the newly created one");
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('mobile no quick create column when grouping on non m2o field', async function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var kanban = await createView({
|
||||
View: KanbanView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<kanban class="o_kanban_test o_kanban_small_column" on_create="quick_create">' +
|
||||
'<templates><t t-name="kanban-box">' +
|
||||
'<div><field name="foo"/></div>' +
|
||||
'<div><field name="int_field"/></div>' +
|
||||
'</t></templates>' +
|
||||
'</kanban>',
|
||||
groupBy: ['int_field'],
|
||||
});
|
||||
|
||||
assert.containsNone(kanban, '.o_kanban_mobile_add_column', "should not have the add column button");
|
||||
assert.containsNone(kanban.$('.o_column_quick_create'),
|
||||
"should not have column quick create tab as we grouped records on integer field");
|
||||
kanban.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user