novo-elements 5.10.0 → 5.13.0

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.
Files changed (31) hide show
  1. package/bundles/novo-elements.umd.js +99 -35
  2. package/bundles/novo-elements.umd.js.map +1 -1
  3. package/bundles/novo-elements.umd.min.js +1 -1
  4. package/bundles/novo-elements.umd.min.js.map +1 -1
  5. package/elements/data-table/cell-headers/data-table-checkbox-header-cell.component.d.ts +2 -0
  6. package/elements/data-table/data-table.component.d.ts +5 -0
  7. package/elements/date-picker/DatePicker.d.ts +1 -0
  8. package/elements/date-picker/DatePicker.scss +7 -1
  9. package/elements/date-picker/DatePickerInput.d.ts +6 -0
  10. package/elements/date-time-picker/DateTimePicker.d.ts +1 -0
  11. package/elements/date-time-picker/DateTimePickerInput.d.ts +1 -0
  12. package/elements/form/Form.scss +2 -1
  13. package/elements/form/NovoFormControl.d.ts +1 -0
  14. package/elements/form/controls/BaseControl.d.ts +1 -0
  15. package/esm2015/elements/data-table/cell-headers/data-table-checkbox-header-cell.component.js +27 -2
  16. package/esm2015/elements/data-table/data-table.component.js +10 -2
  17. package/esm2015/elements/date-picker/DatePicker.js +3 -2
  18. package/esm2015/elements/date-picker/DatePickerInput.js +28 -2
  19. package/esm2015/elements/date-time-picker/DateTimePicker.js +3 -1
  20. package/esm2015/elements/date-time-picker/DateTimePickerInput.js +3 -1
  21. package/esm2015/elements/form/ControlTemplates.js +2 -2
  22. package/esm2015/elements/form/NovoFormControl.js +2 -1
  23. package/esm2015/elements/form/controls/BaseControl.js +2 -1
  24. package/esm2015/services/date-format/DateFormat.js +4 -2
  25. package/esm2015/utils/form-utils/FormUtils.js +17 -17
  26. package/fesm2015/novo-elements.js +90 -22
  27. package/fesm2015/novo-elements.js.map +1 -1
  28. package/novo-elements.metadata.json +1 -1
  29. package/package.json +1 -1
  30. package/services/date-format/DateFormat.d.ts +2 -2
  31. package/utils/form-utils/FormUtils.d.ts +3 -3
@@ -8327,8 +8327,10 @@ class NovoDataTable {
8327
8327
  this.templates = {};
8328
8328
  this.fixedHeader = false;
8329
8329
  this.maxSelected = undefined;
8330
+ this.canSelectAll = false;
8330
8331
  this._hideGlobalSearch = true;
8331
8332
  this.preferencesChanged = new EventEmitter();
8333
+ this.allSelected = new EventEmitter();
8332
8334
  this.loading = true;
8333
8335
  this.columnToTemplate = {};
8334
8336
  this.columnsLoaded = false;
@@ -8614,6 +8616,10 @@ class NovoDataTable {
8614
8616
  this.state.onSelectionChange();
8615
8617
  }
8616
8618
  allCurrentRowsSelected() {
8619
+ var _a, _b;
8620
+ if (!((_b = (_a = this.dataSource) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.length)) {
8621
+ return false;
8622
+ }
8617
8623
  for (let i = 0; i < (this.dataSource.data || []).length; i++) {
8618
8624
  if (!this.isSelected((this.dataSource.data || [])[i])) {
8619
8625
  return false;
@@ -8773,7 +8779,7 @@ NovoDataTable.decorators = [
8773
8779
  [hidden]="dataSource?.totallyEmpty && !state.userFiltered"
8774
8780
  >
8775
8781
  <ng-container cdkColumnDef="selection">
8776
- <novo-data-table-checkbox-header-cell *cdkHeaderCellDef [maxSelected]="maxSelected"></novo-data-table-checkbox-header-cell>
8782
+ <novo-data-table-checkbox-header-cell *cdkHeaderCellDef [maxSelected]="maxSelected" [canSelectAll]="canSelectAll"></novo-data-table-checkbox-header-cell>
8777
8783
  <novo-data-table-checkbox-cell *cdkCellDef="let row; let i = index" [row]="row" [maxSelected]="maxSelected"></novo-data-table-checkbox-cell>
8778
8784
  </ng-container>
8779
8785
  <ng-container cdkColumnDef="expand">
@@ -8956,6 +8962,7 @@ NovoDataTable.propDecorators = {
8956
8962
  fixedHeader: [{ type: Input }],
8957
8963
  paginatorDataFeatureId: [{ type: Input }],
8958
8964
  maxSelected: [{ type: Input }],
8965
+ canSelectAll: [{ type: Input }],
8959
8966
  dataTableService: [{ type: Input }],
8960
8967
  rows: [{ type: Input }],
8961
8968
  outsideFilter: [{ type: Input }],
@@ -8966,6 +8973,7 @@ NovoDataTable.propDecorators = {
8966
8973
  forceShowHeader: [{ type: Input }],
8967
8974
  hideGlobalSearch: [{ type: Input }],
8968
8975
  preferencesChanged: [{ type: Output }],
8976
+ allSelected: [{ type: Output }],
8969
8977
  empty: [{ type: HostBinding, args: ['class.empty',] }],
8970
8978
  loadingClass: [{ type: HostBinding, args: ['class.loading',] }],
8971
8979
  listInteractions: [{ type: Input }]
@@ -28941,7 +28949,7 @@ NovoDatePickerElement.decorators = [
28941
28949
  endfill: isEndFill(range, day.date, selected, selected2),
28942
28950
  'selecting-range': isSelectingRange(range, day.date, selected, selected2, hoverDay, rangeSelectMode, weekRangeSelect)
28943
28951
  }" (mouseover)="rangeHover($event, day)" [attr.data-automation-id]="day.number">
28944
- <button class="day" [attr.data-automation-id]="day.number" [disabled]="isDisabled(day.date, start, end)" (click)="select($event, day, true)">{{day.number}}</button>
28952
+ <button [title]="isDisabled(day.date, start, end) ? disabledDateMessage : ''" class="day" [attr.data-automation-id]="day.number" [disabled]="isDisabled(day.date, start, end)" (click)="select($event, day, true)">{{day.number}}</button>
28945
28953
  </td>
28946
28954
  </tr>
28947
28955
  </tbody>
@@ -28976,6 +28984,7 @@ NovoDatePickerElement.propDecorators = {
28976
28984
  range: [{ type: Input }],
28977
28985
  weekRangeSelect: [{ type: Input }],
28978
28986
  weekStart: [{ type: Input }],
28987
+ disabledDateMessage: [{ type: Input }],
28979
28988
  onSelect: [{ type: Output }]
28980
28989
  };
28981
28990
 
@@ -29031,6 +29040,7 @@ class DateFormatService {
29031
29040
  let month;
29032
29041
  let day;
29033
29042
  let date = new Date();
29043
+ let isInvalidDate = true;
29034
29044
  if (Helpers.isEmpty(dateFormat)) {
29035
29045
  // Default to MM/dd/yyyy
29036
29046
  dateFormat = 'mm/dd/yyyy';
@@ -29054,6 +29064,7 @@ class DateFormatService {
29054
29064
  }
29055
29065
  if (month >= 0 && month <= 11 && year > 1900 && day > 0 && day <= 31) {
29056
29066
  date = new Date(year, month, day);
29067
+ isInvalidDate = false;
29057
29068
  }
29058
29069
  }
29059
29070
  else if (dateFormatTokens && dateFormatTokens.length === 4 && dateString.length >= 1) {
@@ -29068,7 +29079,7 @@ class DateFormatService {
29068
29079
  dateString = `${dateString}${delimiter[1]}`;
29069
29080
  }
29070
29081
  }
29071
- return [date, dateString];
29082
+ return [date, dateString, isInvalidDate];
29072
29083
  }
29073
29084
  parseTimeString(timeString, militaryTime) {
29074
29085
  const value = new Date();
@@ -29178,6 +29189,7 @@ class NovoDatePickerInputElement {
29178
29189
  this._changeDetectorRef = _changeDetectorRef;
29179
29190
  this.dateFormatService = dateFormatService;
29180
29191
  this.formattedValue = '';
29192
+ this.invalidDateErrorMessage = '';
29181
29193
  /** View -> model callback called when value changes */
29182
29194
  this._onChange = () => { };
29183
29195
  /** View -> model callback called when autocomplete has been touched */
@@ -29204,6 +29216,7 @@ class NovoDatePickerInputElement {
29204
29216
  else {
29205
29217
  this.maskOptions = { mask: false };
29206
29218
  }
29219
+ this.setupInvalidDateErrorMessage();
29207
29220
  }
29208
29221
  /** BEGIN: Convenient Panel Methods. */
29209
29222
  openPanel() {
@@ -29231,9 +29244,11 @@ class NovoDatePickerInputElement {
29231
29244
  }
29232
29245
  }
29233
29246
  _handleBlur(event) {
29247
+ this.handleInvalidDate();
29234
29248
  this.blurEvent.emit(event);
29235
29249
  }
29236
29250
  _handleFocus(event) {
29251
+ this.showInvalidDateError = false;
29237
29252
  this.openPanel();
29238
29253
  this.focusEvent.emit(event);
29239
29254
  }
@@ -29250,7 +29265,8 @@ class NovoDatePickerInputElement {
29250
29265
  }
29251
29266
  formatDate(value, blur) {
29252
29267
  try {
29253
- const [dateTimeValue, formatted] = this.dateFormatService.parseString(value, false, 'date');
29268
+ const [dateTimeValue, formatted, isInvalidDate] = this.dateFormatService.parseString(value, false, 'date');
29269
+ this.isInvalidDate = isInvalidDate;
29254
29270
  if (!isNaN(dateTimeValue.getUTCDate())) {
29255
29271
  const dt = new Date(dateTimeValue);
29256
29272
  this.dispatchOnChange(dt, blur);
@@ -29273,6 +29289,24 @@ class NovoDatePickerInputElement {
29273
29289
  setDisabledState(disabled) {
29274
29290
  this.disabled = disabled;
29275
29291
  }
29292
+ handleInvalidDate() {
29293
+ if (this.isInvalidDate && this.value) {
29294
+ this.showInvalidDateError = true;
29295
+ this.clearValue();
29296
+ this.closePanel();
29297
+ }
29298
+ }
29299
+ setupInvalidDateErrorMessage() {
29300
+ let dateFormat = this.labels.dateFormatString();
29301
+ if (Helpers.isEmpty(dateFormat)) {
29302
+ // Default to mm/dd/yyyy
29303
+ dateFormat = 'mm/dd/yyyy';
29304
+ }
29305
+ else {
29306
+ dateFormat = dateFormat.toLowerCase();
29307
+ }
29308
+ this.invalidDateErrorMessage = `Invalid date field entered. Date format of ${dateFormat} is required.`;
29309
+ }
29276
29310
  dispatchOnChange(newValue, blur = false, skip = false) {
29277
29311
  if (newValue !== this.value) {
29278
29312
  this._onChange(newValue);
@@ -29373,6 +29407,7 @@ NovoDatePickerInputElement.decorators = [
29373
29407
  data-automation-id="date-input"
29374
29408
  [disabled]="disabled"
29375
29409
  />
29410
+ <span class="error-text" *ngIf="showInvalidDateError">{{invalidDateErrorMessage}}</span>
29376
29411
  <i *ngIf="!hasValue" (click)="openPanel()" class="bhi-calendar"></i>
29377
29412
  <i *ngIf="hasValue" (click)="clearValue()" class="bhi-times"></i>
29378
29413
  <novo-overlay-template [parent]="element" position="above-below">
@@ -29381,6 +29416,7 @@ NovoDatePickerInputElement.decorators = [
29381
29416
  [end]="end"
29382
29417
  inline="true"
29383
29418
  (onSelect)="setValueAndClose($event)"
29419
+ [disabledDateMessage]="disabledDateMessage"
29384
29420
  [ngModel]="value"
29385
29421
  [weekStart]="weekStart"
29386
29422
  ></novo-date-picker>
@@ -29403,6 +29439,7 @@ NovoDatePickerInputElement.propDecorators = {
29403
29439
  format: [{ type: Input }],
29404
29440
  textMaskEnabled: [{ type: Input }],
29405
29441
  allowInvalidDate: [{ type: Input }],
29442
+ disabledDateMessage: [{ type: Input }],
29406
29443
  disabled: [{ type: HostBinding, args: ['class.disabled',] }, { type: Input }],
29407
29444
  weekStart: [{ type: Input }],
29408
29445
  blurEvent: [{ type: Output }],
@@ -29895,28 +29932,41 @@ class NovoDataTableCheckboxHeaderCell extends CdkHeaderCell {
29895
29932
  this.toaster = toaster;
29896
29933
  this.role = 'columnheader';
29897
29934
  this.maxSelected = undefined;
29935
+ this.canSelectAll = false;
29898
29936
  this.checked = false;
29899
29937
  renderer.setAttribute(elementRef.nativeElement, 'data-automation-id', `novo-checkbox-column-header-${columnDef.cssClassFriendlyName}`);
29900
29938
  renderer.addClass(elementRef.nativeElement, `novo-checkbox-column-${columnDef.cssClassFriendlyName}`);
29901
29939
  renderer.addClass(elementRef.nativeElement, 'novo-data-table-checkbox-header-cell');
29902
29940
  this.selectionSubscription = this.dataTable.state.selectionSource.subscribe(() => {
29903
29941
  this.checked = this.dataTable.allCurrentRowsSelected();
29942
+ if (this.canSelectAll) {
29943
+ this.selectAllChanged();
29944
+ }
29904
29945
  this.ref.markForCheck();
29905
29946
  });
29906
29947
  this.paginationSubscription = this.dataTable.state.paginationSource.subscribe((event) => {
29907
29948
  if (event.isPageSizeChange) {
29908
29949
  this.checked = false;
29950
+ if (this.canSelectAll) {
29951
+ this.selectAllChanged();
29952
+ }
29909
29953
  this.dataTable.selectRows(false);
29910
29954
  this.dataTable.state.checkRetainment('pageSize');
29911
29955
  this.dataTable.state.reset(false, true);
29912
29956
  }
29913
29957
  else {
29914
29958
  this.checked = this.dataTable.allCurrentRowsSelected();
29959
+ if (this.canSelectAll) {
29960
+ this.selectAllChanged();
29961
+ }
29915
29962
  }
29916
29963
  this.ref.markForCheck();
29917
29964
  });
29918
29965
  this.resetSubscription = this.dataTable.state.resetSource.subscribe(() => {
29919
29966
  this.checked = false;
29967
+ if (this.canSelectAll) {
29968
+ this.selectAllChanged();
29969
+ }
29920
29970
  this.ref.markForCheck();
29921
29971
  });
29922
29972
  }
@@ -29946,6 +29996,17 @@ class NovoDataTableCheckboxHeaderCell extends CdkHeaderCell {
29946
29996
  else {
29947
29997
  this.dataTable.selectRows(!this.checked);
29948
29998
  }
29999
+ if (this.canSelectAll) {
30000
+ this.selectAllChanged();
30001
+ }
30002
+ }
30003
+ selectAllChanged() {
30004
+ var _a, _b, _c;
30005
+ const allSelectedEvent = {
30006
+ allSelected: this.checked,
30007
+ selectedCount: (_c = (_b = (_a = this.dataTable) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.selected) === null || _c === void 0 ? void 0 : _c.length,
30008
+ };
30009
+ this.dataTable.allSelected.emit(allSelectedEvent);
29949
30010
  }
29950
30011
  }
29951
30012
  NovoDataTableCheckboxHeaderCell.decorators = [
@@ -29973,7 +30034,8 @@ NovoDataTableCheckboxHeaderCell.ctorParameters = () => [
29973
30034
  ];
29974
30035
  NovoDataTableCheckboxHeaderCell.propDecorators = {
29975
30036
  role: [{ type: HostBinding, args: ['attr.role',] }],
29976
- maxSelected: [{ type: Input }]
30037
+ maxSelected: [{ type: Input }],
30038
+ canSelectAll: [{ type: Input }]
29977
30039
  };
29978
30040
 
29979
30041
  class NovoDataTableHeaderCell extends CdkHeaderCell {
@@ -30680,6 +30742,7 @@ NovoDateTimePickerElement.decorators = [
30680
30742
  [maxYear]="maxYear"
30681
30743
  [start]="start"
30682
30744
  [end]="end"
30745
+ [disabledDateMessage]="disabledDateMessage"
30683
30746
  [weekStart]="weekStart"
30684
30747
  ></novo-date-picker>
30685
30748
  </div>
@@ -30702,6 +30765,7 @@ NovoDateTimePickerElement.propDecorators = {
30702
30765
  end: [{ type: Input }],
30703
30766
  military: [{ type: Input }],
30704
30767
  weekStart: [{ type: Input }],
30768
+ disabledDateMessage: [{ type: Input }],
30705
30769
  onSelect: [{ type: Output }]
30706
30770
  };
30707
30771
 
@@ -30813,6 +30877,7 @@ NovoDateTimePickerInputElement.decorators = [
30813
30877
  (ngModelChange)="updateDate($event)"
30814
30878
  [start]="start"
30815
30879
  [end]="end"
30880
+ [disabledDateMessage]="disabledDateMessage"
30816
30881
  [maskOptions]="maskOptions"
30817
30882
  (blurEvent)="handleBlur($event)"
30818
30883
  (focusEvent)="handleFocus($event)"
@@ -30845,6 +30910,7 @@ NovoDateTimePickerInputElement.propDecorators = {
30845
30910
  disabled: [{ type: Input }],
30846
30911
  format: [{ type: Input }],
30847
30912
  weekStart: [{ type: Input }],
30913
+ disabledDateMessage: [{ type: Input }],
30848
30914
  blurEvent: [{ type: Output }],
30849
30915
  focusEvent: [{ type: Output }],
30850
30916
  changeEvent: [{ type: Output }]
@@ -31737,6 +31803,7 @@ class BaseControl extends ControlConfig {
31737
31803
  this.isEmpty = config.isEmpty;
31738
31804
  }
31739
31805
  this.weekStart = config.weekStart || 0;
31806
+ this.disabledDateMessage = config.disabledDateMessage;
31740
31807
  }
31741
31808
  }
31742
31809
 
@@ -32183,6 +32250,7 @@ class NovoFormControl extends FormControl {
32183
32250
  this.tipWell = control.tipWell;
32184
32251
  this.customControlConfig = control.customControlConfig;
32185
32252
  this.warning = control.warning;
32253
+ this.disabledDateMessage = control.disabledDateMessage;
32186
32254
  // Reactive Form, need to enable/disable, can't bind to [disabled]
32187
32255
  if (this.readOnly) {
32188
32256
  this.disable();
@@ -32558,7 +32626,7 @@ class FormUtils {
32558
32626
  closeOnSelect: field.closeOnSelect,
32559
32627
  layoutOptions: field.layoutOptions,
32560
32628
  };
32561
- this.inferStartDate(controlConfig, field);
32629
+ this.inferDateRange(controlConfig, field);
32562
32630
  // TODO: getControlOptions should always return the correct format
32563
32631
  const optionsConfig = this.getControlOptions(field, http, config, fieldData);
32564
32632
  if (Array.isArray(optionsConfig) && !(type === 'chips' || type === 'picker')) {
@@ -33069,23 +33137,23 @@ class FormUtils {
33069
33137
  return addDays(startOfToday(), dateRange.minOffset);
33070
33138
  }
33071
33139
  }
33072
- /**
33073
- * Get the min start date of a Date base on field data.
33074
- */
33075
- getStartDate(field) {
33076
- if (field.allowedDateRange) {
33077
- return this.getStartDateFromRange(field.allowedDateRange);
33140
+ getEndDateFromRange(dateRange) {
33141
+ if (dateRange.maxDate) {
33142
+ return parse(dateRange.maxDate);
33143
+ }
33144
+ else if (dateRange.minOffset) {
33145
+ return addDays(startOfToday(), dateRange.minOffset);
33078
33146
  }
33079
- // there is no restriction on the start date
33080
- return null;
33081
33147
  }
33082
- inferStartDate(controlConfig, field) {
33083
- if (field.dataType === 'Date') {
33084
- const startDate = this.getStartDate(field);
33085
- if (startDate) {
33086
- controlConfig.startDate = startDate;
33087
- }
33088
- return startDate;
33148
+ /**
33149
+ * Get the min start date and max end date of a Date base on field data.
33150
+ */
33151
+ inferDateRange(controlConfig, field) {
33152
+ var _a;
33153
+ if (field.dataType === 'Date' && field.allowedDateRange) {
33154
+ controlConfig.startDate = this.getStartDateFromRange(field.allowedDateRange);
33155
+ controlConfig.endDate = this.getEndDateFromRange(field.allowedDateRange);
33156
+ controlConfig.disabledDateMessage = (_a = field.allowedDateRange) === null || _a === void 0 ? void 0 : _a.disabledDateMessage;
33089
33157
  }
33090
33158
  }
33091
33159
  inflateEmbeddedProperties(data) {
@@ -35053,7 +35121,7 @@ NovoControlTemplates.decorators = [
35053
35121
  <!--Date-->
35054
35122
  <ng-template novoTemplate="date" let-control let-form="form" let-errors="errors" let-methods="methods">
35055
35123
  <div [formGroup]="form" class="novo-control-input-container" [tooltip]="control.tooltip" [tooltipPosition]="control.tooltipPosition" [tooltipSize]="control?.tooltipSize" [tooltipPreline]="control?.tooltipPreline" [removeTooltipArrow]="control?.removeTooltipArrow" [tooltipAutoPosition]="control?.tooltipAutoPosition">
35056
- <novo-date-picker-input [attr.id]="control.key" [name]="control.key" [formControlName]="control.key" [start]="control.startDate" [end]="control.endDate" [format]="control.dateFormat" [allowInvalidDate]="control.allowInvalidDate" [textMaskEnabled]="control.textMaskEnabled" [placeholder]="control.placeholder" [weekStart]="control.weekStart" (focusEvent)="methods.handleFocus($event)" (blurEvent)="methods.handleBlur($event)" (changeEvent)="methods.emitChange($event)"></novo-date-picker-input>
35124
+ <novo-date-picker-input [attr.id]="control.key" [name]="control.key" [formControlName]="control.key" [start]="control.startDate" [end]="control.endDate" [disabledDateMessage]="control.disabledDateMessage" [format]="control.dateFormat" [allowInvalidDate]="control.allowInvalidDate" [textMaskEnabled]="control.textMaskEnabled" [placeholder]="control.placeholder" [weekStart]="control.weekStart" (focusEvent)="methods.handleFocus($event)" (blurEvent)="methods.handleBlur($event)" (changeEvent)="methods.emitChange($event)"></novo-date-picker-input>
35057
35125
  </div>
35058
35126
  </ng-template>
35059
35127