Adam Shaw 7 éve
szülő
commit
ef76effbc1

+ 4 - 2
plugins/gcal/main.ts

@@ -1,5 +1,5 @@
 import * as request from 'superagent'
-import { registerSourceDef, refineProps, addDays, assignTo } from 'fullcalendar'
+import { registerEventSourceDef, refineProps, addDays, assignTo } from 'fullcalendar'
 
 // TODO: expose somehow
 const API_BASE = 'https://www.googleapis.com/calendar/v3/calendars'
@@ -11,7 +11,7 @@ const STANDARD_PROPS = {
   data: null
 }
 
-registerSourceDef({
+registerEventSourceDef({
 
   parseMeta(raw) {
     if (typeof raw === 'string') {
@@ -31,6 +31,8 @@ registerSourceDef({
         return standardProps
       }
     }
+
+    return null
   },
 
   fetch(arg, onSuccess, onFailure) {

+ 2 - 7
src/reducers/event-sources.ts

@@ -93,15 +93,10 @@ export function reduceEventSourceHash(sourceHash: EventSourceHash, action: any,
       if (eventSource.latestFetchId === action.fetchId) {
 
         if (action.type === 'RECEIVE_EVENT_SOURCE') {
-          if (typeof eventSource.success === 'function') {
-            eventSource.success(action.rawEvents)
-          }
+          eventSource.success(action.rawEvents)
         } else { // failure
           warn(action.error.message, action.error)
-
-          if (typeof eventSource.failure === 'function') {
-            eventSource.failure(action.error)
-          }
+          eventSource.failure(action.error)
         }
 
         return assignTo({}, sourceHash, {

+ 7 - 7
src/structs/date-span.ts

@@ -19,14 +19,14 @@ export interface DateSpan {
 }
 
 const STANDARD_PROPS = {
-  start: null, // dont auto-refine
-  end: null, // dont auto-refine
+  start: null,
+  end: null,
   isAllDay: Boolean
 }
 
 export function parseDateSpan(raw: DateSpanInput, dateEnv: DateEnv): DateSpan | null {
-  let otherProps = {} as any
-  let standardProps = refineProps(raw, STANDARD_PROPS, otherProps)
+  let leftovers = {} as DateSpan
+  let standardProps = refineProps(raw, STANDARD_PROPS, {}, leftovers)
   let startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null
   let endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null
   let isAllDay = standardProps.isAllDay
@@ -38,10 +38,10 @@ export function parseDateSpan(raw: DateSpanInput, dateEnv: DateEnv): DateSpan |
     }
 
     // use this leftover object as the selection object
-    otherProps.range = new UnzonedRange(startMeta.marker, endMeta.marker)
-    otherProps.isAllDay = isAllDay
+    leftovers.range = new UnzonedRange(startMeta.marker, endMeta.marker)
+    leftovers.isAllDay = isAllDay
 
-    return otherProps
+    return leftovers
   }
 
   return null

+ 10 - 9
src/structs/drag-meta.ts

@@ -28,15 +28,16 @@ const DRAG_META_PROPS = {
   stick: Boolean
 }
 
+const DRAG_META_DEFAULTS = {
+  create: true,
+  stick: false
+}
+
 export function parseDragMeta(raw: DragMetaInput): DragMeta {
   let leftoverProps = {}
-  let refined = refineProps(raw, DRAG_META_PROPS, leftoverProps)
-
-  return {
-    time: refined.time,
-    duration: refined.duration,
-    create: refined.create === false ? false : true,
-    stick: refined.stick || false, // TODO: make the default a setting?
-    leftoverProps
-  }
+  let refined = refineProps(raw, DRAG_META_PROPS, DRAG_META_DEFAULTS, leftoverProps) as DragMeta
+
+  refined.leftoverProps = leftoverProps
+
+  return refined
 }

+ 24 - 30
src/structs/event-source.ts

@@ -45,8 +45,8 @@ export interface EventSource {
   backgroundColor: string
   borderColor: string
   textColor: string
-  success: null | ((eventInputs: EventInput[]) => void)
-  failure: null | ((errorObj: any) => void)
+  success: (eventInputs: EventInput[]) => void
+  failure: (errorObj: any) => void
 }
 
 export type EventSourceHash = { [sourceId: string]: EventSource }
@@ -68,7 +68,7 @@ export interface EventSourceDef {
 
 const SIMPLE_SOURCE_PROPS = {
   allDayDefault: Boolean,
-  eventDataTransform: null,
+  eventDataTransform: Function,
   editable: Boolean,
   startEditable: Boolean,
   durationEditable: Boolean,
@@ -76,12 +76,11 @@ const SIMPLE_SOURCE_PROPS = {
   constraint: null,
   rendering: String,
   className: parseClassName,
-  color: String,
   backgroundColor: String,
   borderColor: String,
   textColor: String,
-  success: null,
-  failure: null
+  success: Function,
+  failure: Function
 }
 
 let defs: EventSourceDef[] = []
@@ -112,29 +111,24 @@ export function parseEventSource(raw: EventSourceInput): EventSource | null {
 }
 
 function parseEventSourceProps(raw: EventSourceInput, meta: object, sourceDefId: number): EventSource {
-  let props = refineProps(raw, SIMPLE_SOURCE_PROPS)
-
-  return {
-    sourceId: String(uid++),
-    sourceDefId,
-    meta,
-    publicId: props.id || '',
-    isFetching: false,
-    latestFetchId: '',
-    fetchRange: null,
-    allDayDefault: props.allDayDefault,
-    eventDataTransform: props.eventDataTransform,
-    editable: props.editable,
-    startEditable: props.startEditable,
-    durationEditable: props.durationEditable,
-    overlap: props.overlap,
-    constraint: props.constraint,
-    rendering: props.rendering || '',
-    className: props.className || [],
-    backgroundColor: props.backgroundColor || props.color || '',
-    borderColor: props.borderColor || props.color || '',
-    textColor: props.textColor,
-    success: props.success,
-    failure: props.failure
+  let props = refineProps(raw, SIMPLE_SOURCE_PROPS) as EventSource
+
+  props.isFetching = false
+  props.latestFetchId = ''
+  props.fetchRange = null
+  props.publicId = String(raw.id || '')
+  props.sourceId = String(uid++)
+  props.sourceDefId = sourceDefId
+  props.meta = meta
+
+  if (typeof raw.color === 'string') {
+    if (!props.backgroundColor) {
+      props.backgroundColor = raw.color
+    }
+    if (!props.borderColor) {
+      props.borderColor = raw.color
+    }
   }
+
+  return props
 }

+ 24 - 23
src/structs/event.ts

@@ -81,7 +81,6 @@ export type EventInstanceHash = { [instanceId: string]: EventInstance }
 export type EventDefHash = { [defId: string]: EventDef }
 
 const NON_DATE_PROPS = {
-  id: String,
   groupId: String,
   title: String,
   url: String,
@@ -110,29 +109,31 @@ let uid = 0
 
 export function parseEventDef(raw: EventNonDateInput, sourceId: string, isAllDay: boolean, hasEnd: boolean): EventDef {
   let leftovers = {} as any
-  let props = refineProps(raw, NON_DATE_PROPS, leftovers)
+  let props = refineProps(raw, NON_DATE_PROPS, {}, leftovers) as EventDef
 
-  return {
-    defId: String(uid++),
-    sourceId,
-    publicId: props.id || '',
-    groupId: props.groupId || '',
-    hasEnd,
-    isAllDay,
-    title: props.title || '',
-    url: props.url || '',
-    editable: props.editable,
-    startEditable: props.startEditable,
-    durationEditable: props.durationEditable,
-    constraint: props.constraint,
-    overlap: props.overlap,
-    rendering: props.rendering || '',
-    className: props.className || [],
-    backgroundColor: props.backgroundColor || props.color || '',
-    borderColor: props.borderColor || props.color || '',
-    textColor: props.textColor || '',
-    extendedProps: assignTo(leftovers, props.extendedProps || {})
+  props.defId = String(uid++)
+  props.sourceId = sourceId
+  props.isAllDay = isAllDay
+  props.hasEnd = hasEnd
+
+  if ('id' in leftovers) {
+    props.publicId = String(leftovers.id)
+    delete leftovers.id
+  }
+
+  if ('color' in leftovers) {
+    if (!props.backgroundColor) {
+      props.backgroundColor = leftovers.color
+    }
+    if (!props.borderColor) {
+      props.borderColor = leftovers.color
+    }
+    delete leftovers.color
   }
+
+  props.extendedProps = assignTo(leftovers, props.extendedProps || {})
+
+  return props
 }
 
 export function createEventInstance(
@@ -151,7 +152,7 @@ export function parseEventDateSpan(
   calendar: Calendar,
   leftovers: object
 ): EventDateSpan | null {
-  let dateProps = refineProps(raw, DATE_PROPS, leftovers)
+  let dateProps = refineProps(raw, DATE_PROPS, {}, leftovers)
   let rawStart = dateProps.start
   let startMeta
   let hasEnd = false

+ 33 - 10
src/util/misc.ts

@@ -400,22 +400,45 @@ export function debounce(func, wait) {
 ----------------------------------------------------------------------------------------------------------------------*/
 
 
-export function refineProps(rawProps, processorFuncs, leftoverProps?): any {
-  let refined = {}
-
-  for (let key in processorFuncs) {
-    if (rawProps[key] == null) {
-      refined[key] = null
-    } else if (processorFuncs[key]) {
-      refined[key] = processorFuncs[key](rawProps[key])
+export type GenericHash = { [key: string]: any }
+
+let emptyFunc = function() { }
+
+// Number and Boolean are only types that defaults or not computed for
+// TODO: write more comments
+export function refineProps(rawProps: GenericHash, processors: GenericHash, defaults: GenericHash = {}, leftoverProps?: GenericHash): GenericHash {
+  let refined: GenericHash = {}
+
+  for (let key in processors) {
+    let processor = processors[key]
+
+    if (rawProps[key] !== undefined) {
+      // found
+      if (processor) { // a refining function?
+        refined[key] = processor(rawProps[key])
+      } else {
+        refined[key] = rawProps[key]
+      }
+    } else if (defaults[key] !== undefined) {
+      // there's an explicit default
+      refined[key] = defaults[key]
     } else {
-      refined[key] = rawProps[key]
+      // must compute a default
+      if (processor === String) {
+        refined[key] = '' // empty string is default for String
+      } else if (processor === Function) {
+        refined[key] = emptyFunc // noop is default for Function
+      } else if (!processor || processor === Number || processor === Boolean) {
+        refined[key] = null // assign null for other non-custom processor funcs
+      } else {
+        refined[key] = processor(null) // run the custom processor func
+      }
     }
   }
 
   if (leftoverProps) {
     for (let key in rawProps) {
-      if (processorFuncs[key] === undefined) {
+      if (processors[key] === undefined) {
         leftoverProps[key] = rawProps[key]
       }
     }