From 7099f1f317d2584eb2c31bce32779206d8ba185a Mon Sep 17 00:00:00 2001 From: Sylvain Date: Tue, 23 Mar 2021 11:49:05 +0100 Subject: [PATCH] address required - Ability to set the address as a mandatory field - The address is new requested when creating an account - The profile completion page is less fuzzy for people landing on it without enabled SSO --- CHANGELOG.md | 3 +++ .../api/auth_providers_controller.rb | 1 + app/controllers/application_controller.rb | 3 ++- .../javascript/controllers/admin/members.js | 27 ++++++++++++------- .../src/javascript/controllers/members.js | 9 ++++--- .../src/javascript/controllers/profile.js | 8 ++++++ app/frontend/src/javascript/router.js | 10 +++---- .../templates/admin/settings/general.html | 2 +- app/frontend/templates/profile/complete.html | 16 +++++------ .../templates/shared/_member_form.html | 5 ++-- .../templates/shared/signupModal.html | 18 +++++++++++++ app/models/auth_provider.rb | 5 ++++ .../_auth_provider.json.jbuilder | 4 ++- .../api/auth_providers/active.json.jbuilder | 5 ++++ config/locales/app.admin.en.yml | 2 +- config/locales/app.admin.fr.yml | 3 ++- config/locales/app.public.en.yml | 2 ++ config/locales/app.public.fr.yml | 2 ++ lib/tasks/fablab/auth.rake | 2 +- 19 files changed, 94 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e5dab41e..ee6ab44c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Next release - Ability to disable the trainings module +- Ability to set the address as a mandatory field +- The address is new requested when creating an account +- The profile completion page is less fuzzy for people landing on it without enabled SSO - Prevent showing error message when testing for old versions during upgrade - In the email notification, sent to admins on account creation, show the group of the user - More explanations in the setup script diff --git a/app/controllers/api/auth_providers_controller.rb b/app/controllers/api/auth_providers_controller.rb index 1efd31c44..6a4b5bea0 100644 --- a/app/controllers/api/auth_providers_controller.rb +++ b/app/controllers/api/auth_providers_controller.rb @@ -49,6 +49,7 @@ class API::AuthProvidersController < API::ApiController def active authorize AuthProvider @provider = AuthProvider.active + @previous = AuthProvider.previous end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 181777e43..10b7c224b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -41,7 +41,8 @@ class ApplicationController < ActionController::Base { profile_attributes: %i[phone last_name first_name interest software_mastered], invoicing_profile_attributes: [ - organization_attributes: [:name, address_attributes: [:address]] + organization_attributes: [:name, address_attributes: [:address]], + address_attributes: [:address] ], statistic_profile_attributes: %i[gender birthday] }, diff --git a/app/frontend/src/javascript/controllers/admin/members.js b/app/frontend/src/javascript/controllers/admin/members.js index 505076714..ad5e718db 100644 --- a/app/frontend/src/javascript/controllers/admin/members.js +++ b/app/frontend/src/javascript/controllers/admin/members.js @@ -650,8 +650,8 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce', /** * Controller used in the member edition page */ -Application.Controllers.controller('EditMemberController', ['$scope', '$state', '$stateParams', 'Member', 'Training', 'dialogs', 'growl', 'Group', 'Subscription', 'CSRF', 'memberPromise', 'tagsPromise', '$uibModal', 'Plan', '$filter', '_t', 'walletPromise', 'transactionsPromise', 'activeProviderPromise', 'Wallet', 'phoneRequiredPromise', - function ($scope, $state, $stateParams, Member, Training, dialogs, growl, Group, Subscription, CSRF, memberPromise, tagsPromise, $uibModal, Plan, $filter, _t, walletPromise, transactionsPromise, activeProviderPromise, Wallet, phoneRequiredPromise) { +Application.Controllers.controller('EditMemberController', ['$scope', '$state', '$stateParams', 'Member', 'Training', 'dialogs', 'growl', 'Group', 'Subscription', 'CSRF', 'memberPromise', 'tagsPromise', '$uibModal', 'Plan', '$filter', '_t', 'walletPromise', 'transactionsPromise', 'activeProviderPromise', 'Wallet', 'settingsPromise', + function ($scope, $state, $stateParams, Member, Training, dialogs, growl, Group, Subscription, CSRF, memberPromise, tagsPromise, $uibModal, Plan, $filter, _t, walletPromise, transactionsPromise, activeProviderPromise, Wallet, settingsPromise) { /* PUBLIC SCOPE */ // API URL where the form will be posted @@ -670,7 +670,10 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state', $scope.password = { change: false }; // is the phone number required in _member_form? - $scope.phoneRequired = (phoneRequiredPromise.setting.value === 'true'); + $scope.phoneRequired = (settingsPromise.phone_required === 'true'); + + // is the address required in _member_form? + $scope.addressRequired = (settingsPromise.address_required === 'true'); // the user subscription if (($scope.user.subscribed_plan != null) && ($scope.user.subscription != null)) { @@ -990,8 +993,8 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state', /** * Controller used in the member's creation page (admin view) */ -Application.Controllers.controller('NewMemberController', ['$scope', '$state', '$stateParams', 'Member', 'Training', 'Group', 'CSRF', 'phoneRequiredPromise', - function ($scope, $state, $stateParams, Member, Training, Group, CSRF, phoneRequiredPromise) { +Application.Controllers.controller('NewMemberController', ['$scope', '$state', '$stateParams', 'Member', 'Training', 'Group', 'CSRF', 'settingsPromise', + function ($scope, $state, $stateParams, Member, Training, Group, CSRF, settingsPromise) { CSRF.setMetaTags(); /* PUBLIC SCOPE */ @@ -1006,7 +1009,10 @@ Application.Controllers.controller('NewMemberController', ['$scope', '$state', ' $scope.password = { change: false }; // is the phone number required in _member_form? - $scope.phoneRequired = (phoneRequiredPromise.setting.value === 'true'); + $scope.phoneRequired = (settingsPromise.phone_required === 'true'); + + // is the address required to sign-up? + $scope.addressRequired = (settingsPromise.address_required === 'true'); // Default member's profile parameters $scope.user = { @@ -1109,8 +1115,8 @@ Application.Controllers.controller('ImportMembersResultController', ['$scope', ' /** * Controller used in the admin creation page (admin view) */ -Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'Admin', 'growl', '_t', 'phoneRequiredPromise', - function ($state, $scope, Admin, growl, _t, phoneRequiredPromise) { +Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'Admin', 'growl', '_t', 'settingsPromise', + function ($state, $scope, Admin, growl, _t, settingsPromise) { // default admin profile let getGender; $scope.admin = { @@ -1131,7 +1137,10 @@ Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'A }; // is the phone number required in _admin_form? - $scope.phoneRequired = (phoneRequiredPromise.setting.value === 'true'); + $scope.phoneRequired = (settingsPromise.phone_required === 'true'); + + // is the address required in _admin_form? + $scope.addressRequired = (settingsPromise.address_required === 'true'); /** * Shows the birthday datepicker diff --git a/app/frontend/src/javascript/controllers/members.js b/app/frontend/src/javascript/controllers/members.js index 2b23102ee..05c233fe0 100644 --- a/app/frontend/src/javascript/controllers/members.js +++ b/app/frontend/src/javascript/controllers/members.js @@ -72,8 +72,8 @@ Application.Controllers.controller('MembersController', ['$scope', 'Member', 'me /** * Controller used when editing the current user's profile (in dashboard) */ -Application.Controllers.controller('EditProfileController', ['$scope', '$rootScope', '$state', '$window', '$sce', '$cookies', '$injector', 'Member', 'Auth', 'Session', 'activeProviderPromise', 'phoneRequiredPromise', 'growl', 'dialogs', 'CSRF', 'memberPromise', 'groups', '_t', - function ($scope, $rootScope, $state, $window, $sce, $cookies, $injector, Member, Auth, Session, activeProviderPromise, phoneRequiredPromise, growl, dialogs, CSRF, memberPromise, groups, _t) { +Application.Controllers.controller('EditProfileController', ['$scope', '$rootScope', '$state', '$window', '$sce', '$cookies', '$injector', 'Member', 'Auth', 'Session', 'activeProviderPromise', 'settingsPromise', 'growl', 'dialogs', 'CSRF', 'memberPromise', 'groups', '_t', + function ($scope, $rootScope, $state, $window, $sce, $cookies, $injector, Member, Auth, Session, activeProviderPromise, settingsPromise, growl, dialogs, CSRF, memberPromise, groups, _t) { /* PUBLIC SCOPE */ // API URL where the form will be posted @@ -111,7 +111,10 @@ Application.Controllers.controller('EditProfileController', ['$scope', '$rootSco $scope.password = { change: false }; // is the phone number required in _member_form? - $scope.phoneRequired = (phoneRequiredPromise.setting.value === 'true'); + $scope.phoneRequired = (settingsPromise.phone_required === 'true'); + + // is the address required in _member_form? + $scope.addressRequired = (settingsPromise.address_required === 'true'); // Angular-Bootstrap datepicker configuration for birthday $scope.datePicker = { diff --git a/app/frontend/src/javascript/controllers/profile.js b/app/frontend/src/javascript/controllers/profile.js index cba08dba6..5056c8a1a 100644 --- a/app/frontend/src/javascript/controllers/profile.js +++ b/app/frontend/src/javascript/controllers/profile.js @@ -203,6 +203,14 @@ Application.Controllers.controller('CompleteProfileController', ['$scope', '$roo }); }; + /** + * Hide the new account messages. + * If hidden, the page will be used only to complete the current user's profile. + */ + $scope.hideNewAccountConfirmation = function () { + return !$scope.activeProvider.previous_provider || $scope.activeProvider.previous_provider.id === $scope.activeProvider.id; + }; + /* PRIVATE SCOPE */ /** diff --git a/app/frontend/src/javascript/router.js b/app/frontend/src/javascript/router.js index b1f5540ba..a0e85c3a1 100644 --- a/app/frontend/src/javascript/router.js +++ b/app/frontend/src/javascript/router.js @@ -167,7 +167,7 @@ angular.module('application.router', ['ui.router']) resolve: { groups: ['Group', function (Group) { return Group.query().$promise; }], activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise; }], - phoneRequiredPromise: ['Setting', function (Setting) { return Setting.get({ name: 'phone_required' }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }] } }) .state('app.logged.dashboard.projects', { @@ -915,7 +915,7 @@ angular.module('application.router', ['ui.router']) } }, resolve: { - phoneRequiredPromise: ['Setting', function (Setting) { return Setting.get({ name: 'phone_required' }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }] } }) .state('app.admin.members_import', { @@ -956,7 +956,7 @@ angular.module('application.router', ['ui.router']) walletPromise: ['Wallet', '$stateParams', function (Wallet, $stateParams) { return Wallet.getWalletByUser({ user_id: $stateParams.id }).$promise; }], transactionsPromise: ['Wallet', 'walletPromise', function (Wallet, walletPromise) { return Wallet.transactions({ id: walletPromise.id }).$promise; }], tagsPromise: ['Tag', function (Tag) { return Tag.query().$promise; }], - phoneRequiredPromise: ['Setting', function (Setting) { return Setting.get({ name: 'phone_required' }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }] } }) .state('app.admin.admins_new', { @@ -968,7 +968,7 @@ angular.module('application.router', ['ui.router']) } }, resolve: { - phoneRequiredPromise: ['Setting', function (Setting) { return Setting.get({ name: 'phone_required' }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }] } }) .state('app.admin.managers_new', { @@ -1061,7 +1061,7 @@ angular.module('application.router', ['ui.router']) "'booking_cancel_delay', 'main_color', 'secondary_color', 'spaces_module', 'twitter_analytics', " + "'fablab_name', 'name_genre', 'reminder_enable', 'plans_module', 'confirmation_required', " + "'reminder_delay', 'visibility_yearly', 'visibility_others', 'wallet_module', 'trainings_module', " + - "'display_name_enable', 'machines_sort_by', 'fab_analytics', 'statistics_module', " + + "'display_name_enable', 'machines_sort_by', 'fab_analytics', 'statistics_module', 'address_required', " + "'link_name', 'home_content', 'home_css', 'phone_required', 'upcoming_events_shown']" }).$promise; }], diff --git a/app/frontend/templates/admin/settings/general.html b/app/frontend/templates/admin/settings/general.html index 454672502..6948ffaae 100644 --- a/app/frontend/templates/admin/settings/general.html +++ b/app/frontend/templates/admin/settings/general.html @@ -427,7 +427,7 @@

{{ 'app.admin.settings.address' }}

- {{ 'app.admin.settings.address_required_info' }} + {{ 'app.admin.settings.address_required_info_html' }}

-
+
@@ -34,19 +34,19 @@
-
-

{{ 'app.logged.profile_completion.new_on_this_platform' }}

+

{{ 'app.logged.profile_completion.new_on_this_platform' }}

{{ 'app.logged.profile_completion.please_fill_the_following_form'}}.

{{ 'app.logged.profile_completion.some_data_may_have_already_been_provided_by_provider_and_cannot_be_modified' | translate:{NAME:activeProvider.name} }}.
{{ 'app.logged.profile_completion.then_click_on_' | translate }} {{ 'app.shared.buttons.confirm_changes' }} {{ 'app.logged.profile_completion._to_start_using_the_application' | translate }}.

@@ -145,14 +145,14 @@
-
diff --git a/app/frontend/templates/shared/_member_form.html b/app/frontend/templates/shared/_member_form.html index f277940d4..fbf336c10 100644 --- a/app/frontend/templates/shared/_member_form.html +++ b/app/frontend/templates/shared/_member_form.html @@ -224,7 +224,7 @@
- + @@ -234,7 +234,8 @@ class="form-control" id="user_address" ng-disabled="preventField['profile.address'] && user.invoicing_profile.address.address && !userForm['user[invoicing_profile_attributes][address_attributes][address]'].$dirty" - placeholder="{{ 'app.shared.user.address' | translate }}"/> + placeholder="{{ 'app.shared.user.address' | translate }}" + ng-required="addressRequired"/>
diff --git a/app/frontend/templates/shared/signupModal.html b/app/frontend/templates/shared/signupModal.html index b9f2639a8..a91c05f7d 100644 --- a/app/frontend/templates/shared/signupModal.html +++ b/app/frontend/templates/shared/signupModal.html @@ -213,6 +213,24 @@
+
+
+
+ + +
+ + + + {{ 'app.public.common.address_is_required' }} +
+
+
Please note that, depending on your country, the regulations may requires addresses for the invoices to be valid." address_is_required: "Address is required" captcha: "Captcha" captcha_info_html: "You can setup a protection against robots, to prevent them creating members accounts. This protection is using Google reCAPTCHA. Sign up for an API key pair to start using the captcha." diff --git a/config/locales/app.admin.fr.yml b/config/locales/app.admin.fr.yml index a98083288..d1110ac75 100644 --- a/config/locales/app.admin.fr.yml +++ b/config/locales/app.admin.fr.yml @@ -1073,6 +1073,7 @@ fr: machines_sort_by: "l'ordre d'affichage des machines" fab_analytics: "Fab Analytics" phone_required: "téléphone requis" + address_required: "adresse requise" tracking_id: "l'ID de suivi" facebook_app_id: "l'App ID Facebook" twitter_analytics: "compte Twitter analytics" @@ -1110,7 +1111,7 @@ fr: phone_is_required: "Téléphone requis" phone_required_info: "Vous pouvez définir si le numéro de téléphone doit être requis, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager." address: "Adresse" - address_required_info: "Vous pouvez définir si l'adresse doit être requise, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager. Veuillez noter que, selon votre pays, la réglementation peut exiger des adresses pour que les factures soient valides." + address_required_info_html: "Vous pouvez définir si l'adresse doit être requise, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager.
Veuillez noter que, selon votre pays, la réglementation peut exiger des adresses pour que les factures soient valides." address_is_required: "Adresse requise" captcha: "Captcha" captcha_info_html: "Vous pouvez mettre en place une protection contre les robots, pour les empêcher de créer des comptes membre. Cette protection utilise Google reCAPTCHA. Inscrivez vous pour obtenir une paire de clefs d'API afin d'utiliser le captcha." diff --git a/config/locales/app.public.en.yml b/config/locales/app.public.en.yml index ff55a8efd..f3c8b1244 100644 --- a/config/locales/app.public.en.yml +++ b/config/locales/app.public.en.yml @@ -84,6 +84,8 @@ en: birth_date_is_required: "Birth date is required." phone_number: "Phone number" phone_number_is_required: "Phone number is required." + address: "Address" + address_is_required: "Address is required" i_authorize_Fablab_users_registered_on_the_site_to_contact_me: "I authorize FabLab users, registered on the site, to contact me" i_accept_to_receive_information_from_the_fablab: "I accept to receive information from the FabLab" i_ve_read_and_i_accept_: "I've read and I accept" diff --git a/config/locales/app.public.fr.yml b/config/locales/app.public.fr.yml index ab65878a2..0a6e258d9 100644 --- a/config/locales/app.public.fr.yml +++ b/config/locales/app.public.fr.yml @@ -84,6 +84,8 @@ fr: birth_date_is_required: "La date de naissance est requise." phone_number: "Numéro de téléphone" phone_number_is_required: "Le numéro de téléphone est requis." + address: "Adresse" + address_is_required: "L'adresse est requise" i_authorize_Fablab_users_registered_on_the_site_to_contact_me: "J'autorise les utilisateurs du Fab Lab inscrits sur le site à me contacter" i_accept_to_receive_information_from_the_fablab: "J'accepte de recevoir des informations du Fab Lab" i_ve_read_and_i_accept_: "J'ai lu et j'accepte" diff --git a/lib/tasks/fablab/auth.rake b/lib/tasks/fablab/auth.rake index a555900ad..7d2c1d033 100644 --- a/lib/tasks/fablab/auth.rake +++ b/lib/tasks/fablab/auth.rake @@ -16,7 +16,7 @@ namespace :fablab do raise "FATAL ERROR: the provider '#{args.provider}' is already enabled" if AuthProvider.active.name == args.provider # disable previous provider - prev_prev = AuthProvider.find_by(status: 'previous') + prev_prev = AuthProvider.previous prev_prev&.update_attribute(:status, 'pending') AuthProvider.active.update_attribute(:status, 'previous')