@trudb/tru-common-lib 0.2.536 → 0.2.539

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.
@@ -649,6 +649,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
649
649
  }]
650
650
  }], ctorParameters: () => [] });
651
651
 
652
+ class TruEntityMetadataRegistry {
653
+ static metadataByEntity = new Map();
654
+ static register(entity, metadata) {
655
+ this.metadataByEntity.set(entity, this.normalize(metadata));
656
+ }
657
+ static get(entity) {
658
+ const metadata = this.metadataByEntity.get(entity);
659
+ return metadata ? { ...metadata } : undefined;
660
+ }
661
+ static resolve(entity) {
662
+ return this.get(entity) ?? this.resolveFromBreeze(entity) ?? this.resolveFromConstructorName(entity);
663
+ }
664
+ static resolveFromBreeze(entity) {
665
+ const entityType = entity.prototype?.entityType;
666
+ const entityTypeName = this.getEntityTypeName(entityType);
667
+ if (!entityTypeName)
668
+ return undefined;
669
+ const primaryKeyName = this.getPrimaryKeyName(entityType) ?? `${entityTypeName}Ref`;
670
+ return {
671
+ entityTypeName,
672
+ queryResourceName: `Query${entityTypeName}`,
673
+ primaryKeyName,
674
+ };
675
+ }
676
+ static resolveFromConstructorName(entity) {
677
+ const entityTypeName = this.requireText(entity.name, 'entity.name');
678
+ return {
679
+ entityTypeName,
680
+ queryResourceName: `Query${entityTypeName}`,
681
+ primaryKeyName: `${entityTypeName}Ref`,
682
+ };
683
+ }
684
+ static normalize(metadata) {
685
+ return {
686
+ entityTypeName: this.requireText(metadata.entityTypeName, 'entityTypeName'),
687
+ queryResourceName: this.requireText(metadata.queryResourceName, 'queryResourceName'),
688
+ primaryKeyName: this.requireText(metadata.primaryKeyName, 'primaryKeyName'),
689
+ };
690
+ }
691
+ static getEntityTypeName(entityType) {
692
+ return this.textOrUndefined(entityType?.shortName)
693
+ ?? this.shortNameFromQualifiedName(this.textOrUndefined(entityType?.name));
694
+ }
695
+ static getPrimaryKeyName(entityType) {
696
+ const keyProperty = entityType?.keyProperties?.[0];
697
+ return this.textOrUndefined(keyProperty?.name)
698
+ ?? this.textOrUndefined(keyProperty?.nameOnServer);
699
+ }
700
+ static shortNameFromQualifiedName(name) {
701
+ if (!name)
702
+ return undefined;
703
+ const unqualifiedName = name.split(':#')[0];
704
+ const lastDotIndex = unqualifiedName.lastIndexOf('.');
705
+ return this.textOrUndefined(lastDotIndex >= 0 ? unqualifiedName.substring(lastDotIndex + 1) : unqualifiedName);
706
+ }
707
+ static requireText(value, propertyName) {
708
+ const text = this.textOrUndefined(value);
709
+ if (!text)
710
+ throw new Error(`Missing TruDB entity metadata value: ${propertyName}`);
711
+ return text;
712
+ }
713
+ static textOrUndefined(value) {
714
+ return typeof value === 'string' && value.trim().length > 0 ? value : undefined;
715
+ }
716
+ }
717
+
652
718
  class MaterialModule {
653
719
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: MaterialModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
654
720
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.17", ngImport: i0, type: MaterialModule, exports: [A11yModule,
@@ -1638,9 +1704,9 @@ class TruEntityAccessor {
1638
1704
  this._breezeContext = dataContext.breezeContext;
1639
1705
  this._entityManager = dataContext.entityManager;
1640
1706
  }
1641
- getQueryServiceName = (entity) => {
1642
- return 'Query' + entity.name;
1643
- };
1707
+ getQueryServiceName = (entity) => TruEntityMetadataRegistry.resolve(entity).queryResourceName;
1708
+ getPrimaryKeyName = (entity) => TruEntityMetadataRegistry.resolve(entity).primaryKeyName;
1709
+ getEntityTypeName = (entity) => TruEntityMetadataRegistry.resolve(entity).entityTypeName;
1644
1710
  warnIfMaxRecords = (entities, entityName) => {
1645
1711
  if (entities.length >= this.appEnvironment.maxRecordCount)
1646
1712
  this.uiNotification.warning('[' + entityName + '] has more records available than supported');
@@ -1679,7 +1745,7 @@ class TruEntityAccessor {
1679
1745
  query = setupQuery(query);
1680
1746
  return defer(() => from(this._entityManager.executeQuery(query).then((queryData) => {
1681
1747
  if (!global)
1682
- this.warnIfMaxRecords(queryData.results, entity.name);
1748
+ this.warnIfMaxRecords(queryData.results, this.getEntityTypeName(entity));
1683
1749
  return queryData.results;
1684
1750
  })));
1685
1751
  };
@@ -1697,11 +1763,11 @@ class TruEntityAccessor {
1697
1763
  };
1698
1764
  searchByRefCacheOnlySynchronously = (entity, ref = undefined) => {
1699
1765
  let query = this._breezeContext.createQuery(this.getQueryServiceName(entity));
1700
- query = query.where(entity.name + 'Ref', '==', ref);
1766
+ query = query.where(this.getPrimaryKeyName(entity), '==', ref);
1701
1767
  return this._entityManager.executeQueryLocally(query);
1702
1768
  };
1703
1769
  searchQueryChoices = (entity, setupQuery = null, goToServer = false, ref = undefined, allRecords = false, dependantEntty = undefined, hid = null) => {
1704
- const pkeyName = entity.name + 'Ref';
1770
+ const pkeyName = this.getPrimaryKeyName(entity);
1705
1771
  let query = this._breezeContext.createQuery(this.getQueryServiceName(entity));
1706
1772
  if (setupQuery)
1707
1773
  if (dependantEntty)
@@ -1709,7 +1775,7 @@ class TruEntityAccessor {
1709
1775
  else
1710
1776
  query = setupQuery(query, entity) ?? query;
1711
1777
  if (ref)
1712
- query = query.where(entity.name + 'Ref', '==', ref);
1778
+ query = query.where(this.getPrimaryKeyName(entity), '==', ref);
1713
1779
  if (!allRecords)
1714
1780
  query = query.top(this.appEnvironment.maxRecordCount);
1715
1781
  if (goToServer) {
@@ -1722,20 +1788,20 @@ class TruEntityAccessor {
1722
1788
  }
1723
1789
  };
1724
1790
  searchNameValuesCacheOnly = (entity, setupQuery = null, ref = undefined) => {
1725
- const pkeyName = entity.name + 'Ref';
1791
+ const pkeyName = this.getPrimaryKeyName(entity);
1726
1792
  let query = this._breezeContext.createQuery(this.getQueryServiceName(entity));
1727
1793
  if (setupQuery)
1728
1794
  query = setupQuery(query) ?? query;
1729
1795
  if (ref)
1730
- query = query.where(entity.name + 'Ref', '==', ref);
1796
+ query = query.where(this.getPrimaryKeyName(entity), '==', ref);
1731
1797
  return of(this.formatNameValues(query, this._entityManager.executeQueryLocally(query), pkeyName));
1732
1798
  };
1733
1799
  searchByRef = (entity, ref) => {
1734
- const pkeyName = entity.name + 'Ref';
1800
+ const pkeyName = this.getPrimaryKeyName(entity);
1735
1801
  var queryOptions = this._entityManager.queryOptions.using({
1736
1802
  fetchStrategy: FetchStrategy.FromServer
1737
1803
  });
1738
- var query = this._breezeContext.createQuery(this.getQueryServiceName(entity)).where(entity.name + 'Ref', '==', ref).using(queryOptions);
1804
+ var query = this._breezeContext.createQuery(this.getQueryServiceName(entity)).where(this.getPrimaryKeyName(entity), '==', ref).using(queryOptions);
1739
1805
  return defer(() => from(this._entityManager.executeQuery(query).then((queryData) => {
1740
1806
  return this.formatQueryChoices(query, queryData.results, pkeyName, null);
1741
1807
  })));
@@ -1746,7 +1812,7 @@ class TruEntityAccessor {
1746
1812
  var queryOptions = this._entityManager.queryOptions.using({
1747
1813
  fetchStrategy: FetchStrategy.FromLocalCache
1748
1814
  });
1749
- var query = this._breezeContext.createQuery(this.getQueryServiceName(entity)).where(entity.name + 'Ref', '==', ref).using(queryOptions);
1815
+ var query = this._breezeContext.createQuery(this.getQueryServiceName(entity)).where(this.getPrimaryKeyName(entity), '==', ref).using(queryOptions);
1750
1816
  return defer(() => from(this._entityManager.executeQuery(query).then((queryData) => {
1751
1817
  return queryData.results[0];
1752
1818
  })));
@@ -1755,7 +1821,7 @@ class TruEntityAccessor {
1755
1821
  var queryOptions = this._entityManager.queryOptions.using({
1756
1822
  fetchStrategy: FetchStrategy.FromServer
1757
1823
  });
1758
- var query = this._breezeContext.createQuery(this.getQueryServiceName(entity)).where(entity.name + 'Ref', '==', ref).using(queryOptions);
1824
+ var query = this._breezeContext.createQuery(this.getQueryServiceName(entity)).where(this.getPrimaryKeyName(entity), '==', ref).using(queryOptions);
1759
1825
  return defer(() => from(this._entityManager.executeQuery(query).then((queryData) => {
1760
1826
  return queryData.results[0];
1761
1827
  })));
@@ -1768,7 +1834,7 @@ class TruEntityAccessor {
1768
1834
  includeDeleted: includeDeleted,
1769
1835
  fetchStrategy: FetchStrategy.FromLocalCache
1770
1836
  });
1771
- var query = this._breezeContext.createQuery(this.getQueryServiceName(entity)).where(entity.name + 'Ref', '==', ref).using(queryOptions);
1837
+ var query = this._breezeContext.createQuery(this.getQueryServiceName(entity)).where(this.getPrimaryKeyName(entity), '==', ref).using(queryOptions);
1772
1838
  var result = this._entityManager.executeQueryLocally(query)[0];
1773
1839
  if (result)
1774
1840
  return result;
@@ -1778,7 +1844,7 @@ class TruEntityAccessor {
1778
1844
  var queryOptions = this._entityManager.queryOptions.using({
1779
1845
  fetchStrategy: FetchStrategy.FromServer
1780
1846
  });
1781
- var query = this._breezeContext.createQuery(this.getQueryServiceName(entity)).where(entity.name + 'Ref', '==', ref).using(queryOptions);
1847
+ var query = this._breezeContext.createQuery(this.getQueryServiceName(entity)).where(this.getPrimaryKeyName(entity), '==', ref).using(queryOptions);
1782
1848
  return defer(() => from(this._entityManager.executeQuery(query).then((queryData) => {
1783
1849
  return queryData.results[0];
1784
1850
  })));
@@ -1796,7 +1862,7 @@ class TruEntityAccessor {
1796
1862
  if (query === null) //setupQuery() returned null to select no rows
1797
1863
  return [];
1798
1864
  if (refs.length > 0) {
1799
- const pkeyName = entity.name + 'Ref';
1865
+ const pkeyName = this.getPrimaryKeyName(entity);
1800
1866
  var predicate = this._breezeContext.createPredicate(pkeyName, '==', refs[0]);
1801
1867
  _.rest(refs, 1).forEach(function (ref) {
1802
1868
  predicate = predicate.or(pkeyName, '==', ref);
@@ -1811,7 +1877,7 @@ class TruEntityAccessor {
1811
1877
  searchByRefWithQuery = (entity, setupQuery, ref) => {
1812
1878
  var query = this._breezeContext.createQuery(this.getQueryServiceName(entity));
1813
1879
  query = setupQuery(query);
1814
- const pkeyName = entity.name + 'Ref';
1880
+ const pkeyName = this.getPrimaryKeyName(entity);
1815
1881
  var predicate = this._breezeContext.createPredicate(pkeyName, '==', ref);
1816
1882
  query = query.where(predicate);
1817
1883
  var localResults = this._entityManager.executeQueryLocally(query);
@@ -1836,7 +1902,7 @@ class TruEntityAccessor {
1836
1902
  };
1837
1903
  customSearch = (entity, query) => {
1838
1904
  return defer(() => from(this._entityManager.executeQuery(query).then((queryData) => {
1839
- this.warnIfMaxRecords(queryData.results, entity.name);
1905
+ this.warnIfMaxRecords(queryData.results, this.getEntityTypeName(entity));
1840
1906
  return queryData.results;
1841
1907
  })));
1842
1908
  };
@@ -1853,7 +1919,7 @@ class TruEntityAccessor {
1853
1919
  useNames: false,
1854
1920
  useEmptyTags: false,
1855
1921
  entityRefs: null,
1856
- entityTypeName: entity.name,
1922
+ entityTypeName: this.getEntityTypeName(entity),
1857
1923
  gridSpec: gridSpec
1858
1924
  };
1859
1925
  if (options.async)
@@ -4068,7 +4134,7 @@ class TruAuth {
4068
4134
  });
4069
4135
  }
4070
4136
  userClaims() {
4071
- if (this.appEnvironment.authType === 'session') {
4137
+ if (this.appEnvironment.authType === 'session' || this.appEnvironment.authType === 'windows') {
4072
4138
  return this.http
4073
4139
  .get(`${this.baseUrl}${TRU_AUTH_CONFIG.authUrl}/userClaims`)
4074
4140
  .pipe(tap((userClaims) => {
@@ -4824,6 +4890,35 @@ class TruDetailViewBase {
4824
4890
  this.desktopViewEventNotifier = desktopViewEventNotifier;
4825
4891
  this.util = util;
4826
4892
  }
4893
+ onDocumentKeydown = (event) => {
4894
+ if (this.view.active && this.view.window.active) {
4895
+ let keySequence = this.util.getKeySequence(event);
4896
+ if (keySequence === 'ctrl+i' || keySequence === 'meta+i') {
4897
+ //this.onAddEntity();
4898
+ event.preventDefault();
4899
+ }
4900
+ if (keySequence === 'ctrl+d' || keySequence === 'meta+d') {
4901
+ this.onDeleteEntity();
4902
+ event.preventDefault();
4903
+ }
4904
+ if (keySequence === 'ctrl+up' || keySequence === 'meta+up') {
4905
+ this.onFirstEntity();
4906
+ event.preventDefault();
4907
+ }
4908
+ if (keySequence === 'ctrl+left' || keySequence === 'meta+left') {
4909
+ this.onPreviousEntity();
4910
+ event.preventDefault();
4911
+ }
4912
+ if (keySequence === 'ctrl+right' || keySequence === 'meta+right') {
4913
+ this.onNextEntity();
4914
+ event.preventDefault();
4915
+ }
4916
+ if (keySequence === 'ctrl+down' || keySequence === 'meta+down') {
4917
+ this.onLastEntity();
4918
+ event.preventDefault();
4919
+ }
4920
+ }
4921
+ };
4827
4922
  calculateNextIndex = () => {
4828
4923
  let nextIndex = 0;
4829
4924
  var removedRecords = this.recordsBeforeRevert - this.entities.length;
@@ -4925,38 +5020,7 @@ class TruDetailViewBase {
4925
5020
  if (this.active)
4926
5021
  this.setEntityDisplayValues(this.tableName);
4927
5022
  }));
4928
- this.subs.push(fromEvent(document, 'keydown').subscribe((event) => {
4929
- if (this.view.active && this.view.window.active) {
4930
- let keySequence = this.util.getKeySequence(event);
4931
- if (keySequence === 'ctrl+i' || keySequence === 'meta+i') {
4932
- //this.onAddEntity();
4933
- event.preventDefault();
4934
- }
4935
- if (keySequence === 'ctrl+d' || keySequence === 'meta+d') {
4936
- this.onDeleteEntity();
4937
- event.preventDefault();
4938
- }
4939
- if (keySequence === 'ctrl+up' || keySequence === 'meta+up') {
4940
- this.onFirstEntity();
4941
- event.preventDefault();
4942
- }
4943
- if (keySequence === 'ctrl+left' || keySequence === 'meta+left') {
4944
- this.onPreviousEntity();
4945
- event.preventDefault();
4946
- }
4947
- if (keySequence === 'ctrl+right' || keySequence === 'meta+right') {
4948
- this.onNextEntity();
4949
- event.preventDefault();
4950
- }
4951
- if (keySequence === 'ctrl+down' || keySequence === 'meta+down') {
4952
- this.onLastEntity();
4953
- event.preventDefault();
4954
- }
4955
- var targetIsControl = this.util.targetIsControl(event.target);
4956
- if (!targetIsControl && event.ctrlKey || event.altKey)
4957
- event.preventDefault();
4958
- }
4959
- }));
5023
+ this.subs.push(fromEvent(document, 'keydown').subscribe(this.onDocumentKeydown));
4960
5024
  }
4961
5025
  setNavigationIndex(index) {
4962
5026
  this.navigationIndex = index;
@@ -6165,12 +6229,7 @@ class TruCardColumn {
6165
6229
  return false;
6166
6230
  });
6167
6231
  if (entityParent) {
6168
- if (queryableParentRefs.indexOf(entityParent[this.key]) !== -1) {
6169
- entityParent.cards.push(this.createDataForEntity(entity));
6170
- }
6171
- else {
6172
- entityParent.cards.push(this.createDataForEntity(entity));
6173
- }
6232
+ entityParent.cards.push(this.createDataForEntity(entity));
6174
6233
  }
6175
6234
  else if (!entityParent &&
6176
6235
  entity['o' + this.relatedParentName] &&
@@ -8639,6 +8698,30 @@ class TruDataGrid {
8639
8698
  this.desktopViewEventNotifier = desktopViewEventNotifier;
8640
8699
  this.tabGroupEventNotifier = tabGroupEventNotifier;
8641
8700
  }
8701
+ onDocumentKeydown = (event) => {
8702
+ if (this.config.view.active && this.config.view.window.active) {
8703
+ if (event.code === 'Space' && event.target.classList.contains('ag-cell-value')) {
8704
+ event.preventDefault();
8705
+ }
8706
+ let keySequence = this.util.getKeySequence(event);
8707
+ if (keySequence === 'ctrl+i' || keySequence === 'meta+i') {
8708
+ this.onAdd();
8709
+ event.preventDefault();
8710
+ }
8711
+ if (keySequence === 'ctrl+d' || keySequence === 'meta+d') {
8712
+ this.onDelete();
8713
+ event.preventDefault();
8714
+ }
8715
+ if (keySequence === 'ctrl+k' || keySequence === 'meta+k') {
8716
+ this.onKeep();
8717
+ event.preventDefault();
8718
+ }
8719
+ if (keySequence === 'ctrl+r' || keySequence === 'meta+r') {
8720
+ this.onRemove();
8721
+ event.preventDefault();
8722
+ }
8723
+ }
8724
+ };
8642
8725
  enhanceRowDataForEntity = (entity) => {
8643
8726
  let rowData = this.config.resultConfig.rowDataEnhancer(entity);
8644
8727
  rowData.$entity = entity;
@@ -8770,33 +8853,7 @@ class TruDataGrid {
8770
8853
  }
8771
8854
  this.api.refreshCells({ force: true });
8772
8855
  }));
8773
- this.subs.push(fromEvent(document, 'keydown').subscribe((event) => {
8774
- if (this.config.view.active && this.config.view.window.active) {
8775
- if (event.code === 'Space' && event.target.classList.contains('ag-cell-value')) {
8776
- event.preventDefault();
8777
- }
8778
- let keySequence = this.util.getKeySequence(event);
8779
- if (keySequence === 'ctrl+i' || keySequence === 'meta+i') {
8780
- this.onAdd();
8781
- event.preventDefault();
8782
- }
8783
- if (keySequence === 'ctrl+d' || keySequence === 'meta+d') {
8784
- this.onDelete();
8785
- event.preventDefault();
8786
- }
8787
- if (keySequence === 'ctrl+k' || keySequence === 'meta+k') {
8788
- this.onKeep();
8789
- event.preventDefault();
8790
- }
8791
- if (keySequence === 'ctrl+r' || keySequence === 'meta+r') {
8792
- this.onRemove();
8793
- event.preventDefault();
8794
- }
8795
- var targetIsControl = this.util.targetIsControl(event.target);
8796
- if (!targetIsControl && event.ctrlKey || event.altKey)
8797
- event.preventDefault();
8798
- }
8799
- }));
8856
+ this.subs.push(fromEvent(document, 'keydown').subscribe(this.onDocumentKeydown));
8800
8857
  this.subs.push(fromEvent(document, 'mousedown').subscribe((event) => {
8801
8858
  if (this.config.view.active &&
8802
8859
  this.config.view.window.active &&
@@ -9117,9 +9174,10 @@ class TruDataGrid {
9117
9174
  this.firstSearchRan = true;
9118
9175
  this.api?.hideOverlay();
9119
9176
  this.api?.showLoadingOverlay();
9120
- let searchLocally = this.entity && this.entity['Ref'] < 0 || this.loadedEntities.some((ref) => {
9121
- return ref === this.entity['Ref'];
9122
- });
9177
+ let parentIsUnsaved = !!this.entity && this.entity.Ref < 0;
9178
+ let parentWasLoaded = !!this.entity && this.loadedEntities.indexOf(this.entity.Ref) > -1;
9179
+ let canSearchLocally = this.config.resultConfig.canSearchLocally !== false;
9180
+ let searchLocally = parentIsUnsaved || (canSearchLocally && parentWasLoaded);
9123
9181
  let joins = [];
9124
9182
  if (searchLocally) {
9125
9183
  joins.push(this.dataContext.entityAccess().searchCacheOnly(this.config.resultConfig.entityType, setupQuery, this.config.resultConfig.expands));
@@ -9142,7 +9200,7 @@ class TruDataGrid {
9142
9200
  },
9143
9201
  complete: () => {
9144
9202
  if (this.gridType !== TruDataGridTypes.Search)
9145
- this.loadedEntities.push(this.entity[this.entity.constructor.name + 'Ref']);
9203
+ this.loadedEntities.push(this.entity.Ref);
9146
9204
  this.api.hideOverlay();
9147
9205
  if (this.rowData === null || !this.rowData.length) {
9148
9206
  this.api.showNoRowsOverlay();
@@ -10655,9 +10713,6 @@ class TruDesktopWindow {
10655
10713
  this.lastView();
10656
10714
  event.preventDefault();
10657
10715
  }
10658
- var targetIsControl = this.util.targetIsControl(event.target);
10659
- if (!targetIsControl && event.ctrlKey || event.altKey)
10660
- event.preventDefault();
10661
10716
  };
10662
10717
  /**
10663
10718
  * @tru.doc watch
@@ -11529,8 +11584,6 @@ class TruDesktop {
11529
11584
  onKeyDown = (event) => {
11530
11585
  if (event.key === 'Control' || event.key === 'Shift')
11531
11586
  return;
11532
- if (event.altKey)
11533
- event.preventDefault();
11534
11587
  var keySequence = this.util.getKeySequence(event);
11535
11588
  if (keySequence === 'alt+m') { //Maximize
11536
11589
  var activeWindow = this.getActiveWindow();
@@ -11594,10 +11647,6 @@ class TruDesktop {
11594
11647
  this.restoreSavedPosition(activeWindow);
11595
11648
  event.preventDefault();
11596
11649
  }
11597
- if (keySequence === 'alt+d') { //Toggle Desktop
11598
- //this.desktopShown = this.hideShowAll();
11599
- event.preventDefault();
11600
- }
11601
11650
  if (event.shiftKey)
11602
11651
  this.shiftPressed = true;
11603
11652
  if (event.altKey)
@@ -12058,13 +12107,26 @@ class TruLogin {
12058
12107
  this.appEnvironment = appEnvironment;
12059
12108
  this.title = appEnvironment.loginFormTitle;
12060
12109
  }
12110
+ ngOnInit() {
12111
+ if (this.isWindowsAuth)
12112
+ this.loginWithWindows();
12113
+ }
12061
12114
  get f() {
12062
12115
  return this.loginForm.controls;
12063
12116
  }
12117
+ get isWindowsAuth() {
12118
+ return this.appEnvironment.authType === 'windows';
12119
+ }
12064
12120
  isDisabled = () => {
12121
+ if (this.isWindowsAuth)
12122
+ return this.isLoggingIn;
12065
12123
  return !this.f.username.value || !this.f.password.value || this.isLoggingIn;
12066
12124
  };
12067
12125
  onSubmit() {
12126
+ if (this.isWindowsAuth) {
12127
+ this.loginWithWindows();
12128
+ return;
12129
+ }
12068
12130
  const loginRequest = {
12069
12131
  username: this.f.username.value,
12070
12132
  password: this.f.password.value
@@ -12087,12 +12149,32 @@ class TruLogin {
12087
12149
  });
12088
12150
  }
12089
12151
  }
12152
+ loginWithWindows() {
12153
+ this.isLoggingIn = true;
12154
+ this.auth
12155
+ .login(null).pipe(finalize(() => {
12156
+ this.isLoggingIn = false;
12157
+ }))
12158
+ .subscribe(() => {
12159
+ this.isLoggingIn = false;
12160
+ }, (error) => {
12161
+ if (error.status === 401) {
12162
+ this.loginError = "Windows authentication failed";
12163
+ }
12164
+ else if (error.status === 403) {
12165
+ this.loginError = error.error || "Your Windows account is not authorized for this application";
12166
+ }
12167
+ else {
12168
+ this.loginError = "Invalid Login - Error: " + error.status;
12169
+ }
12170
+ });
12171
+ }
12090
12172
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TruLogin, deps: [{ token: TruAuth }, { token: TruAppEnvironment }], target: i0.ɵɵFactoryTarget.Component });
12091
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", 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\" [type]=\"passwordVisible ? 'text' : 'password'\">\r\n <button class=\"visibility-button\" [disableRipple]=\"true\" type=\"button\" mat-icon-button matSuffix (click)=\"passwordVisible = !passwordVisible\">\r\n <mat-icon class=\"visibility\" *ngIf=\"passwordVisible\" [svgIcon]=\"'visibility-icon'\">visibility-icon</mat-icon>\r\n <mat-icon class=\"visibility-off\" *ngIf=\"!passwordVisible\" [svgIcon]=\"'visibility-off-icon'\">visibility-off-icon</mat-icon>\r\n </button>\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}::ng-deep .login-wrapper .mat-mdc-icon-button.mat-mdc-button-base{height:20px;width:20px;padding:0!important}::ng-deep .login-wrapper .mat-icon{height:20px;width:30px;vertical-align:middle}::ng-deep .login-wrapper .material-icons{font-size:18px}::ng-deep .login-wrapper .visibility svg{fill:#006dcc;height:18px;width:18px;margin-top:5px}::ng-deep .login-wrapper .visibility-off svg{fill:#787878;height:18px;width:18px;margin-top:5px}::ng-deep .login-wrapper .visibility-button{--mat-text-button-state-layer-color: none}::ng-deep .login-wrapper button:focus{outline:none!important}::ng-deep .login-wrapper .mat-button-focus-overlay{display:none!important}::ng-deep .login-wrapper .mat-mdc-button-persistent-ripple{display:none!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: i3.MatIconButton, selector: "button[mat-icon-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: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.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: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i8.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: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i8.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i8.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
12173
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", 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 <ng-container *ngIf=\"isWindowsAuth; else passwordLogin\"></ng-container>\r\n <ng-template #passwordLogin>\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\" [type]=\"passwordVisible ? 'text' : 'password'\">\r\n <button class=\"visibility-button\" [disableRipple]=\"true\" type=\"button\" mat-icon-button matSuffix (click)=\"passwordVisible = !passwordVisible\">\r\n <mat-icon class=\"visibility\" *ngIf=\"passwordVisible\" [svgIcon]=\"'visibility-icon'\">visibility-icon</mat-icon>\r\n <mat-icon class=\"visibility-off\" *ngIf=\"!passwordVisible\" [svgIcon]=\"'visibility-off-icon'\">visibility-off-icon</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </ng-template>\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 *ngIf=\"!isWindowsAuth\">\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}::ng-deep .login-wrapper .mat-mdc-icon-button.mat-mdc-button-base{height:20px;width:20px;padding:0!important}::ng-deep .login-wrapper .mat-icon{height:20px;width:30px;vertical-align:middle}::ng-deep .login-wrapper .material-icons{font-size:18px}::ng-deep .login-wrapper .visibility svg{fill:#006dcc;height:18px;width:18px;margin-top:5px}::ng-deep .login-wrapper .visibility-off svg{fill:#787878;height:18px;width:18px;margin-top:5px}::ng-deep .login-wrapper .visibility-button{--mat-text-button-state-layer-color: none}::ng-deep .login-wrapper button:focus{outline:none!important}::ng-deep .login-wrapper .mat-button-focus-overlay{display:none!important}::ng-deep .login-wrapper .mat-mdc-button-persistent-ripple{display:none!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: i3.MatIconButton, selector: "button[mat-icon-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: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.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: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i8.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i8.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: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i8.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i8.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
12092
12174
  }
12093
12175
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TruLogin, decorators: [{
12094
12176
  type: Component,
12095
- 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\" [type]=\"passwordVisible ? 'text' : 'password'\">\r\n <button class=\"visibility-button\" [disableRipple]=\"true\" type=\"button\" mat-icon-button matSuffix (click)=\"passwordVisible = !passwordVisible\">\r\n <mat-icon class=\"visibility\" *ngIf=\"passwordVisible\" [svgIcon]=\"'visibility-icon'\">visibility-icon</mat-icon>\r\n <mat-icon class=\"visibility-off\" *ngIf=\"!passwordVisible\" [svgIcon]=\"'visibility-off-icon'\">visibility-off-icon</mat-icon>\r\n </button>\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}::ng-deep .login-wrapper .mat-mdc-icon-button.mat-mdc-button-base{height:20px;width:20px;padding:0!important}::ng-deep .login-wrapper .mat-icon{height:20px;width:30px;vertical-align:middle}::ng-deep .login-wrapper .material-icons{font-size:18px}::ng-deep .login-wrapper .visibility svg{fill:#006dcc;height:18px;width:18px;margin-top:5px}::ng-deep .login-wrapper .visibility-off svg{fill:#787878;height:18px;width:18px;margin-top:5px}::ng-deep .login-wrapper .visibility-button{--mat-text-button-state-layer-color: none}::ng-deep .login-wrapper button:focus{outline:none!important}::ng-deep .login-wrapper .mat-button-focus-overlay{display:none!important}::ng-deep .login-wrapper .mat-mdc-button-persistent-ripple{display:none!important}\n"] }]
12177
+ 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 <ng-container *ngIf=\"isWindowsAuth; else passwordLogin\"></ng-container>\r\n <ng-template #passwordLogin>\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\" [type]=\"passwordVisible ? 'text' : 'password'\">\r\n <button class=\"visibility-button\" [disableRipple]=\"true\" type=\"button\" mat-icon-button matSuffix (click)=\"passwordVisible = !passwordVisible\">\r\n <mat-icon class=\"visibility\" *ngIf=\"passwordVisible\" [svgIcon]=\"'visibility-icon'\">visibility-icon</mat-icon>\r\n <mat-icon class=\"visibility-off\" *ngIf=\"!passwordVisible\" [svgIcon]=\"'visibility-off-icon'\">visibility-off-icon</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n </ng-template>\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 *ngIf=\"!isWindowsAuth\">\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}::ng-deep .login-wrapper .mat-mdc-icon-button.mat-mdc-button-base{height:20px;width:20px;padding:0!important}::ng-deep .login-wrapper .mat-icon{height:20px;width:30px;vertical-align:middle}::ng-deep .login-wrapper .material-icons{font-size:18px}::ng-deep .login-wrapper .visibility svg{fill:#006dcc;height:18px;width:18px;margin-top:5px}::ng-deep .login-wrapper .visibility-off svg{fill:#787878;height:18px;width:18px;margin-top:5px}::ng-deep .login-wrapper .visibility-button{--mat-text-button-state-layer-color: none}::ng-deep .login-wrapper button:focus{outline:none!important}::ng-deep .login-wrapper .mat-button-focus-overlay{display:none!important}::ng-deep .login-wrapper .mat-mdc-button-persistent-ripple{display:none!important}\n"] }]
12096
12178
  }], ctorParameters: () => [{ type: TruAuth }, { type: TruAppEnvironment }] });
12097
12179
 
12098
12180
  class TruAuthJwtStrategy {
@@ -12169,7 +12251,7 @@ class TruAuthInterceptor {
12169
12251
  intercept(request, next) {
12170
12252
  if (this.appEnvironment.authType === 'jwt')
12171
12253
  request = this.addToken(request, String(this.jwt.getToken()));
12172
- if (this.appEnvironment.authType === 'session')
12254
+ if (this.appEnvironment.authType === 'session' || this.appEnvironment.authType === 'windows')
12173
12255
  request = request.clone({
12174
12256
  withCredentials: true
12175
12257
  });
@@ -12252,6 +12334,19 @@ class TruAuthSessionStrategy {
12252
12334
  }
12253
12335
  }
12254
12336
 
12337
+ class TruAuthWindowsStrategy {
12338
+ doLoginUser(user) {
12339
+ }
12340
+ doLogoutUser() {
12341
+ }
12342
+ createUser(user) {
12343
+ return of({});
12344
+ }
12345
+ isLoggedIn() {
12346
+ return false;
12347
+ }
12348
+ }
12349
+
12255
12350
  const TruAuthStrategyProvider = {
12256
12351
  provide: TRU_AUTH_STRATEGY,
12257
12352
  deps: [HttpClient, TruAppEnvironment],
@@ -12261,6 +12356,8 @@ const TruAuthStrategyProvider = {
12261
12356
  return new TruAuthSessionStrategy(http);
12262
12357
  case "jwt":
12263
12358
  return new TruAuthJwtStrategy();
12359
+ case "windows":
12360
+ return new TruAuthWindowsStrategy();
12264
12361
  default:
12265
12362
  throw new Error("Invalid auth strategy");
12266
12363
  }
@@ -14414,5 +14511,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
14414
14511
  * Generated bundle index. Do not edit.
14415
14512
  */
14416
14513
 
14417
- export { TruAboutDialog, TruActionInvoke, TruAppEnvironment, TruAppSettingsDialog, TruAuth, TruAuthInterceptor, TruBreezeContext, TruBreezeContextFactory, TruBreezeMetadataProvider, TruBreezeValidator, TruCard, TruCardColumn, TruCardColumnData, TruCardColumnSearchResultsConfigBase, TruChoice, TruCloneView, TruCloudFileManager, TruColumn, TruCommonModule, TruComponentConfigBase, TruComponentLookup, TruConfirmDialog, TruConfirmDialogConfig, TruConnectionHub, TruContextFilter, TruContextFilterChoice, TruContextFilters, TruControlComponentConfigBase, TruCountries, TruDataChange, TruDataContext, TruDataGrid, TruDataGridCellRenderer, TruDataGridHeader, TruDataGridHeaderFilter, TruDataGridPkeyCellRenderer, TruDataGridRefHeader, TruDataGridTypes, TruDataGridUtil, TruDesktop, TruDesktopEventHandler, TruDesktopManager, TruDesktopViewConfig, TruDesktopViewEventNotifier, TruDetailViewBase, TruEditControlBase, TruEditControlConfigBase, TruEditParentControlConfigBase, TruEditPkeyControlConfigBase, TruEntityAccessor, TruEntityBase, TruErrorDialog, TruErrorInterceptor, TruExportDialog, TruExportDialogConfig, TruForm, TruFormatter, TruFormulaEval, TruGlobalDataContext, TruGridValidationDialog, TruGridValidationDialogConfig, TruGroupBox, TruIconModule, TruIframeView, TruIframeViewConfig, TruListControlConfigBase, TruLogin, TruLoginModule, TruMatSelectPanel, TruModelNavigationPropertiesLookup, TruModelPropertyLookup, TruModelTableLookup, TruModelTypeLookup, TruNameValue, TruNavigationPropertiesConfig, TruNavigationPropertyConfig, TruPasswordDialog, TruPredicate, TruPredicateMap, TruPropertyConfigBase, TruPropertyConfigCloudFile, TruPropertyConfigDate, TruPropertyConfigDecimal, TruPropertyConfigFile, TruPropertyConfigForeignKey, TruPropertyConfigInteger, TruPropertyConfigPassword, TruPropertyConfigPercentage, TruPropertyConfigScientific, TruPropertyConfigText, TruPropertyConfigTextChoices, TruPropertyConfigUsaAddress, TruPropertyConfigZipCode, TruQueryPredicateManager, TruReportManager, TruRow, TruSearchConfigBase, TruSearchControlBase, TruSearchControlConfigBase, TruSearchControlParentBase, TruSearchControlRangeBase, TruSearchIconModule, TruSearchPanelPositionManager, TruSearchResultViewBase, TruSearchResultViewManager, TruSearchViewBase, TruSearchViewControlEventHandler, TruSearchViewEventHandler, TruSort, TruTab, TruTabGroup, TruTableConfigBase, TruTextManager, TruToolbar, TruToolbarAppCustomization, TruToolbarButton, TruToolbarContextFilter, TruToolbarDropdown, TruToolbarMenu, TruToolbarSeparator, TruToolbarText, TruToolbarTextbox, TruToolbarUserProfile, TruUiNotification, TruUser, TruUserPreferenceManager, TruUtil, TruValidationDialog, TruValidationDialogConfig, TruValidationDialogContext, TruValidatorFactory, TruViewBase, TruViewMenuConfig, TruWindowActionEventHandler, TruWindowCloseEventArgs, TruWindowEventArgs, TruWindowEventHandler, TruWindowManager };
14514
+ export { TruAboutDialog, TruActionInvoke, TruAppEnvironment, TruAppSettingsDialog, TruAuth, TruAuthInterceptor, TruBreezeContext, TruBreezeContextFactory, TruBreezeMetadataProvider, TruBreezeValidator, TruCard, TruCardColumn, TruCardColumnData, TruCardColumnSearchResultsConfigBase, TruChoice, TruCloneView, TruCloudFileManager, TruColumn, TruCommonModule, TruComponentConfigBase, TruComponentLookup, TruConfirmDialog, TruConfirmDialogConfig, TruConnectionHub, TruContextFilter, TruContextFilterChoice, TruContextFilters, TruControlComponentConfigBase, TruCountries, TruDataChange, TruDataContext, TruDataGrid, TruDataGridCellRenderer, TruDataGridHeader, TruDataGridHeaderFilter, TruDataGridPkeyCellRenderer, TruDataGridRefHeader, TruDataGridTypes, TruDataGridUtil, TruDesktop, TruDesktopEventHandler, TruDesktopManager, TruDesktopViewConfig, TruDesktopViewEventNotifier, TruDetailViewBase, TruEditControlBase, TruEditControlConfigBase, TruEditParentControlConfigBase, TruEditPkeyControlConfigBase, TruEntityAccessor, TruEntityBase, TruEntityMetadataRegistry, TruErrorDialog, TruErrorInterceptor, TruExportDialog, TruExportDialogConfig, TruForm, TruFormatter, TruFormulaEval, TruGlobalDataContext, TruGridValidationDialog, TruGridValidationDialogConfig, TruGroupBox, TruIconModule, TruIframeView, TruIframeViewConfig, TruListControlConfigBase, TruLogin, TruLoginModule, TruMatSelectPanel, TruModelNavigationPropertiesLookup, TruModelPropertyLookup, TruModelTableLookup, TruModelTypeLookup, TruNameValue, TruNavigationPropertiesConfig, TruNavigationPropertyConfig, TruPasswordDialog, TruPredicate, TruPredicateMap, TruPropertyConfigBase, TruPropertyConfigCloudFile, TruPropertyConfigDate, TruPropertyConfigDecimal, TruPropertyConfigFile, TruPropertyConfigForeignKey, TruPropertyConfigInteger, TruPropertyConfigPassword, TruPropertyConfigPercentage, TruPropertyConfigScientific, TruPropertyConfigText, TruPropertyConfigTextChoices, TruPropertyConfigUsaAddress, TruPropertyConfigZipCode, TruQueryPredicateManager, TruReportManager, TruRow, TruSearchConfigBase, TruSearchControlBase, TruSearchControlConfigBase, TruSearchControlParentBase, TruSearchControlRangeBase, TruSearchIconModule, TruSearchPanelPositionManager, TruSearchResultViewBase, TruSearchResultViewManager, TruSearchViewBase, TruSearchViewControlEventHandler, TruSearchViewEventHandler, TruSort, TruTab, TruTabGroup, TruTableConfigBase, TruTextManager, TruToolbar, TruToolbarAppCustomization, TruToolbarButton, TruToolbarContextFilter, TruToolbarDropdown, TruToolbarMenu, TruToolbarSeparator, TruToolbarText, TruToolbarTextbox, TruToolbarUserProfile, TruUiNotification, TruUser, TruUserPreferenceManager, TruUtil, TruValidationDialog, TruValidationDialogConfig, TruValidationDialogContext, TruValidatorFactory, TruViewBase, TruViewMenuConfig, TruWindowActionEventHandler, TruWindowCloseEventArgs, TruWindowEventArgs, TruWindowEventHandler, TruWindowManager };
14418
14515
  //# sourceMappingURL=trudb-tru-common-lib.mjs.map