1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | import { Boundary } from "@blueprintjs/core";
|
17 | import { areSameDay } from "./common/dateUtils";
|
18 |
|
19 | export class DateRangeSelectionStrategy {
|
20 | |
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | static getNextState(currentRange, day, allowSingleDayRange, boundary) {
|
27 | if (boundary != null) {
|
28 | return this.getNextStateForBoundary(currentRange, day, allowSingleDayRange, boundary);
|
29 | }
|
30 | else {
|
31 | return this.getDefaultNextState(currentRange, day, allowSingleDayRange);
|
32 | }
|
33 | }
|
34 | static getNextStateForBoundary(currentRange, day, allowSingleDayRange, boundary) {
|
35 | const boundaryDate = this.getBoundaryDate(boundary, currentRange);
|
36 | const otherBoundary = this.getOtherBoundary(boundary);
|
37 | const otherBoundaryDate = this.getBoundaryDate(otherBoundary, currentRange);
|
38 | let nextBoundary;
|
39 | let nextDateRange;
|
40 | if (boundaryDate == null && otherBoundaryDate == null) {
|
41 | nextBoundary = boundary;
|
42 | nextDateRange = this.createRangeForBoundary(boundary, day, null);
|
43 | }
|
44 | else if (boundaryDate != null && otherBoundaryDate == null) {
|
45 | const nextBoundaryDate = areSameDay(boundaryDate, day) ? null : day;
|
46 | nextBoundary = boundary;
|
47 | nextDateRange = this.createRangeForBoundary(boundary, nextBoundaryDate, null);
|
48 | }
|
49 | else if (boundaryDate == null && otherBoundaryDate != null) {
|
50 | if (areSameDay(day, otherBoundaryDate)) {
|
51 | let nextDate;
|
52 | if (allowSingleDayRange) {
|
53 | nextBoundary = boundary;
|
54 | nextDate = otherBoundaryDate;
|
55 | }
|
56 | else {
|
57 | nextBoundary = otherBoundary;
|
58 | nextDate = null;
|
59 | }
|
60 | nextDateRange = this.createRangeForBoundary(boundary, nextDate, nextDate);
|
61 | }
|
62 | else if (this.isOverlappingOtherBoundary(boundary, day, otherBoundaryDate)) {
|
63 | nextBoundary = otherBoundary;
|
64 | nextDateRange = this.createRangeForBoundary(boundary, otherBoundaryDate, day);
|
65 | }
|
66 | else {
|
67 | nextBoundary = boundary;
|
68 | nextDateRange = this.createRangeForBoundary(boundary, day, otherBoundaryDate);
|
69 | }
|
70 | }
|
71 | else {
|
72 |
|
73 | if (areSameDay(boundaryDate, day)) {
|
74 | const isSingleDayRangeSelected = areSameDay(boundaryDate, otherBoundaryDate);
|
75 | const nextOtherBoundaryDate = isSingleDayRangeSelected ? null : otherBoundaryDate;
|
76 | nextBoundary = boundary;
|
77 | nextDateRange = this.createRangeForBoundary(boundary, null, nextOtherBoundaryDate);
|
78 | }
|
79 | else if (areSameDay(day, otherBoundaryDate)) {
|
80 | const [nextBoundaryDate, nextOtherBoundaryDate] = allowSingleDayRange
|
81 | ? [otherBoundaryDate, otherBoundaryDate]
|
82 | : [boundaryDate, null];
|
83 | nextBoundary = allowSingleDayRange ? boundary : otherBoundary;
|
84 | nextDateRange = this.createRangeForBoundary(boundary, nextBoundaryDate, nextOtherBoundaryDate);
|
85 | }
|
86 | else if (this.isOverlappingOtherBoundary(boundary, day, otherBoundaryDate)) {
|
87 | nextBoundary = boundary;
|
88 | nextDateRange = this.createRangeForBoundary(boundary, day, null);
|
89 | }
|
90 | else {
|
91 |
|
92 | nextBoundary = boundary;
|
93 | nextDateRange = this.createRangeForBoundary(boundary, day, otherBoundaryDate);
|
94 | }
|
95 | }
|
96 | return { dateRange: nextDateRange, boundary: nextBoundary };
|
97 | }
|
98 | static getDefaultNextState(selectedRange, day, allowSingleDayRange) {
|
99 | const [start, end] = selectedRange;
|
100 | let nextDateRange;
|
101 | if (start == null && end == null) {
|
102 | nextDateRange = [day, null];
|
103 | }
|
104 | else if (start != null && end == null) {
|
105 | nextDateRange = this.createRange(day, start, allowSingleDayRange);
|
106 | }
|
107 | else if (start == null && end != null) {
|
108 | nextDateRange = this.createRange(day, end, allowSingleDayRange);
|
109 | }
|
110 | else {
|
111 | const isStart = areSameDay(start, day);
|
112 | const isEnd = areSameDay(end, day);
|
113 | if (isStart && isEnd) {
|
114 | nextDateRange = [null, null];
|
115 | }
|
116 | else if (isStart) {
|
117 | nextDateRange = [null, end];
|
118 | }
|
119 | else if (isEnd) {
|
120 | nextDateRange = [start, null];
|
121 | }
|
122 | else {
|
123 | nextDateRange = [day, null];
|
124 | }
|
125 | }
|
126 | return { dateRange: nextDateRange };
|
127 | }
|
128 | static getOtherBoundary(boundary) {
|
129 | return boundary === Boundary.START ? Boundary.END : Boundary.START;
|
130 | }
|
131 | static getBoundaryDate(boundary, dateRange) {
|
132 | return boundary === Boundary.START ? dateRange[0] : dateRange[1];
|
133 | }
|
134 | static isOverlappingOtherBoundary(boundary, boundaryDate, otherBoundaryDate) {
|
135 | return boundary === Boundary.START ? boundaryDate > otherBoundaryDate : boundaryDate < otherBoundaryDate;
|
136 | }
|
137 | static createRangeForBoundary(boundary, boundaryDate, otherBoundaryDate) {
|
138 | return boundary === Boundary.START
|
139 | ? [boundaryDate, otherBoundaryDate]
|
140 | : [otherBoundaryDate, boundaryDate];
|
141 | }
|
142 | static createRange(a, b, allowSingleDayRange) {
|
143 |
|
144 | if (!allowSingleDayRange && areSameDay(a, b)) {
|
145 | return [null, null];
|
146 | }
|
147 | return a < b ? [a, b] : [b, a];
|
148 | }
|
149 | }
|
150 |
|
\ | No newline at end of file |