mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-19 13:54:25 +01:00
add public calendar menu, view, controller, routes and refactoring calldendar config
This commit is contained in:
parent
44b0fd8aa8
commit
fb26a2e358
@ -4,8 +4,8 @@
|
||||
# Controller used in the calendar management page
|
||||
##
|
||||
|
||||
Application.Controllers.controller "AdminCalendarController", ["$scope", "$state", "$uibModal", "moment", "Availability", 'Slot', 'Setting', 'growl', 'dialogs', 'bookingWindowStart', 'bookingWindowEnd', 'machinesPromise', '_t', 'uiCalendarConfig'
|
||||
($scope, $state, $uibModal, moment, Availability, Slot, Setting, growl, dialogs, bookingWindowStart, bookingWindowEnd, machinesPromise, _t, uiCalendarConfig) ->
|
||||
Application.Controllers.controller "AdminCalendarController", ["$scope", "$state", "$uibModal", "moment", "Availability", 'Slot', 'Setting', 'growl', 'dialogs', 'bookingWindowStart', 'bookingWindowEnd', 'machinesPromise', '_t', 'uiCalendarConfig', 'CalendarConfig'
|
||||
($scope, $state, $uibModal, moment, Availability, Slot, Setting, growl, dialogs, bookingWindowStart, bookingWindowEnd, machinesPromise, _t, uiCalendarConfig, CalendarConfig) ->
|
||||
|
||||
|
||||
|
||||
@ -17,9 +17,6 @@ Application.Controllers.controller "AdminCalendarController", ["$scope", "$state
|
||||
# The bookings can be positioned every half hours
|
||||
BOOKING_SNAP = '00:30:00'
|
||||
|
||||
# The calendar will be initialized positioned under 9:00 AM
|
||||
DEFAULT_CALENDAR_POSITION = '09:00:00'
|
||||
|
||||
# We do not allow the creation of slots that are not a multiple of 60 minutes
|
||||
SLOT_MULTIPLE = 60
|
||||
|
||||
@ -40,33 +37,13 @@ Application.Controllers.controller "AdminCalendarController", ["$scope", "$state
|
||||
textColor: 'black'
|
||||
|
||||
## fullCalendar (v2) configuration
|
||||
$scope.calendarConfig =
|
||||
timezone: Fablab.timezone
|
||||
lang: Fablab.fullcalendar_locale
|
||||
header:
|
||||
left: 'month agendaWeek'
|
||||
center: 'title'
|
||||
right: 'today prev,next'
|
||||
firstDay: 1 # Week start on monday (France)
|
||||
scrollTime: DEFAULT_CALENDAR_POSITION
|
||||
$scope.calendarConfig = CalendarConfig
|
||||
slotDuration: BASE_SLOT
|
||||
snapDuration: BOOKING_SNAP
|
||||
allDayDefault: false
|
||||
minTime: "00:00:00"
|
||||
maxTime: "24:00:00"
|
||||
height: 'auto'
|
||||
buttonIcons:
|
||||
prev: 'left-single-arrow'
|
||||
next: 'right-single-arrow'
|
||||
timeFormat:
|
||||
agenda:'H:mm'
|
||||
month: 'H(:mm)'
|
||||
axisFormat: 'H:mm'
|
||||
|
||||
allDaySlot: false
|
||||
defaultView: 'agendaWeek'
|
||||
selectable: true
|
||||
selecHelper: true
|
||||
minTime: moment.duration(moment(bookingWindowStart.setting.value).format('HH:mm:ss'))
|
||||
maxTime: moment.duration(moment(bookingWindowEnd.setting.value).format('HH:mm:ss'))
|
||||
select: (start, end, jsEvent, view) ->
|
||||
calendarSelectCb(start, end, jsEvent, view)
|
||||
eventClick: (event, jsEvent, view)->
|
||||
@ -74,10 +51,6 @@ Application.Controllers.controller "AdminCalendarController", ["$scope", "$state
|
||||
eventRender: (event, element, view) ->
|
||||
eventRenderCb(event, element)
|
||||
|
||||
## fullCalendar time bounds (up & down)
|
||||
$scope.calendarConfig.minTime = moment.duration(moment(bookingWindowStart.setting.value).format('HH:mm:ss'))
|
||||
$scope.calendarConfig.maxTime = moment.duration(moment(bookingWindowEnd.setting.value).format('HH:mm:ss'))
|
||||
|
||||
|
||||
|
||||
##
|
||||
|
32
app/assets/javascripts/controllers/calendar.coffee
Normal file
32
app/assets/javascripts/controllers/calendar.coffee
Normal file
@ -0,0 +1,32 @@
|
||||
'use strict'
|
||||
|
||||
##
|
||||
# Controller used in the public calendar global
|
||||
##
|
||||
|
||||
Application.Controllers.controller "CalendarController", ["$scope", "$uibModal", "moment", "Availability", 'Slot', 'Setting', 'growl', 'dialogs', 'bookingWindowStart', 'bookingWindowEnd', '_t', 'uiCalendarConfig', 'CalendarConfig'
|
||||
($scope, $uibModal, moment, Availability, Slot, Setting, growl, dialogs, bookingWindowStart, bookingWindowEnd, _t, uiCalendarConfig, CalendarConfig) ->
|
||||
|
||||
|
||||
### PRIVATE STATIC CONSTANTS ###
|
||||
|
||||
|
||||
|
||||
### PUBLIC SCOPE ###
|
||||
|
||||
## bind the availabilities slots with full-Calendar events
|
||||
$scope.eventSources = []
|
||||
$scope.eventSources.push
|
||||
url: '/api/availabilities/public'
|
||||
textColor: 'black'
|
||||
|
||||
## fullCalendar (v2) configuration
|
||||
$scope.calendarConfig = CalendarConfig
|
||||
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'))
|
||||
|
||||
]
|
@ -268,22 +268,13 @@ Application.Controllers.controller "ShowMachineController", ['$scope', '$state',
|
||||
# This controller workflow is pretty similar to the trainings reservation controller.
|
||||
##
|
||||
|
||||
Application.Controllers.controller "ReserveMachineController", ["$scope", "$state", '$stateParams', "$uibModal", '_t', "moment", 'Machine', 'Auth', 'dialogs', '$timeout', 'Price', 'Member', 'Availability', 'Slot', 'Setting', 'CustomAsset', 'plansPromise', 'groupsPromise', 'growl', 'settingsPromise', 'uiCalendarConfig',
|
||||
($scope, $state, $stateParams, $uibModal, _t, moment, Machine, Auth, dialogs, $timeout, Price, Member, Availability, Slot, Setting, CustomAsset, plansPromise, groupsPromise, growl, settingsPromise, uiCalendarConfig) ->
|
||||
Application.Controllers.controller "ReserveMachineController", ["$scope", "$state", '$stateParams', "$uibModal", '_t', "moment", 'Machine', 'Auth', 'dialogs', '$timeout', 'Price', 'Member', 'Availability', 'Slot', 'Setting', 'CustomAsset', 'plansPromise', 'groupsPromise', 'growl', 'settingsPromise', 'uiCalendarConfig', 'CalendarConfig'
|
||||
($scope, $state, $stateParams, $uibModal, _t, moment, Machine, Auth, dialogs, $timeout, Price, Member, Availability, Slot, Setting, CustomAsset, plansPromise, groupsPromise, growl, settingsPromise, uiCalendarConfig, CalendarConfig) ->
|
||||
|
||||
|
||||
|
||||
### PRIVATE STATIC CONSTANTS ###
|
||||
|
||||
# The calendar is divided in slots of 60 minutes
|
||||
BASE_SLOT = '01:00:00'
|
||||
|
||||
# The calendar will be initialized positioned under 9:00 AM
|
||||
DEFAULT_CALENDAR_POSITION = '09:00:00'
|
||||
|
||||
# The user is unable to modify his already booked reservation 1 day before it occurs
|
||||
PREVENT_BOOKING_MODIFICATION_DELAY = 1
|
||||
|
||||
# Slot already booked by the current user
|
||||
FREE_SLOT_BORDER_COLOR = '<%= AvailabilityHelper::MACHINE_COLOR %>'
|
||||
|
||||
@ -340,31 +331,9 @@ Application.Controllers.controller "ReserveMachineController", ["$scope", "$stat
|
||||
$scope.machine = {}
|
||||
|
||||
## fullCalendar (v2) configuration
|
||||
$scope.calendarConfig =
|
||||
timezone: Fablab.timezone
|
||||
lang: Fablab.fullcalendar_locale
|
||||
header:
|
||||
left: 'month agendaWeek'
|
||||
center: 'title'
|
||||
right: 'today prev,next'
|
||||
firstDay: 1 # Week start on monday (France)
|
||||
scrollTime: DEFAULT_CALENDAR_POSITION
|
||||
slotDuration: BASE_SLOT
|
||||
allDayDefault: false
|
||||
minTime: '00:00:00'
|
||||
maxTime: '24:00:00'
|
||||
height: 'auto'
|
||||
buttonIcons:
|
||||
prev: 'left-single-arrow'
|
||||
next: 'right-single-arrow'
|
||||
timeFormat:
|
||||
agenda:'H:mm'
|
||||
month: 'H(:mm)'
|
||||
axisFormat: 'H:mm'
|
||||
|
||||
allDaySlot: false
|
||||
defaultView: 'agendaWeek'
|
||||
editable: false
|
||||
$scope.calendarConfig = CalendarConfig
|
||||
minTime: moment.duration(moment(settingsPromise.booking_window_start).format('HH:mm:ss'))
|
||||
maxTime: moment.duration(moment(settingsPromise.booking_window_end).format('HH:mm:ss'))
|
||||
eventClick: (event, jsEvent, view) ->
|
||||
calendarEventClickCb(event, jsEvent, view)
|
||||
eventRender: (event, element, view) ->
|
||||
@ -388,12 +357,6 @@ Application.Controllers.controller "ReserveMachineController", ["$scope", "$stat
|
||||
## Global config: delay in hours before a booking while the cancellation is forbidden
|
||||
$scope.cancelBookingDelay = parseInt(settingsPromise.booking_cancel_delay)
|
||||
|
||||
## Global config: calendar window in the morning
|
||||
$scope.calendarConfig.minTime = moment.duration(moment(settingsPromise.booking_window_start).format('HH:mm:ss'))
|
||||
|
||||
## Global config: calendar window in the evening
|
||||
$scope.calendarConfig.maxTime = moment.duration(moment(settingsPromise.booking_window_end).format('HH:mm:ss'))
|
||||
|
||||
|
||||
|
||||
##
|
||||
|
@ -28,6 +28,11 @@ Application.Controllers.controller "MainNavController", ["$scope", "$location",
|
||||
linkText: 'events_registrations'
|
||||
linkIcon: 'tags'
|
||||
}
|
||||
{
|
||||
state: 'app.public.calendar'
|
||||
linkText: 'public_calendar'
|
||||
linkIcon: 'calendar'
|
||||
}
|
||||
{
|
||||
state: 'app.public.projects_list'
|
||||
linkText: 'projects_gallery'
|
||||
|
@ -51,22 +51,13 @@ Application.Controllers.controller "ShowTrainingController", ['$scope', '$state'
|
||||
# training can be reserved during the reservation process (the shopping cart may contains only one training and a subscription).
|
||||
##
|
||||
|
||||
Application.Controllers.controller "ReserveTrainingController", ["$scope", "$state", '$stateParams', '$filter', '$compile', "$uibModal", 'Auth', 'dialogs', '$timeout', 'Price', 'Availability', 'Slot', 'Member', 'Setting', 'CustomAsset', 'availabilityTrainingsPromise', 'plansPromise', 'groupsPromise', 'growl', 'settingsPromise', 'trainingPromise', '_t', 'uiCalendarConfig'
|
||||
($scope, $state, $stateParams, $filter, $compile, $uibModal, Auth, dialogs, $timeout, Price, Availability, Slot, Member, Setting, CustomAsset, availabilityTrainingsPromise, plansPromise, groupsPromise, growl, settingsPromise, trainingPromise, _t, uiCalendarConfig) ->
|
||||
Application.Controllers.controller "ReserveTrainingController", ["$scope", "$state", '$stateParams', '$filter', '$compile', "$uibModal", 'Auth', 'dialogs', '$timeout', 'Price', 'Availability', 'Slot', 'Member', 'Setting', 'CustomAsset', 'availabilityTrainingsPromise', 'plansPromise', 'groupsPromise', 'growl', 'settingsPromise', 'trainingPromise', '_t', 'uiCalendarConfig', 'CalendarConfig'
|
||||
($scope, $state, $stateParams, $filter, $compile, $uibModal, Auth, dialogs, $timeout, Price, Availability, Slot, Member, Setting, CustomAsset, availabilityTrainingsPromise, plansPromise, groupsPromise, growl, settingsPromise, trainingPromise, _t, uiCalendarConfig, CalendarConfig) ->
|
||||
|
||||
|
||||
|
||||
### PRIVATE STATIC CONSTANTS ###
|
||||
|
||||
# The calendar is divided in slots of 60 minutes
|
||||
BASE_SLOT = '01:00:00'
|
||||
|
||||
# The calendar will be initialized positioned under 9:00 AM
|
||||
DEFAULT_CALENDAR_POSITION = '09:00:00'
|
||||
|
||||
# The user is unable to modify his already booked reservation 1 day before it occurs
|
||||
PREVENT_BOOKING_MODIFICATION_DELAY = 1
|
||||
|
||||
# Color of the selected event backgound
|
||||
SELECTED_EVENT_BG_COLOR = '#ffdd00'
|
||||
|
||||
@ -117,31 +108,9 @@ Application.Controllers.controller "ReserveTrainingController", ["$scope", "$sta
|
||||
$scope.training = trainingPromise
|
||||
|
||||
## fullCalendar (v2) configuration
|
||||
$scope.calendarConfig =
|
||||
timezone: Fablab.timezone
|
||||
lang: Fablab.fullcalendar_locale
|
||||
header:
|
||||
left: 'month agendaWeek'
|
||||
center: 'title'
|
||||
right: 'today prev,next'
|
||||
firstDay: 1 # Week start on monday (France)
|
||||
scrollTime: DEFAULT_CALENDAR_POSITION
|
||||
slotDuration: BASE_SLOT
|
||||
allDayDefault: false
|
||||
minTime: '00:00:00'
|
||||
maxTime: '24:00:00'
|
||||
height: 'auto'
|
||||
buttonIcons:
|
||||
prev: 'left-single-arrow'
|
||||
next: 'right-single-arrow'
|
||||
timeFormat:
|
||||
agenda:'H:mm'
|
||||
month: 'H(:mm)'
|
||||
axisFormat: 'H:mm'
|
||||
|
||||
allDaySlot: false
|
||||
defaultView: 'agendaWeek'
|
||||
editable: false
|
||||
$scope.calendarConfig = CalendarConfig
|
||||
minTime: moment.duration(moment(settingsPromise.booking_window_start).format('HH:mm:ss'))
|
||||
maxTime: moment.duration(moment(settingsPromise.booking_window_end).format('HH:mm:ss'))
|
||||
eventClick: (event, jsEvent, view) ->
|
||||
calendarEventClickCb(event, jsEvent, view)
|
||||
eventAfterAllRender: (view)->
|
||||
@ -157,8 +126,6 @@ Application.Controllers.controller "ReserveTrainingController", ["$scope", "$sta
|
||||
$scope.moveBookingDelay = parseInt(settingsPromise.booking_move_delay)
|
||||
$scope.enableBookingCancel = (settingsPromise.booking_cancel_enable == "true")
|
||||
$scope.cancelBookingDelay = parseInt(settingsPromise.booking_cancel_delay)
|
||||
$scope.calendarConfig.minTime = moment.duration(moment(settingsPromise.booking_window_start).format('HH:mm:ss'))
|
||||
$scope.calendarConfig.maxTime = moment.duration(moment(settingsPromise.booking_window_end).format('HH:mm:ss'))
|
||||
|
||||
|
||||
|
||||
|
@ -497,6 +497,24 @@ angular.module('application.router', ['ui.router']).
|
||||
Translations.query(['app.public.events_show', 'app.shared.member_select', 'app.shared.stripe', 'app.shared.valid_reservation_modal']).$promise
|
||||
]
|
||||
|
||||
# calendar global (trainings, machines and events)
|
||||
.state 'app.public.calendar',
|
||||
url: '/calendar'
|
||||
views:
|
||||
'main@':
|
||||
templateUrl: '<%= asset_path "calendar/calendar.html" %>'
|
||||
controller: 'CalendarController'
|
||||
resolve:
|
||||
bookingWindowStart: ['Setting', (Setting)->
|
||||
Setting.get(name: 'booking_window_start').$promise
|
||||
]
|
||||
bookingWindowEnd: ['Setting', (Setting)->
|
||||
Setting.get(name: 'booking_window_end').$promise
|
||||
]
|
||||
translations: [ 'Translations', (Translations) ->
|
||||
Translations.query(['app.public.calendar']).$promise
|
||||
]
|
||||
|
||||
# --- namespace /admin/... ---
|
||||
# calendar
|
||||
.state 'app.admin.calendar',
|
||||
|
38
app/assets/javascripts/services/calendar.coffee
Normal file
38
app/assets/javascripts/services/calendar.coffee
Normal file
@ -0,0 +1,38 @@
|
||||
'use strict'
|
||||
|
||||
Application.Services.factory 'CalendarConfig', [->
|
||||
(options = {}) ->
|
||||
# The calendar is divided in slots of 1 hour
|
||||
BASE_SLOT = '01:00:00'
|
||||
|
||||
# The calendar will be initialized positioned under 9:00 AM
|
||||
DEFAULT_CALENDAR_POSITION = '09:00:00'
|
||||
|
||||
defaultOptions =
|
||||
timezone: Fablab.timezone
|
||||
lang: Fablab.fullcalendar_locale
|
||||
header:
|
||||
left: 'month agendaWeek'
|
||||
center: 'title'
|
||||
right: 'today prev,next'
|
||||
firstDay: 1 # Week start on monday (France)
|
||||
scrollTime: DEFAULT_CALENDAR_POSITION
|
||||
slotDuration: BASE_SLOT
|
||||
allDayDefault: false
|
||||
minTime: "00:00:00"
|
||||
maxTime: "24:00:00"
|
||||
height: 'auto'
|
||||
buttonIcons:
|
||||
prev: 'left-single-arrow'
|
||||
next: 'right-single-arrow'
|
||||
timeFormat:
|
||||
agenda:'H:mm'
|
||||
month: 'H(:mm)'
|
||||
axisFormat: 'H:mm'
|
||||
|
||||
allDaySlot: false
|
||||
defaultView: 'agendaWeek'
|
||||
editable: false
|
||||
|
||||
Object.assign({}, defaultOptions, options)
|
||||
]
|
@ -91,7 +91,7 @@
|
||||
cursor: pointer;
|
||||
z-index: 9999;
|
||||
text-align: right;
|
||||
.training-reserve &, .machine-reserve & { display: none; }
|
||||
.training-reserve &, .machine-reserve &, .public-calendar & { display: none; }
|
||||
}
|
||||
|
||||
.fc-v-event.fc-end {
|
||||
|
32
app/assets/templates/calendar/calendar.html.erb
Normal file
32
app/assets/templates/calendar/calendar.html.erb
Normal file
@ -0,0 +1,32 @@
|
||||
<section class="heading b-b">
|
||||
<div class="row no-gutter">
|
||||
<div class="col-xs-2 col-sm-2 col-md-1">
|
||||
<section class="heading-btn">
|
||||
<a href="#" ng-click="backPrevLocation($event)"><i class="fa fa-long-arrow-left "></i></a>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-xs-10 col-sm-10 col-md-8 b-l b-r-md">
|
||||
<section class="heading-title">
|
||||
<h1 translate>{{ 'calendar' }}</h1>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-12 col-md-3 b-t hide-b-md">
|
||||
<section class="heading-actions wrapper">
|
||||
<span class="badge text-sm bg-formation m-t-md" translate>{{ 'trainings' }}</span>
|
||||
<span class="badge text-sm bg-machine" translate>{{ 'machines' }}</span>
|
||||
<span class="badge text-sm bg-event" translate>{{ 'events' }}</span>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="row no-gutter">
|
||||
|
||||
<div class="col-sm-12 col-md-12 col-lg-9">
|
||||
<div ui-calendar="calendarConfig" ng-model="eventSources" calendar="calendar" class="wrapper-lg public-calendar"></div>
|
||||
</div>
|
||||
|
||||
</section>
|
@ -14,6 +14,14 @@ class API::AvailabilitiesController < API::ApiController
|
||||
.where('start_at >= ? AND end_at <= ?', start_date, end_date)
|
||||
end
|
||||
|
||||
def public
|
||||
start_date = ActiveSupport::TimeZone[params[:timezone]].parse(params[:start])
|
||||
end_date = ActiveSupport::TimeZone[params[:timezone]].parse(params[:end]).end_of_day
|
||||
@availabilities = Availability.includes(:machines,:tags,:trainings).where.not(available_type: 'event')
|
||||
.where('start_at >= ? AND end_at <= ?', start_date, end_date)
|
||||
render :index
|
||||
end
|
||||
|
||||
def show
|
||||
authorize Availability
|
||||
end
|
||||
|
@ -32,6 +32,7 @@ en:
|
||||
events_registrations: "Events registrations"
|
||||
projects_gallery: "Projects gallery"
|
||||
subscriptions: "Subscriptions"
|
||||
public_calendar: "Calendar"
|
||||
|
||||
# left menu (admin)
|
||||
trainings_monitoring: "Trainings monitoring"
|
||||
@ -227,3 +228,6 @@ en:
|
||||
book: "Book"
|
||||
change_the_reservation: "Change the reservation"
|
||||
you_can_shift_this_reservation_on_the_following_slots: "You can shift this reservation on the following slots:"
|
||||
|
||||
calendar:
|
||||
calendar: "Calendar"
|
||||
|
@ -32,6 +32,7 @@ fr:
|
||||
events_registrations: "Inscriptions aux évènements"
|
||||
projects_gallery: "Galerie de projets"
|
||||
subscriptions: "Abonnements"
|
||||
public_calendar: "Calendrier"
|
||||
|
||||
# menu de gauche (partie admin)
|
||||
trainings_monitoring: "Suivi formations"
|
||||
@ -229,3 +230,6 @@ fr:
|
||||
book: "Réserver"
|
||||
change_the_reservation: "Modifier la réservation"
|
||||
you_can_shift_this_reservation_on_the_following_slots: "Vous pouvez déplacer cette réservation sur les créneaux suivants :"
|
||||
|
||||
calendar:
|
||||
calendar: "Calendrier"
|
||||
|
@ -29,6 +29,7 @@ en:
|
||||
confirmation_required: "Confirmation required"
|
||||
description: "Description"
|
||||
machines: "Machines"
|
||||
events: "Events"
|
||||
materials: "Materials"
|
||||
date: "Date"
|
||||
price: "Price"
|
||||
|
@ -29,6 +29,7 @@ fr:
|
||||
confirmation_required: "Confirmation requise"
|
||||
description: "Description"
|
||||
machines: "Machines"
|
||||
events: "Events"
|
||||
materials: "Matériaux"
|
||||
date: "Date"
|
||||
price: "Prix"
|
||||
|
@ -66,6 +66,7 @@ Rails.application.routes.draw do
|
||||
get 'machines/:machine_id', action: 'machine', on: :collection
|
||||
get 'trainings/:training_id', action: 'trainings', on: :collection
|
||||
get 'reservations', on: :member
|
||||
get 'public', on: :collection
|
||||
end
|
||||
|
||||
resources :groups, only: [:index, :create, :update, :destroy]
|
||||
|
Loading…
x
Reference in New Issue
Block a user