@trudb/tru-common-lib 0.2.168 → 0.2.170

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,198 +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
- return value;
5976
- };
5977
- copyCell = async (params, tableName, columnName, copiedCellData, copiedCellEntity) => {
5978
- this.tableName = tableName;
5979
- this.columnName = columnName;
5980
- this.copiedCellParams = params;
5981
- this.copiedCellData = copiedCellData;
5982
- this.copiedCellEntity = copiedCellEntity;
5983
- try {
5984
- await navigator.clipboard.writeText(params.value);
5985
- }
5986
- catch (err) {
5987
- console.error('Failed to copy text: ', err);
5988
- }
5989
- };
5990
- pasteCell = (params, pastedCellData, pastedCell) => {
5991
- let colDef = params.colDef;
5992
- let columnName = colDef.field;
5993
- let copiedCellDataTypeName = this.copiedCellData[this.copiedCellParams?.colDef?.field].property.typeName;
5994
- let pastedCellDataTypeName = pastedCellData[params.colDef?.field].property.typeName;
5995
- if (!colDef.editable) {
5996
- this.uiNotification.error('Cannot paste into a non-editable column: ' + colDef.field);
5997
- return;
5998
- }
5999
- if (copiedCellDataTypeName !== pastedCellDataTypeName) {
6000
- this.uiNotification.error('Clipboard data type does not match the current cell data type: ' + copiedCellDataTypeName + ' vs ' + pastedCellDataTypeName);
6001
- return;
6002
- }
6003
- else {
6004
- pastedCell.setProperty(columnName, this.copiedCellEntity?.getProperty(columnName));
6005
- params.api.refreshCells({ force: true });
6006
- }
5969
+ if (isNaN(date.getTime()))
5970
+ return '';
5971
+ var datePipe = new DatePipe('en-US');
5972
+ return datePipe.transform(date, format);
6007
5973
  };
6008
- copyRow = async (tableName, copiedRows) => {
6009
- this.tableName = tableName;
6010
- this.copiedRows = copiedRows;
6011
- if (copiedRows.length) {
6012
- let multiRowString = '';
6013
- this.copiedRows.forEach((copiedRow, index) => {
6014
- let rowPropertyValues = [];
6015
- let properties = copiedRow.$entity.entityType.getPropertyNames();
6016
- properties
6017
- .forEach((propertyName) => {
6018
- let propertyConfig = copiedRow[propertyName]?.property;
6019
- if (propertyConfig &&
6020
- propertyName !== tableName + 'Ref' &&
6021
- propertyName !== 'rowver' &&
6022
- propertyName !== 'Merge_Data_Set' &&
6023
- !propertyName.startsWith('o'))
6024
- rowPropertyValues.push(this.formatCellValue(copiedRow[propertyName].property, copiedRow.$entity.getProperty(propertyName)));
6025
- });
6026
- multiRowString += rowPropertyValues.join('\t') + '\n';
6027
- });
6028
- try {
6029
- 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;
6030
5978
  }
6031
- catch (err) {
6032
- console.error('Failed to copy text: ', err);
5979
+ else {
5980
+ return true;
6033
5981
  }
6034
5982
  }
6035
- };
6036
- pasteRow = (gridApi, config, selectedRows) => {
6037
- if (this.tableName !== config.tableName) {
6038
- this.uiNotification.error('Clipboard data does not match the current table name: ' + this.tableName + ' vs ' + config.tableName);
6039
- return;
6040
- }
6041
- if (selectedRows && selectedRows.length !== this.copiedRows.length) {
6042
- this.uiNotification.error('Clipboard data does not match the number of selected rows: ' + this.copiedRows.length + ' vs ' + selectedRows.length);
6043
- return;
5983
+ else if (moment$1(date, "MM/DD/YYYY", true).isValid()) {
5984
+ return true;
6044
5985
  }
6045
- if (this.copiedRows.length) {
6046
- this.copiedRows.forEach((copiedRow, index) => {
6047
- let selectedRow = selectedRows[index];
6048
- let properties = copiedRow.$entity.entityType.getPropertyNames();
6049
- properties
6050
- .forEach((propertyName) => {
6051
- if (typeof selectedRow.$entity.setProperty !== 'undefined' &&
6052
- selectedRow[propertyName] && selectedRow[propertyName].property.canEdit &&
6053
- propertyName !== config.tableName + 'Ref' &&
6054
- propertyName !== 'rowver' &&
6055
- propertyName !== 'Merge_Data_Set' &&
6056
- !propertyName.startsWith('o'))
6057
- selectedRow.$entity.setProperty(propertyName, copiedRow.$entity.getProperty(propertyName));
6058
- });
6059
- });
6060
- gridApi.refreshCells({ force: true });
5986
+ else {
5987
+ return false;
6061
5988
  }
6062
5989
  };
6063
- insertRowsAtTop = (dataContext, config, addEntity) => {
6064
- if (this.tableName !== config.tableName) {
6065
- this.uiNotification.error('Clipboard data does not match the current table name: ' + this.tableName + ' vs ' + config.tableName);
6066
- return;
6067
- }
6068
- if (this.copiedRows.length) {
6069
- this.copiedRows.forEach((row) => {
6070
- let newEntity = dataContext.entityAccess().add(config.resultConfig.entityType);
6071
- let properties = row.entityType.getPropertyNames();
6072
- properties
6073
- .filter((propertyName) => {
6074
- return propertyName !== 'Ref' &&
6075
- propertyName !== config.resultConfig.entityType.name + 'Ref' &&
6076
- !this.util.isLowerCase(propertyName.charAt(0));
6077
- })
6078
- .forEach((propertyName) => {
6079
- if (typeof newEntity.setProperty !== 'undefined')
6080
- newEntity.setProperty(propertyName, row.getProperty(propertyName));
6081
- });
6082
- addEntity(newEntity, false);
6083
- });
6084
- }
5990
+ isPromise = function (value) {
5991
+ return Boolean(value && typeof value.then === 'function');
6085
5992
  };
6086
- getCopiedRows = () => {
6087
- return this.copiedRows;
5993
+ //Filters
5994
+ bigInteger = (cfg) => {
5995
+ var v = cfg.$;
5996
+ if (v === null)
5997
+ return null;
5998
+ return v;
6088
5999
  };
6089
- getCopiedCell = () => {
6090
- return this.copiedCellEntity;
6000
+ boolean = (cfg) => {
6001
+ var v = cfg.$;
6002
+ if (v === null)
6003
+ return null;
6004
+ return v ? 'True' : 'False';
6091
6005
  };
6092
- 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 });
6093
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruDataGridClipboard, providedIn: 'root' });
6094
- }
6095
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruDataGridClipboard, decorators: [{
6096
- type: Injectable,
6097
- args: [{
6098
- providedIn: 'root',
6099
- }]
6100
- }], ctorParameters: () => [{ type: TruUtil }, { type: TruUiNotification }] });
6101
-
6102
- class TruDataGridPkeyCellRenderer {
6103
- dataContext;
6104
- dataGridClipboard;
6105
- contextMenu;
6106
- // private eGui: is an empty element to satisfy the getGui method.
6107
- eGui;
6108
- windowClickSubscription;
6109
- params;
6110
- contextMenuPosition = { x: '0px', y: '0px' };
6111
- displayValue = '';
6112
- copyIsDisabled = true;
6113
- pasteIsDisabled = true;
6114
- insertAtTopIsDisabled = true;
6115
- constructor(dataContext, dataGridClipboard) {
6116
- this.dataContext = dataContext;
6117
- this.dataGridClipboard = dataGridClipboard;
6118
- }
6119
- onRightClick = (event) => {
6120
- event.preventDefault();
6121
- this.copyIsDisabled = this.params.api.getSelectedRows().length ? false : true;
6122
- this.pasteIsDisabled = this.dataGridClipboard.getCopiedRows().length && this.params.api.getSelectedRows().length ? false : true;
6123
- this.insertAtTopIsDisabled = this.dataGridClipboard.getCopiedRows().length && this.params.api.getSelectedRows().length ? false : true;
6124
- this.contextMenuPosition.x = event.pageX + 'px';
6125
- this.contextMenuPosition.y = (event.pageY) + 'px';
6126
- this.contextMenu.menu?.focusFirstItem('mouse');
6127
- 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;
6128
6020
  };
6129
- 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');
6130
6028
  };
6131
- 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');
6132
6034
  };
6133
- onCopy = (event) => {
6134
- let selectedRows = this.params.api.getSelectedRows();
6135
- if (selectedRows.length) {
6136
- let copiedRowData = selectedRows;
6137
- 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
+ }
6138
6047
  }
6048
+ else {
6049
+ if (end !== null)
6050
+ text += this.formatDate(end, 'MM/dd/yyyy hh:mm a');
6051
+ }
6052
+ return text;
6139
6053
  };
6140
- onPaste = (event) => {
6141
- this.dataGridClipboard.pasteRow(this.params.api, this.params.context.grid.config, this.params.api.getSelectedRows());
6142
- };
6143
- onInsertAtTop = (event) => {
6144
- 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;
6145
6059
  };
6146
- agInit(params) {
6147
- this.params = params;
6148
- 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)
6149
6512
  this.displayValue = 'NEW';
6150
6513
  else
6151
6514
  this.displayValue = params.value;
@@ -10109,1441 +10472,1083 @@ class TruServerError {
10109
10472
  else {
10110
10473
  this.id = parsedError.$id;
10111
10474
  this.type = parsedError.$type;
10112
- this.code = parsedError.Code;
10113
- this.message = parsedError.Message;
10114
- this.stackTrace = parsedError.StackTrace;
10115
- this.status = error.status;
10116
- this.statusText = error.statusText;
10117
- }
10118
- }
10119
- }
10120
-
10121
- class TruErrorManager {
10122
- http;
10123
- dialog;
10124
- textManager;
10125
- uiNotification;
10126
- componentLookup;
10127
- componentFactoryResolver;
10128
- appRef;
10129
- injector;
10130
- appEnvironment;
10131
- baseUrl;
10132
- appName;
10133
- constructor(http, dialog, textManager, uiNotification, componentLookup, componentFactoryResolver, appRef, injector, appEnvironment) {
10134
- this.http = http;
10135
- this.dialog = dialog;
10136
- this.textManager = textManager;
10137
- this.uiNotification = uiNotification;
10138
- this.componentLookup = componentLookup;
10139
- this.componentFactoryResolver = componentFactoryResolver;
10140
- this.appRef = appRef;
10141
- this.injector = injector;
10142
- this.appEnvironment = appEnvironment;
10143
- this.baseUrl = appEnvironment.appUri;
10144
- this.appName = appEnvironment.appName;
10145
- }
10146
- handleClientSideError = (error) => {
10147
- };
10148
- handleServerSideError = (error) => {
10149
- let serverError = new TruServerError(error);
10150
- if (serverError.type === 'tru-db-custom-exception') {
10151
- var component = this.componentLookup.get(serverError.componentName);
10152
- this.dialog.open(component, {
10153
- disableClose: true,
10154
- minWidth: "400px",
10155
- maxWidth: "600px",
10156
- data: serverError
10157
- });
10158
- }
10159
- else if (serverError.type.indexOf('TruDbRequireValidChoiceException') !== -1) {
10160
- let dialogConfig = new TruErrorDialogConfig('Require Valid Choice Exception', error.message, serverError.stackTrace);
10161
- this.dialog.open(TruErrorDialog, {
10162
- disableClose: true,
10163
- minWidth: "400px",
10164
- maxWidth: "600px",
10165
- data: dialogConfig
10166
- });
10167
- }
10168
- else if (serverError.type.indexOf('DuplicateKeyError') !== -1) {
10169
- let dialogConfig = new TruErrorDialogConfig('Duplicate Key Error', error.message
10170
- .replace('Cannot insert duplicate key row in object', 'Cannot insert duplicate value in table')
10171
- .replace('dbo.', '')
10172
- .replace('UIX_', '')
10173
- .replace('The statement has been terminated.', ''), serverError.stackTrace);
10174
- this.dialog.open(TruErrorDialog, {
10175
- disableClose: true,
10176
- minWidth: "400px",
10177
- maxWidth: "600px",
10178
- data: dialogConfig
10179
- });
10180
- }
10181
- else if (serverError.type.indexOf('OptimisticLockViolation') !== -1) {
10182
- let dialogConfig = new TruErrorDialogConfig('Concurrent saves not allowed', 'Please review any changes and save again.', serverError.stackTrace);
10183
- this.dialog.open(TruErrorDialog, {
10184
- disableClose: true,
10185
- minWidth: "400px",
10186
- maxWidth: "600px",
10187
- data: dialogConfig
10188
- });
10189
- }
10190
- else if (serverError.type.lastIndexOf('TruDB.EfMssql.Runtime.DataError', 0) === 0) {
10191
- this.uiNotification.error(this.textManager.fmtDataError(serverError.type), [this.textManager.fmtExceptionToShow(serverError.stackTrace)]);
10192
- }
10193
- else {
10194
- var message = this.textManager.fmtErrorToShow(serverError);
10195
- let dialogConfig = new TruErrorDialogConfig(serverError.type, serverError.message, serverError.stackTrace);
10196
- this.dialog.open(TruErrorDialog, {
10197
- disableClose: true,
10198
- minWidth: "400px",
10199
- maxWidth: "600px",
10200
- data: dialogConfig
10201
- });
10202
- }
10203
- };
10204
- handleError = (error) => {
10205
- if (error.type)
10206
- this.handleClientSideError(error);
10207
- else
10208
- this.handleServerSideError(error);
10209
- };
10210
- 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 });
10211
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorManager, providedIn: 'root' });
10212
- }
10213
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorManager, decorators: [{
10214
- type: Injectable,
10215
- args: [{
10216
- providedIn: 'root',
10217
- }]
10218
- }], ctorParameters: () => [{ type: i2.HttpClient }, { type: i1.MatDialog }, { type: TruTextManager }, { type: TruUiNotification }, { type: TruComponentLookup }, { type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }, { type: TruAppEnvironment }] });
10219
-
10220
- class TruErrorInterceptor {
10221
- errorManager;
10222
- constructor(errorManager) {
10223
- this.errorManager = errorManager;
10224
- }
10225
- intercept(request, next) {
10226
- return next.handle(request).pipe(catchError((error) => {
10227
- if (error.status !== 401 && !(error.error instanceof Blob))
10228
- this.errorManager.handleError(error);
10229
- return next.handle(request);
10230
- }));
10231
- }
10232
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorInterceptor, deps: [{ token: TruErrorManager }], target: i0.ɵɵFactoryTarget.Injectable });
10233
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorInterceptor });
10234
- }
10235
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorInterceptor, decorators: [{
10236
- type: Injectable
10237
- }], ctorParameters: () => [{ type: TruErrorManager }] });
10238
-
10239
- class TruColumn {
10240
- constructor() { }
10241
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruColumn, deps: [], target: i0.ɵɵFactoryTarget.Component });
10242
- 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 }] });
10243
- }
10244
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruColumn, decorators: [{
10245
- type: Component,
10246
- 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"] }]
10247
- }], ctorParameters: () => [] });
10248
-
10249
- class TruForm {
10250
- element;
10251
- constructor(element) {
10252
- this.element = element;
10253
- }
10254
- ngAfterViewInit() {
10255
- this.updateLayout();
10256
- }
10257
- updateLayout = () => {
10258
- let rowComponentElements = this.element.nativeElement.querySelectorAll('.tvl-container-hList');
10259
- rowComponentElements.forEach((rowComponentElement) => {
10260
- var numberOfItems = rowComponentElement.children.length;
10261
- var childWidth = 100 / numberOfItems;
10262
- [...rowComponentElement.children].forEach((rowChildElement, index) => {
10263
- if (index === numberOfItems - 1) {
10264
- rowChildElement.style['width'] = 'calc(' + childWidth + '% - 10px)';
10265
- }
10266
- else {
10267
- rowChildElement.style['width'] = 'calc(' + childWidth + '% - 5px)';
10268
- }
10269
- if (index > 0)
10270
- rowChildElement.style['margin-left'] = '5px';
10271
- });
10272
- });
10273
- };
10274
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruForm, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
10275
- 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 }] });
10276
- }
10277
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruForm, decorators: [{
10278
- type: Component,
10279
- 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"] }]
10280
- }], ctorParameters: () => [{ type: i0.ElementRef }] });
10281
-
10282
- class TruGroupBox {
10283
- constructor() { }
10284
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruGroupBox, deps: [], target: i0.ɵɵFactoryTarget.Component });
10285
- 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 }] });
10286
- }
10287
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruGroupBox, decorators: [{
10288
- type: Component,
10289
- args: [{ selector: 'tru-group-box', imports: [CommonModule, FormsModule], template: "<div>\r\n <ng-content></ng-content>\r\n</div>\r\n" }]
10290
- }], ctorParameters: () => [] });
10291
-
10292
- class TruRow {
10293
- constructor() { }
10294
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruRow, deps: [], target: i0.ɵɵFactoryTarget.Component });
10295
- 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 }] });
10296
- }
10297
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruRow, decorators: [{
10298
- type: Component,
10299
- 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" }]
10300
- }], ctorParameters: () => [] });
10301
-
10302
- class TruTab {
10303
- tabGroupEventNotifier;
10304
- view;
10305
- label;
10306
- matTab;
10307
- constructor(tabGroupEventNotifier) {
10308
- this.tabGroupEventNotifier = tabGroupEventNotifier;
10309
- }
10310
- notifyListeners = (isActive) => {
10311
- this.tabGroupEventNotifier.isActive = isActive;
10312
- };
10313
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTab, deps: [{ token: TruTabGroupEventNotifier }], target: i0.ɵɵFactoryTarget.Component });
10314
- 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 });
10315
- }
10316
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTab, decorators: [{
10317
- type: Component,
10318
- 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" }]
10319
- }], ctorParameters: () => [{ type: TruTabGroupEventNotifier }], propDecorators: { view: [{
10320
- type: Input
10321
- }], label: [{
10322
- type: Input
10323
- }], matTab: [{
10324
- type: ViewChild,
10325
- args: [MatTab]
10326
- }] } });
10327
-
10328
- class TruTabGroup {
10329
- tabGroup;
10330
- tabs;
10331
- constructor() { }
10332
- ngAfterViewInit() {
10333
- const matTabsFromQueryList = this.tabs.map((tab) => tab.matTab);
10334
- const list = new QueryList();
10335
- list.reset([matTabsFromQueryList]);
10336
- this.tabGroup._tabs = list;
10337
- }
10338
- onChange(event) {
10339
- const selectedTabLabel = event.tab.textLabel;
10340
- this.tabs.forEach((tab) => {
10341
- if (selectedTabLabel === tab.label) {
10342
- tab.notifyListeners(true);
10343
- }
10344
- else {
10345
- tab.notifyListeners(false);
10346
- }
10347
- });
10348
- }
10349
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTabGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
10350
- 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 });
10351
- }
10352
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruTabGroup, decorators: [{
10353
- type: Component,
10354
- 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" }]
10355
- }], ctorParameters: () => [], propDecorators: { tabGroup: [{
10356
- type: ViewChild,
10357
- args: [MatTabGroup]
10358
- }], tabs: [{
10359
- type: ContentChildren,
10360
- args: [TruTab]
10361
- }] } });
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
+ }
10362
10483
 
10363
- class TruLogin {
10364
- auth;
10484
+ class TruErrorManager {
10485
+ http;
10486
+ dialog;
10487
+ textManager;
10488
+ uiNotification;
10489
+ componentLookup;
10490
+ componentFactoryResolver;
10491
+ appRef;
10492
+ injector;
10365
10493
  appEnvironment;
10366
- loginForm = new FormGroup({
10367
- username: new FormControl('', Validators.required),
10368
- password: new FormControl('', Validators.required)
10369
- });
10370
- loginError = "";
10371
- isLoggingIn = false;
10372
- title;
10373
- constructor(auth, appEnvironment) {
10374
- 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;
10375
10505
  this.appEnvironment = appEnvironment;
10376
- this.title = appEnvironment.loginFormTitle;
10377
- }
10378
- get f() {
10379
- return this.loginForm.controls;
10506
+ this.baseUrl = appEnvironment.appUri;
10507
+ this.appName = appEnvironment.appName;
10380
10508
  }
10381
- isDisabled = () => {
10382
- return !this.f.username.value || !this.f.password.value || this.isLoggingIn;
10509
+ handleClientSideError = (error) => {
10383
10510
  };
10384
- onSubmit() {
10385
- const loginRequest = {
10386
- username: this.f.username.value,
10387
- password: this.f.password.value
10388
- };
10389
- if (loginRequest.username && loginRequest.password) {
10390
- this.isLoggingIn = true;
10391
- this.auth
10392
- .login(loginRequest).pipe(finalize(() => {
10393
- this.isLoggingIn = false;
10394
- }))
10395
- .subscribe(() => {
10396
- this.isLoggingIn = false;
10397
- }, (error) => {
10398
- if (error.status === 401) {
10399
- this.loginError = "Incorrect username and/or password";
10400
- }
10401
- else {
10402
- this.loginError = "Invalid Login - Error: " + error.status;
10403
- }
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
10404
10520
  });
10405
10521
  }
10406
- }
10407
- 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 });
10408
- 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"] }] });
10409
- }
10410
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLogin, decorators: [{
10411
- type: Component,
10412
- 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"] }]
10413
- }], ctorParameters: () => [{ type: TruAuth }, { type: TruAppEnvironment }] });
10414
-
10415
- class TruAuthJwtStrategy {
10416
- JWT_ACCESS_TOKEN = "ACCESS_TOKEN";
10417
- JWT_REFRESH_TOKEN = "REFRESH_TOKEN";
10418
- doLoginUser(token) {
10419
- localStorage.setItem(this.JWT_ACCESS_TOKEN, JSON.stringify(token.accessToken));
10420
- localStorage.setItem(this.JWT_REFRESH_TOKEN, JSON.stringify(token.refreshToken));
10421
- }
10422
- doLogoutUser() {
10423
- localStorage.removeItem(this.JWT_ACCESS_TOKEN);
10424
- }
10425
- isLoggedIn() {
10426
- return !!this.getJwtToken();
10427
- }
10428
- createUser(user) {
10429
- let jwtData = this.getDecodedJwtJsonData();
10430
- console.log(jwtData);
10431
- let userData = {
10432
- activeUserRef: jwtData.UserRef,
10433
- firstName: jwtData.FirstName,
10434
- lastName: jwtData.LastName,
10435
- email: jwtData.Email,
10436
- username: jwtData['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name'],
10437
- roles: jwtData['http://schemas.microsoft.com/ws/2008/06/identity/claims/role']
10438
- };
10439
- return of(user.create(userData));
10440
- }
10441
- getJwtToken() {
10442
- try {
10443
- 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
+ });
10444
10530
  }
10445
- catch (e) {
10446
- 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
+ });
10447
10543
  }
10448
- }
10449
- getDecodedJwtJsonData() {
10450
- let token = this.getJwtToken();
10451
- let payload = {};
10452
- if (token && token !== "undefined") {
10453
- const encodedPayload = token.split(".")[1];
10454
- const payloadStr = window.atob(encodedPayload);
10455
- 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
+ });
10456
10552
  }
10457
- return payload;
10458
- }
10459
- getToken() {
10460
- var token = this.getJwtToken();
10461
- if (token && token !== "undefined") {
10462
- const encodedPayload = token.split(".")[1];
10463
- const payloadStr = window.atob(encodedPayload);
10464
- var payload = JSON.parse(payloadStr);
10465
- var exp = payload["exp"];
10466
- var d = new Date();
10467
- var epoch = Math.round(d.getTime() / 1000);
10468
- if (exp < epoch) {
10469
- localStorage.removeItem(this.JWT_ACCESS_TOKEN);
10470
- return null;
10471
- }
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)]);
10472
10555
  }
10473
- return token;
10474
- }
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' });
10475
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 }] });
10476
10582
 
10477
- class TruAuthInterceptor {
10478
- auth;
10479
- appEnvironment;
10480
- jwt;
10481
- constructor(auth, appEnvironment, jwt) {
10482
- this.auth = auth;
10483
- this.appEnvironment = appEnvironment;
10484
- this.jwt = jwt;
10583
+ class TruErrorInterceptor {
10584
+ errorManager;
10585
+ constructor(errorManager) {
10586
+ this.errorManager = errorManager;
10485
10587
  }
10486
10588
  intercept(request, next) {
10487
- if (this.appEnvironment.authType === 'jwt')
10488
- request = this.addToken(request, String(this.jwt.getToken()));
10489
- if (this.appEnvironment.authType === 'session')
10490
- request = request.clone({
10491
- withCredentials: true
10492
- });
10493
10589
  return next.handle(request).pipe(catchError((error) => {
10494
- if (error.status === 401) {
10495
- this.auth.doLogoutAndRedirectToLogin();
10496
- }
10497
- return throwError(error);
10498
- }));
10499
- }
10500
- addToken(request, token) {
10501
- return request.clone({
10502
- setHeaders: { Authorization: `Bearer ${token}` },
10503
- });
10504
- }
10505
- 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 });
10506
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruAuthInterceptor });
10507
- }
10508
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruAuthInterceptor, decorators: [{
10509
- type: Injectable
10510
- }], ctorParameters: () => [{ type: TruAuth }, { type: TruAppEnvironment }, { type: TruAuthJwtStrategy, decorators: [{
10511
- type: Inject,
10512
- args: [TRU_AUTH_STRATEGY]
10513
- }] }] });
10514
-
10515
- class TruAuthSessionStrategy {
10516
- http;
10517
- loggedUser;
10518
- constructor(http) {
10519
- this.http = http;
10520
- }
10521
- doLoginUser(user) {
10522
- this.loggedUser = user;
10523
- }
10524
- doLogoutUser() {
10525
- this.loggedUser = undefined;
10526
- }
10527
- createUser(user) {
10528
- return of({});
10529
- }
10530
- isLoggedIn() {
10531
- 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
+ }));
10532
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 });
10533
10597
  }
10598
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruErrorInterceptor, decorators: [{
10599
+ type: Injectable
10600
+ }], ctorParameters: () => [{ type: TruErrorManager }] });
10534
10601
 
10535
- const TruAuthStrategyProvider = {
10536
- provide: TRU_AUTH_STRATEGY,
10537
- deps: [HttpClient, TruAppEnvironment],
10538
- useFactory: (http, appEnvironment) => {
10539
- switch (appEnvironment.authType) {
10540
- case "session":
10541
- return new TruAuthSessionStrategy(http);
10542
- case "jwt":
10543
- return new TruAuthJwtStrategy();
10544
- default:
10545
- throw new Error("Invalid auth strategy");
10546
- }
10547
- },
10548
- };
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: () => [] });
10549
10611
 
10550
- const routes = [
10551
- {
10552
- path: 'login',
10553
- component: TruLogin
10612
+ class TruForm {
10613
+ element;
10614
+ constructor(element) {
10615
+ this.element = element;
10554
10616
  }
10555
- ];
10556
- class TruLoginModule {
10557
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
10558
- 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] });
10559
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, providers: [
10560
- {
10561
- provide: HTTP_INTERCEPTORS,
10562
- useClass: TruAuthInterceptor,
10563
- multi: true,
10564
- },
10565
- {
10566
- provide: HTTP_INTERCEPTORS,
10567
- useClass: TruErrorInterceptor,
10568
- multi: true,
10569
- },
10570
- TruAuthStrategyProvider
10571
- ], 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 }] });
10572
10639
  }
10573
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, decorators: [{
10574
- type: NgModule,
10575
- args: [{
10576
- declarations: [TruLogin],
10577
- imports: [CommonModule, MaterialModule, FormsModule, ReactiveFormsModule, RouterModule.forChild(routes)],
10578
- exports: [TruLogin],
10579
- providers: [
10580
- {
10581
- provide: HTTP_INTERCEPTORS,
10582
- useClass: TruAuthInterceptor,
10583
- multi: true,
10584
- },
10585
- {
10586
- provide: HTTP_INTERCEPTORS,
10587
- useClass: TruErrorInterceptor,
10588
- multi: true,
10589
- },
10590
- TruAuthStrategyProvider
10591
- ],
10592
- }]
10593
- }] });
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 }] });
10594
10644
 
10595
- var TruValidationDialogContext;
10596
- (function (TruValidationDialogContext) {
10597
- TruValidationDialogContext[TruValidationDialogContext["Control"] = 0] = "Control";
10598
- TruValidationDialogContext[TruValidationDialogContext["Grid"] = 1] = "Grid";
10599
- TruValidationDialogContext[TruValidationDialogContext["Card"] = 2] = "Card";
10600
- })(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: () => [] });
10601
10654
 
10602
- class TruValidationDialog {
10603
- renderer;
10604
- elementRef;
10605
- util;
10606
- config;
10607
- close = new EventEmitter();
10608
- errorMsg = '';
10609
- rowElement;
10610
- cellElement;
10611
- listeners = [];
10612
- constructor(renderer, elementRef, util) {
10613
- this.renderer = renderer;
10614
- this.elementRef = elementRef;
10615
- 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;
10616
10672
  }
10617
- onAcceptAll = () => {
10618
- let entity = this.config.entity;
10619
- let originalValues = entity.entityAspect.originalValues;
10620
- for (const key in this.config.mergeData?.getAll()) {
10621
- entity[key] = this.config.mergeData?.get(key).value;
10622
- if (originalValues.hasOwnProperty(key))
10623
- delete originalValues[key];
10624
- }
10625
- ;
10626
- if (Object.keys(originalValues).length === 0 && originalValues.constructor === Object)
10627
- entity.entityAspect.setUnchanged();
10628
- entity.Merge_Data_Set.clearAll();
10629
- entity.entityAspect.validateEntity();
10630
- if (this.config.context === TruValidationDialogContext.Grid)
10631
- this.elementRef.nativeElement.remove();
10632
- };
10633
- onAccept = () => {
10634
- let entity = this.config.entity;
10635
- let originalValues = entity.entityAspect.originalValues;
10636
- let propertyName = this.config.propertyName;
10637
- entity[propertyName] = this.config.mergeData?.get(propertyName).value;
10638
- this.config.mergeData?.clear(propertyName);
10639
- if (originalValues.hasOwnProperty(propertyName) && (Object.keys(originalValues).length === 0 && originalValues.constructor === Object))
10640
- delete originalValues[propertyName];
10641
- if (this.config.mergeData?.isEmpty())
10642
- entity.entityAspect.setUnchanged();
10643
- entity.entityAspect.validateEntity();
10644
- if (this.config.context === TruValidationDialogContext.Grid)
10645
- this.elementRef.nativeElement.remove();
10646
- };
10647
- onDecline = () => {
10648
- let entity = this.config.entity;
10649
- this.config.mergeData?.clearAll();
10650
- entity.entityAspect.validateEntity();
10651
- if (this.config.context === TruValidationDialogContext.Grid)
10652
- this.elementRef.nativeElement.remove();
10673
+ notifyListeners = (isActive) => {
10674
+ this.tabGroupEventNotifier.isActive = isActive;
10653
10675
  };
10654
- ngOnInit() {
10655
- this.errorMsg = this.config.errorMsg;
10656
- if (this.config.context === TruValidationDialogContext.Control) {
10657
- var invalidTarget = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.invalid-target');
10658
- if (invalidTarget) {
10659
- this.listeners.push(this.renderer.listen(invalidTarget, 'mouseenter', (event) => {
10660
- this.elementRef.nativeElement.childNodes[0].classList.remove('hide');
10661
- this.elementRef.nativeElement.childNodes[0].classList.add('show');
10662
- }));
10663
- this.listeners.push(this.renderer.listen(invalidTarget, 'mouseleave', (event) => {
10664
- this.elementRef.nativeElement.childNodes[0].classList.remove('show');
10665
- this.elementRef.nativeElement.childNodes[0].classList.add('hide');
10666
- }));
10667
- }
10668
- }
10669
- else if (this.config.context === TruValidationDialogContext.Grid) {
10670
- this.rowElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-row');
10671
- this.cellElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-cell-value');
10672
- this.rowElement.style.zIndex = '10000000000';
10673
- this.cellElement.classList.add('show');
10674
- this.errorMsg = this.config.errorMsg;
10675
- }
10676
- }
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() { }
10677
10695
  ngAfterViewInit() {
10678
- if (this.config.context === TruValidationDialogContext.Control) {
10679
- let invalidTarget = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.invalid-target');
10680
- if (invalidTarget)
10681
- invalidTarget.classList.add('invalid');
10682
- }
10696
+ const matTabsFromQueryList = this.tabs.map((tab) => tab.matTab);
10697
+ const list = new QueryList();
10698
+ list.reset([matTabsFromQueryList]);
10699
+ this.tabGroup._tabs = list;
10683
10700
  }
10684
- ngOnDestroy() {
10685
- if (this.config.context === TruValidationDialogContext.Control) {
10686
- let invalidTarget = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.invalid-target');
10687
- if (invalidTarget)
10688
- invalidTarget.classList.remove('invalid');
10689
- }
10690
- else if (this.config.context === TruValidationDialogContext.Grid) {
10691
- this.rowElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-row');
10692
- this.cellElement = this.util.findClosestAncestorByClass(this.elementRef.nativeElement, '.ag-cell-value');
10693
- if (this.rowElement)
10694
- this.rowElement.style.zIndex = 'auto';
10695
- if (this.cellElement)
10696
- this.cellElement.classList.remove('show');
10697
- }
10698
- 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
+ });
10699
10711
  }
10700
- 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 });
10701
- 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 });
10702
10714
  }
10703
- 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: [{
10704
10716
  type: Component,
10705
- 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"] }]
10706
- }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: TruUtil }], propDecorators: { config: [{
10707
- type: Input
10708
- }], close: [{
10709
- 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]
10710
10724
  }] } });
10711
10725
 
10712
- class TruValidationDialogConfig {
10713
- _entity;
10714
- _propertyConfig;
10715
- _context;
10716
- _isSubProperty;
10717
- _ignore;
10718
- _propertyName = '';
10719
- _errorMsg = '';
10720
- _mergeData = null;
10721
- get entity() {
10722
- return this._entity;
10723
- }
10724
- get propertyConfig() {
10725
- return this._propertyConfig;
10726
- }
10727
- get context() {
10728
- return this._context;
10729
- }
10730
- get isSubProperty() {
10731
- return this._isSubProperty;
10732
- }
10733
- get ignore() {
10734
- return this._ignore;
10735
- }
10736
- get propertyName() {
10737
- return this._propertyName;
10738
- }
10739
- set propertyName(value) {
10740
- this._propertyName = value;
10741
- }
10742
- get errorMsg() {
10743
- return this._errorMsg;
10744
- }
10745
- set errorMsg(value) {
10746
- this._errorMsg = value;
10747
- }
10748
- get mergeData() {
10749
- return this._mergeData;
10750
- }
10751
- set mergeData(value) {
10752
- this._mergeData = value;
10753
- }
10754
- constructor(entity, propertyConfig, context = TruValidationDialogContext.Control, isSubProperty = false, ignore = false) {
10755
- this._entity = entity;
10756
- this._propertyConfig = propertyConfig;
10757
- this._context = context;
10758
- this._isSubProperty = isSubProperty;
10759
- 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;
10760
10740
  }
10761
- }
10762
-
10763
- class TruBreezeValidator {
10764
- el;
10765
- dataContext;
10766
- viewContainerRef;
10767
- componentFactoryResolver;
10768
- entity;
10769
- config;
10770
- constructor(el, dataContext, viewContainerRef, componentFactoryResolver) {
10771
- this.el = el;
10772
- this.dataContext = dataContext;
10773
- this.viewContainerRef = viewContainerRef;
10774
- this.componentFactoryResolver = componentFactoryResolver;
10741
+ get f() {
10742
+ return this.loginForm.controls;
10775
10743
  }
10776
- configModel = {};
10777
- mergeData;
10778
- dialogRef = null;
10779
- subs = [];
10780
- currentDialog = null;
10781
- context = TruValidationDialogContext.Control;
10782
- getMergeData = () => {
10783
- if (this.config.propertyPath?.includes('/')) {
10784
- let propertyNameParts = this.config.propertyPath.split('/');
10785
- propertyNameParts.pop();
10786
- let targetProperty;
10787
- propertyNameParts.forEach((name) => {
10788
- if (!targetProperty) {
10789
- let targetPropertyName = 'o' + name;
10790
- 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";
10791
10763
  }
10792
10764
  else {
10793
- let targetPropertyName = 'o' + name;
10794
- targetProperty = targetProperty[targetPropertyName];
10765
+ this.loginError = "Invalid Login - Error: " + error.status;
10795
10766
  }
10796
10767
  });
10797
- if (targetProperty && targetProperty.Merge_Data) {
10798
- return targetProperty.Merge_Data_Set;
10799
- }
10800
- return undefined;
10801
- }
10802
- else {
10803
- return this.entity.Merge_Data_Set?.get(this.config.propertyName) ? this.entity.Merge_Data_Set : undefined;
10804
10768
  }
10805
- };
10806
- parseErrorMessages = (validationErrors) => {
10807
- let errorMsg = '';
10808
- validationErrors.forEach((error) => {
10809
- errorMsg += error.errorMessage + '; ';
10810
- });
10811
- return errorMsg;
10812
- };
10813
- addValidationDialog = (config) => {
10814
- let componentFactory = this.componentFactoryResolver.resolveComponentFactory(TruValidationDialog);
10815
- let component = this.viewContainerRef.createComponent(componentFactory, 0, this.viewContainerRef.injector);
10816
- component.instance.config = config;
10817
- this.currentDialog = component;
10818
- this.dialogRef = component;
10819
- };
10820
- removeValidationDialog = () => {
10821
- if (this.currentDialog) {
10822
- this.currentDialog.destroy();
10823
- 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));
10824
10807
  }
10825
- };
10826
- valErrsChanged = (validationObject) => {
10827
- let validationObjectEntity = validationObject.entity;
10828
- let validationTableName = validationObjectEntity.constructor.name;
10829
- const entityPkeyName = validationTableName + 'Ref';
10830
- const validationObjectEntitypkeyName = validationTableName + 'Ref';
10831
- let propertyName = this.config.isSubProperty ? this.config.propertyName.replace(/\./g, "") : this.config.propertyName;
10832
- let addedPropertyValdations = validationObject.added.filter((v) => {
10833
- return v.propertyName === propertyName;
10834
- });
10835
- let removedPropertyValdations = validationObject.removed.filter((v) => {
10836
- return v.propertyName === propertyName;
10837
- });
10838
- this.mergeData = this.getMergeData();
10839
- if (this.config.rootTable === validationTableName &&
10840
- this.entity[entityPkeyName] === validationObjectEntity[validationObjectEntitypkeyName] &&
10841
- (addedPropertyValdations.length || this.mergeData)) {
10842
- this.removeValidationDialog();
10843
- let config = new TruValidationDialogConfig(this.entity, this.config);
10844
- config.propertyName = this.config.propertyName;
10845
- config.mergeData = this.mergeData;
10846
- config.errorMsg = this.parseErrorMessages(addedPropertyValdations);
10847
- this.addValidationDialog(config);
10808
+ catch (e) {
10809
+ return null;
10848
10810
  }
10849
- if (this.config.rootTable === validationTableName &&
10850
- this.entity[entityPkeyName] === validationObjectEntity[validationObjectEntitypkeyName] &&
10851
- (removedPropertyValdations.length)) {
10852
- 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);
10853
10819
  }
10854
- };
10855
- ngOnInit() { }
10856
- ngAfterViewInit() {
10857
- if (this.context !== TruValidationDialogContext.Grid) {
10858
- this.subs.push(this.dataContext.validationChangeDetection.subscribe(entities => {
10859
- this.valErrsChanged(entities);
10860
- }));
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
+ }
10861
10835
  }
10862
- this.entity.entityAspect.validateEntity();
10836
+ return token;
10863
10837
  }
10864
- ngOnChanges(changes) {
10865
- this.removeValidationDialog();
10866
- 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;
10867
10848
  }
10868
- ngOnDestroy() {
10869
- 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
+ }));
10870
10862
  }
10871
- 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 });
10872
- 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 });
10873
10870
  }
10874
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruBreezeValidator, decorators: [{
10875
- type: Directive,
10876
- args: [{
10877
- selector: '[truBreezeValidator]'
10878
- }]
10879
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: TruDataContext }, { type: i0.ViewContainerRef }, { type: i0.ComponentFactoryResolver }], propDecorators: { entity: [{
10880
- type: Input,
10881
- args: ['truBreezeValidator']
10882
- }], config: [{
10883
- type: Input
10884
- }] } });
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
+ }] }] });
10885
10877
 
10886
- class TruSearchPanelPositionManager {
10887
- el;
10888
- renderer;
10889
- config = { size: 300 };
10890
- searchViewPortal = null;
10891
- tab = null;
10892
- dropZones = [];
10893
- dragHandles = [];
10894
- currentWidth = 0;
10895
- currentMinWidth = 0;
10896
- mouseOffsetX = 0;
10897
- lastMouseX = 0;
10898
- dragHandle = null;
10899
- listeners = [];
10900
- mousemoveListener;
10901
- mouseupListener;
10902
- constructor(el, renderer) {
10903
- this.el = el;
10904
- this.renderer = renderer;
10878
+ class TruAuthSessionStrategy {
10879
+ http;
10880
+ loggedUser;
10881
+ constructor(http) {
10882
+ this.http = http;
10905
10883
  }
10906
- ngAfterViewInit() {
10907
- this.searchViewPortal = this.el.nativeElement.closest('.search-container');
10908
- this.tab = this.el.nativeElement.querySelectorAll('.search-panel-tab')[0];
10909
- this.dropZones = this.searchViewPortal?.querySelectorAll('.search-panel-dropzone');
10910
- this.dragHandles = this.el.nativeElement.querySelectorAll('.search-panel-resizable-handle');
10911
- this.addTabEventListeners();
10912
- this.addDropzoneEventListeners();
10913
- this.addDragHandleEventListeners();
10884
+ doLoginUser(user) {
10885
+ this.loggedUser = user;
10914
10886
  }
10915
- addTabEventListeners = () => {
10916
- this.listeners.push(this.renderer.listen(this.tab, 'dragstart', this.dragStart));
10917
- this.listeners.push(this.renderer.listen(this.tab, 'dragend', this.dragEnd));
10918
- };
10919
- addDropzoneEventListeners = () => {
10920
- this.dropZones.forEach((dropZone) => {
10921
- this.listeners.push(this.renderer.listen(dropZone, 'dragover', this.dragOver));
10922
- this.listeners.push(this.renderer.listen(dropZone, 'dragleave', this.dragLeave));
10923
- this.listeners.push(this.renderer.listen(dropZone, 'drop', this.drop));
10924
- });
10925
- };
10926
- addDragHandleEventListeners = () => {
10927
- this.dragHandles.forEach((dropHandle) => {
10928
- this.listeners.push(this.renderer.listen(dropHandle, 'mousedown', this.mousedown));
10929
- });
10930
- };
10931
- addPointerEvents = () => {
10932
- this.dropZones.forEach((dropZone) => {
10933
- dropZone.style.pointerEvents = 'all';
10934
- });
10935
- };
10936
- removePointerEvents = () => {
10937
- this.dropZones.forEach((dropZone) => {
10938
- dropZone.style.pointerEvents = 'none';
10939
- });
10940
- };
10941
- addMouseoverDropzoneStyles = (event) => {
10942
- event.target.classList.add('mouseover');
10943
- };
10944
- removeMouseoverDropzoneStyles = (event) => {
10945
- for (var i = 0; i < this.dropZones.length; i++) {
10946
- if (event.target !== this.dropZones[i])
10947
- this.dropZones[i].classList.remove('mouseover');
10948
- }
10949
- };
10950
- dragStart = (event) => {
10951
- this.addPointerEvents();
10952
- };
10953
- dragEnd = (event) => {
10954
- this.removePointerEvents();
10955
- this.removeMouseoverDropzoneStyles(event);
10956
- };
10957
- dragOver = (event) => {
10958
- event.preventDefault();
10959
- this.addMouseoverDropzoneStyles(event);
10960
- };
10961
- dragLeave = (event) => {
10962
- event.target.classList.remove('mouseover');
10963
- };
10964
- drop = (event) => {
10965
- if (event.target.classList.contains('left')) {
10966
- this.config.side = 'left';
10967
- this.config.setGridPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
10968
- this.config.setToolbarPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
10969
- //userPreference.set(userPreference.searchPanelSide, 'left');
10970
- }
10971
- if (event.target.classList.contains('right')) {
10972
- this.config.side = 'right';
10973
- this.config.setGridPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
10974
- this.config.setToolbarPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
10975
- //userPreference.set(userPreference.searchPanelSide, 'right');
10976
- }
10977
- this.removeMouseoverDropzoneStyles(event);
10978
- };
10979
- mousedown = (event) => {
10980
- if (this.config.pinned)
10981
- return;
10982
- if (!this.dragHandle)
10983
- this.dragHandle = event.target;
10984
- this.mouseOffsetX = event.clientX;
10985
- this.mousemoveListener = this.renderer.listen('document', 'mousemove', this.mouseMove);
10986
- this.mouseupListener = this.renderer.listen('document', 'mouseup', this.mouseUp);
10987
- };
10988
- mouseMove = (event) => {
10989
- var mouseX = event.pageX - this.mouseOffsetX;
10990
- var diffX = mouseX - this.lastMouseX;
10991
- this.lastMouseX = mouseX;
10992
- this.currentWidth = this.config.size;
10993
- this.currentMinWidth = 100;
10994
- if (this.dragHandle?.classList.contains('search-panel-resizable-w')) {
10995
- if (this.currentWidth - diffX < this.currentMinWidth)
10996
- this.mouseOffsetX = this.mouseOffsetX - (diffX - (diffX = this.currentWidth - this.currentMinWidth));
10997
- this.config.size = (this.currentWidth - diffX);
10998
- this.updateSide();
10999
- }
11000
- if (this.dragHandle?.classList.contains('search-panel-resizable-e')) {
11001
- if (this.currentWidth + diffX < this.currentMinWidth)
11002
- this.mouseOffsetX = this.mouseOffsetX - (diffX - (diffX = this.currentMinWidth - this.currentWidth));
11003
- this.config.size = (this.currentWidth + diffX);
11004
- 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");
11005
10909
  }
11006
- };
11007
- mouseUp = () => {
11008
- this.dragHandle = null;
11009
- this.mouseOffsetX = 0;
11010
- this.lastMouseX = 0;
11011
- this.mousemoveListener();
11012
- this.mouseupListener();
11013
- };
11014
- updateSide = () => {
11015
- //if (this.config.side === 'left') {
11016
- // this.config.setGridPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
11017
- // this.config.setToolbarPinnedPositionFn({ 'position': 'absolute', 'width': 'calc(100% - ' + (this.config.size - 20) + 'px', 'left': (this.config.size - 20) + 'px', 'margin-left': 'auto' });
11018
- //}
11019
- //if (this.config.side === 'right') {
11020
- // this.config.setGridPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
11021
- // this.config.setToolbarPinnedPositionFn({ 'width': 'calc(100% - ' + (this.config.size - 20) + 'px' });
11022
- //}
11023
- };
11024
- ngOnDestroy() {
11025
- this.listeners.forEach(fn => fn());
10910
+ },
10911
+ };
10912
+
10913
+ const routes = [
10914
+ {
10915
+ path: 'login',
10916
+ component: TruLogin
11026
10917
  }
11027
- 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 });
11028
- 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)] });
11029
10935
  }
11030
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruSearchPanelPositionManager, decorators: [{
11031
- type: Directive,
10936
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruLoginModule, decorators: [{
10937
+ type: NgModule,
11032
10938
  args: [{
11033
- 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
+ ],
11034
10955
  }]
11035
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { config: [{
11036
- type: Input
11037
- }] } });
10956
+ }] });
11038
10957
 
11039
- class TruCloudFileManager {
11040
- 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;
11041
10968
  util;
11042
- user;
11043
- baseUrl;
11044
- reader;
11045
- file;
11046
- sliceSize = 10000 * 1024;
11047
- constructor(appEnvironment, util, user) {
11048
- 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;
11049
10978
  this.util = util;
11050
- this.user = user;
11051
- this.baseUrl = this.appEnvironment.appUri;
11052
10979
  }
11053
- getFileLength = (blobId, temp) => {
11054
- return Observable.create((observer) => {
11055
- let xhr = new XMLHttpRequest();
11056
- xhr.onreadystatechange = function () {
11057
- if (xhr.readyState == XMLHttpRequest.DONE) {
11058
- if (xhr.status == 200) {
11059
- observer.next(xhr.response);
11060
- }
11061
- else {
11062
- console.log('Download Failed. Unable to acquire file size.');
11063
- }
11064
- }
11065
- };
11066
- xhr.open('POST', this.baseUrl + '/api/CloudFile/BlobLength', true);
11067
- xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11068
- xhr.send(JSON.stringify({
11069
- blobId: blobId,
11070
- temp: temp ? true : false
11071
- }));
11072
- });
11073
- };
11074
- uploadFile = (start, tableName, propertyName, filename, blobMetaData, temp, updateProgress, done) => {
11075
- let nextSlice = start + this.sliceSize + 1;
11076
- let blob = this.file?.slice(start, nextSlice);
11077
- this.reader.onloadend = (event) => {
11078
- if (event.target?.readyState !== FileReader.DONE) {
11079
- return;
11080
- }
11081
- let xhr = new XMLHttpRequest();
11082
- xhr.onreadystatechange = () => {
11083
- if (xhr.readyState == XMLHttpRequest.DONE) {
11084
- if (xhr.status == 200) {
11085
- var sizeDone = start + this.sliceSize;
11086
- var percentDone = Math.floor((sizeDone / this.file.size) * 100);
11087
- var blobMetaData = JSON.parse(xhr.response);
11088
- if (nextSlice < this.file?.size) {
11089
- updateProgress(percentDone);
11090
- console.log('Uploading File - ' + percentDone + '%');
11091
- this.uploadFile(nextSlice, tableName, propertyName, filename, blobMetaData, temp, updateProgress, done);
11092
- }
11093
- else {
11094
- done(blobMetaData.truDbCloudFileRef);
11095
- }
11096
- }
11097
- else {
11098
- console.log(xhr.responseType);
11099
- }
11100
- }
11101
- };
11102
- xhr.open('POST', this.baseUrl + '/api/CloudFile/Upload', true);
11103
- xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11104
- xhr.send(JSON.stringify({
11105
- tableName: tableName,
11106
- propertyName: propertyName,
11107
- fileData: event.target.result.split(',')[1],
11108
- filename: filename,
11109
- blobId: blobMetaData.blobId,
11110
- blobBlockIdStr: blobMetaData.blobBlockIdStr,
11111
- createdRef: this.user.activeUserRef,
11112
- public: false,
11113
- temp: temp ? true : false,
11114
- commit: nextSlice < this.file.size ? false : true
11115
- }));
11116
- };
11117
- this.reader.readAsDataURL(blob);
11118
- };
11119
- upload = (tableName, propertyName, fileData, temp, updateProgress, done) => {
11120
- this.reader = new FileReader();
11121
- this.file = fileData;
11122
- 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();
11123
10995
  };
11124
- download = (blobId, temp, filename, updateProgress, done) => {
11125
- this.getFileLength(blobId, temp).subscribe((fileLength) => {
11126
- var xhr = new XMLHttpRequest();
11127
- xhr.onprogress = function (e) {
11128
- updateProgress(Math.round(e.loaded / e.total * 100));
11129
- };
11130
- xhr.onload = function () {
11131
- //var fileName = xhr.getResponseHeader('Content-Disposition').split("filename=")[1];
11132
- var blob = new Blob([xhr.response], { type: 'application/octet-stream' });
11133
- var a = document.createElement('a');
11134
- a.href = URL.createObjectURL(blob);
11135
- a.download = filename;
11136
- document.body.appendChild(a);
11137
- a.dispatchEvent(new MouseEvent('click'));
11138
- done();
11139
- };
11140
- xhr.onerror = function (e) {
11141
- done();
11142
- console.log(e);
11143
- };
11144
- xhr.ontimeout = function (e) {
11145
- done();
11146
- console.log(e);
11147
- };
11148
- xhr.open('POST', this.baseUrl + '/api/CloudFile/Download');
11149
- xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11150
- xhr.responseType = 'arraybuffer';
11151
- xhr.send(JSON.stringify({
11152
- blobId: blobId,
11153
- filename: filename,
11154
- fileLength: parseInt(fileLength),
11155
- temp: temp ? true : false
11156
- }));
11157
- });
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();
11158
11009
  };
11159
- sasUrl = (blobId, temp, filename, updateProgress, done) => {
11160
- var xhr = new XMLHttpRequest();
11161
- xhr.onprogress = function (e) { };
11162
- xhr.onload = function () {
11163
- done(xhr.response);
11164
- };
11165
- xhr.onerror = function (e) {
11166
- done(undefined);
11167
- console.log(e);
11168
- };
11169
- xhr.ontimeout = function (e) {
11170
- done(undefined);
11171
- console.log(e);
11172
- };
11173
- xhr.open('POST', this.baseUrl + '/api/CloudFile/SASTokenURL');
11174
- xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
11175
- xhr.responseType = 'text';
11176
- xhr.send(JSON.stringify({
11177
- blobId: blobId
11178
- }));
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();
11179
11016
  };
11180
- 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 });
11181
- 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 }] });
11182
11065
  }
11183
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.3", ngImport: i0, type: TruCloudFileManager, decorators: [{
11184
- type: Injectable,
11185
- args: [{
11186
- providedIn: 'root',
11187
- }]
11188
- }], 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
+ }] } });
11189
11074
 
11190
- class TruFormatter {
11191
- appEnvironemt;
11192
- modelTypeLookup;
11193
- constructor(appEnvironemt, modelTypeLookup) {
11194
- this.appEnvironemt = appEnvironemt;
11195
- 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;
11196
11086
  }
11197
- formatDate = (date, format) => {
11198
- if (date === null)
11199
- return null;
11200
- if (!(date instanceof Date))
11201
- return '';
11202
- if (isNaN(date.getTime()))
11203
- return '';
11204
- var datePipe = new DatePipe('en-US');
11205
- return datePipe.transform(date, format);
11206
- };
11207
- isDate = (date) => {
11208
- if (Object.prototype.toString.call(date) === '[object Date]') {
11209
- if (isNaN(date.getTime())) {
11210
- return false;
11211
- }
11212
- else {
11213
- 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;
11214
11162
  }
11215
- }
11216
- else if (moment$1(date, "MM/DD/YYYY", true).isValid()) {
11217
- return true;
11163
+ return undefined;
11218
11164
  }
11219
11165
  else {
11220
- return false;
11166
+ return this.entity.Merge_Data_Set?.get(this.config.propertyName) ? this.entity.Merge_Data_Set : undefined;
11221
11167
  }
11222
11168
  };
11223
- isPromise = function (value) {
11224
- 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;
11225
11175
  };
11226
- //Filters
11227
- bigInteger = (cfg) => {
11228
- var v = cfg.$;
11229
- if (v === null)
11230
- return null;
11231
- 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;
11232
11182
  };
11233
- boolean = (cfg) => {
11234
- var v = cfg.$;
11235
- if (v === null)
11236
- return null;
11237
- return v ? 'True' : 'False';
11183
+ removeValidationDialog = () => {
11184
+ if (this.currentDialog) {
11185
+ this.currentDialog.destroy();
11186
+ this.currentDialog = null;
11187
+ }
11238
11188
  };
11239
- choiceLabel = (cfg) => {
11240
- if (cfg.$ === null)
11241
- return null;
11242
- if (cfg.type) {
11243
- var item = cfg.type.choices.filter(function (c) {
11244
- return c.$ === cfg.$;
11245
- });
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);
11246
11211
  }
11247
- else {
11248
- return cfg.$;
11212
+ if (this.config.rootTable === validationTableName &&
11213
+ this.entity[entityPkeyName] === validationObjectEntity[validationObjectEntitypkeyName] &&
11214
+ (removedPropertyValdations.length)) {
11215
+ this.removeValidationDialog();
11249
11216
  }
11250
- if (item.length == 0)
11251
- return null;
11252
- return item[0].label;
11253
11217
  };
11254
- dateShort = (cfg) => {
11255
- var v = cfg.$;
11256
- if (!v || !this.isDate(v))
11257
- return 'mm/dd/yyyy';
11258
- v = new Date(v);
11259
- var utc = new Date(v.getUTCFullYear(), v.getUTCMonth(), v.getUTCDate());
11260
- 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));
11261
11281
  };
11262
- datetimeShort = (cfg) => {
11263
- var v = cfg.$;
11264
- if (!v)
11265
- return 'mm/dd/yyyy hh:mm a';
11266
- 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
+ });
11267
11288
  };
11268
- datetimespanShort = (cfg) => {
11269
- var start = cfg.start.$;
11270
- var end = cfg.end.$;
11271
- var text = '';
11272
- if (start !== null) {
11273
- text = this.formatDate(start, 'MM/dd/yyyy hh:mm a') + ' - ';
11274
- if (end != null) {
11275
- if (start.getYear() === end.getYear() && start.getMonth() === end.getMonth() && start.getDay() === end.getDay())
11276
- text += this.formatDate(end, 'hh:mm a');
11277
- else
11278
- text += this.formatDate(end, 'MM/dd/yyyy hh:mm a');
11279
- }
11280
- }
11281
- else {
11282
- if (end !== null)
11283
- text += this.formatDate(end, 'MM/dd/yyyy hh:mm a');
11284
- }
11285
- return text;
11289
+ addDragHandleEventListeners = () => {
11290
+ this.dragHandles.forEach((dropHandle) => {
11291
+ this.listeners.push(this.renderer.listen(dropHandle, 'mousedown', this.mousedown));
11292
+ });
11286
11293
  };
11287
- decimal = (cfg) => {
11288
- var v = cfg.$;
11289
- if (v === null)
11290
- return null;
11291
- return v;
11294
+ addPointerEvents = () => {
11295
+ this.dropZones.forEach((dropZone) => {
11296
+ dropZone.style.pointerEvents = 'all';
11297
+ });
11292
11298
  };
11293
- excelFormula = (val) => {
11294
- if (_.isNaN(val))
11295
- return '#VALUE!';
11296
- if (val === Infinity)
11297
- return '#DIV/0!';
11298
- return val;
11299
+ removePointerEvents = () => {
11300
+ this.dropZones.forEach((dropZone) => {
11301
+ dropZone.style.pointerEvents = 'none';
11302
+ });
11299
11303
  };
11300
- file = (cfg) => {
11301
- if (this.isPromise(cfg.filename.$))
11302
- return null;
11303
- var text = '';
11304
- if (cfg.filename.$ !== null)
11305
- text += cfg.filename.$;
11306
- return text;
11304
+ addMouseoverDropzoneStyles = (event) => {
11305
+ event.target.classList.add('mouseover');
11307
11306
  };
11308
- float = (cfg) => {
11309
- var v = cfg.$;
11310
- if (v === null)
11311
- return null;
11312
- 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
+ }
11313
11312
  };
11314
- id = (value) => {
11315
- if (!value)
11316
- return null;
11317
- return value;
11313
+ dragStart = (event) => {
11314
+ this.addPointerEvents();
11318
11315
  };
11319
- integer = (cfg) => {
11320
- var v = cfg.$;
11321
- if (v === null)
11322
- return null;
11323
- return v;
11316
+ dragEnd = (event) => {
11317
+ this.removePointerEvents();
11318
+ this.removeMouseoverDropzoneStyles(event);
11324
11319
  };
11325
- intlAddress = (cfg) => {
11326
- var text = '';
11327
- if (cfg.address1.$ !== null)
11328
- text += cfg.address1.$ + ' ';
11329
- if (cfg.address2.$ !== null)
11330
- text += cfg.address2.$ + ' ';
11331
- if (cfg.country.$ !== null)
11332
- text += cfg.country.$ + ' ';
11333
- if (cfg.city.$ !== null)
11334
- text += cfg.city.$ + ' ';
11335
- if (cfg.stateProvince.$ !== null)
11336
- text += cfg.stateProvince.$ + ' ';
11337
- if (cfg.postalCode.$ !== null)
11338
- text += cfg.postalCode.$ + ' ';
11339
- return text;
11320
+ dragOver = (event) => {
11321
+ event.preventDefault();
11322
+ this.addMouseoverDropzoneStyles(event);
11340
11323
  };
11341
- intlAddressBasic = (cfg) => {
11342
- var text = '';
11343
- if (cfg.address1.$ !== null)
11344
- text += cfg.address1.$ + ' ';
11345
- if (cfg.address2.$ !== null)
11346
- text += cfg.address2.$ + ' ';
11347
- if (cfg.country.$ !== null)
11348
- text += cfg.country.$ + ' ';
11349
- if (cfg.city.$ !== null)
11350
- text += cfg.city.$ + ' ';
11351
- if (cfg.stateProvince.$ !== null)
11352
- text += cfg.stateProvince.$ + ' ';
11353
- if (cfg.postalCode.$ !== null)
11354
- text += cfg.postalCode.$ + ' ';
11355
- return text;
11324
+ dragLeave = (event) => {
11325
+ event.target.classList.remove('mouseover');
11356
11326
  };
11357
- naPhone = (number) => {
11358
- if (!number) {
11359
- return '';
11360
- }
11361
- if (number) {
11362
- if (number.$)
11363
- number = number.$.replace(/[^0-9]/g, '');
11364
- else
11365
- number = number.$;
11366
- }
11367
- if (!number) {
11368
- return '';
11369
- }
11370
- number = String(number);
11371
- var formattedNumber = number;
11372
- var c = (number[0] == '1') ? '+1 ' : '';
11373
- number = number[0] == '1' ? number.slice(1) : number;
11374
- var area = number.substring(0, 3);
11375
- var front = number.substring(3, 6);
11376
- var end = number.substring(6, 10);
11377
- var ext = number.substring(10, 20);
11378
- if (front) {
11379
- formattedNumber = (c + "(" + area + ") " + front);
11380
- }
11381
- if (end) {
11382
- 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');
11383
11333
  }
11384
- if (ext) {
11385
- 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');
11386
11339
  }
11387
- return formattedNumber;
11388
- };
11389
- intlPhone = (cfg) => {
11390
- var field = cfg;
11391
- var text = '';
11392
- //if (cfg.countryCode.$ !== null) {
11393
- // var country = _.find(countries.allCountries, function (country) { return country.iso2 === cfg.countryCode.$ });
11394
- // var dialCode = country.dialCode;
11395
- // text += '+' + dialCode + ' ';
11396
- //}
11397
- //if (cfg.phone.$ !== null) {
11398
- // var clean = cfg.phone.$.replace(/[^0-9]/g, '');
11399
- // try {
11400
- // var countryCode = cfg.countryCode.$ ? cfg.countryCode.$ : field.property.countryCode;
11401
- // var number = clean;
11402
- // text += number + ' ';
11403
- // } catch (e) {
11404
- // text += clean + ' ';
11405
- // }
11406
- //}
11407
- //if (cfg.extension.$ !== null)
11408
- // text += ' x' + cfg.extension.$;
11409
- return text;
11410
- };
11411
- password = (cfg) => {
11412
- var v = cfg.$;
11413
- if (v === null)
11414
- return null;
11415
- if (v.length > 0)
11416
- return '********';
11417
- return '';
11418
- };
11419
- percentage = (cfg) => {
11420
- var v = cfg.$;
11421
- if (typeof v === 'undefined')
11422
- return undefined;
11423
- if (v === null)
11424
- return null;
11425
- if (typeof v.toFixed === 'function')
11426
- return (v * 100).toFixed(2) + '%';
11427
- return v;
11428
- };
11429
- picture = (cfg) => {
11430
- var text = '';
11431
- if (cfg.filename.$ !== null)
11432
- text += cfg.filename.$;
11433
- return text;
11434
- };
11435
- ref = (cfg) => {
11436
- var v = cfg.$;
11437
- if (v === null)
11438
- return null;
11439
- return v.toString();
11440
- };
11441
- richText = (cfg) => {
11442
- return cfg.$;
11340
+ this.removeMouseoverDropzoneStyles(event);
11443
11341
  };
11444
- socialSecurityNumber = (cfg) => {
11445
- var v = cfg.$;
11446
- if (v === null)
11447
- return null;
11448
- 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);
11449
11350
  };
11450
- text = (cfg) => {
11451
- 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
+ }
11452
11369
  };
11453
- textFormatting = (text) => {
11454
- if (!text)
11455
- return text;
11456
- if (typeof text.replace === 'function')
11457
- return text.replace(/[\n\r]+/g, ' ').replace(/\s{2,}/g, ' ').replace(/^\s+|\s+$/, '');
11458
- return text;
11370
+ mouseUp = () => {
11371
+ this.dragHandle = null;
11372
+ this.mouseOffsetX = 0;
11373
+ this.lastMouseX = 0;
11374
+ this.mousemoveListener();
11375
+ this.mouseupListener();
11459
11376
  };
11460
- timeShort = (cfg) => {
11461
- var v = cfg.$;
11462
- if (v === null)
11463
- return null;
11464
- var duration = moment$1.duration(v);
11465
- var datetime = new Date('01/01/1999 ' + duration.hours + ':' + duration.minutes + ':' + duration.seconds);
11466
- var datePipe = new DatePipe('en-US');
11467
- 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
+ //}
11468
11386
  };
11469
- timeSpanHhMmSs = (cfg) => {
11470
- 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
+ });
11471
11436
  };
11472
- usaAddress = (cfg) => {
11473
- let text = "Loading...";
11474
- let buildText = () => {
11475
- text = '';
11476
- if (cfg.address1.$ !== null)
11477
- text += cfg.address1.$ + ' ';
11478
- if (cfg.address2.$ !== null)
11479
- text += cfg.address2.$ + ' ';
11480
- if (cfg.city.$ !== null)
11481
- text += cfg.city.$ + ' ';
11482
- if (cfg.state.$ !== null) {
11483
- var state = this.appEnvironemt.globalDataContext?.entityAccess().searchByRefCacheOnly(this.modelTypeLookup.getType('StdUSAState'), cfg.state.$);
11484
- if (state)
11485
- text += state.Code + ', ';
11486
- }
11487
- if (cfg.zip.$ !== null) {
11488
- if (cfg.zip.$.length > 5)
11489
- text += cfg.zip.$.substring(0, 5) + '-' + cfg.zip.$.substring(5);
11490
- else
11491
- 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;
11492
11443
  }
11493
- 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
+ }));
11494
11479
  };
11495
- if (this.appEnvironemt.globalDataContext?.entityAccess().searchByRefCacheOnly(this.modelTypeLookup.getType('StdUSAState'), cfg.state.$)) {
11496
- return buildText();
11497
- }
11498
- return null;
11499
- };
11500
- usaDollars = (cfg) => {
11501
- var v = cfg.$;
11502
- if (v === null)
11503
- return null;
11504
- return '$' + (v)?.toFixed(2);
11505
- };
11506
- usaSocialSecurity = (cfg) => {
11507
- var v = cfg.$;
11508
- if (v === null)
11509
- return null;
11510
- return v.substring(0, 3) + '-' + v.substring(3, 5) + '-' + v.substring(5);
11511
- };
11512
- usaZip = (cfg) => {
11513
- var v = cfg.$;
11514
- if (v === null)
11515
- return null;
11516
- if (v.length > 5)
11517
- return v.substring(0, 5) + '-' + v.substring(5);
11518
- return v;
11480
+ this.reader.readAsDataURL(blob);
11519
11481
  };
11520
- zipCode = (cfg) => {
11521
- var v = cfg.$;
11522
- if (v === null)
11523
- return null;
11524
- if (v.length > 5)
11525
- return v.substring(0, 5) + '-' + v.substring(5);
11526
- 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);
11527
11486
  };
11528
- passwordEightBullets = (cfg) => {
11529
- var v = cfg.$;
11530
- 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
+ });
11531
11521
  };
11532
- formulaJsonParser = (formatter, data) => {
11533
- var json = JSON.parse(data);
11534
- if (json.DATA || (typeof json.DATA === 'number' && isFinite(json.DATA)))
11535
- return formatter({ $: json.DATA });
11536
- 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
+ }));
11537
11542
  };
11538
- 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 });
11539
- 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' });
11540
11545
  }
11541
- 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: [{
11542
11547
  type: Injectable,
11543
11548
  args: [{
11544
11549
  providedIn: 'root',
11545
11550
  }]
11546
- }], ctorParameters: () => [{ type: TruAppEnvironment }, { type: TruModelTypeLookup }] });
11551
+ }], ctorParameters: () => [{ type: TruAppEnvironment }, { type: TruUtil }, { type: TruUser }] });
11547
11552
 
11548
11553
  class TruPredicateMap {
11549
11554
  constructor() { }