@myrtex-org/form 1.1.27 → 1.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/modules/object-form/components/elements/base/base-field/base-field.component.mjs +8 -2
- package/esm2022/lib/modules/object-form/components/elements/input/number/input-number.component.mjs +9 -3
- package/esm2022/lib/modules/object-form/components/elements/input/table/components/input-table-modal/input-table-modal.component.mjs +52 -10
- package/esm2022/lib/modules/object-form/components/elements/input/table/input-table.component.mjs +2 -20
- package/esm2022/lib/modules/object-form/factories/component-factory/component-factory.directive.mjs +23 -32
- package/esm2022/lib/modules/object-form/services/formula-calculate.service.mjs +180 -0
- package/esm2022/lib/modules/object-form/services/index.mjs +2 -1
- package/fesm2022/myrtex-org-form.mjs +264 -60
- package/fesm2022/myrtex-org-form.mjs.map +1 -1
- package/lib/modules/object-form/components/elements/input/number/input-number.component.d.ts +2 -0
- package/lib/modules/object-form/components/elements/input/table/components/input-table-modal/input-table-modal.component.d.ts +5 -3
- package/lib/modules/object-form/components/elements/input/table/input-table.component.d.ts +1 -1
- package/lib/modules/object-form/factories/component-factory/component-factory.directive.d.ts +2 -3
- package/lib/modules/object-form/services/formula-calculate.service.d.ts +19 -0
- package/lib/modules/object-form/services/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, inject,
|
|
2
|
+
import { Injectable, inject, ChangeDetectionStrategy, Component, EventEmitter, Output, Input, Directive, ChangeDetectorRef, Inject, ViewChild, NgModule } from '@angular/core';
|
|
3
3
|
import * as i1$3 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import * as i1$1 from '@angular/router';
|
|
@@ -863,6 +863,184 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
863
863
|
type: Injectable
|
|
864
864
|
}] });
|
|
865
865
|
|
|
866
|
+
class FormulaCalculateService {
|
|
867
|
+
constructor() {
|
|
868
|
+
this._operatorPrecedence = {
|
|
869
|
+
'+': 1,
|
|
870
|
+
'-': 1,
|
|
871
|
+
'*': 2,
|
|
872
|
+
'/': 2,
|
|
873
|
+
};
|
|
874
|
+
this._operators = ['+', '-', '*', '/'];
|
|
875
|
+
}
|
|
876
|
+
calculateMathExpression(expression, values) {
|
|
877
|
+
try {
|
|
878
|
+
return this._calculateMathExpression(expression, values);
|
|
879
|
+
}
|
|
880
|
+
catch {
|
|
881
|
+
return 0;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
calculateStringConcatenation(expression, values) {
|
|
885
|
+
return expression.replace(/{(?<systemName>\w+)(?::(?<format>[^}]+))?}/g, (_match, systemName) => {
|
|
886
|
+
const value = values.find(x => x.sysName === systemName);
|
|
887
|
+
return value?.value?.toString?.() ?? '';
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
_calculateMathExpression(expression, values) {
|
|
891
|
+
const operatorStack = [];
|
|
892
|
+
const operandStack = [];
|
|
893
|
+
for (let i = 0; i < expression.length; i++) {
|
|
894
|
+
const charValue = expression[i];
|
|
895
|
+
if (/\s/.test(charValue)) {
|
|
896
|
+
continue;
|
|
897
|
+
}
|
|
898
|
+
if (charValue === '{') {
|
|
899
|
+
let sysNameOperand = '';
|
|
900
|
+
while (i < expression.length && expression[i] !== '}') {
|
|
901
|
+
sysNameOperand += expression[i];
|
|
902
|
+
i++;
|
|
903
|
+
}
|
|
904
|
+
sysNameOperand += expression[i] ?? '';
|
|
905
|
+
const value = this._getNumberValue(values, sysNameOperand);
|
|
906
|
+
if (value === null) {
|
|
907
|
+
return 0;
|
|
908
|
+
}
|
|
909
|
+
operandStack.push(value);
|
|
910
|
+
continue;
|
|
911
|
+
}
|
|
912
|
+
if (charValue === '(') {
|
|
913
|
+
const nestedExpression = this._getExpressionBetweenParentheses(expression, i);
|
|
914
|
+
operandStack.push(this._calculateMathExpression(nestedExpression, values));
|
|
915
|
+
i += nestedExpression.length + 1;
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
918
|
+
if (this._isOperator(charValue)) {
|
|
919
|
+
this._addOperator(operatorStack, operandStack, charValue);
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
if (/\d/.test(charValue)) {
|
|
923
|
+
let number = '';
|
|
924
|
+
while (i < expression.length && (/[\d.]/.test(expression[i]))) {
|
|
925
|
+
number += expression[i];
|
|
926
|
+
i++;
|
|
927
|
+
}
|
|
928
|
+
i--;
|
|
929
|
+
const value = this._getNumberValue(values, number);
|
|
930
|
+
if (value === null) {
|
|
931
|
+
return 0;
|
|
932
|
+
}
|
|
933
|
+
operandStack.push(value);
|
|
934
|
+
continue;
|
|
935
|
+
}
|
|
936
|
+
if (/[a-zA-Z]/.test(charValue)) {
|
|
937
|
+
i += this._addFunctionResult(operandStack, values, expression, i);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
this._calculateAll(operandStack, operatorStack);
|
|
941
|
+
return operandStack.pop() ?? 0;
|
|
942
|
+
}
|
|
943
|
+
_addFunctionResult(operandStack, values, expression, startIndex) {
|
|
944
|
+
const idxEof = expression.indexOf(')', startIndex);
|
|
945
|
+
const operand = expression.substring(startIndex, idxEof - startIndex + 1);
|
|
946
|
+
const lowerOperand = operand.toLowerCase();
|
|
947
|
+
if (lowerOperand.startsWith('pow(') && lowerOperand.endsWith(')')) {
|
|
948
|
+
const innerExpression = operand.substring(4, operand.length - 1);
|
|
949
|
+
const innerOperands = innerExpression.split(',').map(x => x.trim());
|
|
950
|
+
const baseValue = this._getNumberValue(values, innerOperands[0]);
|
|
951
|
+
const exponent = this._getNumberValue(values, innerOperands[1]);
|
|
952
|
+
if (baseValue === null || exponent === null) {
|
|
953
|
+
operandStack.push(0);
|
|
954
|
+
}
|
|
955
|
+
else {
|
|
956
|
+
operandStack.push(Math.pow(baseValue, exponent));
|
|
957
|
+
}
|
|
958
|
+
return operand.length - 1;
|
|
959
|
+
}
|
|
960
|
+
if (lowerOperand.startsWith('sqrt(') && lowerOperand.endsWith(')')) {
|
|
961
|
+
const innerExpression = operand.substring(5, operand.length - 1);
|
|
962
|
+
const value = this._getNumberValue(values, innerExpression);
|
|
963
|
+
operandStack.push(value === null ? 0 : Math.sqrt(value));
|
|
964
|
+
return operand.length - 1;
|
|
965
|
+
}
|
|
966
|
+
throw new Error('Invalid function operand');
|
|
967
|
+
}
|
|
968
|
+
_addOperator(operatorStack, operandStack, operatorToken) {
|
|
969
|
+
while (operatorStack.length > 0 &&
|
|
970
|
+
this._getOperatorPrecedence(operatorToken) <= this._getOperatorPrecedence(operatorStack[operatorStack.length - 1])) {
|
|
971
|
+
const operand2 = operandStack.pop() ?? 0;
|
|
972
|
+
const operand1 = operandStack.pop() ?? 0;
|
|
973
|
+
const operatorTokenToApply = operatorStack.pop();
|
|
974
|
+
operandStack.push(this._calculate(operand1, operand2, operatorTokenToApply));
|
|
975
|
+
}
|
|
976
|
+
operatorStack.push(operatorToken);
|
|
977
|
+
}
|
|
978
|
+
_calculateAll(operandStack, operatorStack) {
|
|
979
|
+
while (operatorStack.length > 0) {
|
|
980
|
+
const operatorToken = operatorStack.pop();
|
|
981
|
+
const operand2 = operandStack.pop() ?? 0;
|
|
982
|
+
const operand1 = operandStack.pop() ?? 0;
|
|
983
|
+
operandStack.push(this._calculate(operand1, operand2, operatorToken));
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
_getOperatorPrecedence(operatorToken) {
|
|
987
|
+
return this._operatorPrecedence[operatorToken];
|
|
988
|
+
}
|
|
989
|
+
_getExpressionBetweenParentheses(expression, startIndex) {
|
|
990
|
+
let level = 0;
|
|
991
|
+
for (let i = startIndex; i < expression.length; i++) {
|
|
992
|
+
if (expression[i] === '(') {
|
|
993
|
+
level++;
|
|
994
|
+
}
|
|
995
|
+
else if (expression[i] === ')') {
|
|
996
|
+
level--;
|
|
997
|
+
if (level === 0) {
|
|
998
|
+
return expression.substring(startIndex + 1, i);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
throw new Error('Unbalanced parentheses');
|
|
1003
|
+
}
|
|
1004
|
+
_getNumberValue(values, operand) {
|
|
1005
|
+
const cleanOperand = operand.trim().replace(',', '.').replace(/^\{|\}$/g, '');
|
|
1006
|
+
const val = values.find(x => x.sysName === cleanOperand);
|
|
1007
|
+
if (val) {
|
|
1008
|
+
if (val.value === null || val.value === undefined || val.value === '') {
|
|
1009
|
+
return null;
|
|
1010
|
+
}
|
|
1011
|
+
const parsed = Number(String(val.value).replace(',', '.'));
|
|
1012
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
1013
|
+
}
|
|
1014
|
+
const asNumber = Number(cleanOperand);
|
|
1015
|
+
if (Number.isFinite(asNumber)) {
|
|
1016
|
+
return asNumber;
|
|
1017
|
+
}
|
|
1018
|
+
throw new Error(`Invalid operand ${operand}`);
|
|
1019
|
+
}
|
|
1020
|
+
_calculate(operand1, operand2, operatorToken) {
|
|
1021
|
+
switch (operatorToken) {
|
|
1022
|
+
case '+':
|
|
1023
|
+
return operand1 + operand2;
|
|
1024
|
+
case '-':
|
|
1025
|
+
return operand1 - operand2;
|
|
1026
|
+
case '*':
|
|
1027
|
+
return operand1 * operand2;
|
|
1028
|
+
case '/':
|
|
1029
|
+
return operand1 / operand2;
|
|
1030
|
+
default:
|
|
1031
|
+
throw new Error(`Invalid operator ${operatorToken}`);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
_isOperator(token) {
|
|
1035
|
+
return this._operators.includes(token);
|
|
1036
|
+
}
|
|
1037
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FormulaCalculateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1038
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FormulaCalculateService }); }
|
|
1039
|
+
}
|
|
1040
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FormulaCalculateService, decorators: [{
|
|
1041
|
+
type: Injectable
|
|
1042
|
+
}] });
|
|
1043
|
+
|
|
866
1044
|
class ObjectFormEffects {
|
|
867
1045
|
constructor(_actions$, _store, _router, _applicationService, _toasterService) {
|
|
868
1046
|
this._actions$ = _actions$;
|
|
@@ -1041,48 +1219,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1041
1219
|
}], ctorParameters: () => [{ type: i1$1.Router }] });
|
|
1042
1220
|
|
|
1043
1221
|
class ComponentFactoryDirective {
|
|
1044
|
-
constructor(viewContainer
|
|
1222
|
+
constructor(viewContainer) {
|
|
1045
1223
|
this.viewContainer = viewContainer;
|
|
1046
|
-
this.cdr = cdr;
|
|
1047
1224
|
this.values = [];
|
|
1048
1225
|
this.changed = new EventEmitter();
|
|
1049
1226
|
}
|
|
1050
1227
|
ngOnChanges(changes) {
|
|
1051
|
-
|
|
1052
|
-
if ('type' in changes && this.type) {
|
|
1228
|
+
if ('type' in changes && this.type && changes['type'].previousValue !== changes['type'].currentValue) {
|
|
1053
1229
|
this.initWidget(this.type);
|
|
1054
1230
|
}
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
// Используем currentValue из changes, чтобы быть уверенными в свежести данных
|
|
1064
|
-
if ('values' in changes) {
|
|
1065
|
-
this.dynamicComponent.instance.values = changes['values'].currentValue;
|
|
1066
|
-
}
|
|
1067
|
-
// КРИТИЧНО: уведомляем Angular, что в динамическом компоненте обновились данные
|
|
1068
|
-
this.dynamicComponent.changeDetectorRef.detectChanges();
|
|
1231
|
+
if ('data' in changes && this.data) {
|
|
1232
|
+
this.applyData(this.data);
|
|
1233
|
+
}
|
|
1234
|
+
if ('valueMode' in changes && this.data && this.valueMode) {
|
|
1235
|
+
this.applyValueMode(this.valueMode);
|
|
1236
|
+
}
|
|
1237
|
+
if ('values' in changes && this.data) {
|
|
1238
|
+
this.applyValues(this.values);
|
|
1069
1239
|
}
|
|
1070
1240
|
}
|
|
1071
1241
|
initWidget(type) {
|
|
1072
1242
|
const componentType = this.map[type];
|
|
1073
|
-
if (!componentType)
|
|
1243
|
+
if (!componentType) {
|
|
1074
1244
|
return;
|
|
1075
|
-
|
|
1245
|
+
}
|
|
1246
|
+
if (this.dynamicComponent) {
|
|
1247
|
+
this.viewContainer.clear();
|
|
1248
|
+
this.dynamicComponent = undefined;
|
|
1249
|
+
}
|
|
1076
1250
|
this.dynamicComponent = this.viewContainer.createComponent(componentType);
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
if (this.values)
|
|
1082
|
-
instance.values = this.values;
|
|
1083
|
-
if (this.valueMode)
|
|
1084
|
-
instance.valueMode = this.valueMode;
|
|
1085
|
-
if (this.dynamicComponent && this.dynamicComponent.instance.changed) {
|
|
1251
|
+
if (this.data) {
|
|
1252
|
+
this.dynamicComponent.instance.data = this.data;
|
|
1253
|
+
}
|
|
1254
|
+
if (this.dynamicComponent.instance.changed) {
|
|
1086
1255
|
this.dynamicComponent.instance.changed.subscribe((res) => {
|
|
1087
1256
|
this.changed.emit(res);
|
|
1088
1257
|
});
|
|
@@ -1103,7 +1272,7 @@ class ComponentFactoryDirective {
|
|
|
1103
1272
|
this.dynamicComponent.instance.valueMode = valueMode;
|
|
1104
1273
|
}
|
|
1105
1274
|
}
|
|
1106
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComponentFactoryDirective, deps: [{ token: i0.ViewContainerRef }
|
|
1275
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComponentFactoryDirective, deps: [{ token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1107
1276
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: ComponentFactoryDirective, isStandalone: true, selector: "[appComponentFactory]", inputs: { type: "type", data: "data", values: "values", valueMode: "valueMode", map: "map" }, outputs: { changed: "changed" }, usesOnChanges: true, ngImport: i0 }); }
|
|
1108
1277
|
}
|
|
1109
1278
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ComponentFactoryDirective, decorators: [{
|
|
@@ -1112,7 +1281,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1112
1281
|
selector: '[appComponentFactory]',
|
|
1113
1282
|
standalone: true
|
|
1114
1283
|
}]
|
|
1115
|
-
}], ctorParameters: () => [{ type: i0.ViewContainerRef }
|
|
1284
|
+
}], ctorParameters: () => [{ type: i0.ViewContainerRef }], propDecorators: { type: [{
|
|
1116
1285
|
type: Input
|
|
1117
1286
|
}], data: [{
|
|
1118
1287
|
type: Input
|
|
@@ -1172,6 +1341,12 @@ class BaseFieldComponent {
|
|
|
1172
1341
|
set values(value) {
|
|
1173
1342
|
if (this.valueMode === 'manual') {
|
|
1174
1343
|
this.manualValues = value;
|
|
1344
|
+
const isFormulaInputNumber = this.settings?.type === ComponentType.InputNumber &&
|
|
1345
|
+
this.settings?.options?.inputState === InputState.Formula;
|
|
1346
|
+
if (isFormulaInputNumber && this.model) {
|
|
1347
|
+
this.model.value = getValueModel(this.settings, this.manualValues)?.value;
|
|
1348
|
+
this._detector.detectChanges();
|
|
1349
|
+
}
|
|
1175
1350
|
}
|
|
1176
1351
|
}
|
|
1177
1352
|
set data(settings) {
|
|
@@ -1403,6 +1578,12 @@ class InputNumberComponent extends BaseFieldComponent {
|
|
|
1403
1578
|
this.validateValue = 0;
|
|
1404
1579
|
}
|
|
1405
1580
|
get isReadonly() {
|
|
1581
|
+
return this.hasFormula;
|
|
1582
|
+
}
|
|
1583
|
+
get isInputDisabled() {
|
|
1584
|
+
return this.disabled || this.hasFormula;
|
|
1585
|
+
}
|
|
1586
|
+
get hasFormula() {
|
|
1406
1587
|
return this.settings.options.inputState === InputState.Formula;
|
|
1407
1588
|
}
|
|
1408
1589
|
onChangeInput() {
|
|
@@ -1415,11 +1596,11 @@ class InputNumberComponent extends BaseFieldComponent {
|
|
|
1415
1596
|
this.settings.options.maxValue && model.value && this.settings.options.maxValue < model.value);
|
|
1416
1597
|
}
|
|
1417
1598
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: InputNumberComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
1418
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: InputNumberComponent, selector: "app-input-number", usesInheritance: true, ngImport: i0, template: "@if (settings) {\r\n <div class=\"input-number-content\">\r\n @if (settings.options.label) {\r\n <mrx-label\r\n [required]=\"settings.options.required\"\r\n [tooltip]=\"settings.options.tooltip || ''\"\r\n >\r\n {{ settings.options.label }}\r\n </mrx-label>\r\n }\r\n\r\n <mrx-input-number\r\n [(ngModel)]=\"model.value\"\r\n [fields]=\"autosaveFields\"\r\n [readonly]=\"isReadonly\"\r\n [allowNegative]=\"true\"\r\n [numberType]=\"isReadonly || settings.options.decimals ? 'float' : 'int'\"\r\n [decimalSeparator]=\"settings.options.decimalSeparator\"\r\n [decimals]=\"isReadonly ? (settings.options.decimals || 2) : settings.options.decimals\"\r\n [placeholder]=\"settings.options.placeholder\"\r\n [disabled]=\"
|
|
1599
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: InputNumberComponent, selector: "app-input-number", usesInheritance: true, ngImport: i0, template: "@if (settings) {\r\n <div class=\"input-number-content\">\r\n @if (settings.options.label) {\r\n <mrx-label\r\n [required]=\"settings.options.required\"\r\n [tooltip]=\"settings.options.tooltip || ''\"\r\n >\r\n {{ settings.options.label }}\r\n </mrx-label>\r\n }\r\n\r\n <mrx-input-number\r\n [(ngModel)]=\"model.value\"\r\n [fields]=\"autosaveFields\"\r\n [readonly]=\"isReadonly\"\r\n [allowNegative]=\"true\"\r\n [numberType]=\"isReadonly || settings.options.decimals ? 'float' : 'int'\"\r\n [decimalSeparator]=\"settings.options.decimalSeparator\"\r\n [decimals]=\"isReadonly ? (settings.options.decimals || 2) : settings.options.decimals\"\r\n [placeholder]=\"settings.options.placeholder\"\r\n [disabled]=\"isInputDisabled\"\r\n [invalid]=\"getInvalid\"\r\n [invalidMessage]=\"getInvalidMessage\"\r\n (modelChange)=\"dispatchModify($event)\"\r\n (change)=\"onChangeInput()\"\r\n ></mrx-input-number>\r\n\r\n @if (settings.options.minValue) {\r\n <mrx-hint-error-message\r\n message=\"\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u2014 {{ settings.options.minValue }}\"\r\n [value]=\"validateValue\"\r\n [minValue]=\"settings.options.minValue\"\r\n ></mrx-hint-error-message>\r\n }\r\n @if (settings.options.maxValue) {\r\n <mrx-hint-error-message\r\n message=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u2014 {{ settings.options.maxValue }}\"\r\n [value]=\"validateValue\"\r\n [maxValue]=\"settings.options.maxValue\"\r\n ></mrx-hint-error-message>\r\n }\r\n </div>\r\n}\r\n", styles: [""], dependencies: [{ kind: "component", type: i1$2.LabelComponent, selector: "mrx-label", inputs: ["requiredHidden", "required", "boldLabel", "disabled", "placeholder", "label", "customClasses", "triggerTextPosition", "isPublicInfo", "publicInfoTooltip", "isSwitch", "switchLabel", "switchValue", "switchSize", "isCheckbox", "checkboxLabel", "checkboxValue", "counter", "linkText", "linkPrevent", "linkType", "linkMonochrome", "href", "triggerType", "tooltip", "tooltipInitialVisible", "isSaveToStorage"], outputs: ["changeSwitchValue", "changeCheckboxValue", "clickedLink"] }, { kind: "directive", type: i2$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i1$2.InputNumberComponent, selector: "mrx-input-number", inputs: ["fields", "placeholder", "innerClass", "customClasses", "required", "allowNegative", "size", "separator", "decimalSeparator", "decimals", "isNullableValue", "isAutoCorrectingValue", "invalid", "checkInvalid", "numberType", "invalidMessage", "disabled", "readonly", "minValue", "maxValue"], outputs: ["modelChange", "modelChangeBlur"] }, { kind: "component", type: i1$2.HintErrorMessageComponent, selector: "mrx-hint-error-message", inputs: ["message", "value", "maxValue", "minValue", "minLength", "maxLength", "checkInvalid"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1419
1600
|
}
|
|
1420
1601
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: InputNumberComponent, decorators: [{
|
|
1421
1602
|
type: Component,
|
|
1422
|
-
args: [{ selector: 'app-input-number', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (settings) {\r\n <div class=\"input-number-content\">\r\n @if (settings.options.label) {\r\n <mrx-label\r\n [required]=\"settings.options.required\"\r\n [tooltip]=\"settings.options.tooltip || ''\"\r\n >\r\n {{ settings.options.label }}\r\n </mrx-label>\r\n }\r\n\r\n <mrx-input-number\r\n [(ngModel)]=\"model.value\"\r\n [fields]=\"autosaveFields\"\r\n [readonly]=\"isReadonly\"\r\n [allowNegative]=\"true\"\r\n [numberType]=\"isReadonly || settings.options.decimals ? 'float' : 'int'\"\r\n [decimalSeparator]=\"settings.options.decimalSeparator\"\r\n [decimals]=\"isReadonly ? (settings.options.decimals || 2) : settings.options.decimals\"\r\n [placeholder]=\"settings.options.placeholder\"\r\n [disabled]=\"
|
|
1603
|
+
args: [{ selector: 'app-input-number', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (settings) {\r\n <div class=\"input-number-content\">\r\n @if (settings.options.label) {\r\n <mrx-label\r\n [required]=\"settings.options.required\"\r\n [tooltip]=\"settings.options.tooltip || ''\"\r\n >\r\n {{ settings.options.label }}\r\n </mrx-label>\r\n }\r\n\r\n <mrx-input-number\r\n [(ngModel)]=\"model.value\"\r\n [fields]=\"autosaveFields\"\r\n [readonly]=\"isReadonly\"\r\n [allowNegative]=\"true\"\r\n [numberType]=\"isReadonly || settings.options.decimals ? 'float' : 'int'\"\r\n [decimalSeparator]=\"settings.options.decimalSeparator\"\r\n [decimals]=\"isReadonly ? (settings.options.decimals || 2) : settings.options.decimals\"\r\n [placeholder]=\"settings.options.placeholder\"\r\n [disabled]=\"isInputDisabled\"\r\n [invalid]=\"getInvalid\"\r\n [invalidMessage]=\"getInvalidMessage\"\r\n (modelChange)=\"dispatchModify($event)\"\r\n (change)=\"onChangeInput()\"\r\n ></mrx-input-number>\r\n\r\n @if (settings.options.minValue) {\r\n <mrx-hint-error-message\r\n message=\"\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u2014 {{ settings.options.minValue }}\"\r\n [value]=\"validateValue\"\r\n [minValue]=\"settings.options.minValue\"\r\n ></mrx-hint-error-message>\r\n }\r\n @if (settings.options.maxValue) {\r\n <mrx-hint-error-message\r\n message=\"\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u2014 {{ settings.options.maxValue }}\"\r\n [value]=\"validateValue\"\r\n [maxValue]=\"settings.options.maxValue\"\r\n ></mrx-hint-error-message>\r\n }\r\n </div>\r\n}\r\n" }]
|
|
1423
1604
|
}] });
|
|
1424
1605
|
|
|
1425
1606
|
class InputSelectComponent extends BaseFieldComponent {
|
|
@@ -1994,11 +2175,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1994
2175
|
}] } });
|
|
1995
2176
|
|
|
1996
2177
|
class InputTableModalComponent extends ModalServiceComponent {
|
|
1997
|
-
constructor(dialogRef, store,
|
|
2178
|
+
constructor(dialogRef, store, formulaCalculateService, data) {
|
|
1998
2179
|
super();
|
|
1999
2180
|
this.dialogRef = dialogRef;
|
|
2000
2181
|
this.store = store;
|
|
2001
|
-
this.
|
|
2182
|
+
this.formulaCalculateService = formulaCalculateService;
|
|
2002
2183
|
this.emptyRow = true;
|
|
2003
2184
|
this.title = data.title;
|
|
2004
2185
|
this.okText = data.okText;
|
|
@@ -2016,6 +2197,7 @@ class InputTableModalComponent extends ModalServiceComponent {
|
|
|
2016
2197
|
else {
|
|
2017
2198
|
this._transformValues(valueModel);
|
|
2018
2199
|
}
|
|
2200
|
+
this._recalculateFormulaFields();
|
|
2019
2201
|
this.emptyRow = this.rowModel.data.every(x => this.isEmpty(x.value, x.valueType));
|
|
2020
2202
|
}
|
|
2021
2203
|
ok() {
|
|
@@ -2036,14 +2218,52 @@ class InputTableModalComponent extends ModalServiceComponent {
|
|
|
2036
2218
|
this.dialogRef.close(this.result);
|
|
2037
2219
|
}
|
|
2038
2220
|
_transformValues(value) {
|
|
2039
|
-
console.log('Update field:', value.sysName, 'with value:', value.value);
|
|
2040
2221
|
const cloneRowModel = structuredClone(this.rowModel);
|
|
2041
|
-
const findValue = cloneRowModel.data.find(c => c.sysName === value.sysName);
|
|
2222
|
+
const findValue = cloneRowModel.data.find((c) => c.sysName === value.sysName);
|
|
2042
2223
|
if (findValue) {
|
|
2043
2224
|
findValue.value = value.value;
|
|
2044
2225
|
}
|
|
2045
2226
|
this.rowModel = cloneRowModel;
|
|
2046
|
-
|
|
2227
|
+
}
|
|
2228
|
+
_recalculateFormulaFields() {
|
|
2229
|
+
const formulaComponents = this._getFormulaNumberComponents(this.settings.components);
|
|
2230
|
+
if (!formulaComponents.length) {
|
|
2231
|
+
return;
|
|
2232
|
+
}
|
|
2233
|
+
const cloneRowModel = structuredClone(this.rowModel);
|
|
2234
|
+
for (let i = 0; i < formulaComponents.length; i++) {
|
|
2235
|
+
let hasUpdates = false;
|
|
2236
|
+
for (const component of formulaComponents) {
|
|
2237
|
+
const formula = component.options?.formula?.trim();
|
|
2238
|
+
if (!formula) {
|
|
2239
|
+
continue;
|
|
2240
|
+
}
|
|
2241
|
+
const result = this.formulaCalculateService.calculateMathExpression(formula, cloneRowModel.data);
|
|
2242
|
+
const targetValue = cloneRowModel.data.find(x => x.sysName === component.sysName);
|
|
2243
|
+
if (!targetValue || targetValue.value === result) {
|
|
2244
|
+
continue;
|
|
2245
|
+
}
|
|
2246
|
+
targetValue.value = result;
|
|
2247
|
+
hasUpdates = true;
|
|
2248
|
+
}
|
|
2249
|
+
if (!hasUpdates) {
|
|
2250
|
+
break;
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
this.rowModel = cloneRowModel;
|
|
2254
|
+
}
|
|
2255
|
+
_getFormulaNumberComponents(components) {
|
|
2256
|
+
const result = [];
|
|
2257
|
+
for (const component of components) {
|
|
2258
|
+
if (component.type === ComponentType.InputNumber &&
|
|
2259
|
+
component.options?.inputState === InputState.Formula) {
|
|
2260
|
+
result.push(component);
|
|
2261
|
+
}
|
|
2262
|
+
if (component.components?.length) {
|
|
2263
|
+
result.push(...this._getFormulaNumberComponents(component.components));
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
return result;
|
|
2047
2267
|
}
|
|
2048
2268
|
_isValid() {
|
|
2049
2269
|
var hasError = false;
|
|
@@ -2076,9 +2296,10 @@ class InputTableModalComponent extends ModalServiceComponent {
|
|
|
2076
2296
|
return value.length === 0;
|
|
2077
2297
|
return false;
|
|
2078
2298
|
}
|
|
2079
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: InputTableModalComponent, deps: [{ token: i1$2.ModalRef }, { token: i2.Store }, { token:
|
|
2299
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: InputTableModalComponent, deps: [{ token: i1$2.ModalRef }, { token: i2.Store }, { token: FormulaCalculateService }, { token: MODAL_DATA }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2080
2300
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: InputTableModalComponent, isStandalone: true, selector: "app-input-table-modal", providers: [
|
|
2081
2301
|
provideNgxMask(),
|
|
2302
|
+
FormulaCalculateService,
|
|
2082
2303
|
ReferenceService // для компонента список
|
|
2083
2304
|
], usesInheritance: true, ngImport: i0, template: "<mrx-modal\r\n [title]=\"title\"\r\n size=\"large\"\r\n (close)=\"close()\"\r\n (ok)=\"ok()\"\r\n>\r\n <app-form-dispenser-modal\r\n [sectionSettings]=\"settings\"\r\n [values]=\"rowModel.data\"\r\n [valueMode]=\"'manual'\"\r\n (changed)=\"componentValueChanged($event)\"\r\n ></app-form-dispenser-modal>\r\n\r\n <ng-template #footerContent>\r\n <mrx-button\r\n [customClasses]=\"'mr-3'\"\r\n [type]=\"'secondary'\"\r\n [size]=\"'medium'\"\r\n (click)=\"close()\"\r\n >\u041E\u0442\u043C\u0435\u043D\u0430\r\n </mrx-button>\r\n <mrx-button\r\n [type]=\"'primary'\"\r\n [size]=\"'medium'\"\r\n [disabled]=\"emptyRow\"\r\n (click)=\"ok()\"\r\n >{{ okText }}\r\n </mrx-button>\r\n </ng-template>\r\n</mrx-modal>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ModalModule }, { kind: "component", type: i1$2.ModalComponent, selector: "mrx-modal", inputs: ["title", "message", "alert", "okText", "closeText", "size", "color", "customClasses", "expandable", "isEmbed", "isClose", "isBack", "backText", "enableFooter", "alignButtons", "isLoading", "iconPosition"], outputs: ["ok", "close", "back", "expand"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$2.ButtonComponent, selector: "mrx-button", inputs: ["size", "type", "color", "iconPosition", "active", "disabled", "isLoading", "iconOnly", "customClasses", "label", "icon", "iconClass", "buttonType", "href", "target", "routerLink", "queryParams"], outputs: ["mrxClick"] }, { kind: "component", type: FormDispenserModal, selector: "app-form-dispenser-modal", inputs: ["sectionSettings", "values", "valueMode"], outputs: ["changed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2084
2305
|
}
|
|
@@ -2090,9 +2311,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2090
2311
|
FormDispenserModal,
|
|
2091
2312
|
], providers: [
|
|
2092
2313
|
provideNgxMask(),
|
|
2314
|
+
FormulaCalculateService,
|
|
2093
2315
|
ReferenceService // для компонента список
|
|
2094
2316
|
], template: "<mrx-modal\r\n [title]=\"title\"\r\n size=\"large\"\r\n (close)=\"close()\"\r\n (ok)=\"ok()\"\r\n>\r\n <app-form-dispenser-modal\r\n [sectionSettings]=\"settings\"\r\n [values]=\"rowModel.data\"\r\n [valueMode]=\"'manual'\"\r\n (changed)=\"componentValueChanged($event)\"\r\n ></app-form-dispenser-modal>\r\n\r\n <ng-template #footerContent>\r\n <mrx-button\r\n [customClasses]=\"'mr-3'\"\r\n [type]=\"'secondary'\"\r\n [size]=\"'medium'\"\r\n (click)=\"close()\"\r\n >\u041E\u0442\u043C\u0435\u043D\u0430\r\n </mrx-button>\r\n <mrx-button\r\n [type]=\"'primary'\"\r\n [size]=\"'medium'\"\r\n [disabled]=\"emptyRow\"\r\n (click)=\"ok()\"\r\n >{{ okText }}\r\n </mrx-button>\r\n </ng-template>\r\n</mrx-modal>\r\n" }]
|
|
2095
|
-
}], ctorParameters: () => [{ type: i1$2.ModalRef }, { type: i2.Store }, { type:
|
|
2317
|
+
}], ctorParameters: () => [{ type: i1$2.ModalRef }, { type: i2.Store }, { type: FormulaCalculateService }, { type: undefined, decorators: [{
|
|
2096
2318
|
type: Inject,
|
|
2097
2319
|
args: [MODAL_DATA]
|
|
2098
2320
|
}] }] });
|
|
@@ -2193,7 +2415,7 @@ class InputTableComponent {
|
|
|
2193
2415
|
});
|
|
2194
2416
|
}
|
|
2195
2417
|
deleteRow(event) {
|
|
2196
|
-
const findRow =
|
|
2418
|
+
const findRow = this.model.data.find(item => item.id === event.row.data.id);
|
|
2197
2419
|
if (findRow) {
|
|
2198
2420
|
this.model.data = this.model.data.filter(item => item.id !== event.row.data.id);
|
|
2199
2421
|
this._initDataSource(this.model.data);
|
|
@@ -2241,8 +2463,6 @@ class InputTableComponent {
|
|
|
2241
2463
|
switch (component.type) {
|
|
2242
2464
|
case ComponentType.InputDate:
|
|
2243
2465
|
return 'date';
|
|
2244
|
-
case ComponentType.InputSwitch:
|
|
2245
|
-
return 'boolean';
|
|
2246
2466
|
default:
|
|
2247
2467
|
return 'string';
|
|
2248
2468
|
}
|
|
@@ -2299,7 +2519,6 @@ class InputTableComponent {
|
|
|
2299
2519
|
this._detector.detectChanges();
|
|
2300
2520
|
}
|
|
2301
2521
|
_transformColumn(component) {
|
|
2302
|
-
const dataType = this.getDataType(component);
|
|
2303
2522
|
const column = {
|
|
2304
2523
|
caption: component.options.label || '',
|
|
2305
2524
|
columns: component.components.map(c => this._transformColumn(structuredClone(c))),
|
|
@@ -2308,21 +2527,6 @@ class InputTableComponent {
|
|
|
2308
2527
|
format: this.getFormat(component),
|
|
2309
2528
|
minWidth: 160
|
|
2310
2529
|
};
|
|
2311
|
-
if (dataType === 'boolean') {
|
|
2312
|
-
column.calculateCellValue = (rowData) => {
|
|
2313
|
-
const value = rowData[component.sysName];
|
|
2314
|
-
// Если true — Да, если false, "" или null — Нет
|
|
2315
|
-
return !!value;
|
|
2316
|
-
};
|
|
2317
|
-
column.lookup = {
|
|
2318
|
-
dataSource: [
|
|
2319
|
-
{ value: true, displayValue: 'Да' },
|
|
2320
|
-
{ value: false, displayValue: 'Нет' }
|
|
2321
|
-
],
|
|
2322
|
-
valueExpr: 'value',
|
|
2323
|
-
displayExpr: 'displayValue'
|
|
2324
|
-
};
|
|
2325
|
-
}
|
|
2326
2530
|
if (this.settings.options.groups.length) {
|
|
2327
2531
|
const findIdx = this.settings.options.groups.findIndex(x => x === component.sysName);
|
|
2328
2532
|
if (findIdx !== -1) {
|