[IMP] runbot: diffable error contents

Adds the ability to make a diff between error contents in the error form
view.
This commit is contained in:
William Braeckman 2025-03-13 10:19:08 +01:00
parent cc39949464
commit fb80ad81c3
3 changed files with 113 additions and 2 deletions

View File

@ -0,0 +1,84 @@
import { Component, useEffect, useState } from '@odoo/owl';
import { registry } from '@web/core/registry';
import { useBus } from '@web/core/utils/hooks';
import { standardFieldProps } from "@web/views/fields/standard_field_props";
import { TextField } from '@web/views/fields/text/text_field';
import { X2ManyField, x2ManyField } from "@web/views/fields/x2many/x2many_field";
import { CheckBox } from "@web/core/checkbox/checkbox";
import { diff_match_patch } from "@runbot/libs/diff_match_patch/diff_match_patch";
import { DiffDisplay } from './diff_display';
export class ErrorContentOne2ManyList extends X2ManyField {
static template = 'runbot.ErrorContentOne2ManyList';
static components = {...X2ManyField.components, CheckBox};
setup() {
super.setup(...arguments);
this.creates = [];
this.state = useState({
useDiff: localStorage.getItem('runbot.error_content_diff_mode') === 'true',
});
useEffect(() => {
localStorage.setItem('runbot.error_content_diff_mode', this.state.useDiff);
this.env.bus.trigger(
'RUNBOT.TOGGLE-DIFF-MODE', {
mode: this.state.useDiff,
},
);
}, () => [this.state.useDiff]);
}
get displayControlPanelButtons() {
return true;
}
onToggle(state) {
this.state.useDiff = state;
}
}
export const errorContentOne2ManyList = {
...x2ManyField,
component: ErrorContentOne2ManyList,
};
export class FieldErrorContentContent extends Component {
static template = 'runbot.FieldErrorContentContent';
static components = { TextField, DiffDisplay };
static props = {...standardFieldProps};
setup() {
// We assume that the content is readonly here
this.otherRecords = this.props.record.model.root.data.error_content_ids.records;
this.state = useState({
useDiff: localStorage.getItem('runbot.error_content_diff_mode') === 'true',
});
useBus(
this.env.bus, 'RUNBOT.TOGGLE-DIFF-MODE',
({detail: {mode}}) => this.state.useDiff = mode,
);
}
get isParent() {
return this.otherRecords[0] === this.props.record;
}
get parent() {
return this.otherRecords[0];
}
}
export const fieldErrorContentContent = {
component: FieldErrorContentContent,
displayName: "Error Content diffable (list)",
supportedTypes: ["html", "text", "char"],
};
registry.category('fields').add('error_content_list', errorContentOne2ManyList);
registry.category('fields').add('list.error_content_content', fieldErrorContentContent);

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-name="runbot.ErrorContentOne2ManyList" t-inherit="web.X2ManyField" t-inherit-mode="primary">
<div class="o_x2m_control_panel d-empty-none mt-1 mb-4" position="attributes">
<attribute name="class">o_x2m_control_panel d-empty-none mt-1</attribute>
</div>
<div role="toolbar" position="inside">
<CheckBox
className="'o_boolean_toggle form-switch'"
value="state.useDiff"
onChange.bind="onToggle"
>
Toggle diff mode
</CheckBox>
</div>
</t>
<t t-name="runbot.FieldErrorContentContent">
<t t-if="isParent || !this.state.useDiff">
<TextField t-props="this.props"/>
</t>
<DiffDisplay t-else=""
fromValue="parent.data.content" toValue="props.record.data.content"
lineFilter="(line) => line.type === 'added'"
/>
</t>
</templates>

View File

@ -15,9 +15,9 @@
<button name="action_view_errors" string="See all linked errors" type="object" class="oe_highlight"/> <button name="action_view_errors" string="See all linked errors" type="object" class="oe_highlight"/>
<group string="Base info"> <group string="Base info">
<field name="name"/> <field name="name"/>
<field name="error_content_ids" readonly="1"> <field name="error_content_ids" readonly="1" widget="error_content_list">
<list limit="5"> <list limit="5">
<field name="content" readonly="1"/> <field name="content" readonly="1" widget="error_content_content"/>
<!--field name="module_name" readonly="1"/--> <!--field name="module_name" readonly="1"/-->
<!--field name="function" readonly="1"/--> <!--field name="function" readonly="1"/-->
<!--field name="file_path" readonly="1"/--> <!--field name="file_path" readonly="1"/-->