stimulsoft-forms
Version:
Stimulsoft PDF Forms
906 lines • 114 kB
JavaScript
import { Component, ViewChild } from "@angular/core";
import { StiFormElement } from "../../elements/base/StiFormElement";
import { StiLabelElement } from "../../elements/StiLabelElement";
import { StiNumberBoxElement } from "../../elements/StiNumberBoxElement";
import { StiTableElement } from "../../elements/StiTableElement";
import { StiTextBoxElement } from "../../elements/StiTextBoxElement";
import { StiTotalsFieldItem } from "../../elements/table/StiTotalsFieldItem";
import { StiExpressionService } from "../../services/sti-expression.service";
import { RotateAnimation } from "../animations/animations";
import { StiColumnItem } from "../../elements/table/StiColumnItem";
import * as i0 from "@angular/core";
import * as i1 from "../../services/model.service";
import * as i2 from "../../services/sti-expression.service";
import * as i3 from "../../services/sti-localization.service";
import * as i4 from "../../services/mouse.service";
import * as i5 from "../../services/sti-editable-content.service";
import * as i6 from "@angular/common";
import * as i7 from "./sti-columns-preview.component";
import * as i8 from "../sti-tooltip/sti-tooltip.directive";
export class StiExpressionEditorComponent {
constructor(model, expressionService, loc, mouseService, editableService, cdr) {
this.model = model;
this.expressionService = expressionService;
this.loc = loc;
this.mouseService = mouseService;
this.editableService = editableService;
this.cdr = cdr;
this.expressionString = "{}";
this.currentSelectedMode = "functions";
this.currentSelectedFunction = "value";
this.canDragExpression = false;
this.arrayOfSamples = [
{
functionName: "value",
samples: ["Value('TextBox')", "Value('NumberBox')", "Value('Label')"],
title: "Value of NumberBox, TextBox or Label element",
},
{
functionName: "count",
samples: ["Count(Col(1,'Table'))", "Count(Row('First','Table'))"],
title: "Number of items in the list",
},
{
functionName: "min",
samples: ["Min(Col(1,'Table'))", "Min(Row('First','Table'))"],
title: "The smallest number in list",
},
{
functionName: "max",
samples: ["Max(Col(1,'Table'))", "Max(Row('First','Table'))"],
title: "The largest number in list",
},
{
functionName: "sum",
samples: ["Sum(Col(1,'Table'))", "Sum(Row('First','Table'))"],
title: "Sum of all numbers in list",
},
{
functionName: "cell",
samples: ["Cell(columnId,rowId)", "Cell(columnId,rowId,'Table')"],
title: "Number value of specified cell",
},
{
functionName: "total",
samples: ["Total(totalId)", "Total(totalId,'Table')"],
title: "Value of Tables Totals field",
},
{
functionName: "col",
samples: ["Col(columnId)", "Col(columnId,'Table')"],
title: "List of numbers which are cell values from specified column",
},
{
functionName: "row",
samples: ["Row(rowLabel)", "Row(rowLabel,'Table')"],
title: "List of numbers which are cell values from specified row",
},
{
functionName: "line",
samples: ["Line"],
title: "Returns the current table line number (starts from 1).",
},
{
functionName: "today",
samples: ["Today"],
title: "Returns the current date in default format.",
},
{
functionName: "time",
samples: ["Time"],
title: "Returns the current time in default format.",
},
];
this.arrayOfStates = [];
}
ngAfterViewInit() {
this.expressionService.elementRef = this.elementRef;
}
ngOnDestroy() {
this.mouseMoveSubscription?.unsubscribe();
this.mouseUpSubscription?.unsubscribe();
this.expressionUpdatingSubscription?.unsubscribe();
this.expressionService.elementRef = null;
}
startExpressionDragging(dragObject) {
this.startX = dragObject.event.clientX;
this.startY = dragObject.event.clientY;
this.canDragExpression = true;
this.dragObject = dragObject;
}
setContent(innerText) {
if (this.model.getBrowserType() == "safari" || this.model.getBrowserType() == "firefox") {
this.cdr.detach();
}
this.expressionString = innerText;
}
checkBrackets() {
let haveCloseBreaket = false;
let haveOpenBreaket = false;
if (this.lastCaretPosition) {
for (let i = this.lastCaretPosition - 1; i >= 0; i--) {
if (this.expressionString[i] === "}") {
haveCloseBreaket = true;
break;
}
else if (this.expressionString[i] === "{") {
haveOpenBreaket = true;
break;
}
}
}
if (haveCloseBreaket || (!haveCloseBreaket && !haveOpenBreaket)) {
return true;
}
else {
return false;
}
}
showInfo() {
this.model.showHelpWindow = true;
}
addValue(element) {
this.addFunction("Value", element.name, true);
}
changeMode(mode) {
if (this.model.getBrowserType() == "safari" || this.model.getBrowserType() == "firefox") {
this.cdr.reattach();
this.cdr.detectChanges();
}
if (this.currentSelectedMode != mode && mode == "systemVariable") {
this.currentSelectedFunction = "line";
}
else {
this.currentSelectedFunction = "value";
}
this.currentSelectedMode = mode;
}
changeCurrentFuction(func) {
this.currentSelectedFunction = func;
}
startDrag(event) {
this.startX = event.clientX;
this.startY = event.clientY;
this.startComponentX = this.expressionService.componentX;
this.startComponentY = this.expressionService.componentY;
this.isDragging = true;
}
get samples() {
return this.arrayOfSamples.find((sample) => sample.functionName == this.currentSelectedFunction).samples;
}
get title() {
return this.arrayOfSamples.find((sample) => sample.functionName == this.currentSelectedFunction).title;
}
nestedFieldClick(field) {
if (field instanceof StiTotalsFieldItem) {
this.insertInExpression(this.lastCaretPosition, `Total(${field.eParent.totalsFields.indexOf(field) + 1},'${field.eParent.name}')`);
}
else {
this.insertInExpression(this.lastCaretPosition, `Cell(${field.column.eParent.columns.indexOf(field.column) + 1},${field.index},'${field.column.eParent.name}')`);
}
}
get fields() {
let fields = [];
this.model?.form?.pages?.forEach((page) => {
page.allElements.forEach((element) => {
if (this.haveExpression(element)) {
fields.push(element);
}
});
});
return fields;
}
isTable(element) {
return element instanceof StiTableElement;
}
haveExpression(element) {
return element instanceof StiTableElement ||
element instanceof StiTextBoxElement ||
element instanceof StiNumberBoxElement
? true
: false;
}
addOperator(operator) {
this.insertInExpression(this.lastCaretPosition, operator, true);
}
addFunction(func, name, filled = false) {
let string = "";
if (func.toLowerCase() == "value") {
string = func + `('${name ? name : ""}')`;
}
else if (func.toLowerCase() == "line" || func.toLowerCase() == "today" || func.toLowerCase() == "time") {
string = func;
}
else if (func.toLowerCase() == "cell") {
string = func + "(,,'')";
}
else if (func.toLowerCase() == "total" || func.toLowerCase() == "col" || func.toLowerCase() == "row") {
string = func + "(,'')";
}
else {
string = func + "()";
}
this.insertInExpression(this.lastCaretPosition, string, false, filled ? false : true);
}
insertInExpression(position, string, isOperator = false, isFunction = false) {
let needBrackets = isOperator ? false : this.checkBrackets();
let previousString = this.expressionString;
let insertedExpression = `${needBrackets ? "{" : ""}${string}${needBrackets ? "}" : ""}`;
if (this.expressionString.length > 0 && position) {
if (position == 0) {
this.expressionString = insertedExpression + previousString;
}
else {
this.expressionString =
previousString.slice(0, position) +
insertedExpression +
previousString.slice(position, previousString.length);
}
}
else {
this.expressionString += insertedExpression;
}
this.setCaret(insertedExpression, isFunction);
}
setCaret(insertedExpression, isFunction = false) {
let leftBracketIndex = insertedExpression.indexOf("(");
let carretOffset = 0;
if (!this.lastCaretPosition) {
this.lastCaretPosition = this.expressionString.length - insertedExpression.length;
}
if (isFunction) {
if (insertedExpression[leftBracketIndex + 1] == "'") {
carretOffset = this.lastCaretPosition + leftBracketIndex + 2;
}
else {
carretOffset = this.lastCaretPosition + leftBracketIndex + 1;
}
}
else {
carretOffset = this.lastCaretPosition + insertedExpression.length;
}
let elem = this.elementRef.nativeElement;
elem.focus();
setTimeout(() => {
var range = document.createRange();
var sel = window.getSelection();
range.setStart(elem.childNodes[0], carretOffset);
range.collapse(true);
this.lastCaretPosition += insertedExpression.length;
sel.removeAllRanges();
sel.addRange(range);
});
}
save() {
if (this.expressionService.currentSelectedObject instanceof StiLabelElement) {
this.expressionService.currentSelectedObject.text.value = this.expressionString;
this.model.formEvents.next({ name: "ValueChanged" });
}
else {
this.expressionService.currentSelectedObject.expression = this.expressionString;
}
this.model.showExpressionEditor = false;
}
ngOnInit() {
this.expressionService.componentX = (window.innerWidth - this.expressionService.componentWidth) / 2;
this.expressionService.componentY = (window.innerHeight - this.expressionService.componentHeight) / 2;
this.expressionString = this.expressionService.currentSelectedObject?.expression
? this.expressionService.currentSelectedObject?.expression
: this.expressionService.currentSelectedObject?.text?.value
? this.expressionService.currentSelectedObject?.text?.value
: "";
this.fields?.forEach((field) => {
if (this.isTable(field)) {
this.arrayOfStates.push({ element: field, state: "default" });
}
});
this.currentSelectedFunction = "value";
this.currentSelectedMode = "functions";
this.expressionUpdatingSubscription = this.expressionService.needToAddExpression.subscribe((object) => {
this.addExpressionByDrag(object);
});
this.mouseUpSubscription = this.mouseService.getDocumentMouseUp().subscribe(() => {
this.isDragging = false;
this.canDragExpression = false;
});
this.mouseMoveSubscription = this.mouseService.getDocumentMouseMove().subscribe((event) => {
this.onMouseMove(event);
});
}
addExpressionByDrag(expressionObject) {
if (this.expressionString.length == 0) {
this.lastCaretPosition = 0;
}
else {
this.lastCaretPosition = expressionObject.lastCaretOffset;
}
if (typeof expressionObject.startObject.object == "string") {
if (expressionObject.startObject.object.length == 1) {
this.addOperator(expressionObject.startObject.object);
}
else {
this.addFunction(expressionObject.startObject.object);
}
}
else {
if (expressionObject.startObject.object instanceof StiFormElement) {
this.addFunction("Value", expressionObject.startObject.object.name, true);
}
else {
if (expressionObject.startObject.object instanceof StiTotalsFieldItem) {
this.insertInExpression(this.lastCaretPosition, `Total(${expressionObject.startObject.object.eParent.totalsFields.indexOf(expressionObject.startObject.object) + 1},'${expressionObject.startObject.object.eParent.name}')`);
}
else if (expressionObject.startObject.object instanceof StiColumnItem &&
!expressionObject.startObject.isCell) {
this.insertInExpression(this.lastCaretPosition, `Col(${expressionObject.startObject.object.eParent.columns.indexOf(expressionObject.startObject.object) + 1},'${expressionObject.startObject.object.eParent.name}')`);
}
else {
this.insertInExpression(this.lastCaretPosition, `Cell(${expressionObject.startObject.object.eParent.columns.indexOf(expressionObject.startObject.object) + 1},${expressionObject.startObject.index},'${expressionObject.startObject.object.eParent.name}')`);
}
}
}
}
onMouseMove(event) {
if (this.canDragExpression &&
Math.max(Math.abs(this.startX - event.clientX), Math.abs(this.startY - event.clientY)) >
StiExpressionService.MOUSE_DELTA) {
this.expressionService.expressionDraggableContainerX = this.dragObject.event.clientX - 10;
this.expressionService.expressionDraggableContainerY = this.dragObject.event.clientY - 10;
this.expressionService.startContainerDrag(this.dragObject);
this.canDragExpression = false;
}
if (this.isDragging) {
let deltaX = event.clientX - this.startX;
let deltaY = event.clientY - this.startY;
if (this.startComponentX + deltaX < 0) {
this.expressionService.componentX = 0;
}
else if (this.startComponentX + deltaX > window.innerWidth - this.expressionService.componentWidth) {
this.expressionService.componentX = window.innerWidth - this.expressionService.componentWidth;
}
else {
this.expressionService.componentX = this.startComponentX + deltaX;
}
if (this.startComponentY + deltaY < 0) {
this.expressionService.componentY = 0;
}
else if (this.startComponentY + deltaY > window.innerHeight - this.expressionService.componentHeight) {
this.expressionService.componentY = window.innerHeight - this.expressionService.componentHeight;
}
else {
this.expressionService.componentY = this.startComponentY + deltaY;
}
}
}
getState(element) {
return this.arrayOfStates.find((item) => item.element == element).state;
}
changeState(element) {
let index = this.arrayOfStates.findIndex((item) => item.element == element);
this.arrayOfStates[index].state == "default"
? (this.arrayOfStates[index].state = "rotated")
: (this.arrayOfStates[index].state = "default");
}
focus() {
this.expressionService.elementRef = this.elementRef;
}
blur() {
if (this.model.getBrowserType() == "safari" || this.model.getBrowserType() == "firefox") {
this.cdr.reattach();
this.cdr.detectChanges();
}
}
getCaret() {
this.lastCaretPosition = this.expressionService.getCaretOffset(this.elementRef.nativeElement ?? this.elementRef);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiExpressionEditorComponent, deps: [{ token: i1.StiModelService }, { token: i2.StiExpressionService }, { token: i3.StiLocalizationService }, { token: i4.StiMouseService }, { token: i5.StiEditableContentService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: StiExpressionEditorComponent, selector: "sti-expression-editor", viewQueries: [{ propertyName: "elementRef", first: true, predicate: ["expressionRef"], descendants: true }], ngImport: i0, template: `<div
class="expression-editor-container"
[style.left.px]="expressionService.componentX"
[style.top.px]="expressionService.componentY"
[style.pointer-events]="model.showHelpWindow ? 'none' : ''"
>
<div class="header-navigation" (mousedown)="startDrag($event)">
<span>{{ loc.get2("FormTitles", "ExpressionEditorForm") }}</span>
<div class="nav-button" (click)="showInfo()"><img [src]="model.getImage('images.Other.HelpIcon.png')" /></div>
<div class="nav-button" (click)="model.showExpressionEditor = false">
<img [src]="model.getImage('images.Other.CloseForm.png')" />
<!-- <i class="pi pi-times"></i> -->
</div>
</div>
<div
class="expression-preview {{ expressionService.isDragging ? 'dragging-over' : '' }}"
(click)="expressionRef.focus()"
>
<label
[id]="'expressionLabel'"
#expressionRef
contenteditable="plaintext-only"
(mouseup)="getCaret()"
(input)="setContent($event.target.textContent)"
(keyup)="getCaret()"
spellcheck="false"
[textContent]="expressionString"
[style.cursor]="expressionService.isDragging ? 'default' : 'text'"
></label>
</div>
<div class="expression-navigation">
<div
class="expression-functions column"
[style.width]="currentSelectedMode == 'functions' || currentSelectedMode == 'systemVariable' ? '100%' : '30%'"
>
<div class="column-content">
<span
class="column-item {{ currentSelectedMode == 'functions' ? 'selected' : '' }}"
(click)="changeMode('functions')"
>
{{ loc.getP("Functions") }}
</span>
<span
class="column-item {{ currentSelectedMode == 'elements' ? 'selected' : '' }}"
(click)="changeMode('elements')"
>
{{ loc.get2("Report", "Components") }}
</span>
<span
class="column-item {{ currentSelectedMode == 'systemVariable' ? 'selected' : '' }}"
(click)="changeMode('systemVariable')"
>
{{ loc.getP("SystemVariable") }}
</span>
<span
class="column-item {{ currentSelectedMode == 'operators' ? 'selected' : '' }}"
(click)="changeMode('operators')"
>
{{ loc.get2("MathFormula", "Operators") }}
</span>
</div>
</div>
<div
class="expression-operators column"
*ngIf="currentSelectedMode == 'functions' || currentSelectedMode == 'systemVariable'"
>
<div class="column-content" *ngIf="currentSelectedMode == 'functions'">
<span
class="column-item {{ currentSelectedFunction == 'value' ? 'selected' : '' }}"
(click)="changeCurrentFuction('value')"
(mousedown)="startExpressionDragging({ object: 'Value', event: $event })"
(dblclick)="addFunction('Value')"
>
{{ "Value()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'count' ? 'selected' : '' }}"
(click)="changeCurrentFuction('count')"
(mousedown)="startExpressionDragging({ object: 'Count', event: $event })"
(dblclick)="addFunction('Count')"
>
{{ "Count()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'min' ? 'selected' : '' }}"
(click)="changeCurrentFuction('min')"
(mousedown)="startExpressionDragging({ object: 'Min', event: $event })"
(dblclick)="addFunction('Min')"
>
{{ "Min()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'max' ? 'selected' : '' }}"
(click)="changeCurrentFuction('max')"
(mousedown)="startExpressionDragging({ object: 'Max', event: $event })"
(dblclick)="addFunction('Max')"
>
{{ "Max()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'sum' ? 'selected' : '' }}"
(click)="changeCurrentFuction('sum')"
(mousedown)="startExpressionDragging({ object: 'Sum', event: $event })"
(dblclick)="addFunction('Sum')"
>
{{ "Sum()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'cell' ? 'selected' : '' }}"
(click)="changeCurrentFuction('cell')"
(mousedown)="startExpressionDragging({ object: 'Cell', event: $event })"
(dblclick)="addFunction('Cell')"
>
{{ "Cell()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'total' ? 'selected' : '' }}"
(click)="changeCurrentFuction('total')"
(mousedown)="startExpressionDragging({ object: 'Total', event: $event })"
(dblclick)="addFunction('Total')"
>
{{ "Total()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'col' ? 'selected' : '' }}"
(click)="changeCurrentFuction('col')"
(mousedown)="startExpressionDragging({ object: 'Col', event: $event })"
(dblclick)="addFunction('Col')"
>
{{ "Col()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'row' ? 'selected' : '' }}"
(click)="changeCurrentFuction('row')"
(mousedown)="startExpressionDragging({ object: 'Row', event: $event })"
(dblclick)="addFunction('Row')"
>
{{ "Row()" }}
</span>
</div>
<div class="column-content" *ngIf="currentSelectedMode == 'systemVariable'">
<span
class="column-item {{ currentSelectedFunction == 'line' ? 'selected' : '' }}"
(click)="changeCurrentFuction('line')"
(mousedown)="startExpressionDragging({ object: 'Line', event: $event })"
(dblclick)="addFunction('Line')"
>
{{ "Line" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'today' ? 'selected' : '' }}"
(click)="changeCurrentFuction('today')"
(mousedown)="startExpressionDragging({ object: 'Today', event: $event })"
(dblclick)="addFunction('Today')"
>
{{ "Today" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'time' ? 'selected' : '' }}"
(click)="changeCurrentFuction('time')"
(mousedown)="startExpressionDragging({ object: 'Time', event: $event })"
(dblclick)="addFunction('Time')"
>
{{ "Time" }}
</span>
</div>
</div>
<div class="expression-fields column">
<div
class="column-content"
*ngIf="currentSelectedMode == 'functions' || currentSelectedMode == 'systemVariable'"
>
<div *ngFor="let sample of samples" class="sample-item">
<span>{{ sample }}</span>
</div>
<div class="sample-item" [style.padding]="'15px 0px'">
<span>{{ title }}</span>
</div>
</div>
<div class="column-content" *ngIf="currentSelectedMode == 'operators'">
<span
class="operator-item"
[stiTooltip]="loc.get2('Shapes', 'Plus')"
tooltipPosition="bottom"
showDelay="500"
(dblclick)="addOperator('+')"
(mousedown)="startExpressionDragging({ object: '+', event: $event })"
>+</span
>
<span
class="operator-item"
[stiTooltip]="loc.get2('Shapes', 'Minus')"
tooltipPosition="bottom"
showDelay="500"
(mousedown)="startExpressionDragging({ object: '-', event: $event })"
(dblclick)="addOperator('-')"
>-</span
>
<span
class="operator-item"
[stiTooltip]="loc.get2('Shapes', 'Multiply')"
tooltipPosition="bottom"
showDelay="500"
(mousedown)="startExpressionDragging({ object: '*', event: $event })"
(dblclick)="addOperator('*')"
>*</span
>
<span
class="operator-item"
[stiTooltip]="loc.get2('Shapes', 'Division')"
tooltipPosition="bottom"
showDelay="500"
(mousedown)="startExpressionDragging({ object: '/', event: $event })"
(dblclick)="addOperator('/')"
>/</span
>
</div>
<div class="column-content" *ngIf="currentSelectedMode == 'elements'">
<div *ngFor="let field of fields">
<div
class="column-item field"
[style.padding]="isTable(field) ? '4px 5px 4px 0px' : '4px 5px'"
(click)="isTable(field) ? changeState(field) : ''"
(mousedown)="!isTable(field) ? startExpressionDragging({ object: field, event: $event }) : ''"
(dblclick)="!isTable(field) ? addValue(field) : ''"
>
<div *ngIf="isTable(field)" class="arrow" [@rotatedState]="getState(field)">
<i class="pi pi-chevron-right"></i>
</div>
<span>{{ field.name }}</span>
</div>
<sti-columns-preview
*ngIf="isTable(field)"
[object]="field"
(fieldClick)="nestedFieldClick($event)"
(startFieldDrag)="startExpressionDragging($event)"
[state]="getState(field) == 'default' ? false : true"
></sti-columns-preview>
</div>
</div>
</div>
</div>
<div class="footer-navigation">
<div class="footer-button accept" (click)="save()" [style.margin-right.px]="0">
<span>{{ loc.get2("Buttons", "Save") }}</span>
</div>
<div class="footer-button cancel" (click)="model.showExpressionEditor = false">
<span>{{ loc.getP("Cancel") }}</span>
</div>
</div>
</div>`, isInline: true, styles: [".arrow{width:20px;cursor:default;-webkit-touch-callout:none;-webkit-user-select:none;display:flex;align-items:center;justify-content:center}.arrow .pi{font-size:.625rem}.pi{font-size:.825rem}.selected{background-color:#e5e5e5}.expression-editor-container{position:absolute;font-size:13px;font-family:Arial;color:var(--text-color);min-height:480px;width:700px;border-radius:5px;left:calc(50% - 350px);top:calc(50% - 250px);display:flex;flex-direction:column;border:1px solid rgb(28,71,134);background-color:#fff;-moz-box-shadow:0px 0px 7px rgba(0,0,0,.6);-webkit-box-shadow:0px 0px 7px rgb(0 0 0 / 60%);box-shadow:0 0 7px #0000004d;z-index:999}.header-navigation{display:flex;height:40px;align-items:center;padding-left:15px;padding-right:5px;border-top-left-radius:3px;border-top-right-radius:3px;background-color:#515c6a;color:#fff;-webkit-user-select:none}.header-navigation span{width:100%;font-size:17px;-webkit-user-select:none;cursor:default}.nav-button{height:24px;width:28px;border-radius:3px;display:flex;align-items:center;justify-content:center;align-self:start;margin-top:5px}.nav-button:hover{background-color:#d3d3d3}.nav-button img{height:16px;width:16px;filter:brightness(0) invert(1)}.expression-preview{width:calc(100% - 20px);margin:10px 10px 5px;padding:5px;background-color:#fafafa;border:1px solid lightgray;height:135px;-webkit-user-select:text;display:flex}.expression-preview label{-webkit-user-select:text;font-size:13px;outline:none;height:100%;width:100%;overflow:auto}.dragging-over{background-color:#ebebeb!important;border:1px dashed black!important}.expression-navigation{display:flex;width:100%;padding:0 5px}.column{border:1px solid lightgray;height:230px;width:100%;margin:5px}.buttons{height:250px;min-width:150px;display:flex;flex-direction:column;justify-content:center;align-items:center}.buttons img{height:52px;width:52px;border-radius:3px;margin:5px;padding:10px}.buttons img:hover{background-color:#d3d3d3}.column-header{-webkit-user-select:none;height:30px;background-color:#d3d3d3;display:flex;align-items:center;padding:0 10px;border-top-left-radius:4px;border-top-right-radius:4px}.column-header span{font-size:15px;-webkit-user-select:none;cursor:default}.footer-navigation{width:100%;display:flex;justify-content:flex-end;height:50px;align-items:center}.footer-button{min-width:90px;height:30px;border-radius:3px;display:flex;align-items:center;justify-content:center;margin:0 10px;-webkit-user-select:none;font-size:12px}.accept{background-color:#19478a;color:#fff}.accept:hover{background-color:#3d6298}.cancel{background-color:#ddd;color:#444}.cancel:hover{background-color:#d5d5d5}.column-content{width:100%;padding:5px;display:flex;max-height:229px;overflow-y:auto;flex-direction:column}.operator-item{font-family:Arial;color:var(--text-color);font-size:17px;padding:2px 7px;border-radius:3px;-webkit-user-select:none}.operator-item:hover{background-color:#f0f0f0}.sample-item{font-family:Arial;color:var(--text-color);font-size:12px;-webkit-user-select:none;padding-bottom:3px;cursor:default}.column-item{font-family:Arial;color:var(--text-color);font-size:12px;-webkit-user-select:none;padding:5px;cursor:default}.column-item:hover{background-color:#f0f0f0}.info{height:30px;width:30px;display:flex;align-items:center;justify-content:center}.info img{height:16px;width:16px;cursor:pointer}.field{display:flex;align-items:center}.field img{height:16px;width:16px;margin-right:5px}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i7.StiColumnsPreviewComponent, selector: "sti-columns-preview", inputs: ["state", "object"], outputs: ["fieldClick", "startFieldDrag"] }, { kind: "directive", type: i8.StiTooltipDirective, selector: "[stiTooltip]", inputs: ["tooltipPosition", "stiTooltip", "showDelay"] }], animations: [RotateAnimation] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiExpressionEditorComponent, decorators: [{
type: Component,
args: [{ selector: "sti-expression-editor", template: `<div
class="expression-editor-container"
[style.left.px]="expressionService.componentX"
[style.top.px]="expressionService.componentY"
[style.pointer-events]="model.showHelpWindow ? 'none' : ''"
>
<div class="header-navigation" (mousedown)="startDrag($event)">
<span>{{ loc.get2("FormTitles", "ExpressionEditorForm") }}</span>
<div class="nav-button" (click)="showInfo()"><img [src]="model.getImage('images.Other.HelpIcon.png')" /></div>
<div class="nav-button" (click)="model.showExpressionEditor = false">
<img [src]="model.getImage('images.Other.CloseForm.png')" />
<!-- <i class="pi pi-times"></i> -->
</div>
</div>
<div
class="expression-preview {{ expressionService.isDragging ? 'dragging-over' : '' }}"
(click)="expressionRef.focus()"
>
<label
[id]="'expressionLabel'"
#expressionRef
contenteditable="plaintext-only"
(mouseup)="getCaret()"
(input)="setContent($event.target.textContent)"
(keyup)="getCaret()"
spellcheck="false"
[textContent]="expressionString"
[style.cursor]="expressionService.isDragging ? 'default' : 'text'"
></label>
</div>
<div class="expression-navigation">
<div
class="expression-functions column"
[style.width]="currentSelectedMode == 'functions' || currentSelectedMode == 'systemVariable' ? '100%' : '30%'"
>
<div class="column-content">
<span
class="column-item {{ currentSelectedMode == 'functions' ? 'selected' : '' }}"
(click)="changeMode('functions')"
>
{{ loc.getP("Functions") }}
</span>
<span
class="column-item {{ currentSelectedMode == 'elements' ? 'selected' : '' }}"
(click)="changeMode('elements')"
>
{{ loc.get2("Report", "Components") }}
</span>
<span
class="column-item {{ currentSelectedMode == 'systemVariable' ? 'selected' : '' }}"
(click)="changeMode('systemVariable')"
>
{{ loc.getP("SystemVariable") }}
</span>
<span
class="column-item {{ currentSelectedMode == 'operators' ? 'selected' : '' }}"
(click)="changeMode('operators')"
>
{{ loc.get2("MathFormula", "Operators") }}
</span>
</div>
</div>
<div
class="expression-operators column"
*ngIf="currentSelectedMode == 'functions' || currentSelectedMode == 'systemVariable'"
>
<div class="column-content" *ngIf="currentSelectedMode == 'functions'">
<span
class="column-item {{ currentSelectedFunction == 'value' ? 'selected' : '' }}"
(click)="changeCurrentFuction('value')"
(mousedown)="startExpressionDragging({ object: 'Value', event: $event })"
(dblclick)="addFunction('Value')"
>
{{ "Value()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'count' ? 'selected' : '' }}"
(click)="changeCurrentFuction('count')"
(mousedown)="startExpressionDragging({ object: 'Count', event: $event })"
(dblclick)="addFunction('Count')"
>
{{ "Count()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'min' ? 'selected' : '' }}"
(click)="changeCurrentFuction('min')"
(mousedown)="startExpressionDragging({ object: 'Min', event: $event })"
(dblclick)="addFunction('Min')"
>
{{ "Min()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'max' ? 'selected' : '' }}"
(click)="changeCurrentFuction('max')"
(mousedown)="startExpressionDragging({ object: 'Max', event: $event })"
(dblclick)="addFunction('Max')"
>
{{ "Max()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'sum' ? 'selected' : '' }}"
(click)="changeCurrentFuction('sum')"
(mousedown)="startExpressionDragging({ object: 'Sum', event: $event })"
(dblclick)="addFunction('Sum')"
>
{{ "Sum()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'cell' ? 'selected' : '' }}"
(click)="changeCurrentFuction('cell')"
(mousedown)="startExpressionDragging({ object: 'Cell', event: $event })"
(dblclick)="addFunction('Cell')"
>
{{ "Cell()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'total' ? 'selected' : '' }}"
(click)="changeCurrentFuction('total')"
(mousedown)="startExpressionDragging({ object: 'Total', event: $event })"
(dblclick)="addFunction('Total')"
>
{{ "Total()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'col' ? 'selected' : '' }}"
(click)="changeCurrentFuction('col')"
(mousedown)="startExpressionDragging({ object: 'Col', event: $event })"
(dblclick)="addFunction('Col')"
>
{{ "Col()" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'row' ? 'selected' : '' }}"
(click)="changeCurrentFuction('row')"
(mousedown)="startExpressionDragging({ object: 'Row', event: $event })"
(dblclick)="addFunction('Row')"
>
{{ "Row()" }}
</span>
</div>
<div class="column-content" *ngIf="currentSelectedMode == 'systemVariable'">
<span
class="column-item {{ currentSelectedFunction == 'line' ? 'selected' : '' }}"
(click)="changeCurrentFuction('line')"
(mousedown)="startExpressionDragging({ object: 'Line', event: $event })"
(dblclick)="addFunction('Line')"
>
{{ "Line" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'today' ? 'selected' : '' }}"
(click)="changeCurrentFuction('today')"
(mousedown)="startExpressionDragging({ object: 'Today', event: $event })"
(dblclick)="addFunction('Today')"
>
{{ "Today" }}
</span>
<span
class="column-item {{ currentSelectedFunction == 'time' ? 'selected' : '' }}"
(click)="changeCurrentFuction('time')"
(mousedown)="startExpressionDragging({ object: 'Time', event: $event })"
(dblclick)="addFunction('Time')"
>
{{ "Time" }}
</span>
</div>
</div>
<div class="expression-fields column">
<div
class="column-content"
*ngIf="currentSelectedMode == 'functions' || currentSelectedMode == 'systemVariable'"
>
<div *ngFor="let sample of samples" class="sample-item">
<span>{{ sample }}</span>
</div>
<div class="sample-item" [style.padding]="'15px 0px'">
<span>{{ title }}</span>
</div>
</div>
<div class="column-content" *ngIf="currentSelectedMode == 'operators'">
<span
class="operator-item"
[stiTooltip]="loc.get2('Shapes', 'Plus')"
tooltipPosition="bottom"
showDelay="500"
(dblclick)="addOperator('+')"
(mousedown)="startExpressionDragging({ object: '+', event: $event })"
>+</span
>
<span
class="operator-item"
[stiTooltip]="loc.get2('Shapes', 'Minus')"
tooltipPosition="bottom"
showDelay="500"
(mousedown)="startExpressionDragging({ object: '-', event: $event })"
(dblclick)="addOperator('-')"
>-</span
>
<span
class="operator-item"
[stiTooltip]="loc.get2('Shapes', 'Multiply')"
tooltipPosition="bottom"
showDelay="500"
(mousedown)="startExpressionDragging({ object: '*', event: $event })"
(dblclick)="addOperator('*')"
>*</span
>
<span
class="operator-item"
[stiTooltip]="loc.get2('Shapes', 'Division')"
tooltipPosition="bottom"
showDelay="500"
(mousedown)="startExpressionDragging({ object: '/', event: $event })"
(dblclick)="addOperator('/')"
>/</span
>
</div>
<div class="column-content" *ngIf="currentSelectedMode == 'elements'">
<div *ngFor="let field of fields">
<div
class="column-item field"
[style.padding]="isTable(field) ? '4px 5px 4px 0px' : '4px 5px'"
(click)="isTable(field) ? changeState(field) : ''"
(mousedown)="!isTable(field) ? startExpressionDragging({ object: field, event: $event }) : ''"
(dblclick)="!isTable(field) ? addValue(field) : ''"
>
<div *ngIf="isTable(field)" class="arrow" [@rotatedState]="getState(field)">
<i class="pi pi-chevron-right"></i>
</div>
<span>{{ field.name }}</span>
</div>
<sti-columns-preview
*ngIf="isTable(field)"
[object]="field"
(fieldClick)="nestedFieldClick($event)"
(startFieldDrag)="startExpressionDragging($event)"
[state]="getState(field) == 'default' ? false : true"
></sti-columns-preview>
</div>
</div>
</div>
</div>
<div class="footer-navigation">
<div class="footer-button accept" (click)="save()" [style.margin-right.px]="0">
<span>{{ loc.get2("Buttons", "Save") }}</span>
</div>
<div class="footer-button cancel" (click)="model.showExpressionEditor = false">
<span>{{ loc.getP("Cancel") }}</span>
</div>
</div>
</div>`, animations: [RotateAnimation], styles: [".arrow{width:20px;cursor:default;-webkit-touch-callout:none;-webkit-user-select:none;display:flex;align-items:center;justify-content:center}.arrow .pi{font-size:.625rem}.pi{font-size:.825rem}.selected{background-color:#e5e5e5}.expression-editor-container{position:absolute;font-size:13px;font-family:Arial;color:var(--text-color);min-height:480px;width:700px;border-radius:5px;left:calc(50% - 350px);top:calc(50% - 250px);display:flex;flex-direction:column;border:1px solid rgb(28,71,134);background-color:#fff;-moz-box-shadow:0px 0px 7px rgba(0,0,0,.6);-webkit-box-shadow:0px 0px 7px rgb(0 0 0 / 60%);box-shadow:0 0 7px #0000004d;z-index:999}.header-navigation{display:flex;height:40px;align-items:center;padding-left:15px;padding-right:5px;border-top-left-radius:3px;border-top-right-radius:3px;background-color:#515c6a;color:#fff;-webkit-user-select:none}.header-navigation span{width:100%;font-size:17px;-webkit-user-select:none;cursor:default}.nav-button{height:24px;width:28px;border-radius:3px;display:flex;align-items:center;justify-content:center;align-self:start;margin-top:5px}.nav-button:hover{background-color:#d3d3d3}.nav-button img{height:16px;width:16px;filter:brightness(0) invert(1)}.expression-preview{width:calc(100% - 20px);margin:10px 10px 5px;padding:5px;background-color:#fafafa;border:1px solid lightgray;height:135px;-webkit-user-select:text;display:flex}.expression-preview label{-webkit-user-select:text;font-size:13px;outline:none;height:100%;width:100%;overflow:auto}.dragging-over{background-color:#ebebeb!important;border:1px dashed black!important}.expression-navigation{display:flex;width:100%;padding:0 5px}.column{border:1px solid lightgray;height:230px;width:100%;margin:5px}.buttons{height:250px;min-width:150px;display:flex;flex-direction:column;justify-content:center;align-items:center}.buttons img{height:52px;width:52px;border-radius:3px;margin:5px;padding:10px}.buttons img:hover{background-color:#d3d3d3}.column-header{-webkit-user-select:none;height:30px;background-color:#d3d3d3;display:flex;align-items:center;padding:0 10px;border-top-left-radius:4px;border-top-right-radius:4px}.column-header span{font-size:15px;-webkit-user-select:none;cursor:default}.footer-navigation{width:100%;display:flex;justify-content:flex-end;height:50px;align-items:center}.footer-button{min-width:90px;height:30px;border-radius:3px;display:flex;align-items:center;justify-content:center;margin:0 10px;-webkit-user-select:none;font-size:12px}.accept{background-color:#19478a;color:#fff}.accept:hover{background-color:#3d6298}.cancel{background-color:#ddd;color:#444}.cancel:hover{background-color:#d5d5d5}.column-content{width:100%;padding:5px;display:flex;max-height:229px;overflow-y:auto;flex-direction:column}.operator-item{font-family:Arial;color:var(--text-color);font-size:17px;padding:2px 7px;border-radius:3px;-webkit-user-select:none}.operator-item:hover{background-color:#f0f0f0}.sample-item{font-family:Arial;color:var(--text-color);font-size:12px;-webkit-user-select:none;padding-bottom:3px;cursor:default}.column-item{font-family:Arial;color:var(--text-color);font-size:12px;-webkit-user-select:none;padding:5px;cursor:default}.column-item:hover{background-color:#f0f0f0}.info{height:30px;width:30px;display:flex;align-items:center;justify-content:center}.info img{height:16px;width:16px;cursor:pointer}.field{display:flex;align-items:center}.field img{height:16px;width:16px;margin-right:5px}\n"] }]
}], ctorParameters: () => [{ type: i1.StiModelService }, { type: i2.StiExpressionService }, { type: i3.StiLocalizationService }, { type: i4.StiMouseService }, { type: i5.StiEditableContentService }, { type: i0.ChangeDetectorRef }], propDecorators: { elementRef: [{
type: ViewChild,
args: ["expressionRef"]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RpLWV4cHJlc3Npb24tZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0aW11bHNvZnQtZm9ybXMvc3JjL2xpYi9jb21wb25lbnRzL3N0aS1leHByZXNzaW9uLWVkaXRvci9zdGktZXhwcmVzc2lvbi1lZGl0b3IuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBb0MsU0FBUyxFQUFpQyxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFdEgsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNqRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUN6RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDakUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFJN0UsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFHN0UsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQzs7Ozs7Ozs7OztBQTZlbkUsTUFBTSxPQUFPLDRCQUE0QjtJQW1GdkMsWUFDUyxLQUFzQixFQUN0QixpQkFBdUMsRUFDdkMsR0FBMkIsRUFDM0IsWUFBNkIsRUFDN0IsZUFBMEMsRUFDekMsR0FBc0I7UUFMdkIsVUFBSyxHQUFMLEtBQUssQ0FBaUI7UUFDdEIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFzQjtRQUN2QyxRQUFHLEdBQUgsR0FBRyxDQUF3QjtRQUMzQixpQkFBWSxHQUFaLFlBQVksQ0FBaUI7UUFDN0Isb0JBQWUsR0FBZixlQUFlLENBQTJCO1FBQ3pDLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBdEZ6QixxQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDeEIsd0JBQW1CLEdBQUcsV0FBVyxDQUFDO1FBQ2xDLDRCQUF1QixHQUFHLE9BQU8sQ0FBQztRQU9sQyxzQkFBaUIsR0FBWSxLQUFLLENBQUM7UUFPbkMsbUJBQWMsR0FBMEI7WUFDN0M7Z0JBQ0UsWUFBWSxFQUFFLE9BQU87Z0JBQ3JCLE9BQU8sRUFBRSxDQUFDLGtCQUFrQixFQUFFLG9CQUFvQixFQUFFLGdCQUFnQixDQUFDO2dCQUNyRSxLQUFLLEVBQUUsOENBQThDO2FBQ3REO1lBQ0Q7Z0JBQ0UsWUFBWSxFQUFFLE9BQU87Z0JBQ3JCLE9BQU8sRUFBRSxDQUFDLHVCQUF1QixFQUFFLDZCQUE2QixDQUFDO2dCQUNqRSxLQUFLLEVBQUUsNkJBQTZCO2FBQ3JDO1lBQ0Q7Z0JBQ0UsWUFBWSxFQUFFLEtBQUs7Z0JBQ25CLE9BQU8sRUFBRSxDQUFDLHFCQUFxQixFQUFFLDJCQUEyQixDQUFDO2dCQUM3RCxLQUFLLEVBQUUsNkJBQTZCO2FBQ3JDO1lBQ0Q7Z0JBQ0UsWUFBWSxFQUFFLEtBQUs7Z0JBQ25CLE9BQU8sRUFBRSxDQUFDLHFCQUFxQixFQUFFLDJCQUEyQixDQUFDO2dCQUM3RCxLQUFLLEVBQUUsNEJBQTRCO2FBQ3BDO1lBQ0Q7Z0JBQ0UsWUFBWSxFQUFFLEtBQUs7Z0JBQ25CLE9BQU8sRUFBRSxDQUFDLHFCQUFxQixFQUFFLDJCQUEyQixDQUFDO2dCQUM3RCxLQUFLLEVBQUUsNEJBQTRCO2FBQ3BDO1lBQ0Q7Z0JBQ0UsWUFBWSxFQUFFLE1BQU07Z0JBQ3BCLE9BQU8sRUFBRSxDQUFDLHNCQUFzQixFQUFFLDhCQUE4QixDQUFDO2dCQUNqRSxLQUFLLEVBQUUsZ0NBQWdDO2FBQ3hDO1lBQ0Q7Z0JBQ0UsWUFBWSxFQUFFLE9BQU87Z0JBQ3JCLE9BQU8sRUFBRSxDQUFDLGdCQUFnQixFQUFFLHdCQUF3QixDQUFDO2dCQUNyRCxLQUFLLEVBQUUsOEJBQThCO2FBQ3RDO1lBQ0Q7Z0JBQ0UsWUFBWSxFQUFFLEtBQUs7Z0JBQ25CLE9BQU8sRUFBRSxDQUFDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQztnQkFDbkQsS0FBSyxFQUFFLDZEQUE2RDthQUNyRTtZQUNEO2dCQUNFLFlBQVksRUFBRSxLQUFLO2dCQUNuQixPQUFPLEVBQUUsQ0FBQyxlQUFlLEVBQUUsdUJBQXVCLENBQUM7Z0JBQ25ELEtBQUssRUFBRSwwREFBMEQ7YUFDbEU7WUFDRDtnQkFDRSxZQUFZLEVBQUUsTUFBTTtnQkFDcEIsT0FBTyxFQUFFLENBQUMsTUFBTSxDQUFDO2dCQUNqQixLQUFLLEVBQUUsd0RBQXdEO2FBQ2hFO1lBQ0Q7Z0JBQ0UsWUFBWSxFQUFFLE9BQU87Z0JBQ3JCLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQztnQkFDbEIsS0FBSyxFQUFFLDZDQUE2QzthQUNyRDtZQUNEO2dCQUNFLFlBQVksRUFBRSxNQUFNO2dCQUNwQixPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUM7Z0JBQ2pCLEtBQUssRUFBRSw2Q0FBNkM7YUFDckQ7U0FDRixDQUFDO1FBRUssa0JBQWEsR0FBRyxFQUFFLENBQU