mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-12-01 12:24:28 +01:00
space creation interface
This commit is contained in:
parent
9d367f95db
commit
da95e6e0d8
@ -1,4 +1,76 @@
|
||||
|
||||
### COMMON CODE ###
|
||||
|
||||
##
|
||||
# Provides a set of common callback methods to the $scope parameter. These methods are used
|
||||
# in the various spaces' admin controllers.
|
||||
#
|
||||
# Provides :
|
||||
# - $scope.submited(content)
|
||||
# - $scope.cancel()
|
||||
# - $scope.fileinputClass(v)
|
||||
# - $scope.addFile()
|
||||
# - $scope.deleteFile(file)
|
||||
#
|
||||
# Requires :
|
||||
# - $scope.space.space_files_attributes = []
|
||||
# - $state (Ui-Router) [ 'app.public.spaces_list' ]
|
||||
##
|
||||
class SpacesController
|
||||
constructor: ($scope, $state) ->
|
||||
##
|
||||
# For use with ngUpload (https://github.com/twilson63/ngUpload).
|
||||
# Intended to be the callback when the upload is done: any raised error will be stacked in the
|
||||
# $scope.alerts array. If everything goes fine, the user is redirected to the spaces list.
|
||||
# @param content {Object} JSON - The upload's result
|
||||
##
|
||||
$scope.submited = (content) ->
|
||||
if !content.id?
|
||||
$scope.alerts = []
|
||||
angular.forEach content, (v, k)->
|
||||
angular.forEach v, (err)->
|
||||
$scope.alerts.push
|
||||
msg: k+': '+err
|
||||
type: 'danger'
|
||||
else
|
||||
$state.go('app.public.spaces_list')
|
||||
|
||||
##
|
||||
# Changes the current user's view, redirecting him to the spaces list
|
||||
##
|
||||
$scope.cancel = ->
|
||||
$state.go('app.public.spaces_list')
|
||||
|
||||
##
|
||||
# For use with 'ng-class', returns the CSS class name for the uploads previews.
|
||||
# The preview may show a placeholder or the content of the file depending on the upload state.
|
||||
# @param v {*} any attribute, will be tested for truthiness (see JS evaluation rules)
|
||||
##
|
||||
$scope.fileinputClass = (v)->
|
||||
if v
|
||||
'fileinput-exists'
|
||||
else
|
||||
'fileinput-new'
|
||||
|
||||
##
|
||||
# This will create a single new empty entry into the space attachements list.
|
||||
##
|
||||
$scope.addFile = ->
|
||||
$scope.space.space_files_attributes.push {}
|
||||
|
||||
##
|
||||
# This will remove the given file from the space attachements list. If the file was previously uploaded
|
||||
# to the server, it will be marked for deletion on the server. Otherwise, it will be simply truncated from
|
||||
# the attachements array.
|
||||
# @param file {Object} the file to delete
|
||||
##
|
||||
$scope.deleteFile = (file) ->
|
||||
index = $scope.space.space_files_attributes.indexOf(file)
|
||||
if file.id?
|
||||
file._destroy = true
|
||||
else
|
||||
$scope.space.space_files_attributes.splice(index, 1)
|
||||
|
||||
##
|
||||
# Manages the transition when a user clicks on the reservation button.
|
||||
# According to the status of user currently logged into the system, redirect him to the reservation page,
|
||||
@ -26,7 +98,7 @@ _reserveSpace = (space, e) ->
|
||||
##
|
||||
Application.Controllers.controller "SpacesController", ["$scope", "$state", 'spacesPromise', ($scope, $state, spacesPromise) ->
|
||||
|
||||
## Retrieve the list of machines
|
||||
## Retrieve the list of spaces
|
||||
$scope.spaces = spacesPromise
|
||||
|
||||
##
|
||||
@ -36,7 +108,7 @@ Application.Controllers.controller "SpacesController", ["$scope", "$state", 'spa
|
||||
$state.go('app.public.space_show', { id: space.slug })
|
||||
|
||||
##
|
||||
# Callback to book a reservation for the current machine
|
||||
# Callback to book a reservation for the current space
|
||||
##
|
||||
$scope.reserveSpace = _reserveSpace.bind
|
||||
$scope: $scope
|
||||
@ -57,7 +129,7 @@ Application.Controllers.controller "NewSpaceController", ["$scope", "$state", 'C
|
||||
## Form action on the above URL
|
||||
$scope.method = "post"
|
||||
|
||||
## default machine parameters
|
||||
## default space parameters
|
||||
$scope.space =
|
||||
space_files_attributes: []
|
||||
|
||||
|
@ -0,0 +1,134 @@
|
||||
<form role="form"
|
||||
name="spaceForm"
|
||||
class="form-horizontal"
|
||||
action="{{ actionUrl }}"
|
||||
ng-upload="submited(content)"
|
||||
upload-options-enable-rails-csrf="true"
|
||||
unsaved-warning-form
|
||||
novalidate>
|
||||
|
||||
<input name="_method" type="hidden" ng-value="method">
|
||||
|
||||
<section class="panel panel-default bg-light m-lg">
|
||||
<div class="panel-body m-r">
|
||||
|
||||
<uib-alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)">{{alert.msg}}</uib-alert>
|
||||
|
||||
<div class="form-group m-b-lg" ng-class="{'has-error': spaceForm['space[name]'].$dirty && spaceForm['space[name]'].$invalid}">
|
||||
<label for="space_name" class="col-sm-2 control-label">{{ 'space.name' | translate }} *</label>
|
||||
<div class="col-sm-4">
|
||||
<input ng-model="space.name"
|
||||
type="text"
|
||||
name="space[name]"
|
||||
class="form-control"
|
||||
id="space_name"
|
||||
placeholder="{{'space.name' | translate}}"
|
||||
required>
|
||||
<span class="help-block" ng-show="spaceForm['space[name]'].$dirty && spaceForm['space[name]'].$error.required" translate>{{ 'space.name_is_required' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group m-b-lg">
|
||||
<label for="space_image" class="col-sm-2 control-label">{{ 'space.illustration' | translate }} *</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="fileinput" data-provides="fileinput" ng-class="fileinputClass(space.space_image)">
|
||||
<div class="fileinput-new thumbnail" style="width: 334px; height: 250px;">
|
||||
<img src="data:image/png;base64," data-src="holder.js/100%x100%/text:/font:FontAwesome/icon" bs-holder ng-if="!space.space_image">
|
||||
</div>
|
||||
<div class="fileinput-preview fileinput-exists thumbnail" style="max-width: 334px;">
|
||||
<img ng-src="{{ space.space_image }}" alt="" />
|
||||
</div>
|
||||
<div>
|
||||
<span class="btn btn-default btn-file">
|
||||
<span class="fileinput-new">{{ 'space.add_an_illustration' | translate }} <i class="fa fa-upload fa-fw"></i></span>
|
||||
<span class="fileinput-exists" translate>{{ 'change' }}</span>
|
||||
<input type="file"
|
||||
id="space_image"
|
||||
ng-model="space.space_image"
|
||||
name="space[space_image_attributes][attachment]"
|
||||
accept="image/*"
|
||||
required
|
||||
bs-jasny-fileinput>
|
||||
</span>
|
||||
<a href="#" class="btn btn-danger fileinput-exists" data-dismiss="fileinput" translate>{{ 'delete' }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group m-b-xl" ng-class="{'has-error': spaceForm['space[default_places]'].$dirty && spaceForm['space[default_places]'].$invalid}">
|
||||
<label for="default_places" class="col-sm-2 control-label">{{ 'space.default_places' | translate }} *</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number"
|
||||
name="space[default_places]"
|
||||
ng-model="space.default_places"
|
||||
id="default_places"
|
||||
class="form-control"
|
||||
required>
|
||||
<span class="help-block" ng-show="spaceForm['space[default_places]'].$dirty && spaceForm['space[default_places]'].$error.required" translate>{{ 'space.default_places_is_required' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group m-b-xl">
|
||||
<label for="space_description" class="col-sm-2 control-label" translate>{{ 'space.description' }}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="hidden"
|
||||
name="space[description]"
|
||||
ng-value="space.description" />
|
||||
<summernote ng-model="space.description"
|
||||
id="space_description"
|
||||
placeholder=""
|
||||
config="summernoteOpts"
|
||||
name="space[description]">
|
||||
</summernote>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group m-b-xl">
|
||||
<label for="space_characteristics" class="col-sm-2 control-label" translate>{{ 'space.characteristics' }}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="hidden"
|
||||
name="space[characteristics]"
|
||||
ng-value="space.characteristics" />
|
||||
<summernote ng-model="space.characteristics"
|
||||
id="space_characteristics"
|
||||
placeholder=""
|
||||
config="summernoteOpts"
|
||||
name="space[characteristics]">
|
||||
</summernote>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group m-b-xl">
|
||||
<label class="col-sm-2 control-label" translate>{{ 'space.attached_files_(pdf)' }}</label>
|
||||
<div class="col-sm-10">
|
||||
<div ng-repeat="file in space.space_files_attributes" ng-show="!file._destroy">
|
||||
<input type="hidden" ng-model="file.id" name="space[space_files_attributes][][id]" ng-value="file.id" />
|
||||
<input type="hidden" ng-model="file._destroy" name="space[space_files_attributes][][_destroy]" ng-value="file._destroy"/>
|
||||
|
||||
<div class="fileinput input-group" data-provides="fileinput" ng-class="fileinputClass(file.attachment)">
|
||||
<div class="form-control" data-trigger="fileinput">
|
||||
<i class="glyphicon glyphicon-file fileinput-exists"></i> <span class="fileinput-filename">{{file.attachment}}</span>
|
||||
</div>
|
||||
<span class="input-group-addon btn btn-default btn-file"><span class="fileinput-new" translate>{{ 'space.attach_a_file' }}</span>
|
||||
<span class="fileinput-exists" translate>{{ 'change' }}</span><input type="file" name="space[space_files_attributes][][attachment]" accept=".pdf"></span>
|
||||
<a class="input-group-addon btn btn-danger fileinput-exists" data-dismiss="fileinput" ng-click="deleteFile(file)"><i class="fa fa-trash-o"></i></a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<a class="btn btn-default" ng-click="addFile()" role="button"> {{ 'space.add_an_attachment' | translate }} <i class="fa fa-file-o fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- ./panel-body -->
|
||||
|
||||
<div class="panel-footer no-padder">
|
||||
<input type="submit"
|
||||
value="{{ 'space.add_this_space' | translate }}"
|
||||
class="r-b btn-valid btn btn-warning btn-block p-lg btn-lg text-u-c"
|
||||
ng-disabled="spaceForm.$invalid"/>
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
@ -42,7 +42,7 @@ class API::SpacesController < API::ApiController
|
||||
end
|
||||
|
||||
def space_params
|
||||
params.require(:space).permit(:name, :description, :characteristics, space_image_attributes: [:attachment],
|
||||
params.require(:space).permit(:name, :description, :characteristics, :default_places, space_image_attributes: [:attachment],
|
||||
space_files_attributes: [:id, :attachment, :_destroy])
|
||||
end
|
||||
end
|
||||
|
@ -2,6 +2,8 @@ class Space < ActiveRecord::Base
|
||||
extend FriendlyId
|
||||
friendly_id :name, use: :slugged
|
||||
|
||||
validates :name, :default_places, presence: true
|
||||
|
||||
has_one :space_image, as: :viewable, dependent: :destroy
|
||||
accepts_nested_attributes_for :space_image, allow_destroy: true
|
||||
has_many :space_files, as: :viewable, dependent: :destroy
|
||||
|
@ -73,7 +73,7 @@ fr:
|
||||
# créer un nouvel espace
|
||||
add_a_new_space: "Ajouter un nouvel espace"
|
||||
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "Attention, lors de la création d'un espace, ses tarifs de réservation sont initialisés à zero pour tout les abonnements."
|
||||
consider_changing_its_prices_before_creating_any_reservation_slot: "Pensez à modifier ces prix avant de créer des créneaux pour cette machine."
|
||||
consider_changing_its_prices_before_creating_any_reservation_slot: "Pensez à modifier ces prix avant de créer des créneaux pour cet espace."
|
||||
|
||||
events:
|
||||
# gestion et suivi des évènements
|
||||
|
@ -381,3 +381,21 @@ en:
|
||||
unable_to_apply_the_coupon_because_amount_exceeded: "Unable to apply the coupon: the discount exceed the total amount of this purchase."
|
||||
unable_to_apply_the_coupon_because_undefined: "Unable to apply the coupon: an unexpected error occurred, please contact the Fablab's manager."
|
||||
unable_to_apply_the_coupon_because_rejected: "This code does not exists."
|
||||
|
||||
space:
|
||||
# form to create/edit a space
|
||||
space:
|
||||
name: "Name"
|
||||
name_is_required: "Name is required."
|
||||
illustration: "Illustration"
|
||||
add_an_illustration: "Add an illustration"
|
||||
description: "Description"
|
||||
description_is_required: "Description is required."
|
||||
characteristics: "Characteristics"
|
||||
characteristics_are_required: "Characteristics are required."
|
||||
attached_files_(pdf): "Attached files (pdf)"
|
||||
attach_a_file: "Attach a file"
|
||||
add_an_attachment: "Add an attachment"
|
||||
add_this_space: "Add this space"
|
||||
default_places: "Default maximum tickets"
|
||||
default_places_is_required: "Default maximum tickets is required."
|
@ -380,4 +380,22 @@ fr:
|
||||
unable_to_apply_the_coupon_because_already_used: "Impossible d'appliquer la réduction : vous avez déjà utilisé ce code promo par le passé."
|
||||
unable_to_apply_the_coupon_because_amount_exceeded: "Impossible d'appliquer la réduction : la réduction dépasse le total de cet achat."
|
||||
unable_to_apply_the_coupon_because_undefined: "Impossible d'appliquer la réduction : une erreur inattendue s'est produite, veuillez contacter le gestionnaire du Fablab."
|
||||
unable_to_apply_the_coupon_because_rejected: "Ce code promo n'existe pas."
|
||||
unable_to_apply_the_coupon_because_rejected: "Ce code promo n'existe pas."
|
||||
|
||||
space:
|
||||
# formulaire de création/modification d'un espace
|
||||
space:
|
||||
name: "Nom"
|
||||
name_is_required: "Le nom est requis."
|
||||
illustration: "Visuel"
|
||||
add_an_illustration: "Ajouter un visuel"
|
||||
description: "Description"
|
||||
description_is_required: "La description est requise."
|
||||
characteristics: "Caractéristiques"
|
||||
characteristics_are_required: "Les caractéristiques sont requises."
|
||||
attached_files_(pdf): "Pièces jointes (pdf)"
|
||||
attach_a_file: "Joindre un fichier"
|
||||
add_an_attachment: "Ajouter une pièce jointe"
|
||||
add_this_space: "Ajouter cet espace"
|
||||
default_places: "Maximum de places par défaut"
|
||||
default_places_is_required: "Le nombre de places maximum par défaut est requis."
|
Loading…
Reference in New Issue
Block a user