mirror of
https://github.com/odoo/runbot.git
synced 2025-03-27 13:25:47 +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 { patch } from "@web/core/utils/patch";
|
||||||
import { Message } from "@mail/core/common/message";
|
import { Message } from "@mail/core/common/message";
|
||||||
import { diff_match_patch } from "@runbot/libs/diff_match_patch/diff_match_patch";
|
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, {
|
patch(Message.prototype, {
|
||||||
setup() {
|
setup() {
|
||||||
@ -13,9 +18,6 @@ patch(Message.prototype, {
|
|||||||
const newValue = trackingValue.newValue.value;
|
const newValue = trackingValue.newValue.value;
|
||||||
return ((oldValue && typeof oldValue=== 'string' && oldValue.includes('\n')) && (newValue && typeof oldValue=== 'string' && newValue.includes('\n')))
|
return ((oldValue && typeof oldValue=== 'string' && oldValue.includes('\n')) && (newValue && typeof oldValue=== 'string' && newValue.includes('\n')))
|
||||||
},
|
},
|
||||||
formatTracking(trackingType, trackingValue) {
|
|
||||||
return super.formatTracking(trackingType, trackingValue)
|
|
||||||
},
|
|
||||||
toggleKept() {
|
toggleKept() {
|
||||||
this.kept = !this.kept;
|
this.kept = !this.kept;
|
||||||
},
|
},
|
||||||
@ -29,52 +31,4 @@ patch(Message.prototype, {
|
|||||||
navigator.clipboard.writeText(trackingValue.newValue.value);
|
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>
|
<button class="btn btn-sm btn-outline-primary" t-on-click="copyNewToClipboard(trackingValue)">Copy new value to clipboard</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="o-mail-Message-trackingField ms-1 fst-italic text-muted">(<t t-out="trackingValue.changedField"/>)</div>
|
<div class="o-mail-Message-trackingField ms-1 fst-italic text-muted">(<t t-out="trackingValue.changedField"/>)</div>
|
||||||
<div class="code_diff">
|
<DiffDisplay
|
||||||
<table>
|
fromValue="trackingValue.oldValue.value" toValue="trackingValue.newValue.value"
|
||||||
<t t-foreach="lines(trackingValue)" t-as="line" t-key="line_index">
|
lineFilter="kept ? () => true : undefined"
|
||||||
<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>
|
|
||||||
</t>
|
</t>
|
||||||
<t t-else="">
|
<t t-else="">
|
||||||
<span class="o-mail-Message-trackingOld me-1 px-1 text-muted fw-bold" t-out="formatTrackingOrNone(trackingValue.fieldType, trackingValue.oldValue)"/>
|
<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