Skip to content
24 changes: 22 additions & 2 deletions web_timeline/static/src/views/timeline/timeline_controller.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ export class TimelineController extends Component {
* @returns {jQuery.Deferred}
*/
_onItemDoubleClick(event) {
const item_id =
typeof event.item === "string" && event.item.indexOf("_") !== -1
? Number(event.item.split("_")[0]) || event.item.split("_")[0]
: Number(event.item) || event.item;

// Update event item to be just the ID
event.item = item_id;
return this.openItem(event.item, false);
}

Expand All @@ -92,7 +99,10 @@ export class TimelineController extends Component {
* @returns {Object}
*/
_onUpdate(item) {
const item_id = Number(item.evt.id) || item.evt.id;
const item_id =
typeof item.evt.id === "string" && item.evt.id.indexOf("_") !== -1
? Number(item.evt.id.split("_")[0]) || item.evt.id.split("_")[0]
: Number(item.evt.id) || item.evt.id;
return this.openItem(item_id, true);
}

Expand All @@ -101,6 +111,12 @@ export class TimelineController extends Component {
* @param {Boolean} is_editable
*/
openItem(item_id, is_editable) {
const _id =
typeof item_id === "string" && item_id.indexOf("_") !== -1
? Number(item_id.split("_")[0]) || item_id.split("_")[0]
: Number(item_id) || item_id;
item_id = _id;

if (this.open_popup_action) {
const options = {
resModel: this.model.model_name,
Expand Down Expand Up @@ -243,7 +259,11 @@ export class TimelineController extends Component {
context[`default_${this.date_delay}`] = diff.hours;
}
if (item.group > 0) {
context[`default_${this.model.last_group_bys[0]}`] = item.group;
if (this.model.fields[this.model.last_group_bys[0]].type !== "many2many") {
context[`default_${this.model.last_group_bys[0]}`] = item.group;
} else {
context[`default_${this.model.last_group_bys[0]}`] = [item.group];
}
}
// Show popup
this.dialogService.add(
Expand Down
93 changes: 60 additions & 33 deletions web_timeline/static/src/views/timeline/timeline_model.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ export class TimelineModel extends Model {
// because it is not supported by Odoo
// In the module sale_timesheet_timeline, it is used
// with default_group_by = task_user_ids
let field_to_order = this.params.default_group_by;
if (this.fields[field_to_order].type === "many2many") {
field_to_order = undefined;
}
const field_to_order = this.params.default_group_by;
// If (this.fields[field_to_order].type === "many2many") {
// field_to_order = undefined;
// }
this.data = await this.keepLast.add(
this.orm.call(this.model_name, "search_read", [], {
fields: fields,
Expand All @@ -87,39 +87,61 @@ export class TimelineModel extends Model {
*/
_event_data_transform(record) {
const [date_start, date_stop] = this._get_event_dates(record);
let group = record[this.last_group_bys[0]];
if (group && Array.isArray(group) && group.length > 0) {
group = group[0];
const group = record[this.last_group_bys[0]];
let groups = [];
if (
group &&
Array.isArray(group) &&
group.length === 2 &&
typeof group[1] === "string"
) {
// TODO: this breaks if m2m and only 2 items
// I guess detect if its a number/id or array of ids
groups.push(group[0]);
} else {
group = -1;
groups = group || [];
}
let colorToApply = false;
for (const color of this.colors) {
if (evaluate(color.ast, record)) {
colorToApply = color.color;
}
if (groups.length === 0) {
groups = [-1];
}

let content = record.display_name;
if (this.recordTemplate) {
content = this._render_timeline_item(record);
}
console.log("groups", groups);
// eslint-disable-next-line prefer-const
let all_timeline_items = [];

for (const this_group of groups) {
let colorToApply = false;
for (const color of this.colors) {
if (evaluate(color.ast, record)) {
colorToApply = color.color;
}
}

const timeline_item = {
start: date_start.toJSDate(),
content: content,
id: record.id,
order: record.order,
group: group,
evt: record,
style: `background-color: ${colorToApply};`,
};
// Only specify range end when there actually is one.
// ➔ Instantaneous events / those with inverted dates are displayed as points.
if (date_stop && DateTime.fromISO(date_start) < DateTime.fromISO(date_stop)) {
timeline_item.end = date_stop.toJSDate();
let content = record.display_name;
if (this.recordTemplate) {
content = this._render_timeline_item(record);
}

const timeline_item = {
start: date_start.toJSDate(),
content: content,
id: record.id + (this_group ? `_${this_group}` : ""),
order: record.order,
group: this_group,
evt: record,
style: `background-color: ${colorToApply};`,
};
// Only specify range end when there actually is one.
// ➔ Instantaneous events / those with inverted dates are displayed as points.
if (
date_stop &&
DateTime.fromISO(date_start) < DateTime.fromISO(date_stop)
) {
timeline_item.end = date_stop.toJSDate();
}
all_timeline_items.push(timeline_item);
}
return timeline_item;
return all_timeline_items;
}
/**
* Get dates from given event
Expand Down Expand Up @@ -194,8 +216,13 @@ export class TimelineModel extends Model {
* @returns {jQuery.Deferred}
*/
async remove_completed(event) {
await this.orm.call(this.model_name, "unlink", [[event.evt.id]]);
const unlink_index = this.data.findIndex((item) => item.id === event.evt.id);
const item_id =
typeof event.evt.id === "string" && event.evt.id.indexOf("_") !== -1
? Number(event.evt.id.split("_")[0]) || event.evt.id.split("_")[0]
: Number(event.evt.id) || event.evt.id;

await this.orm.call(this.model_name, "unlink", [[item_id]]);
const unlink_index = this.data.findIndex((item) => item.id === item_id);
if (unlink_index !== -1) {
this.data.splice(unlink_index, 1);
}
Expand Down
10 changes: 8 additions & 2 deletions web_timeline/static/src/views/timeline/timeline_renderer.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,12 +326,16 @@ export class TimelineRenderer extends Component {
* @private
*/
async on_data_loaded(records, adjust_window) {
const data = [];
let data = []; // Changed to non const to allow concat

for (const record of records) {
if (record[this.date_start]) {
data.push(this.model._event_data_transform(record));
// Change here to allow multiple items per record
// Does this make the get_m2m_grouping_datas function obsolete?
data = data.concat(this.model._event_data_transform(record));
}
}

const groups = await this.split_groups(records);
this.timeline.setGroups(groups);
this.timeline.setItems(data);
Expand Down Expand Up @@ -425,6 +429,8 @@ export class TimelineRenderer extends Component {
* @private
*/
on_timeline_double_click(e) {
// Fun Fact: this function never gets called.
// On_timeline_click fires twice but this never does.
if (e.what === "item" && e.item !== -1) {
this.props.onItemDoubleClick(e);
}
Expand Down