@dereekb/dbx-form 9.25.3 → 9.25.5

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.
@@ -7,7 +7,7 @@ import { Injectable, SkipSelf, Directive, Injector, Optional, Component, Inject,
7
7
  import { FieldType } from '@ngx-formly/material';
8
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, 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';
10
+ import { DateCellScheduleDayCode, expandDateCellScheduleDayCodesToDayOfWeekSet, dateCellTimingStartsAtForStartOfDay, dateCellTimingRelativeIndexFactory, dateCellDayOfWeekFactory, findMaxDate, findMinDate, isSameDateRange, isSameDateDay, isSameDate, dateCellTimingDateFactory, expandDateCellScheduleRange, formatToISO8601DayString, changeDateCellScheduleDateRangeToTimezone, isSameDateCellScheduleDateRange, dateCellTimingRelativeIndexArrayFactory, isInfiniteDateRange, copyDateCellScheduleDateFilterConfig, SYSTEM_DATE_TIMEZONE_UTC_NORMAL_INSTANCE, 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';
@@ -332,21 +332,34 @@ function updateStateWithFilter(state, inputFilter) {
332
332
  let filterStart = null; // the start date that will be used/set on the filter.
333
333
  if (inputFilter) {
334
334
  filter = copyDateCellScheduleDateFilterConfig(inputFilter); // copy filter
335
+ let nextFilterTimezone; // only set if inputFilter.start or inputFilter.startsAt
335
336
  // configure filter start
336
337
  if (inputFilter.start) {
337
338
  filterStart = inputFilter.start;
339
+ // if no timezone is specified, then use the system timezone and align filterStart to the start of the day.
340
+ if (!inputFilter.timezone) {
341
+ filterStart = SYSTEM_DATE_TIMEZONE_UTC_NORMAL_INSTANCE.startOfDayInTargetTimezone(inputFilter.startsAt);
342
+ nextFilterTimezone = systemTimezone;
343
+ }
344
+ else {
345
+ nextFilterTimezone = inputFilter.timezone;
346
+ }
338
347
  }
339
348
  else if (inputFilter.startsAt) {
340
349
  if (inputFilter.timezone) {
350
+ // if no timezone is provided, use startsAt as-is
341
351
  const timezoneNormal = dateTimezoneUtcNormal(inputFilter.timezone);
342
352
  filterStart = timezoneNormal.startOfDayInTargetTimezone(inputFilter.startsAt);
353
+ nextFilterTimezone = inputFilter.timezone;
343
354
  }
344
355
  else {
345
- filterStart = inputFilter.startsAt;
346
- filter.timezone = systemTimezone;
356
+ // set to the start of today in the system timezone.
357
+ filterStart = SYSTEM_DATE_TIMEZONE_UTC_NORMAL_INSTANCE.startOfDayInTargetTimezone(inputFilter.startsAt);
358
+ nextFilterTimezone = systemTimezone;
347
359
  }
348
360
  }
349
361
  filter.start = filterStart ?? undefined;
362
+ filter.timezone = nextFilterTimezone;
350
363
  // configure exclusions
351
364
  if (exclusions?.length) {
352
365
  enabledFilter = {
@@ -372,17 +385,46 @@ function updateStateWithFilter(state, inputFilter) {
372
385
  * If the input filter has a start date, use that as the relative start to ensure indexes are compared the same,
373
386
  * otherwise use the state's start. This is important for the index calculations.
374
387
  */
375
- enabledFilter.start = filter?.start ?? state.start;
388
+ let finalEnabledStart;
389
+ let finalEnabledTimezone;
390
+ // filter?.start ?? state.start;
391
+ if (!enabledFilter.start) {
392
+ // use the current state's start, but make sure it is in the proper timezone.
393
+ if (enabledFilter.timezone) {
394
+ const timezoneNormal = dateTimezoneUtcNormal(enabledFilter.timezone);
395
+ finalEnabledStart = timezoneNormal.startOfDayInTargetTimezone(state.start); // get the start of the day for the current start
396
+ finalEnabledTimezone = enabledFilter.timezone;
397
+ }
398
+ else {
399
+ finalEnabledStart = state.start;
400
+ finalEnabledTimezone = systemTimezone;
401
+ }
402
+ }
403
+ else if (!enabledFilter.timezone) {
404
+ finalEnabledTimezone = systemTimezone;
405
+ const timezoneNormal = dateTimezoneUtcNormal(finalEnabledTimezone);
406
+ finalEnabledStart = timezoneNormal.startOfDayInTargetTimezone(enabledFilter.start); // get the start of the day for the target timezone
407
+ }
408
+ else {
409
+ finalEnabledStart = enabledFilter.start;
410
+ finalEnabledTimezone = enabledFilter.timezone;
411
+ }
412
+ enabledFilter.start = finalEnabledStart;
413
+ enabledFilter.timezone = finalEnabledTimezone;
376
414
  // create the filter
377
415
  isEnabledFilterDay = dateCellScheduleDateFilter(enabledFilter);
378
416
  }
379
417
  state = { ...state, filter, isEnabledFilterDay };
380
418
  // For the same reason as above, use the filter's start date as the relative start if applicable.
381
419
  if (filter && filter.start) {
382
- const start = filter.start;
383
- state.start = start;
384
- state.indexFactory = dateCellTimingRelativeIndexFactory({ startsAt: start, timezone: filter.timezone ?? systemTimezone });
385
- state.indexDayOfWeek = dateCellDayOfWeekFactory(start);
420
+ let startForSystemTimezone = filter.start;
421
+ if (filter.timezone) {
422
+ const timezoneNormal = dateTimezoneUtcNormal(filter.timezone);
423
+ startForSystemTimezone = timezoneNormal.systemDateToTargetDate(filter.start); // get the start of the day for the system timezone
424
+ }
425
+ state.start = startForSystemTimezone;
426
+ state.indexFactory = dateCellTimingRelativeIndexFactory({ startsAt: startForSystemTimezone, timezone: systemTimezone });
427
+ state.indexDayOfWeek = dateCellDayOfWeekFactory(startForSystemTimezone);
386
428
  }
387
429
  // attempt to re-apply the initial selection state once filter is applied
388
430
  if (state.initialSelectionState) {
@@ -633,7 +675,7 @@ function isEnabledDayInCalendarScheduleSelectionState(state) {
633
675
  };
634
676
  }
635
677
  function computeScheduleSelectionValue(state) {
636
- const { indexFactory, allowedDaysOfWeek, effectiveScheduleDays, indexDayOfWeek, computeSelectionResultRelativeToFilter, filter, systemTimezone } = state;
678
+ const { indexFactory: systemIndexFactory, allowedDaysOfWeek, effectiveScheduleDays, indexDayOfWeek, computeSelectionResultRelativeToFilter, filter, systemTimezone } = state;
637
679
  let timezone = systemTimezone;
638
680
  const rangeAndExclusion = computeScheduleSelectionRangeAndExclusion(state);
639
681
  if (rangeAndExclusion == null) {
@@ -647,12 +689,16 @@ function computeScheduleSelectionValue(state) {
647
689
  // If computeSelectionResultRelativeToFilter is true, then we need to offset the values to be relative to that start.
648
690
  if (computeSelectionResultRelativeToFilter && filter?.start) {
649
691
  start = filter.start; // always start at the filter's start date
692
+ let startInSystemTimezone = start;
650
693
  if (filter.timezone) {
651
694
  timezone = filter.timezone;
652
695
  const filterNormal = dateTimezoneUtcNormal(timezone);
653
696
  end = filterNormal.startOfDayInTargetTimezone(end);
697
+ startInSystemTimezone = filterNormal.systemDateToTargetDate(start); // convert the start to the system timezone normal for deriving the index
654
698
  }
655
- const filterStartIndexOffset = indexFactory(rangeStart) - indexFactory(start);
699
+ const rangeStartIndex = systemIndexFactory(rangeStart);
700
+ const startIndex = systemIndexFactory(startInSystemTimezone);
701
+ const filterStartIndexOffset = rangeStartIndex - startIndex;
656
702
  filterOffsetExcludedRange = range(0, filterStartIndexOffset);
657
703
  indexOffset = indexOffset - filterStartIndexOffset;
658
704
  }