mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-29 18:52:22 +01:00
ability to set phone number optional or required
also: show stars on required fields in new admin form
This commit is contained in:
parent
9ec736e6b5
commit
ad928bd4e6
@ -1,13 +1,17 @@
|
||||
# Changelog Fab Manager
|
||||
|
||||
- Ability to create and delete periodic calendar availabilities (recurrence)
|
||||
- An administrator can delete a member
|
||||
- Ability to configure the duration of a reservation slot. Previously, only 60 minutes slots were allowed
|
||||
- Display indications on required fields in new administrator form
|
||||
- Configuration of phone number in members registration forms: can be required or optional, depending on `PHONE_REQUIRED` configuration
|
||||
- Improved user experience in defining slots in the calendar management
|
||||
- Improved notification email to the member when a rolling subscription is taken
|
||||
- Handle Ctrl^C in upgrade scripts
|
||||
- Updated moment-timezone
|
||||
- Fix a security issue: fixed [CVE-2019-15587](https://github.com/advisories/GHSA-c3gv-9cxf-6f57)
|
||||
- [TODO DEPLOY] add the `SLOT_DURATION` environment variable (see [doc/environment.md](doc/environment.md#SLOT_DURATION) for configuration details)
|
||||
- [TODO DEPLOY] add the `PHONE_REQUIRED` environment variable (see [doc/environment.md](doc/environment.md#PHONE_REQUIRED) for configuration details)
|
||||
- [TODO DEPLOY] -> (only dev) `bundle install`
|
||||
- [TODO DEPLOY] `rake db:migrate`
|
||||
|
||||
|
@ -86,6 +86,8 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
|
||||
$rootScope.fablabWithoutOnlinePayment = Fablab.withoutOnlinePayment;
|
||||
// Global config: if true, no invoices will be generated
|
||||
$rootScope.fablabWithoutInvoices = Fablab.withoutInvoices;
|
||||
// Global config: if true, the phone number is required to create an account
|
||||
$rootScope.phoneRequired = Fablab.phoneRequired;
|
||||
|
||||
// Global function to allow the user to navigate to the previous screen (ie. $state).
|
||||
// If no previous $state were recorded, navigate to the home page
|
||||
|
@ -20,7 +20,7 @@
|
||||
<form role="form" name="adminForm" class="form-horizontal" novalidate>
|
||||
<section class="panel panel-default bg-light m-lg">
|
||||
<div class="panel-body m-r">
|
||||
<ng-include src="'<%= asset_path 'shared/_admin_form.html' %>'"></ng-include>
|
||||
<ng-include src="'<%= asset_path "shared/_admin_form.html" %>'"></ng-include>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -1,26 +1,27 @@
|
||||
<div class="row m-t">
|
||||
<div class="col-sm-offset-3 col-sm-6">
|
||||
<div class="form-group" ng-class="{'has-error': adminForm['admin[statistic_profile_attributes][gender]'].$dirty && adminForm['admin[statistic_profile_attributes][gender]'].$invalid}">
|
||||
<label class="checkbox-inline btn btn-default">
|
||||
<input type="radio"
|
||||
name="admin[statistic_profile_attributes][gender]"
|
||||
ng-model="admin.statistic_profile_attributes.gender"
|
||||
ng-value="true"
|
||||
required/>
|
||||
<i class="fa fa-male m-l-sm"></i> {{ 'man' | translate }}
|
||||
</label>
|
||||
<label class="checkbox-inline btn btn-default">
|
||||
<input type="radio"
|
||||
name="admin[statistic_profile_attributes][gender]"
|
||||
ng-model="admin.statistic_profile_attributes.gender"
|
||||
ng-value="false"/>
|
||||
<i class="fa fa-female m-l-sm"></i> {{ 'woman' | translate }}
|
||||
</label>
|
||||
<label class="checkbox-inline btn btn-default">
|
||||
<input type="radio"
|
||||
name="admin[statistic_profile_attributes][gender]"
|
||||
ng-model="admin.statistic_profile_attributes.gender"
|
||||
ng-value="true"
|
||||
required/>
|
||||
<i class="fa fa-male m-l-sm"></i> {{ 'man' | translate }}
|
||||
</label>
|
||||
<label class="checkbox-inline btn btn-default">
|
||||
<input type="radio"
|
||||
name="admin[statistic_profile_attributes][gender]"
|
||||
ng-model="admin.statistic_profile_attributes.gender"
|
||||
ng-value="false"/>
|
||||
<i class="fa fa-female m-l-sm"></i> {{ 'woman' | translate }}
|
||||
</label>
|
||||
<span class="exponent m-l-xs help-cursor"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': adminForm['admin[username]'].$dirty && adminForm['admin[username]'].$invalid}">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-user"></i></span>
|
||||
<span class="input-group-addon"><i class="fa fa-user"></i> <span class="exponent"><i class="fa fa-asterisk" aria-hidden="true"></i></span></span>
|
||||
<input ng-model="admin.username"
|
||||
type="text" name="admin[username]"
|
||||
class="form-control"
|
||||
@ -33,7 +34,7 @@
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': adminForm['admin[profile_attributes][last_name]'].$dirty && adminForm['admin[profile_attributes][last_name]'].$invalid}">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-user"></i></span>
|
||||
<span class="input-group-addon"><i class="fa fa-user"></i> <span class="exponent"><i class="fa fa-asterisk" aria-hidden="true"></i></span></span>
|
||||
<input ng-model="admin.profile_attributes.last_name"
|
||||
type="text"
|
||||
name="admin[profile_attributes][last_name]"
|
||||
@ -47,7 +48,7 @@
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': adminForm['admin[profile_attributes][first_name]'].$dirty && adminForm['admin[profile_attributes][first_name]'].$invalid}">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-user"></i></span>
|
||||
<span class="input-group-addon"><i class="fa fa-user"></i> <span class="exponent"><i class="fa fa-asterisk" aria-hidden="true"></i></span></span>
|
||||
<input ng-model="admin.profile_attributes.first_name"
|
||||
type="text"
|
||||
name="admin[profile_attributes][first_name]"
|
||||
@ -61,7 +62,7 @@
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': adminForm['admin[email]'].$dirty && adminForm['admin[email]'].$invalid}">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-envelope"></i> </span>
|
||||
<span class="input-group-addon"><i class="fa fa-envelope"></i> <span class="exponent"><i class="fa fa-asterisk" aria-hidden="true"></i></span></span>
|
||||
<input ng-model="admin.email"
|
||||
type="email"
|
||||
name="admin[email]"
|
||||
|
@ -240,7 +240,7 @@
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': userForm['user[profile_attributes][phone]'].$dirty && userForm['user[profile_attributes][phone]'].$invalid}">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon help-cursor" title="{{ 'used_for_reservation' | translate }}"><i class="fa fa-phone"></i> <span class="exponent"><i class="fa fa-asterisk" aria-hidden="true"></i></span></span>
|
||||
<span class="input-group-addon help-cursor" title="{{ 'used_for_reservation' | translate }}"><i class="fa fa-phone"></i> <span class="exponent" ng-show="phoneRequired"><i class="fa fa-asterisk" aria-hidden="true"></i></span></span>
|
||||
<input type="text"
|
||||
name="user[profile_attributes][phone]"
|
||||
ng-model="user.profile.phone"
|
||||
@ -248,7 +248,7 @@
|
||||
id="user_phone"
|
||||
placeholder="{{ 'phone_number' | translate }}"
|
||||
ng-disabled="preventField['profile.phone'] && user.profile.phone && !userForm['user[profile_attributes][phone]'].$dirty"
|
||||
required/>
|
||||
ng-required="phoneRequired"/>
|
||||
</div>
|
||||
<span class="help-block" ng-show="userForm['user[profile_attributes][phone]'].$dirty && userForm['user[profile_attributes][phone]'].$error.required" translate>{{ 'phone_number_is_required' }}</span>
|
||||
</div>
|
||||
|
@ -204,9 +204,11 @@
|
||||
name="phone"
|
||||
class="form-control"
|
||||
placeholder="{{ 'phone_number' | translate }}"
|
||||
required>
|
||||
ng-required="phoneRequired">
|
||||
</div>
|
||||
<span class="exponent help-cursor" title="{{ 'used_for_reservation' | translate }}"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
<span ng-show="phoneRequired" class="exponent help-cursor" title="{{ 'used_for_reservation' | translate }}">
|
||||
<i class="fa fa-asterisk" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="help-block" ng-show="signupForm.phone.$dirty && signupForm.phone.$error.required" translate>{{ 'phone_number_is_required' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -10,7 +10,7 @@ class Profile < ActiveRecord::Base
|
||||
|
||||
validates :first_name, presence: true, length: { maximum: 30 }
|
||||
validates :last_name, presence: true, length: { maximum: 30 }
|
||||
validates_numericality_of :phone, only_integer: true, allow_blank: false
|
||||
validates_numericality_of :phone, only_integer: true, allow_blank: false, if: -> { Rails.application.secrets.phone_required }
|
||||
|
||||
after_commit :update_invoicing_profile, if: :invoicing_data_was_modified?, on: [:update]
|
||||
|
||||
|
@ -160,7 +160,8 @@ class User < ActiveRecord::Base
|
||||
|
||||
def need_completion?
|
||||
statistic_profile.gender.nil? || profile.first_name.blank? || profile.last_name.blank? || username.blank? ||
|
||||
email.blank? || encrypted_password.blank? || group_id.nil? || statistic_profile.birthday.blank? || profile.phone.blank?
|
||||
email.blank? || encrypted_password.blank? || group_id.nil? || statistic_profile.birthday.blank? ||
|
||||
(Rails.application.secrets.phone_required && profile.phone.blank?)
|
||||
end
|
||||
|
||||
## Retrieve the requested data in the User and user's Profile tables
|
||||
|
@ -20,6 +20,7 @@
|
||||
Fablab.withoutSpaces = ('<%= Rails.application.secrets.fablab_without_spaces %>' !== 'false');
|
||||
Fablab.withoutOnlinePayment = ('<%= Rails.application.secrets.fablab_without_online_payments %>' === 'true');
|
||||
Fablab.withoutInvoices = ('<%= Rails.application.secrets.fablab_without_invoices %>' === 'true');
|
||||
Fablab.phoneRequired = ('<%= Rails.application.secrets.phone_required %>' === 'true');
|
||||
Fablab.slotDuration = parseInt("<%= ApplicationHelper::SLOT_DURATION %>", 10);
|
||||
Fablab.disqusShortname = "<%= Rails.application.secrets.disqus_shortname %>";
|
||||
Fablab.defaultHost = "<%= Rails.application.secrets.default_host %>";
|
||||
|
@ -20,6 +20,7 @@ FABLAB_WITHOUT_PLANS: 'false'
|
||||
FABLAB_WITHOUT_SPACES: 'true'
|
||||
FABLAB_WITHOUT_ONLINE_PAYMENT: 'false'
|
||||
FABLAB_WITHOUT_INVOICES: 'false'
|
||||
PHONE_REQUIRED: 'true'
|
||||
|
||||
SLOT_DURATION: '60'
|
||||
|
||||
|
@ -20,6 +20,7 @@ development:
|
||||
fablab_without_spaces: <%= ENV["FABLAB_WITHOUT_SPACES"] %>
|
||||
fablab_without_online_payments: <%= ENV["FABLAB_WITHOUT_ONLINE_PAYMENT"] %>
|
||||
fablab_without_invoices: <%= ENV["FABLAB_WITHOUT_INVOICES"] %>
|
||||
phone_required: <%= ENV["PHONE_REQUIRED"] %>
|
||||
slot_duration: <%= ENV["SLOT_DURATION"] %>
|
||||
default_host: <%= ENV["DEFAULT_HOST"] %>
|
||||
default_protocol: <%= ENV["DEFAULT_PROTOCOL"] %>
|
||||
@ -63,6 +64,7 @@ test:
|
||||
fablab_without_spaces: false
|
||||
fablab_without_online_payments: false
|
||||
fablab_without_invoices: false
|
||||
phone_required: true
|
||||
slot_duration: <%= ENV["SLOT_DURATION"] %>
|
||||
default_host: <%= ENV["DEFAULT_HOST"] %>
|
||||
default_protocol: <%= ENV["DEFAULT_PROTOCOL"] %>
|
||||
@ -106,6 +108,7 @@ staging:
|
||||
fablab_without_spaces: <%= ENV["FABLAB_WITHOUT_SPACES"] %>
|
||||
fablab_without_online_payments: <%= ENV["FABLAB_WITHOUT_ONLINE_PAYMENT"] %>
|
||||
fablab_without_invoices: <%= ENV["FABLAB_WITHOUT_INVOICES"] %>
|
||||
phone_required: <%= ENV["PHONE_REQUIRED"] %>
|
||||
slot_duration: <%= ENV["SLOT_DURATION"] %>
|
||||
default_host: <%= ENV["DEFAULT_HOST"] %>
|
||||
default_protocol: <%= ENV["DEFAULT_PROTOCOL"] %>
|
||||
@ -160,6 +163,7 @@ production:
|
||||
fablab_without_spaces: <%= ENV["FABLAB_WITHOUT_SPACES"] %>
|
||||
fablab_without_online_payments: <%= ENV["FABLAB_WITHOUT_ONLINE_PAYMENT"] %>
|
||||
fablab_without_invoices: <%= ENV["FABLAB_WITHOUT_INVOICES"] %>
|
||||
phone_required: <%= ENV["PHONE_REQUIRED"] %>
|
||||
slot_duration: <%= ENV["SLOT_DURATION"] %>
|
||||
default_host: <%= ENV["DEFAULT_HOST"] %>
|
||||
default_protocol: <%= ENV["DEFAULT_PROTOCOL"] %>
|
||||
|
@ -102,6 +102,11 @@ Valid stripe API keys are still required, even if you don't require online payme
|
||||
If set to 'true', the invoices will be disabled.
|
||||
This is useful if you have your own invoicing system and you want to prevent Fab-manager from generating and sending invoices to members.
|
||||
**Very important**: if you disable invoices, you still have to configure VAT in the interface to prevent errors in accounting and prices.
|
||||
<a name="PHONE_REQUIRED"></a>
|
||||
|
||||
PHONE_REQUIRED
|
||||
|
||||
If set to 'false' the phone number won't be required to register a new user on the software.
|
||||
<a name="SLOT_DURATION"></a>
|
||||
|
||||
SLOT_DURATION
|
||||
|
@ -13,6 +13,7 @@ FABLAB_WITHOUT_PLANS=false
|
||||
FABLAB_WITHOUT_SPACES=true
|
||||
FABLAB_WITHOUT_ONLINE_PAYMENT=true
|
||||
FABLAB_WITHOUT_INVOICES=false
|
||||
PHONE_REQUIRED=false
|
||||
|
||||
SLOT_DURATION=60
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user