mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 15:35:46 +07:00
[REF] runbot: extract diff display to own component
Also modernize code of the diff match patch use.
This commit is contained in:
parent
9097aa4545
commit
cc39949464
79
runbot/static/src/js/fields/diff_display.js
Normal file
79
runbot/static/src/js/fields/diff_display.js
Normal file
@ -0,0 +1,79 @@
|
||||
import { Component, onWillRender } from '@odoo/owl';
|
||||
|
||||
import { diff_match_patch } from "@runbot/libs/diff_match_patch/diff_match_patch";
|
||||
|
||||
|
||||
export class DiffDisplay extends Component {
|
||||
static template = 'runbot.DiffDisplay';
|
||||
static props = {
|
||||
fromValue: { type: String },
|
||||
toValue: { type: String },
|
||||
lineFilter: { type: Function },
|
||||
}
|
||||
static defaultProps = {
|
||||
lineFilter: (line) => line.type !== 'kept',
|
||||
}
|
||||
|
||||
setup() {
|
||||
onWillRender(() => {
|
||||
this.lines = this.makeLines(this.props.fromValue, this.props.toValue);
|
||||
});
|
||||
}
|
||||
|
||||
makeLines(oldValue, newValue) {
|
||||
const diff = this.makeDiff(oldValue, newValue);
|
||||
const lines = this.prepareForRendering(diff);
|
||||
return lines;
|
||||
}
|
||||
|
||||
makeDiff(text1, text2) {
|
||||
const dmp = new diff_match_patch();
|
||||
const a = dmp.diff_linesToChars_(text1, text2);
|
||||
const lineText1 = a.chars1;
|
||||
const lineText2 = a.chars2;
|
||||
const lineArray = a.lineArray;
|
||||
const diffs = dmp.diff_main(lineText1, lineText2, false);
|
||||
dmp.diff_charsToLines_(diffs, lineArray);
|
||||
dmp.diff_cleanupSemantic(diffs);
|
||||
return diffs;
|
||||
}
|
||||
|
||||
prepareForRendering(diffs) {
|
||||
let preLineCounter = 0;
|
||||
let postLineCounter = 0;
|
||||
return diffs.reduce((lines, {0: diff_type, 1: data}) => {
|
||||
data.split('\n').forEach(line => {
|
||||
line = line
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
let type, colOne, colTwo;
|
||||
switch (diff_type) {
|
||||
case 0: //kept
|
||||
type = 'kept'
|
||||
colOne = ''
|
||||
colTwo = postLineCounter;
|
||||
preLineCounter++; postLineCounter++;
|
||||
break;
|
||||
case -1: //removed
|
||||
type = 'removed';
|
||||
colOne = preLineCounter;
|
||||
colTwo = '-';
|
||||
preLineCounter++;
|
||||
break;
|
||||
case 1: //added
|
||||
type = 'added';
|
||||
colOne = '+';
|
||||
colTwo = postLineCounter;
|
||||
postLineCounter++;
|
||||
break;
|
||||
default:
|
||||
console.warn('Unknown diff_type', diff_type)
|
||||
return;
|
||||
}
|
||||
lines.push({type, colOne, colTwo, line});
|
||||
})
|
||||
return lines
|
||||
}, []);
|
||||
}
|
||||
}
|
14
runbot/static/src/js/fields/diff_display.xml
Normal file
14
runbot/static/src/js/fields/diff_display.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates>
|
||||
<t t-name="runbot.DiffDisplay">
|
||||
<div class="code_diff">
|
||||
<table>
|
||||
<tr t-foreach="lines" t-as="line" t-key="line_index" t-if="props.lineFilter(line)">
|
||||
<td class="col_number" t-out="line.colOne"/>
|
||||
<td class="col_number" t-out="line.colTwo"/>
|
||||
<td class="code" t-att-class="line.type" t-out="line.line"/>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
@ -2,6 +2,11 @@
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
import { Message } from "@mail/core/common/message";
|
||||
import { diff_match_patch } from "@runbot/libs/diff_match_patch/diff_match_patch";
|
||||
import { DiffDisplay } from './diff_display';
|
||||
|
||||
patch(Message, {
|
||||
components: {...Message.components, DiffDisplay},
|
||||
});
|
||||
|
||||
patch(Message.prototype, {
|
||||
setup() {
|
||||
@ -13,9 +18,6 @@ patch(Message.prototype, {
|
||||
const newValue = trackingValue.newValue.value;
|
||||
return ((oldValue && typeof oldValue=== 'string' && oldValue.includes('\n')) && (newValue && typeof oldValue=== 'string' && newValue.includes('\n')))
|
||||
},
|
||||
formatTracking(trackingType, trackingValue) {
|
||||
return super.formatTracking(trackingType, trackingValue)
|
||||
},
|
||||
toggleKept() {
|
||||
this.kept = !this.kept;
|
||||
},
|
||||
@ -29,52 +31,4 @@ patch(Message.prototype, {
|
||||
navigator.clipboard.writeText(trackingValue.newValue.value);
|
||||
};
|
||||
},
|
||||
lines(trackingValue) {
|
||||
const oldValue = trackingValue.oldValue.value;
|
||||
const newValue = trackingValue.newValue.value;
|
||||
const diff = this.makeDiff(oldValue, newValue);
|
||||
const lines = this.prepareForRendering(diff);
|
||||
return lines;
|
||||
},
|
||||
makeDiff(text1, text2) {
|
||||
var dmp = new diff_match_patch();
|
||||
var a = dmp.diff_linesToChars_(text1, text2);
|
||||
var lineText1 = a.chars1;
|
||||
var lineText2 = a.chars2;
|
||||
var lineArray = a.lineArray;
|
||||
var diffs = dmp.diff_main(lineText1, lineText2, false);
|
||||
dmp.diff_charsToLines_(diffs, lineArray);
|
||||
dmp.diff_cleanupSemantic(diffs);
|
||||
return diffs;
|
||||
},
|
||||
prepareForRendering(diffs) {
|
||||
var lines = [];
|
||||
var pre_line_counter = 0
|
||||
var post_line_counter = 0
|
||||
for (var x = 0; x < diffs.length; x++) {
|
||||
var diff_type = diffs[x][0];
|
||||
var data = diffs[x][1];
|
||||
var data_lines = data.split('\n');
|
||||
for (var line_index in data_lines) {
|
||||
var line = data_lines[line_index];
|
||||
line = line.replace(/&/g, '&');
|
||||
line = line.replace(/</g, '<');
|
||||
line = line.replace(/>/g, '>');
|
||||
//text = text.replace(/\n/g, '<br>');
|
||||
//text = text.replace(/ /g, '  ');
|
||||
if (diff_type == -1) {
|
||||
lines.push({type:'removed', pre_line_counter: pre_line_counter, post_line_counter: '-', line: line})
|
||||
pre_line_counter += 1
|
||||
} else if (diff_type == 0) {
|
||||
lines.push({type:'kept', pre_line_counter: '', post_line_counter: post_line_counter, line: line})
|
||||
pre_line_counter += 1
|
||||
post_line_counter +=1
|
||||
} else if (diff_type == 1) {
|
||||
lines.push({type:'added', pre_line_counter: '+', post_line_counter: post_line_counter, line: line})
|
||||
post_line_counter +=1
|
||||
}
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
},
|
||||
});
|
||||
|
@ -10,17 +10,10 @@
|
||||
<button class="btn btn-sm btn-outline-primary" t-on-click="copyNewToClipboard(trackingValue)">Copy new value to clipboard</button>
|
||||
</div>
|
||||
<div class="o-mail-Message-trackingField ms-1 fst-italic text-muted">(<t t-out="trackingValue.changedField"/>)</div>
|
||||
<div class="code_diff">
|
||||
<table>
|
||||
<t t-foreach="lines(trackingValue)" t-as="line" t-key="line_index">
|
||||
<tr t-if="kept or line.type!=='kept'">
|
||||
<td class="col_number" t-out="line.pre_line_counter"/>
|
||||
<td class="col_number" t-out="line.post_line_counter"/>
|
||||
<td class="code" t-att-class="line.type" t-out="line.line"/>
|
||||
</tr>
|
||||
</t>
|
||||
</table>
|
||||
</div>
|
||||
<DiffDisplay
|
||||
fromValue="trackingValue.oldValue.value" toValue="trackingValue.newValue.value"
|
||||
lineFilter="kept ? () => true : undefined"
|
||||
/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span class="o-mail-Message-trackingOld me-1 px-1 text-muted fw-bold" t-out="formatTrackingOrNone(trackingValue.fieldType, trackingValue.oldValue)"/>
|
||||
|
Loading…
Reference in New Issue
Block a user