mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-30 19:52:20 +01:00
filter calendar by machine/formation/event or disponible
This commit is contained in:
parent
0b1a19cd76
commit
70d623f65a
@ -4,52 +4,54 @@
|
|||||||
# Controller used in the public calendar global
|
# Controller used in the public calendar global
|
||||||
##
|
##
|
||||||
|
|
||||||
Application.Controllers.controller "CalendarController", ["$scope", "$state", "$uibModal", "moment", "Availability", 'Slot', 'Setting', 'growl', 'dialogs', 'bookingWindowStart', 'bookingWindowEnd', '_t', 'uiCalendarConfig', 'CalendarConfig'
|
Application.Controllers.controller "CalendarController", ["$scope", "$state", "$uibModal", "moment", "Availability", 'Slot', 'Setting', 'growl', 'dialogs', 'bookingWindowStart', 'bookingWindowEnd', '_t', 'uiCalendarConfig', 'CalendarConfig', 'trainingsPromise', 'machinesPromise',
|
||||||
($scope, $state, $uibModal, moment, Availability, Slot, Setting, growl, dialogs, bookingWindowStart, bookingWindowEnd, _t, uiCalendarConfig, CalendarConfig) ->
|
($scope, $state, $uibModal, moment, Availability, Slot, Setting, growl, dialogs, bookingWindowStart, bookingWindowEnd, _t, uiCalendarConfig, CalendarConfig, trainingsPromise, machinesPromise) ->
|
||||||
|
|
||||||
|
|
||||||
### PRIVATE STATIC CONSTANTS ###
|
### PRIVATE STATIC CONSTANTS ###
|
||||||
availableTypes = ['machines', 'training', 'event']
|
|
||||||
availabilitySource =
|
|
||||||
url: "/api/availabilities/public?#{$.param({available_type: availableTypes})}"
|
|
||||||
textColor: 'black'
|
|
||||||
currentMachineEvent = null
|
currentMachineEvent = null
|
||||||
|
machinesPromise.forEach((m) -> m.checked = true)
|
||||||
|
trainingsPromise.forEach((t) -> t.checked = true)
|
||||||
|
|
||||||
|
|
||||||
### PUBLIC SCOPE ###
|
### PUBLIC SCOPE ###
|
||||||
|
|
||||||
|
## List of trainings
|
||||||
|
$scope.trainings = trainingsPromise
|
||||||
|
|
||||||
|
## List of machines
|
||||||
|
$scope.machines = machinesPromise
|
||||||
|
|
||||||
|
## variable for filter event
|
||||||
|
$scope.evt = true
|
||||||
|
|
||||||
|
## variable for show/hidden slot no dispo
|
||||||
|
$scope.dispo = true
|
||||||
|
|
||||||
## add availabilities source to event sources
|
## add availabilities source to event sources
|
||||||
$scope.eventSources = []
|
$scope.eventSources = []
|
||||||
|
|
||||||
## fullCalendar (v2) configuration
|
## filter availabilities if have change
|
||||||
$scope.calendarConfig = CalendarConfig
|
$scope.filterAvailabilities = ->
|
||||||
events: availabilitySource.url
|
$scope.filter =
|
||||||
slotEventOverlap: true
|
trainings: $scope.isSelectAll('trainings')
|
||||||
header:
|
machines: $scope.isSelectAll('machines')
|
||||||
left: 'month agendaWeek agendaDay'
|
$scope.calendarConfig.events = availabilitySourceUrl()
|
||||||
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'))
|
|
||||||
eventClick: (event, jsEvent, view)->
|
|
||||||
calendarEventClickCb(event, jsEvent, view)
|
|
||||||
viewRender: (view, element) ->
|
|
||||||
viewRenderCb(view, element)
|
|
||||||
eventRender: (event, element, view) ->
|
|
||||||
eventRenderCb(event, element)
|
|
||||||
|
|
||||||
$scope.filterAvailableType = (type) ->
|
## check all formation/machine is select in filter
|
||||||
index = availableTypes.indexOf(type)
|
$scope.isSelectAll = (type) ->
|
||||||
if index != -1
|
$scope[type].length == $scope[type].filter((t) -> t.checked).length
|
||||||
availableTypes.splice(index, 1)
|
|
||||||
else
|
## a variable for formation/machine checkbox is or not checked
|
||||||
availableTypes.push(type)
|
$scope.filter =
|
||||||
availabilitySource.url = "/api/availabilities/public?#{$.param({available_type: availableTypes})}"
|
trainings: $scope.isSelectAll('trainings')
|
||||||
$scope.calendarConfig.events = availabilitySource.url
|
machines: $scope.isSelectAll('machines')
|
||||||
|
|
||||||
|
## toggle to select all formation/machine
|
||||||
|
$scope.toggleFilter = (type) ->
|
||||||
|
$scope[type].forEach((t) -> t.checked = $scope.filter[type])
|
||||||
|
$scope.filterAvailabilities()
|
||||||
|
|
||||||
$scope.isAvailableTypeInactive = (type) ->
|
|
||||||
index = availableTypes.indexOf(type)
|
|
||||||
index == -1 ? true : false
|
|
||||||
|
|
||||||
### PRIVATE SCOPE ###
|
### PRIVATE SCOPE ###
|
||||||
|
|
||||||
@ -98,4 +100,36 @@ Application.Controllers.controller "CalendarController", ["$scope", "$state", "$
|
|||||||
html += "<span class='label label-success text-white'>#{tag.name}</span> "
|
html += "<span class='label label-success text-white'>#{tag.name}</span> "
|
||||||
element.find('.fc-title').append("<br/>"+html)
|
element.find('.fc-title').append("<br/>"+html)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
getFilter = ->
|
||||||
|
t = $scope.trainings.filter((t) -> t.checked).map((t) -> t.id)
|
||||||
|
m = $scope.machines.filter((m) -> m.checked).map((m) -> m.id)
|
||||||
|
{t: t, m: m, evt: $scope.evt, dispo: $scope.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'))
|
||||||
|
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()
|
||||||
]
|
]
|
||||||
|
@ -511,6 +511,12 @@ angular.module('application.router', ['ui.router']).
|
|||||||
bookingWindowEnd: ['Setting', (Setting)->
|
bookingWindowEnd: ['Setting', (Setting)->
|
||||||
Setting.get(name: 'booking_window_end').$promise
|
Setting.get(name: 'booking_window_end').$promise
|
||||||
]
|
]
|
||||||
|
trainingsPromise: ['Training', (Training)->
|
||||||
|
Training.query().$promise
|
||||||
|
]
|
||||||
|
machinesPromise: ['Machine', (Machine)->
|
||||||
|
Machine.query().$promise
|
||||||
|
]
|
||||||
translations: [ 'Translations', (Translations) ->
|
translations: [ 'Translations', (Translations) ->
|
||||||
Translations.query(['app.public.calendar']).$promise
|
Translations.query(['app.public.calendar']).$promise
|
||||||
]
|
]
|
||||||
|
@ -12,14 +12,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-xs-12 col-sm-12 col-md-3 b-t hide-b-md">
|
<div class="col-xs-12 col-sm-12 col-md-3 b-t hide-b-md">
|
||||||
<section class="heading-actions wrapper calendar-filter">
|
<section class="heading-actions wrapper">
|
||||||
<div>
|
<span class="badge text-sm bg-formation m-t" translate>{{ 'trainings' }}</span>
|
||||||
<i class="fa fa-filter"></i>
|
<span class="badge text-sm bg-machine" translate>{{ 'machines' }}</span>
|
||||||
<span translate>{{ 'filter' }}</span>
|
<span class="badge text-sm bg-event" translate>{{ 'events' }}</span>
|
||||||
</div>
|
|
||||||
<span class="badge text-sm bg-formation" ng-class="{'inactive': isAvailableTypeInactive('training')}" translate ng-click="filterAvailableType('training')">{{ 'trainings' }}</span>
|
|
||||||
<span class="badge text-sm bg-machine" ng-class="{'inactive': isAvailableTypeInactive('machines')}" translate ng-click="filterAvailableType('machines')">{{ 'machines' }}</span>
|
|
||||||
<span class="badge text-sm bg-event" ng-class="{'inactive': isAvailableTypeInactive('event')}" translate ng-click="filterAvailableType('event')">{{ 'events' }}</span>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -29,8 +25,46 @@
|
|||||||
|
|
||||||
<section class="row no-gutter">
|
<section class="row no-gutter">
|
||||||
|
|
||||||
<div class="col-sm-12 col-md-12 col-lg-12">
|
<div class="col-sm-9 col-md-9 col-lg-9">
|
||||||
<div ui-calendar="calendarConfig" ng-model="eventSources" calendar="calendar" class="wrapper-lg public-calendar"></div>
|
<div ui-calendar="calendarConfig" ng-model="eventSources" calendar="calendar" class="wrapper-lg public-calendar"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-12 col-md-3 col-lg-3">
|
||||||
|
<div class="widget panel b-a m m-t-lg">
|
||||||
|
<div class="panel-heading b-b small">
|
||||||
|
<h3 translate>{{ 'filter' }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="widget-content no-bg auto wrapper">
|
||||||
|
<div>
|
||||||
|
<div class="row">
|
||||||
|
<h3 class="col-md-11" translate>{{ 'trainings' }}</h3>
|
||||||
|
<input class="col-md-1" type="checkbox" ng-model="filter.trainings" ng-change="toggleFilter('trainings')">
|
||||||
|
</div>
|
||||||
|
<div ng-repeat="t in trainings" class="row">
|
||||||
|
<span class="col-md-11">{{::t.name}}</span>
|
||||||
|
<input class="col-md-1" type="checkbox" ng-model="t.checked" ng-change="filterAvailabilities()">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="m-t">
|
||||||
|
<div class="row">
|
||||||
|
<h3 class="col-md-11" translate>{{ 'machines' }}</h3>
|
||||||
|
<input class="col-md-1" type="checkbox" ng-model="filter.machines" ng-change="toggleFilter('machines')">
|
||||||
|
</div>
|
||||||
|
<div ng-repeat="m in machines" class="row">
|
||||||
|
<span class="col-md-11">{{::m.name}}</span>
|
||||||
|
<input class="col-md-1" type="checkbox" ng-model="m.checked" ng-change="filterAvailabilities()">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="m-t row">
|
||||||
|
<h3 class="col-md-11" translate>{{ 'events' }}</h3>
|
||||||
|
<input class="col-md-1" type="checkbox" ng-model="evt" ng-change="filterAvailabilities()">
|
||||||
|
</div>
|
||||||
|
<div class="m-t row">
|
||||||
|
<h3 class="col-md-11" translate>{{ 'show_no_disponible' }}</h3>
|
||||||
|
<input class="col-md-1" type="checkbox" ng-model="dispo" ng-change="filterAvailabilities()">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
@ -17,20 +17,21 @@ class API::AvailabilitiesController < API::ApiController
|
|||||||
def public
|
def public
|
||||||
start_date = ActiveSupport::TimeZone[params[:timezone]].parse(params[:start])
|
start_date = ActiveSupport::TimeZone[params[:timezone]].parse(params[:start])
|
||||||
end_date = ActiveSupport::TimeZone[params[:timezone]].parse(params[:end]).end_of_day
|
end_date = ActiveSupport::TimeZone[params[:timezone]].parse(params[:end]).end_of_day
|
||||||
available_type = params[:available_type] || []
|
|
||||||
@reservations = Reservation.includes(:slots, user: [:profile]).references(:slots, :user).where('slots.start_at >= ? AND slots.end_at <= ?', start_date, end_date)
|
@reservations = Reservation.includes(:slots, user: [:profile]).references(:slots, :user).where('slots.start_at >= ? AND slots.end_at <= ?', start_date, end_date)
|
||||||
if in_same_day(start_date, end_date)
|
if in_same_day(start_date, end_date)
|
||||||
@training_and_event_availabilities = Availability.includes(:tags, :trainings, :event, :slots).where(available_type: available_type.dup.delete_if {|t| t == 'machines'})
|
@training_and_event_availabilities = Availability.includes(:tags, :trainings, :event, :slots).where(available_type: ['training', 'event'])
|
||||||
.where('start_at >= ? AND end_at <= ?', start_date, end_date)
|
.where('start_at >= ? AND end_at <= ?', start_date, end_date)
|
||||||
@machine_availabilities = Availability.includes(:tags, :machines).where(available_type: available_type.dup.delete_if {|t| t == 'training' or t == 'event'})
|
@machine_availabilities = Availability.includes(:tags, :machines).where(available_type: 'machines')
|
||||||
.where('start_at >= ? AND end_at <= ?', start_date, end_date)
|
.where('start_at >= ? AND end_at <= ?', start_date, end_date)
|
||||||
@machine_slots = []
|
@machine_slots = []
|
||||||
@machine_availabilities.each do |a|
|
@machine_availabilities.each do |a|
|
||||||
a.machines.each do |machine|
|
a.machines.each do |machine|
|
||||||
((a.end_at - a.start_at)/SLOT_DURATION.minutes).to_i.times do |i|
|
if params[:m] and params[:m].include?(machine.id.to_s)
|
||||||
slot = Slot.new(start_at: a.start_at + (i*SLOT_DURATION).minutes, end_at: a.start_at + (i*SLOT_DURATION).minutes + SLOT_DURATION.minutes, availability_id: a.id, availability: a, machine: machine, title: machine.name)
|
((a.end_at - a.start_at)/SLOT_DURATION.minutes).to_i.times do |i|
|
||||||
slot = verify_machine_is_reserved(slot, @reservations, current_user, '')
|
slot = Slot.new(start_at: a.start_at + (i*SLOT_DURATION).minutes, end_at: a.start_at + (i*SLOT_DURATION).minutes + SLOT_DURATION.minutes, availability_id: a.id, availability: a, machine: machine, title: machine.name)
|
||||||
@machine_slots << slot
|
slot = verify_machine_is_reserved(slot, @reservations, current_user, '')
|
||||||
|
@machine_slots << slot
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -38,12 +39,16 @@ class API::AvailabilitiesController < API::ApiController
|
|||||||
else
|
else
|
||||||
|
|
||||||
@availabilities = Availability.includes(:tags, :machines, :trainings, :event, :slots)
|
@availabilities = Availability.includes(:tags, :machines, :trainings, :event, :slots)
|
||||||
.where(available_type: available_type)
|
|
||||||
.where('start_at >= ? AND end_at <= ?', start_date, end_date)
|
.where('start_at >= ? AND end_at <= ?', start_date, end_date)
|
||||||
@availabilities.each do |a|
|
@availabilities.each do |a|
|
||||||
a = verify_training_event_is_reserved(a, @reservations)
|
if a.available_type != 'machines'
|
||||||
|
a = verify_training_event_is_reserved(a, @reservations)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
machine_ids = params[:m] || []
|
||||||
|
@title_filter = {machine_ids: machine_ids.map(&:to_i)}
|
||||||
|
@availabilities = filter_availabilites(@availabilities)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@ -220,4 +225,36 @@ class API::AvailabilitiesController < API::ApiController
|
|||||||
def in_same_day(start_date, end_date)
|
def in_same_day(start_date, end_date)
|
||||||
(end_date.to_date - start_date.to_date).to_i == 1
|
(end_date.to_date - start_date.to_date).to_i == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def filter_availabilites(availabilities)
|
||||||
|
availabilities_filtered = []
|
||||||
|
availabilities.to_ary.each do |a|
|
||||||
|
# machine slot
|
||||||
|
if !a.try(:available_type)
|
||||||
|
availabilities_filtered << a
|
||||||
|
else
|
||||||
|
# training
|
||||||
|
if params[:t] and a.available_type == 'training'
|
||||||
|
if params[:t].include?(a.trainings.first.id.to_s)
|
||||||
|
availabilities_filtered << a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# machines
|
||||||
|
if params[:m] and a.available_type == 'machines'
|
||||||
|
if (params[:m].map(&:to_i) & a.machine_ids).any?
|
||||||
|
availabilities_filtered << a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# event
|
||||||
|
if params[:evt] and params[:evt] == 'true' and a.available_type == 'event'
|
||||||
|
availabilities_filtered << a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
availabilities_filtered.delete_if do |a|
|
||||||
|
if params[:dispo] == 'false'
|
||||||
|
a.is_reserved or (a.try(:is_completed) and a.is_completed)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -39,9 +39,12 @@ class Availability < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def title
|
def title(filter = {})
|
||||||
if available_type == 'machines'
|
if available_type == 'machines'
|
||||||
machines.map(&:name).join(' - ')
|
if filter[:machine_ids]
|
||||||
|
return machines.to_ary.delete_if {|m| !filter[:machine_ids].include?(m.id)}.map(&:name).join(' - ')
|
||||||
|
end
|
||||||
|
return machines.map(&:name).join(' - ')
|
||||||
elsif available_type == 'event'
|
elsif available_type == 'event'
|
||||||
event.name
|
event.name
|
||||||
else
|
else
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
json.array!(@availabilities) do |availability|
|
json.array!(@availabilities) do |availability|
|
||||||
json.id availability.id
|
json.id availability.id
|
||||||
json.title availability.title
|
|
||||||
json.start availability.start_at.iso8601
|
json.start availability.start_at.iso8601
|
||||||
json.end availability.end_at.iso8601
|
json.end availability.end_at.iso8601
|
||||||
json.textColor 'black'
|
json.textColor 'black'
|
||||||
json.backgroundColor 'white'
|
json.backgroundColor 'white'
|
||||||
# availability object
|
# availability object
|
||||||
if availability.try(:available_type)
|
if availability.try(:available_type)
|
||||||
|
json.title availability.title(@title_filter)
|
||||||
if availability.available_type == 'event'
|
if availability.available_type == 'event'
|
||||||
json.event_id availability.event.id
|
json.event_id availability.event.id
|
||||||
end
|
end
|
||||||
@ -35,6 +35,7 @@ json.array!(@availabilities) do |availability|
|
|||||||
|
|
||||||
# machine slot object ( here => availability = slot )
|
# machine slot object ( here => availability = slot )
|
||||||
else
|
else
|
||||||
|
json.title availability.title
|
||||||
json.machine_id availability.machine.id
|
json.machine_id availability.machine.id
|
||||||
json.borderColor machines_slot_border_color(availability)
|
json.borderColor machines_slot_border_color(availability)
|
||||||
json.tag_ids availability.availability.tag_ids
|
json.tag_ids availability.availability.tag_ids
|
||||||
@ -42,5 +43,6 @@ json.array!(@availabilities) do |availability|
|
|||||||
json.id t.id
|
json.id t.id
|
||||||
json.name t.name
|
json.name t.name
|
||||||
end
|
end
|
||||||
|
json.is_reserved availability.is_reserved
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -231,3 +231,4 @@ en:
|
|||||||
|
|
||||||
calendar:
|
calendar:
|
||||||
calendar: "Calendar"
|
calendar: "Calendar"
|
||||||
|
show_no_disponible: "Show the slots no disponibles"
|
||||||
|
@ -233,3 +233,4 @@ fr:
|
|||||||
|
|
||||||
calendar:
|
calendar:
|
||||||
calendar: "Calendrier"
|
calendar: "Calendrier"
|
||||||
|
show_no_disponible: "Afficher les crénaux non disponibles"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user