mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-11-28 09:24:24 +01:00
admin can lock and unlock availbilities
This commit is contained in:
parent
82511aa781
commit
d092a1c5ea
@ -132,6 +132,29 @@ Application.Controllers.controller "AdminCalendarController", ["$scope", "$state
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Mark the selected slot as unavailable for new reservations or allow reservations again on it
|
||||||
|
##
|
||||||
|
$scope.toggleLockReservations = ->
|
||||||
|
locked = $scope.availability.lock
|
||||||
|
# open a confirmation dialog
|
||||||
|
dialogs.confirm
|
||||||
|
resolve:
|
||||||
|
object: ->
|
||||||
|
title: _t('admin_calendar.confirmation_required')
|
||||||
|
msg: if locked then _t("admin_calendar.do_you_really_want_to_allow_reservations") else _t("admin_calendar.do_you_really_want_to_block_this_slot_html")
|
||||||
|
, ->
|
||||||
|
# the admin has confirmed, lock/unlock the slot
|
||||||
|
Availability.lock {id: $scope.availability.id}, {lock: !locked}
|
||||||
|
, (data) -> # success
|
||||||
|
$scope.availability = data
|
||||||
|
growl.success(if locked then _t('admin_calendar.unlocking_success') else _t('admin_calendar.locking_success') )
|
||||||
|
uiCalendarConfig.calendars.calendar.fullCalendar 'refetchEvents'
|
||||||
|
, (error) -> # failed
|
||||||
|
growl.error(if locked then _t('admin_calendar.unlocking_failed') else _t('admin_calendar.locking_failed'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### PRIVATE SCOPE ###
|
### PRIVATE SCOPE ###
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -24,4 +24,7 @@ Application.Services.factory 'Availability', ["$resource", ($resource)->
|
|||||||
isArray: true
|
isArray: true
|
||||||
update:
|
update:
|
||||||
method: 'PUT'
|
method: 'PUT'
|
||||||
|
lock:
|
||||||
|
method: 'PUT'
|
||||||
|
url: '/api/availabilities/:id/lock'
|
||||||
]
|
]
|
||||||
|
@ -360,6 +360,10 @@ body.container{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.reservations-locked {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
.reservation-canceled {
|
.reservation-canceled {
|
||||||
color: #606060;
|
color: #606060;
|
||||||
border-radius: 0.2em;
|
border-radius: 0.2em;
|
||||||
|
@ -42,11 +42,12 @@
|
|||||||
</a>
|
</a>
|
||||||
<iframe name="export-frame" height="0" width="0" class="none"></iframe>
|
<iframe name="export-frame" height="0" width="0" class="none"></iframe>
|
||||||
</div>
|
</div>
|
||||||
<div class="widget panel b-a m m-t-lg">
|
|
||||||
|
<div class="widget panel b-a m m-t-lg" ng-if="availability">
|
||||||
<div class="panel-heading b-b small">
|
<div class="panel-heading b-b small">
|
||||||
<h3 translate>{{ 'admin_calendar.ongoing_reservations' }}</h3>
|
<h3 translate>{{ 'admin_calendar.ongoing_reservations' }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="widget-content no-bg auto wrapper">
|
<div class="widget-content no-bg auto wrapper" ng-class="{'reservations-locked': availability.lock}">
|
||||||
<ul class="list-unstyled" ng-if="reservations.length > 0">
|
<ul class="list-unstyled" ng-if="reservations.length > 0">
|
||||||
<li ng-repeat="r in reservations" class="m-b-xs" ng-class="{'reservation-canceled':r.canceled_at}">
|
<li ng-repeat="r in reservations" class="m-b-xs" ng-class="{'reservation-canceled':r.canceled_at}">
|
||||||
{{r.user.name}}
|
{{r.user.name}}
|
||||||
@ -55,25 +56,42 @@
|
|||||||
<span class="btn btn-warning btn-xs" ng-click="cancelBooking(r)" ng-if="!r.canceled_at"><i class="fa fa-times red"></i></span>
|
<span class="btn btn-warning btn-xs" ng-click="cancelBooking(r)" ng-if="!r.canceled_at"><i class="fa fa-times red"></i></span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div ng-if="reservations.length == 0" translate>{{ 'admin_calendar.no_reservations' }}</div>
|
<div ng-show="reservations.length == 0" translate>{{ 'admin_calendar.no_reservations' }}</div>
|
||||||
|
<div class="m-t" ng-show="availability.lock"><i class="fa fa-ban"/> <span class="m-l-xs" translate>{{ 'admin_calendar.reservations_locked' }}</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="widget panel b-a m m-t-lg" ng-if="availability.machine_ids.length > 0">
|
||||||
|
<div class="panel-heading b-b small">
|
||||||
|
<h3 translate>{{ 'admin_calendar.machines' }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="widget-content no-bg auto wrapper">
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<li ng-repeat="m in machines" class="m-b-xs" ng-show="availability.machine_ids.indexOf(m.id) > -1">
|
||||||
|
{{m.name}}
|
||||||
|
<span class="btn btn-warning btn-xs" ng-click="removeMachine(m)" ng-if="availability.machine_ids.length > 1"><i class="fa fa-times red"></i></span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="widget panel b-a m m-t-lg" ng-if="availability">
|
||||||
|
<div class="panel-heading b-b small">
|
||||||
|
<h3 translate>{{ 'admin_calendar.actions' }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="widget-content no-bg auto wrapper">
|
||||||
|
<button class="btn btn-default" ng-click="toggleLockReservations()">
|
||||||
|
<span ng-hide="availability.lock">
|
||||||
|
<i class="fa fa-stop" />
|
||||||
|
<span class="m-l-xs" translate>{{ 'admin_calendar.block_reservations' }}</span>
|
||||||
|
</span>
|
||||||
|
<span ng-show="availability.lock">
|
||||||
|
<i class="fa fa-play" />
|
||||||
|
<span class="m-l-xs" translate>{{ 'admin_calendar.allow_reservations' }}</span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-12 col-md-12 col-lg-3" ng-if="availability.machine_ids.length > 0">
|
</section>
|
||||||
<div class="widget panel b-a m m-t-lg">
|
|
||||||
<div class="panel-heading b-b small">
|
|
||||||
<h3 translate>{{ 'admin_calendar.machines' }}</h3>
|
|
||||||
</div>
|
|
||||||
<div class="widget-content no-bg auto wrapper">
|
|
||||||
<ul class="list-unstyled">
|
|
||||||
<li ng-repeat="m in machines" class="m-b-xs" ng-show="availability.machine_ids.indexOf(m.id) > -1">
|
|
||||||
{{m.name}}
|
|
||||||
<span class="btn btn-warning btn-xs" ng-click="removeMachine(m)" ng-if="availability.machine_ids.length > 1"><i class="fa fa-times red"></i></span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</section>
|
|
@ -2,7 +2,7 @@ class API::AvailabilitiesController < API::ApiController
|
|||||||
include FablabConfiguration
|
include FablabConfiguration
|
||||||
|
|
||||||
before_action :authenticate_user!, except: [:public]
|
before_action :authenticate_user!, except: [:public]
|
||||||
before_action :set_availability, only: [:show, :update, :destroy, :reservations]
|
before_action :set_availability, only: [:show, :update, :destroy, :reservations, :lock]
|
||||||
before_action :define_max_visibility, only: [:machine, :trainings, :spaces]
|
before_action :define_max_visibility, only: [:machine, :trainings, :spaces]
|
||||||
respond_to :json
|
respond_to :json
|
||||||
|
|
||||||
@ -235,6 +235,15 @@ class API::AvailabilitiesController < API::ApiController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def lock
|
||||||
|
authorize @availability
|
||||||
|
if @availability.update_attributes(lock: lock_params)
|
||||||
|
render :show, status: :ok, location: @availability
|
||||||
|
else
|
||||||
|
render json: @availability.errors, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def set_availability
|
def set_availability
|
||||||
@availability = Availability.find(params[:id])
|
@availability = Availability.find(params[:id])
|
||||||
@ -245,6 +254,10 @@ class API::AvailabilitiesController < API::ApiController
|
|||||||
:machines_attributes => [:id, :_destroy])
|
:machines_attributes => [:id, :_destroy])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def lock_params
|
||||||
|
params.require(:lock)
|
||||||
|
end
|
||||||
|
|
||||||
def is_reserved_availability(availability, user_id)
|
def is_reserved_availability(availability, user_id)
|
||||||
reserved_slots = []
|
reserved_slots = []
|
||||||
availability.slots.each do |s|
|
availability.slots.each do |s|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
class AvailabilityPolicy < ApplicationPolicy
|
class AvailabilityPolicy < ApplicationPolicy
|
||||||
%w(index? show? create? update? destroy? reservations? export?).each do |action|
|
%w(index? show? create? update? destroy? reservations? export? lock?).each do |action|
|
||||||
define_method action do
|
define_method action do
|
||||||
user.is_admin?
|
user.is_admin?
|
||||||
end
|
end
|
||||||
|
@ -6,11 +6,12 @@ json.array!(@availabilities) do |availability|
|
|||||||
json.available_type availability.available_type
|
json.available_type availability.available_type
|
||||||
json.machine_ids availability.machine_ids
|
json.machine_ids availability.machine_ids
|
||||||
json.training_ids availability.training_ids
|
json.training_ids availability.training_ids
|
||||||
json.backgroundColor 'white'
|
json.backgroundColor !availability.lock ? 'white' : '#f5f5f5'
|
||||||
json.borderColor availability_border_color(availability)
|
json.borderColor availability_border_color(availability)
|
||||||
json.tag_ids availability.tag_ids
|
json.tag_ids availability.tag_ids
|
||||||
json.tags availability.tags do |t|
|
json.tags availability.tags do |t|
|
||||||
json.id t.id
|
json.id t.id
|
||||||
json.name t.name
|
json.name t.name
|
||||||
end
|
end
|
||||||
|
json.lock availability.lock
|
||||||
end
|
end
|
||||||
|
@ -11,3 +11,4 @@ json.tags @availability.tags do |t|
|
|||||||
json.id t.id
|
json.id t.id
|
||||||
json.name t.name
|
json.name t.name
|
||||||
end
|
end
|
||||||
|
json.lock @availability.lock
|
||||||
|
@ -48,6 +48,16 @@ fr:
|
|||||||
unable_to_delete_the_slot_START-END_because_it_s_already_reserved_by_a_member: "Le créneau {{START}} - {{END}} n'a pu être supprimé car il est déjà réservé par un membre" # angular interpolation
|
unable_to_delete_the_slot_START-END_because_it_s_already_reserved_by_a_member: "Le créneau {{START}} - {{END}} n'a pu être supprimé car il est déjà réservé par un membre" # angular interpolation
|
||||||
you_should_select_at_least_a_machine: "Vous devriez sélectionne au moins une machine pour ce créneau."
|
you_should_select_at_least_a_machine: "Vous devriez sélectionne au moins une machine pour ce créneau."
|
||||||
export_is_running_you_ll_be_notified_when_its_ready: "L'export est en cours. Vous serez notifié lorsqu'il sera prêt."
|
export_is_running_you_ll_be_notified_when_its_ready: "L'export est en cours. Vous serez notifié lorsqu'il sera prêt."
|
||||||
|
actions: "Actions"
|
||||||
|
block_reservations: "Bloquer les réservations"
|
||||||
|
do_you_really_want_to_block_this_slot_html: "Êtes vous sur de vouloir bloquer les nouvelles réservations sur ce créneau ? Il deviendra alors invisible pour les utilisateurs. <br/><strong>Attention</strong> : cela n'annulera pas les réservations existantes."
|
||||||
|
locking_success: "Le créneau a bien été verrouillé, il n'apparaitra plus dans le calendrier utilisateur"
|
||||||
|
locking_failed: "Une erreur est survenue. Le verrouillage du créneau a échoué"
|
||||||
|
allow_reservations: "Autoriser les réservations"
|
||||||
|
do_you_really_want_to_allow_reservations: "Êtes vous sur de vouloir autoriser de nouveau la prise de réservations sur ce créneau ? Il deviendra alors visible pour les utilisateurs."
|
||||||
|
unlocking_success: "Le créneau a bien été déverrouillé, il apparaîtra de nouveau dans le calendrier utilisateur"
|
||||||
|
unlocking_failed: "Une erreur est survenue. Le déverrouillage du créneau a échoué"
|
||||||
|
reservations_locked: "Réservations bloquées"
|
||||||
|
|
||||||
project_elements:
|
project_elements:
|
||||||
# gestion des éléments constituant les projets
|
# gestion des éléments constituant les projets
|
||||||
|
@ -85,6 +85,7 @@ Rails.application.routes.draw do
|
|||||||
get 'reservations', on: :member
|
get 'reservations', on: :member
|
||||||
get 'public', on: :collection
|
get 'public', on: :collection
|
||||||
get '/export_index', action: 'export_availabilities', on: :collection
|
get '/export_index', action: 'export_availabilities', on: :collection
|
||||||
|
put ':id/lock', action: 'lock', on: :collection
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :groups, only: [:index, :create, :update, :destroy]
|
resources :groups, only: [:index, :create, :update, :destroy]
|
||||||
|
5
db/migrate/20170906100906_add_lock_to_availability.rb
Normal file
5
db/migrate/20170906100906_add_lock_to_availability.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
class AddLockToAvailability < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :availabilities, :lock, :boolean, default: false
|
||||||
|
end
|
||||||
|
end
|
@ -11,7 +11,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20170227114634) do
|
ActiveRecord::Schema.define(version: 20170906100906) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
@ -79,6 +79,7 @@ ActiveRecord::Schema.define(version: 20170227114634) do
|
|||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
t.integer "nb_total_places"
|
t.integer "nb_total_places"
|
||||||
t.boolean "destroying", default: false
|
t.boolean "destroying", default: false
|
||||||
|
t.boolean "lock", default: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "availability_tags", force: :cascade do |t|
|
create_table "availability_tags", force: :cascade do |t|
|
||||||
|
Loading…
Reference in New Issue
Block a user