@dereekb/dbx-form 9.25.6 → 9.25.8

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.
@@ -44,7 +44,7 @@ import * as i6 from '@angular/material/chips';
44
44
  import { MatChipsModule } from '@angular/material/chips';
45
45
  import { MatListModule } from '@angular/material/list';
46
46
  import { ENTER, COMMA } from '@angular/cdk/keycodes';
47
- import { skipUntilTimeElapsedAfterLastEmission, toJsDate, parseISO8601DayStringToDate, formatToISO8601DateString, formatToISO8601DayString, isSameDateHoursAndMinutes, safeToJsDate, guessCurrentTimezone, dateTimezoneUtcNormal, toLocalReadableTimeString, getTimezoneAbbreviation, isSameDateDay, utcDayForDate, readableTimeStringToDate, findMinDate, dateFromLogicalDate, findMaxDate, dateTimeMinuteDecisionFunction, DateTimeMinuteInstance, limitDateTimeInstance, isSameDateDayRange, dateRange, clampDateRangeToDateRange, isDateInDateRange, isSameDateRange, allTimezoneInfos, timezoneInfoForSystem, searchTimezoneInfos } from '@dereekb/date';
47
+ import { skipUntilTimeElapsedAfterLastEmission, toJsDate, parseISO8601DayStringToDate, formatToISO8601DateString, formatToISO8601DayString, isSameDateHoursAndMinutes, safeToJsDate, guessCurrentTimezone, dateTimezoneUtcNormal, toJsDayDate, isSameDateDay, toLocalReadableTimeString, getTimezoneAbbreviation, utcDayForDate, readableTimeStringToDate, findMinDate, dateFromLogicalDate, findMaxDate, dateTimeMinuteDecisionFunction, DateTimeMinuteInstance, isSameDate, limitDateTimeInstance, isSameDateDayRange, dateRange, clampDateRangeToDateRange, isDateInDateRange, isSameDateRange, allTimezoneInfos, timezoneInfoForSystem, searchTimezoneInfos } from '@dereekb/date';
48
48
  import { FieldType as FieldType$2, FormlyMatFormFieldModule } from '@ngx-formly/material/form-field';
49
49
  import * as i3$3 from '@angular/material/select';
50
50
  import { MatSelectModule } from '@angular/material/select';
@@ -3827,6 +3827,7 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
3827
3827
  this._config = new BehaviorSubject(undefined);
3828
3828
  this._syncConfigObs = new BehaviorSubject(undefined);
3829
3829
  this._defaultTimezone = new BehaviorSubject(undefined);
3830
+ this._timeDate = new BehaviorSubject(undefined);
3830
3831
  this._presets = new BehaviorSubject(of([]));
3831
3832
  this._fullDayControlObs = new BehaviorSubject(undefined);
3832
3833
  this.fullDayControl$ = this._fullDayControlObs.pipe(filterMaybe());
@@ -3838,6 +3839,7 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
3838
3839
  return defaultTimezone ?? guessCurrentTimezone();
3839
3840
  }), distinctUntilChanged(), shareReplay(1));
3840
3841
  this.timezoneInstance$ = this.timezone$.pipe(map((timezone) => (timezone ? dateTimezoneUtcNormal({ timezone }) : undefined)), shareReplay(1));
3842
+ this.timeDate$ = this._timeDate.pipe(switchMapMaybeDefault(), map((x) => (x ? toJsDayDate(x) : undefined)), distinctUntilChanged(isSameDateDay), shareReplay(1));
3841
3843
  this.valueInSystemTimezone$ = this.formControl$.pipe(map((control) => control.valueChanges.pipe(startWith(control.value), shareReplay(1))), combineLatestWith(this.timezoneInstance$), switchMap(([x, timezoneInstance]) => {
3842
3844
  return x.pipe(map(dbxDateTimeInputValueParseFactory(this.valueMode, timezoneInstance)));
3843
3845
  }), throttleTime(20, undefined, { leading: false, trailing: true }), // throttle incoming values and timezone changes
@@ -3857,7 +3859,7 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
3857
3859
  this.showTimeInput$ = this.fullDay$.pipe(map((x) => !x && this.timeMode !== DbxDateTimeFieldTimeMode.NONE));
3858
3860
  this.showAddTime$ = this.showTimeInput$.pipe(map((x) => !x && this.timeMode === DbxDateTimeFieldTimeMode.OPTIONAL), shareReplay(1));
3859
3861
  this.date$ = this.dateInputCtrl.valueChanges.pipe(startWith(this.dateInputCtrl.value), filterMaybe(), shareReplay(1));
3860
- this.timezoneAbbreviation$ = combineLatest([this.date$, this.timezone$]).pipe(map(([date, timezone]) => getTimezoneAbbreviation(timezone, date)), distinctUntilChanged(), shareReplay(1));
3862
+ this.timezoneAbbreviation$ = combineLatest([this.date$, this.timezone$, this.timeDate$]).pipe(map(([date, timezone, timeDate]) => getTimezoneAbbreviation(timezone, timeDate ?? date)), distinctUntilChanged(), shareReplay(1));
3861
3863
  this.dateValue$ = merge(this.date$, this.valueInSystemTimezone$.pipe(skipFirstMaybe())).pipe(map((x) => (x ? startOfDay(x) : null)), distinctUntilChanged(isSameDateDay), shareReplay(1));
3862
3864
  this.timeInput$ = this._updateTime.pipe(debounceTime(5), map(() => this.timeInputCtrl.value || ''), distinctUntilChanged());
3863
3865
  this.syncConfigObs$ = this._syncConfigObs.pipe(switchMapMaybeDefault(), shareReplay(1));
@@ -3887,10 +3889,10 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
3887
3889
  // TODO: Get min/max using the DateTimePickerConfiguration too
3888
3890
  this.dateInputMin$ = this.syncConfigBeforeValue$;
3889
3891
  this.dateInputMax$ = this.syncConfigAfterValue$;
3890
- this.rawDateTime$ = combineLatest([this.dateValue$, this.timeInput$.pipe(startWith(null)), this.fullDay$]).pipe(map(([date, timeString, fullDay]) => {
3892
+ this.rawDateTime$ = combineLatest([this.dateValue$, this.timeInput$.pipe(startWith(null)), this.fullDay$, this.timeDate$]).pipe(map(([date, timeString, fullDay, timeDate]) => {
3891
3893
  let result;
3892
- if (!date && this.timeOnly) {
3893
- date = new Date();
3894
+ if (!date || this.timeOnly) {
3895
+ date = timeDate ?? new Date(); // use the time date, or default to the current day
3894
3896
  }
3895
3897
  if (date) {
3896
3898
  if (fullDay) {
@@ -3908,7 +3910,7 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
3908
3910
  useSystemTimezone: true
3909
3911
  }) ?? date;
3910
3912
  }
3911
- else {
3913
+ else if (!this.timeOnly) {
3912
3914
  result = date;
3913
3915
  }
3914
3916
  }
@@ -3948,7 +3950,7 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
3948
3950
  ...config,
3949
3951
  roundDownToMinute: true
3950
3952
  });
3951
- date = instance.limit(date);
3953
+ date = instance.clamp(date);
3952
3954
  const minutes = stepsOffset * 5;
3953
3955
  date = addMinutes(date, minutes);
3954
3956
  }
@@ -4004,6 +4006,9 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
4004
4006
  get timezone() {
4005
4007
  return this.field.props.timezone;
4006
4008
  }
4009
+ get timeDate() {
4010
+ return this.field.props.timeDate;
4011
+ }
4007
4012
  get showTimezone() {
4008
4013
  return this.field.props.showTimezone ?? true;
4009
4014
  }
@@ -4024,17 +4029,35 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
4024
4029
  this.formControl.markAsDirty();
4025
4030
  this.formControl.markAsTouched();
4026
4031
  });
4032
+ let hasSetMidnightFromInput = false;
4033
+ /*
4027
4034
  this._valueSub.subscription = this.timeString$.subscribe((x) => {
4028
- // Skip events where the timeInput value is cleared.
4029
- if (!this.timeInputCtrl.value && x === '12:00AM') {
4035
+ this.setTime(x);
4036
+ });
4037
+ */
4038
+ this._valueSub.subscription = this.valueInSystemTimezone$
4039
+ .pipe(map((x) => (x ? isSameDate(x, startOfDay(x)) : false)), distinctUntilChanged(), switchMap((isInputValueAtMidnight) => {
4040
+ hasSetMidnightFromInput = false;
4041
+ return this.timeString$.pipe(
4042
+ // skip(1),
4043
+ map((timeString) => [timeString, isInputValueAtMidnight]));
4044
+ }))
4045
+ .subscribe(([x, isInputValueAtMidnight]) => {
4046
+ // Skip events where the timeInput value is cleared, unless the input value is at midnight and we've already processed it being at midnight
4047
+ if (!this.timeInputCtrl.value && x === '12:00AM' && (!isInputValueAtMidnight || (isInputValueAtMidnight && hasSetMidnightFromInput))) {
4030
4048
  return;
4031
4049
  }
4050
+ // update the has set flag
4051
+ if (x === '12:00AM' && isInputValueAtMidnight) {
4052
+ hasSetMidnightFromInput = true;
4053
+ }
4032
4054
  this.setTime(x);
4033
4055
  });
4034
4056
  // Set default timezone if provided.
4035
4057
  if (this.timezone && !this.dateTimeField.fullDayInUTC) {
4036
4058
  this._defaultTimezone.next(asObservableFromGetter(this.timezone));
4037
4059
  }
4060
+ this._timeDate.next(asObservableFromGetter(this.timeDate));
4038
4061
  // Watch for disabled changes so we can propogate them properly.
4039
4062
  this.formControl.registerOnDisabledChange((disabled) => {
4040
4063
  if (disabled) {
@@ -4084,6 +4107,7 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
4084
4107
  this._valueSub.destroy();
4085
4108
  this._config.complete();
4086
4109
  this._defaultTimezone.complete();
4110
+ this._timeDate.complete();
4087
4111
  this._presets.complete();
4088
4112
  this._fullDayControlObs.complete();
4089
4113
  this._offset.complete();
@@ -4121,9 +4145,11 @@ class DbxDateTimeFieldComponent extends FieldType$1 {
4121
4145
  this.setTime(timeString);
4122
4146
  }
4123
4147
  setTime(time) {
4124
- this.timeInputCtrl.setValue(time);
4125
- this._offset.next(0);
4126
- this._updateTime.next();
4148
+ if (this.timeInputCtrl.value !== time) {
4149
+ this.timeInputCtrl.setValue(time);
4150
+ this._offset.next(0);
4151
+ this._updateTime.next();
4152
+ }
4127
4153
  }
4128
4154
  keydownOnDateInput(event) {
4129
4155
  let direction = 0;
@@ -4778,7 +4804,7 @@ function timeOnlyField(config = {}) {
4778
4804
  });
4779
4805
  }
4780
4806
  function dateTimeField(config = {}) {
4781
- const { key = 'date', dateLabel, timeLabel, allDayLabel, atTimeLabel, timezone, showTimezone, timeMode = DbxDateTimeFieldTimeMode.REQUIRED, valueMode, fullDayInUTC, fullDayFieldName, pickerConfig, getConfigObs, getSyncFieldsObs, hideDatePicker, hideDateHint, timeOnly = false, presets, materialFormField } = config;
4807
+ const { key = 'date', dateLabel, timeLabel, allDayLabel, atTimeLabel, timeDate, timezone, showTimezone, timeMode = DbxDateTimeFieldTimeMode.REQUIRED, valueMode, fullDayInUTC, fullDayFieldName, pickerConfig, getConfigObs, getSyncFieldsObs, hideDatePicker, hideDateHint, timeOnly = false, presets, materialFormField } = config;
4782
4808
  const fieldConfig = formlyField({
4783
4809
  key,
4784
4810
  type: 'datetime',
@@ -4794,6 +4820,7 @@ function dateTimeField(config = {}) {
4794
4820
  presets,
4795
4821
  timeMode: timeOnly ? DbxDateTimeFieldTimeMode.REQUIRED : timeMode,
4796
4822
  timezone,
4823
+ timeDate,
4797
4824
  showTimezone,
4798
4825
  fullDayFieldName,
4799
4826
  fullDayInUTC,
@@ -4809,7 +4836,7 @@ function dateTimeField(config = {}) {
4809
4836
  });
4810
4837
  }
4811
4838
  function dateRangeField(config = {}) {
4812
- const { required: inputRequired, start, end, timezone, showTimezone, presets } = config;
4839
+ const { required: inputRequired, start, end, timeDate, timezone, showTimezone, presets } = config;
4813
4840
  const required = inputRequired ?? start?.required ?? false;
4814
4841
  const startFieldKey = start?.key ?? 'start';
4815
4842
  const endFieldKey = end?.key ?? 'end';
@@ -4819,9 +4846,10 @@ function dateRangeField(config = {}) {
4819
4846
  getSyncFieldsObs: () => of([{ syncWith: endFieldKey, syncType: 'after' }]),
4820
4847
  presets,
4821
4848
  allDayLabel: '',
4822
- ...start,
4849
+ timeDate,
4823
4850
  timezone,
4824
4851
  showTimezone,
4852
+ ...start,
4825
4853
  required,
4826
4854
  key: startFieldKey
4827
4855
  });
@@ -4831,9 +4859,10 @@ function dateRangeField(config = {}) {
4831
4859
  getSyncFieldsObs: () => of([{ syncWith: startFieldKey, syncType: 'before' }]),
4832
4860
  presets,
4833
4861
  allDayLabel: '',
4834
- ...end,
4862
+ timeDate,
4835
4863
  timezone,
4836
4864
  showTimezone,
4865
+ ...end,
4837
4866
  required,
4838
4867
  key: endFieldKey
4839
4868
  });
@@ -4843,7 +4872,7 @@ function dateRangeField(config = {}) {
4843
4872
  };
4844
4873
  }
4845
4874
  function dateTimeRangeField(inputConfig = {}) {
4846
- const { required = false, start: inputStart, end: inputEnd, timezone, showTimezone, presets } = inputConfig;
4875
+ const { required = false, start: inputStart, end: inputEnd, timezone, timeDate, showTimezone, presets } = inputConfig;
4847
4876
  function dateTimeRangeFieldConfig(config) {
4848
4877
  return {
4849
4878
  ...config,
@@ -4868,6 +4897,7 @@ function dateTimeRangeField(inputConfig = {}) {
4868
4897
  };
4869
4898
  const config = {
4870
4899
  timezone,
4900
+ timeDate,
4871
4901
  showTimezone,
4872
4902
  presets,
4873
4903
  start,