mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-20 21:50:49 +01:00
Change diff widget to webcomponent, update diff library
This commit is contained in:
parent
0c98dc30a5
commit
0c387604f8
@ -41,7 +41,7 @@ module.exports = function (grunt) {
|
|||||||
files: {
|
files: {
|
||||||
"pixelegg/css/fancy.min.css": [
|
"pixelegg/css/fancy.min.css": [
|
||||||
"node_modules/flatpickr/dist/themes/light.css",
|
"node_modules/flatpickr/dist/themes/light.css",
|
||||||
"vendor/bower-asset/diff2html/dist/diff2html.css",
|
"node_modules/diff2html/bundles/css/diff2html.min.css",
|
||||||
"vendor/bower-asset/cropper/dist/cropper.min.css",
|
"vendor/bower-asset/cropper/dist/cropper.min.css",
|
||||||
"api/templates/default/css/flags.css",
|
"api/templates/default/css/flags.css",
|
||||||
"api/templates/default/css/htmlarea.css",
|
"api/templates/default/css/htmlarea.css",
|
||||||
@ -52,7 +52,7 @@ module.exports = function (grunt) {
|
|||||||
],
|
],
|
||||||
"pixelegg/css/pixelegg.min.css": [
|
"pixelegg/css/pixelegg.min.css": [
|
||||||
"node_modules/flatpickr/dist/themes/light.css",
|
"node_modules/flatpickr/dist/themes/light.css",
|
||||||
"vendor/bower-asset/diff2html/dist/diff2html.css",
|
"node_modules/diff2html/bundles/css/diff2html.min.css",
|
||||||
"vendor/bower-asset/cropper/dist/cropper.min.css",
|
"vendor/bower-asset/cropper/dist/cropper.min.css",
|
||||||
"api/templates/default/css/flags.css",
|
"api/templates/default/css/flags.css",
|
||||||
"api/templates/default/css/htmlarea.css",
|
"api/templates/default/css/htmlarea.css",
|
||||||
@ -63,7 +63,7 @@ module.exports = function (grunt) {
|
|||||||
],
|
],
|
||||||
"pixelegg/css/mobile.min.css": [
|
"pixelegg/css/mobile.min.css": [
|
||||||
"node_modules/flatpickr/dist/themes/light.css",
|
"node_modules/flatpickr/dist/themes/light.css",
|
||||||
"vendor/bower-asset/diff2html/dist/diff2html.css",
|
"node_modules/diff2html/bundles/css/diff2html.min.css",
|
||||||
"vendor/bower-asset/cropper/dist/cropper.min.css",
|
"vendor/bower-asset/cropper/dist/cropper.min.css",
|
||||||
"api/templates/default/css/flags.css",
|
"api/templates/default/css/flags.css",
|
||||||
"api/templates/default/css/htmlarea.css",
|
"api/templates/default/css/htmlarea.css",
|
||||||
@ -74,7 +74,7 @@ module.exports = function (grunt) {
|
|||||||
],
|
],
|
||||||
"pixelegg/mobile/fw_mobile.min.css": [
|
"pixelegg/mobile/fw_mobile.min.css": [
|
||||||
"node_modules/flatpickr/dist/themes/light.css",
|
"node_modules/flatpickr/dist/themes/light.css",
|
||||||
"api/js/etemplate/lib/jsdifflib/diffview.css",
|
"node_modules/diff2html/bundles/css/diff2html.min.css",
|
||||||
"vendor/bower-asset/cropper/dist/cropper.min.css",
|
"vendor/bower-asset/cropper/dist/cropper.min.css",
|
||||||
"api/templates/default/css/flags.css",
|
"api/templates/default/css/flags.css",
|
||||||
"api/templates/default/css/htmlarea.css",
|
"api/templates/default/css/htmlarea.css",
|
||||||
|
45
api/js/etemplate/Et2Diff/Et2Diff.md
Normal file
45
api/js/etemplate/Et2Diff/Et2Diff.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
```html:preview
|
||||||
|
<et2-diff class="diff-example"></et2-diff>
|
||||||
|
<script>
|
||||||
|
document.querySelector(".diff-example").value = `--- diff
|
||||||
|
+++ diff
|
||||||
|
@@ -1,2 +1,3 @@
|
||||||
|
Diff widget shows changes
|
||||||
|
-highlighting removed words
|
||||||
|
+highlighting added words
|
||||||
|
+and lines
|
||||||
|
`;
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Shows a snippet of a [diff](https://www.gnu.org/software/diffutils/manual/html_node/Unified-Format.html), and if you
|
||||||
|
click on it shows a dialog with the whole diff.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### noDialog
|
||||||
|
|
||||||
|
Use the noDialog property to disable the size limit and show the whole diff
|
||||||
|
|
||||||
|
```html:preview
|
||||||
|
<et2-diff noDialog class="big-diff"></et2-diff>
|
||||||
|
<script>
|
||||||
|
document.querySelector(".big-diff").value = `
|
||||||
|
--- a/doc/etemplate2/etemplate2.0.dtd (revision 30665eb1c58c6d903dde091382c7121f5cf5de88)
|
||||||
|
+++ b/doc/etemplate2/etemplate2.0.dtd (revision e96e8d9469bf4bc5f52a58d0dd8d9c2b87bc914e)
|
||||||
|
@@ -27,21 +27,22 @@
|
||||||
|
|barcode|itempicker|script|countdown|customfields-types|nextmatch|nextmatch-header
|
||||||
|
|nextmatch-customfields|nextmatch-sortheader|et2-nextmatch-header-account|et2-appicon|et2-avatar
|
||||||
|
|et2-avatar-group|et2-box|et2-button|et2-button-copy|et2-button-icon|et2-button-scroll
|
||||||
|
- |et2-button-timestamp|et2-category-tag|et2-checkbox|et2-colorpicker|et2-nextmatch-columnselection
|
||||||
|
- |et2-nextmatch-header-custom|et2-date|et2-date-duration|et2-date-range|et2-date-since|et2-date-time
|
||||||
|
- |et2-date-timeonly|et2-date-time-today|et2-description|et2-description-expose|et2-details|et2-dialog
|
||||||
|
- |et2-dropdown-button|et2-email|et2-email-tag|et2-nextmatch-header-entry|et2-favorites
|
||||||
|
+ |et2-button-timestamp|et2-button-toggle|et2-category-tag|et2-checkbox|et2-colorpicker
|
||||||
|
+ |et2-nextmatch-columnselection|et2-nextmatch-header-custom|et2-date|et2-date-duration|et2-date-range
|
||||||
|
+ |et2-date-since|et2-date-time|et2-date-timeonly|et2-date-time-today|et2-description
|
||||||
|
+ |et2-description-expose|et2-details|et2-dialog|et2-dropdown|et2-dropdown-button|et2-email
|
||||||
|
+ |et2-email-tag|et2-nextmatch-header-entry|et2-favorites|et2-favorites-menu
|
||||||
|
`;
|
||||||
|
</script>
|
||||||
|
```
|
172
api/js/etemplate/Et2Diff/Et2Diff.ts
Normal file
172
api/js/etemplate/Et2Diff/Et2Diff.ts
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
import {customElement} from "lit/decorators/custom-element.js";
|
||||||
|
import {css, html, LitElement, nothing, PropertyValueMap, render} from "lit";
|
||||||
|
import {classMap} from "lit/directives/class-map.js";
|
||||||
|
import {unsafeHTML} from "lit/directives/unsafe-html.js";
|
||||||
|
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
||||||
|
import * as Diff2Html from "diff2html";
|
||||||
|
import {Diff2HtmlConfig} from "diff2html";
|
||||||
|
import {ColorSchemeType} from "diff2html/lib/types";
|
||||||
|
import {property} from "lit/decorators/property.js";
|
||||||
|
import shoelace from "../Styles/shoelace";
|
||||||
|
import {Et2Dialog} from "../Et2Dialog/Et2Dialog";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a nicely formatted diff
|
||||||
|
*/
|
||||||
|
@customElement("et2-diff")
|
||||||
|
export class Et2Diff extends Et2InputWidget(LitElement)
|
||||||
|
{
|
||||||
|
@property({type: Boolean, reflect: true})
|
||||||
|
open = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the dialog and show the whole diff
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
@property({type: Boolean, reflect: true})
|
||||||
|
noDialog = false;
|
||||||
|
|
||||||
|
// CSS in etemplate2.css due to library
|
||||||
|
static get styles()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
shoelace,
|
||||||
|
...super.styles,
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-icon {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
bottom: var(--sl-spacing-medium);
|
||||||
|
right: var(--sl-spacing-medium);
|
||||||
|
background-color: var(--sl-panel-background-color);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(:hover) {
|
||||||
|
.expand-icon {
|
||||||
|
display: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(:not([open])) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(:not([noDialog])) .form-control-input {
|
||||||
|
max-height: 9em;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private readonly diff_options : Diff2HtmlConfig = {
|
||||||
|
matching: "words",
|
||||||
|
drawFileList: false,
|
||||||
|
colorScheme: ColorSchemeType.AUTO
|
||||||
|
};
|
||||||
|
|
||||||
|
updated(changedProperties : PropertyValueMap<any>)
|
||||||
|
{
|
||||||
|
if(changedProperties.has("value") || this.value && this.childElementCount == 0)
|
||||||
|
{
|
||||||
|
// Put diff into lightDOM so styles can leak, since we can't import the library CSS into the component
|
||||||
|
render(html`${unsafeHTML(Diff2Html.html(this.value ?? "", this.diff_options))}`, this, {host: this});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set value(value : string)
|
||||||
|
{
|
||||||
|
if(typeof value == 'string')
|
||||||
|
{
|
||||||
|
|
||||||
|
// Diff2Html likes to have files, we don't have them
|
||||||
|
if(value.indexOf('---') !== 0)
|
||||||
|
{
|
||||||
|
value = "--- diff\n+++ diff\n" + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.value = value;
|
||||||
|
this.requestUpdate("value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_handleClick(e)
|
||||||
|
{
|
||||||
|
const oldValue = this.getAttribute("open")
|
||||||
|
this.toggleAttribute("open");
|
||||||
|
this.requestUpdate("open", oldValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
getDetachedAttributes(attrs)
|
||||||
|
{
|
||||||
|
attrs.push("id", "value", "class");
|
||||||
|
}
|
||||||
|
|
||||||
|
getDetachedNodes() : HTMLElement[]
|
||||||
|
{
|
||||||
|
return [<HTMLElement><unknown>this];
|
||||||
|
}
|
||||||
|
|
||||||
|
setDetachedAttributes(_nodes : HTMLElement[], _values : object, _data? : any) : void
|
||||||
|
{
|
||||||
|
for(let attr in _values)
|
||||||
|
{
|
||||||
|
this[attr] = _values[attr];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render()
|
||||||
|
{
|
||||||
|
const labelTemplate = this._labelTemplate();
|
||||||
|
const helpTextTemplate = this._helpTextTemplate();
|
||||||
|
return html`
|
||||||
|
<div
|
||||||
|
part="form-control"
|
||||||
|
class=${classMap({
|
||||||
|
'form-control': true,
|
||||||
|
'form-control--medium': true,
|
||||||
|
'form-control--has-label': labelTemplate !== nothing,
|
||||||
|
'form-control--has-help-text': helpTextTemplate !== nothing
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
${labelTemplate}
|
||||||
|
<div part="form-control-input" class="form-control-input">
|
||||||
|
<!-- Actual diff goes into lightDOM since we can't import the CSS directly -->
|
||||||
|
${this.open && !this.noDialog ?
|
||||||
|
html`
|
||||||
|
<et2-dialog
|
||||||
|
part=dialog" label="Diff" open
|
||||||
|
buttons=${Et2Dialog.BUTTONS_OK}
|
||||||
|
@click=${(e) =>
|
||||||
|
{
|
||||||
|
// Stop bubble or it will re-show dialog
|
||||||
|
e.stopPropagation()
|
||||||
|
}}
|
||||||
|
@close=${() =>
|
||||||
|
{
|
||||||
|
this.removeAttribute("open");
|
||||||
|
this.requestUpdate("open", true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
</et2-dialog>` : html`
|
||||||
|
${!this.noDialog ? html`
|
||||||
|
<et2-button-icon
|
||||||
|
part="expand-icon"
|
||||||
|
class="expand-icon"
|
||||||
|
image="arrows-fullscreen" label="View" noSubmit></et2-button-icon>` : nothing}
|
||||||
|
<slot></slot>`
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
${helpTextTemplate}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
@ -9,202 +9,15 @@
|
|||||||
* @copyright Nathan Gray 2012
|
* @copyright Nathan Gray 2012
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*egw:uses
|
import {et2_register_widget} from "./et2_core_widget";
|
||||||
/vendor/bower-asset/jquery/dist/jquery.js;
|
import {Et2Diff} from "./Et2Diff/Et2Diff";
|
||||||
/vendor/bower-asset/diff2html/dist/diff2html.min.js;
|
|
||||||
et2_core_valueWidget;
|
|
||||||
*/
|
|
||||||
import "../../../vendor/bower-asset/diff2html/dist/diff2html.min";
|
|
||||||
import {et2_register_widget, WidgetConfig} from "./et2_core_widget";
|
|
||||||
import {ClassWithAttributes} from "./et2_core_inheritance";
|
|
||||||
import {et2_valueWidget} from "./et2_core_valueWidget";
|
|
||||||
import {et2_IDetachedDOM} from "./et2_core_interfaces";
|
|
||||||
import {Et2Dialog} from "./Et2Dialog/Et2Dialog";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that displays the diff between two [text] values
|
* Class that displays the diff between two [text] values
|
||||||
*
|
*
|
||||||
* @augments et2_valueWidget
|
* @augments et2_valueWidget
|
||||||
*/
|
*/
|
||||||
export class et2_diff extends et2_valueWidget implements et2_IDetachedDOM
|
export class et2_diff extends Et2Diff
|
||||||
{
|
{
|
||||||
static readonly _attributes = {
|
|
||||||
"value": {
|
|
||||||
"type": "any"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly diff_options: {
|
|
||||||
"inputFormat":"diff",
|
|
||||||
"matching": "words"
|
|
||||||
};
|
|
||||||
private div: HTMLDivElement;
|
|
||||||
private mini: boolean = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
constructor(_parent, _attrs? : WidgetConfig, _child? : object)
|
|
||||||
{
|
|
||||||
// Call the inherited constructor
|
|
||||||
super(_parent, _attrs, ClassWithAttributes.extendAttributes(et2_diff._attributes, _child || {}));
|
|
||||||
|
|
||||||
// included via etemplate2.css
|
|
||||||
//this.egw().includeCSS('../../../vendor/bower-asset/dist/dist2html.css');
|
|
||||||
this.div = document.createElement("div");
|
|
||||||
jQuery(this.div).addClass('et2_diff');
|
|
||||||
}
|
|
||||||
|
|
||||||
set_value( value)
|
|
||||||
{
|
|
||||||
jQuery(this.div).empty();
|
|
||||||
if(typeof value == 'string') {
|
|
||||||
|
|
||||||
// Diff2Html likes to have files, we don't have them
|
|
||||||
if(value.indexOf('---') !== 0)
|
|
||||||
{
|
|
||||||
value = "--- diff\n+++ diff\n"+value;
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
|
||||||
var diff = Diff2Html.getPrettyHtml(value, this.diff_options);
|
|
||||||
// var ui = new Diff2HtmlUI({diff: diff});
|
|
||||||
// ui.draw(jQuery(this.div), this.diff_options);
|
|
||||||
jQuery(this.div).append(diff);
|
|
||||||
}
|
|
||||||
else if(typeof value != 'object')
|
|
||||||
{
|
|
||||||
jQuery(this.div).append(value);
|
|
||||||
}
|
|
||||||
this.check_mini();
|
|
||||||
}
|
|
||||||
|
|
||||||
check_mini( )
|
|
||||||
{
|
|
||||||
if(!this.mini)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var view = jQuery(this.div).children();
|
|
||||||
this.minify(view);
|
|
||||||
var self = this;
|
|
||||||
jQuery('<span class="ui-icon ui-icon-circle-plus"> </span>')
|
|
||||||
.appendTo(self.div)
|
|
||||||
.css("cursor", "pointer")
|
|
||||||
.click({diff: view, div: self.div, label: self.options.label}, function(e)
|
|
||||||
{
|
|
||||||
var diff = e.data.diff;
|
|
||||||
var div = e.data.div;
|
|
||||||
self.un_minify(diff);
|
|
||||||
let dialog = new Et2Dialog(self.egw());
|
|
||||||
|
|
||||||
dialog.transformAttributes({
|
|
||||||
title: e.data.label,
|
|
||||||
//modal: true,
|
|
||||||
buttons: [{label: 'ok'}],
|
|
||||||
class: "et2_diff",
|
|
||||||
});
|
|
||||||
diff.attr("slot", "content");
|
|
||||||
dialog.addEventListener("open", () =>
|
|
||||||
{
|
|
||||||
diff.appendTo(dialog);
|
|
||||||
if(jQuery(this).parent().height() > jQuery(window).height())
|
|
||||||
{
|
|
||||||
jQuery(this).height(jQuery(window).height() * 0.7);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
dialog.addEventListener("close", () =>
|
|
||||||
{
|
|
||||||
// Need to destroy the dialog, etemplate widget needs divs back where they were
|
|
||||||
self.minify(this);
|
|
||||||
|
|
||||||
// Put it back where it came from, or et2 will error when clear() is called
|
|
||||||
diff.prependTo(div);
|
|
||||||
});
|
|
||||||
document.body.appendChild(dialog);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
set_label( _label)
|
|
||||||
{
|
|
||||||
this.options.label = _label;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make the diff into a mini-diff
|
|
||||||
*
|
|
||||||
* @param {DOMNode|String} view
|
|
||||||
*/
|
|
||||||
minify( view)
|
|
||||||
{
|
|
||||||
view = jQuery(view)
|
|
||||||
.addClass('mini')
|
|
||||||
// Dialog changes these, if resized
|
|
||||||
.css('height', 'inherit')
|
|
||||||
.show();
|
|
||||||
jQuery('th', view).hide();
|
|
||||||
jQuery('td.equal',view).hide()
|
|
||||||
.prevAll().hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Expand mini-diff
|
|
||||||
*
|
|
||||||
* @param {DOMNode|String} view
|
|
||||||
*/
|
|
||||||
un_minify( view)
|
|
||||||
{
|
|
||||||
jQuery(view).removeClass('mini').show();
|
|
||||||
jQuery('th',view).show();
|
|
||||||
jQuery('td.equal',view).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Code for implementing et2_IDetachedDOM
|
|
||||||
* Fast-clonable read-only widget that only deals with DOM nodes, not the widget tree
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build a list of attributes which can be set when working in the
|
|
||||||
* "detached" mode in the _attrs array which is provided
|
|
||||||
* by the calling code.
|
|
||||||
*
|
|
||||||
* @param {object} _attrs
|
|
||||||
*/
|
|
||||||
getDetachedAttributes(_attrs)
|
|
||||||
{
|
|
||||||
_attrs.push("value", "label");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of DOM nodes. The (relativly) same DOM-Nodes have to be
|
|
||||||
* passed to the "setDetachedAttributes" function in the same order.
|
|
||||||
*/
|
|
||||||
getDetachedNodes()
|
|
||||||
{
|
|
||||||
return [this.div];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the given associative attribute->value array and applies the
|
|
||||||
* attributes to the given DOM-Node.
|
|
||||||
*
|
|
||||||
* @param _nodes is an array of nodes which has to be in the same order as
|
|
||||||
* the nodes returned by "getDetachedNodes"
|
|
||||||
* @param _values is an associative array which contains a subset of attributes
|
|
||||||
* returned by the "getDetachedAttributes" function and sets them to the
|
|
||||||
* given values.
|
|
||||||
*/
|
|
||||||
setDetachedAttributes(_nodes, _values)
|
|
||||||
{
|
|
||||||
this.div = _nodes[0];
|
|
||||||
if(typeof _values['label'] != 'undefined')
|
|
||||||
{
|
|
||||||
this.set_label(_values['label']);
|
|
||||||
}
|
|
||||||
if(typeof _values['value'] != 'undefined')
|
|
||||||
{
|
|
||||||
this.set_value(_values['value']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
et2_register_widget(et2_diff, ["diff"]);
|
et2_register_widget(et2_diff, ["diff"]);
|
@ -25,12 +25,12 @@ import {et2_valueWidget} from "./et2_core_valueWidget";
|
|||||||
import {et2_dataview} from "./et2_dataview";
|
import {et2_dataview} from "./et2_dataview";
|
||||||
import {et2_dataview_column} from "./et2_dataview_model_columns";
|
import {et2_dataview_column} from "./et2_dataview_model_columns";
|
||||||
import {et2_dataview_controller} from "./et2_dataview_controller";
|
import {et2_dataview_controller} from "./et2_dataview_controller";
|
||||||
import {et2_diff} from "./et2_widget_diff";
|
|
||||||
import {et2_IDetachedDOM, et2_IResizeable} from "./et2_core_interfaces";
|
import {et2_IDetachedDOM, et2_IResizeable} from "./et2_core_interfaces";
|
||||||
import {et2_customfields_list} from "./et2_extension_customfields";
|
import {et2_customfields_list} from "./et2_extension_customfields";
|
||||||
import {et2_selectbox} from "./et2_widget_selectbox";
|
import {et2_selectbox} from "./et2_widget_selectbox";
|
||||||
import {loadWebComponent} from "./Et2Widget/Et2Widget";
|
import {loadWebComponent} from "./Et2Widget/Et2Widget";
|
||||||
import {cleanSelectOptions, SelectOption} from "./Et2Select/FindSelectOptions";
|
import {cleanSelectOptions, SelectOption} from "./Et2Select/FindSelectOptions";
|
||||||
|
import {Et2Diff} from "./Et2Diff/Et2Diff";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eTemplate history log widget displays a list of changes to the current record.
|
* eTemplate history log widget displays a list of changes to the current record.
|
||||||
@ -98,7 +98,7 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
|||||||
private dataview: et2_dataview;
|
private dataview: et2_dataview;
|
||||||
private controller: et2_dataview_controller;
|
private controller: et2_dataview_controller;
|
||||||
private fields: any;
|
private fields: any;
|
||||||
private diff: et2_diff;
|
private diff : { nodes : Et2Diff, widget : Et2Diff };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@ -399,11 +399,10 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Widget for text diffs
|
// Widget for text diffs
|
||||||
const diff = et2_createWidget('diff', {}, this);
|
const diff = loadWebComponent('et2-diff', {}, this);
|
||||||
this.diff = {
|
this.diff = {
|
||||||
// @ts-ignore
|
|
||||||
widget: diff,
|
widget: diff,
|
||||||
nodes: jQuery(diff.getDetachedNodes())
|
nodes: diff
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,7 +655,7 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
|||||||
widget = self.diff.widget;
|
widget = self.diff.widget;
|
||||||
nodes = self.diff.nodes.clone();
|
nodes = self.diff.nodes.clone();
|
||||||
|
|
||||||
if(widget) widget.setDetachedAttributes(nodes, {
|
if(nodes) nodes.setDetachedAttributes(nodes, {
|
||||||
value: value,
|
value: value,
|
||||||
label: jthis.parents("td").prev().text()
|
label: jthis.parents("td").prev().text()
|
||||||
});
|
});
|
||||||
@ -678,7 +677,11 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
|||||||
{
|
{
|
||||||
const id = widget._children[j].id;
|
const id = widget._children[j].id;
|
||||||
const widget_value = value ? value[id] || "" : "";
|
const widget_value = value ? value[id] || "" : "";
|
||||||
widget._children[j].setDetachedAttributes(nodes[j], {value: widget_value});
|
widget._children[j].setDetachedAttributes(widget._children[j], {value: widget_value});
|
||||||
|
if(widget._children[j] instanceof Et2Diff)
|
||||||
|
{
|
||||||
|
self._spanValueColumns(jQuery(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -754,7 +757,7 @@ export class et2_historylog extends et2_valueWidget implements et2_IDataProvider
|
|||||||
if(this.dataview)
|
if(this.dataview)
|
||||||
{
|
{
|
||||||
const columns = this.dataview.getColumnMgr();
|
const columns = this.dataview.getColumnMgr();
|
||||||
jQuery('.et2_diff', this.div).closest('.innerContainer')
|
jQuery('[colspan=2]', this.div).find('.innerContainer')
|
||||||
.width(columns.getColumnWidth(et2_historylog.NEW_VALUE) + columns.getColumnWidth(et2_historylog.OLD_VALUE));
|
.width(columns.getColumnWidth(et2_historylog.NEW_VALUE) + columns.getColumnWidth(et2_historylog.OLD_VALUE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ import './Et2Date/Et2DateTimeToday';
|
|||||||
import './Et2Description/Et2Description';
|
import './Et2Description/Et2Description';
|
||||||
import './Et2Dialog/Et2Dialog';
|
import './Et2Dialog/Et2Dialog';
|
||||||
import './Et2Dialog/Et2MergeDialog';
|
import './Et2Dialog/Et2MergeDialog';
|
||||||
|
import './Et2Diff/Et2Diff';
|
||||||
import './Et2DropdownButton/Et2DropdownButton';
|
import './Et2DropdownButton/Et2DropdownButton';
|
||||||
import './Et2Email/Et2Email';
|
import './Et2Email/Et2Email';
|
||||||
import './Expose/Et2ImageExpose';
|
import './Expose/Et2ImageExpose';
|
||||||
|
@ -883,62 +883,42 @@ for printing
|
|||||||
/**
|
/**
|
||||||
* Diff widget
|
* Diff widget
|
||||||
*/
|
*/
|
||||||
div.et2_diff {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.et2_diff thead,
|
|
||||||
.author,
|
et2-diff thead,
|
||||||
.d2h-file-header,
|
et2-diff .author,
|
||||||
.d2h-file-info,
|
et2-diff .d2h-file-header,
|
||||||
.d2h-info,
|
et2-diff .d2h-file-info,
|
||||||
.et2_diff:not(.ui-dialog-content) .d2h-cntx {
|
et2-diff .d2h-info {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.d2h-file-diff {
|
et2-diff .d2h-file-diff {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.et2_diff .d2h-file-wrapper {
|
et2-diff .d2h-file-diff {
|
||||||
}
|
|
||||||
|
|
||||||
.et2_diff .d2h-file-diff {
|
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.et2_diff .d2h-code-wrapper {
|
et2-diff .d2h-code-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-widget-content .d2h-code-line-ctn {
|
et2-diff .d2h-del, et2-diff.d2h-del.d2h-change, et2-diff .d2h-file-diff .d2h-del.d2h-change {
|
||||||
white-space: normal;
|
background-color: var(--sl-color-red-100, #ffeef0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-widget-content .d2h-file-diff {
|
et2-diff .d2h-code-line del, et2-diff .d2h-code-side-line del {
|
||||||
overflow-x: visible;
|
background-color: var(--sl-color-red-300, #fdb8c0);
|
||||||
overflow-y: visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.et2_diff .ui-icon {
|
et2-diff .d2h-ins, et2-diff.d2h-ins.d2h-change, et2-diff .d2h-file-diff .d2h-ins.d2h-change {
|
||||||
margin-top: -14px;
|
background-color: var(--sl-color-green-100, #e6ffed);
|
||||||
float: right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.et2_diff .d2h-del, .et2_diff.d2h-del.d2h-change, .et2_diff .d2h-file-diff .d2h-del.d2h-change {
|
et2-diff .d2h-code-line ins, et2-diff .d2h-code-side-line ins {
|
||||||
background-color: #ffeef0;
|
background-color: var(--sl-color-green-300, #acf2bd);
|
||||||
}
|
|
||||||
|
|
||||||
.et2_diff .d2h-code-line del, .et2_diff .d2h-code-side-line del {
|
|
||||||
background-color: #fdb8c0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.et2_diff .d2h-ins, .et2_diff.d2h-ins.d2h-change, .et2_diff .d2h-file-diff .d2h-ins.d2h-change {
|
|
||||||
background-color: #e6ffed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.et2_diff .d2h-code-line ins, .et2_diff .d2h-code-side-line ins {
|
|
||||||
background-color: #acf2bd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Display a loading icon **/
|
/** Display a loading icon **/
|
||||||
|
@ -75,7 +75,6 @@
|
|||||||
"async-aws/s3": "^2.0",
|
"async-aws/s3": "^2.0",
|
||||||
"bigbluebutton/bigbluebutton-api-php": "^2.0",
|
"bigbluebutton/bigbluebutton-api-php": "^2.0",
|
||||||
"bower-asset/cropper": "2.3.*",
|
"bower-asset/cropper": "2.3.*",
|
||||||
"bower-asset/diff2html": "^2.7",
|
|
||||||
"bower-asset/jquery": "^1.12.4",
|
"bower-asset/jquery": "^1.12.4",
|
||||||
"defuse/php-encryption": "^2.4",
|
"defuse/php-encryption": "^2.4",
|
||||||
"egroupware/activesync": "self.version",
|
"egroupware/activesync": "self.version",
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
<!-- Breaks page scrolling <link rel="stylesheet" href="{{ assetUrl('styles/monochrome.css') }}" /> -->
|
<!-- Breaks page scrolling <link rel="stylesheet" href="{{ assetUrl('styles/monochrome.css') }}" /> -->
|
||||||
<script src="{{ assetUrl('scripts/sub/dir/etemplate/etemplate2.js') }}" type="module" id="egw_script_id"></script>
|
<script src="{{ assetUrl('scripts/sub/dir/etemplate/etemplate2.js') }}" type="module" id="egw_script_id"></script>
|
||||||
<link rel="stylesheet" href="{{assetUrl("styles/bootstrap-icons.min.css")}}" />
|
<link rel="stylesheet" href="{{assetUrl("styles/bootstrap-icons.min.css")}}" />
|
||||||
|
<link rel="stylesheet" href="{{assetUrl("styles/diff2html.min.css")}}" />
|
||||||
|
|
||||||
{# Set the initial theme and menu states here to prevent flashing #}
|
{# Set the initial theme and menu states here to prevent flashing #}
|
||||||
<script>
|
<script>
|
||||||
|
@ -70,7 +70,6 @@ module.exports = function (eleventyConfig)
|
|||||||
eleventyConfig.addPassthroughCopy({
|
eleventyConfig.addPassthroughCopy({
|
||||||
"../../vendor/bower-asset/jquery/dist/jquery.min.js": "assets/scripts/vendor/bower-asset/jquery/dist/jquery.min.js",
|
"../../vendor/bower-asset/jquery/dist/jquery.min.js": "assets/scripts/vendor/bower-asset/jquery/dist/jquery.min.js",
|
||||||
"../../vendor/bower-asset/cropper/dist/cropper.min.js": "assets/scripts/vendor/bower-asset/cropper/dist/cropper.min.js",
|
"../../vendor/bower-asset/cropper/dist/cropper.min.js": "assets/scripts/vendor/bower-asset/cropper/dist/cropper.min.js",
|
||||||
"../../vendor/bower-asset/diff2html/dist/diff2html.min.js": "assets/scripts/vendor/bower-asset/diff2html/dist/diff2html.min.js",
|
|
||||||
"../../vendor/tinymce/tinymce/tinymce.min.js": "assets/scripts/vendor/tinymce/tinymce/tinymce.min.js",
|
"../../vendor/tinymce/tinymce/tinymce.min.js": "assets/scripts/vendor/tinymce/tinymce/tinymce.min.js",
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -78,6 +77,7 @@ module.exports = function (eleventyConfig)
|
|||||||
eleventyConfig.addPassthroughCopy({"../../chunks": "assets/scripts/chunks"});
|
eleventyConfig.addPassthroughCopy({"../../chunks": "assets/scripts/chunks"});
|
||||||
eleventyConfig.addPassthroughCopy({"../../api/js/etemplate/etemplate2.js": "assets/scripts/sub/dir/etemplate/etemplate2.js"});
|
eleventyConfig.addPassthroughCopy({"../../api/js/etemplate/etemplate2.js": "assets/scripts/sub/dir/etemplate/etemplate2.js"});
|
||||||
eleventyConfig.addPassthroughCopy({"../../node_modules/bootstrap-icons/font/bootstrap-icons.min.css": "assets/styles/bootstrap-icons.min.css"});
|
eleventyConfig.addPassthroughCopy({"../../node_modules/bootstrap-icons/font/bootstrap-icons.min.css": "assets/styles/bootstrap-icons.min.css"});
|
||||||
|
eleventyConfig.addPassthroughCopy({"../../node_modules/diff2html/bundles/css/diff2html.min.css": "assets/styles/diff2html.min.css"});
|
||||||
|
|
||||||
//eleventyConfig.addPassthroughCopy({"../../vendor/**/*min.js": "assets/scripts/vendor/"});
|
//eleventyConfig.addPassthroughCopy({"../../vendor/**/*min.js": "assets/scripts/vendor/"});
|
||||||
//eleventyConfig.addPassthroughCopy("../dist/etemplate2.js", "assets/scripts/etemplate2.js");
|
//eleventyConfig.addPassthroughCopy("../dist/etemplate2.js", "assets/scripts/etemplate2.js");
|
||||||
|
73
package-lock.json
generated
73
package-lock.json
generated
@ -18,6 +18,7 @@
|
|||||||
"colortranslator": "^1.9.2",
|
"colortranslator": "^1.9.2",
|
||||||
"core-js": "^3.29.1",
|
"core-js": "^3.29.1",
|
||||||
"dexie": "^3.2.4",
|
"dexie": "^3.2.4",
|
||||||
|
"diff2html": "^3.4.48",
|
||||||
"imask": "^7.6.1",
|
"imask": "^7.6.1",
|
||||||
"lit": "^2.7.5",
|
"lit": "^2.7.5",
|
||||||
"lit-flatpickr": "^0.3.0",
|
"lit-flatpickr": "^0.3.0",
|
||||||
@ -7258,6 +7259,31 @@
|
|||||||
"node": ">=0.3.1"
|
"node": ">=0.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/diff2html": {
|
||||||
|
"version": "3.4.48",
|
||||||
|
"resolved": "https://registry.npmjs.org/diff2html/-/diff2html-3.4.48.tgz",
|
||||||
|
"integrity": "sha512-1lzNSg0G0VPKZPTyi4knzV2nAWTXBy/QaWCKzDto6iEIlcuOJEG0li4bElJfpHNz+pBqPu4AcC1i9ZCo9KMUOg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"diff": "5.1.0",
|
||||||
|
"hogan.js": "3.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"highlight.js": "11.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/diff2html/node_modules/diff": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dir-glob": {
|
"node_modules/dir-glob": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||||
@ -9248,6 +9274,53 @@
|
|||||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
|
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/highlight.js": {
|
||||||
|
"version": "11.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz",
|
||||||
|
"integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hogan.js": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==",
|
||||||
|
"dependencies": {
|
||||||
|
"mkdirp": "0.3.0",
|
||||||
|
"nopt": "1.0.10"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"hulk": "bin/hulk"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hogan.js/node_modules/mkdirp": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==",
|
||||||
|
"deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
|
||||||
|
"license": "MIT/X11",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hogan.js/node_modules/nopt": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"abbrev": "1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"nopt": "bin/nopt.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/homedir-polyfill": {
|
"node_modules/homedir-polyfill": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
||||||
|
@ -90,6 +90,7 @@
|
|||||||
"colortranslator": "^1.9.2",
|
"colortranslator": "^1.9.2",
|
||||||
"core-js": "^3.29.1",
|
"core-js": "^3.29.1",
|
||||||
"dexie": "^3.2.4",
|
"dexie": "^3.2.4",
|
||||||
|
"diff2html": "^3.4.48",
|
||||||
"imask": "^7.6.1",
|
"imask": "^7.6.1",
|
||||||
"lit": "^2.7.5",
|
"lit": "^2.7.5",
|
||||||
"lit-flatpickr": "^0.3.0",
|
"lit-flatpickr": "^0.3.0",
|
||||||
|
Loading…
Reference in New Issue
Block a user