@dereekb/dbx-form 9.24.4 → 9.24.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.
@@ -4,13 +4,13 @@ import * as i0 from '@angular/core';
4
4
  import { Injectable, SkipSelf, Directive, Injector, Optional, Component, Inject, Input, ElementRef, ViewChild, ChangeDetectionStrategy, EventEmitter, Output, InjectionToken, NgModule } from '@angular/core';
5
5
  import { FieldType } from '@ngx-formly/material';
6
6
  import { switchMap, first, tap, map, distinctUntilChanged, shareReplay, combineLatestWith, BehaviorSubject, of, startWith, filter, throttleTime, combineLatest } from 'rxjs';
7
- import { filterMaybe, SubscriptionObject, asObservable } from '@dereekb/rxjs';
7
+ import { filterMaybe, distinctUntilHasDifferentValues, SubscriptionObject, asObservable } from '@dereekb/rxjs';
8
8
  import { DateScheduleDayCode, expandDateScheduleDayCodesToDayOfWeekSet, dateTimingRelativeIndexFactory, dateBlockDayOfWeekFactory, findMaxDate, findMinDate, isSameDateRange, isSameDateDay, isSameDate, expandDateScheduleRange, isSameDateScheduleRange, dateTimingRelativeIndexArrayFactory, isInfiniteDateRange, copyDateScheduleDateFilterConfig, dateScheduleDateFilter, dateTimezoneUtcNormal, expandDateScheduleDayCodes, isDateInDateRangeFunction, isDateWithinDateBlockRangeFunction, copyHoursAndMinutesFromDate, dateScheduleEncodedWeek, dateBlockTimingDateFactory, enabledDaysFromDateScheduleDayCodes, dateScheduleDayCodesFromEnabledDays, formatToMonthDayString } from '@dereekb/date';
9
- import { setsAreEquivalent, unique, mergeArrays, iterableToArray, toggleInSet, addToSet, isIndexNumberInIndexRangeFunction, range, minAndMaxNumber, getDaysOfWeekNames, mergeObjects, KeyValueTypleValueFilter } from '@dereekb/util';
9
+ import { setsAreEquivalent, unique, mergeArrays, iterableToArray, range, toggleInSet, removeFromSet, addToSet, isIndexNumberInIndexRangeFunction, minAndMaxNumber, getDaysOfWeekNames, mergeObjects, KeyValueTypleValueFilter } from '@dereekb/util';
10
10
  import { ComponentStore } from '@ngrx/component-store';
11
11
  import { startOfDay, endOfDay, isBefore } from 'date-fns';
12
12
  import * as i1$1 from '@dereekb/dbx-web';
13
- import { AbstractPopoverDirective, AbstractDialogDirective, DbxActionModule, DbxButtonModule, DbxDialogInteractionModule, DbxPopoverInteractionModule, DbxTextModule } from '@dereekb/dbx-web';
13
+ import { AbstractPopoverDirective, AbstractDialogDirective, sanitizeDbxDialogContentConfig, DbxActionModule, DbxButtonModule, DbxDialogInteractionModule, DbxPopoverInteractionModule, DbxTextModule } from '@dereekb/dbx-web';
14
14
  import * as i3 from '@angular/forms';
15
15
  import { FormGroup, FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
16
16
  import * as i5 from '@angular/material/form-field';
@@ -96,7 +96,7 @@ function initialCalendarScheduleSelectionState() {
96
96
  return {
97
97
  start,
98
98
  indexFactory,
99
- selectedIndexes: new Set(),
99
+ toggledIndexes: new Set(),
100
100
  scheduleDays,
101
101
  allowedDaysOfWeek,
102
102
  indexDayOfWeek,
@@ -153,7 +153,7 @@ class DbxCalendarScheduleSelectionStore extends ComponentStore {
153
153
  /**
154
154
  * @deprecated This is not the same as the current selection value. This is the set of manually togged off dates. It will be removed in a future update.
155
155
  */
156
- this.selectedDates$ = this.state$.pipe(map((x) => x.selectedIndexes), distinctUntilChanged(), shareReplay(1));
156
+ this.selectedDates$ = this.state$.pipe(map((x) => x.toggledIndexes), distinctUntilChanged(), shareReplay(1));
157
157
  this.isEnabledFilterDayFunction$ = this.state$.pipe(map((x) => x.isEnabledFilterDay), shareReplay(1));
158
158
  this.isEnabledDayFunction$ = this.state$.pipe(map((x) => x.isEnabledDay), shareReplay(1));
159
159
  this.currentDateRange$ = this.state$.pipe(map(computeCalendarScheduleSelectionRange), distinctUntilChanged((a, b) => isSameDateRange(a, b)), shareReplay(1));
@@ -167,6 +167,9 @@ class DbxCalendarScheduleSelectionStore extends ComponentStore {
167
167
  this.effectiveTimezone$ = this.state$.pipe(map((x) => (!calendarScheduleStartBeingUsedFromFilter(x) && x.timezone ? x.timezone : undefined)), distinctUntilChanged(), shareReplay(1));
168
168
  this.effectiveTimezoneNormal$ = this.state$.pipe(map((x) => (!calendarScheduleStartBeingUsedFromFilter(x) && x.timezoneNormal ? x.timezoneNormal : undefined)), distinctUntilChanged(), shareReplay(1));
169
169
  this.currentSelectionValue$ = this.state$.pipe(map((x) => x.currentSelectionValue), shareReplay(1));
170
+ this.currentSelectionValueDateBlockDurationSpan$ = this.currentSelectionValue$.pipe(map((x) => (x ? expandDateScheduleRange(x) : [])), shareReplay(1));
171
+ this.selectionValueSelectedIndexes$ = this.currentSelectionValueDateBlockDurationSpan$.pipe(map((x) => new Set(x.map((y) => y.i))), distinctUntilHasDifferentValues(), shareReplay(1));
172
+ this.selectionValue$ = this.currentSelectionValue$.pipe(filterMaybe(), shareReplay(1));
170
173
  this.currentSelectionValueWithTimezone$ = this.currentSelectionValue$.pipe(combineLatestWith(this.effectiveTimezoneNormal$), map(([x, timezoneNormal]) => {
171
174
  if (x && timezoneNormal) {
172
175
  x = {
@@ -175,6 +178,8 @@ class DbxCalendarScheduleSelectionStore extends ComponentStore {
175
178
  }
176
179
  return x;
177
180
  }), distinctUntilChanged(), shareReplay(1));
181
+ this.selectionValueWithTimezone$ = this.currentSelectionValueWithTimezone$.pipe(filterMaybe(), shareReplay(1));
182
+ this.selectionValueWithTimezoneDateBlockDurationSpan$ = this.selectionValueWithTimezone$.pipe(map((x) => expandDateScheduleRange(x)), shareReplay(1));
178
183
  this.nextToggleSelection$ = this.hasConfiguredMinMaxRange$.pipe(switchMap((hasConfiguredMinMaxRange) => {
179
184
  let obs;
180
185
  if (hasConfiguredMinMaxRange) {
@@ -185,13 +190,10 @@ class DbxCalendarScheduleSelectionStore extends ComponentStore {
185
190
  }
186
191
  return obs;
187
192
  }), shareReplay(1));
188
- this.selectionValue$ = this.currentSelectionValueWithTimezone$.pipe(filterMaybe(), shareReplay(1));
189
- this.selectionValueDateBlockDurationSpan$ = this.selectionValue$.pipe(map((x) => expandDateScheduleRange(x)), shareReplay(1));
190
- this.selectionValueSelectedIndexes$ = this.selectionValueDateBlockDurationSpan$.pipe(map((x) => new Set(x.map((y) => y.i))), shareReplay(1));
191
193
  this.currentDateScheduleRangeValue$ = this.currentSelectionValueWithTimezone$.pipe(map((x) => x === null || x === void 0 ? void 0 : x.dateScheduleRange), distinctUntilChanged(isSameDateScheduleRange), shareReplay(1));
192
194
  this.dateScheduleRangeValue$ = this.currentDateScheduleRangeValue$.pipe(filterMaybe(), shareReplay(1));
193
195
  this.cellContentFactory$ = this.state$.pipe(map((x) => x.cellContentFactory), distinctUntilChanged(), shareReplay(1));
194
- this.isCustomized$ = this.state$.pipe(map((x) => x.selectedIndexes.size > 0), distinctUntilChanged(), shareReplay(1));
196
+ this.isCustomized$ = this.state$.pipe(map((x) => x.toggledIndexes.size > 0), distinctUntilChanged(), shareReplay(1));
195
197
  // MARK: State Changes
196
198
  this.setMinMaxDateRange = this.updater(updateStateWithMinMaxDateRange);
197
199
  this.setFilter = this.updater(updateStateWithFilter);
@@ -200,10 +202,13 @@ class DbxCalendarScheduleSelectionStore extends ComponentStore {
200
202
  this.clearFilter = this.updater((state) => updateStateWithFilter(state, undefined));
201
203
  this.setTimezone = this.updater(updateStateWithTimezoneValue);
202
204
  this.setInputRange = this.updater(updateStateWithChangedRange);
205
+ // NOTE: Selected dates are NOT selected indexes. They are the internal selected dates that are excluded from the selection.
203
206
  this.toggleSelectedDates = this.updater((state, toggle) => updateStateWithChangedDates(state, { toggle }));
204
207
  this.addSelectedDates = this.updater((state, add) => updateStateWithChangedDates(state, { add }));
205
208
  this.removeSelectedDates = this.updater((state, remove) => updateStateWithChangedDates(state, { remove }));
206
209
  this.setSelectedDates = this.updater((state, set) => updateStateWithChangedDates(state, { set }));
210
+ // NOTE: Selected indexes are the typical/expected indexes that are selected or not.
211
+ this.setSelectedIndexes = this.updater((state, set) => updateStateWithChangedDates(state, { set, invertSetBehavior: true }));
207
212
  this.selectAllDates = this.updater((state, selectAll = 'all') => updateStateWithChangedDates(state, { selectAll }));
208
213
  this.setInitialSelectionState = this.updater(updateStateWithInitialSelectionState);
209
214
  this.setScheduleDays = this.updater(updateStateWithChangedScheduleDays);
@@ -218,8 +223,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
218
223
  type: Injectable
219
224
  }], ctorParameters: function () { return []; } });
220
225
  function updateStateWithInitialSelectionState(state, initialSelectionState) {
221
- const { selectedIndexes } = state;
222
- if (selectedIndexes.size === 0 && initialSelectionState === 'all') {
226
+ const { toggledIndexes } = state;
227
+ if (toggledIndexes.size === 0 && initialSelectionState === 'all') {
223
228
  state = updateStateWithChangedDates(state, { selectAll: initialSelectionState });
224
229
  }
225
230
  return Object.assign(Object.assign({}, state), { initialSelectionState });
@@ -340,7 +345,7 @@ function updateStateWithDateScheduleRangeValue(state, change) {
340
345
  }
341
346
  else {
342
347
  if (change != null) {
343
- const nextState = Object.assign(Object.assign({}, state), { inputStart: change.start, inputEnd: change.end, selectedIndexes: new Set(change.ex) });
348
+ const nextState = Object.assign(Object.assign({}, state), { inputStart: change.start, inputEnd: change.end, toggledIndexes: new Set(change.ex) });
344
349
  return updateStateWithChangedScheduleDays(finalizeNewCalendarScheduleSelectionState(nextState), expandDateScheduleDayCodes(change.w || '89'));
345
350
  }
346
351
  else {
@@ -362,12 +367,20 @@ function updateStateWithChangedScheduleDays(state, change) {
362
367
  }
363
368
  function updateStateWithChangedDates(state, change) {
364
369
  var _a;
365
- const { indexFactory, allowedDaysOfWeek, indexDayOfWeek, inputStart: currentInputStart, inputEnd: currentInputEnd, minMaxDateRange } = state;
370
+ const { indexFactory, allowedDaysOfWeek, indexDayOfWeek, inputStart: currentInputStart, inputEnd: currentInputEnd, minMaxDateRange, filter } = state;
366
371
  const { start: minDate, end: maxDate } = calendarScheduleMinAndMaxDateRange(state);
367
372
  let inputStart = currentInputStart;
368
373
  let inputEnd = currentInputEnd;
369
- let selectedIndexes;
370
- if (change.reset || change.selectAll != null || change.set) {
374
+ /**
375
+ * This is a set of indexes that are internally "selected" so that they are excluded from the inputStart/inputEnd date range.
376
+ *
377
+ * Do not confuse this with the actual indexes that are selected.
378
+ */
379
+ let toggledIndexes;
380
+ function asIndexes(indexes) {
381
+ return iterableToArray(indexes).map(indexFactory);
382
+ }
383
+ if (change.reset || change.selectAll != null || change.set != null) {
371
384
  let set = (_a = change.set) !== null && _a !== void 0 ? _a : [];
372
385
  const selectAll = change.reset === true ? state.initialSelectionState : change.selectAll;
373
386
  switch (selectAll) {
@@ -384,29 +397,52 @@ function updateStateWithChangedDates(state, change) {
384
397
  set = [];
385
398
  break;
386
399
  }
387
- selectedIndexes = new Set(iterableToArray(set).map(indexFactory));
400
+ toggledIndexes = new Set(asIndexes(set));
401
+ if (change.invertSetBehavior && minDate && maxDate && !selectAll) {
402
+ const minIndex = indexFactory(minDate);
403
+ const maxIndex = indexFactory(maxDate);
404
+ inputStart = minDate;
405
+ inputEnd = maxDate;
406
+ toggledIndexes = new Set(range(minIndex, maxIndex + 1).filter((x) => !toggledIndexes.has(x)));
407
+ }
388
408
  }
389
409
  else {
390
- selectedIndexes = new Set(state.selectedIndexes);
410
+ toggledIndexes = new Set(state.toggledIndexes);
391
411
  if (change.toggle) {
392
- const allowedToToggle = iterableToArray(change.toggle)
393
- .map(indexFactory)
394
- .filter((i) => allowedDaysOfWeek.has(indexDayOfWeek(i)));
395
- toggleInSet(selectedIndexes, allowedToToggle);
412
+ const allowedToToggle = asIndexes(change.toggle).filter((i) => allowedDaysOfWeek.has(indexDayOfWeek(i)));
413
+ toggleInSet(toggledIndexes, allowedToToggle);
396
414
  }
415
+ let addToExclusion;
416
+ let removeFromExclusion;
397
417
  if (change.add) {
398
- addToSet(selectedIndexes, iterableToArray(change.add).map(indexFactory));
418
+ if (change.invertSetBehavior) {
419
+ addToExclusion = change.add;
420
+ }
421
+ else {
422
+ removeFromExclusion = change.add;
423
+ }
399
424
  }
400
425
  if (change.remove) {
401
- addToSet(selectedIndexes, iterableToArray(change.remove).map(indexFactory));
426
+ if (change.invertSetBehavior) {
427
+ removeFromExclusion = change.remove;
428
+ }
429
+ else {
430
+ addToExclusion = change.remove;
431
+ }
432
+ }
433
+ if (addToExclusion) {
434
+ removeFromSet(toggledIndexes, asIndexes(addToExclusion));
435
+ }
436
+ if (removeFromExclusion) {
437
+ addToSet(toggledIndexes, asIndexes(removeFromExclusion));
402
438
  }
403
439
  }
404
- const nextState = Object.assign(Object.assign({}, state), { inputStart, inputEnd, selectedIndexes });
440
+ const nextState = Object.assign(Object.assign({}, state), { inputStart, inputEnd, toggledIndexes });
405
441
  nextState.isEnabledDay = isEnabledDayInCalendarScheduleSelectionState(nextState);
406
442
  // Recalculate the range and simplified to exclusions
407
443
  const rangeAndExclusion = computeScheduleSelectionRangeAndExclusion(nextState);
408
444
  if (rangeAndExclusion) {
409
- return finalizeNewCalendarScheduleSelectionState(Object.assign(Object.assign({}, nextState), { selectedIndexes: new Set(rangeAndExclusion.excluded), inputStart: rangeAndExclusion.start, inputEnd: rangeAndExclusion.end }));
445
+ return finalizeNewCalendarScheduleSelectionState(Object.assign(Object.assign({}, nextState), { toggledIndexes: new Set(rangeAndExclusion.excluded), inputStart: rangeAndExclusion.start, inputEnd: rangeAndExclusion.end }));
410
446
  }
411
447
  else {
412
448
  // no selected days
@@ -414,7 +450,7 @@ function updateStateWithChangedDates(state, change) {
414
450
  }
415
451
  }
416
452
  function noSelectionCalendarScheduleSelectionState(state) {
417
- return finalizeNewCalendarScheduleSelectionState(Object.assign(Object.assign({}, state), { selectedIndexes: new Set(), inputStart: null, inputEnd: null }));
453
+ return finalizeNewCalendarScheduleSelectionState(Object.assign(Object.assign({}, state), { toggledIndexes: new Set(), inputStart: null, inputEnd: null }));
418
454
  }
419
455
  function updateStateWithChangedRange(state, change) {
420
456
  const { inputStart: currentInputStart, inputEnd: currentInputEnd, indexFactory, minMaxDateRange } = state;
@@ -428,11 +464,11 @@ function updateStateWithChangedRange(state, change) {
428
464
  // retain all indexes that are within the new range
429
465
  const minIndex = indexFactory(inputStart);
430
466
  const maxIndex = indexFactory(inputEnd) + 1;
431
- const currentIndexes = Array.from(state.selectedIndexes);
467
+ const currentIndexes = Array.from(state.toggledIndexes);
432
468
  const isInCurrentRange = isIndexNumberInIndexRangeFunction({ minIndex, maxIndex });
433
469
  const excludedIndexesInNewRange = currentIndexes.filter(isInCurrentRange);
434
- const selectedIndexes = new Set(excludedIndexesInNewRange);
435
- const nextState = Object.assign(Object.assign({}, state), { selectedIndexes, inputStart, inputEnd });
470
+ const toggledIndexes = new Set(excludedIndexesInNewRange);
471
+ const nextState = Object.assign(Object.assign({}, state), { toggledIndexes, inputStart, inputEnd });
436
472
  return finalizeNewCalendarScheduleSelectionState(nextState);
437
473
  }
438
474
  function finalizeNewCalendarScheduleSelectionState(nextState) {
@@ -453,7 +489,7 @@ function isEnabledDayInCalendarScheduleSelectionState(state) {
453
489
  const index = indexFactory(input);
454
490
  const dayOfWeek = indexDayOfWeek(index);
455
491
  const isInSelectedRange = isInStartAndEndRange(input);
456
- const isSelected = state.selectedIndexes.has(index);
492
+ const isSelected = state.toggledIndexes.has(index);
457
493
  const isAllowedDayOfWeek = allowedDaysOfWeek.has(dayOfWeek);
458
494
  const result = isAllowedDayOfWeek && ((isInSelectedRange && !isSelected) || (isSelected && !isInSelectedRange));
459
495
  return result;
@@ -535,8 +571,8 @@ function computeCalendarScheduleSelectionRange(state) {
535
571
  }
536
572
  function computeCalendarScheduleSelectionDateBlockRange(state) {
537
573
  const { indexFactory, inputStart, inputEnd, allowedDaysOfWeek, indexDayOfWeek, isEnabledDay, isEnabledFilterDay } = state;
538
- const enabledSelectedIndexes = Array.from(state.selectedIndexes).filter((i) => allowedDaysOfWeek.has(indexDayOfWeek(i)));
539
- const minAndMaxSelectedValues = minAndMaxNumber(enabledSelectedIndexes);
574
+ const enabledExclusionIndexes = Array.from(state.toggledIndexes).filter((i) => allowedDaysOfWeek.has(indexDayOfWeek(i)));
575
+ const minAndMaxSelectedValues = minAndMaxNumber(enabledExclusionIndexes);
540
576
  let startRange;
541
577
  let endRange;
542
578
  if (minAndMaxSelectedValues) {
@@ -1123,7 +1159,7 @@ class DbxScheduleSelectionCalendarDateDialogComponent extends AbstractDialogDire
1123
1159
  const contentConfig = mergeObjects([defaultContentConfig, inputContentConfig], KeyValueTypleValueFilter.NULL);
1124
1160
  const closeConfig = mergeObjects([defaultCloseConfig, contentConfig === null || contentConfig === void 0 ? void 0 : contentConfig.closeConfig, inputCloseConfig], KeyValueTypleValueFilter.NULL);
1125
1161
  contentConfig.closeConfig = closeConfig;
1126
- return matDialog.open(DbxScheduleSelectionCalendarDateDialogComponent, Object.assign(Object.assign({ height: 'calc(var(--vh100) * 0.9)', width: '80vw', minHeight: 400, minWidth: 360 }, contentConfig.dialogConfig), { injector, data: {
1162
+ return matDialog.open(DbxScheduleSelectionCalendarDateDialogComponent, Object.assign(Object.assign({ height: 'calc(var(--vh100) * 0.9)', width: '80vw', minHeight: 400, minWidth: 360 }, sanitizeDbxDialogContentConfig(contentConfig.dialogConfig)), { injector, data: {
1127
1163
  config,
1128
1164
  contentConfig
1129
1165
  } }));