@dereekb/dbx-form 9.25.1 → 9.25.3

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.
@@ -5,9 +5,9 @@ import { AbstractPopoverDirective, AbstractDialogDirective, sanitizeDbxDialogCon
5
5
  import * as i0 from '@angular/core';
6
6
  import { Injectable, SkipSelf, Directive, Injector, Optional, Component, Inject, Input, ViewChild, ElementRef, ChangeDetectionStrategy, EventEmitter, Output, InjectionToken, NgModule } from '@angular/core';
7
7
  import { FieldType } from '@ngx-formly/material';
8
- import { switchMap, first, tap, map, distinctUntilChanged, shareReplay, of, combineLatestWith, BehaviorSubject, filter, combineLatest, startWith, throttleTime } from 'rxjs';
8
+ import { switchMap, first, tap, map, distinctUntilChanged, shareReplay, of, combineLatestWith, BehaviorSubject, filter, combineLatest, EMPTY, startWith, throttleTime } from 'rxjs';
9
9
  import { filterMaybe, distinctUntilHasDifferentValues, SubscriptionObject, asObservableFromGetter, asObservable } from '@dereekb/rxjs';
10
- import { DateCellScheduleDayCode, expandDateCellScheduleDayCodesToDayOfWeekSet, dateCellTimingStartsAtForStartOfDay, dateCellTimingRelativeIndexFactory, dateCellDayOfWeekFactory, findMaxDate, findMinDate, isSameDateRange, isSameDateDay, isSameDate, dateCellTimingDateFactory, expandDateCellScheduleRange, formatToISO8601DayString, isSameDateCellScheduleDateRange, dateCellTimingRelativeIndexArrayFactory, isInfiniteDateRange, copyDateCellScheduleDateFilterConfig, dateCellScheduleDateFilter, dateTimezoneUtcNormal, fullDateCellScheduleRange, expandDateCellScheduleDayCodes, fullWeekDateCellScheduleDayCodes, dateCellScheduleDayCodesAreSetsEquivalent, simplifyDateCellScheduleDayCodes, isDateInDateRangeFunction, isDateWithinDateCellRangeFunction, copyHoursAndMinutesFromDate, dateCellScheduleEncodedWeek, dateCellTimingStartDateFactory, enabledDaysFromDateCellScheduleDayCodes, dateCellScheduleDayCodesFromEnabledDays, formatToMonthDayString, dateRange, DateRangeType } from '@dereekb/date';
10
+ import { DateCellScheduleDayCode, expandDateCellScheduleDayCodesToDayOfWeekSet, dateCellTimingStartsAtForStartOfDay, dateCellTimingRelativeIndexFactory, dateCellDayOfWeekFactory, findMaxDate, findMinDate, isSameDateRange, isSameDateDay, isSameDate, dateCellTimingDateFactory, expandDateCellScheduleRange, formatToISO8601DayString, changeDateCellScheduleDateRangeToTimezone, isSameDateCellScheduleDateRange, dateCellTimingRelativeIndexArrayFactory, isInfiniteDateRange, copyDateCellScheduleDateFilterConfig, dateTimezoneUtcNormal, dateCellScheduleDateFilter, fullDateCellScheduleRange, dateCellTimingTimezoneNormalInstance, expandDateCellScheduleDayCodes, fullWeekDateCellScheduleDayCodes, dateCellScheduleDayCodesAreSetsEquivalent, simplifyDateCellScheduleDayCodes, isDateInDateRangeFunction, isDateWithinDateCellRangeFunction, dateCellScheduleEncodedWeek, dateCellTimingStartDateFactory, enabledDaysFromDateCellScheduleDayCodes, dateCellScheduleDayCodesFromEnabledDays, formatToMonthDayString, dateRange, DateRangeType } from '@dereekb/date';
11
11
  import { isInAllowedDaysOfWeekSet, mapValuesToSet, unique, mergeArrays, iterableToArray, range, toggleInSet, removeFromSet, addToSet, isIndexNumberInIndexRangeFunction, minAndMaxNumber, getDaysOfWeekNames, reduceBooleansWithAnd, mergeObjects, KeyValueTypleValueFilter } from '@dereekb/util';
12
12
  import { ComponentStore } from '@ngrx/component-store';
13
13
  import { startOfDay, endOfDay, isBefore, endOfWeek } from 'date-fns';
@@ -37,7 +37,7 @@ import { MatButtonToggleModule } from '@angular/material/button-toggle';
37
37
  import { FlexLayoutModule } from '@angular/flex-layout';
38
38
 
39
39
  function dateScheduleRangeField(config = {}) {
40
- const { key = 'schedule', appearance, hideCustomize, allowTextInput, filter, timezone, initialSelectionState, computeSelectionResultRelativeToFilter, exclusions, defaultScheduleDays, minMaxDateRange, cellContentFactory, dialogContentConfig, customDetailsConfig } = config;
40
+ const { key = 'schedule', appearance, hideCustomize, allowTextInput, filter, outputTimezone, timezone, initialSelectionState, computeSelectionResultRelativeToFilter, exclusions, defaultScheduleDays, minMaxDateRange, cellContentFactory, dialogContentConfig, customDetailsConfig } = config;
41
41
  const fieldConfig = {
42
42
  ...formlyField({
43
43
  key,
@@ -47,6 +47,7 @@ function dateScheduleRangeField(config = {}) {
47
47
  allowTextInput,
48
48
  appearance,
49
49
  hideCustomize,
50
+ outputTimezone,
50
51
  timezone,
51
52
  defaultScheduleDays,
52
53
  minMaxDateRange,
@@ -128,7 +129,7 @@ function calendarScheduleMinAndMaxDateRange(x) {
128
129
  };
129
130
  }
130
131
  function calendarScheduleStartBeingUsedFromFilter(x) {
131
- return x.computeSelectionResultRelativeToFilter && x.filter?.start != null;
132
+ return x.computeSelectionResultRelativeToFilter && x.filter?.start != null; // may be using either
132
133
  }
133
134
  class DbxCalendarScheduleSelectionStore extends ComponentStore {
134
135
  constructor() {
@@ -147,7 +148,7 @@ class DbxCalendarScheduleSelectionStore extends ComponentStore {
147
148
  this.hasConfiguredMinMaxRange$ = this.minMaxDateRange$.pipe(map((x) => x != null && x.start != null && x.end != null), distinctUntilChanged(), shareReplay(1));
148
149
  this.inputStart$ = this.state$.pipe(map((x) => x.inputStart), distinctUntilChanged(isSameDate), shareReplay(1));
149
150
  this.inputEnd$ = this.state$.pipe(map((x) => x.inputEnd), distinctUntilChanged(isSameDate), shareReplay(1));
150
- this.currentInputRange$ = this.state$.pipe(map(({ inputStart, inputEnd }) => ({ inputStart, inputEnd })), distinctUntilChanged((a, b) => isSameDate(a.inputStart, b.inputStart) && isSameDate(a.inputEnd, b.inputEnd)), map((x) => {
151
+ this.currentInputRange$ = this.state$.pipe(map(({ inputStart, inputEnd }) => ({ start: inputStart, end: inputEnd })), distinctUntilChanged((a, b) => isSameDateRange(a, b)), map((x) => ({ inputStart: x.start, inputEnd: x.end })), map((x) => {
151
152
  if (x.inputStart && x.inputEnd) {
152
153
  return x;
153
154
  }
@@ -172,9 +173,19 @@ class DbxCalendarScheduleSelectionStore extends ComponentStore {
172
173
  this.isInAllowedDaysOfWeekFunction$ = this.allowedDaysOfWeek$.pipe(map((x) => isInAllowedDaysOfWeekSet(x)), shareReplay(1));
173
174
  this.scheduleDays$ = this.state$.pipe(map((x) => x.effectiveScheduleDays), distinctUntilHasDifferentValues(), shareReplay(1));
174
175
  this.outputTimezone$ = this.state$.pipe(map((x) => x.outputTimezone), distinctUntilChanged(), shareReplay(1));
175
- this.effectiveOutputTimezone$ = this.state$.pipe(map((x) => (!calendarScheduleStartBeingUsedFromFilter(x) && x.outputTimezone ? x.outputTimezone : undefined)), distinctUntilChanged(), shareReplay(1));
176
- this.effectiveOutputTimezoneNormal$ = this.state$.pipe(map((x) => (!calendarScheduleStartBeingUsedFromFilter(x) && x.outputTimezoneNormal ? x.outputTimezoneNormal : undefined)), distinctUntilChanged(), shareReplay(1));
177
- this.currentSelectionValue$ = this.state$.pipe(map((x) => x.currentSelectionValue), shareReplay(1));
176
+ /**
177
+ * The timezone of the output values.
178
+ *
179
+ * If an outputTimezone is not specified, this defaults to the system timezone.
180
+ */
181
+ this.effectiveOutputTimezone$ = this.state$.pipe(map((x) => x.outputTimezone || x.systemTimezone), distinctUntilChanged(), shareReplay(1));
182
+ /**
183
+ * An outputTimezoneNormal to use.
184
+ *
185
+ * If an outputTimezone is not specified, this is undefined.
186
+ */
187
+ this.effectiveOutputTimezoneNormal$ = this.state$.pipe(map((x) => (x.outputTimezoneNormal ? x.outputTimezoneNormal : undefined)), distinctUntilChanged(), shareReplay(1));
188
+ this.currentSelectionValue$ = this.state$.pipe(map((x) => x.currentSelectionValue), distinctUntilChanged(), shareReplay(1));
178
189
  this.currentSelectionValueStart$ = this.currentSelectionValue$.pipe(map((x) => x?.dateScheduleRange.start), distinctUntilChanged(isSameDate), shareReplay(1));
179
190
  this.currentSelectionValueDateCellTimingDateFactory$ = this.currentSelectionValue$.pipe(map((x) => (x ? dateCellTimingDateFactory({ startsAt: x.dateScheduleRange.start, timezone: x.dateScheduleRange.timezone }) : undefined)), shareReplay(1));
180
191
  this.currentSelectionValueDateCellDurationSpanExpansion$ = this.currentSelectionValue$.pipe(map((x) => (x ? expandDateCellScheduleRange({ dateCellScheduleRange: x.dateScheduleRange }) : [])), shareReplay(1));
@@ -184,16 +195,14 @@ class DbxCalendarScheduleSelectionStore extends ComponentStore {
184
195
  }), shareReplay(1));
185
196
  this.selectionValue$ = this.currentSelectionValue$.pipe(filterMaybe(), shareReplay(1));
186
197
  this.currentSelectionValueWithTimezone$ = this.currentSelectionValue$.pipe(combineLatestWith(this.effectiveOutputTimezoneNormal$), map(([x, timezoneNormal]) => {
198
+ let currentValueWithTimezone = x;
187
199
  if (x && timezoneNormal) {
188
- x = {
189
- dateScheduleRange: {
190
- ...x.dateScheduleRange,
191
- start: timezoneNormal.targetDateToSystemDate(x.dateScheduleRange.start),
192
- end: timezoneNormal.targetDateToSystemDate(x.dateScheduleRange.end)
193
- }
200
+ currentValueWithTimezone = {
201
+ dateScheduleRange: changeDateCellScheduleDateRangeToTimezone(x.dateScheduleRange, timezoneNormal),
202
+ minMaxRange: x.minMaxRange
194
203
  };
195
204
  }
196
- return x;
205
+ return currentValueWithTimezone;
197
206
  }), distinctUntilChanged(), shareReplay(1));
198
207
  this.selectionValueWithTimezone$ = this.currentSelectionValueWithTimezone$.pipe(filterMaybe(), shareReplay(1));
199
208
  this.selectionValueWithTimezoneDateCellDurationSpanExpansion$ = this.selectionValueWithTimezone$.pipe(map((x) => expandDateCellScheduleRange({ dateCellScheduleRange: x.dateScheduleRange })), shareReplay(1));
@@ -220,6 +229,9 @@ class DbxCalendarScheduleSelectionStore extends ComponentStore {
220
229
  this.setComputeSelectionResultRelativeToFilter = this.updater(updateStateWithComputeSelectionResultRelativeToFilter);
221
230
  this.clearFilter = this.updater((state) => updateStateWithFilter(state, undefined));
222
231
  this.setOutputTimezone = this.updater(updateStateWithTimezoneValue);
232
+ /**
233
+ * Sets the "input" date range. This is the range that gets displayed on the date range picker.
234
+ */
223
235
  this.setInputRange = this.updater(updateStateWithChangedRange);
224
236
  // NOTE: Selected dates are NOT selected indexes. They are the internal selected dates that are excluded from the selection.
225
237
  this.toggleSelectedDates = this.updater((state, toggle) => updateStateWithChangedDates(state, { toggle }));
@@ -317,8 +329,25 @@ function updateStateWithFilter(state, inputFilter) {
317
329
  // create the filter using inputFilter, exclusions, and minMaxDateRange
318
330
  if (inputFilter || exclusions?.length || minMaxDateRange) {
319
331
  let enabledFilter;
332
+ let filterStart = null; // the start date that will be used/set on the filter.
320
333
  if (inputFilter) {
321
334
  filter = copyDateCellScheduleDateFilterConfig(inputFilter); // copy filter
335
+ // configure filter start
336
+ if (inputFilter.start) {
337
+ filterStart = inputFilter.start;
338
+ }
339
+ else if (inputFilter.startsAt) {
340
+ if (inputFilter.timezone) {
341
+ const timezoneNormal = dateTimezoneUtcNormal(inputFilter.timezone);
342
+ filterStart = timezoneNormal.startOfDayInTargetTimezone(inputFilter.startsAt);
343
+ }
344
+ else {
345
+ filterStart = inputFilter.startsAt;
346
+ filter.timezone = systemTimezone;
347
+ }
348
+ }
349
+ filter.start = filterStart ?? undefined;
350
+ // configure exclusions
322
351
  if (exclusions?.length) {
323
352
  enabledFilter = {
324
353
  ...filter,
@@ -337,13 +366,13 @@ function updateStateWithFilter(state, inputFilter) {
337
366
  }
338
367
  if (minMaxDateRange) {
339
368
  enabledFilter.minMaxDateRange = minMaxDateRange;
340
- enabledFilter.setStartAsMinDate = filter?.start ? true : false; // If a start date is set, then it becomes the floor.
369
+ enabledFilter.setStartAsMinDate = filterStart ? true : false; // If a start date is set, then it becomes the floor.
341
370
  }
342
371
  /**
343
372
  * If the input filter has a start date, use that as the relative start to ensure indexes are compared the same,
344
373
  * otherwise use the state's start. This is important for the index calculations.
345
374
  */
346
- enabledFilter.start = inputFilter?.start ?? state.start;
375
+ enabledFilter.start = filter?.start ?? state.start;
347
376
  // create the filter
348
377
  isEnabledFilterDay = dateCellScheduleDateFilter(enabledFilter);
349
378
  }
@@ -386,24 +415,30 @@ function updateStateWithTimezoneValue(state, timezone) {
386
415
  }
387
416
  }
388
417
  function updateStateWithDateCellScheduleRangeValue(state, inputChange) {
389
- const { outputTimezoneNormal: timezoneNormal, currentSelectionValue } = state;
418
+ const { currentSelectionValue, systemTimezone } = state;
390
419
  const currentDateCellScheduleRange = currentSelectionValue?.dateScheduleRange; // current range is always in system time
391
420
  let change;
392
- if (!calendarScheduleStartBeingUsedFromFilter(state) && timezoneNormal) {
393
- // When using timezones, always return from the start of the day. Inputs are converted to the system time and used as the start of the day.
394
- // Outputs remain accurate.
395
- if (inputChange) {
396
- // calculate the schedule range
397
- const fullChange = fullDateCellScheduleRange({ dateCellScheduleRange: inputChange });
398
- // convert the start/end to system time
399
- change = {
400
- start: startOfDay(timezoneNormal.systemDateToTargetDate(fullChange.start)),
401
- end: startOfDay(timezoneNormal.systemDateToTargetDate(fullChange.end)),
402
- w: fullChange.w,
403
- ex: fullChange.ex,
404
- timezone: fullChange.timezone
405
- };
406
- }
421
+ // When using timezones, always return from the start of the day. Inputs are converted to the system time and used as the start of the day.
422
+ // Outputs remain accurate.
423
+ if (inputChange) {
424
+ // make sure a timezone is set. Input may not have a timezone attached. Default to system time.
425
+ const inputChangeWithTimezoneSet = {
426
+ ...inputChange,
427
+ timezone: inputChange.timezone ?? systemTimezone
428
+ };
429
+ // calculate the schedule range
430
+ const fullChange = fullDateCellScheduleRange({ dateCellScheduleRange: inputChangeWithTimezoneSet });
431
+ const inputNormal = dateCellTimingTimezoneNormalInstance(fullChange);
432
+ const startInSystemTz = inputNormal.systemDateToTargetDate(fullChange.start);
433
+ const endInSystemTz = startOfDay(inputNormal.systemDateToTargetDate(fullChange.end));
434
+ // convert the start/end to system time
435
+ change = {
436
+ start: startInSystemTz,
437
+ end: endInSystemTz,
438
+ w: fullChange.w,
439
+ ex: fullChange.ex,
440
+ timezone: fullChange.timezone
441
+ };
407
442
  }
408
443
  const isSameValue = isSameDateCellScheduleDateRange(currentDateCellScheduleRange, change);
409
444
  if (isSameValue) {
@@ -558,7 +593,7 @@ function updateStateWithChangedRange(state, change) {
558
593
  const { inputStart: currentInputStart, inputEnd: currentInputEnd, indexFactory, minMaxDateRange } = state;
559
594
  const { start: minDate, end: maxDate } = minMaxDateRange ?? {};
560
595
  const inputStart = startOfDay(change.inputStart);
561
- const inputEnd = endOfDay(change.inputEnd);
596
+ const inputEnd = startOfDay(change.inputEnd); // midnight of the last day
562
597
  const isValidRange = minDate != null || maxDate != null ? isDateInDateRangeFunction({ start: minDate ?? undefined, end: maxDate ?? undefined }) : () => true;
563
598
  if (!isValidRange(inputStart) || !isValidRange(inputEnd) || (isSameDateDay(inputStart, currentInputStart) && isSameDateDay(inputEnd, currentInputEnd))) {
564
599
  return state; // if no change, return the current state.
@@ -599,6 +634,7 @@ function isEnabledDayInCalendarScheduleSelectionState(state) {
599
634
  }
600
635
  function computeScheduleSelectionValue(state) {
601
636
  const { indexFactory, allowedDaysOfWeek, effectiveScheduleDays, indexDayOfWeek, computeSelectionResultRelativeToFilter, filter, systemTimezone } = state;
637
+ let timezone = systemTimezone;
602
638
  const rangeAndExclusion = computeScheduleSelectionRangeAndExclusion(state);
603
639
  if (rangeAndExclusion == null) {
604
640
  return null;
@@ -610,9 +646,11 @@ function computeScheduleSelectionValue(state) {
610
646
  let end = rangeEnd;
611
647
  // If computeSelectionResultRelativeToFilter is true, then we need to offset the values to be relative to that start.
612
648
  if (computeSelectionResultRelativeToFilter && filter?.start) {
613
- start = filter.start;
614
- if (filter?.end) {
615
- end = copyHoursAndMinutesFromDate(end, filter.end);
649
+ start = filter.start; // always start at the filter's start date
650
+ if (filter.timezone) {
651
+ timezone = filter.timezone;
652
+ const filterNormal = dateTimezoneUtcNormal(timezone);
653
+ end = filterNormal.startOfDayInTargetTimezone(end);
616
654
  }
617
655
  const filterStartIndexOffset = indexFactory(rangeStart) - indexFactory(start);
618
656
  filterOffsetExcludedRange = range(0, filterStartIndexOffset);
@@ -633,7 +671,7 @@ function computeScheduleSelectionValue(state) {
633
671
  end = start; // end is start
634
672
  }
635
673
  const dateScheduleRange = {
636
- timezone: systemTimezone,
674
+ timezone,
637
675
  start,
638
676
  end,
639
677
  w,
@@ -772,7 +810,7 @@ class DbxScheduleSelectionCalendarDateRangeComponent {
772
810
  this.matFormFieldDefaultOptions = matFormFieldDefaultOptions;
773
811
  this._required = new BehaviorSubject(false);
774
812
  this.required$ = this._required.asObservable();
775
- this.timezone$ = this.dbxCalendarScheduleSelectionStore.currentTimezone$;
813
+ this.timezone$ = this.dbxCalendarScheduleSelectionStore.effectiveOutputTimezone$;
776
814
  this.openPickerOnTextClick = true;
777
815
  this.label = 'Enter a date range';
778
816
  this.showCustomize = false;
@@ -857,7 +895,7 @@ class DbxScheduleSelectionCalendarDateRangeComponent {
857
895
  .pipe(distinctUntilChanged(), switchMap((opened) => {
858
896
  let obs;
859
897
  if (opened) {
860
- obs = of({});
898
+ obs = EMPTY;
861
899
  }
862
900
  else {
863
901
  obs = this.range.valueChanges.pipe(startWith(this.range.value));
@@ -1248,10 +1286,11 @@ class DbxScheduleSelectionCalendarComponent {
1248
1286
  this._inputReadonly = new BehaviorSubject(undefined);
1249
1287
  this._config = new BehaviorSubject({});
1250
1288
  this._centerRangeSub = new SubscriptionObject();
1251
- this.readonly$ = this._config.pipe(switchMap((x) => (x.readonly != null ? asObservableFromGetter(x.readonly) : of(undefined))), combineLatestWith(this._inputReadonly), map(([configReadonly, inputReadonly]) => {
1289
+ this.config$ = this._config.pipe(distinctUntilChanged(), shareReplay(1));
1290
+ this.readonly$ = this.config$.pipe(switchMap((x) => (x.readonly != null ? asObservableFromGetter(x.readonly) : of(undefined))), combineLatestWith(this._inputReadonly), map(([configReadonly, inputReadonly]) => {
1252
1291
  return (configReadonly ?? false) || (inputReadonly ?? false);
1253
1292
  }), shareReplay(1));
1254
- this.showButtonsOnReadonly$ = this._config.pipe(map((x) => x.showButtonsOnReadonly ?? false), distinctUntilChanged(), shareReplay(1));
1293
+ this.showButtonsOnReadonly$ = this.config$.pipe(map((x) => x.showButtonsOnReadonly ?? false), distinctUntilChanged(), shareReplay(1));
1255
1294
  this.showButtons$ = this.showButtonsOnReadonly$.pipe(switchMap((x) => {
1256
1295
  if (x) {
1257
1296
  return of(true);
@@ -1260,12 +1299,12 @@ class DbxScheduleSelectionCalendarComponent {
1260
1299
  return this.readonly$.pipe(map((x) => !x));
1261
1300
  }
1262
1301
  }), distinctUntilChanged(), shareReplay(1));
1263
- this.showClearSelectionButton$ = this._config.pipe(map((config) => config.showClearSelectionButton ?? true), combineLatestWith(this.showButtons$), map((x) => reduceBooleansWithAnd(x)), distinctUntilChanged(), shareReplay(1));
1264
- this.datePopoverButtonInjectionConfig$ = this._config.pipe(map((x) => x.buttonInjectionConfig), switchMapDbxInjectionComponentConfig(DbxScheduleSelectionCalendarDatePopoverButtonComponent), combineLatestWith(this.showButtons$), map(([config, showButton]) => (showButton ? config : undefined)), shareReplay(1));
1302
+ this.showClearSelectionButton$ = this.config$.pipe(map((config) => config.showClearSelectionButton ?? true), combineLatestWith(this.showButtons$), map((x) => reduceBooleansWithAnd(x)), distinctUntilChanged(), shareReplay(1));
1303
+ this.datePopoverButtonInjectionConfig$ = this.config$.pipe(map((x) => x.buttonInjectionConfig), switchMapDbxInjectionComponentConfig(DbxScheduleSelectionCalendarDatePopoverButtonComponent), combineLatestWith(this.showButtons$), map(([config, showButton]) => (showButton ? config : undefined)), shareReplay(1));
1265
1304
  this.clickEvent = new EventEmitter();
1266
1305
  // refresh any time the selected day function updates
1267
1306
  this.state$ = this.dbxCalendarScheduleSelectionStore.state$;
1268
- this.beforeMonthViewRender$ = this._config.pipe(switchMap((x) => {
1307
+ this.beforeMonthViewRender$ = this.config$.pipe(switchMap((x) => {
1269
1308
  let factory;
1270
1309
  if (x.beforeMonthViewRenderFunctionFactory) {
1271
1310
  factory = asObservable(x.beforeMonthViewRenderFunctionFactory);
@@ -1500,8 +1539,8 @@ class DbxFormCalendarDateScheduleRangeFieldComponent extends FieldType {
1500
1539
  get exclusions() {
1501
1540
  return this.props.exclusions;
1502
1541
  }
1503
- get timezone() {
1504
- return this.props.timezone;
1542
+ get outputTimezone() {
1543
+ return this.props.outputTimezone || this.props.timezone;
1505
1544
  }
1506
1545
  get initialSelectionState() {
1507
1546
  return this.props.initialSelectionState;
@@ -1526,7 +1565,7 @@ class DbxFormCalendarDateScheduleRangeFieldComponent extends FieldType {
1526
1565
  this._valueSub.subscription = this.dbxCalendarScheduleSelectionStore.currentDateCellScheduleRangeValue$.subscribe((x) => {
1527
1566
  this.formControl.setValue(x);
1528
1567
  });
1529
- const { timezone, minMaxDateRange, filter, exclusions, defaultScheduleDays } = this;
1568
+ const { outputTimezone, minMaxDateRange, filter, exclusions, defaultScheduleDays } = this;
1530
1569
  if (filter != null) {
1531
1570
  this._filterSub.subscription = this.dbxCalendarScheduleSelectionStore.setFilter(asObservable(filter));
1532
1571
  }
@@ -1539,8 +1578,8 @@ class DbxFormCalendarDateScheduleRangeFieldComponent extends FieldType {
1539
1578
  if (exclusions != null) {
1540
1579
  this._exclusionsSub.subscription = this.dbxCalendarScheduleSelectionStore.setExclusions(asObservable(exclusions));
1541
1580
  }
1542
- if (timezone != null) {
1543
- this.dbxCalendarScheduleSelectionStore.setTimezone(asObservable(this.timezone));
1581
+ if (outputTimezone != null) {
1582
+ this.dbxCalendarScheduleSelectionStore.setOutputTimezone(asObservable(this.outputTimezone));
1544
1583
  }
1545
1584
  if (this.initialSelectionState !== undefined) {
1546
1585
  this.dbxCalendarScheduleSelectionStore.setInitialSelectionState(this.initialSelectionState);