mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-18 07:52:23 +01:00
[ongoing][UI] advanced trainings management
This commit is contained in:
parent
2df2d8796d
commit
644a5a9d47
@ -1,7 +1,52 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
Application.Controllers.controller "TrainingsController", ["$scope", "$state", "$uibModal", 'Training', 'trainingsPromise', 'machinesPromise', '_t', 'growl'
|
|
||||||
, ($scope, $state, $uibModal, Training, trainingsPromise, machinesPromise, _t, growl) ->
|
|
||||||
|
##
|
||||||
|
# Controller used in the training creation page (admin)
|
||||||
|
##
|
||||||
|
Application.Controllers.controller "NewTrainingController", [ '$scope', ($scope) ->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### PUBLIC SCOPE ###
|
||||||
|
|
||||||
|
## Form action on the following URL
|
||||||
|
$scope.method = 'post'
|
||||||
|
|
||||||
|
## API URL where the form will be posted
|
||||||
|
$scope.actionUrl = '/api/trainings'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Controller used in the training edition page (admin)
|
||||||
|
##
|
||||||
|
Application.Controllers.controller "EditTrainingController", [ '$scope', '$stateParams', 'trainingPromise', ($scope, $stateParams, trainingPromise) ->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### PUBLIC SCOPE ###
|
||||||
|
|
||||||
|
## Form action on the following URL
|
||||||
|
$scope.method = 'put'
|
||||||
|
|
||||||
|
## API URL where the form will be posted
|
||||||
|
$scope.actionUrl = '/api/trainings' + $stateParams.id
|
||||||
|
|
||||||
|
## Details of the training to edit (id in URL)
|
||||||
|
$scope.training = trainingPromise
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Controller used in the public listing page, allowing logged users to see the list of trainings
|
||||||
|
##
|
||||||
|
Application.Controllers.controller "TrainingsController", ["$scope", "$state", "$uibModal", 'Training', 'trainingsPromise', 'machinesPromise', '_t', 'growl', 'dialogs'
|
||||||
|
, ($scope, $state, $uibModal, Training, trainingsPromise, machinesPromise, _t, growl, dialogs) ->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -40,35 +85,6 @@ Application.Controllers.controller "TrainingsController", ["$scope", "$state", "
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Create a new empty training object and append it to the $scope.trainings list
|
|
||||||
##
|
|
||||||
$scope.addTraining = ->
|
|
||||||
$scope.inserted =
|
|
||||||
name: ''
|
|
||||||
machine_ids: []
|
|
||||||
$scope.trainings.push($scope.inserted)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Saves a new training / Update an existing training to the server (form validation callback)
|
|
||||||
# @param data {Object} training name, associated machine(s) and default places number
|
|
||||||
# @param id {number} training id, in case of update
|
|
||||||
##
|
|
||||||
$scope.saveTraining = (data, id) ->
|
|
||||||
if id?
|
|
||||||
Training.update {id: id},
|
|
||||||
training: data
|
|
||||||
else
|
|
||||||
Training.save
|
|
||||||
training: data
|
|
||||||
, (resp) ->
|
|
||||||
$scope.trainings[$scope.trainings.length-1] = resp
|
|
||||||
console.log(resp)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Removes the newly inserted but not saved training / Cancel the current training modification
|
# Removes the newly inserted but not saved training / Cancel the current training modification
|
||||||
# @param rowform {Object} see http://vitalets.github.io/angular-xeditable/
|
# @param rowform {Object} see http://vitalets.github.io/angular-xeditable/
|
||||||
@ -138,6 +154,12 @@ Application.Controllers.controller "TrainingsController", ["$scope", "$state", "
|
|||||||
# @param training {Object} training to delete
|
# @param training {Object} training to delete
|
||||||
##
|
##
|
||||||
$scope.removeTraining = (index, training)->
|
$scope.removeTraining = (index, training)->
|
||||||
|
dialogs.confirm
|
||||||
|
resolve:
|
||||||
|
object: ->
|
||||||
|
title: _t('confirmation_required')
|
||||||
|
msg: _t('do_you_really_want_to_delete_this_traning')
|
||||||
|
, -> # deletion confirmed
|
||||||
training.$delete ->
|
training.$delete ->
|
||||||
$scope.trainings.splice(index, 1)
|
$scope.trainings.splice(index, 1)
|
||||||
growl.info(_t('training_successfully_deleted'))
|
growl.info(_t('training_successfully_deleted'))
|
||||||
@ -146,25 +168,6 @@ Application.Controllers.controller "TrainingsController", ["$scope", "$state", "
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Open the modal to edit description of the training
|
|
||||||
# @param training {Object} Training to edit description
|
|
||||||
##
|
|
||||||
$scope.openModalToSetDescription = (training)->
|
|
||||||
$uibModal.open(
|
|
||||||
templateUrl: "<%= asset_path 'admin/trainings/modal_edit.html' %>"
|
|
||||||
controller: ['$scope', '$uibModalInstance', 'Training', 'growl', ($scope, $uibModalInstance, Training, growl)->
|
|
||||||
$scope.training = training
|
|
||||||
$scope.save = ->
|
|
||||||
Training.update id: training.id, { training: { description: $scope.training.description } }, (training)->
|
|
||||||
$uibModalInstance.close()
|
|
||||||
growl.success(_t('description_was_successfully_saved'))
|
|
||||||
return
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Takes a month number and return its localized literal name
|
# Takes a month number and return its localized literal name
|
||||||
# @param {Number} from 0 to 11
|
# @param {Number} from 0 to 11
|
||||||
|
@ -523,7 +523,29 @@ angular.module('application.router', ['ui.router']).
|
|||||||
translations: [ 'Translations', (Translations) ->
|
translations: [ 'Translations', (Translations) ->
|
||||||
Translations.query('app.admin.trainings').$promise
|
Translations.query('app.admin.trainings').$promise
|
||||||
]
|
]
|
||||||
|
.state 'app.admin.trainings_new',
|
||||||
|
url: '/admin/trainings/new'
|
||||||
|
views:
|
||||||
|
'main@':
|
||||||
|
templateUrl: '<%= asset_path "admin/trainings/new.html" %>'
|
||||||
|
controller: 'NewTrainingController'
|
||||||
|
resolve:
|
||||||
|
translations: [ 'Translations', (Translations) ->
|
||||||
|
Translations.query(['app.admin.trainings_new', 'app.shared.trainings']).$promise
|
||||||
|
]
|
||||||
|
.state 'app.admin.trainings_edit',
|
||||||
|
url: '/admin/trainings/:id/edit'
|
||||||
|
views:
|
||||||
|
'main@':
|
||||||
|
templateUrl: '<%= asset_path "admin/trainings/edit.html" %>'
|
||||||
|
controller: 'EditTrainingController'
|
||||||
|
resolve:
|
||||||
|
trainingPromise: ['Training', '$stateParams', (Training, $stateParams)->
|
||||||
|
Training.get(id: $stateParams.id).$promise
|
||||||
|
]
|
||||||
|
translations: [ 'Translations', (Translations) ->
|
||||||
|
Translations.query(['app.admin.trainings_edit', 'app.shared.trainings']).$promise
|
||||||
|
]
|
||||||
# events
|
# events
|
||||||
.state 'app.admin.events',
|
.state 'app.admin.events',
|
||||||
url: '/admin/events'
|
url: '/admin/events'
|
||||||
|
60
app/assets/templates/admin/trainings/_form.html.erb
Normal file
60
app/assets/templates/admin/trainings/_form.html.erb
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<form role="form" name="trainingForm" class="form-horizontal" novalidate action="{{ actionUrl }}" ng-upload="submited(content)" upload-options-enable-rails-csrf="true" unsaved-warning-form>
|
||||||
|
|
||||||
|
<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': trainingForm['training[name]'].$dirty && trainingForm['training[name]'].$invalid}">
|
||||||
|
<label for="name" class="col-sm-2 control-label">{{ 'name' | translate }} *</label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<input ng-model="training.name" type="text" name="training[name]" class="form-control" id="training_name" placeholder="{{'name' | translate}}" required>
|
||||||
|
<span class="help-block" ng-show="trainingForm['training[name]'].$dirty && trainingForm['training[name]'].$error.required" translate>{{ 'name_is_required' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group m-b-lg">
|
||||||
|
<label for="training_image" class="col-sm-2 control-label">{{ 'illustration' | translate }} *</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="fileinput" data-provides="fileinput" ng-class="fileinputClass(training.training_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="!training.training_image">
|
||||||
|
</div>
|
||||||
|
<div class="fileinput-preview fileinput-exists thumbnail" style="max-width: 334px;">
|
||||||
|
<img ng-src="{{ training.training_image }}" alt="" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span class="btn btn-default btn-file">
|
||||||
|
<span class="fileinput-new">{{ 'add_an_illustration' | translate }} <i class="fa fa-upload fa-fw"></i></span>
|
||||||
|
<span class="fileinput-exists" translate>{{ 'change' }}</span>
|
||||||
|
<input type="file"
|
||||||
|
ng-model="training.training_image"
|
||||||
|
name="training[training_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': trainingForm['training[description]'].$dirty && trainingForm['training[description]'].$invalid}">
|
||||||
|
<label for="description" class="col-sm-2 control-label">{{ 'description' | translate }} *</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<textarea ng-model="training.description" class="form-control" rows="12" id="training_description" placeholder="" name="training[description]" required></textarea>
|
||||||
|
<span class="help-block" ng-show="trainingForm['training[description]'].$dirty && trainingForm['training[description]'].$error.required" translate>{{ 'description_is_required' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div> <!-- ./panel-body -->
|
||||||
|
|
||||||
|
<div class="panel-footer no-padder">
|
||||||
|
<input type="submit" value="{{ 'validate_your_training' | translate }}" class="r-b btn-valid btn btn-warning btn-block p-lg btn-lg text-u-c" ng-disabled="trainingForm.$invalid"/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</form>
|
30
app/assets/templates/admin/trainings/edit.html.erb
Normal file
30
app/assets/templates/admin/trainings/edit.html.erb
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<div>
|
||||||
|
|
||||||
|
<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 ng-click="cancel()"><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>{{ training.name }}</h1>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xs-12 col-sm-12 col-md-3 b-t hide-b-md">
|
||||||
|
<section class="heading-actions wrapper">
|
||||||
|
<div class="btn btn-lg btn-block btn-default rounded m-t-xs" ng-click="cancel()" translate>{{ 'cancel' }}</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row no-gutter">
|
||||||
|
<div class="col-sm-12 col-md-12 col-lg-9 b-r-lg nopadding">
|
||||||
|
<ng-include src="'<%= asset_path 'admin/trainings/_form.html' %>'"></ng-include>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -21,11 +21,7 @@
|
|||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<uib-tabset justified="true">
|
<uib-tabset justified="true">
|
||||||
<uib-tab heading="{{ 'trainings' | translate }}">
|
<uib-tab heading="{{ 'trainings' | translate }}">
|
||||||
<button type="button" class="btn btn-warning m-t m-b" ng-click="addTraining()" translate>{{ 'add_a_new_training' }}</button>
|
<button type="button" class="btn btn-warning m-t m-b" ui-sref="app.admin.trainings_new" translate>{{ 'add_a_new_training' }}</button>
|
||||||
<div class="alert alert-warning" role="alert">
|
|
||||||
{{ 'beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero' | translate }}
|
|
||||||
{{ 'dont_forget_to_change_them_before_creating_slots_for_this_training' | translate }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
@ -38,35 +34,12 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="training in trainings">
|
<tr ng-repeat="training in trainings">
|
||||||
|
<td>{{ training.name }}</td>
|
||||||
|
<td>{{ showMachines(training) }}</td>
|
||||||
|
<td>{{ training.nb_total_places }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span editable-text="training.name" e-name="name" e-form="rowform" e-required>
|
<div class="buttons">
|
||||||
{{ training.name }}
|
<button class="btn btn-default" ui-sref="app.admin.trainings_edit({id:training.id})">
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span editable-checklist="training.machine_ids" e-ng-options="m.id as m.name for m in machines" e-name="machine_ids" e-form="rowform">
|
|
||||||
{{ showMachines(training) }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span editable-number="training.nb_total_places" e-name="nb_total_places" e-form="rowform" e-required>
|
|
||||||
{{ training.nb_total_places }}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<form editable-form name="rowform" onbeforesave="saveTraining($data, training.id)" ng-show="rowform.$visible" class="form-buttons form-inline" shown="inserted == training">
|
|
||||||
<button type="submit" ng-disabled="rowform.$waiting" class="btn btn-warning">
|
|
||||||
<i class="fa fa-check"></i>
|
|
||||||
</button>
|
|
||||||
<button type="button" ng-disabled="rowform.$waiting" ng-click="cancelTraining(rowform, $index)" class="btn btn-default">
|
|
||||||
<i class="fa fa-times"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
<div class="buttons" ng-show="!rowform.$visible">
|
|
||||||
<button ng-click="openModalToSetDescription(training)" class="btn btn-default">
|
|
||||||
<i class="fa fa-comment-o"></i>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-default" ng-click="rowform.$show()">
|
|
||||||
<i class="fa fa-edit"></i> {{ 'edit' | translate }}
|
<i class="fa fa-edit"></i> {{ 'edit' | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-danger" ng-click="removeTraining($index, training)">
|
<button class="btn btn-danger" ng-click="removeTraining($index, training)">
|
||||||
|
35
app/assets/templates/admin/trainings/new.html.erb
Normal file
35
app/assets/templates/admin/trainings/new.html.erb
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<section class="heading b-b">
|
||||||
|
<div class="row no-gutter">
|
||||||
|
<div class="col-md-1 hidden-xs">
|
||||||
|
<section class="heading-btn">
|
||||||
|
<a href="#" ng-click="backPrevLocation($event)"><i class="fa fa-long-arrow-left "></i></a>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8 b-l b-r">
|
||||||
|
<section class="heading-title">
|
||||||
|
<h1 translate>{{ 'add_a_new_training' }}</h1>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row no-gutter" >
|
||||||
|
|
||||||
|
<div class="col-md-9 b-r nopadding">
|
||||||
|
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
{{ 'beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero' | translate }}
|
||||||
|
{{ 'dont_forget_to_change_them_before_creating_slots_for_this_training' | translate }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-include src="'<%= asset_path 'admin/trainings/_form.html' %>'"></ng-include>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<!-- <button class="btn">TEST</button> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -10,7 +10,7 @@
|
|||||||
<div class="form-group m-b-lg" ng-class="{'has-error': machineForm['machine[name]'].$dirty && machineForm['machine[name]'].$invalid}">
|
<div class="form-group m-b-lg" ng-class="{'has-error': machineForm['machine[name]'].$dirty && machineForm['machine[name]'].$invalid}">
|
||||||
<label for="name" class="col-sm-2 control-label">{{ 'name' | translate }} *</label>
|
<label for="name" class="col-sm-2 control-label">{{ 'name' | translate }} *</label>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<input ng-model="machine.name" type="text" name="machine[name]" class="form-control" id="machine_name" placeholder="Nom :" required>
|
<input ng-model="machine.name" type="text" name="machine[name]" class="form-control" id="machine_name" placeholder="{{'name' | translate}}" required>
|
||||||
<span class="help-block" ng-show="machineForm['machine[name]'].$dirty && machineForm['machine[name]'].$error.required" translate>{{ 'name_is_required' }}</span>
|
<span class="help-block" ng-show="machineForm['machine[name]'].$dirty && machineForm['machine[name]'].$error.required" translate>{{ 'name_is_required' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user