diff --git a/Gemfile.lock b/Gemfile.lock index 7c9fd821a7899afb7289f296cee8b600ca4146da..1d0265d8fc1277cb5150d76a8e1de49099dbe081 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -80,8 +80,8 @@ GEM minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) angularjs-rails (1.8.0) annotate (3.2.0) activerecord (>= 3.2, < 8.0) @@ -89,8 +89,8 @@ GEM autoprefixer-rails (10.4.7.0) execjs (~> 2) aws-eventstream (1.2.0) - aws-partitions (1.613.0) - aws-sdk-core (3.131.5) + aws-partitions (1.621.0) + aws-sdk-core (3.135.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.525.0) aws-sigv4 (~> 1.1) @@ -134,7 +134,7 @@ GEM childprocess (4.1.0) cocoon (1.2.15) concurrent-ruby (1.1.10) - countries (5.1.1) + countries (5.1.2) sixarm_ruby_unaccent (~> 1.1) country_select (8.0.0) countries (~> 5.0) @@ -168,45 +168,31 @@ GEM encryptor (3.0.0) enum_help (0.0.19) activesupport (>= 3.0.0) - erubi (1.10.0) + erubi (1.11.0) ethon (0.15.0) ffi (>= 1.15.0) execjs (2.8.1) faceted_search (3.5.15) font-awesome-sass rails (>= 5.2.0) - faraday (1.10.0) - faraday-em_http (~> 1.0) - faraday-em_synchrony (~> 1.0) - faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0) - faraday-multipart (~> 1.0) - faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.0) - faraday-patron (~> 1.0) - faraday-rack (~> 1.0) - faraday-retry (~> 1.0) + faraday (2.5.2) + faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) faraday-cookie_jar (0.0.7) faraday (>= 0.8.0) http-cookie (~> 1.0.0) - faraday-em_http (1.0.0) - faraday-em_synchrony (1.0.0) faraday-encoding (0.0.5) faraday - faraday-excon (1.1.0) - faraday-http-cache (2.4.0) + faraday-follow_redirects (0.3.0) + faraday (>= 1, < 3) + faraday-gzip (0.1.0) + faraday (>= 1.0) + zlib (~> 2.1) + faraday-http-cache (2.4.1) faraday (>= 0.8) - faraday-httpclient (1.0.1) - faraday-multipart (1.0.4) - multipart-post (~> 2) - faraday-net_http (1.0.1) - faraday-net_http_persistent (1.2.0) - faraday-patron (1.0.0) - faraday-rack (1.0.0) - faraday-retry (1.0.3) - faraday_middleware (1.2.0) - faraday (~> 1.0) + faraday-net_http (3.0.0) + faraday-retry (2.0.0) + faraday (~> 2.0) fastimage (2.2.6) ffi (1.15.5) figaro (1.2.0) @@ -277,27 +263,28 @@ GEM mini_mime (>= 0.1.1) marcel (1.0.2) matrix (0.4.2) - metainspector (5.12.1) - addressable (~> 2.7) - faraday (>= 1.4, < 3.0) + metainspector (5.13.0) + addressable (~> 2.8) + faraday (~> 2.5) faraday-cookie_jar (~> 0.0) faraday-encoding (~> 0.0) - faraday-http-cache (~> 2.2) - faraday_middleware (~> 1.0) + faraday-follow_redirects (~> 0.3) + faraday-gzip (~> 0.1) + faraday-http-cache (~> 2.4) + faraday-retry (~> 2.0) fastimage (~> 2.2) nesty (~> 1.0) - nokogiri (~> 1.11) + nokogiri (~> 1.13) method_source (1.0.0) mime-types (3.4.1) mime-types-data (~> 3.2015) mime-types-data (3.2022.0105) mini_magick (4.11.0) mini_mime (1.1.2) - minitest (5.16.2) - msgpack (1.5.4) + minitest (5.16.3) + msgpack (1.5.6) multi_json (1.15.0) multi_xml (0.6.0) - multipart-post (2.2.3) mustermann (2.0.2) ruby2_keywords (~> 0.0.1) nesty (1.0.2) @@ -314,7 +301,7 @@ GEM multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - octokit (5.2.0) + octokit (5.3.0) faraday (>= 1, < 3) sawyer (~> 0.9) omniauth (2.1.0) @@ -328,10 +315,10 @@ GEM omniauth (~> 2.0) ruby-saml (~> 1.12) orm_adapter (0.5.0) - pg (1.4.2) + pg (1.4.3) popper_js (2.11.5) - public_suffix (4.0.7) - puma (5.6.4) + public_suffix (5.0.0) + puma (5.6.5) nio4r (~> 2.0) racc (1.6.0) rack (2.2.4) @@ -405,12 +392,12 @@ GEM sawyer (0.9.2) addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) - selenium-webdriver (4.3.0) + selenium-webdriver (4.4.0) childprocess (>= 0.5, < 5.0) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) - sib-api-v3-sdk (8.1.0) + sib-api-v3-sdk (9.0.0) addressable (~> 2.3, >= 2.3.0) json (~> 2.1, >= 2.1.0) typhoeus (~> 1.0, >= 1.0.1) @@ -466,7 +453,7 @@ GEM nokogiri (~> 1.6) rubyzip (>= 1.3.0) selenium-webdriver (~> 4.0) - webmock (3.17.1) + webmock (3.18.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -477,6 +464,7 @@ GEM xpath (3.2.0) nokogiri (~> 1.8) zeitwerk (2.6.0) + zlib (2.1.1) PLATFORMS arm64-darwin-21 @@ -548,4 +536,4 @@ RUBY VERSION ruby 2.7.6p219 BUNDLED WITH - 2.3.11 + 2.3.12 diff --git a/app/assets/stylesheets/extranet.sass b/app/assets/stylesheets/extranet.sass index 3a08f1af68e965ca9100b29bf83936c2bc5b8a0e..55f7e1025b411247dc6558838dc03e1660f39ba3 100644 --- a/app/assets/stylesheets/extranet.sass +++ b/app/assets/stylesheets/extranet.sass @@ -8,6 +8,7 @@ @import 'simple_form_password_with_hints' @import 'simple_form_bs5_file_input' @import 'gdpr/cookie_consent' +@import 'cropperjs/dist/cropper' // Default @import 'extranet/_default/base/*' diff --git a/app/assets/stylesheets/extranet/_default/base/_typography.sass b/app/assets/stylesheets/extranet/_default/base/_typography.sass index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d3ba1250a0653c92085d5977c92b04fac4515e7e 100644 --- a/app/assets/stylesheets/extranet/_default/base/_typography.sass +++ b/app/assets/stylesheets/extranet/_default/base/_typography.sass @@ -0,0 +1,2 @@ +h1 + font-weight: normal \ No newline at end of file diff --git a/app/controllers/extranet/account_controller.rb b/app/controllers/extranet/account_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..de458497330aadcfbbc1a04829406014cfa99883 --- /dev/null +++ b/app/controllers/extranet/account_controller.rb @@ -0,0 +1,42 @@ +class Extranet::AccountController < Extranet::ApplicationController + def show + # Superadmins don't have a person + @person = current_user.person + breadcrumb + end + + def edit + breadcrumb + add_breadcrumb t('extranet.account.edit') + end + + def update + manage_password + current_user.update user_params + redirect_to account_path, notice: t('extranet.account.updated') + end + + protected + + def manage_password + # to prevent cognitive complexity (the bottom block should be in an if condition where password present) + # Password not provided when user from sso + params[:user][:password] ||= '' + + if params[:user][:password].empty? + params[:user].delete(:password) + else + current_user.reset_password(params[:user][:password], params[:user][:password]) + end + end + + def user_params + params.require(:user) + .permit(:first_name, :last_name, :email, :mobile_phone, :language_id, :password, :picture, :picture_infos, :picture_delete) + end + + def breadcrumb + super + add_breadcrumb t('extranet.account.my'), account_path + end +end \ No newline at end of file diff --git a/app/views/extranet/account/edit.html.erb b/app/views/extranet/account/edit.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..25b2681db863441340122b34f868e3c7e7ef364b --- /dev/null +++ b/app/views/extranet/account/edit.html.erb @@ -0,0 +1,39 @@ +<% content_for :title, current_user %> + +<%= simple_form_for current_user, url: account_path do |f| %> + <%= f.error_notification %> + <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %> + + <div class="row"> + <div class="col-lg-6"> + <%= f.input :first_name %> + <%= f.input :last_name %> + <%= f.association :language, + include_blank: false, + label_method: lambda { |l| t("languages.#{l.iso_code.to_s}") } %> + <%= f.input :picture, + as: :single_deletable_file, + input_html: { accept: '.jpg,.jpeg,.png,.svg' }, + preview: 200, + resize: 1, + direct_upload: true %> + </div> + <div class="col-lg-6"> + <%= f.input :email %> + <%= f.input :mobile_phone %> + <%= f.input :password, + as: :password_with_hints, + hint: t('admin.password_hint'), + allow_password_uncloaking: true, + validators: { + length: Devise.password_length.first, + uppercase_char: true, + lowercase_char: true, + numeric_char: true, + special_char: Rails.application.config.allowed_special_chars + }, + input_html: { autocomplete: "new-password" } %> + </div> + </div> + <%= submit f %> +<% end %> \ No newline at end of file diff --git a/app/views/extranet/account/show.html.erb b/app/views/extranet/account/show.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..a0b28a37eb1969c9d549368db24f0d0a05f16faf --- /dev/null +++ b/app/views/extranet/account/show.html.erb @@ -0,0 +1,13 @@ +<% content_for :title, @person %> + +<%= render 'extranet/persons/header', person: @person unless @person.nil? %> + +<%= link_to t('extranet.account.edit'), edit_account_path, class: 'btn btn-primary' %> + +<div class="row"> + <div class="col-md-9"> + </div> + <div class="col-md-3"> + <%= render 'extranet/persons/details', person: @person unless @person.nil? %> + </div> +</div> \ No newline at end of file diff --git a/app/views/extranet/persons/_details.html.erb b/app/views/extranet/persons/_details.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..8d95d637e87c54baa0743fc3546581b9c2a7ca51 --- /dev/null +++ b/app/views/extranet/persons/_details.html.erb @@ -0,0 +1,46 @@ +<dl> + <% person.cohorts.each do |cohort| %> + <dt><%= cohort.program %></dt> + <dd><%= link_to cohort.academic_year, cohort %></dd> + <% end %> + <% if person.phone_mobile.present? %> + <dt><%= University::Person.human_attribute_name(:phone_mobile) %></dt> + <dd> + <a href="tel:<%= person.phone_mobile %>" target="_blank" rel="noreferrer"> + <%= person.phone_mobile %> + </a> + </dd> + <% end %> + <% if person.email.present? %> + <dt><%= University::Person.human_attribute_name(:email) %></dt> + <dd> + <a href="mailto:<%= person.email %>" target="_blank" rel="noreferrer"> + <%= person.email %> + </a> + </dd> + <% end %> + <% if person.url.present? %> + <dt><%= University::Person.human_attribute_name(:url) %></dt> + <dd> + <a href="<%= social_website_to_url person.url %>" target="_blank" rel="noreferrer"> + <%= social_website_to_s person.url %> + </a> + </dd> + <% end %> + <% if person.linkedin.present? %> + <dt><%= University::Person.human_attribute_name(:linkedin) %></dt> + <dd> + <a href="<%= social_linkedin_to_url person.linkedin %>" target="_blank" rel="noreferrer"> + <%= social_linkedin_to_s person.linkedin %> + </a> + </dd> + <% end %> + <% if person.twitter.present? %> + <dt><%= University::Person.human_attribute_name(:twitter) %></dt> + <dd> + <a href="<%= social_twitter_to_url person.twitter %>" target="_blank" rel="noreferrer"> + <%= social_twitter_to_s person.twitter %> + </a> + </dd> + <% end %> +</dl> \ No newline at end of file diff --git a/app/views/extranet/persons/_header.html.erb b/app/views/extranet/persons/_header.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..b0a32dd5861eb8a417a4ce0f794caef326b4e95e --- /dev/null +++ b/app/views/extranet/persons/_header.html.erb @@ -0,0 +1,14 @@ +<div class="row mb-5 top"> + <div class="col-md-9"> + <header> + <h1><%= person.first_name %> <b><%= person.last_name %></b></h1> + </header> + </div> + <div class="col-md-3"> + <% if person.picture.attached? %> + <%= kamifusen_tag person.picture, width: 400, class: 'img-fluid' %> + <% else %> + <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid' %> + <% end %> + </div> +</div> \ No newline at end of file diff --git a/app/views/extranet/persons/show.html.erb b/app/views/extranet/persons/show.html.erb index 7f3ac732a9dfdf4acc8a2d86c0132e53002f17c5..6ae31ae89d1e1640513d86222dc904b929b99e44 100644 --- a/app/views/extranet/persons/show.html.erb +++ b/app/views/extranet/persons/show.html.erb @@ -1,19 +1,6 @@ <% content_for :title, @person %> -<div class="row mb-5 top"> - <div class="col-md-9"> - <header> - <h1><%= @person.first_name %> <b><%= @person.last_name %></b></h1> - </header> - </div> - <div class="col-md-3"> - <% if @person.picture.attached? %> - <%= kamifusen_tag @person.picture, width: 400, class: 'img-fluid' %> - <% else %> - <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid' %> - <% end %> - </div> -</div> +<%= render 'extranet/persons/header', person: @person %> <div class="row"> <div class="col-md-9"> @@ -57,51 +44,6 @@ <% end %> </div> <div class="col-md-3"> - <dl> - <% @person.cohorts.each do |cohort| %> - <dt><%= cohort.program %></dt> - <dd><%= link_to cohort.academic_year, cohort %></dd> - <% end %> - <% if @person.phone_mobile.present? %> - <dt><%= University::Person.human_attribute_name(:phone_mobile) %></dt> - <dd> - <a href="tel:<%= @person.phone_mobile %>" target="_blank" rel="noreferrer"> - <%= @person.phone_mobile %> - </a> - </dd> - <% end %> - <% if @person.email.present? %> - <dt><%= University::Person.human_attribute_name(:email) %></dt> - <dd> - <a href="mailto:<%= @person.email %>" target="_blank" rel="noreferrer"> - <%= @person.email %> - </a> - </dd> - <% end %> - <% if @person.url.present? %> - <dt><%= University::Person.human_attribute_name(:url) %></dt> - <dd> - <a href="<%= social_website_to_url @person.url %>" target="_blank" rel="noreferrer"> - <%= social_website_to_s @person.url %> - </a> - </dd> - <% end %> - <% if @person.linkedin.present? %> - <dt><%= University::Person.human_attribute_name(:linkedin) %></dt> - <dd> - <a href="<%= social_linkedin_to_url @person.linkedin %>" target="_blank" rel="noreferrer"> - <%= social_linkedin_to_s @person.linkedin %> - </a> - </dd> - <% end %> - <% if @person.twitter.present? %> - <dt><%= University::Person.human_attribute_name(:twitter) %></dt> - <dd> - <a href="<%= social_twitter_to_url @person.twitter %>" target="_blank" rel="noreferrer"> - <%= social_twitter_to_s @person.twitter %> - </a> - </dd> - <% end %> - </dl> + <%= render 'extranet/persons/details', person: @person %> </div> </div> diff --git a/config/locales/en.yml b/config/locales/en.yml index 81d8721d041f8b765046598b0036baaf8552c619..1fc6eabd7c9d169ccfdd07526f22a76ae02e2d44 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -159,6 +159,12 @@ en: finished: Finished finished_with_errors: Finished with errors pending: Pending + extranet: + account: + my: My account + edit: Edit + updated: Updated + logout: Log out false: No featured_image: title: Image diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 50fb3b6871d3b6ce0bb66b5c6b686cbb5ac089d3..f4512be94a0f35af994e7123bce880290b867876 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -162,6 +162,12 @@ fr: finished: Traité finished_with_errors: Traité avec des erreurs pending: En cours de traitement + extranet: + account: + my: Mon compte + edit: Modifier + updated: Mise à jour effectuée + logout: Déconnexion false: Non featured_image: title: Image diff --git a/config/navigation.rb b/config/navigation.rb index cb9701bc517107013309b64883701c420ee87d3b..098c9bb14e1d89a9ad7ab1bd57a2361a30eb31b3 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -16,5 +16,16 @@ SimpleNavigation::Configuration.run do |navigation| primary.item :organizations, University::Organization.model_name.human(count: 2), university_organizations_path + primary.item :account, + current_user, + nil do |secondary| + secondary.item :edit, + t('extranet.account.my'), + account_path + secondary.item :logout, + t('extranet.account.logout'), + destroy_user_session_path, + method: :delete + end end end diff --git a/config/routes/extranet.rb b/config/routes/extranet.rb index dfb9725e828f9a4dad77e525e094e19232c2a6bd..6870b88c5115cfe69cdb37b37634771fee245d39 100644 --- a/config/routes/extranet.rb +++ b/config/routes/extranet.rb @@ -1,9 +1,12 @@ get 'cohorts' => 'extranet/cohorts#index', as: :education_cohorts get 'cohorts/:id' => 'extranet/cohorts#show', as: :education_cohort get 'organizations' => 'extranet/organizations#index', as: :university_organizations -get 'organizations/:id' => 'extranet/organizations#show', as: :university_organization +get 'organizations/:id' => 'extranet/organizations#show', as: :university_organization get 'persons' => 'extranet/persons#index', as: :university_persons get 'persons/:id' => 'extranet/persons#show', as: :university_person get 'years' => 'extranet/academic_years#index', as: :education_academic_years get 'years/:id' => 'extranet/academic_years#show', as: :education_academic_year +get 'account' => 'extranet/account#show', as: :account +get 'account/edit' => 'extranet/account#edit', as: :edit_account +patch 'account' => 'extranet/account#update' root to: 'extranet/home#index'