'use strict' ## # Controller used in the public calendar global ## Application.Controllers.controller "CalendarController", ["$scope", "$state", "$aside", "moment", "Availability", 'Slot', 'Setting', 'growl', 'dialogs', 'bookingWindowStart', 'bookingWindowEnd', '_t', 'uiCalendarConfig', 'CalendarConfig', 'trainingsPromise', 'machinesPromise', 'spacesPromise', ($scope, $state, $aside, moment, Availability, Slot, Setting, growl, dialogs, bookingWindowStart, bookingWindowEnd, _t, uiCalendarConfig, CalendarConfig, trainingsPromise, machinesPromise, spacesPromise) -> ### PRIVATE STATIC CONSTANTS ### currentMachineEvent = null machinesPromise.forEach((m) -> m.checked = true) trainingsPromise.forEach((t) -> t.checked = true) spacesPromise.forEach((s) -> s.checked = true) ## check all formation/machine is select in filter isSelectAll = (type, scope) -> scope[type].length == scope[type].filter((t) -> t.checked).length ### PUBLIC SCOPE ### ## List of trainings $scope.trainings = trainingsPromise ## List of machines $scope.machines = machinesPromise ## List of spaces $scope.spaces = spacesPromise ## add availabilities source to event sources $scope.eventSources = [] ## filter availabilities if have change $scope.filterAvailabilities = (filter, scope) -> scope ||= $scope scope.filter = $scope.filter = trainings: isSelectAll('trainings', scope) machines: isSelectAll('machines', scope) spaces: isSelectAll('spaces', scope) evt: filter.evt dispo: filter.dispo $scope.calendarConfig.events = availabilitySourceUrl() ## a variable for formation/machine/event/dispo checkbox is or not checked $scope.filter = trainings: isSelectAll('trainings', $scope) machines: isSelectAll('machines', $scope) spaces: isSelectAll('spaces', $scope) evt: true dispo: true ## toggle to select all formation/machine $scope.toggleFilter = (type, filter) -> $scope[type].forEach((t) -> t.checked = filter[type]) $scope.filterAvailabilities(filter, $scope) $scope.openFilterAside = -> $aside.open templateUrl: 'filterAside.html' placement: 'right' size: 'md' backdrop: false resolve: trainings: -> $scope.trainings machines: -> $scope.machines spaces: -> $scope.spaces filter: -> $scope.filter toggleFilter: -> $scope.toggleFilter filterAvailabilities: -> $scope.filterAvailabilities controller: ['$scope', '$uibModalInstance', 'trainings', 'machines', 'spaces', 'filter', 'toggleFilter', 'filterAvailabilities', ($scope, $uibModalInstance, trainings, machines, spaces, filter, toggleFilter, filterAvailabilities) -> $scope.trainings = trainings $scope.machines = machines $scope.spaces = spaces $scope.filter = filter $scope.toggleFilter = (type, filter) -> toggleFilter(type, filter) $scope.filterAvailabilities = (filter) -> filterAvailabilities(filter, $scope) $scope.close = (e) -> $uibModalInstance.dismiss() e.stopPropagation() ] ### PRIVATE SCOPE ### calendarEventClickCb = (event, jsEvent, view) -> ## current calendar object calendar = uiCalendarConfig.calendars.calendar if event.available_type == 'machines' currentMachineEvent = event calendar.fullCalendar('changeView', 'agendaDay') calendar.fullCalendar('gotoDate', event.start) else if event.available_type == 'space' calendar.fullCalendar('changeView', 'agendaDay') calendar.fullCalendar('gotoDate', event.start) else if event.available_type == 'event' $state.go('app.public.events_show', {id: event.event_id}) else if event.available_type == 'training' $state.go('app.public.training_show', {id: event.training_id}) else if event.machine_id $state.go('app.public.machines_show', {id: event.machine_id}) else if event.space_id $state.go('app.public.space_show', {id: event.space_id}) ## agendaDay view: disable slotEventOverlap ## agendaWeek view: enable slotEventOverlap toggleSlotEventOverlap = (view) -> # set defaultView, because when we change slotEventOverlap # ui-calendar will trigger rerender calendar $scope.calendarConfig.defaultView = view.type today = if currentMachineEvent then currentMachineEvent.start else moment().utc().startOf('day') if today > view.intervalStart and today < view.intervalEnd and today != view.intervalStart $scope.calendarConfig.defaultDate = today else $scope.calendarConfig.defaultDate = view.intervalStart if view.type == 'agendaDay' $scope.calendarConfig.slotEventOverlap = false else $scope.calendarConfig.slotEventOverlap = true ## function is called when calendar view is rendered or changed viewRenderCb = (view, element) -> toggleSlotEventOverlap(view) if view.type == 'agendaDay' # get availabilties by 1 day for show machine slots uiCalendarConfig.calendars.calendar.fullCalendar('refetchEvents') eventRenderCb = (event, element) -> if event.tags.length > 0 html = '' for tag in event.tags html += "#{tag.name} " element.find('.fc-title').append("
"+html) return getFilter = -> t = $scope.trainings.filter((t) -> t.checked).map((t) -> t.id) m = $scope.machines.filter((m) -> m.checked).map((m) -> m.id) s = $scope.spaces.filter((s) -> s.checked).map((s) -> s.id) {t: t, m: m, s: s, evt: $scope.filter.evt, dispo: $scope.filter.dispo} availabilitySourceUrl = -> "/api/availabilities/public?#{$.param(getFilter())}" initialize = -> ## fullCalendar (v2) configuration $scope.calendarConfig = CalendarConfig events: availabilitySourceUrl() slotEventOverlap: true header: left: 'month agendaWeek agendaDay' center: 'title' right: 'today prev,next' minTime: moment.duration(moment(bookingWindowStart.setting.value).format('HH:mm:ss')) maxTime: moment.duration(moment(bookingWindowEnd.setting.value).format('HH:mm:ss')) defaultView: if window.innerWidth <= 480 then 'agendaDay' else 'agendaWeek' eventClick: (event, jsEvent, view)-> calendarEventClickCb(event, jsEvent, view) viewRender: (view, element) -> viewRenderCb(view, element) eventRender: (event, element, view) -> eventRenderCb(event, element) ## !!! MUST BE CALLED AT THE END of the controller initialize() ]