|
|
@@ -1,4 +1,4 @@
|
|
|
-import { DateRange, rangesEqual } from '../datelib/date-range'
|
|
|
+import { DateRange, rangesEqual, OpenDateRange } from '../datelib/date-range'
|
|
|
import { DateInput, DateEnv } from '../datelib/env'
|
|
|
import { refineProps } from '../util/misc'
|
|
|
import { Duration } from '../datelib/duration'
|
|
|
@@ -8,19 +8,28 @@ A data-structure for a date-range that will be visually displayed.
|
|
|
Contains other metadata like isAllDay, and anything else Components might like to store.
|
|
|
*/
|
|
|
|
|
|
-export interface DateSpanInput {
|
|
|
- start: DateInput
|
|
|
- end: DateInput
|
|
|
+export interface OpenDateSpanInput {
|
|
|
+ start?: DateInput
|
|
|
+ end?: DateInput
|
|
|
isAllDay?: boolean
|
|
|
[otherProp: string]: any
|
|
|
}
|
|
|
|
|
|
-export interface DateSpan {
|
|
|
- range: DateRange
|
|
|
+export interface DateSpanInput extends OpenDateSpanInput {
|
|
|
+ start: DateInput
|
|
|
+ end: DateInput
|
|
|
+}
|
|
|
+
|
|
|
+export interface OpenDateSpan {
|
|
|
+ range: OpenDateRange
|
|
|
isAllDay: boolean
|
|
|
[otherProp: string]: any
|
|
|
}
|
|
|
|
|
|
+export interface DateSpan extends OpenDateSpan {
|
|
|
+ range: DateRange
|
|
|
+}
|
|
|
+
|
|
|
const STANDARD_PROPS = {
|
|
|
start: null,
|
|
|
end: null,
|
|
|
@@ -28,54 +37,63 @@ const STANDARD_PROPS = {
|
|
|
}
|
|
|
|
|
|
export function parseDateSpan(raw: DateSpanInput, dateEnv: DateEnv, defaultDuration?: Duration): DateSpan | null {
|
|
|
+ let span = parseOpenDateSpan(raw, dateEnv)
|
|
|
+ let { range } = span
|
|
|
+
|
|
|
+ if (!range.start) {
|
|
|
+ return null
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!range.end) {
|
|
|
+ if (defaultDuration == null) {
|
|
|
+ return null
|
|
|
+ } else {
|
|
|
+ range.end = dateEnv.add(range.start, defaultDuration)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return span as DateSpan
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+TODO: somehow combine with parseRange?
|
|
|
+*/
|
|
|
+export function parseOpenDateSpan(raw: OpenDateSpanInput, dateEnv: DateEnv): OpenDateSpan | null {
|
|
|
let leftovers = {} as DateSpan
|
|
|
let standardProps = refineProps(raw, STANDARD_PROPS, {}, leftovers)
|
|
|
let startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null
|
|
|
- let startMarker
|
|
|
let endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null
|
|
|
- let endMarker
|
|
|
let isAllDay = standardProps.isAllDay
|
|
|
|
|
|
if (startMeta) {
|
|
|
- startMarker = startMeta.marker
|
|
|
|
|
|
if (isAllDay == null) {
|
|
|
- isAllDay = startMeta.isTimeUnspecified && (!endMeta || endMeta.isTimeUnspecified)
|
|
|
- }
|
|
|
-
|
|
|
- if (endMeta) {
|
|
|
- endMarker = endMeta.marker
|
|
|
- } else if (defaultDuration) {
|
|
|
- endMarker = dateEnv.add(startMarker, defaultDuration)
|
|
|
+ isAllDay = (startMeta && startMeta.isTimeUnspecified) &&
|
|
|
+ (!endMeta || endMeta.isTimeUnspecified)
|
|
|
}
|
|
|
|
|
|
- if (endMarker) {
|
|
|
-
|
|
|
- // use this leftover object as the selection object
|
|
|
- leftovers.range = { start: startMarker, end: endMarker }
|
|
|
- leftovers.isAllDay = isAllDay
|
|
|
+ // use this leftover object as the selection object
|
|
|
+ leftovers.range = { start: startMeta.marker, end: endMeta.marker }
|
|
|
+ leftovers.isAllDay = isAllDay
|
|
|
|
|
|
- return leftovers
|
|
|
- }
|
|
|
+ return leftovers
|
|
|
}
|
|
|
|
|
|
return null
|
|
|
}
|
|
|
|
|
|
export function isDateSpansEqual(span0: DateSpan, span1: DateSpan): boolean {
|
|
|
+ return rangesEqual(span0.range, span1.range) && isDateSpanPropsEqual(span0, span1)
|
|
|
+}
|
|
|
|
|
|
- if (!rangesEqual(span0.range, span1.range)) {
|
|
|
- return false
|
|
|
- }
|
|
|
+// besides range
|
|
|
+export function isDateSpanPropsEqual(span0: DateSpan, span1: DateSpan): boolean {
|
|
|
|
|
|
- for (let propName in span1) {
|
|
|
- if (propName !== 'range') {
|
|
|
- if (span0[propName] !== span1[propName]) {
|
|
|
- return false
|
|
|
- }
|
|
|
- }
|
|
|
+ if (!isDateSpanPropsWithin(span0, span1)) {
|
|
|
+ return false
|
|
|
}
|
|
|
|
|
|
+ // are there any props that span0 has that span1 DOESN'T have?
|
|
|
for (let propName in span0) {
|
|
|
if (!(propName in span1)) {
|
|
|
return false
|
|
|
@@ -84,3 +102,17 @@ export function isDateSpansEqual(span0: DateSpan, span1: DateSpan): boolean {
|
|
|
|
|
|
return true
|
|
|
}
|
|
|
+
|
|
|
+// does subjectSpan have all the props that validationSpan has? (subjectSpan can be a superset)
|
|
|
+export function isDateSpanPropsWithin(subjectSpan: DateSpan, validationSpan: DateSpan): boolean {
|
|
|
+
|
|
|
+ for (let propName in validationSpan) {
|
|
|
+ if (propName !== 'range') {
|
|
|
+ if (subjectSpan[propName] !== validationSpan[propName]) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true
|
|
|
+}
|