@trudb/tru-common-lib 0.2.169 → 0.2.171

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.
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { Input, Directive, Injectable, NgModule, Inject, Component, HostListener, InjectionToken, ViewChild, EventEmitter, Output, ViewEncapsulation, Pipe, ViewContainerRef, ChangeDetectionStrategy, createComponent, Optional, ViewChildren, signal, QueryList, ContentChildren } from '@angular/core';
3
3
  import { EntityAspect, MetadataStore, DataService, EntityManager, EntityQuery, Predicate, FetchStrategy, EntityAction, breeze, EntityState, BinaryPredicate, AndOrPredicate } from 'breeze-client';
4
4
  import * as i1$1 from '@angular/common';
5
- import { CommonModule, NgIf, NgClass, DatePipe } from '@angular/common';
5
+ import { CommonModule, DatePipe, NgIf, NgClass } from '@angular/common';
6
6
  import * as i7 from '@angular/forms';
7
7
  import { FormsModule, FormControl, ReactiveFormsModule, FormGroup, Validators } from '@angular/forms';
8
8
  import { BehaviorSubject, defer, from, of, Subject, Observable, fromEvent, skip, forkJoin, first, finalize, throwError } from 'rxjs';
@@ -78,10 +78,10 @@ import * as i1$5 from '@angular/platform-browser';
78
78
  import { BrowserModule } from '@angular/platform-browser';
79
79
  import moment from 'moment/moment';
80
80
  import { v4 } from 'uuid';
81
+ import moment$1 from 'moment';
81
82
  import { AgGridAngular } from 'ag-grid-angular';
82
83
  import { provideGlobalGridOptions, ModuleRegistry, TextFilterModule, TextEditorModule, CustomFilterModule, ClientSideRowModelModule, AllCommunityModule } from 'ag-grid-community';
83
84
  import * as signalR from '@microsoft/signalr';
84
- import moment$1 from 'moment';
85
85
  import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
86
86
 
87
87
  class TruComponentConfigBase {
@@ -5954,200 +5954,561 @@ class TruDataGridCellRenderer {
5954
5954
  }
5955
5955
  }
5956
5956
 
5957
- class TruDataGridClipboard {
5958
- util;
5959
- uiNotification;
5960
- tableName = null;
5961
- columnName = null;
5962
- copiedCellData = null;
5963
- copiedCellEntity = null;
5964
- copiedCellParams = null;
5965
- copiedRows = [];
5966
- constructor(util, uiNotification) {
5967
- this.util = util;
5968
- this.uiNotification = uiNotification;
5957
+ class TruFormatter {
5958
+ appEnvironemt;
5959
+ modelTypeLookup;
5960
+ constructor(appEnvironemt, modelTypeLookup) {
5961
+ this.appEnvironemt = appEnvironemt;
5962
+ this.modelTypeLookup = modelTypeLookup;
5969
5963
  }
5970
- formatCellValue = (propertyConfig, value) => {
5971
- if (value === null || typeof value === 'undefined')
5964
+ formatDate = (date, format) => {
5965
+ if (date === null)
5966
+ return null;
5967
+ if (!(date instanceof Date))
5972
5968
  return '';
5973
- if (propertyConfig.typeName === 'rich-text-unbounded')
5974
- return this.util.htmlToPlainText(value);
5975
- if (propertyConfig.formatter)
5976
- return propertyConfig.formatter(propertyConfig);
5977
- return value;
5978
- };
5979
- copyCell = async (params, tableName, columnName, copiedCellData, copiedCellEntity) => {
5980
- this.tableName = tableName;
5981
- this.columnName = columnName;
5982
- this.copiedCellParams = params;
5983
- this.copiedCellData = copiedCellData;
5984
- this.copiedCellEntity = copiedCellEntity;
5985
- try {
5986
- await navigator.clipboard.writeText(params.value);
5987
- }
5988
- catch (err) {
5989
- console.error('Failed to copy text: ', err);
5990
- }
5991
- };
5992
- pasteCell = (params, pastedCellData, pastedCell) => {
5993
- let colDef = params.colDef;
5994
- let columnName = colDef.field;
5995
- let copiedCellDataTypeName = this.copiedCellData[this.copiedCellParams?.colDef?.field].property.typeName;
5996
- let pastedCellDataTypeName = pastedCellData[params.colDef?.field].property.typeName;
5997
- if (!colDef.editable) {
5998
- this.uiNotification.error('Cannot paste into a non-editable column: ' + colDef.field);
5999
- return;
6000
- }
6001
- if (copiedCellDataTypeName !== pastedCellDataTypeName) {
6002
- this.uiNotification.error('Clipboard data type does not match the current cell data type: ' + copiedCellDataTypeName + ' vs ' + pastedCellDataTypeName);
6003
- return;
6004
- }
6005
- else {
6006
- pastedCell.setProperty(columnName, this.copiedCellEntity?.getProperty(columnName));
6007
- params.api.refreshCells({ force: true });
6008
- }
5969
+ if (isNaN(date.getTime()))
5970
+ return '';
5971
+ var datePipe = new DatePipe('en-US');
5972
+ return datePipe.transform(date, format);
6009
5973
  };
6010
- copyRow = async (tableName, copiedRows) => {
6011
- this.tableName = tableName;
6012
- this.copiedRows = copiedRows;
6013
- if (copiedRows.length) {
6014
- let multiRowString = '';
6015
- this.copiedRows.forEach((copiedRow, index) => {
6016
- let rowPropertyValues = [];
6017
- let properties = copiedRow.$entity.entityType.getPropertyNames();
6018
- properties
6019
- .forEach((propertyName) => {
6020
- let propertyConfig = copiedRow[propertyName]?.property;
6021
- if (propertyConfig &&
6022
- propertyName !== tableName + 'Ref' &&
6023
- propertyName !== 'rowver' &&
6024
- propertyName !== 'Merge_Data_Set' &&
6025
- !propertyName.startsWith('o'))
6026
- rowPropertyValues.push(this.formatCellValue(copiedRow[propertyName].property, copiedRow.$entity.getProperty(propertyName)));
6027
- });
6028
- multiRowString += rowPropertyValues.join('\t') + '\n';
6029
- });
6030
- try {
6031
- await navigator.clipboard.writeText(multiRowString);
5974
+ isDate = (date) => {
5975
+ if (Object.prototype.toString.call(date) === '[object Date]') {
5976
+ if (isNaN(date.getTime())) {
5977
+ return false;
6032
5978
  }
6033
- catch (err) {
6034
- console.error('Failed to copy text: ', err);
5979
+ else {
5980
+ return true;
6035
5981
  }
6036
5982
  }
6037
- };
6038
- pasteRow = (gridApi, config, selectedRows) => {
6039
- if (this.tableName !== config.tableName) {
6040
- this.uiNotification.error('Clipboard data does not match the current table name: ' + this.tableName + ' vs ' + config.tableName);
6041
- return;
6042
- }
6043
- if (selectedRows && selectedRows.length !== this.copiedRows.length) {
6044
- this.uiNotification.error('Clipboard data does not match the number of selected rows: ' + this.copiedRows.length + ' vs ' + selectedRows.length);
6045
- return;
5983
+ else if (moment$1(date, "MM/DD/YYYY", true).isValid()) {
5984
+ return true;
6046
5985
  }
6047
- if (this.copiedRows.length) {
6048
- this.copiedRows.forEach((copiedRow, index) => {
6049
- let selectedRow = selectedRows[index];
6050
- let properties = copiedRow.$entity.entityType.getPropertyNames();
6051
- properties
6052
- .forEach((propertyName) => {
6053
- if (typeof selectedRow.$entity.setProperty !== 'undefined' &&
6054
- selectedRow[propertyName] && selectedRow[propertyName].property.canEdit &&
6055
- propertyName !== config.tableName + 'Ref' &&
6056
- propertyName !== 'rowver' &&
6057
- propertyName !== 'Merge_Data_Set' &&
6058
- !propertyName.startsWith('o'))
6059
- selectedRow.$entity.setProperty(propertyName, copiedRow.$entity.getProperty(propertyName));
6060
- });
6061
- });
6062
- gridApi.refreshCells({ force: true });
5986
+ else {
5987
+ return false;
6063
5988
  }
6064
5989
  };
6065
- insertRowsAtTop = (dataContext, config, addEntity) => {
6066
- if (this.tableName !== config.tableName) {
6067
- this.uiNotification.error('Clipboard data does not match the current table name: ' + this.tableName + ' vs ' + config.tableName);
6068
- return;
6069
- }
6070
- if (this.copiedRows.length) {
6071
- this.copiedRows.forEach((row) => {
6072
- let newEntity = dataContext.entityAccess().add(config.resultConfig.entityType);
6073
- let properties = row.entityType.getPropertyNames();
6074
- properties
6075
- .filter((propertyName) => {
6076
- return propertyName !== 'Ref' &&
6077
- propertyName !== config.resultConfig.entityType.name + 'Ref' &&
6078
- !this.util.isLowerCase(propertyName.charAt(0));
6079
- })
6080
- .forEach((propertyName) => {
6081
- if (typeof newEntity.setProperty !== 'undefined')
6082
- newEntity.setProperty(propertyName, row.getProperty(propertyName));
6083
- });
6084
- addEntity(newEntity, false);
6085
- });
6086
- }
5990
+ isPromise = function (value) {
5991
+ return Boolean(value && typeof value.then === 'function');
6087
5992
  };
6088
- getCopiedRows = () => {
6089
- return this.copiedRows;
5993
+ //Filters
5994
+ bigInteger = (cfg) => {
5995
+ var v = cfg.$;
5996
+ if (v === null)
5997
+ return null;
5998
+ return v;
6090
5999
  };
6091
- getCopiedCell = () => {
6092
- return this.copiedCellEntity;
6000
+ boolean = (cfg) => {
6001
+ var v = cfg.$;
6002
+ if (v === null)
6003
+ return null;
6004
+ return v ? 'True' : 'False';
6093
6005
  };
6094
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruDataGridClipboard, deps: [{ token: TruUtil }, { token: TruUiNotification }], target: i0.ɵɵFactoryTarget.Injectable });
6095
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruDataGridClipboard, providedIn: 'root' });
6096
- }
6097
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruDataGridClipboard, decorators: [{
6098
- type: Injectable,
6099
- args: [{
6100
- providedIn: 'root',
6101
- }]
6102
- }], ctorParameters: () => [{ type: TruUtil }, { type: TruUiNotification }] });
6103
-
6104
- class TruDataGridPkeyCellRenderer {
6105
- dataContext;
6106
- dataGridClipboard;
6107
- contextMenu;
6108
- // private eGui: is an empty element to satisfy the getGui method.
6109
- eGui;
6110
- windowClickSubscription;
6111
- params;
6112
- contextMenuPosition = { x: '0px', y: '0px' };
6113
- displayValue = '';
6114
- copyIsDisabled = true;
6115
- pasteIsDisabled = true;
6116
- insertAtTopIsDisabled = true;
6117
- constructor(dataContext, dataGridClipboard) {
6118
- this.dataContext = dataContext;
6119
- this.dataGridClipboard = dataGridClipboard;
6120
- }
6121
- onRightClick = (event) => {
6122
- event.preventDefault();
6123
- this.copyIsDisabled = this.params.api.getSelectedRows().length ? false : true;
6124
- this.pasteIsDisabled = this.dataGridClipboard.getCopiedRows().length && this.params.api.getSelectedRows().length ? false : true;
6125
- this.insertAtTopIsDisabled = this.dataGridClipboard.getCopiedRows().length && this.params.api.getSelectedRows().length ? false : true;
6126
- this.contextMenuPosition.x = event.pageX + 'px';
6127
- this.contextMenuPosition.y = (event.pageY) + 'px';
6128
- this.contextMenu.menu?.focusFirstItem('mouse');
6129
- this.contextMenu.openMenu();
6006
+ choiceLabel = (cfg) => {
6007
+ if (cfg.$ === null)
6008
+ return null;
6009
+ if (cfg.type) {
6010
+ var item = cfg.type.choices.filter(function (c) {
6011
+ return c.$ === cfg.$;
6012
+ });
6013
+ }
6014
+ else {
6015
+ return cfg.$;
6016
+ }
6017
+ if (item.length == 0)
6018
+ return null;
6019
+ return item[0].label;
6130
6020
  };
6131
- onMouseDown = (event) => {
6021
+ dateShort = (cfg) => {
6022
+ var v = cfg.$;
6023
+ if (!v || !this.isDate(v))
6024
+ return 'mm/dd/yyyy';
6025
+ v = new Date(v);
6026
+ var utc = new Date(v.getUTCFullYear(), v.getUTCMonth(), v.getUTCDate());
6027
+ return this.formatDate(utc, 'MM/dd/yyyy');
6132
6028
  };
6133
- onMouseUp = (event) => {
6029
+ datetimeShort = (cfg) => {
6030
+ var v = cfg.$;
6031
+ if (!v)
6032
+ return 'mm/dd/yyyy hh:mm a';
6033
+ return this.formatDate(v, 'MM/dd/yyyy hh:mm a');
6134
6034
  };
6135
- onCopy = (event) => {
6136
- let selectedRows = this.params.api.getSelectedRows();
6137
- if (selectedRows.length) {
6138
- let copiedRowData = selectedRows;
6139
- this.dataGridClipboard.copyRow(this.params.context.grid.config.tableName, copiedRowData);
6035
+ datetimespanShort = (cfg) => {
6036
+ var start = cfg.start.$;
6037
+ var end = cfg.end.$;
6038
+ var text = '';
6039
+ if (start !== null) {
6040
+ text = this.formatDate(start, 'MM/dd/yyyy hh:mm a') + ' - ';
6041
+ if (end != null) {
6042
+ if (start.getYear() === end.getYear() && start.getMonth() === end.getMonth() && start.getDay() === end.getDay())
6043
+ text += this.formatDate(end, 'hh:mm a');
6044
+ else
6045
+ text += this.formatDate(end, 'MM/dd/yyyy hh:mm a');
6046
+ }
6140
6047
  }
6048
+ else {
6049
+ if (end !== null)
6050
+ text += this.formatDate(end, 'MM/dd/yyyy hh:mm a');
6051
+ }
6052
+ return text;
6141
6053
  };
6142
- onPaste = (event) => {
6143
- this.dataGridClipboard.pasteRow(this.params.api, this.params.context.grid.config, this.params.api.getSelectedRows());
6144
- };
6145
- onInsertAtTop = (event) => {
6146
- this.dataGridClipboard.insertRowsAtTop(this.dataContext, this.params.context.grid.config, this.params.context.grid.addEntity);
6054
+ decimal = (cfg) => {
6055
+ var v = cfg.$;
6056
+ if (v === null)
6057
+ return null;
6058
+ return v;
6147
6059
  };
6148
- agInit(params) {
6149
- this.params = params;
6150
- if (params.value < 0)
6060
+ excelFormula = (val) => {
6061
+ if (_.isNaN(val))
6062
+ return '#VALUE!';
6063
+ if (val === Infinity)
6064
+ return '#DIV/0!';
6065
+ return val;
6066
+ };
6067
+ file = (cfg) => {
6068
+ if (this.isPromise(cfg.filename.$))
6069
+ return null;
6070
+ var text = '';
6071
+ if (cfg.filename.$ !== null)
6072
+ text += cfg.filename.$;
6073
+ return text;
6074
+ };
6075
+ float = (cfg) => {
6076
+ var v = cfg.$;
6077
+ if (v === null)
6078
+ return null;
6079
+ return v;
6080
+ };
6081
+ id = (value) => {
6082
+ if (!value)
6083
+ return null;
6084
+ return value;
6085
+ };
6086
+ integer = (cfg) => {
6087
+ var v = cfg.$;
6088
+ if (v === null)
6089
+ return null;
6090
+ return v;
6091
+ };
6092
+ intlAddress = (cfg) => {
6093
+ var text = '';
6094
+ if (cfg.address1.$ !== null)
6095
+ text += cfg.address1.$ + ' ';
6096
+ if (cfg.address2.$ !== null)
6097
+ text += cfg.address2.$ + ' ';
6098
+ if (cfg.country.$ !== null)
6099
+ text += cfg.country.$ + ' ';
6100
+ if (cfg.city.$ !== null)
6101
+ text += cfg.city.$ + ' ';
6102
+ if (cfg.stateProvince.$ !== null)
6103
+ text += cfg.stateProvince.$ + ' ';
6104
+ if (cfg.postalCode.$ !== null)
6105
+ text += cfg.postalCode.$ + ' ';
6106
+ return text;
6107
+ };
6108
+ intlAddressBasic = (cfg) => {
6109
+ var text = '';
6110
+ if (cfg.address1.$ !== null)
6111
+ text += cfg.address1.$ + ' ';
6112
+ if (cfg.address2.$ !== null)
6113
+ text += cfg.address2.$ + ' ';
6114
+ if (cfg.country.$ !== null)
6115
+ text += cfg.country.$ + ' ';
6116
+ if (cfg.city.$ !== null)
6117
+ text += cfg.city.$ + ' ';
6118
+ if (cfg.stateProvince.$ !== null)
6119
+ text += cfg.stateProvince.$ + ' ';
6120
+ if (cfg.postalCode.$ !== null)
6121
+ text += cfg.postalCode.$ + ' ';
6122
+ return text;
6123
+ };
6124
+ naPhone = (number) => {
6125
+ if (!number) {
6126
+ return '';
6127
+ }
6128
+ if (number) {
6129
+ if (number.$)
6130
+ number = number.$.replace(/[^0-9]/g, '');
6131
+ else
6132
+ number = number.$;
6133
+ }
6134
+ if (!number) {
6135
+ return '';
6136
+ }
6137
+ number = String(number);
6138
+ var formattedNumber = number;
6139
+ var c = (number[0] == '1') ? '+1 ' : '';
6140
+ number = number[0] == '1' ? number.slice(1) : number;
6141
+ var area = number.substring(0, 3);
6142
+ var front = number.substring(3, 6);
6143
+ var end = number.substring(6, 10);
6144
+ var ext = number.substring(10, 20);
6145
+ if (front) {
6146
+ formattedNumber = (c + "(" + area + ") " + front);
6147
+ }
6148
+ if (end) {
6149
+ formattedNumber += ("-" + end);
6150
+ }
6151
+ if (ext) {
6152
+ formattedNumber += (" x" + ext);
6153
+ }
6154
+ return formattedNumber;
6155
+ };
6156
+ intlPhone = (cfg) => {
6157
+ var field = cfg;
6158
+ var text = '';
6159
+ //if (cfg.countryCode.$ !== null) {
6160
+ // var country = _.find(countries.allCountries, function (country) { return country.iso2 === cfg.countryCode.$ });
6161
+ // var dialCode = country.dialCode;
6162
+ // text += '+' + dialCode + ' ';
6163
+ //}
6164
+ //if (cfg.phone.$ !== null) {
6165
+ // var clean = cfg.phone.$.replace(/[^0-9]/g, '');
6166
+ // try {
6167
+ // var countryCode = cfg.countryCode.$ ? cfg.countryCode.$ : field.property.countryCode;
6168
+ // var number = clean;
6169
+ // text += number + ' ';
6170
+ // } catch (e) {
6171
+ // text += clean + ' ';
6172
+ // }
6173
+ //}
6174
+ //if (cfg.extension.$ !== null)
6175
+ // text += ' x' + cfg.extension.$;
6176
+ return text;
6177
+ };
6178
+ password = (cfg) => {
6179
+ var v = cfg.$;
6180
+ if (v === null)
6181
+ return null;
6182
+ if (v.length > 0)
6183
+ return '********';
6184
+ return '';
6185
+ };
6186
+ percentage = (cfg) => {
6187
+ var v = cfg.$;
6188
+ if (typeof v === 'undefined')
6189
+ return undefined;
6190
+ if (v === null)
6191
+ return null;
6192
+ if (typeof v.toFixed === 'function')
6193
+ return (v * 100).toFixed(2) + '%';
6194
+ return v;
6195
+ };
6196
+ picture = (cfg) => {
6197
+ var text = '';
6198
+ if (cfg.filename.$ !== null)
6199
+ text += cfg.filename.$;
6200
+ return text;
6201
+ };
6202
+ ref = (cfg) => {
6203
+ var v = cfg.$;
6204
+ if (v === null)
6205
+ return null;
6206
+ return v.toString();
6207
+ };
6208
+ richText = (cfg) => {
6209
+ return cfg.$;
6210
+ };
6211
+ socialSecurityNumber = (cfg) => {
6212
+ var v = cfg.$;
6213
+ if (v === null)
6214
+ return null;
6215
+ return v.substring(0, 3) + '-' + v.substring(3, 5) + '-' + v.substring(5);
6216
+ };
6217
+ text = (cfg) => {
6218
+ return cfg.$;
6219
+ };
6220
+ textFormatting = (text) => {
6221
+ if (!text)
6222
+ return text;
6223
+ if (typeof text.replace === 'function')
6224
+ return text.replace(/[\n\r]+/g, ' ').replace(/\s{2,}/g, ' ').replace(/^\s+|\s+$/, '');
6225
+ return text;
6226
+ };
6227
+ timeShort = (cfg) => {
6228
+ var v = cfg.$;
6229
+ if (v === null)
6230
+ return null;
6231
+ var duration = moment$1.duration(v);
6232
+ var datetime = new Date('01/01/1999 ' + duration.hours + ':' + duration.minutes + ':' + duration.seconds);
6233
+ var datePipe = new DatePipe('en-US');
6234
+ return datePipe.transform(datetime, 'hh:mm a');
6235
+ };
6236
+ timeSpanHhMmSs = (cfg) => {
6237
+ return cfg.hours.$ + ' H, ' + cfg.minutes.$ + ' M, ' + cfg.seconds.$ + '.' + cfg.milliseconds.$ + ' S';
6238
+ };
6239
+ usaAddress = (cfg) => {
6240
+ let text = "Loading...";
6241
+ let buildText = () => {
6242
+ text = '';
6243
+ if (cfg.address1.$ !== null)
6244
+ text += cfg.address1.$ + ' ';
6245
+ if (cfg.address2.$ !== null)
6246
+ text += cfg.address2.$ + ' ';
6247
+ if (cfg.city.$ !== null)
6248
+ text += cfg.city.$ + ' ';
6249
+ if (cfg.state.$ !== null) {
6250
+ var state = this.appEnvironemt.globalDataContext?.entityAccess().searchByRefCacheOnly(this.modelTypeLookup.getType('StdUSAState'), cfg.state.$);
6251
+ if (state)
6252
+ text += state.Code + ', ';
6253
+ }
6254
+ if (cfg.zip.$ !== null) {
6255
+ if (cfg.zip.$.length > 5)
6256
+ text += cfg.zip.$.substring(0, 5) + '-' + cfg.zip.$.substring(5);
6257
+ else
6258
+ text += cfg.zip.$;
6259
+ }
6260
+ return text;
6261
+ };
6262
+ if (this.appEnvironemt.globalDataContext?.entityAccess().searchByRefCacheOnly(this.modelTypeLookup.getType('StdUSAState'), cfg.state.$)) {
6263
+ return buildText();
6264
+ }
6265
+ return null;
6266
+ };
6267
+ usaDollars = (cfg) => {
6268
+ var v = cfg.$;
6269
+ if (v === null)
6270
+ return null;
6271
+ return '$' + (v)?.toFixed(2);
6272
+ };
6273
+ usaSocialSecurity = (cfg) => {
6274
+ var v = cfg.$;
6275
+ if (v === null)
6276
+ return null;
6277
+ return v.substring(0, 3) + '-' + v.substring(3, 5) + '-' + v.substring(5);
6278
+ };
6279
+ usaZip = (cfg) => {
6280
+ var v = cfg.$;
6281
+ if (v === null)
6282
+ return null;
6283
+ if (v.length > 5)
6284
+ return v.substring(0, 5) + '-' + v.substring(5);
6285
+ return v;
6286
+ };
6287
+ zipCode = (cfg) => {
6288
+ var v = cfg.$;
6289
+ if (v === null)
6290
+ return null;
6291
+ if (v.length > 5)
6292
+ return v.substring(0, 5) + '-' + v.substring(5);
6293
+ return v;
6294
+ };
6295
+ passwordEightBullets = (cfg) => {
6296
+ var v = cfg.$;
6297
+ return v;
6298
+ };
6299
+ formulaJsonParser = (formatter, data) => {
6300
+ var json = JSON.parse(data);
6301
+ if (json.DATA || (typeof json.DATA === 'number' && isFinite(json.DATA)))
6302
+ return formatter({ $: json.DATA });
6303
+ return { $: json.Error_Message };
6304
+ };
6305
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruFormatter, deps: [{ token: TruAppEnvironment }, { token: TruModelTypeLookup }], target: i0.ɵɵFactoryTarget.Injectable });
6306
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruFormatter, providedIn: 'root' });
6307
+ }
6308
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruFormatter, decorators: [{
6309
+ type: Injectable,
6310
+ args: [{
6311
+ providedIn: 'root',
6312
+ }]
6313
+ }], ctorParameters: () => [{ type: TruAppEnvironment }, { type: TruModelTypeLookup }] });
6314
+
6315
+ class TruDataGridClipboard {
6316
+ util;
6317
+ formatter;
6318
+ uiNotification;
6319
+ tableName = null;
6320
+ columnName = null;
6321
+ copiedCellData = null;
6322
+ copiedCellEntity = null;
6323
+ copiedCellParams = null;
6324
+ copiedRows = [];
6325
+ constructor(util, formatter, uiNotification) {
6326
+ this.util = util;
6327
+ this.formatter = formatter;
6328
+ this.uiNotification = uiNotification;
6329
+ }
6330
+ formatCellValue = (controlConfig, propertyConfig, value) => {
6331
+ if (value === null || typeof value === 'undefined')
6332
+ return '';
6333
+ if (propertyConfig.typeName === 'rich-text-unbounded')
6334
+ return this.util.htmlToPlainText(value);
6335
+ else if (propertyConfig.typeName === 'foreign-key' || propertyConfig.typeName === 'user-foreign-key')
6336
+ return this.formatter.excelFormula(propertyConfig.formatter(propertyConfig).hid(controlConfig.$entity));
6337
+ else
6338
+ return this.formatter.excelFormula(propertyConfig.formatter(propertyConfig));
6339
+ };
6340
+ copyCell = async (params, tableName, columnName, copiedCellData, copiedCellEntity) => {
6341
+ this.tableName = tableName;
6342
+ this.columnName = columnName;
6343
+ this.copiedCellParams = params;
6344
+ this.copiedCellData = copiedCellData;
6345
+ this.copiedCellEntity = copiedCellEntity;
6346
+ try {
6347
+ await navigator.clipboard.writeText(params.value);
6348
+ }
6349
+ catch (err) {
6350
+ console.error('Failed to copy text: ', err);
6351
+ }
6352
+ };
6353
+ pasteCell = (params, pastedCellData, pastedCell) => {
6354
+ let colDef = params.colDef;
6355
+ let columnName = colDef.field;
6356
+ let copiedCellDataTypeName = this.copiedCellData[this.copiedCellParams?.colDef?.field].property.typeName;
6357
+ let pastedCellDataTypeName = pastedCellData[params.colDef?.field].property.typeName;
6358
+ if (!colDef.editable) {
6359
+ this.uiNotification.error('Cannot paste into a non-editable column: ' + colDef.field);
6360
+ return;
6361
+ }
6362
+ if (copiedCellDataTypeName !== pastedCellDataTypeName) {
6363
+ this.uiNotification.error('Clipboard data type does not match the current cell data type: ' + copiedCellDataTypeName + ' vs ' + pastedCellDataTypeName);
6364
+ return;
6365
+ }
6366
+ else {
6367
+ pastedCell.setProperty(columnName, this.copiedCellEntity?.getProperty(columnName));
6368
+ params.api.refreshCells({ force: true });
6369
+ }
6370
+ };
6371
+ copyRow = async (tableName, copiedRows) => {
6372
+ this.tableName = tableName;
6373
+ this.copiedRows = copiedRows;
6374
+ if (copiedRows.length) {
6375
+ let multiRowString = '';
6376
+ this.copiedRows.forEach((copiedRow, index) => {
6377
+ let rowPropertyValues = [];
6378
+ let properties = copiedRow.$entity.entityType.getPropertyNames();
6379
+ properties
6380
+ .forEach((propertyName) => {
6381
+ let propertyConfig = copiedRow[propertyName]?.property;
6382
+ if (propertyConfig &&
6383
+ propertyName !== tableName + 'Ref' &&
6384
+ propertyName !== 'rowver' &&
6385
+ propertyName !== 'Merge_Data_Set' &&
6386
+ !propertyName.startsWith('o'))
6387
+ rowPropertyValues.push(this.formatCellValue(copiedRow[propertyName], copiedRow[propertyName].property, copiedRow.$entity.getProperty(propertyName)));
6388
+ });
6389
+ multiRowString += rowPropertyValues.join('\t') + '\n';
6390
+ });
6391
+ try {
6392
+ await navigator.clipboard.writeText(multiRowString);
6393
+ }
6394
+ catch (err) {
6395
+ console.error('Failed to copy text: ', err);
6396
+ }
6397
+ }
6398
+ };
6399
+ pasteRow = (gridApi, config, selectedRows) => {
6400
+ if (this.tableName !== config.tableName) {
6401
+ this.uiNotification.error('Clipboard data does not match the current table name: ' + this.tableName + ' vs ' + config.tableName);
6402
+ return;
6403
+ }
6404
+ if (selectedRows && selectedRows.length !== this.copiedRows.length) {
6405
+ this.uiNotification.error('Clipboard data does not match the number of selected rows: ' + this.copiedRows.length + ' vs ' + selectedRows.length);
6406
+ return;
6407
+ }
6408
+ if (this.copiedRows.length) {
6409
+ this.copiedRows.forEach((copiedRow, index) => {
6410
+ let selectedRow = selectedRows[index];
6411
+ let properties = copiedRow.$entity.entityType.getPropertyNames();
6412
+ properties
6413
+ .forEach((propertyName) => {
6414
+ if (typeof selectedRow.$entity.setProperty !== 'undefined' &&
6415
+ selectedRow[propertyName] && selectedRow[propertyName].property.canEdit &&
6416
+ propertyName !== config.tableName + 'Ref' &&
6417
+ propertyName !== 'rowver' &&
6418
+ propertyName !== 'Merge_Data_Set' &&
6419
+ !propertyName.startsWith('o'))
6420
+ selectedRow.$entity.setProperty(propertyName, copiedRow.$entity.getProperty(propertyName));
6421
+ });
6422
+ });
6423
+ gridApi.refreshCells({ force: true });
6424
+ }
6425
+ };
6426
+ insertRowsAtTop = (dataContext, config, addEntity) => {
6427
+ if (this.tableName !== config.tableName) {
6428
+ this.uiNotification.error('Clipboard data does not match the current table name: ' + this.tableName + ' vs ' + config.tableName);
6429
+ return;
6430
+ }
6431
+ if (this.copiedRows.length) {
6432
+ this.copiedRows.forEach((row) => {
6433
+ let newEntity = dataContext.entityAccess().add(config.resultConfig.entityType);
6434
+ let properties = row.entityType.getPropertyNames();
6435
+ properties
6436
+ .filter((propertyName) => {
6437
+ return propertyName !== 'Ref' &&
6438
+ propertyName !== config.resultConfig.entityType.name + 'Ref' &&
6439
+ !this.util.isLowerCase(propertyName.charAt(0));
6440
+ })
6441
+ .forEach((propertyName) => {
6442
+ if (typeof newEntity.setProperty !== 'undefined')
6443
+ newEntity.setProperty(propertyName, row.getProperty(propertyName));
6444
+ });
6445
+ addEntity(newEntity, false);
6446
+ });
6447
+ }
6448
+ };
6449
+ getCopiedRows = () => {
6450
+ return this.copiedRows;
6451
+ };
6452
+ getCopiedCell = () => {
6453
+ return this.copiedCellEntity;
6454
+ };
6455
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruDataGridClipboard, deps: [{ token: TruUtil }, { token: TruFormatter }, { token: TruUiNotification }], target: i0.ɵɵFactoryTarget.Injectable });
6456
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruDataGridClipboard, providedIn: 'root' });
6457
+ }
6458
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruDataGridClipboard, decorators: [{
6459
+ type: Injectable,
6460
+ args: [{
6461
+ providedIn: 'root',
6462
+ }]
6463
+ }], ctorParameters: () => [{ type: TruUtil }, { type: TruFormatter }, { type: TruUiNotification }] });
6464
+
6465
+ class TruDataGridPkeyCellRenderer {
6466
+ dataContext;
6467
+ dataGridClipboard;
6468
+ contextMenu;
6469
+ // private eGui: is an empty element to satisfy the getGui method.
6470
+ eGui;
6471
+ windowClickSubscription;
6472
+ params;
6473
+ contextMenuPosition = { x: '0px', y: '0px' };
6474
+ displayValue = '';
6475
+ copyIsDisabled = true;
6476
+ pasteIsDisabled = true;
6477
+ insertAtTopIsDisabled = true;
6478
+ constructor(dataContext, dataGridClipboard) {
6479
+ this.dataContext = dataContext;
6480
+ this.dataGridClipboard = dataGridClipboard;
6481
+ }
6482
+ onRightClick = (event) => {
6483
+ event.preventDefault();
6484
+ this.copyIsDisabled = this.params.api.getSelectedRows().length ? false : true;
6485
+ this.pasteIsDisabled = this.dataGridClipboard.getCopiedRows().length && this.params.api.getSelectedRows().length ? false : true;
6486
+ this.insertAtTopIsDisabled = this.dataGridClipboard.getCopiedRows().length && this.params.api.getSelectedRows().length ? false : true;
6487
+ this.contextMenuPosition.x = event.pageX + 'px';
6488
+ this.contextMenuPosition.y = (event.pageY) + 'px';
6489
+ this.contextMenu.menu?.focusFirstItem('mouse');
6490
+ this.contextMenu.openMenu();
6491
+ };
6492
+ onMouseDown = (event) => {
6493
+ };
6494
+ onMouseUp = (event) => {
6495
+ };
6496
+ onCopy = (event) => {
6497
+ let selectedRows = this.params.api.getSelectedRows();
6498
+ if (selectedRows.length) {
6499
+ let copiedRowData = selectedRows;
6500
+ this.dataGridClipboard.copyRow(this.params.context.grid.config.tableName, copiedRowData);
6501
+ }
6502
+ };
6503
+ onPaste = (event) => {
6504
+ this.dataGridClipboard.pasteRow(this.params.api, this.params.context.grid.config, this.params.api.getSelectedRows());
6505
+ };
6506
+ onInsertAtTop = (event) => {
6507
+ this.dataGridClipboard.insertRowsAtTop(this.dataContext, this.params.context.grid.config, this.params.context.grid.addEntity);
6508
+ };
6509
+ agInit(params) {
6510
+ this.params = params;
6511
+ if (params.value < 0)
6151
6512
  this.displayValue = 'NEW';
6152
6513
  else
6153
6514
  this.displayValue = params.value;
@@ -10111,1441 +10472,1083 @@ class TruServerError {
10111
10472
  else {
10112
10473
  this.id = parsedError.$id;
10113
10474
  this.type = parsedError.$type;
10114
- this.code = parsedError.Code;
10115
- this.message = parsedError.Message;
10116
- this.stackTrace = parsedError.StackTrace;
10117
- this.status = error.status;
10118
- this.statusText = error.statusText;
10119
- }
10120
- }
10121
- }
10122
-
10123
- class TruErrorManager {
10124
- http;
10125
- dialog;
10126
- textManager;
10127
- uiNotification;
10128
- componentLookup;
10129
- componentFactoryResolver;
10130
- appRef;
10131
- injector;
10132
- appEnvironment;
10133
- baseUrl;
10134
- appName;
10135
- constructor(http, dialog, textManager, uiNotification, componentLookup, componentFactoryResolver, appRef, injector, appEnvironment) {
10136
- this.http = http;
10137
- this.dialog = dialog;
10138
- this.textManager = textManager;
10139
- this.uiNotification = uiNotification;
10140
- this.componentLookup = componentLookup;
10141
- this.componentFactoryResolver = componentFactoryResolver;
10142
- this.appRef = appRef;
10143
- this.injector = injector;
10144
- this.appEnvironment = appEnvironment;
10145
- this.baseUrl = appEnvironment.appUri;
10146
- this.appName = appEnvironment.appName;
10147
- }
10148
- handleClientSideError = (error) => {
10149
- };
10150
- handleServerSideError = (error) => {
10151
- let serverError = new TruServerError(error);
10152
- if (serverError.type === 'tru-db-custom-exception') {
10153
- var component = this.componentLookup.get(serverError.componentName);
10154
- this.dialog.open(component, {
10155
- disableClose: true,
10156
- minWidth: "400px",
10157
- maxWidth: "600px",
10158
- data: serverError
10159
- });
10160
- }
10161
- else if (serverError.type.indexOf('TruDbRequireValidChoiceException') !== -1) {
10162
- let dialogConfig = new TruErrorDialogConfig('Require Valid Choice Exception', error.message, serverError.stackTrace);
10163
- this.dialog.open(TruErrorDialog, {
10164
- disableClose: true,
10165
- minWidth: "400px",
10166
- maxWidth: "600px",
10167
- data: dialogConfig
10168
- });
10169
- }
10170
- else if (serverError.type.indexOf('DuplicateKeyError') !== -1) {
10171
- let dialogConfig = new TruErrorDialogConfig('Duplicate Key Error', error.message
10172
- .replace('Cannot insert duplicate key row in object', 'Cannot insert duplicate value in table')
10173
- .replace('dbo.', '')
10174
- .replace('UIX_', '')
10175
- .replace('The statement has been terminated.', ''), serverError.stackTrace);
10176
- this.dialog.open(TruErrorDialog, {
10177
- disableClose: true,
10178
- minWidth: "400px",
10179
- maxWidth: "600px",
10180
- data: dialogConfig
10181
- });
10182
- }
10183
- else if (serverError.type.indexOf('OptimisticLockViolation') !== -1) {
10184
- let dialogConfig = new TruErrorDialogConfig('Concurrent saves not allowed', 'Please review any changes and save again.', serverError.stackTrace);
10185
- this.dialog.open(TruErrorDialog, {
10186
- disableClose: true,
10187
- minWidth: "400px",
10188
- maxWidth: "600px",
10189
- data: dialogConfig
10190
- });
10191
- }
10192
- else if (serverError.type.lastIndexOf('TruDB.EfMssql.Runtime.DataError', 0) === 0) {
10193
- this.uiNotification.error(this.textManager.fmtDataError(serverError.type), [this.textManager.fmtExceptionToShow(serverError.stackTrace)]);
10194
- }
10195
- else {
10196
- var message = this.textManager.fmtErrorToShow(serverError);
10197
- let dialogConfig = new TruErrorDialogConfig(serverError.type, serverError.message, serverError.stackTrace);
10198
- this.dialog.open(TruErrorDialog, {
10199
- disableClose: true,
10200
- minWidth: "400px",
10201
- maxWidth: "600px",
10202
- data: dialogConfig
10203
- });
10204
- }
10205
- };
10206
- handleError = (error) => {
10207
- if (error.type)
10208
- this.handleClientSideError(error);
10209
- else
10210
- this.handleServerSideError(error);
10211
- };
10212
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorManager, deps: [{ token: i2.HttpClient }, { token: i1.MatDialog }, { token: TruTextManager }, { token: TruUiNotification }, { token: TruComponentLookup }, { token: i0.ComponentFactoryResolver }, { token: i0.ApplicationRef }, { token: i0.Injector }, { token: TruAppEnvironment }], target: i0.ɵɵFactoryTarget.Injectable });
10213
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorManager, providedIn: 'root' });
10214
- }
10215
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorManager, decorators: [{
10216
- type: Injectable,
10217
- args: [{
10218
- providedIn: 'root',
10219
- }]
10220
- }], ctorParameters: () => [{ type: i2.HttpClient }, { type: i1.MatDialog }, { type: TruTextManager }, { type: TruUiNotification }, { type: TruComponentLookup }, { type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }, { type: TruAppEnvironment }] });
10221
-
10222
- class TruErrorInterceptor {
10223
- errorManager;
10224
- constructor(errorManager) {
10225
- this.errorManager = errorManager;
10226
- }
10227
- intercept(request, next) {
10228
- return next.handle(request).pipe(catchError((error) => {
10229
- if (error.status !== 401 && !(error.error instanceof Blob))
10230
- this.errorManager.handleError(error);
10231
- return next.handle(request);
10232
- }));
10233
- }
10234
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorInterceptor, deps: [{ token: TruErrorManager }], target: i0.ɵɵFactoryTarget.Injectable });
10235
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorInterceptor });
10236
- }
10237
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorInterceptor, decorators: [{
10238
- type: Injectable
10239
- }], ctorParameters: () => [{ type: TruErrorManager }] });
10240
-
10241
- class TruColumn {
10242
- constructor() { }
10243
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruColumn, deps: [], target: i0.ɵɵFactoryTarget.Component });
10244
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruColumn, isStandalone: true, selector: "tru-column", ngImport: i0, template: "<li>\r\n <div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-vList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n</li>\r\n", styles: ["button{margin-right:5px}.button-container{margin-bottom:10px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
10245
- }
10246
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruColumn, decorators: [{
10247
- type: Component,
10248
- args: [{ selector: 'tru-column', imports: [CommonModule, FormsModule], template: "<li>\r\n <div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-vList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n</li>\r\n", styles: ["button{margin-right:5px}.button-container{margin-bottom:10px}\n"] }]
10249
- }], ctorParameters: () => [] });
10250
-
10251
- class TruForm {
10252
- element;
10253
- constructor(element) {
10254
- this.element = element;
10255
- }
10256
- ngAfterViewInit() {
10257
- this.updateLayout();
10258
- }
10259
- updateLayout = () => {
10260
- let rowComponentElements = this.element.nativeElement.querySelectorAll('.tvl-container-hList');
10261
- rowComponentElements.forEach((rowComponentElement) => {
10262
- var numberOfItems = rowComponentElement.children.length;
10263
- var childWidth = 100 / numberOfItems;
10264
- [...rowComponentElement.children].forEach((rowChildElement, index) => {
10265
- if (index === numberOfItems - 1) {
10266
- rowChildElement.style['width'] = 'calc(' + childWidth + '% - 10px)';
10267
- }
10268
- else {
10269
- rowChildElement.style['width'] = 'calc(' + childWidth + '% - 5px)';
10270
- }
10271
- if (index > 0)
10272
- rowChildElement.style['margin-left'] = '5px';
10273
- });
10274
- });
10275
- };
10276
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruForm, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
10277
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruForm, isStandalone: true, selector: "tru-form", ngImport: i0, template: "<div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-hList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["button{margin-right:5px}.button-container{margin-bottom:10px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
10278
- }
10279
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruForm, decorators: [{
10280
- type: Component,
10281
- args: [{ selector: 'tru-form', imports: [CommonModule, FormsModule], template: "<div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-hList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["button{margin-right:5px}.button-container{margin-bottom:10px}\n"] }]
10282
- }], ctorParameters: () => [{ type: i0.ElementRef }] });
10283
-
10284
- class TruGroupBox {
10285
- constructor() { }
10286
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruGroupBox, deps: [], target: i0.ɵɵFactoryTarget.Component });
10287
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruGroupBox, isStandalone: true, selector: "tru-group-box", ngImport: i0, template: "<div>\r\n <ng-content></ng-content>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
10288
- }
10289
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruGroupBox, decorators: [{
10290
- type: Component,
10291
- args: [{ selector: 'tru-group-box', imports: [CommonModule, FormsModule], template: "<div>\r\n <ng-content></ng-content>\r\n</div>\r\n" }]
10292
- }], ctorParameters: () => [] });
10293
-
10294
- class TruRow {
10295
- constructor() { }
10296
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruRow, deps: [], target: i0.ɵɵFactoryTarget.Component });
10297
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruRow, isStandalone: true, selector: "tru-row", ngImport: i0, template: "<li>\r\n <div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-hList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n</li>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
10298
- }
10299
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruRow, decorators: [{
10300
- type: Component,
10301
- args: [{ selector: 'tru-row', imports: [CommonModule, FormsModule], template: "<li>\r\n <div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-hList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n</li>\r\n" }]
10302
- }], ctorParameters: () => [] });
10303
-
10304
- class TruTab {
10305
- tabGroupEventNotifier;
10306
- view;
10307
- label;
10308
- matTab;
10309
- constructor(tabGroupEventNotifier) {
10310
- this.tabGroupEventNotifier = tabGroupEventNotifier;
10311
- }
10312
- notifyListeners = (isActive) => {
10313
- this.tabGroupEventNotifier.isActive = isActive;
10314
- };
10315
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTab, deps: [{ token: TruTabGroupEventNotifier }], target: i0.ɵɵFactoryTarget.Component });
10316
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruTab, isStandalone: true, selector: "tru-tab", inputs: { view: "view", label: "label" }, providers: [TruTabGroupEventNotifier], viewQueries: [{ propertyName: "matTab", first: true, predicate: MatTab, descendants: true }], ngImport: i0, template: "<mat-tab [label]=\"label\" [disabled]=\"!view.window.isActive()\">\r\n <ng-content></ng-content>\r\n</mat-tab>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2$3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }], encapsulation: i0.ViewEncapsulation.None });
10317
- }
10318
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTab, decorators: [{
10319
- type: Component,
10320
- args: [{ selector: 'tru-tab', imports: [CommonModule, FormsModule, MatTabsModule], encapsulation: ViewEncapsulation.None, providers: [TruTabGroupEventNotifier], template: "<mat-tab [label]=\"label\" [disabled]=\"!view.window.isActive()\">\r\n <ng-content></ng-content>\r\n</mat-tab>\r\n" }]
10321
- }], ctorParameters: () => [{ type: TruTabGroupEventNotifier }], propDecorators: { view: [{
10322
- type: Input
10323
- }], label: [{
10324
- type: Input
10325
- }], matTab: [{
10326
- type: ViewChild,
10327
- args: [MatTab]
10328
- }] } });
10329
-
10330
- class TruTabGroup {
10331
- tabGroup;
10332
- tabs;
10333
- constructor() { }
10334
- ngAfterViewInit() {
10335
- const matTabsFromQueryList = this.tabs.map((tab) => tab.matTab);
10336
- const list = new QueryList();
10337
- list.reset([matTabsFromQueryList]);
10338
- this.tabGroup._tabs = list;
10339
- }
10340
- onChange(event) {
10341
- const selectedTabLabel = event.tab.textLabel;
10342
- this.tabs.forEach((tab) => {
10343
- if (selectedTabLabel === tab.label) {
10344
- tab.notifyListeners(true);
10345
- }
10346
- else {
10347
- tab.notifyListeners(false);
10348
- }
10349
- });
10350
- }
10351
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTabGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
10352
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruTabGroup, isStandalone: true, selector: "tru-tab-group", queries: [{ propertyName: "tabs", predicate: TruTab }], viewQueries: [{ propertyName: "tabGroup", first: true, predicate: MatTabGroup, descendants: true }], ngImport: i0, template: "<mat-tab-group #tabGroup\r\n (selectedTabChange)=\"onChange($event)\"\r\n animationDuration=\"0ms\">\r\n <ng-content #outlet></ng-content>\r\n</mat-tab-group>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2$3.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }], encapsulation: i0.ViewEncapsulation.None });
10353
- }
10354
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTabGroup, decorators: [{
10355
- type: Component,
10356
- args: [{ selector: 'tru-tab-group', imports: [CommonModule, FormsModule, MatTabsModule], encapsulation: ViewEncapsulation.None, template: "<mat-tab-group #tabGroup\r\n (selectedTabChange)=\"onChange($event)\"\r\n animationDuration=\"0ms\">\r\n <ng-content #outlet></ng-content>\r\n</mat-tab-group>\r\n" }]
10357
- }], ctorParameters: () => [], propDecorators: { tabGroup: [{
10358
- type: ViewChild,
10359
- args: [MatTabGroup]
10360
- }], tabs: [{
10361
- type: ContentChildren,
10362
- args: [TruTab]
10363
- }] } });
10475
+ this.code = parsedError.Code;
10476
+ this.message = parsedError.Message;
10477
+ this.stackTrace = parsedError.StackTrace;
10478
+ this.status = error.status;
10479
+ this.statusText = error.statusText;
10480
+ }
10481
+ }
10482
+ }
10364
10483
 
10365
- class TruLogin {
10366
- auth;
10484
+ class TruErrorManager {
10485
+ http;
10486
+ dialog;
10487
+ textManager;
10488
+ uiNotification;
10489
+ componentLookup;
10490
+ componentFactoryResolver;
10491
+ appRef;
10492
+ injector;
10367
10493
  appEnvironment;
10368
- loginForm = new FormGroup({
10369
- username: new FormControl('', Validators.required),
10370
- password: new FormControl('', Validators.required)
10371
- });
10372
- loginError = "";
10373
- isLoggingIn = false;
10374
- title;
10375
- constructor(auth, appEnvironment) {
10376
- this.auth = auth;
10494
+ baseUrl;
10495
+ appName;
10496
+ constructor(http, dialog, textManager, uiNotification, componentLookup, componentFactoryResolver, appRef, injector, appEnvironment) {
10497
+ this.http = http;
10498
+ this.dialog = dialog;
10499
+ this.textManager = textManager;
10500
+ this.uiNotification = uiNotification;
10501
+ this.componentLookup = componentLookup;
10502
+ this.componentFactoryResolver = componentFactoryResolver;
10503
+ this.appRef = appRef;
10504
+ this.injector = injector;
10377
10505
  this.appEnvironment = appEnvironment;
10378
- this.title = appEnvironment.loginFormTitle;
10379
- }
10380
- get f() {
10381
- return this.loginForm.controls;
10506
+ this.baseUrl = appEnvironment.appUri;
10507
+ this.appName = appEnvironment.appName;
10382
10508
  }
10383
- isDisabled = () => {
10384
- return !this.f.username.value || !this.f.password.value || this.isLoggingIn;
10509
+ handleClientSideError = (error) => {
10385
10510
  };
10386
- onSubmit() {
10387
- const loginRequest = {
10388
- username: this.f.username.value,
10389
- password: this.f.password.value
10390
- };
10391
- if (loginRequest.username && loginRequest.password) {
10392
- this.isLoggingIn = true;
10393
- this.auth
10394
- .login(loginRequest).pipe(finalize(() => {
10395
- this.isLoggingIn = false;
10396
- }))
10397
- .subscribe(() => {
10398
- this.isLoggingIn = false;
10399
- }, (error) => {
10400
- if (error.status === 401) {
10401
- this.loginError = "Incorrect username and/or password";
10402
- }
10403
- else {
10404
- this.loginError = "Invalid Login - Error: " + error.status;
10405
- }
10511
+ handleServerSideError = (error) => {
10512
+ let serverError = new TruServerError(error);
10513
+ if (serverError.type === 'tru-db-custom-exception') {
10514
+ var component = this.componentLookup.get(serverError.componentName);
10515
+ this.dialog.open(component, {
10516
+ disableClose: true,
10517
+ minWidth: "400px",
10518
+ maxWidth: "600px",
10519
+ data: serverError
10406
10520
  });
10407
10521
  }
10408
- }
10409
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLogin, deps: [{ token: TruAuth }, { token: TruAppEnvironment }], target: i0.ɵɵFactoryTarget.Component });
10410
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruLogin, isStandalone: false, selector: "tru-login", ngImport: i0, template: "<div class=\"login-wrapper\">\r\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"onSubmit()\">\r\n <mat-card class=\"animate-login\">\r\n <mat-card-header>\r\n <mat-card-title> {{title}} </mat-card-title>\r\n </mat-card-header>\r\n <mat-card-content>\r\n <mat-form-field>\r\n <mat-label>Username</mat-label>\r\n <input matInput formControlName=\"username\" placeholder=\"Username\">\r\n </mat-form-field>\r\n <mat-form-field>\r\n <mat-label>Password</mat-label>\r\n <input matInput type=\"password\" formControlName=\"password\" placeholder=\"Password\">\r\n </mat-form-field>\r\n <div *ngIf=\"loginError\" class=\"animate-login-error animated rubberBand\">\r\n <p style=\"color: red; font-weight: bold;\"> {{ loginError }}</p>\r\n </div>\r\n </mat-card-content>\r\n <mat-card-actions>\r\n <button mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"isDisabled()\">Login</button>\r\n </mat-card-actions>\r\n </mat-card>\r\n </form>\r\n</div>\r\n", styles: [".login-container{display:flex;justify-content:center;align-items:center;height:100vh;margin:0;padding:0}.login-input{margin-bottom:20px}.animate-login{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;margin-top:50px}.wrapper{display:flex;justify-content:center;align-items:center;height:100vh}mat-card{max-width:300px;width:100%;max-height:300px;padding:20px}.form-group{width:100%;max-width:400px;margin-bottom:20px}.login-wrapper{display:flex;justify-content:center;align-items:center;height:100vh}::ng-deep .login-wrapper .mat-mdc-text-field-wrapper{padding:0 16px!important}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i5$3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i5$3.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i5$3.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i5$3.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i5$3.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i7.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
10411
- }
10412
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLogin, decorators: [{
10413
- type: Component,
10414
- args: [{ selector: 'tru-login', standalone: false, template: "<div class=\"login-wrapper\">\r\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"onSubmit()\">\r\n <mat-card class=\"animate-login\">\r\n <mat-card-header>\r\n <mat-card-title> {{title}} </mat-card-title>\r\n </mat-card-header>\r\n <mat-card-content>\r\n <mat-form-field>\r\n <mat-label>Username</mat-label>\r\n <input matInput formControlName=\"username\" placeholder=\"Username\">\r\n </mat-form-field>\r\n <mat-form-field>\r\n <mat-label>Password</mat-label>\r\n <input matInput type=\"password\" formControlName=\"password\" placeholder=\"Password\">\r\n </mat-form-field>\r\n <div *ngIf=\"loginError\" class=\"animate-login-error animated rubberBand\">\r\n <p style=\"color: red; font-weight: bold;\"> {{ loginError }}</p>\r\n </div>\r\n </mat-card-content>\r\n <mat-card-actions>\r\n <button mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"isDisabled()\">Login</button>\r\n </mat-card-actions>\r\n </mat-card>\r\n </form>\r\n</div>\r\n", styles: [".login-container{display:flex;justify-content:center;align-items:center;height:100vh;margin:0;padding:0}.login-input{margin-bottom:20px}.animate-login{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;margin-top:50px}.wrapper{display:flex;justify-content:center;align-items:center;height:100vh}mat-card{max-width:300px;width:100%;max-height:300px;padding:20px}.form-group{width:100%;max-width:400px;margin-bottom:20px}.login-wrapper{display:flex;justify-content:center;align-items:center;height:100vh}::ng-deep .login-wrapper .mat-mdc-text-field-wrapper{padding:0 16px!important}\n"] }]
10415
- }], ctorParameters: () => [{ type: TruAuth }, { type: TruAppEnvironment }] });
10416
-
10417
- class TruAuthJwtStrategy {
10418
- JWT_ACCESS_TOKEN = "ACCESS_TOKEN";
10419
- JWT_REFRESH_TOKEN = "REFRESH_TOKEN";
10420
- doLoginUser(token) {
10421
- localStorage.setItem(this.JWT_ACCESS_TOKEN, JSON.stringify(token.accessToken));
10422
- localStorage.setItem(this.JWT_REFRESH_TOKEN, JSON.stringify(token.refreshToken));
10423
- }
10424
- doLogoutUser() {
10425
- localStorage.removeItem(this.JWT_ACCESS_TOKEN);
10426
- }
10427
- isLoggedIn() {
10428
- return !!this.getJwtToken();
10429
- }
10430
- createUser(user) {
10431
- let jwtData = this.getDecodedJwtJsonData();
10432
- console.log(jwtData);
10433
- let userData = {
10434
- activeUserRef: jwtData.UserRef,
10435
- firstName: jwtData.FirstName,
10436
- lastName: jwtData.LastName,
10437
- email: jwtData.Email,
10438
- username: jwtData['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name'],
10439
- roles: jwtData['http://schemas.microsoft.com/ws/2008/06/identity/claims/role']
10440
- };
10441
- return of(user.create(userData));
10442
- }
10443
- getJwtToken() {
10444
- try {
10445
- return JSON.parse(localStorage.getItem(this.JWT_ACCESS_TOKEN));
10522
+ else if (serverError.type.indexOf('TruDbRequireValidChoiceException') !== -1) {
10523
+ let dialogConfig = new TruErrorDialogConfig('Require Valid Choice Exception', error.message, serverError.stackTrace);
10524
+ this.dialog.open(TruErrorDialog, {
10525
+ disableClose: true,
10526
+ minWidth: "400px",
10527
+ maxWidth: "600px",
10528
+ data: dialogConfig
10529
+ });
10446
10530
  }
10447
- catch (e) {
10448
- return null;
10531
+ else if (serverError.type.indexOf('DuplicateKeyError') !== -1) {
10532
+ let dialogConfig = new TruErrorDialogConfig('Duplicate Key Error', error.message
10533
+ .replace('Cannot insert duplicate key row in object', 'Cannot insert duplicate value in table')
10534
+ .replace('dbo.', '')
10535
+ .replace('UIX_', '')
10536
+ .replace('The statement has been terminated.', ''), serverError.stackTrace);
10537
+ this.dialog.open(TruErrorDialog, {
10538
+ disableClose: true,
10539
+ minWidth: "400px",
10540
+ maxWidth: "600px",
10541
+ data: dialogConfig
10542
+ });
10449
10543
  }
10450
- }
10451
- getDecodedJwtJsonData() {
10452
- let token = this.getJwtToken();
10453
- let payload = {};
10454
- if (token && token !== "undefined") {
10455
- const encodedPayload = token.split(".")[1];
10456
- const payloadStr = window.atob(encodedPayload);
10457
- payload = JSON.parse(payloadStr);
10544
+ else if (serverError.type.indexOf('OptimisticLockViolation') !== -1) {
10545
+ let dialogConfig = new TruErrorDialogConfig('Concurrent saves not allowed', 'Please review any changes and save again.', serverError.stackTrace);
10546
+ this.dialog.open(TruErrorDialog, {
10547
+ disableClose: true,
10548
+ minWidth: "400px",
10549
+ maxWidth: "600px",
10550
+ data: dialogConfig
10551
+ });
10458
10552
  }
10459
- return payload;
10460
- }
10461
- getToken() {
10462
- var token = this.getJwtToken();
10463
- if (token && token !== "undefined") {
10464
- const encodedPayload = token.split(".")[1];
10465
- const payloadStr = window.atob(encodedPayload);
10466
- var payload = JSON.parse(payloadStr);
10467
- var exp = payload["exp"];
10468
- var d = new Date();
10469
- var epoch = Math.round(d.getTime() / 1000);
10470
- if (exp < epoch) {
10471
- localStorage.removeItem(this.JWT_ACCESS_TOKEN);
10472
- return null;
10473
- }
10553
+ else if (serverError.type.lastIndexOf('TruDB.EfMssql.Runtime.DataError', 0) === 0) {
10554
+ this.uiNotification.error(this.textManager.fmtDataError(serverError.type), [this.textManager.fmtExceptionToShow(serverError.stackTrace)]);
10474
10555
  }
10475
- return token;
10476
- }
10556
+ else {
10557
+ var message = this.textManager.fmtErrorToShow(serverError);
10558
+ let dialogConfig = new TruErrorDialogConfig(serverError.type, serverError.message, serverError.stackTrace);
10559
+ this.dialog.open(TruErrorDialog, {
10560
+ disableClose: true,
10561
+ minWidth: "400px",
10562
+ maxWidth: "600px",
10563
+ data: dialogConfig
10564
+ });
10565
+ }
10566
+ };
10567
+ handleError = (error) => {
10568
+ if (error.type)
10569
+ this.handleClientSideError(error);
10570
+ else
10571
+ this.handleServerSideError(error);
10572
+ };
10573
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorManager, deps: [{ token: i2.HttpClient }, { token: i1.MatDialog }, { token: TruTextManager }, { token: TruUiNotification }, { token: TruComponentLookup }, { token: i0.ComponentFactoryResolver }, { token: i0.ApplicationRef }, { token: i0.Injector }, { token: TruAppEnvironment }], target: i0.ɵɵFactoryTarget.Injectable });
10574
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorManager, providedIn: 'root' });
10477
10575
  }
10576
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorManager, decorators: [{
10577
+ type: Injectable,
10578
+ args: [{
10579
+ providedIn: 'root',
10580
+ }]
10581
+ }], ctorParameters: () => [{ type: i2.HttpClient }, { type: i1.MatDialog }, { type: TruTextManager }, { type: TruUiNotification }, { type: TruComponentLookup }, { type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }, { type: TruAppEnvironment }] });
10478
10582
 
10479
- class TruAuthInterceptor {
10480
- auth;
10481
- appEnvironment;
10482
- jwt;
10483
- constructor(auth, appEnvironment, jwt) {
10484
- this.auth = auth;
10485
- this.appEnvironment = appEnvironment;
10486
- this.jwt = jwt;
10583
+ class TruErrorInterceptor {
10584
+ errorManager;
10585
+ constructor(errorManager) {
10586
+ this.errorManager = errorManager;
10487
10587
  }
10488
10588
  intercept(request, next) {
10489
- if (this.appEnvironment.authType === 'jwt')
10490
- request = this.addToken(request, String(this.jwt.getToken()));
10491
- if (this.appEnvironment.authType === 'session')
10492
- request = request.clone({
10493
- withCredentials: true
10494
- });
10495
10589
  return next.handle(request).pipe(catchError((error) => {
10496
- if (error.status === 401) {
10497
- this.auth.doLogoutAndRedirectToLogin();
10498
- }
10499
- return throwError(error);
10500
- }));
10501
- }
10502
- addToken(request, token) {
10503
- return request.clone({
10504
- setHeaders: { Authorization: `Bearer ${token}` },
10505
- });
10506
- }
10507
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruAuthInterceptor, deps: [{ token: TruAuth }, { token: TruAppEnvironment }, { token: TRU_AUTH_STRATEGY }], target: i0.ɵɵFactoryTarget.Injectable });
10508
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruAuthInterceptor });
10509
- }
10510
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruAuthInterceptor, decorators: [{
10511
- type: Injectable
10512
- }], ctorParameters: () => [{ type: TruAuth }, { type: TruAppEnvironment }, { type: TruAuthJwtStrategy, decorators: [{
10513
- type: Inject,
10514
- args: [TRU_AUTH_STRATEGY]
10515
- }] }] });
10516
-
10517
- class TruAuthSessionStrategy {
10518
- http;
10519
- loggedUser;
10520
- constructor(http) {
10521
- this.http = http;
10522
- }
10523
- doLoginUser(user) {
10524
- this.loggedUser = user;
10525
- }
10526
- doLogoutUser() {
10527
- this.loggedUser = undefined;
10528
- }
10529
- createUser(user) {
10530
- return of({});
10531
- }
10532
- isLoggedIn() {
10533
- return false; //todo, implement this
10590
+ if (error.status !== 401 && !(error.error instanceof Blob))
10591
+ this.errorManager.handleError(error);
10592
+ return next.handle(request);
10593
+ }));
10534
10594
  }
10595
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorInterceptor, deps: [{ token: TruErrorManager }], target: i0.ɵɵFactoryTarget.Injectable });
10596
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorInterceptor });
10535
10597
  }
10598
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorInterceptor, decorators: [{
10599
+ type: Injectable
10600
+ }], ctorParameters: () => [{ type: TruErrorManager }] });
10536
10601
 
10537
- const TruAuthStrategyProvider = {
10538
- provide: TRU_AUTH_STRATEGY,
10539
- deps: [HttpClient, TruAppEnvironment],
10540
- useFactory: (http, appEnvironment) => {
10541
- switch (appEnvironment.authType) {
10542
- case "session":
10543
- return new TruAuthSessionStrategy(http);
10544
- case "jwt":
10545
- return new TruAuthJwtStrategy();
10546
- default:
10547
- throw new Error("Invalid auth strategy");
10548
- }
10549
- },
10550
- };
10602
+ class TruColumn {
10603
+ constructor() { }
10604
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruColumn, deps: [], target: i0.ɵɵFactoryTarget.Component });
10605
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruColumn, isStandalone: true, selector: "tru-column", ngImport: i0, template: "<li>\r\n <div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-vList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n</li>\r\n", styles: ["button{margin-right:5px}.button-container{margin-bottom:10px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
10606
+ }
10607
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruColumn, decorators: [{
10608
+ type: Component,
10609
+ args: [{ selector: 'tru-column', imports: [CommonModule, FormsModule], template: "<li>\r\n <div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-vList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n</li>\r\n", styles: ["button{margin-right:5px}.button-container{margin-bottom:10px}\n"] }]
10610
+ }], ctorParameters: () => [] });
10551
10611
 
10552
- const routes = [
10553
- {
10554
- path: 'login',
10555
- component: TruLogin
10612
+ class TruForm {
10613
+ element;
10614
+ constructor(element) {
10615
+ this.element = element;
10556
10616
  }
10557
- ];
10558
- class TruLoginModule {
10559
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
10560
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, declarations: [TruLogin], imports: [CommonModule, MaterialModule, FormsModule, ReactiveFormsModule, i1$4.RouterModule], exports: [TruLogin] });
10561
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, providers: [
10562
- {
10563
- provide: HTTP_INTERCEPTORS,
10564
- useClass: TruAuthInterceptor,
10565
- multi: true,
10566
- },
10567
- {
10568
- provide: HTTP_INTERCEPTORS,
10569
- useClass: TruErrorInterceptor,
10570
- multi: true,
10571
- },
10572
- TruAuthStrategyProvider
10573
- ], imports: [CommonModule, MaterialModule, FormsModule, ReactiveFormsModule, RouterModule.forChild(routes)] });
10617
+ ngAfterViewInit() {
10618
+ this.updateLayout();
10619
+ }
10620
+ updateLayout = () => {
10621
+ let rowComponentElements = this.element.nativeElement.querySelectorAll('.tvl-container-hList');
10622
+ rowComponentElements.forEach((rowComponentElement) => {
10623
+ var numberOfItems = rowComponentElement.children.length;
10624
+ var childWidth = 100 / numberOfItems;
10625
+ [...rowComponentElement.children].forEach((rowChildElement, index) => {
10626
+ if (index === numberOfItems - 1) {
10627
+ rowChildElement.style['width'] = 'calc(' + childWidth + '% - 10px)';
10628
+ }
10629
+ else {
10630
+ rowChildElement.style['width'] = 'calc(' + childWidth + '% - 5px)';
10631
+ }
10632
+ if (index > 0)
10633
+ rowChildElement.style['margin-left'] = '5px';
10634
+ });
10635
+ });
10636
+ };
10637
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruForm, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
10638
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruForm, isStandalone: true, selector: "tru-form", ngImport: i0, template: "<div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-hList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["button{margin-right:5px}.button-container{margin-bottom:10px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
10574
10639
  }
10575
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, decorators: [{
10576
- type: NgModule,
10577
- args: [{
10578
- declarations: [TruLogin],
10579
- imports: [CommonModule, MaterialModule, FormsModule, ReactiveFormsModule, RouterModule.forChild(routes)],
10580
- exports: [TruLogin],
10581
- providers: [
10582
- {
10583
- provide: HTTP_INTERCEPTORS,
10584
- useClass: TruAuthInterceptor,
10585
- multi: true,
10586
- },
10587
- {
10588
- provide: HTTP_INTERCEPTORS,
10589
- useClass: TruErrorInterceptor,
10590
- multi: true,
10591
- },
10592
- TruAuthStrategyProvider
10593
- ],
10594
- }]
10595
- }] });
10640
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruForm, decorators: [{
10641
+ type: Component,
10642
+ args: [{ selector: 'tru-form', imports: [CommonModule, FormsModule], template: "<div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-hList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: ["button{margin-right:5px}.button-container{margin-bottom:10px}\n"] }]
10643
+ }], ctorParameters: () => [{ type: i0.ElementRef }] });
10596
10644
 
10597
- var TruValidationDialogContext;
10598
- (function (TruValidationDialogContext) {
10599
- TruValidationDialogContext[TruValidationDialogContext["Control"] = 0] = "Control";
10600
- TruValidationDialogContext[TruValidationDialogContext["Grid"] = 1] = "Grid";
10601
- TruValidationDialogContext[TruValidationDialogContext["Card"] = 2] = "Card";
10602
- })(TruValidationDialogContext || (TruValidationDialogContext = {}));
10645
+ class TruGroupBox {
10646
+ constructor() { }
10647
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruGroupBox, deps: [], target: i0.ɵɵFactoryTarget.Component });
10648
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruGroupBox, isStandalone: true, selector: "tru-group-box", ngImport: i0, template: "<div>\r\n <ng-content></ng-content>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
10649
+ }
10650
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruGroupBox, decorators: [{
10651
+ type: Component,
10652
+ args: [{ selector: 'tru-group-box', imports: [CommonModule, FormsModule], template: "<div>\r\n <ng-content></ng-content>\r\n</div>\r\n" }]
10653
+ }], ctorParameters: () => [] });
10603
10654
 
10604
- class TruValidationDialog {
10605
- renderer;
10606
- elementRef;
10607
- util;
10608
- config;
10609
- close = new EventEmitter();
10610
- errorMsg = '';
10611
- rowElement;
10612
- cellElement;
10613
- listeners = [];
10614
- constructor(renderer, elementRef, util) {
10615
- this.renderer = renderer;
10616
- this.elementRef = elementRef;
10617
- this.util = util;
10655
+ class TruRow {
10656
+ constructor() { }
10657
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruRow, deps: [], target: i0.ɵɵFactoryTarget.Component });
10658
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruRow, isStandalone: true, selector: "tru-row", ngImport: i0, template: "<li>\r\n <div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-hList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n</li>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
10659
+ }
10660
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruRow, decorators: [{
10661
+ type: Component,
10662
+ args: [{ selector: 'tru-row', imports: [CommonModule, FormsModule], template: "<li>\r\n <div class=\"tvl-container-grid js-grid\">\r\n <div class=\"tvl-container-grid-col\">\r\n <div class=\"tvl-container-panel\">\r\n <ul class=\"tvl-container-hList\">\r\n <ng-content></ng-content>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n</li>\r\n" }]
10663
+ }], ctorParameters: () => [] });
10664
+
10665
+ class TruTab {
10666
+ tabGroupEventNotifier;
10667
+ view;
10668
+ label;
10669
+ matTab;
10670
+ constructor(tabGroupEventNotifier) {
10671
+ this.tabGroupEventNotifier = tabGroupEventNotifier;
10618
10672
  }
10619
- onAcceptAll = () => {
10620
- let entity = this.config.entity;
10621
- let originalValues = entity.entityAspect.originalValues;
10622
- for (const key in this.config.mergeData?.getAll()) {
10623
- entity[key] = this.config.mergeData?.get(key).value;
10624
- if (originalValues.hasOwnProperty(key))
10625
- delete originalValues[key];
10626
- }
10627
- ;
10628
- if (Object.keys(originalValues).length === 0 && originalValues.constructor === Object)
10629
- entity.entityAspect.setUnchanged();
10630
- entity.Merge_Data_Set.clearAll();
10631
- entity.entityAspect.validateEntity();
10632
- if (this.config.context === TruValidationDialogContext.Grid)
10633
- this.elementRef.nativeElement.remove();
10634
- };
10635
- onAccept = () => {
10636
- let entity = this.config.entity;
10637
- let originalValues = entity.entityAspect.originalValues;
10638
- let propertyName = this.config.propertyName;
10639
- entity[propertyName] = this.config.mergeData?.get(propertyName).value;
10640
- this.config.mergeData?.clear(propertyName);
10641
- if (originalValues.hasOwnProperty(propertyName) && (Object.keys(originalValues).length === 0 && originalValues.constructor === Object))
10642
- delete originalValues[propertyName];
10643
- if (this.config.mergeData?.isEmpty())
10644
- entity.entityAspect.setUnchanged();
10645
- entity.entityAspect.validateEntity();
10646
- if (this.config.context === TruValidationDialogContext.Grid)
10647
- this.elementRef.nativeElement.remove();
10648
- };
10649
- onDecline = () => {
10650
- let entity = this.config.entity;
10651
- this.config.mergeData?.clearAll();
10652
- entity.entityAspect.validateEntity();
10653
- if (this.config.context === TruValidationDialogContext.Grid)
10654
- this.elementRef.nativeElement.remove();
10673
+ notifyListeners = (isActive) => {
10674
+ this.tabGroupEventNotifier.isActive = isActive;
10655
10675
  };
10656
- ngOnInit() {
10657
- this.errorMsg = this.config.errorMsg;
10658
- if (this.config.context === TruValidationDialogContext.Control) {
10659
- var invalidTarget = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.invalid-target');
10660
- if (invalidTarget) {
10661
- this.listeners.push(this.renderer.listen(invalidTarget, 'mouseenter', (event) => {
10662
- this.elementRef.nativeElement.childNodes[0].classList.remove('hide');
10663
- this.elementRef.nativeElement.childNodes[0].classList.add('show');
10664
- }));
10665
- this.listeners.push(this.renderer.listen(invalidTarget, 'mouseleave', (event) => {
10666
- this.elementRef.nativeElement.childNodes[0].classList.remove('show');
10667
- this.elementRef.nativeElement.childNodes[0].classList.add('hide');
10668
- }));
10669
- }
10670
- }
10671
- else if (this.config.context === TruValidationDialogContext.Grid) {
10672
- this.rowElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-row');
10673
- this.cellElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-cell-value');
10674
- this.rowElement.style.zIndex = '10000000000';
10675
- this.cellElement.classList.add('show');
10676
- this.errorMsg = this.config.errorMsg;
10677
- }
10678
- }
10676
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTab, deps: [{ token: TruTabGroupEventNotifier }], target: i0.ɵɵFactoryTarget.Component });
10677
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruTab, isStandalone: true, selector: "tru-tab", inputs: { view: "view", label: "label" }, providers: [TruTabGroupEventNotifier], viewQueries: [{ propertyName: "matTab", first: true, predicate: MatTab, descendants: true }], ngImport: i0, template: "<mat-tab [label]=\"label\" [disabled]=\"!view.window.isActive()\">\r\n <ng-content></ng-content>\r\n</mat-tab>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2$3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }], encapsulation: i0.ViewEncapsulation.None });
10678
+ }
10679
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTab, decorators: [{
10680
+ type: Component,
10681
+ args: [{ selector: 'tru-tab', imports: [CommonModule, FormsModule, MatTabsModule], encapsulation: ViewEncapsulation.None, providers: [TruTabGroupEventNotifier], template: "<mat-tab [label]=\"label\" [disabled]=\"!view.window.isActive()\">\r\n <ng-content></ng-content>\r\n</mat-tab>\r\n" }]
10682
+ }], ctorParameters: () => [{ type: TruTabGroupEventNotifier }], propDecorators: { view: [{
10683
+ type: Input
10684
+ }], label: [{
10685
+ type: Input
10686
+ }], matTab: [{
10687
+ type: ViewChild,
10688
+ args: [MatTab]
10689
+ }] } });
10690
+
10691
+ class TruTabGroup {
10692
+ tabGroup;
10693
+ tabs;
10694
+ constructor() { }
10679
10695
  ngAfterViewInit() {
10680
- if (this.config.context === TruValidationDialogContext.Control) {
10681
- let invalidTarget = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.invalid-target');
10682
- if (invalidTarget)
10683
- invalidTarget.classList.add('invalid');
10684
- }
10696
+ const matTabsFromQueryList = this.tabs.map((tab) => tab.matTab);
10697
+ const list = new QueryList();
10698
+ list.reset([matTabsFromQueryList]);
10699
+ this.tabGroup._tabs = list;
10685
10700
  }
10686
- ngOnDestroy() {
10687
- if (this.config.context === TruValidationDialogContext.Control) {
10688
- let invalidTarget = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.invalid-target');
10689
- if (invalidTarget)
10690
- invalidTarget.classList.remove('invalid');
10691
- }
10692
- else if (this.config.context === TruValidationDialogContext.Grid) {
10693
- this.rowElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-row');
10694
- this.cellElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-cell-value');
10695
- if (this.rowElement)
10696
- this.rowElement.style.zIndex = 'auto';
10697
- if (this.cellElement)
10698
- this.cellElement.classList.remove('show');
10699
- }
10700
- this.listeners.forEach(l => l());
10701
+ onChange(event) {
10702
+ const selectedTabLabel = event.tab.textLabel;
10703
+ this.tabs.forEach((tab) => {
10704
+ if (selectedTabLabel === tab.label) {
10705
+ tab.notifyListeners(true);
10706
+ }
10707
+ else {
10708
+ tab.notifyListeners(false);
10709
+ }
10710
+ });
10701
10711
  }
10702
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruValidationDialog, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: TruUtil }], target: i0.ɵɵFactoryTarget.Component });
10703
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.3", type: TruValidationDialog, isStandalone: true, selector: "tru-validation-dialog", inputs: { config: "config" }, outputs: { close: "close" }, ngImport: i0, template: "@if (config.context === 0) {\r\n<div class=\"invalid hide\">\r\n <i class=\"icon-warning-sign icon-white\"></i>{{config.errorMsg}}\r\n <div *ngIf=\"config.mergeData\">\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAcceptAll()\">Accept All</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAccept()\">Accept</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onDecline()\">Decline</button>\r\n </div>\r\n</div>\r\n<span class=\"invalid-flag\"></span>\r\n}\r\n@else {\r\n<i class=\"icon-warning-sign icon-white\"></i>{{config.errorMsg}}\r\n<div *ngIf=\"config.mergeData\">\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAcceptAll()\">Accept All</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAccept()\">Accept</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onDecline()\">Decline</button>\r\n</div>\r\n}\r\n", styles: ["::ng-deep .tru-control.edit .mat-mdc-form-field .invalid,::ng-deep .tru-control.list .mat-mdc-form-field .invalid,::ng-deep .NgxEditor__Wrapper .invalid{position:absolute;left:0;top:24px;min-width:200px;min-height:20px;max-width:500px;max-height:500px;font-size:12px!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid.hide,::ng-deep .tru-control.list .mat-mdc-form-field .invalid.hide,::ng-deep .NgxEditor__Wrapper .invalid.hide{display:none!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid.show,::ng-deep .tru-control.list .mat-mdc-form-field .invalid.show,::ng-deep .NgxEditor__Wrapper .invalid.show{display:inline-block!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid-flag,::ng-deep .tru-control.list .mat-mdc-form-field .invalid-flag,::ng-deep .NgxEditor__Wrapper .invalid-flag{box-sizing:border-box;position:absolute;left:0;top:0;width:3px;height:3px;border-bottom:solid 3px transparent;border-right:solid 3px transparent;border-left:solid 3px red;border-top:solid 3px red}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid-triangle:after,::ng-deep .tru-control.list .mat-mdc-form-field .invalid-triangle:after{box-sizing:border-box}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid,::ng-deep .tru-control.list .mat-mdc-form-field .invalid,::ng-deep .NgxEditor__Wrapper .invalid{background-color:#bd362f;margin:2px 0 0;padding:4px 10px;-ms-border-radius:3px 3px 3px 3px!important;border-radius:3px!important;background-position:15px center;background-repeat:no-repeat;-webkit-box-shadow:0 0 12px #999999;-ms-box-shadow:0 0 12px #999999;box-shadow:0 0 12px #999;color:#fff;-ms-opacity:.9;opacity:.9;z-index:1000}::ng-deep .merge-button,::ng-deep .NgxEditor__Wrapper .invalid .merge-button{margin:5px;font-size:12px;font-family:Calibri,Helvetica,Arial,sans-serif!important;background-color:#fff}::ng-deep .mat-mdc-form-field.invalid .mdc-line-ripple:before{border-bottom-color:red!important}::ng-deep .mat-mdc-form-field.invalid .mdc-line-ripple:after{border-bottom-color:red!important}.invalid{font-family:Calibri,Helvetica,Arial,sans-serif!important}i{line-height:24px!important}::ng-deep .ag-row .ag-cell-value .invalid{position:absolute;left:0;top:18px;-moz-min-width:200px;-ms-min-width:200px;-o-min-width:200px;-webkit-min-width:200px;min-width:200px;min-height:20px;max-width:500px;max-height:500px;font-size:12px}::ng-deep .ag-row .ag-cell-value.hide .invalid{display:none!important}::ng-deep .ag-row .ag-cell-value.show .invalid{display:inline-block!important}::ng-deep .ag-row .ag-cell-value.invalid.show{overflow:visible!important}::ng-deep .ag-row .ag-cell-value .invalid{background-color:#bd362f;margin:2px 0 0;padding:4px 10px;-ms-border-radius:3px 3px 3px 3px!important;border-radius:3px!important;background-position:15px center;background-repeat:no-repeat;-webkit-box-shadow:0 0 12px #999999;-ms-box-shadow:0 0 12px #999999;box-shadow:0 0 12px #999;color:#fff;-ms-opacity:.9;opacity:.9;z-index:1000}::ng-deep .ag-cell .tru-control.list.in-cell .invalid-flag{display:none!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }] });
10712
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTabGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
10713
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruTabGroup, isStandalone: true, selector: "tru-tab-group", queries: [{ propertyName: "tabs", predicate: TruTab }], viewQueries: [{ propertyName: "tabGroup", first: true, predicate: MatTabGroup, descendants: true }], ngImport: i0, template: "<mat-tab-group #tabGroup\r\n (selectedTabChange)=\"onChange($event)\"\r\n animationDuration=\"0ms\">\r\n <ng-content #outlet></ng-content>\r\n</mat-tab-group>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2$3.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }], encapsulation: i0.ViewEncapsulation.None });
10704
10714
  }
10705
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruValidationDialog, decorators: [{
10715
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTabGroup, decorators: [{
10706
10716
  type: Component,
10707
- args: [{ selector: 'tru-validation-dialog', imports: [CommonModule, FormsModule], template: "@if (config.context === 0) {\r\n<div class=\"invalid hide\">\r\n <i class=\"icon-warning-sign icon-white\"></i>{{config.errorMsg}}\r\n <div *ngIf=\"config.mergeData\">\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAcceptAll()\">Accept All</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAccept()\">Accept</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onDecline()\">Decline</button>\r\n </div>\r\n</div>\r\n<span class=\"invalid-flag\"></span>\r\n}\r\n@else {\r\n<i class=\"icon-warning-sign icon-white\"></i>{{config.errorMsg}}\r\n<div *ngIf=\"config.mergeData\">\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAcceptAll()\">Accept All</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAccept()\">Accept</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onDecline()\">Decline</button>\r\n</div>\r\n}\r\n", styles: ["::ng-deep .tru-control.edit .mat-mdc-form-field .invalid,::ng-deep .tru-control.list .mat-mdc-form-field .invalid,::ng-deep .NgxEditor__Wrapper .invalid{position:absolute;left:0;top:24px;min-width:200px;min-height:20px;max-width:500px;max-height:500px;font-size:12px!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid.hide,::ng-deep .tru-control.list .mat-mdc-form-field .invalid.hide,::ng-deep .NgxEditor__Wrapper .invalid.hide{display:none!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid.show,::ng-deep .tru-control.list .mat-mdc-form-field .invalid.show,::ng-deep .NgxEditor__Wrapper .invalid.show{display:inline-block!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid-flag,::ng-deep .tru-control.list .mat-mdc-form-field .invalid-flag,::ng-deep .NgxEditor__Wrapper .invalid-flag{box-sizing:border-box;position:absolute;left:0;top:0;width:3px;height:3px;border-bottom:solid 3px transparent;border-right:solid 3px transparent;border-left:solid 3px red;border-top:solid 3px red}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid-triangle:after,::ng-deep .tru-control.list .mat-mdc-form-field .invalid-triangle:after{box-sizing:border-box}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid,::ng-deep .tru-control.list .mat-mdc-form-field .invalid,::ng-deep .NgxEditor__Wrapper .invalid{background-color:#bd362f;margin:2px 0 0;padding:4px 10px;-ms-border-radius:3px 3px 3px 3px!important;border-radius:3px!important;background-position:15px center;background-repeat:no-repeat;-webkit-box-shadow:0 0 12px #999999;-ms-box-shadow:0 0 12px #999999;box-shadow:0 0 12px #999;color:#fff;-ms-opacity:.9;opacity:.9;z-index:1000}::ng-deep .merge-button,::ng-deep .NgxEditor__Wrapper .invalid .merge-button{margin:5px;font-size:12px;font-family:Calibri,Helvetica,Arial,sans-serif!important;background-color:#fff}::ng-deep .mat-mdc-form-field.invalid .mdc-line-ripple:before{border-bottom-color:red!important}::ng-deep .mat-mdc-form-field.invalid .mdc-line-ripple:after{border-bottom-color:red!important}.invalid{font-family:Calibri,Helvetica,Arial,sans-serif!important}i{line-height:24px!important}::ng-deep .ag-row .ag-cell-value .invalid{position:absolute;left:0;top:18px;-moz-min-width:200px;-ms-min-width:200px;-o-min-width:200px;-webkit-min-width:200px;min-width:200px;min-height:20px;max-width:500px;max-height:500px;font-size:12px}::ng-deep .ag-row .ag-cell-value.hide .invalid{display:none!important}::ng-deep .ag-row .ag-cell-value.show .invalid{display:inline-block!important}::ng-deep .ag-row .ag-cell-value.invalid.show{overflow:visible!important}::ng-deep .ag-row .ag-cell-value .invalid{background-color:#bd362f;margin:2px 0 0;padding:4px 10px;-ms-border-radius:3px 3px 3px 3px!important;border-radius:3px!important;background-position:15px center;background-repeat:no-repeat;-webkit-box-shadow:0 0 12px #999999;-ms-box-shadow:0 0 12px #999999;box-shadow:0 0 12px #999;color:#fff;-ms-opacity:.9;opacity:.9;z-index:1000}::ng-deep .ag-cell .tru-control.list.in-cell .invalid-flag{display:none!important}\n"] }]
10708
- }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: TruUtil }], propDecorators: { config: [{
10709
- type: Input
10710
- }], close: [{
10711
- type: Output
10717
+ args: [{ selector: 'tru-tab-group', imports: [CommonModule, FormsModule, MatTabsModule], encapsulation: ViewEncapsulation.None, template: "<mat-tab-group #tabGroup\r\n (selectedTabChange)=\"onChange($event)\"\r\n animationDuration=\"0ms\">\r\n <ng-content #outlet></ng-content>\r\n</mat-tab-group>\r\n" }]
10718
+ }], ctorParameters: () => [], propDecorators: { tabGroup: [{
10719
+ type: ViewChild,
10720
+ args: [MatTabGroup]
10721
+ }], tabs: [{
10722
+ type: ContentChildren,
10723
+ args: [TruTab]
10712
10724
  }] } });
10713
10725
 
10714
- class TruValidationDialogConfig {
10715
- _entity;
10716
- _propertyConfig;
10717
- _context;
10718
- _isSubProperty;
10719
- _ignore;
10720
- _propertyName = '';
10721
- _errorMsg = '';
10722
- _mergeData = null;
10723
- get entity() {
10724
- return this._entity;
10725
- }
10726
- get propertyConfig() {
10727
- return this._propertyConfig;
10728
- }
10729
- get context() {
10730
- return this._context;
10731
- }
10732
- get isSubProperty() {
10733
- return this._isSubProperty;
10734
- }
10735
- get ignore() {
10736
- return this._ignore;
10737
- }
10738
- get propertyName() {
10739
- return this._propertyName;
10740
- }
10741
- set propertyName(value) {
10742
- this._propertyName = value;
10743
- }
10744
- get errorMsg() {
10745
- return this._errorMsg;
10746
- }
10747
- set errorMsg(value) {
10748
- this._errorMsg = value;
10749
- }
10750
- get mergeData() {
10751
- return this._mergeData;
10752
- }
10753
- set mergeData(value) {
10754
- this._mergeData = value;
10755
- }
10756
- constructor(entity, propertyConfig, context = TruValidationDialogContext.Control, isSubProperty = false, ignore = false) {
10757
- this._entity = entity;
10758
- this._propertyConfig = propertyConfig;
10759
- this._context = context;
10760
- this._isSubProperty = isSubProperty;
10761
- this._ignore = ignore;
10726
+ class TruLogin {
10727
+ auth;
10728
+ appEnvironment;
10729
+ loginForm = new FormGroup({
10730
+ username: new FormControl('', Validators.required),
10731
+ password: new FormControl('', Validators.required)
10732
+ });
10733
+ loginError = "";
10734
+ isLoggingIn = false;
10735
+ title;
10736
+ constructor(auth, appEnvironment) {
10737
+ this.auth = auth;
10738
+ this.appEnvironment = appEnvironment;
10739
+ this.title = appEnvironment.loginFormTitle;
10762
10740
  }
10763
- }
10764
-
10765
- class TruBreezeValidator {
10766
- el;
10767
- dataContext;
10768
- viewContainerRef;
10769
- componentFactoryResolver;
10770
- entity;
10771
- config;
10772
- constructor(el, dataContext, viewContainerRef, componentFactoryResolver) {
10773
- this.el = el;
10774
- this.dataContext = dataContext;
10775
- this.viewContainerRef = viewContainerRef;
10776
- this.componentFactoryResolver = componentFactoryResolver;
10741
+ get f() {
10742
+ return this.loginForm.controls;
10777
10743
  }
10778
- configModel = {};
10779
- mergeData;
10780
- dialogRef = null;
10781
- subs = [];
10782
- currentDialog = null;
10783
- context = TruValidationDialogContext.Control;
10784
- getMergeData = () => {
10785
- if (this.config.propertyPath?.includes('/')) {
10786
- let propertyNameParts = this.config.propertyPath.split('/');
10787
- propertyNameParts.pop();
10788
- let targetProperty;
10789
- propertyNameParts.forEach((name) => {
10790
- if (!targetProperty) {
10791
- let targetPropertyName = 'o' + name;
10792
- targetProperty = this.entity[targetPropertyName];
10744
+ isDisabled = () => {
10745
+ return !this.f.username.value || !this.f.password.value || this.isLoggingIn;
10746
+ };
10747
+ onSubmit() {
10748
+ const loginRequest = {
10749
+ username: this.f.username.value,
10750
+ password: this.f.password.value
10751
+ };
10752
+ if (loginRequest.username && loginRequest.password) {
10753
+ this.isLoggingIn = true;
10754
+ this.auth
10755
+ .login(loginRequest).pipe(finalize(() => {
10756
+ this.isLoggingIn = false;
10757
+ }))
10758
+ .subscribe(() => {
10759
+ this.isLoggingIn = false;
10760
+ }, (error) => {
10761
+ if (error.status === 401) {
10762
+ this.loginError = "Incorrect username and/or password";
10793
10763
  }
10794
10764
  else {
10795
- let targetPropertyName = 'o' + name;
10796
- targetProperty = targetProperty[targetPropertyName];
10765
+ this.loginError = "Invalid Login - Error: " + error.status;
10797
10766
  }
10798
10767
  });
10799
- if (targetProperty && targetProperty.Merge_Data) {
10800
- return targetProperty.Merge_Data_Set;
10801
- }
10802
- return undefined;
10803
- }
10804
- else {
10805
- return this.entity.Merge_Data_Set?.get(this.config.propertyName) ? this.entity.Merge_Data_Set : undefined;
10806
10768
  }
10807
- };
10808
- parseErrorMessages = (validationErrors) => {
10809
- let errorMsg = '';
10810
- validationErrors.forEach((error) => {
10811
- errorMsg += error.errorMessage + '; ';
10812
- });
10813
- return errorMsg;
10814
- };
10815
- addValidationDialog = (config) => {
10816
- let componentFactory = this.componentFactoryResolver.resolveComponentFactory(TruValidationDialog);
10817
- let component = this.viewContainerRef.createComponent(componentFactory, 0, this.viewContainerRef.injector);
10818
- component.instance.config = config;
10819
- this.currentDialog = component;
10820
- this.dialogRef = component;
10821
- };
10822
- removeValidationDialog = () => {
10823
- if (this.currentDialog) {
10824
- this.currentDialog.destroy();
10825
- this.currentDialog = null;
10769
+ }
10770
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLogin, deps: [{ token: TruAuth }, { token: TruAppEnvironment }], target: i0.ɵɵFactoryTarget.Component });
10771
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.3", type: TruLogin, isStandalone: false, selector: "tru-login", ngImport: i0, template: "<div class=\"login-wrapper\">\r\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"onSubmit()\">\r\n <mat-card class=\"animate-login\">\r\n <mat-card-header>\r\n <mat-card-title> {{title}} </mat-card-title>\r\n </mat-card-header>\r\n <mat-card-content>\r\n <mat-form-field>\r\n <mat-label>Username</mat-label>\r\n <input matInput formControlName=\"username\" placeholder=\"Username\">\r\n </mat-form-field>\r\n <mat-form-field>\r\n <mat-label>Password</mat-label>\r\n <input matInput type=\"password\" formControlName=\"password\" placeholder=\"Password\">\r\n </mat-form-field>\r\n <div *ngIf=\"loginError\" class=\"animate-login-error animated rubberBand\">\r\n <p style=\"color: red; font-weight: bold;\"> {{ loginError }}</p>\r\n </div>\r\n </mat-card-content>\r\n <mat-card-actions>\r\n <button mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"isDisabled()\">Login</button>\r\n </mat-card-actions>\r\n </mat-card>\r\n </form>\r\n</div>\r\n", styles: [".login-container{display:flex;justify-content:center;align-items:center;height:100vh;margin:0;padding:0}.login-input{margin-bottom:20px}.animate-login{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;margin-top:50px}.wrapper{display:flex;justify-content:center;align-items:center;height:100vh}mat-card{max-width:300px;width:100%;max-height:300px;padding:20px}.form-group{width:100%;max-width:400px;margin-bottom:20px}.login-wrapper{display:flex;justify-content:center;align-items:center;height:100vh}::ng-deep .login-wrapper .mat-mdc-text-field-wrapper{padding:0 16px!important}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i5$3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i5$3.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i5$3.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i5$3.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i5$3.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: i9.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i7.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
10772
+ }
10773
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLogin, decorators: [{
10774
+ type: Component,
10775
+ args: [{ selector: 'tru-login', standalone: false, template: "<div class=\"login-wrapper\">\r\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"onSubmit()\">\r\n <mat-card class=\"animate-login\">\r\n <mat-card-header>\r\n <mat-card-title> {{title}} </mat-card-title>\r\n </mat-card-header>\r\n <mat-card-content>\r\n <mat-form-field>\r\n <mat-label>Username</mat-label>\r\n <input matInput formControlName=\"username\" placeholder=\"Username\">\r\n </mat-form-field>\r\n <mat-form-field>\r\n <mat-label>Password</mat-label>\r\n <input matInput type=\"password\" formControlName=\"password\" placeholder=\"Password\">\r\n </mat-form-field>\r\n <div *ngIf=\"loginError\" class=\"animate-login-error animated rubberBand\">\r\n <p style=\"color: red; font-weight: bold;\"> {{ loginError }}</p>\r\n </div>\r\n </mat-card-content>\r\n <mat-card-actions>\r\n <button mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"isDisabled()\">Login</button>\r\n </mat-card-actions>\r\n </mat-card>\r\n </form>\r\n</div>\r\n", styles: [".login-container{display:flex;justify-content:center;align-items:center;height:100vh;margin:0;padding:0}.login-input{margin-bottom:20px}.animate-login{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;margin-top:50px}.wrapper{display:flex;justify-content:center;align-items:center;height:100vh}mat-card{max-width:300px;width:100%;max-height:300px;padding:20px}.form-group{width:100%;max-width:400px;margin-bottom:20px}.login-wrapper{display:flex;justify-content:center;align-items:center;height:100vh}::ng-deep .login-wrapper .mat-mdc-text-field-wrapper{padding:0 16px!important}\n"] }]
10776
+ }], ctorParameters: () => [{ type: TruAuth }, { type: TruAppEnvironment }] });
10777
+
10778
+ class TruAuthJwtStrategy {
10779
+ JWT_ACCESS_TOKEN = "ACCESS_TOKEN";
10780
+ JWT_REFRESH_TOKEN = "REFRESH_TOKEN";
10781
+ doLoginUser(token) {
10782
+ localStorage.setItem(this.JWT_ACCESS_TOKEN, JSON.stringify(token.accessToken));
10783
+ localStorage.setItem(this.JWT_REFRESH_TOKEN, JSON.stringify(token.refreshToken));
10784
+ }
10785
+ doLogoutUser() {
10786
+ localStorage.removeItem(this.JWT_ACCESS_TOKEN);
10787
+ }
10788
+ isLoggedIn() {
10789
+ return !!this.getJwtToken();
10790
+ }
10791
+ createUser(user) {
10792
+ let jwtData = this.getDecodedJwtJsonData();
10793
+ console.log(jwtData);
10794
+ let userData = {
10795
+ activeUserRef: jwtData.UserRef,
10796
+ firstName: jwtData.FirstName,
10797
+ lastName: jwtData.LastName,
10798
+ email: jwtData.Email,
10799
+ username: jwtData['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name'],
10800
+ roles: jwtData['http://schemas.microsoft.com/ws/2008/06/identity/claims/role']
10801
+ };
10802
+ return of(user.create(userData));
10803
+ }
10804
+ getJwtToken() {
10805
+ try {
10806
+ return JSON.parse(localStorage.getItem(this.JWT_ACCESS_TOKEN));
10826
10807
  }
10827
- };
10828
- valErrsChanged = (validationObject) => {
10829
- let validationObjectEntity = validationObject.entity;
10830
- let validationTableName = validationObjectEntity.constructor.name;
10831
- const entityPkeyName = validationTableName + 'Ref';
10832
- const validationObjectEntitypkeyName = validationTableName + 'Ref';
10833
- let propertyName = this.config.isSubProperty ? this.config.propertyName.replace(/\./g, "") : this.config.propertyName;
10834
- let addedPropertyValdations = validationObject.added.filter((v) => {
10835
- return v.propertyName === propertyName;
10836
- });
10837
- let removedPropertyValdations = validationObject.removed.filter((v) => {
10838
- return v.propertyName === propertyName;
10839
- });
10840
- this.mergeData = this.getMergeData();
10841
- if (this.config.rootTable === validationTableName &&
10842
- this.entity[entityPkeyName] === validationObjectEntity[validationObjectEntitypkeyName] &&
10843
- (addedPropertyValdations.length || this.mergeData)) {
10844
- this.removeValidationDialog();
10845
- let config = new TruValidationDialogConfig(this.entity, this.config);
10846
- config.propertyName = this.config.propertyName;
10847
- config.mergeData = this.mergeData;
10848
- config.errorMsg = this.parseErrorMessages(addedPropertyValdations);
10849
- this.addValidationDialog(config);
10808
+ catch (e) {
10809
+ return null;
10850
10810
  }
10851
- if (this.config.rootTable === validationTableName &&
10852
- this.entity[entityPkeyName] === validationObjectEntity[validationObjectEntitypkeyName] &&
10853
- (removedPropertyValdations.length)) {
10854
- this.removeValidationDialog();
10811
+ }
10812
+ getDecodedJwtJsonData() {
10813
+ let token = this.getJwtToken();
10814
+ let payload = {};
10815
+ if (token && token !== "undefined") {
10816
+ const encodedPayload = token.split(".")[1];
10817
+ const payloadStr = window.atob(encodedPayload);
10818
+ payload = JSON.parse(payloadStr);
10855
10819
  }
10856
- };
10857
- ngOnInit() { }
10858
- ngAfterViewInit() {
10859
- if (this.context !== TruValidationDialogContext.Grid) {
10860
- this.subs.push(this.dataContext.validationChangeDetection.subscribe(entities => {
10861
- this.valErrsChanged(entities);
10862
- }));
10820
+ return payload;
10821
+ }
10822
+ getToken() {
10823
+ var token = this.getJwtToken();
10824
+ if (token && token !== "undefined") {
10825
+ const encodedPayload = token.split(".")[1];
10826
+ const payloadStr = window.atob(encodedPayload);
10827
+ var payload = JSON.parse(payloadStr);
10828
+ var exp = payload["exp"];
10829
+ var d = new Date();
10830
+ var epoch = Math.round(d.getTime() / 1000);
10831
+ if (exp < epoch) {
10832
+ localStorage.removeItem(this.JWT_ACCESS_TOKEN);
10833
+ return null;
10834
+ }
10863
10835
  }
10864
- this.entity.entityAspect.validateEntity();
10836
+ return token;
10865
10837
  }
10866
- ngOnChanges(changes) {
10867
- this.removeValidationDialog();
10868
- this.entity.entityAspect.validateEntity();
10838
+ }
10839
+
10840
+ class TruAuthInterceptor {
10841
+ auth;
10842
+ appEnvironment;
10843
+ jwt;
10844
+ constructor(auth, appEnvironment, jwt) {
10845
+ this.auth = auth;
10846
+ this.appEnvironment = appEnvironment;
10847
+ this.jwt = jwt;
10869
10848
  }
10870
- ngOnDestroy() {
10871
- this.subs.forEach(s => s.unsubscribe());
10849
+ intercept(request, next) {
10850
+ if (this.appEnvironment.authType === 'jwt')
10851
+ request = this.addToken(request, String(this.jwt.getToken()));
10852
+ if (this.appEnvironment.authType === 'session')
10853
+ request = request.clone({
10854
+ withCredentials: true
10855
+ });
10856
+ return next.handle(request).pipe(catchError((error) => {
10857
+ if (error.status === 401) {
10858
+ this.auth.doLogoutAndRedirectToLogin();
10859
+ }
10860
+ return throwError(error);
10861
+ }));
10872
10862
  }
10873
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruBreezeValidator, deps: [{ token: i0.ElementRef }, { token: TruDataContext }, { token: i0.ViewContainerRef }, { token: i0.ComponentFactoryResolver }], target: i0.ɵɵFactoryTarget.Directive });
10874
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.3", type: TruBreezeValidator, isStandalone: true, selector: "[truBreezeValidator]", inputs: { entity: ["truBreezeValidator", "entity"], config: "config" }, usesOnChanges: true, ngImport: i0 });
10863
+ addToken(request, token) {
10864
+ return request.clone({
10865
+ setHeaders: { Authorization: `Bearer ${token}` },
10866
+ });
10867
+ }
10868
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruAuthInterceptor, deps: [{ token: TruAuth }, { token: TruAppEnvironment }, { token: TRU_AUTH_STRATEGY }], target: i0.ɵɵFactoryTarget.Injectable });
10869
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruAuthInterceptor });
10875
10870
  }
10876
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruBreezeValidator, decorators: [{
10877
- type: Directive,
10878
- args: [{
10879
- selector: '[truBreezeValidator]'
10880
- }]
10881
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: TruDataContext }, { type: i0.ViewContainerRef }, { type: i0.ComponentFactoryResolver }], propDecorators: { entity: [{
10882
- type: Input,
10883
- args: ['truBreezeValidator']
10884
- }], config: [{
10885
- type: Input
10886
- }] } });
10871
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruAuthInterceptor, decorators: [{
10872
+ type: Injectable
10873
+ }], ctorParameters: () => [{ type: TruAuth }, { type: TruAppEnvironment }, { type: TruAuthJwtStrategy, decorators: [{
10874
+ type: Inject,
10875
+ args: [TRU_AUTH_STRATEGY]
10876
+ }] }] });
10887
10877
 
10888
- class TruSearchPanelPositionManager {
10889
- el;
10890
- renderer;
10891
- config = { size: 300 };
10892
- searchViewPortal = null;
10893
- tab = null;
10894
- dropZones = [];
10895
- dragHandles = [];
10896
- currentWidth = 0;
10897
- currentMinWidth = 0;
10898
- mouseOffsetX = 0;
10899
- lastMouseX = 0;
10900
- dragHandle = null;
10901
- listeners = [];
10902
- mousemoveListener;
10903
- mouseupListener;
10904
- constructor(el, renderer) {
10905
- this.el = el;
10906
- this.renderer = renderer;
10878
+ class TruAuthSessionStrategy {
10879
+ http;
10880
+ loggedUser;
10881
+ constructor(http) {
10882
+ this.http = http;
10907
10883
  }
10908
- ngAfterViewInit() {
10909
- this.searchViewPortal = this.el.nativeElement.closest('.search-container');
10910
- this.tab = this.el.nativeElement.querySelectorAll('.search-panel-tab')[0];
10911
- this.dropZones = this.searchViewPortal?.querySelectorAll('.search-panel-dropzone');
10912
- this.dragHandles = this.el.nativeElement.querySelectorAll('.search-panel-resizable-handle');
10913
- this.addTabEventListeners();
10914
- this.addDropzoneEventListeners();
10915
- this.addDragHandleEventListeners();
10884
+ doLoginUser(user) {
10885
+ this.loggedUser = user;
10916
10886
  }
10917
- addTabEventListeners = () => {
10918
- this.listeners.push(this.renderer.listen(this.tab, 'dragstart', this.dragStart));
10919
- this.listeners.push(this.renderer.listen(this.tab, 'dragend', this.dragEnd));
10920
- };
10921
- addDropzoneEventListeners = () => {
10922
- this.dropZones.forEach((dropZone) => {
10923
- this.listeners.push(this.renderer.listen(dropZone, 'dragover', this.dragOver));
10924
- this.listeners.push(this.renderer.listen(dropZone, 'dragleave', this.dragLeave));
10925
- this.listeners.push(this.renderer.listen(dropZone, 'drop', this.drop));
10926
- });
10927
- };
10928
- addDragHandleEventListeners = () => {
10929
- this.dragHandles.forEach((dropHandle) => {
10930
- this.listeners.push(this.renderer.listen(dropHandle, 'mousedown', this.mousedown));
10931
- });
10932
- };
10933
- addPointerEvents = () => {
10934
- this.dropZones.forEach((dropZone) => {
10935
- dropZone.style.pointerEvents = 'all';
10936
- });
10937
- };
10938
- removePointerEvents = () => {
10939
- this.dropZones.forEach((dropZone) => {
10940
- dropZone.style.pointerEvents = 'none';
10941
- });
10942
- };
10943
- addMouseoverDropzoneStyles = (event) => {
10944
- event.target.classList.add('mouseover');
10945
- };
10946
- removeMouseoverDropzoneStyles = (event) => {
10947
- for (var i = 0; i < this.dropZones.length; i++) {
10948
- if (event.target !== this.dropZones[i])
10949
- this.dropZones[i].classList.remove('mouseover');
10950
- }
10951
- };
10952
- dragStart = (event) => {
10953
- this.addPointerEvents();
10954
- };
10955
- dragEnd = (event) => {
10956
- this.removePointerEvents();
10957
- this.removeMouseoverDropzoneStyles(event);
10958
- };
10959
- dragOver = (event) => {
10960
- event.preventDefault();
10961
- this.addMouseoverDropzoneStyles(event);
10962
- };
10963
- dragLeave = (event) => {
10964
- event.target.classList.remove('mouseover');
10965
- };
10966
- drop = (event) => {
10967
- if (event.target.classList.contains('left')) {
10968
- this.config.side = 'left';
10969
- this.config.setGridPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
10970
- this.config.setToolbarPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
10971
- //userPreference.set(userPreference.searchPanelSide, 'left');
10972
- }
10973
- if (event.target.classList.contains('right')) {
10974
- this.config.side = 'right';
10975
- this.config.setGridPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
10976
- this.config.setToolbarPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
10977
- //userPreference.set(userPreference.searchPanelSide, 'right');
10978
- }
10979
- this.removeMouseoverDropzoneStyles(event);
10980
- };
10981
- mousedown = (event) => {
10982
- if (this.config.pinned)
10983
- return;
10984
- if (!this.dragHandle)
10985
- this.dragHandle = event.target;
10986
- this.mouseOffsetX = event.clientX;
10987
- this.mousemoveListener = this.renderer.listen('document', 'mousemove', this.mouseMove);
10988
- this.mouseupListener = this.renderer.listen('document', 'mouseup', this.mouseUp);
10989
- };
10990
- mouseMove = (event) => {
10991
- var mouseX = event.pageX - this.mouseOffsetX;
10992
- var diffX = mouseX - this.lastMouseX;
10993
- this.lastMouseX = mouseX;
10994
- this.currentWidth = this.config.size;
10995
- this.currentMinWidth = 100;
10996
- if (this.dragHandle?.classList.contains('search-panel-resizable-w')) {
10997
- if (this.currentWidth - diffX < this.currentMinWidth)
10998
- this.mouseOffsetX = this.mouseOffsetX - (diffX - (diffX = this.currentWidth - this.currentMinWidth));
10999
- this.config.size = (this.currentWidth - diffX);
11000
- this.updateSide();
11001
- }
11002
- if (this.dragHandle?.classList.contains('search-panel-resizable-e')) {
11003
- if (this.currentWidth + diffX < this.currentMinWidth)
11004
- this.mouseOffsetX = this.mouseOffsetX - (diffX - (diffX = this.currentMinWidth - this.currentWidth));
11005
- this.config.size = (this.currentWidth + diffX);
11006
- this.updateSide();
10887
+ doLogoutUser() {
10888
+ this.loggedUser = undefined;
10889
+ }
10890
+ createUser(user) {
10891
+ return of({});
10892
+ }
10893
+ isLoggedIn() {
10894
+ return false; //todo, implement this
10895
+ }
10896
+ }
10897
+
10898
+ const TruAuthStrategyProvider = {
10899
+ provide: TRU_AUTH_STRATEGY,
10900
+ deps: [HttpClient, TruAppEnvironment],
10901
+ useFactory: (http, appEnvironment) => {
10902
+ switch (appEnvironment.authType) {
10903
+ case "session":
10904
+ return new TruAuthSessionStrategy(http);
10905
+ case "jwt":
10906
+ return new TruAuthJwtStrategy();
10907
+ default:
10908
+ throw new Error("Invalid auth strategy");
11007
10909
  }
11008
- };
11009
- mouseUp = () => {
11010
- this.dragHandle = null;
11011
- this.mouseOffsetX = 0;
11012
- this.lastMouseX = 0;
11013
- this.mousemoveListener();
11014
- this.mouseupListener();
11015
- };
11016
- updateSide = () => {
11017
- //if (this.config.side === 'left') {
11018
- // this.config.setGridPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
11019
- // this.config.setToolbarPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
11020
- //}
11021
- //if (this.config.side === 'right') {
11022
- // this.config.setGridPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
11023
- // this.config.setToolbarPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
11024
- //}
11025
- };
11026
- ngOnDestroy() {
11027
- this.listeners.forEach(fn => fn());
10910
+ },
10911
+ };
10912
+
10913
+ const routes = [
10914
+ {
10915
+ path: 'login',
10916
+ component: TruLogin
11028
10917
  }
11029
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruSearchPanelPositionManager, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
11030
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.3", type: TruSearchPanelPositionManager, isStandalone: true, selector: "[truSearchPanelPositionManager]", inputs: { config: "config" }, ngImport: i0 });
10918
+ ];
10919
+ class TruLoginModule {
10920
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
10921
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, declarations: [TruLogin], imports: [CommonModule, MaterialModule, FormsModule, ReactiveFormsModule, i1$4.RouterModule], exports: [TruLogin] });
10922
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, providers: [
10923
+ {
10924
+ provide: HTTP_INTERCEPTORS,
10925
+ useClass: TruAuthInterceptor,
10926
+ multi: true,
10927
+ },
10928
+ {
10929
+ provide: HTTP_INTERCEPTORS,
10930
+ useClass: TruErrorInterceptor,
10931
+ multi: true,
10932
+ },
10933
+ TruAuthStrategyProvider
10934
+ ], imports: [CommonModule, MaterialModule, FormsModule, ReactiveFormsModule, RouterModule.forChild(routes)] });
11031
10935
  }
11032
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruSearchPanelPositionManager, decorators: [{
11033
- type: Directive,
10936
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, decorators: [{
10937
+ type: NgModule,
11034
10938
  args: [{
11035
- selector: '[truSearchPanelPositionManager]'
10939
+ declarations: [TruLogin],
10940
+ imports: [CommonModule, MaterialModule, FormsModule, ReactiveFormsModule, RouterModule.forChild(routes)],
10941
+ exports: [TruLogin],
10942
+ providers: [
10943
+ {
10944
+ provide: HTTP_INTERCEPTORS,
10945
+ useClass: TruAuthInterceptor,
10946
+ multi: true,
10947
+ },
10948
+ {
10949
+ provide: HTTP_INTERCEPTORS,
10950
+ useClass: TruErrorInterceptor,
10951
+ multi: true,
10952
+ },
10953
+ TruAuthStrategyProvider
10954
+ ],
11036
10955
  }]
11037
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { config: [{
11038
- type: Input
11039
- }] } });
10956
+ }] });
11040
10957
 
11041
- class TruCloudFileManager {
11042
- appEnvironment;
10958
+ var TruValidationDialogContext;
10959
+ (function (TruValidationDialogContext) {
10960
+ TruValidationDialogContext[TruValidationDialogContext["Control"] = 0] = "Control";
10961
+ TruValidationDialogContext[TruValidationDialogContext["Grid"] = 1] = "Grid";
10962
+ TruValidationDialogContext[TruValidationDialogContext["Card"] = 2] = "Card";
10963
+ })(TruValidationDialogContext || (TruValidationDialogContext = {}));
10964
+
10965
+ class TruValidationDialog {
10966
+ renderer;
10967
+ elementRef;
11043
10968
  util;
11044
- user;
11045
- baseUrl;
11046
- reader;
11047
- file;
11048
- sliceSize = 10000 * 1024;
11049
- constructor(appEnvironment, util, user) {
11050
- this.appEnvironment = appEnvironment;
10969
+ config;
10970
+ close = new EventEmitter();
10971
+ errorMsg = '';
10972
+ rowElement;
10973
+ cellElement;
10974
+ listeners = [];
10975
+ constructor(renderer, elementRef, util) {
10976
+ this.renderer = renderer;
10977
+ this.elementRef = elementRef;
11051
10978
  this.util = util;
11052
- this.user = user;
11053
- this.baseUrl = this.appEnvironment.appUri;
11054
10979
  }
11055
- getFileLength = (blobId, temp) => {
11056
- return Observable.create((observer) => {
11057
- let xhr = new XMLHttpRequest();
11058
- xhr.onreadystatechange = function () {
11059
- if (xhr.readyState == XMLHttpRequest.DONE) {
11060
- if (xhr.status == 200) {
11061
- observer.next(xhr.response);
11062
- }
11063
- else {
11064
- console.log('Download Failed. Unable to acquire file size.');
11065
- }
11066
- }
11067
- };
11068
- xhr.open('POST', this.baseUrl + '/api/CloudFile/BlobLength', true);
11069
- xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11070
- xhr.send(JSON.stringify({
11071
- blobId: blobId,
11072
- temp: temp ? true : false
11073
- }));
11074
- });
11075
- };
11076
- uploadFile = (start, tableName, propertyName, filename, blobMetaData, temp, updateProgress, done) => {
11077
- let nextSlice = start + this.sliceSize + 1;
11078
- let blob = this.file?.slice(start, nextSlice);
11079
- this.reader.onloadend = (event) => {
11080
- if (event.target?.readyState !== FileReader.DONE) {
11081
- return;
11082
- }
11083
- let xhr = new XMLHttpRequest();
11084
- xhr.onreadystatechange = () => {
11085
- if (xhr.readyState == XMLHttpRequest.DONE) {
11086
- if (xhr.status == 200) {
11087
- var sizeDone = start + this.sliceSize;
11088
- var percentDone = Math.floor((sizeDone / this.file.size) * 100);
11089
- var blobMetaData = JSON.parse(xhr.response);
11090
- if (nextSlice < this.file?.size) {
11091
- updateProgress(percentDone);
11092
- console.log('Uploading File - ' + percentDone + '%');
11093
- this.uploadFile(nextSlice, tableName, propertyName, filename, blobMetaData, temp, updateProgress, done);
11094
- }
11095
- else {
11096
- done(blobMetaData.truDbCloudFileRef);
11097
- }
11098
- }
11099
- else {
11100
- console.log(xhr.responseType);
11101
- }
11102
- }
11103
- };
11104
- xhr.open('POST', this.baseUrl + '/api/CloudFile/Upload', true);
11105
- xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11106
- xhr.send(JSON.stringify({
11107
- tableName: tableName,
11108
- propertyName: propertyName,
11109
- fileData: event.target.result.split(',')[1],
11110
- filename: filename,
11111
- blobId: blobMetaData.blobId,
11112
- blobBlockIdStr: blobMetaData.blobBlockIdStr,
11113
- createdRef: this.user.activeUserRef,
11114
- public: false,
11115
- temp: temp ? true : false,
11116
- commit: nextSlice < this.file.size ? false : true
11117
- }));
11118
- };
11119
- this.reader.readAsDataURL(blob);
11120
- };
11121
- upload = (tableName, propertyName, fileData, temp, updateProgress, done) => {
11122
- this.reader = new FileReader();
11123
- this.file = fileData;
11124
- this.uploadFile(0, tableName, propertyName, this.file.name, { blobId: null, blobBlockIdStr: null }, temp, updateProgress, done);
10980
+ onAcceptAll = () => {
10981
+ let entity = this.config.entity;
10982
+ let originalValues = entity.entityAspect.originalValues;
10983
+ for (const key in this.config.mergeData?.getAll()) {
10984
+ entity[key] = this.config.mergeData?.get(key).value;
10985
+ if (originalValues.hasOwnProperty(key))
10986
+ delete originalValues[key];
10987
+ }
10988
+ ;
10989
+ if (Object.keys(originalValues).length === 0 && originalValues.constructor === Object)
10990
+ entity.entityAspect.setUnchanged();
10991
+ entity.Merge_Data_Set.clearAll();
10992
+ entity.entityAspect.validateEntity();
10993
+ if (this.config.context === TruValidationDialogContext.Grid)
10994
+ this.elementRef.nativeElement.remove();
11125
10995
  };
11126
- download = (blobId, temp, filename, updateProgress, done) => {
11127
- this.getFileLength(blobId, temp).subscribe((fileLength) => {
11128
- var xhr = new XMLHttpRequest();
11129
- xhr.onprogress = function (e) {
11130
- updateProgress(Math.round(e.loaded / e.total * 100));
11131
- };
11132
- xhr.onload = function () {
11133
- //var fileName = xhr.getResponseHeader('Content-Disposition').split("filename=")[1];
11134
- var blob = new Blob([xhr.response], { type: 'application/octet-stream' });
11135
- var a = document.createElement('a');
11136
- a.href = URL.createObjectURL(blob);
11137
- a.download = filename;
11138
- document.body.appendChild(a);
11139
- a.dispatchEvent(new MouseEvent('click'));
11140
- done();
11141
- };
11142
- xhr.onerror = function (e) {
11143
- done();
11144
- console.log(e);
11145
- };
11146
- xhr.ontimeout = function (e) {
11147
- done();
11148
- console.log(e);
11149
- };
11150
- xhr.open('POST', this.baseUrl + '/api/CloudFile/Download');
11151
- xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11152
- xhr.responseType = 'arraybuffer';
11153
- xhr.send(JSON.stringify({
11154
- blobId: blobId,
11155
- filename: filename,
11156
- fileLength: parseInt(fileLength),
11157
- temp: temp ? true : false
11158
- }));
11159
- });
10996
+ onAccept = () => {
10997
+ let entity = this.config.entity;
10998
+ let originalValues = entity.entityAspect.originalValues;
10999
+ let propertyName = this.config.propertyName;
11000
+ entity[propertyName] = this.config.mergeData?.get(propertyName).value;
11001
+ this.config.mergeData?.clear(propertyName);
11002
+ if (originalValues.hasOwnProperty(propertyName) && (Object.keys(originalValues).length === 0 && originalValues.constructor === Object))
11003
+ delete originalValues[propertyName];
11004
+ if (this.config.mergeData?.isEmpty())
11005
+ entity.entityAspect.setUnchanged();
11006
+ entity.entityAspect.validateEntity();
11007
+ if (this.config.context === TruValidationDialogContext.Grid)
11008
+ this.elementRef.nativeElement.remove();
11160
11009
  };
11161
- sasUrl = (blobId, temp, filename, updateProgress, done) => {
11162
- var xhr = new XMLHttpRequest();
11163
- xhr.onprogress = function (e) { };
11164
- xhr.onload = function () {
11165
- done(xhr.response);
11166
- };
11167
- xhr.onerror = function (e) {
11168
- done(undefined);
11169
- console.log(e);
11170
- };
11171
- xhr.ontimeout = function (e) {
11172
- done(undefined);
11173
- console.log(e);
11174
- };
11175
- xhr.open('POST', this.baseUrl + '/api/CloudFile/SASTokenURL');
11176
- xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11177
- xhr.responseType = 'text';
11178
- xhr.send(JSON.stringify({
11179
- blobId: blobId
11180
- }));
11010
+ onDecline = () => {
11011
+ let entity = this.config.entity;
11012
+ this.config.mergeData?.clearAll();
11013
+ entity.entityAspect.validateEntity();
11014
+ if (this.config.context === TruValidationDialogContext.Grid)
11015
+ this.elementRef.nativeElement.remove();
11181
11016
  };
11182
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruCloudFileManager, deps: [{ token: TruAppEnvironment }, { token: TruUtil }, { token: TruUser }], target: i0.ɵɵFactoryTarget.Injectable });
11183
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruCloudFileManager, providedIn: 'root' });
11017
+ ngOnInit() {
11018
+ this.errorMsg = this.config.errorMsg;
11019
+ if (this.config.context === TruValidationDialogContext.Control) {
11020
+ var invalidTarget = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.invalid-target');
11021
+ if (invalidTarget) {
11022
+ this.listeners.push(this.renderer.listen(invalidTarget, 'mouseenter', (event) => {
11023
+ this.elementRef.nativeElement.childNodes[0].classList.remove('hide');
11024
+ this.elementRef.nativeElement.childNodes[0].classList.add('show');
11025
+ }));
11026
+ this.listeners.push(this.renderer.listen(invalidTarget, 'mouseleave', (event) => {
11027
+ this.elementRef.nativeElement.childNodes[0].classList.remove('show');
11028
+ this.elementRef.nativeElement.childNodes[0].classList.add('hide');
11029
+ }));
11030
+ }
11031
+ }
11032
+ else if (this.config.context === TruValidationDialogContext.Grid) {
11033
+ this.rowElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-row');
11034
+ this.cellElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-cell-value');
11035
+ this.rowElement.style.zIndex = '10000000000';
11036
+ this.cellElement.classList.add('show');
11037
+ this.errorMsg = this.config.errorMsg;
11038
+ }
11039
+ }
11040
+ ngAfterViewInit() {
11041
+ if (this.config.context === TruValidationDialogContext.Control) {
11042
+ let invalidTarget = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.invalid-target');
11043
+ if (invalidTarget)
11044
+ invalidTarget.classList.add('invalid');
11045
+ }
11046
+ }
11047
+ ngOnDestroy() {
11048
+ if (this.config.context === TruValidationDialogContext.Control) {
11049
+ let invalidTarget = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.invalid-target');
11050
+ if (invalidTarget)
11051
+ invalidTarget.classList.remove('invalid');
11052
+ }
11053
+ else if (this.config.context === TruValidationDialogContext.Grid) {
11054
+ this.rowElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-row');
11055
+ this.cellElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-cell-value');
11056
+ if (this.rowElement)
11057
+ this.rowElement.style.zIndex = 'auto';
11058
+ if (this.cellElement)
11059
+ this.cellElement.classList.remove('show');
11060
+ }
11061
+ this.listeners.forEach(l => l());
11062
+ }
11063
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruValidationDialog, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: TruUtil }], target: i0.ɵɵFactoryTarget.Component });
11064
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.3", type: TruValidationDialog, isStandalone: true, selector: "tru-validation-dialog", inputs: { config: "config" }, outputs: { close: "close" }, ngImport: i0, template: "@if (config.context === 0) {\r\n<div class=\"invalid hide\">\r\n <i class=\"icon-warning-sign icon-white\"></i>{{config.errorMsg}}\r\n <div *ngIf=\"config.mergeData\">\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAcceptAll()\">Accept All</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAccept()\">Accept</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onDecline()\">Decline</button>\r\n </div>\r\n</div>\r\n<span class=\"invalid-flag\"></span>\r\n}\r\n@else {\r\n<i class=\"icon-warning-sign icon-white\"></i>{{config.errorMsg}}\r\n<div *ngIf=\"config.mergeData\">\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAcceptAll()\">Accept All</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAccept()\">Accept</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onDecline()\">Decline</button>\r\n</div>\r\n}\r\n", styles: ["::ng-deep .tru-control.edit .mat-mdc-form-field .invalid,::ng-deep .tru-control.list .mat-mdc-form-field .invalid,::ng-deep .NgxEditor__Wrapper .invalid{position:absolute;left:0;top:24px;min-width:200px;min-height:20px;max-width:500px;max-height:500px;font-size:12px!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid.hide,::ng-deep .tru-control.list .mat-mdc-form-field .invalid.hide,::ng-deep .NgxEditor__Wrapper .invalid.hide{display:none!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid.show,::ng-deep .tru-control.list .mat-mdc-form-field .invalid.show,::ng-deep .NgxEditor__Wrapper .invalid.show{display:inline-block!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid-flag,::ng-deep .tru-control.list .mat-mdc-form-field .invalid-flag,::ng-deep .NgxEditor__Wrapper .invalid-flag{box-sizing:border-box;position:absolute;left:0;top:0;width:3px;height:3px;border-bottom:solid 3px transparent;border-right:solid 3px transparent;border-left:solid 3px red;border-top:solid 3px red}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid-triangle:after,::ng-deep .tru-control.list .mat-mdc-form-field .invalid-triangle:after{box-sizing:border-box}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid,::ng-deep .tru-control.list .mat-mdc-form-field .invalid,::ng-deep .NgxEditor__Wrapper .invalid{background-color:#bd362f;margin:2px 0 0;padding:4px 10px;-ms-border-radius:3px 3px 3px 3px!important;border-radius:3px!important;background-position:15px center;background-repeat:no-repeat;-webkit-box-shadow:0 0 12px #999999;-ms-box-shadow:0 0 12px #999999;box-shadow:0 0 12px #999;color:#fff;-ms-opacity:.9;opacity:.9;z-index:1000}::ng-deep .merge-button,::ng-deep .NgxEditor__Wrapper .invalid .merge-button{margin:5px;font-size:12px;font-family:Calibri,Helvetica,Arial,sans-serif!important;background-color:#fff}::ng-deep .mat-mdc-form-field.invalid .mdc-line-ripple:before{border-bottom-color:red!important}::ng-deep .mat-mdc-form-field.invalid .mdc-line-ripple:after{border-bottom-color:red!important}.invalid{font-family:Calibri,Helvetica,Arial,sans-serif!important}i{line-height:24px!important}::ng-deep .ag-row .ag-cell-value .invalid{position:absolute;left:0;top:18px;-moz-min-width:200px;-ms-min-width:200px;-o-min-width:200px;-webkit-min-width:200px;min-width:200px;min-height:20px;max-width:500px;max-height:500px;font-size:12px}::ng-deep .ag-row .ag-cell-value.hide .invalid{display:none!important}::ng-deep .ag-row .ag-cell-value.show .invalid{display:inline-block!important}::ng-deep .ag-row .ag-cell-value.invalid.show{overflow:visible!important}::ng-deep .ag-row .ag-cell-value .invalid{background-color:#bd362f;margin:2px 0 0;padding:4px 10px;-ms-border-radius:3px 3px 3px 3px!important;border-radius:3px!important;background-position:15px center;background-repeat:no-repeat;-webkit-box-shadow:0 0 12px #999999;-ms-box-shadow:0 0 12px #999999;box-shadow:0 0 12px #999;color:#fff;-ms-opacity:.9;opacity:.9;z-index:1000}::ng-deep .ag-cell .tru-control.list.in-cell .invalid-flag{display:none!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }] });
11184
11065
  }
11185
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruCloudFileManager, decorators: [{
11186
- type: Injectable,
11187
- args: [{
11188
- providedIn: 'root',
11189
- }]
11190
- }], ctorParameters: () => [{ type: TruAppEnvironment }, { type: TruUtil }, { type: TruUser }] });
11066
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruValidationDialog, decorators: [{
11067
+ type: Component,
11068
+ args: [{ selector: 'tru-validation-dialog', imports: [CommonModule, FormsModule], template: "@if (config.context === 0) {\r\n<div class=\"invalid hide\">\r\n <i class=\"icon-warning-sign icon-white\"></i>{{config.errorMsg}}\r\n <div *ngIf=\"config.mergeData\">\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAcceptAll()\">Accept All</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAccept()\">Accept</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onDecline()\">Decline</button>\r\n </div>\r\n</div>\r\n<span class=\"invalid-flag\"></span>\r\n}\r\n@else {\r\n<i class=\"icon-warning-sign icon-white\"></i>{{config.errorMsg}}\r\n<div *ngIf=\"config.mergeData\">\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAcceptAll()\">Accept All</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onAccept()\">Accept</button>\r\n <button class=\"md-primary md-button ng-scope md-ink-ripple merge-button\" (click)=\"onDecline()\">Decline</button>\r\n</div>\r\n}\r\n", styles: ["::ng-deep .tru-control.edit .mat-mdc-form-field .invalid,::ng-deep .tru-control.list .mat-mdc-form-field .invalid,::ng-deep .NgxEditor__Wrapper .invalid{position:absolute;left:0;top:24px;min-width:200px;min-height:20px;max-width:500px;max-height:500px;font-size:12px!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid.hide,::ng-deep .tru-control.list .mat-mdc-form-field .invalid.hide,::ng-deep .NgxEditor__Wrapper .invalid.hide{display:none!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid.show,::ng-deep .tru-control.list .mat-mdc-form-field .invalid.show,::ng-deep .NgxEditor__Wrapper .invalid.show{display:inline-block!important}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid-flag,::ng-deep .tru-control.list .mat-mdc-form-field .invalid-flag,::ng-deep .NgxEditor__Wrapper .invalid-flag{box-sizing:border-box;position:absolute;left:0;top:0;width:3px;height:3px;border-bottom:solid 3px transparent;border-right:solid 3px transparent;border-left:solid 3px red;border-top:solid 3px red}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid-triangle:after,::ng-deep .tru-control.list .mat-mdc-form-field .invalid-triangle:after{box-sizing:border-box}::ng-deep .tru-control.edit .mat-mdc-form-field .invalid,::ng-deep .tru-control.list .mat-mdc-form-field .invalid,::ng-deep .NgxEditor__Wrapper .invalid{background-color:#bd362f;margin:2px 0 0;padding:4px 10px;-ms-border-radius:3px 3px 3px 3px!important;border-radius:3px!important;background-position:15px center;background-repeat:no-repeat;-webkit-box-shadow:0 0 12px #999999;-ms-box-shadow:0 0 12px #999999;box-shadow:0 0 12px #999;color:#fff;-ms-opacity:.9;opacity:.9;z-index:1000}::ng-deep .merge-button,::ng-deep .NgxEditor__Wrapper .invalid .merge-button{margin:5px;font-size:12px;font-family:Calibri,Helvetica,Arial,sans-serif!important;background-color:#fff}::ng-deep .mat-mdc-form-field.invalid .mdc-line-ripple:before{border-bottom-color:red!important}::ng-deep .mat-mdc-form-field.invalid .mdc-line-ripple:after{border-bottom-color:red!important}.invalid{font-family:Calibri,Helvetica,Arial,sans-serif!important}i{line-height:24px!important}::ng-deep .ag-row .ag-cell-value .invalid{position:absolute;left:0;top:18px;-moz-min-width:200px;-ms-min-width:200px;-o-min-width:200px;-webkit-min-width:200px;min-width:200px;min-height:20px;max-width:500px;max-height:500px;font-size:12px}::ng-deep .ag-row .ag-cell-value.hide .invalid{display:none!important}::ng-deep .ag-row .ag-cell-value.show .invalid{display:inline-block!important}::ng-deep .ag-row .ag-cell-value.invalid.show{overflow:visible!important}::ng-deep .ag-row .ag-cell-value .invalid{background-color:#bd362f;margin:2px 0 0;padding:4px 10px;-ms-border-radius:3px 3px 3px 3px!important;border-radius:3px!important;background-position:15px center;background-repeat:no-repeat;-webkit-box-shadow:0 0 12px #999999;-ms-box-shadow:0 0 12px #999999;box-shadow:0 0 12px #999;color:#fff;-ms-opacity:.9;opacity:.9;z-index:1000}::ng-deep .ag-cell .tru-control.list.in-cell .invalid-flag{display:none!important}\n"] }]
11069
+ }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: TruUtil }], propDecorators: { config: [{
11070
+ type: Input
11071
+ }], close: [{
11072
+ type: Output
11073
+ }] } });
11191
11074
 
11192
- class TruFormatter {
11193
- appEnvironemt;
11194
- modelTypeLookup;
11195
- constructor(appEnvironemt, modelTypeLookup) {
11196
- this.appEnvironemt = appEnvironemt;
11197
- this.modelTypeLookup = modelTypeLookup;
11075
+ class TruValidationDialogConfig {
11076
+ _entity;
11077
+ _propertyConfig;
11078
+ _context;
11079
+ _isSubProperty;
11080
+ _ignore;
11081
+ _propertyName = '';
11082
+ _errorMsg = '';
11083
+ _mergeData = null;
11084
+ get entity() {
11085
+ return this._entity;
11198
11086
  }
11199
- formatDate = (date, format) => {
11200
- if (date === null)
11201
- return null;
11202
- if (!(date instanceof Date))
11203
- return '';
11204
- if (isNaN(date.getTime()))
11205
- return '';
11206
- var datePipe = new DatePipe('en-US');
11207
- return datePipe.transform(date, format);
11208
- };
11209
- isDate = (date) => {
11210
- if (Object.prototype.toString.call(date) === '[object Date]') {
11211
- if (isNaN(date.getTime())) {
11212
- return false;
11213
- }
11214
- else {
11215
- return true;
11087
+ get propertyConfig() {
11088
+ return this._propertyConfig;
11089
+ }
11090
+ get context() {
11091
+ return this._context;
11092
+ }
11093
+ get isSubProperty() {
11094
+ return this._isSubProperty;
11095
+ }
11096
+ get ignore() {
11097
+ return this._ignore;
11098
+ }
11099
+ get propertyName() {
11100
+ return this._propertyName;
11101
+ }
11102
+ set propertyName(value) {
11103
+ this._propertyName = value;
11104
+ }
11105
+ get errorMsg() {
11106
+ return this._errorMsg;
11107
+ }
11108
+ set errorMsg(value) {
11109
+ this._errorMsg = value;
11110
+ }
11111
+ get mergeData() {
11112
+ return this._mergeData;
11113
+ }
11114
+ set mergeData(value) {
11115
+ this._mergeData = value;
11116
+ }
11117
+ constructor(entity, propertyConfig, context = TruValidationDialogContext.Control, isSubProperty = false, ignore = false) {
11118
+ this._entity = entity;
11119
+ this._propertyConfig = propertyConfig;
11120
+ this._context = context;
11121
+ this._isSubProperty = isSubProperty;
11122
+ this._ignore = ignore;
11123
+ }
11124
+ }
11125
+
11126
+ class TruBreezeValidator {
11127
+ el;
11128
+ dataContext;
11129
+ viewContainerRef;
11130
+ componentFactoryResolver;
11131
+ entity;
11132
+ config;
11133
+ constructor(el, dataContext, viewContainerRef, componentFactoryResolver) {
11134
+ this.el = el;
11135
+ this.dataContext = dataContext;
11136
+ this.viewContainerRef = viewContainerRef;
11137
+ this.componentFactoryResolver = componentFactoryResolver;
11138
+ }
11139
+ configModel = {};
11140
+ mergeData;
11141
+ dialogRef = null;
11142
+ subs = [];
11143
+ currentDialog = null;
11144
+ context = TruValidationDialogContext.Control;
11145
+ getMergeData = () => {
11146
+ if (this.config.propertyPath?.includes('/')) {
11147
+ let propertyNameParts = this.config.propertyPath.split('/');
11148
+ propertyNameParts.pop();
11149
+ let targetProperty;
11150
+ propertyNameParts.forEach((name) => {
11151
+ if (!targetProperty) {
11152
+ let targetPropertyName = 'o' + name;
11153
+ targetProperty = this.entity[targetPropertyName];
11154
+ }
11155
+ else {
11156
+ let targetPropertyName = 'o' + name;
11157
+ targetProperty = targetProperty[targetPropertyName];
11158
+ }
11159
+ });
11160
+ if (targetProperty && targetProperty.Merge_Data) {
11161
+ return targetProperty.Merge_Data_Set;
11216
11162
  }
11217
- }
11218
- else if (moment$1(date, "MM/DD/YYYY", true).isValid()) {
11219
- return true;
11163
+ return undefined;
11220
11164
  }
11221
11165
  else {
11222
- return false;
11166
+ return this.entity.Merge_Data_Set?.get(this.config.propertyName) ? this.entity.Merge_Data_Set : undefined;
11223
11167
  }
11224
11168
  };
11225
- isPromise = function (value) {
11226
- return Boolean(value && typeof value.then === 'function');
11169
+ parseErrorMessages = (validationErrors) => {
11170
+ let errorMsg = '';
11171
+ validationErrors.forEach((error) => {
11172
+ errorMsg += error.errorMessage + '; ';
11173
+ });
11174
+ return errorMsg;
11227
11175
  };
11228
- //Filters
11229
- bigInteger = (cfg) => {
11230
- var v = cfg.$;
11231
- if (v === null)
11232
- return null;
11233
- return v;
11176
+ addValidationDialog = (config) => {
11177
+ let componentFactory = this.componentFactoryResolver.resolveComponentFactory(TruValidationDialog);
11178
+ let component = this.viewContainerRef.createComponent(componentFactory, 0, this.viewContainerRef.injector);
11179
+ component.instance.config = config;
11180
+ this.currentDialog = component;
11181
+ this.dialogRef = component;
11234
11182
  };
11235
- boolean = (cfg) => {
11236
- var v = cfg.$;
11237
- if (v === null)
11238
- return null;
11239
- return v ? 'True' : 'False';
11183
+ removeValidationDialog = () => {
11184
+ if (this.currentDialog) {
11185
+ this.currentDialog.destroy();
11186
+ this.currentDialog = null;
11187
+ }
11240
11188
  };
11241
- choiceLabel = (cfg) => {
11242
- if (cfg.$ === null)
11243
- return null;
11244
- if (cfg.type) {
11245
- var item = cfg.type.choices.filter(function (c) {
11246
- return c.$ === cfg.$;
11247
- });
11189
+ valErrsChanged = (validationObject) => {
11190
+ let validationObjectEntity = validationObject.entity;
11191
+ let validationTableName = validationObjectEntity.constructor.name;
11192
+ const entityPkeyName = validationTableName + 'Ref';
11193
+ const validationObjectEntitypkeyName = validationTableName + 'Ref';
11194
+ let propertyName = this.config.isSubProperty ? this.config.propertyName.replace(/\./g, "") : this.config.propertyName;
11195
+ let addedPropertyValdations = validationObject.added.filter((v) => {
11196
+ return v.propertyName === propertyName;
11197
+ });
11198
+ let removedPropertyValdations = validationObject.removed.filter((v) => {
11199
+ return v.propertyName === propertyName;
11200
+ });
11201
+ this.mergeData = this.getMergeData();
11202
+ if (this.config.rootTable === validationTableName &&
11203
+ this.entity[entityPkeyName] === validationObjectEntity[validationObjectEntitypkeyName] &&
11204
+ (addedPropertyValdations.length || this.mergeData)) {
11205
+ this.removeValidationDialog();
11206
+ let config = new TruValidationDialogConfig(this.entity, this.config);
11207
+ config.propertyName = this.config.propertyName;
11208
+ config.mergeData = this.mergeData;
11209
+ config.errorMsg = this.parseErrorMessages(addedPropertyValdations);
11210
+ this.addValidationDialog(config);
11248
11211
  }
11249
- else {
11250
- return cfg.$;
11212
+ if (this.config.rootTable === validationTableName &&
11213
+ this.entity[entityPkeyName] === validationObjectEntity[validationObjectEntitypkeyName] &&
11214
+ (removedPropertyValdations.length)) {
11215
+ this.removeValidationDialog();
11251
11216
  }
11252
- if (item.length == 0)
11253
- return null;
11254
- return item[0].label;
11255
11217
  };
11256
- dateShort = (cfg) => {
11257
- var v = cfg.$;
11258
- if (!v || !this.isDate(v))
11259
- return 'mm/dd/yyyy';
11260
- v = new Date(v);
11261
- var utc = new Date(v.getUTCFullYear(), v.getUTCMonth(), v.getUTCDate());
11262
- return this.formatDate(utc, 'MM/dd/yyyy');
11218
+ ngOnInit() { }
11219
+ ngAfterViewInit() {
11220
+ if (this.context !== TruValidationDialogContext.Grid) {
11221
+ this.subs.push(this.dataContext.validationChangeDetection.subscribe(entities => {
11222
+ this.valErrsChanged(entities);
11223
+ }));
11224
+ }
11225
+ this.entity.entityAspect.validateEntity();
11226
+ }
11227
+ ngOnChanges(changes) {
11228
+ this.removeValidationDialog();
11229
+ this.entity.entityAspect.validateEntity();
11230
+ }
11231
+ ngOnDestroy() {
11232
+ this.subs.forEach(s => s.unsubscribe());
11233
+ }
11234
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruBreezeValidator, deps: [{ token: i0.ElementRef }, { token: TruDataContext }, { token: i0.ViewContainerRef }, { token: i0.ComponentFactoryResolver }], target: i0.ɵɵFactoryTarget.Directive });
11235
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.3", type: TruBreezeValidator, isStandalone: true, selector: "[truBreezeValidator]", inputs: { entity: ["truBreezeValidator", "entity"], config: "config" }, usesOnChanges: true, ngImport: i0 });
11236
+ }
11237
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruBreezeValidator, decorators: [{
11238
+ type: Directive,
11239
+ args: [{
11240
+ selector: '[truBreezeValidator]'
11241
+ }]
11242
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: TruDataContext }, { type: i0.ViewContainerRef }, { type: i0.ComponentFactoryResolver }], propDecorators: { entity: [{
11243
+ type: Input,
11244
+ args: ['truBreezeValidator']
11245
+ }], config: [{
11246
+ type: Input
11247
+ }] } });
11248
+
11249
+ class TruSearchPanelPositionManager {
11250
+ el;
11251
+ renderer;
11252
+ config = { size: 300 };
11253
+ searchViewPortal = null;
11254
+ tab = null;
11255
+ dropZones = [];
11256
+ dragHandles = [];
11257
+ currentWidth = 0;
11258
+ currentMinWidth = 0;
11259
+ mouseOffsetX = 0;
11260
+ lastMouseX = 0;
11261
+ dragHandle = null;
11262
+ listeners = [];
11263
+ mousemoveListener;
11264
+ mouseupListener;
11265
+ constructor(el, renderer) {
11266
+ this.el = el;
11267
+ this.renderer = renderer;
11268
+ }
11269
+ ngAfterViewInit() {
11270
+ this.searchViewPortal = this.el.nativeElement.closest('.search-container');
11271
+ this.tab = this.el.nativeElement.querySelectorAll('.search-panel-tab')[0];
11272
+ this.dropZones = this.searchViewPortal?.querySelectorAll('.search-panel-dropzone');
11273
+ this.dragHandles = this.el.nativeElement.querySelectorAll('.search-panel-resizable-handle');
11274
+ this.addTabEventListeners();
11275
+ this.addDropzoneEventListeners();
11276
+ this.addDragHandleEventListeners();
11277
+ }
11278
+ addTabEventListeners = () => {
11279
+ this.listeners.push(this.renderer.listen(this.tab, 'dragstart', this.dragStart));
11280
+ this.listeners.push(this.renderer.listen(this.tab, 'dragend', this.dragEnd));
11263
11281
  };
11264
- datetimeShort = (cfg) => {
11265
- var v = cfg.$;
11266
- if (!v)
11267
- return 'mm/dd/yyyy hh:mm a';
11268
- return this.formatDate(v, 'MM/dd/yyyy hh:mm a');
11282
+ addDropzoneEventListeners = () => {
11283
+ this.dropZones.forEach((dropZone) => {
11284
+ this.listeners.push(this.renderer.listen(dropZone, 'dragover', this.dragOver));
11285
+ this.listeners.push(this.renderer.listen(dropZone, 'dragleave', this.dragLeave));
11286
+ this.listeners.push(this.renderer.listen(dropZone, 'drop', this.drop));
11287
+ });
11269
11288
  };
11270
- datetimespanShort = (cfg) => {
11271
- var start = cfg.start.$;
11272
- var end = cfg.end.$;
11273
- var text = '';
11274
- if (start !== null) {
11275
- text = this.formatDate(start, 'MM/dd/yyyy hh:mm a') + ' - ';
11276
- if (end != null) {
11277
- if (start.getYear() === end.getYear() && start.getMonth() === end.getMonth() && start.getDay() === end.getDay())
11278
- text += this.formatDate(end, 'hh:mm a');
11279
- else
11280
- text += this.formatDate(end, 'MM/dd/yyyy hh:mm a');
11281
- }
11282
- }
11283
- else {
11284
- if (end !== null)
11285
- text += this.formatDate(end, 'MM/dd/yyyy hh:mm a');
11286
- }
11287
- return text;
11289
+ addDragHandleEventListeners = () => {
11290
+ this.dragHandles.forEach((dropHandle) => {
11291
+ this.listeners.push(this.renderer.listen(dropHandle, 'mousedown', this.mousedown));
11292
+ });
11288
11293
  };
11289
- decimal = (cfg) => {
11290
- var v = cfg.$;
11291
- if (v === null)
11292
- return null;
11293
- return v;
11294
+ addPointerEvents = () => {
11295
+ this.dropZones.forEach((dropZone) => {
11296
+ dropZone.style.pointerEvents = 'all';
11297
+ });
11294
11298
  };
11295
- excelFormula = (val) => {
11296
- if (_.isNaN(val))
11297
- return '#VALUE!';
11298
- if (val === Infinity)
11299
- return '#DIV/0!';
11300
- return val;
11299
+ removePointerEvents = () => {
11300
+ this.dropZones.forEach((dropZone) => {
11301
+ dropZone.style.pointerEvents = 'none';
11302
+ });
11301
11303
  };
11302
- file = (cfg) => {
11303
- if (this.isPromise(cfg.filename.$))
11304
- return null;
11305
- var text = '';
11306
- if (cfg.filename.$ !== null)
11307
- text += cfg.filename.$;
11308
- return text;
11304
+ addMouseoverDropzoneStyles = (event) => {
11305
+ event.target.classList.add('mouseover');
11309
11306
  };
11310
- float = (cfg) => {
11311
- var v = cfg.$;
11312
- if (v === null)
11313
- return null;
11314
- return v;
11307
+ removeMouseoverDropzoneStyles = (event) => {
11308
+ for (var i = 0; i < this.dropZones.length; i++) {
11309
+ if (event.target !== this.dropZones[i])
11310
+ this.dropZones[i].classList.remove('mouseover');
11311
+ }
11315
11312
  };
11316
- id = (value) => {
11317
- if (!value)
11318
- return null;
11319
- return value;
11313
+ dragStart = (event) => {
11314
+ this.addPointerEvents();
11320
11315
  };
11321
- integer = (cfg) => {
11322
- var v = cfg.$;
11323
- if (v === null)
11324
- return null;
11325
- return v;
11316
+ dragEnd = (event) => {
11317
+ this.removePointerEvents();
11318
+ this.removeMouseoverDropzoneStyles(event);
11326
11319
  };
11327
- intlAddress = (cfg) => {
11328
- var text = '';
11329
- if (cfg.address1.$ !== null)
11330
- text += cfg.address1.$ + ' ';
11331
- if (cfg.address2.$ !== null)
11332
- text += cfg.address2.$ + ' ';
11333
- if (cfg.country.$ !== null)
11334
- text += cfg.country.$ + ' ';
11335
- if (cfg.city.$ !== null)
11336
- text += cfg.city.$ + ' ';
11337
- if (cfg.stateProvince.$ !== null)
11338
- text += cfg.stateProvince.$ + ' ';
11339
- if (cfg.postalCode.$ !== null)
11340
- text += cfg.postalCode.$ + ' ';
11341
- return text;
11320
+ dragOver = (event) => {
11321
+ event.preventDefault();
11322
+ this.addMouseoverDropzoneStyles(event);
11342
11323
  };
11343
- intlAddressBasic = (cfg) => {
11344
- var text = '';
11345
- if (cfg.address1.$ !== null)
11346
- text += cfg.address1.$ + ' ';
11347
- if (cfg.address2.$ !== null)
11348
- text += cfg.address2.$ + ' ';
11349
- if (cfg.country.$ !== null)
11350
- text += cfg.country.$ + ' ';
11351
- if (cfg.city.$ !== null)
11352
- text += cfg.city.$ + ' ';
11353
- if (cfg.stateProvince.$ !== null)
11354
- text += cfg.stateProvince.$ + ' ';
11355
- if (cfg.postalCode.$ !== null)
11356
- text += cfg.postalCode.$ + ' ';
11357
- return text;
11324
+ dragLeave = (event) => {
11325
+ event.target.classList.remove('mouseover');
11358
11326
  };
11359
- naPhone = (number) => {
11360
- if (!number) {
11361
- return '';
11362
- }
11363
- if (number) {
11364
- if (number.$)
11365
- number = number.$.replace(/[^0-9]/g, '');
11366
- else
11367
- number = number.$;
11368
- }
11369
- if (!number) {
11370
- return '';
11371
- }
11372
- number = String(number);
11373
- var formattedNumber = number;
11374
- var c = (number[0] == '1') ? '+1 ' : '';
11375
- number = number[0] == '1' ? number.slice(1) : number;
11376
- var area = number.substring(0, 3);
11377
- var front = number.substring(3, 6);
11378
- var end = number.substring(6, 10);
11379
- var ext = number.substring(10, 20);
11380
- if (front) {
11381
- formattedNumber = (c + "(" + area + ") " + front);
11382
- }
11383
- if (end) {
11384
- formattedNumber += ("-" + end);
11327
+ drop = (event) => {
11328
+ if (event.target.classList.contains('left')) {
11329
+ this.config.side = 'left';
11330
+ this.config.setGridPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
11331
+ this.config.setToolbarPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
11332
+ //userPreference.set(userPreference.searchPanelSide, 'left');
11385
11333
  }
11386
- if (ext) {
11387
- formattedNumber += (" x" + ext);
11334
+ if (event.target.classList.contains('right')) {
11335
+ this.config.side = 'right';
11336
+ this.config.setGridPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
11337
+ this.config.setToolbarPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
11338
+ //userPreference.set(userPreference.searchPanelSide, 'right');
11388
11339
  }
11389
- return formattedNumber;
11390
- };
11391
- intlPhone = (cfg) => {
11392
- var field = cfg;
11393
- var text = '';
11394
- //if (cfg.countryCode.$ !== null) {
11395
- // var country = _.find(countries.allCountries, function (country) { return country.iso2 === cfg.countryCode.$ });
11396
- // var dialCode = country.dialCode;
11397
- // text += '+' + dialCode + ' ';
11398
- //}
11399
- //if (cfg.phone.$ !== null) {
11400
- // var clean = cfg.phone.$.replace(/[^0-9]/g, '');
11401
- // try {
11402
- // var countryCode = cfg.countryCode.$ ? cfg.countryCode.$ : field.property.countryCode;
11403
- // var number = clean;
11404
- // text += number + ' ';
11405
- // } catch (e) {
11406
- // text += clean + ' ';
11407
- // }
11408
- //}
11409
- //if (cfg.extension.$ !== null)
11410
- // text += ' x' + cfg.extension.$;
11411
- return text;
11412
- };
11413
- password = (cfg) => {
11414
- var v = cfg.$;
11415
- if (v === null)
11416
- return null;
11417
- if (v.length > 0)
11418
- return '********';
11419
- return '';
11420
- };
11421
- percentage = (cfg) => {
11422
- var v = cfg.$;
11423
- if (typeof v === 'undefined')
11424
- return undefined;
11425
- if (v === null)
11426
- return null;
11427
- if (typeof v.toFixed === 'function')
11428
- return (v * 100).toFixed(2) + '%';
11429
- return v;
11430
- };
11431
- picture = (cfg) => {
11432
- var text = '';
11433
- if (cfg.filename.$ !== null)
11434
- text += cfg.filename.$;
11435
- return text;
11436
- };
11437
- ref = (cfg) => {
11438
- var v = cfg.$;
11439
- if (v === null)
11440
- return null;
11441
- return v.toString();
11442
- };
11443
- richText = (cfg) => {
11444
- return cfg.$;
11340
+ this.removeMouseoverDropzoneStyles(event);
11445
11341
  };
11446
- socialSecurityNumber = (cfg) => {
11447
- var v = cfg.$;
11448
- if (v === null)
11449
- return null;
11450
- return v.substring(0, 3) + '-' + v.substring(3, 5) + '-' + v.substring(5);
11342
+ mousedown = (event) => {
11343
+ if (this.config.pinned)
11344
+ return;
11345
+ if (!this.dragHandle)
11346
+ this.dragHandle = event.target;
11347
+ this.mouseOffsetX = event.clientX;
11348
+ this.mousemoveListener = this.renderer.listen('document', 'mousemove', this.mouseMove);
11349
+ this.mouseupListener = this.renderer.listen('document', 'mouseup', this.mouseUp);
11451
11350
  };
11452
- text = (cfg) => {
11453
- return cfg.$;
11351
+ mouseMove = (event) => {
11352
+ var mouseX = event.pageX - this.mouseOffsetX;
11353
+ var diffX = mouseX - this.lastMouseX;
11354
+ this.lastMouseX = mouseX;
11355
+ this.currentWidth = this.config.size;
11356
+ this.currentMinWidth = 100;
11357
+ if (this.dragHandle?.classList.contains('search-panel-resizable-w')) {
11358
+ if (this.currentWidth - diffX < this.currentMinWidth)
11359
+ this.mouseOffsetX = this.mouseOffsetX - (diffX - (diffX = this.currentWidth - this.currentMinWidth));
11360
+ this.config.size = (this.currentWidth - diffX);
11361
+ this.updateSide();
11362
+ }
11363
+ if (this.dragHandle?.classList.contains('search-panel-resizable-e')) {
11364
+ if (this.currentWidth + diffX < this.currentMinWidth)
11365
+ this.mouseOffsetX = this.mouseOffsetX - (diffX - (diffX = this.currentMinWidth - this.currentWidth));
11366
+ this.config.size = (this.currentWidth + diffX);
11367
+ this.updateSide();
11368
+ }
11454
11369
  };
11455
- textFormatting = (text) => {
11456
- if (!text)
11457
- return text;
11458
- if (typeof text.replace === 'function')
11459
- return text.replace(/[\n\r]+/g, ' ').replace(/\s{2,}/g, ' ').replace(/^\s+|\s+$/, '');
11460
- return text;
11370
+ mouseUp = () => {
11371
+ this.dragHandle = null;
11372
+ this.mouseOffsetX = 0;
11373
+ this.lastMouseX = 0;
11374
+ this.mousemoveListener();
11375
+ this.mouseupListener();
11461
11376
  };
11462
- timeShort = (cfg) => {
11463
- var v = cfg.$;
11464
- if (v === null)
11465
- return null;
11466
- var duration = moment$1.duration(v);
11467
- var datetime = new Date('01/01/1999 ' + duration.hours + ':' + duration.minutes + ':' + duration.seconds);
11468
- var datePipe = new DatePipe('en-US');
11469
- return datePipe.transform(datetime, 'hh:mm a');
11377
+ updateSide = () => {
11378
+ //if (this.config.side === 'left') {
11379
+ // this.config.setGridPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
11380
+ // this.config.setToolbarPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
11381
+ //}
11382
+ //if (this.config.side === 'right') {
11383
+ // this.config.setGridPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
11384
+ // this.config.setToolbarPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
11385
+ //}
11470
11386
  };
11471
- timeSpanHhMmSs = (cfg) => {
11472
- return cfg.hours.$ + ' H, ' + cfg.minutes.$ + ' M, ' + cfg.seconds.$ + '.' + cfg.milliseconds.$ + ' S';
11387
+ ngOnDestroy() {
11388
+ this.listeners.forEach(fn => fn());
11389
+ }
11390
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruSearchPanelPositionManager, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
11391
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.3", type: TruSearchPanelPositionManager, isStandalone: true, selector: "[truSearchPanelPositionManager]", inputs: { config: "config" }, ngImport: i0 });
11392
+ }
11393
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruSearchPanelPositionManager, decorators: [{
11394
+ type: Directive,
11395
+ args: [{
11396
+ selector: '[truSearchPanelPositionManager]'
11397
+ }]
11398
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { config: [{
11399
+ type: Input
11400
+ }] } });
11401
+
11402
+ class TruCloudFileManager {
11403
+ appEnvironment;
11404
+ util;
11405
+ user;
11406
+ baseUrl;
11407
+ reader;
11408
+ file;
11409
+ sliceSize = 10000 * 1024;
11410
+ constructor(appEnvironment, util, user) {
11411
+ this.appEnvironment = appEnvironment;
11412
+ this.util = util;
11413
+ this.user = user;
11414
+ this.baseUrl = this.appEnvironment.appUri;
11415
+ }
11416
+ getFileLength = (blobId, temp) => {
11417
+ return Observable.create((observer) => {
11418
+ let xhr = new XMLHttpRequest();
11419
+ xhr.onreadystatechange = function () {
11420
+ if (xhr.readyState == XMLHttpRequest.DONE) {
11421
+ if (xhr.status == 200) {
11422
+ observer.next(xhr.response);
11423
+ }
11424
+ else {
11425
+ console.log('Download Failed. Unable to acquire file size.');
11426
+ }
11427
+ }
11428
+ };
11429
+ xhr.open('POST', this.baseUrl + '/api/CloudFile/BlobLength', true);
11430
+ xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11431
+ xhr.send(JSON.stringify({
11432
+ blobId: blobId,
11433
+ temp: temp ? true : false
11434
+ }));
11435
+ });
11473
11436
  };
11474
- usaAddress = (cfg) => {
11475
- let text = "Loading...";
11476
- let buildText = () => {
11477
- text = '';
11478
- if (cfg.address1.$ !== null)
11479
- text += cfg.address1.$ + ' ';
11480
- if (cfg.address2.$ !== null)
11481
- text += cfg.address2.$ + ' ';
11482
- if (cfg.city.$ !== null)
11483
- text += cfg.city.$ + ' ';
11484
- if (cfg.state.$ !== null) {
11485
- var state = this.appEnvironemt.globalDataContext?.entityAccess().searchByRefCacheOnly(this.modelTypeLookup.getType('StdUSAState'), cfg.state.$);
11486
- if (state)
11487
- text += state.Code + ', ';
11488
- }
11489
- if (cfg.zip.$ !== null) {
11490
- if (cfg.zip.$.length > 5)
11491
- text += cfg.zip.$.substring(0, 5) + '-' + cfg.zip.$.substring(5);
11492
- else
11493
- text += cfg.zip.$;
11437
+ uploadFile = (start, tableName, propertyName, filename, blobMetaData, temp, updateProgress, done) => {
11438
+ let nextSlice = start + this.sliceSize + 1;
11439
+ let blob = this.file?.slice(start, nextSlice);
11440
+ this.reader.onloadend = (event) => {
11441
+ if (event.target?.readyState !== FileReader.DONE) {
11442
+ return;
11494
11443
  }
11495
- return text;
11444
+ let xhr = new XMLHttpRequest();
11445
+ xhr.onreadystatechange = () => {
11446
+ if (xhr.readyState == XMLHttpRequest.DONE) {
11447
+ if (xhr.status == 200) {
11448
+ var sizeDone = start + this.sliceSize;
11449
+ var percentDone = Math.floor((sizeDone / this.file.size) * 100);
11450
+ var blobMetaData = JSON.parse(xhr.response);
11451
+ if (nextSlice < this.file?.size) {
11452
+ updateProgress(percentDone);
11453
+ console.log('Uploading File - ' + percentDone + '%');
11454
+ this.uploadFile(nextSlice, tableName, propertyName, filename, blobMetaData, temp, updateProgress, done);
11455
+ }
11456
+ else {
11457
+ done(blobMetaData.truDbCloudFileRef);
11458
+ }
11459
+ }
11460
+ else {
11461
+ console.log(xhr.responseType);
11462
+ }
11463
+ }
11464
+ };
11465
+ xhr.open('POST', this.baseUrl + '/api/CloudFile/Upload', true);
11466
+ xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11467
+ xhr.send(JSON.stringify({
11468
+ tableName: tableName,
11469
+ propertyName: propertyName,
11470
+ fileData: event.target.result.split(',')[1],
11471
+ filename: filename,
11472
+ blobId: blobMetaData.blobId,
11473
+ blobBlockIdStr: blobMetaData.blobBlockIdStr,
11474
+ createdRef: this.user.activeUserRef,
11475
+ public: false,
11476
+ temp: temp ? true : false,
11477
+ commit: nextSlice < this.file.size ? false : true
11478
+ }));
11496
11479
  };
11497
- if (this.appEnvironemt.globalDataContext?.entityAccess().searchByRefCacheOnly(this.modelTypeLookup.getType('StdUSAState'), cfg.state.$)) {
11498
- return buildText();
11499
- }
11500
- return null;
11501
- };
11502
- usaDollars = (cfg) => {
11503
- var v = cfg.$;
11504
- if (v === null)
11505
- return null;
11506
- return '$' + (v)?.toFixed(2);
11507
- };
11508
- usaSocialSecurity = (cfg) => {
11509
- var v = cfg.$;
11510
- if (v === null)
11511
- return null;
11512
- return v.substring(0, 3) + '-' + v.substring(3, 5) + '-' + v.substring(5);
11513
- };
11514
- usaZip = (cfg) => {
11515
- var v = cfg.$;
11516
- if (v === null)
11517
- return null;
11518
- if (v.length > 5)
11519
- return v.substring(0, 5) + '-' + v.substring(5);
11520
- return v;
11480
+ this.reader.readAsDataURL(blob);
11521
11481
  };
11522
- zipCode = (cfg) => {
11523
- var v = cfg.$;
11524
- if (v === null)
11525
- return null;
11526
- if (v.length > 5)
11527
- return v.substring(0, 5) + '-' + v.substring(5);
11528
- return v;
11482
+ upload = (tableName, propertyName, fileData, temp, updateProgress, done) => {
11483
+ this.reader = new FileReader();
11484
+ this.file = fileData;
11485
+ this.uploadFile(0, tableName, propertyName, this.file.name, { blobId: null, blobBlockIdStr: null }, temp, updateProgress, done);
11529
11486
  };
11530
- passwordEightBullets = (cfg) => {
11531
- var v = cfg.$;
11532
- return v;
11487
+ download = (blobId, temp, filename, updateProgress, done) => {
11488
+ this.getFileLength(blobId, temp).subscribe((fileLength) => {
11489
+ var xhr = new XMLHttpRequest();
11490
+ xhr.onprogress = function (e) {
11491
+ updateProgress(Math.round(e.loaded / e.total * 100));
11492
+ };
11493
+ xhr.onload = function () {
11494
+ //var fileName = xhr.getResponseHeader('Content-Disposition').split("filename=")[1];
11495
+ var blob = new Blob([xhr.response], { type: 'application/octet-stream' });
11496
+ var a = document.createElement('a');
11497
+ a.href = URL.createObjectURL(blob);
11498
+ a.download = filename;
11499
+ document.body.appendChild(a);
11500
+ a.dispatchEvent(new MouseEvent('click'));
11501
+ done();
11502
+ };
11503
+ xhr.onerror = function (e) {
11504
+ done();
11505
+ console.log(e);
11506
+ };
11507
+ xhr.ontimeout = function (e) {
11508
+ done();
11509
+ console.log(e);
11510
+ };
11511
+ xhr.open('POST', this.baseUrl + '/api/CloudFile/Download');
11512
+ xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11513
+ xhr.responseType = 'arraybuffer';
11514
+ xhr.send(JSON.stringify({
11515
+ blobId: blobId,
11516
+ filename: filename,
11517
+ fileLength: parseInt(fileLength),
11518
+ temp: temp ? true : false
11519
+ }));
11520
+ });
11533
11521
  };
11534
- formulaJsonParser = (formatter, data) => {
11535
- var json = JSON.parse(data);
11536
- if (json.DATA || (typeof json.DATA === 'number' && isFinite(json.DATA)))
11537
- return formatter({ $: json.DATA });
11538
- return { $: json.Error_Message };
11522
+ sasUrl = (blobId, temp, filename, updateProgress, done) => {
11523
+ var xhr = new XMLHttpRequest();
11524
+ xhr.onprogress = function (e) { };
11525
+ xhr.onload = function () {
11526
+ done(xhr.response);
11527
+ };
11528
+ xhr.onerror = function (e) {
11529
+ done(undefined);
11530
+ console.log(e);
11531
+ };
11532
+ xhr.ontimeout = function (e) {
11533
+ done(undefined);
11534
+ console.log(e);
11535
+ };
11536
+ xhr.open('POST', this.baseUrl + '/api/CloudFile/SASTokenURL');
11537
+ xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11538
+ xhr.responseType = 'text';
11539
+ xhr.send(JSON.stringify({
11540
+ blobId: blobId
11541
+ }));
11539
11542
  };
11540
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruFormatter, deps: [{ token: TruAppEnvironment }, { token: TruModelTypeLookup }], target: i0.ɵɵFactoryTarget.Injectable });
11541
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruFormatter, providedIn: 'root' });
11543
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruCloudFileManager, deps: [{ token: TruAppEnvironment }, { token: TruUtil }, { token: TruUser }], target: i0.ɵɵFactoryTarget.Injectable });
11544
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruCloudFileManager, providedIn: 'root' });
11542
11545
  }
11543
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruFormatter, decorators: [{
11546
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruCloudFileManager, decorators: [{
11544
11547
  type: Injectable,
11545
11548
  args: [{
11546
11549
  providedIn: 'root',
11547
11550
  }]
11548
- }], ctorParameters: () => [{ type: TruAppEnvironment }, { type: TruModelTypeLookup }] });
11551
+ }], ctorParameters: () => [{ type: TruAppEnvironment }, { type: TruUtil }, { type: TruUser }] });
11549
11552
 
11550
11553
  class TruPredicateMap {
11551
11554
  constructor() { }