diff --git a/app/assets/javascripts/admin/appstack.js b/app/assets/javascripts/admin/appstack.js index aa96e4785e2122a1d5a8f8f4f5c96192ec2041f6..288469caaf16052c44adc410d92efad1a25c718e 100644 --- a/app/assets/javascripts/admin/appstack.js +++ b/app/assets/javascripts/admin/appstack.js @@ -12,6 +12,7 @@ //= require summernote/summernote-bs5 //= require slug/slug //= require cocoon +//= require codemirror/lib/codemirror //= require_self //= require_tree ./commons //= require_tree ../application/plugins diff --git a/app/assets/javascripts/admin/plugins/codemirror.js b/app/assets/javascripts/admin/plugins/codemirror.js new file mode 100644 index 0000000000000000000000000000000000000000..553e9afd748b24c9bf3dee73f9bd49c39d0b5d11 --- /dev/null +++ b/app/assets/javascripts/admin/plugins/codemirror.js @@ -0,0 +1,53 @@ +//= require codemirror/mode/xml/xml +//= require codemirror/mode/javascript/javascript +//= require codemirror/mode/css/css +//= require codemirror/mode/htmlmixed/htmlmixed +//= require codemirror/mode/sass/sass + +/*global CodeMirror */ + +// Add [data-provider="codemirror"] to textarea. +// You need to set [data-codemirror-mode="<language>"] to set the language. +// You can use set [data-codemirror-indentation="n"] to set the indentation level (2 by default). +window.codemirrorManager = { + init: function () { + 'use strict'; + var i; + this.textareas = document.querySelectorAll('textarea[data-provider="codemirror"]'); + this.instances = []; + for (i = 0; i < this.textareas.length; i += 1) { + this.instances.push(this.createInstance(this.textareas[i])); + } + }, + + createInstance: function (textarea) { + 'use strict'; + var mode = textarea.getAttribute('data-codemirror-mode'), + indentationLevel = window.parseInt(textarea.getAttribute('data-codemirror-indentation')); + + if (isNaN(indentationLevel)) { + indentationLevel = 2; + } + + return CodeMirror.fromTextArea(textarea, { + lineNumbers: true, + matchBrackets: true, + styleActiveLine: true, + indentUnit: indentationLevel, + viewportMargin: Infinity, + mode: mode + }); + }, + + invoke: function () { + 'use strict'; + return { + init: this.init.bind(this) + }; + } +}.invoke(); + +window.addEventListener('DOMContentLoaded', function () { + 'use strict'; + window.codemirrorManager.init(); +}); diff --git a/app/assets/javascripts/admin/pure.js b/app/assets/javascripts/admin/pure.js index ce84c279a86652825ff124a99876d8cf2f5339c1..94017fb5f5845850521b0e158949325b6794e6f7 100644 --- a/app/assets/javascripts/admin/pure.js +++ b/app/assets/javascripts/admin/pure.js @@ -13,6 +13,7 @@ //= require summernote/summernote-bs5 //= require slug/slug //= require cocoon +//= require codemirror/lib/codemirror //= require_self //= require_tree ./commons //= require_tree ../application/plugins diff --git a/app/assets/javascripts/extranet/experiences.js b/app/assets/javascripts/extranet/experiences.js index f00ced3d8d9560c7d5f1953a057c253fd798be18..4246230c05e4b2d28eb7f648021262a9c52dba65 100644 --- a/app/assets/javascripts/extranet/experiences.js +++ b/app/assets/javascripts/extranet/experiences.js @@ -1,18 +1,42 @@ /*global $ */ $(function () { 'use strict'; - var setAutocompleteTargetValue = function (targetId, value) { + var setAutocompleteTargetValue, + setAutocompleteNothingFound; + + setAutocompleteTargetValue = function (targetId, value) { var targetInput = document.querySelector(targetId); if (targetInput) { targetInput.value = value; } }; + setAutocompleteNothingFound = function (target, search) { + var defaultText, + text; + if (target) { + defaultText = target.dataset.defaultText; + text = defaultText.replaceAll('CHANGEME', search); + target.innerHTML = text; + target.classList.remove('d-none'); + } + }; + $('input.autocomplete') .on('input', function ($event) { setAutocompleteTargetValue($event.target.dataset.autocompleteTarget, ''); }) .on('railsAutocomplete.select', function ($event, data) { + var noResultTarget = document.querySelector($event.target.dataset.autocompleteNoResultTarget); setAutocompleteTargetValue($event.target.dataset.autocompleteTarget, data.item.id); + noResultTarget.classList.add('d-none'); + }) + .on('railsAutocomplete.source', function ($event, data) { + var noResultTarget = document.querySelector($event.target.dataset.autocompleteNoResultTarget); + if (data.length === 0) { + setAutocompleteNothingFound(noResultTarget, $event.target.value); + } else { + noResultTarget.classList.add('d-none'); + } }); }); diff --git a/app/assets/stylesheets/admin/appstack.sass b/app/assets/stylesheets/admin/appstack.sass index 06e674993f421ad82117422b524ea86c91d90846..3413526ba440914d25ccfa8aea3f2e44d45ddf3e 100644 --- a/app/assets/stylesheets/admin/appstack.sass +++ b/app/assets/stylesheets/admin/appstack.sass @@ -7,6 +7,7 @@ @import 'summernote-bs5' @import 'cropperjs/dist/cropper' @import 'gdpr/cookie_consent' +@import 'codemirror/lib/codemirror' @import '../commons/*' @import 'commons/*' @import 'appstack/*' diff --git a/app/assets/stylesheets/admin/commons/codemirror.sass b/app/assets/stylesheets/admin/commons/codemirror.sass new file mode 100644 index 0000000000000000000000000000000000000000..f7c3a66762077a977db4ae333af3814473903be8 --- /dev/null +++ b/app/assets/stylesheets/admin/commons/codemirror.sass @@ -0,0 +1,2 @@ +.CodeMirror + border: 1px solid #CED4DA \ No newline at end of file diff --git a/app/assets/stylesheets/admin/pure.sass b/app/assets/stylesheets/admin/pure.sass index a769401d2472d51dab00ff4d314da975acb0c262..3a2248c6d08bd76b573ece1fce347666a5d0c63a 100644 --- a/app/assets/stylesheets/admin/pure.sass +++ b/app/assets/stylesheets/admin/pure.sass @@ -10,6 +10,7 @@ @import 'summernote-bs5' @import 'cropperjs/dist/cropper' @import 'gdpr/cookie_consent' +@import 'codemirror/lib/codemirror' @import '../commons/*' @import 'commons/*' @import 'pure/buttons' diff --git a/app/assets/stylesheets/extranet/layout/_header.sass b/app/assets/stylesheets/extranet/layout/_header.sass index 444cef53578dbad447ee1a70efb6a7dea04b00d2..0056fb05b3145cd6710ecc859bcbffd47197bd64 100644 --- a/app/assets/stylesheets/extranet/layout/_header.sass +++ b/app/assets/stylesheets/extranet/layout/_header.sass @@ -9,3 +9,7 @@ header, text-align: right margin-top: -60px margin-bottom: 0 + &__title + @extend h1 + p + margin-bottom: 0 \ No newline at end of file diff --git a/app/assets/stylesheets/extranet/pages/_experiences.sass b/app/assets/stylesheets/extranet/pages/_experiences.sass index 39dbc8668dedc2b9523a4529269fb524698266e4..efbd0e9f1e2ac2d8e276af2778eeab2d0b9b8366 100644 --- a/app/assets/stylesheets/extranet/pages/_experiences.sass +++ b/app/assets/stylesheets/extranet/pages/_experiences.sass @@ -1,2 +1,5 @@ -.experience__organization__logo - height: 100% \ No newline at end of file +.experience + line-height: px2rem(24) + position: relative + &__organization__logo + height: 100% \ No newline at end of file diff --git a/app/controllers/extranet/alumni/organizations_controller.rb b/app/controllers/extranet/alumni/organizations_controller.rb index 2d75beb4ba2fc320e5012540cdada5a70a43d1d0..69c516df49146c5fd211f6b4aee349aaa51eccad 100644 --- a/app/controllers/extranet/alumni/organizations_controller.rb +++ b/app/controllers/extranet/alumni/organizations_controller.rb @@ -12,13 +12,6 @@ class Extranet::Alumni::OrganizationsController < Extranet::Alumni::ApplicationC breadcrumb end - def search - @term = params[:term].to_s - @organizations = current_university.organizations - .search_by_siren_or_name(@term) - .ordered - end - def show @organization = about.university_person_alumni_organizations.find(params[:id]) breadcrumb diff --git a/app/controllers/extranet/application_controller.rb b/app/controllers/extranet/application_controller.rb index a4a6731228372351ae07c62c8be95ce2d4a0ef9e..e0b98e084b3920e685900ad3c1860dfe81515f22 100644 --- a/app/controllers/extranet/application_controller.rb +++ b/app/controllers/extranet/application_controller.rb @@ -19,6 +19,23 @@ class Extranet::ApplicationController < ApplicationController end def authorize_extranet_access! - raise CanCan::AccessDenied if current_user.visitor? && about.alumni.find_by(id: current_user.person&.id).nil? + raise CanCan::AccessDenied unless user_is_authorized? end + + def user_is_authorized? + user_is_more_than_visitor || user_is_alumnus || user_is_contact + end + + def user_is_more_than_visitor + !current_user.visitor? + end + + def user_is_alumnus + about.alumni.find_by(id: current_user.person&.id).present? + end + + def user_is_contact + current_extranet.connected_persons.find_by(id: current_user.person&.id).present? + end + end diff --git a/app/controllers/extranet/contacts/organizations_controller.rb b/app/controllers/extranet/contacts/organizations_controller.rb index f2cbefc1a568633f17e571d9a225690f1f348857..b58426e960e1abb83684c8e795897fa8a2a75f63 100644 --- a/app/controllers/extranet/contacts/organizations_controller.rb +++ b/app/controllers/extranet/contacts/organizations_controller.rb @@ -10,6 +10,7 @@ class Extranet::Contacts::OrganizationsController < Extranet::Contacts::Applicat def show @organization = current_extranet.connected_organizations.find(params[:id]) + @current_experiences = @organization.experiences.includes(:person).current.ordered breadcrumb end diff --git a/app/controllers/extranet/contacts/persons_controller.rb b/app/controllers/extranet/contacts/persons_controller.rb index 6ef8e86c3ade4f8339fc7b488138b6bad8e64d74..5d6b40885d51e771d254fc9445e123e1287b38a0 100644 --- a/app/controllers/extranet/contacts/persons_controller.rb +++ b/app/controllers/extranet/contacts/persons_controller.rb @@ -10,6 +10,7 @@ class Extranet::Contacts::PersonsController < Extranet::Contacts::ApplicationCon def show @person = current_extranet.connected_persons.find(params[:id]) + @current_experiences = @person.experiences.includes(:organization).current.ordered breadcrumb end diff --git a/app/controllers/extranet/experiences_controller.rb b/app/controllers/extranet/experiences_controller.rb index 2697cc7f87a314a9158035bb8121ac72d5d29b5c..9a297799d554f70d46251856421fd427ed409294 100644 --- a/app/controllers/extranet/experiences_controller.rb +++ b/app/controllers/extranet/experiences_controller.rb @@ -1,11 +1,11 @@ class Extranet::ExperiencesController < Extranet::ApplicationController + before_action :load_experience, only: [:edit, :update, :destroy] def new @experience = current_user.experiences.new breadcrumb end def edit - @experience = current_user.experiences.find(params[:id]) breadcrumb end @@ -13,7 +13,8 @@ class Extranet::ExperiencesController < Extranet::ApplicationController @experience = current_user.experiences.new(experience_params) @experience.university = current_university if @experience.save - redirect_to account_path, notice: 'Ok' + redirect_to account_path, + notice: t('admin.successfully_created_html', model: @experience.organization.to_s) else breadcrumb render :new @@ -21,17 +22,27 @@ class Extranet::ExperiencesController < Extranet::ApplicationController end def update - @experience = current_user.experiences.find(params[:id]) if @experience.update experience_params - redirect_to account_path, notice: 'Ok' + redirect_to account_path, + notice: t('admin.successfully_updated_html', model: @experience.organization.to_s) else breadcrumb render :edit end end + def destroy + @experience.destroy + redirect_to account_path, + notice: t('admin.successfully_destroyed_html', model: @experience.organization.to_s) + end + protected + def load_experience + @experience = current_user.experiences.find_by!(id: params[:id]) + end + def experience_params params.require(:university_person_experience) .permit(:description, :from_year, :to_year, :organization_id, :organization_name) @@ -42,4 +53,4 @@ class Extranet::ExperiencesController < Extranet::ApplicationController add_breadcrumb t('extranet.account.my'), account_path add_breadcrumb @experience end -end \ No newline at end of file +end diff --git a/app/controllers/extranet/organizations_controller.rb b/app/controllers/extranet/organizations_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..af318f25a12e5deabde835ae1e8818b5be56f243 --- /dev/null +++ b/app/controllers/extranet/organizations_controller.rb @@ -0,0 +1,74 @@ +class Extranet::OrganizationsController < Extranet::ApplicationController + before_action :load_organization, only: [:show, :edit, :update] + + def search + @term = params[:term].to_s + @organizations = current_university.organizations + .search_by_siren_or_name(@term) + .ordered + end + + def show + breadcrumb + end + + def new + @organization = current_university.organizations.new + @organization.name = params[:name] if params.has_key?(:name) + breadcrumb + add_breadcrumb t('create') + end + + def create + @organization = current_university.organizations.new(organization_params) + if @organization.save + redirect_to organization_path(@organization), + notice: t('admin.successfully_created_html', model: @organization.to_s) + else + breadcrumb + add_breadcrumb t('create') + render :new, status: :unprocessable_entity + end + end + + def edit + breadcrumb + add_breadcrumb t('edit') + end + + def update + if @organization.update(organization_params) + redirect_to organization_path(@organization), + notice: t('admin.successfully_updated_html', model: @organization.to_s) + else + breadcrumb + add_breadcrumb t('edit') + render :new, status: :unprocessable_entity + end + end + + private + + def breadcrumb + super + add_breadcrumb University::Organization.model_name.human(count: 2) + add_breadcrumb @organization, organization_path(@organization) if @organization.persisted? + end + + def load_organization + # this is an "experience" organization so it can be not connected to the extranet + @organization = current_university.organizations.find_by!(id: params[:id]) + end + + def organization_params + params.require(:university_organization) + .permit( + :name, :long_name, :summary, :siren, :kind, + :address, :address_name, :address_additional, :zipcode, :city, :country, :text, + :url, :phone, :email, :linkedin, :twitter, :mastodon, + :logo, :logo_delete, :logo_infos, + :logo_on_dark_background, :logo_on_dark_background_delete, :logo_on_dark_background_infos, + ) + end + +end diff --git a/app/controllers/extranet/pages_controller.rb b/app/controllers/extranet/pages_controller.rb index 1cb2242cc14d3f32c33f1aeac241531f59861786..a3bc8035e5d7d9c40a26063051c6c4832affdcb5 100644 --- a/app/controllers/extranet/pages_controller.rb +++ b/app/controllers/extranet/pages_controller.rb @@ -17,14 +17,21 @@ class Extranet::PagesController < Extranet::ApplicationController end def data - @metrics = [ - { value: current_extranet.alumni.count, name: University::Person::Alumnus.model_name.human(count: 2) }, - { value: current_extranet.users.count, name: User.model_name.human(count: 2) }, - { value: current_extranet.experiences.count, name: University::Person::Experience.model_name.human(count: 2) }, - { value: current_extranet.academic_years.count, name: Education::AcademicYear.model_name.human(count: 2) }, - { value: current_extranet.cohorts.count, name: Education::Cohort.model_name.human(count: 2) }, - { value: current_extranet.organizations.count, name: University::Organization.model_name.human(count: 2) }, - ] + @metrics = [] + if current_extranet.has_feature?(:alumni) + @metrics.concat [ + { value: current_extranet.alumni.count, name: University::Person::Alumnus.model_name.human(count: 2) }, + { value: current_extranet.academic_years.count, name: Education::AcademicYear.model_name.human(count: 2) }, + { value: current_extranet.cohorts.count, name: Education::Cohort.model_name.human(count: 2) } + ] + end + if current_extranet.has_feature?(:alumni) || current_extranet.has_feature?(:contacts) + @metrics.concat [ + { value: current_extranet.users.count, name: User.model_name.human(count: 2) }, + { value: current_extranet.experiences.count, name: University::Person::Experience.model_name.human(count: 2) }, + { value: current_extranet.organizations.count, name: University::Organization.model_name.human(count: 2) } + ] + end breadcrumb add_breadcrumb t('extranet.data') end diff --git a/app/controllers/extranet/style_controller.rb b/app/controllers/extranet/style_controller.rb index dea8f4d4b07d08303b30e5c00abfabf28fc330eb..3eb7c8587a2876c04a9be5b355261ab86f509bf7 100644 --- a/app/controllers/extranet/style_controller.rb +++ b/app/controllers/extranet/style_controller.rb @@ -1,5 +1,7 @@ class Extranet::StyleController < Extranet::ApplicationController + skip_before_action :authenticate_user!, :authorize_extranet_access! + def index render body: current_extranet.css, content_type: 'text/css' end -end \ No newline at end of file +end diff --git a/app/models/communication/extranet.rb b/app/models/communication/extranet.rb index c8ab92c466d3180edc318ed5d12aec0055b7ab65..c99daf122abc88d0f162d495cacdae7a82b36e3b 100644 --- a/app/models/communication/extranet.rb +++ b/app/models/communication/extranet.rb @@ -66,6 +66,7 @@ class Communication::Extranet < ApplicationRecord validates_presence_of :name, :host validates :logo, size: { less_than: 1.megabytes } validates :favicon, size: { less_than: 1.megabytes } + validates_presence_of :about_type, :about_id, if: :feature_alumni before_validation :sanitize_fields @@ -106,11 +107,19 @@ class Communication::Extranet < ApplicationRecord alias academic_years years def organizations - about&.alumni_organizations + if about.present? && about.respond_to?(:alumni_organizations) + about.alumni_organizations + else + connected_organizations + end end def experiences - about&.alumni_experiences + if about.present? && about.respond_to?(:alumni_experiences) + about.alumni_experiences + else + experiences_through_connections + end end def url diff --git a/app/models/communication/extranet/document.rb b/app/models/communication/extranet/document.rb index 9b332be81ebbaf763b0c4202fc428b07a1b3a046..09e6d96b62b4aae947b7cfb1f82b6adf6c4303a4 100644 --- a/app/models/communication/extranet/document.rb +++ b/app/models/communication/extranet/document.rb @@ -8,24 +8,18 @@ # published_at :datetime # created_at :datetime not null # updated_at :datetime not null -# category_id :uuid indexed # extranet_id :uuid not null, indexed -# kind_id :uuid indexed # university_id :uuid not null, indexed # # Indexes # -# extranet_document_categories (category_id) # index_communication_extranet_documents_on_extranet_id (extranet_id) # index_communication_extranet_documents_on_university_id (university_id) -# index_extranet_document_kinds (kind_id) # # Foreign Keys # # fk_rails_1272fd263c (extranet_id => communication_extranets.id) -# fk_rails_51f7db2f66 (kind_id => communication_extranet_document_kinds.id) # fk_rails_af877a8c0c (university_id => universities.id) -# fk_rails_eb351dc444 (category_id => communication_extranet_document_categories.id) # class Communication::Extranet::Document < ApplicationRecord include Sanitizable diff --git a/app/models/communication/extranet/with_connections.rb b/app/models/communication/extranet/with_connections.rb index 67841e9235ab6d571a83acd50aa0c5dbb50ac225..1325bfcec6c8751760fa94ad125c951a992930e5 100644 --- a/app/models/communication/extranet/with_connections.rb +++ b/app/models/communication/extranet/with_connections.rb @@ -27,4 +27,8 @@ module Communication::Extranet::WithConnections University::Person.where(id: ids) end + def experiences_through_connections + University::Person::Experience.where(person_id: connected_persons, organization_id: connected_organizations) + end + end \ No newline at end of file diff --git a/app/models/university/person/experience.rb b/app/models/university/person/experience.rb index 60c2a43632ea9fdd7e62cadab1a7e9af2c5f6b8e..2bd6df5582ef29bf0a12db955a01907c06dce9de 100644 --- a/app/models/university/person/experience.rb +++ b/app/models/university/person/experience.rb @@ -33,14 +33,12 @@ class University::Person::Experience < ApplicationRecord belongs_to :person belongs_to :organization, class_name: "University::Organization" - validates_presence_of :organization validates_presence_of :from_year - # TODO validateur de comparaison - # validates_numericality_of :to_year, { greater_than_or_equal_to: :from_year }, allow_nil: true validate :to_year, :not_before_from_year - before_validation :create_organization_if_needed + after_validation :deport_error_on_organization + scope :current, -> { where('from_year <= :current_year AND (to_year IS NULL OR to_year >= :current_year)', current_year: Date.today.year) } scope :ordered, -> { order('university_person_experiences.to_year DESC NULLS FIRST, university_person_experiences.from_year') } scope :recent, -> { where.not(from_year: nil) @@ -65,13 +63,10 @@ class University::Person::Experience < ApplicationRecord end end - def create_organization_if_needed - if organization.nil? && organization_name.present? - self.organization_name = self.organization_name.strip - orga = university.organizations.find_by("name ILIKE ?", organization_name) - orga ||= university.organizations.find_by(siren: organization_name) - orga ||= university.organizations.create(name: organization_name, created_from_extranet: true) - self.organization = orga if orga.persisted? + def deport_error_on_organization + if errors[:organization].present? && organization_name + errors.add :organization_name, :required end end + end diff --git a/app/views/admin/communication/blocks/components/_edit.html.erb b/app/views/admin/communication/blocks/components/_edit.html.erb index b2bc336a1db1ad86780cdde67f3b6f1f2e460177..f3c6a8352944be21b27cfb764eca6860d68614e1 100644 --- a/app/views/admin/communication/blocks/components/_edit.html.erb +++ b/app/views/admin/communication/blocks/components/_edit.html.erb @@ -19,6 +19,7 @@ placeholder ||= t "#{i18n_component}.placeholder", default: '' hint ||= t "#{i18n_component}.hint", default: '' none ||= t "#{i18n_component}.none", default: '' summernote_config ||= "mini-list" +codemirror_mode ||= "htmlmixed" partial = "admin/communication/blocks/components/#{component.kind}/edit" local_assigns[:template] = template @@ -31,5 +32,6 @@ local_assigns[:placeholder] = placeholder local_assigns[:hint] = hint local_assigns[:none] ||= t "#{i18n_component}.none", default: '' local_assigns[:summernote_config] ||= summernote_config +local_assigns[:codemirror_mode] ||= codemirror_mode %> <%= render partial, **local_assigns %> diff --git a/app/views/admin/communication/blocks/components/code/_edit.html.erb b/app/views/admin/communication/blocks/components/code/_edit.html.erb index 378a26d41bc751c05ee349f1ddeca7895b1df33d..c21538631ba9c501802a04f93d723a9f2a6c109b 100644 --- a/app/views/admin/communication/blocks/components/code/_edit.html.erb +++ b/app/views/admin/communication/blocks/components/code/_edit.html.erb @@ -4,7 +4,8 @@ <%= label %> </label> <textarea :id="<%= dom_id.html_safe %>" - class="form-control mb-3" + class="form-control mb-3 codemirror-vue" + data-codemirror-mode="<%= codemirror_mode %>" rows="<%= rows %>" v-model="<%= model %>.<%= property %>" placeholder="<%= placeholder %>"></textarea> diff --git a/app/views/admin/communication/blocks/edit.html.erb b/app/views/admin/communication/blocks/edit.html.erb index d57c344baacdba41e8e45f2cabe0122919169d07..e4813e15a33e370cab21e7dfe3c010a6b4dec19a 100644 --- a/app/views/admin/communication/blocks/edit.html.erb +++ b/app/views/admin/communication/blocks/edit.html.erb @@ -71,9 +71,9 @@ this.uploadFile(event.target, files[0], object, key); }, uploadFile(input, file, object, key) { - var size = Math.round(file.size / 1024 / 1024), + var size = Math.round(file.size / 1024 / 1024), sizeLimit = <%= Communication::Block::IMAGE_MAX_SIZE %>, - sizeLimitMo = 0, + sizeLimitMo = 0, controller; if (input.hasAttribute('data-size-limit')) { sizeLimit = input.getAttribute('data-size-limit'); @@ -107,6 +107,13 @@ this.initSummernote($summernoteElements.get(index)); }.bind(this)); }, + handleCodemirrors() { + var $codemirrorElements = $('.codemirror-vue'); + + $codemirrorElements.each(function(index){ + this.initCodemirror($codemirrorElements.get(index)); + }.bind(this)); + }, initSummernote(element) { var config = element.getAttribute('data-summernote-config') || 'default'; $(element).summernote({ @@ -121,10 +128,21 @@ }.bind(this) } }); + }, + initCodemirror(element) { + CodeMirror.fromTextArea(element, { + lineNumbers: true, + styleActiveLine: true, + indentUnit: 2, + viewportMargin: Infinity, + mode: element.getAttribute('data-codemirror-mode') + }); } }, mounted: function() { this.handleSummernotes(); + // Use Timeout to prevent display issues + setTimeout(this.handleCodemirrors.bind(this), 0); } }); diff --git a/app/views/admin/communication/extranets/_form.html.erb b/app/views/admin/communication/extranets/_form.html.erb index eef002e8e81176d5512e22bc0b363c067fc711ec..bcd8c3d72b1a3ef086441a29c6caa0d9082d59a3 100644 --- a/app/views/admin/communication/extranets/_form.html.erb +++ b/app/views/admin/communication/extranets/_form.html.erb @@ -22,8 +22,15 @@ preview: 100, direct_upload: true %> <%= f.input :color, as: :color %> - <%= f.input :home_sentence %> - <%= f.input :sass %> + <%= f.input :home_sentence, as: :summernote, input_html: { data: { 'summernote-config': 'link' } } %> + <%= f.input :sass, + input_html: { + data: { + provider: 'codemirror', + "codemirror-mode": "sass", + "codemirror-indentation": 4 + } + } %> <% end %> </div> <div class="col-xl-6"> diff --git a/app/views/admin/communication/extranets/posts/show.html.erb b/app/views/admin/communication/extranets/posts/show.html.erb index a4aa85eec80ed99554224e3cdb473d32c1e71440..4895b36dcec1e322112143a3c39a91e9819b04dc 100644 --- a/app/views/admin/communication/extranets/posts/show.html.erb +++ b/app/views/admin/communication/extranets/posts/show.html.erb @@ -10,7 +10,7 @@ <% action = '' action += link_to t('open'), - posts_communication_extranet_post_url(@post.slug, host: @post.extranet.url, extranet_id: nil), + posts_post_url(@post.slug, host: @post.extranet.url, extranet_id: nil), target: :_blank, class: 'btn btn-light btn-xs' if @post.published %> diff --git a/app/views/admin/university/organizations/show.html.erb b/app/views/admin/university/organizations/show.html.erb index d45b20164b2363af7bfc5702a857e13f855662c6..46dd34a5f1e7a11749586f6d6b25a1faf1b83bab 100644 --- a/app/views/admin/university/organizations/show.html.erb +++ b/app/views/admin/university/organizations/show.html.erb @@ -123,12 +123,12 @@ <tbody> <% @organization.experiences.ordered.each do |experience| %> <% - alumnus = experience.person - path = admin_university_alumnus_path(alumnus) + person = experience.person + path = admin_university_person_path(person) %> <tr> - <td><%= link_to_if can?(:read, alumnus), alumnus.last_name, path %></td> - <td><%= link_to_if can?(:read, alumnus), alumnus.first_name, path %></td> + <td><%= link_to_if can?(:read, person), person.last_name, path %></td> + <td><%= link_to_if can?(:read, person), person.first_name, path %></td> <td> <%= "#{experience.from_year} - #{experience.to_year.present? ? experience.to_year : t('today')}" %> </td> diff --git a/app/views/admin/university/organizations/static.html.erb b/app/views/admin/university/organizations/static.html.erb index 60054f0d4fbeacd0eb5c737974fdfedd7db117d9..ac035815dde3defe990bba3c4ff006073013dd31 100644 --- a/app/views/admin/university/organizations/static.html.erb +++ b/app/views/admin/university/organizations/static.html.erb @@ -16,8 +16,6 @@ kind: :zipcode, :city, :country, - :latitude, - :longitude, :phone, :email, :twitter, @@ -43,6 +41,9 @@ contact_details: <%= render 'admin/application/static/contact_detail', variable: :mastodon, data: @about.mastodon, kind: ContactDetails::Mastodon %> <%= render 'admin/application/static/contact_detail', variable: :phone, data: @about.phone, kind: ContactDetails::Phone %> <%= render 'admin/application/static/contact_detail', variable: :email, data: @about.email, kind: ContactDetails::Email %> + geolocation: + latitude: <%= @about.latitude %> + longitude: <%= @about.longitude %> <% if @about.logo.attached? %> logo: "<%= @about.logo.blob.id %>" <% end %> diff --git a/app/views/extranet/account/show.html.erb b/app/views/extranet/account/show.html.erb index cb79fe1a16b9feb55f4dd90dce2838bcd618d681..d36d78bad6c0351babe368cb53646604b38261a1 100644 --- a/app/views/extranet/account/show.html.erb +++ b/app/views/extranet/account/show.html.erb @@ -11,7 +11,7 @@ <%= link_to University::Person::Experience.human_attribute_name('new'), new_experience_path, class: 'btn btn-sm btn-primary mt-md-n5 float-md-end' %> - <%= render 'extranet/alumni/persons/path', person: @person, edit: true %> + <%= render 'extranet/experiences/list', person: @person, edit: true %> </div> <div class="col-md-3"> <%= kamifusen_tag @person.best_picture, width: 400, class: 'img-fluid person__portrait' if @person&.best_picture&.attached? %> @@ -19,6 +19,6 @@ <%= link_to t('extranet.account.edit'), edit_account_path, class: 'btn btn-primary mb-2' %> <%= link_to t('extranet.account.edit_personal_data'), edit_personal_data_path, class: 'btn btn-primary mb-2' %> </div> - <%= render 'extranet/alumni/persons/details', person: @person unless @person.nil? %> + <%= render 'extranet/personal_data/details', person: @person unless @person.nil? %> </div> </div> diff --git a/app/views/extranet/alumni/persons/_path.html.erb b/app/views/extranet/alumni/persons/_path.html.erb deleted file mode 100644 index 4572ea2b20a4cbf92e2ea566c4204e678c18d22a..0000000000000000000000000000000000000000 --- a/app/views/extranet/alumni/persons/_path.html.erb +++ /dev/null @@ -1,34 +0,0 @@ -<% -edit ||= false -%> -<div class="experiences mt-4"> - <ul class="list-unstyled"> - <% if person&.experiences&.any? %> - <% @person.experiences.ordered.each do |experience| %> - <%= render 'extranet/experiences/experience', experience: experience, edit: edit %> - <% end %> - <% end %> - <% person&.cohorts&.each do |cohort| %> - <li class="experiences__experience py-4 border-top"> - <div class="row"> - <div class="col-md-6"> - <p class="mb-0"> - <%= link_to [:alumni, cohort] do %> - <b><%= cohort.program %></b><br> - <%= cohort.program.diploma %><br> - <%= cohort.year %> - <% end %> - </p> - </div> - <div class="col-md-6 text-end"> - <% if cohort.school.logo.attached? %> - <%= kamifusen_tag cohort.school.logo, width: 100, class: 'img-fluid experience__organization__logo' %> - <% else %> - <p class="text-end"><%= cohort.school %></p> - <% end %> - </div> - </div> - </li> - <% end %> - </ul> -</div> diff --git a/app/views/extranet/alumni/persons/show.html.erb b/app/views/extranet/alumni/persons/show.html.erb index 6079d71e13004f41c86705e6603db3862af383d2..33896432b2c293381a5a587c0daaf7e90ab9a7ea 100644 --- a/app/views/extranet/alumni/persons/show.html.erb +++ b/app/views/extranet/alumni/persons/show.html.erb @@ -12,10 +12,38 @@ </div> </div> <p class="mb-4"><%= t('extranet.experiences.title') %></p> - <%= render 'extranet/alumni/persons/path', person: @person %> + <%= render 'extranet/experiences/list', person: @person %> + + <div class="experiences mt-4"> + <ul class="list-unstyled"> + <% @person&.cohorts&.each do |cohort| %> + <li class="experiences__experience py-4 border-top"> + <div class="row"> + <div class="col-md-6"> + <p class="mb-0"> + <%= link_to [:alumni, cohort] do %> + <b><%= cohort.program %></b><br> + <%= cohort.program.diploma %><br> + <%= cohort.year %> + <% end %> + </p> + </div> + <div class="col-md-6 text-end"> + <% if cohort.school.logo.attached? %> + <%= kamifusen_tag cohort.school.logo, width: 100, class: 'img-fluid experience__organization__logo' %> + <% else %> + <p class="text-end"><%= cohort.school %></p> + <% end %> + </div> + </div> + </li> + <% end %> + </ul> + </div> + </div> <div class="offset-md-1 col-md-3 order-1 order-md-2"> <%= kamifusen_tag @person.best_picture, width: 400, class: 'img-fluid person__portrait' if @person.best_picture.attached? %> - <%= render 'extranet/alumni/persons/details', person: @person %> + <%= render 'extranet/personal_data/details', person: @person %> </div> </div> diff --git a/app/views/extranet/contacts/organizations/show.html.erb b/app/views/extranet/contacts/organizations/show.html.erb index 7e294913f1fba849ab800f8e7e133a04d0cd0924..855d43325861c3883b55c05266735e3a50acad1e 100644 --- a/app/views/extranet/contacts/organizations/show.html.erb +++ b/app/views/extranet/contacts/organizations/show.html.erb @@ -7,6 +7,36 @@ <div class="biography mb-5"> <%= sanitize @organization.text %> </div> + <% if @current_experiences.any? %> + <div class="experiences mb-5"> + <h3><%= t('extranet.contacts.organizations.experiences', count: @current_experiences.pluck(:person_id).uniq.size) %></h3> + + <% @current_experiences.each do |experience| %> + <article class="experience mb-4"> + <div class="row gx-3"> + <div class="col-md-3"> + <% if experience.person.best_picture.attached? %> + <%= kamifusen_tag experience.person.best_picture, width: 400, class: 'img-fluid', + sizes: { + '(max-width: 576px)': '400px', + '(max-width: 991px)': '200px' + } %> + <% else %> + <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid' %> + <% end %> + </div> + <div class="col-md-9"> + <%= link_to [:contacts, experience.person], class: 'stretched-link' do %> + <p> + <b><%= experience.person.first_name %> <%= experience.person.last_name %></b><br> + <span class="text-muted"><%= experience.description %></span> + </p> + <% end %> + </div> + </article> + <% end %> + </div> + <% end %> </div> </div> </div> diff --git a/app/views/extranet/contacts/persons/show.html.erb b/app/views/extranet/contacts/persons/show.html.erb index 36302396a7f90bee2cc44955907a1f096817c230..69c480d48020311a0e36f6559cdbb65c94a7e26f 100644 --- a/app/views/extranet/contacts/persons/show.html.erb +++ b/app/views/extranet/contacts/persons/show.html.erb @@ -10,15 +10,43 @@ </p> <% end %> <% unless @person.biography.blank? %> - <div class="biography mt-5"> + <div class="biography my-5"> <%= sanitize @person&.biography %> </div> <% end %> + <% if @current_experiences.any? %> + <div class="experiences mb-5"> + <h3><%= t('extranet.contacts.persons.experiences', count: @current_experiences.pluck(:organization_id).uniq.size) %></h3> + + <% @current_experiences.each do |experience| %> + <article class="experience mb-4"> + <div class="row gx-3"> + <div class="col-md-3"> + <% if experience.organization.logo.attached? %> + <%= kamifusen_tag experience.organization.logo, width: 400, class: 'img-fluid', + sizes: { + '(max-width: 576px)': '400px', + '(max-width: 991px)': '200px' + } %> + <% end %> + </div> + <div class="col-md-9"> + <%= link_to [:contacts, experience.organization], class: 'stretched-link' do %> + <p> + <b><%= experience.organization %></b><br> + <span class="text-muted"><%= experience.description %></span> + </p> + <% end %> + </div> + </article> + <% end %> + </div> + <% end %> </div> </div> </div> <div class="offset-md-1 col-md-3 order-1 order-md-2"> <%= kamifusen_tag @person.best_picture, width: 400, class: 'img-fluid person__portrait' if @person.best_picture.attached? %> - <%= render 'extranet/alumni/persons/details', person: @person %> + <%= render 'extranet/personal_data/details', person: @person %> </div> </div> diff --git a/app/views/extranet/experiences/_experience.html.erb b/app/views/extranet/experiences/_experience.html.erb index e5f211fc62bc64248d3ebdb99f8faf04068b3f5c..4db5233f761ba5c886c29c841f66da37dc86c745 100644 --- a/app/views/extranet/experiences/_experience.html.erb +++ b/app/views/extranet/experiences/_experience.html.erb @@ -15,12 +15,12 @@ edit ||= false </div> <div class="col-md-6 text-end"> <% if experience.organization.present? %> - <%= link_to [:alumni, experience.organization] do %> - <% if experience.organization.logo.attached? %> + <% if experience.organization.logo.attached? %> + <%= link_to organization_path(experience.organization) do %> <%= kamifusen_tag experience.organization.logo, width: 100, class: 'img-fluid experience__organization__logo' %> - <% else %> - <p class="text-end><%= link_to experience.organization, [:alumni, experience.organization] %></p> <% end %> + <% else %> + <p class="text-end><%= link_to experience.organization, organization_path(experience.organization) %></p> <% end %> <div> <% end %> diff --git a/app/views/extranet/experiences/_form.html.erb b/app/views/extranet/experiences/_form.html.erb index 5ff1f5470817ac3386fa70c3f46a06fa23f9ce9e..1773637dbbc7521096017c0352f99831fbe65ffc 100644 --- a/app/views/extranet/experiences/_form.html.erb +++ b/app/views/extranet/experiences/_form.html.erb @@ -1,18 +1,30 @@ <%= simple_form_for experience, url: experience.persisted? ? experience_path(experience) : experiences_path do |f| %> - <% if experience.errors.any? %> - <div id="error_explanation" class="text-danger"> - <ul class="list-unstyled"> - <% experience.errors.each do |error| %> - <li><%= error.full_message %></li> + <div class="row"> + <div class="col-lg-6"> + <%= f.input :organization_name, + label: University::Organization.model_name.human, + as: :autocomplete, + required: true, + url: search_organizations_path, + placeholder: t("extranet.experiences.search_organization"), + input_html: { + data: { + "showNoMatches": "false", + "autocomplete-target": "#university_person_experience_organization_id", + "autocomplete-no-result-target": "#university_person_experience_organization_not_found" + }, + autocomplete: 'off', + role: 'presentation' + } %> + <%= f.hidden_field :organization_id %> + <div class="<%= 'd-none' unless experience.organization_id.nil? && experience.organization_name.present? %>" id="university_person_experience_organization_not_found" data-default-text="<%= t('extranet.account.experiences.create_new_html', name: 'CHANGEME', url: new_organization_path(name: 'CHANGEME')) %>"> + <% if experience.organization_id.nil? && experience.organization_name.present? %> + <%= t('extranet.account.experiences.create_new_html', name: experience.organization_name, url: new_organization_path(name: experience.organization_name)) %> <% end %> - </ul> + </div> </div> - <% end %> - - <div class="row"> <div class="col-lg-6"> - <%= f.input :description, as: :string %> <div class="row"> <div class="col-6"> <%= f.input :from_year %> @@ -21,23 +33,8 @@ <%= f.input :to_year %> </div> </div> - </div> - <div class="col-lg-6"> - <%= f.input :organization_name, - label: University::Organization.model_name.human, - as: :autocomplete, - url: alumni_search_university_organizations_path, - placeholder: t("extranet.experiences.search_organization"), - input_html: { - data: { - "showNoMatches": "false", - "autocomplete-target": "#university_person_experience_organization_id" - }, - autocomplete: 'off', - role: 'presentation' - } %> - <%= f.hidden_field :organization_id %> + <%= f.input :description, as: :string %> </div> </div> <%= submit f %> -<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/extranet/experiences/_list.html.erb b/app/views/extranet/experiences/_list.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..8873d0a515295669d128e561397da4501fd286c1 --- /dev/null +++ b/app/views/extranet/experiences/_list.html.erb @@ -0,0 +1,12 @@ +<% +edit ||= false +%> +<div class="experiences mt-4"> + <ul class="list-unstyled"> + <% if person&.experiences&.any? %> + <% @person.experiences.ordered.each do |experience| %> + <%= render 'extranet/experiences/experience', experience: experience, edit: edit %> + <% end %> + <% end %> + </ul> +</div> diff --git a/app/views/extranet/experiences/edit.html.erb b/app/views/extranet/experiences/edit.html.erb index acfba4993cd514add045f930bcb215301e21d5d6..0a0c8aa0b70e1e3613ac1c7dfcee924e4b40bd37 100644 --- a/app/views/extranet/experiences/edit.html.erb +++ b/app/views/extranet/experiences/edit.html.erb @@ -1,3 +1,5 @@ <% content_for :title, @experience %> -<%= render 'form', experience: @experience %> \ No newline at end of file +<%= render 'form', experience: @experience %> + +<%= link_to t('delete'), experience_path(@experience), method: :delete, data: { confirm: t('please_confirm') }, class: 'btn btn-danger mt-3' %> diff --git a/app/views/extranet/home/index.html.erb b/app/views/extranet/home/index.html.erb index 6cd5f804587ddcd34b4c52ad301c15842ca52472..dcfaf67ad3356a166c43626f0fa8ce1d732f9060 100644 --- a/app/views/extranet/home/index.html.erb +++ b/app/views/extranet/home/index.html.erb @@ -1,15 +1,14 @@ <% content_for :title, current_context %> <% content_for :header do %> - <h1> + <div class="header__title"> <% if current_extranet.home_sentence.present? %> - <%= current_extranet.home_sentence.html_safe %> + <%= sanitize current_extranet.home_sentence %> <% else %> - <%= t 'extranet.home.welcome' %> + <p><%= t 'extranet.home.welcome' %></p> <% end %> - </h1> + </div> <% end %> <%= render 'extranet/home/features/posts' if current_extranet.feature_posts %> <%= render 'extranet/home/features/alumni' if current_extranet.feature_alumni %> <%= render 'extranet/home/features/contacts' if current_extranet.feature_contacts %> - diff --git a/app/views/extranet/layouts/devise.html.erb b/app/views/extranet/layouts/devise.html.erb index b8ebe5083ad89910bc9b58d2daccbed966e33421..f94aae6fee43e9285b0b021aa7c4ae9b779a4464 100644 --- a/app/views/extranet/layouts/devise.html.erb +++ b/app/views/extranet/layouts/devise.html.erb @@ -6,7 +6,7 @@ <body class="<%= body_classes %> layout-devise"> <main class="container"> <div class="row"> - <div class="offset-md-2 col-md-8"> + <div class="offset-xl-1 col-xl-10"> <h1 class="text-center"> <%= link_to root_path do %> <%= render 'logo' %> @@ -31,5 +31,6 @@ </main> <%= render 'extranet/gdpr/cookie_consent' %> <%= render 'bugsnag' %> + <%= javascript_include_tag 'extranet' %> </body> </html> diff --git a/app/views/extranet/organizations/_form.html.erb b/app/views/extranet/organizations/_form.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..21d1904fcb3aae321d04ec8d44ba9635165837bf --- /dev/null +++ b/app/views/extranet/organizations/_form.html.erb @@ -0,0 +1,92 @@ +<% url = organization.persisted? ? organization_path(organization) : organizations_path %> +<%= simple_form_for organization, url: url 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-xl-6"> + <%= f.input :name %> + <%= render 'admin/application/summary/form', f: f, about: organization %> + <%= f.input :text, + as: :summernote, + input_html: { + data: { 'summernote-config' => 'mini-list' } + } %> + + <h2><%= University::Organization.human_attribute_name('legal') %></h2> + <div class="row"> + <div class="col-xl-6"> + <%= f.input :long_name %> + </div> + <div class="col-xl-6"> + <%= f.input :kind, include_blank: false %> + </div> + <div class="col-xl-6"> + <%= f.input :siren %> + </div> + </div> + </div> + + <div class="col-xl-6"> + <h2><%= University::Organization.human_attribute_name('physical') %></h2> + <div class="row"> + <div class="col-xl-6"> + <%= f.input :address_name %> + </div> + <div class="col-xl-6"> + <%= f.input :address %> + </div> + <div class="col-xl-6"> + <%= f.input :address_additional %> + </div> + <div class="col-xl-6"> + <%= f.input :zipcode %> + </div> + <div class="col-xl-6"> + <%= f.input :city %> + </div> + <div class="col-xl-6"> + <%= f.input :country, input_html: { class: 'form-select' } %> + </div> + </div> + + <h2><%= University::Organization.human_attribute_name('digital') %></h2> + <div class="row"> + <div class="col-xl-6"> + <%= f.input :url %> + </div> + <div class="col-xl-6"> + <%= f.input :phone %> + </div> + <div class="col-xl-6"> + <%= f.input :email %> + </div> + <div class="col-xl-6"> + <%= f.input :linkedin %> + </div> + <div class="col-xl-6"> + <%= f.input :twitter %> + </div> + <div class="col-xl-6"> + <%= f.input :mastodon %> + </div> + </div> + + <h2><%= University::Organization.human_attribute_name('logos') %></h2> + <%= f.input :logo, + as: :single_deletable_file, + input_html: { accept: '.jpg,.jpeg,.png,.svg' }, + preview: 200, + resize: false, + direct_upload: true %> + <%= f.input :logo_on_dark_background, + as: :single_deletable_file, + input_html: { accept: '.jpg,.jpeg,.png,.svg' }, + preview: 200, + resize: false, + direct_upload: true %> + </div> + + </div> + <%= submit f %> +<% end %> diff --git a/app/views/extranet/organizations/edit.html.erb b/app/views/extranet/organizations/edit.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..8e990f07344d2b5384fcbe9aaa67cbce7e2000ce --- /dev/null +++ b/app/views/extranet/organizations/edit.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, @organization %> + +<%= render 'form', organization: @organization %> diff --git a/app/views/extranet/organizations/new.html.erb b/app/views/extranet/organizations/new.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..96d61c5358d2c3ff3efb5df4fb854c9cbe98b367 --- /dev/null +++ b/app/views/extranet/organizations/new.html.erb @@ -0,0 +1,3 @@ +<% content_for :title, University::Organization.model_name.human %> + +<%= render 'form', organization: @organization %> diff --git a/app/views/extranet/alumni/organizations/search.json.jbuilder b/app/views/extranet/organizations/search.json.jbuilder similarity index 100% rename from app/views/extranet/alumni/organizations/search.json.jbuilder rename to app/views/extranet/organizations/search.json.jbuilder diff --git a/app/views/extranet/organizations/show.html.erb b/app/views/extranet/organizations/show.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..0c6394a26b6b4c23d11efb0fd894d7e380ec959b --- /dev/null +++ b/app/views/extranet/organizations/show.html.erb @@ -0,0 +1,117 @@ +<% content_for :title, @organization %> +<div class="row"> + <div class="col-md-6"> + <%= render 'admin/application/summary/show', about: @organization %> + + <% if strip_tags(@organization.text.to_s).present? %> + <h2><%= University::Organization.human_attribute_name('text') %></h2> + <%= @organization.text.to_s.html_safe %> + <% end %> + + <h2><%= University::Organization.human_attribute_name('legal') %></h2> + <div class="row"> + <% if @organization.long_name.present? %> + <div class="col-xxl-6"> + <%= osuny_label University::Organization.human_attribute_name('long_name') %> + <p><%= @organization.long_name %></p> + </div> + <% end %> + <div class="col-xxl-6"> + <%= osuny_label University::Organization.human_attribute_name('kind') %> + <p><%= @organization.kind_i18n %></p> + </div> + <% if @organization.siren.present? %> + <div class="col-xxl-6"> + <%= osuny_label University::Organization.human_attribute_name('siren') %> + <p><%= @organization.siren %></p> + </div> + <% end %> + </div> + </div> + + <div class="col-md-6"> + <% if @organization.address_name.present? || + @organization.address.present? || + @organization.address_additional.present? || + @organization.zipcode.present? || + @organization.city.present? || + @organization.country.present? || + @organization.geolocated? %> + <h2><%= University::Organization.human_attribute_name('physical') %> + <div class="row"> + <% [ + :address_name, + :address, + :address_additional, + :zipcode, + :city, + ].each do |property| %> + <% value = @organization.send property %> + <% next if value.blank? %> + <div class="col-xxl-6"> + <%= osuny_label University::Organization.human_attribute_name(property) %> + <p><%= value %></p> + </div> + <% end %> + <% if @organization.country.present? %> + <div class="col-xxl-6"> + <%= osuny_label University::Organization.human_attribute_name('country') %> + <p><%= ISO3166::Country[@organization.country].common_name %></p> + </div> + <% end %> + <% if @organization.geolocated? %> + <div class="col-xxl-6"> + <%= osuny_label University::Organization.human_attribute_name('geolocation') %> + <p><%= @organization.geo_point.to_s %></p> + </div> + <% end %> + </div> + <% end %> + + <% if @organization.phone.present? || + @organization.email.present? || + @organization.linkedin.present? || + @organization.twitter.present? || + @organization.mastodon.present? %> + <h2><%= University::Organization.human_attribute_name('digital') %></h2> + <div class="row"> + <% unless @organization.url.blank? %> + <div class="col-xxl-6"> + <%= osuny_label University::Organization.human_attribute_name('url') %> + <p><%= link_to @organization.url, + @organization.url, + target: :_blank %></p> + </div> + <% end %> + <% [ + :phone, + :email, + :linkedin, + :twitter, + :mastodon + ].each do |property| %> + <% value = @organization.send property %> + <% next if value.blank? %> + <div class="col-xxl-6"> + <%= osuny_label University::Organization.human_attribute_name(property) %> + <p><%= value %></p> + </div> + <% end %> + </div> + <% end %> + + <% if @organization.logo.attached? || @organization.logo_on_dark_background.attached? %> + <h2><%= t('university.organization.logos') %></h2> + <% if @organization.logo.attached? %> + <%= osuny_label University::Organization.human_attribute_name('logo') %><br> + <%= kamifusen_tag @organization.logo, class: 'img-fluid img-fill bg-light img-thumbnail mb-3' %> + <% end %> + <% if @organization.logo_on_dark_background.attached? %> + <%= osuny_label University::Organization.human_attribute_name('logo_on_dark_background') %><br> + <%= kamifusen_tag @organization.logo_on_dark_background, class: 'img-fluid img-fill bg-dark img-thumbnail' %> + <% end %> + <% end %> + </div> + +</div> +<%= link_to t('edit'), edit_organization_path(@organization), class: 'btn btn-primary' %> diff --git a/app/views/extranet/alumni/persons/_details.html.erb b/app/views/extranet/personal_data/_details.html.erb similarity index 100% rename from app/views/extranet/alumni/persons/_details.html.erb rename to app/views/extranet/personal_data/_details.html.erb diff --git a/config/application.sample.yml b/config/application.sample.yml index f273685fe74d4c19abeb00985b75ea07beeebbff..105eafe9569a653dec5c252a097c1b38266b1254 100644 --- a/config/application.sample.yml +++ b/config/application.sample.yml @@ -1,6 +1,4 @@ APPLICATION_ENV: development -# Can be used when working on two incompatible branches (e.g. main & i18n) -OSUNY_DEVELOPMENT_DBNAME: BUGSNAG_JAVASCRIPT_KEY: BUGSNAG_RUBY_KEY: @@ -8,6 +6,9 @@ BUGSNAG_RUBY_KEY: MAIL_FROM_DEFAULT_ADDRESS: MAIL_FROM_DEFAULT_NAME: + # Can be used when working on two incompatible branches (e.g. main & i18n) +OSUNY_DEVELOPMENT_DBNAME: + OSUNY_STAGING_APP_NAME: OSUNY_STAGING_PG_ADDON_ID: diff --git a/config/locales/extranet/en.yml b/config/locales/extranet/en.yml index fb877a0b81a1a8e13a913c766b1ee9b417e7e671..8e470e5b45f7803d2055e53a1b3df5825cea472a 100644 --- a/config/locales/extranet/en.yml +++ b/config/locales/extranet/en.yml @@ -2,12 +2,18 @@ en: extranet: features: Features account: - my: My account edit: Edit account edit_personal_data: Edit profile + experiences: + create_new_html: The organization *** doesn't exist, do you want to <a class='btn btn-primary' href='%{url}'>create it</a>? + my: My account updated: Updated logout: Log out contacts: + organizations: + experiences: Members of this organization (%{count}) + persons: + experiences: Organizations where they belong (%{count}) search: home: Search in directory title: Search @@ -38,4 +44,4 @@ en: updated: Your personal data has been updated! posts: home: Recent posts - read_post: Read post \ No newline at end of file + read_post: Read post diff --git a/config/locales/extranet/fr.yml b/config/locales/extranet/fr.yml index 87fcc92b5e502247244bb5761ce3c12ede289ffd..1c80d42bc669ca36ad67f6cf15572ea5842efe8e 100644 --- a/config/locales/extranet/fr.yml +++ b/config/locales/extranet/fr.yml @@ -2,12 +2,18 @@ fr: extranet: features: Fonctionnalités account: - my: Mon compte edit: Modifier mon compte edit_personal_data: Modifier mon profil + experiences: + create_new_html: L'organisation <b>%{name}</b> n'existe pas, souhaitez-vous <a class='btn btn-primary' href='%{url}'>la créer</a> ? + my: Mon compte updated: Mise à jour effectuée logout: Déconnexion contacts: + organizations: + experiences: Membres de cette organisation (%{count}) + persons: + experiences: Organisations dont iel fait partie (%{count}) search: home: Chercher dans l'annuaire title: Recherche @@ -38,4 +44,4 @@ fr: updated: Mise à jour des donnes personnelles effectuée ! posts: home: Actualités récentes - read_post: Lire l'article \ No newline at end of file + read_post: Lire l'article diff --git a/config/locales/university/en.yml b/config/locales/university/en.yml index 1958db7928d4368fc45c70cc5542c3b85ceb0ee4..b681492b3a478c70796c3d221a13bda8e9935c7d 100644 --- a/config/locales/university/en.yml +++ b/config/locales/university/en.yml @@ -76,6 +76,7 @@ en: description: Description edit: Edit experience organization: Organization + organization_name: Organisation from_year: Start year to_year: End year new: Add experience diff --git a/config/locales/university/fr.yml b/config/locales/university/fr.yml index bec6dcddafad2f5715b4fcb1e02d19bce32c0f9d..2adbfaf37179e61069498280868d3204bf736a14 100644 --- a/config/locales/university/fr.yml +++ b/config/locales/university/fr.yml @@ -78,6 +78,7 @@ fr: from_year: Année de début new: Ajouter une expérience organization: Organisation + organization_name: Organisation to_year: Année de fin university/person/involvement: description: Mission (dans ce contexte) diff --git a/config/routes/extranet.rb b/config/routes/extranet.rb index 8ea81aaa667989b9db0cf730edf47d903a4a1fc7..f62c4b0e96b0d094f1efd00c227b73f203a6d586 100644 --- a/config/routes/extranet.rb +++ b/config/routes/extranet.rb @@ -7,18 +7,22 @@ namespace :contacts do get 'search' => 'search#index', as: :search root to: 'persons#index' end -namespace :alumni do +namespace :alumni do get 'cohorts' => 'cohorts#index', as: :education_cohorts get 'cohorts/:id' => 'cohorts#show', as: :education_cohort get 'organizations' => 'organizations#index', as: :university_organizations - get 'organizations/search' => 'organizations#search', as: :search_university_organizations, defaults: { format: 'json' } - get 'organizations/:id' => 'organizations#show', as: :university_organization + get 'organization/:id' => 'organizations#show', as: :university_organization get 'persons' => 'persons#index', as: :university_persons get 'persons/:id' => 'persons#show', as: :university_person get 'years' => 'academic_years#index', as: :education_academic_years get 'years/:id' => 'academic_years#show', as: :education_academic_year root to: 'persons#index' end +resources :organizations, except: [:index, :destroy] do + collection do + get 'search' => 'organizations#search', as: :search, defaults: { format: 'json' } + end +end namespace :posts do get 'categories' => 'categories#index', as: :categories get 'categories/:slug' => 'categories#show', as: :category diff --git a/package.json b/package.json index bea2adeadb53d5f70e63ae09c35ceb6b12cb0879..11690b06ba4a455b22621bafeea7231ffad8c7e0 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "dependencies": { "bootstrap-icons": "^1.9.1", "bootstrap-print-css": "^1.0.1", + "codemirror": "5", "cropperjs": "^1.5.12", "jquery-cropper": "^1.0.1", "notyf": "^3.10.0", diff --git a/test/controllers/extranet/alumni/organizations_controller_test.rb b/test/controllers/extranet/alumni/organizations_controller_test.rb index 4ae389477eb5ff650133f317dd1ecdf7f4be5030..fa9557a8bdda0f8277b6d929fc7a9d1d8357f843 100644 --- a/test/controllers/extranet/alumni/organizations_controller_test.rb +++ b/test/controllers/extranet/alumni/organizations_controller_test.rb @@ -8,14 +8,6 @@ class Extranet::Alumni::OrganizationsControllerTest < ActionDispatch::Integratio assert_response(:success) end - def test_search - get alumni_search_university_organizations_path(term: "Organisation de test") - assert_response(:success) - results = JSON.parse(response.body) - assert_equal(1, results.size) - assert_equal("Organisation de test", results.first["label"]) - end - def test_show get alumni_university_organization_path(university_organizations(:default_organization)) assert_response(:success) diff --git a/test/controllers/extranet/organizations_controller_test.rb b/test/controllers/extranet/organizations_controller_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..112be04e1bef97dbcd572c87cdfbf20c4e8d3a7b --- /dev/null +++ b/test/controllers/extranet/organizations_controller_test.rb @@ -0,0 +1,14 @@ +require "test_helper" + +class Extranet::OrganizationsControllerTest < ActionDispatch::IntegrationTest + include ExtranetSetup + + def test_search + get search_organizations_path(term: "Organisation de test") + assert_response(:success) + results = JSON.parse(response.body) + assert_equal(1, results.size) + assert_equal("Organisation de test", results.first["label"]) + end + +end diff --git a/test/fixtures/communication/extranet/documents.yml b/test/fixtures/communication/extranet/documents.yml index fb4fa23733ee89bef580ed42a2418d63d9d1b4cd..be1d0d6ab57326b590356596a4609a335ddd6e69 100644 --- a/test/fixtures/communication/extranet/documents.yml +++ b/test/fixtures/communication/extranet/documents.yml @@ -8,24 +8,18 @@ # published_at :datetime # created_at :datetime not null # updated_at :datetime not null -# category_id :uuid indexed # extranet_id :uuid not null, indexed -# kind_id :uuid indexed # university_id :uuid not null, indexed # # Indexes # -# extranet_document_categories (category_id) # index_communication_extranet_documents_on_extranet_id (extranet_id) # index_communication_extranet_documents_on_university_id (university_id) -# index_extranet_document_kinds (kind_id) # # Foreign Keys # # fk_rails_1272fd263c (extranet_id => communication_extranets.id) -# fk_rails_51f7db2f66 (kind_id => communication_extranet_document_kinds.id) # fk_rails_af877a8c0c (university_id => universities.id) -# fk_rails_eb351dc444 (category_id => communication_extranet_document_categories.id) # one: diff --git a/yarn.lock b/yarn.lock index a8431a395052b1f0405556a0c582ccce88c64c1d..c7d515077ce9a861f931e17189c3cecd9862a22a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -107,6 +107,11 @@ bootstrap-print-css@^1.0.1: resolved "https://registry.yarnpkg.com/bootstrap-print-css/-/bootstrap-print-css-1.0.1.tgz#acc0264388caebbad0805e60c869d42cd6fe55bf" integrity sha512-I73Cw87BaxCccTjo3qEbvn7KRb55msMxTuT7mpkAAY4Obq8iG9xCybdxnJqq+RrykLD79O3092AiJwaKiEex7w== +codemirror@5: + version "5.65.12" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.12.tgz#294fdf097d10ac5b56a9e011a91eff252afc73ae" + integrity sha512-z2jlHBocElRnPYysN2HAuhXbO3DNB0bcSKmNz3hcWR2Js2Dkhc1bEOxG93Z3DeUrnm+qx56XOY5wQmbP5KY0sw== + cropperjs@^1.5.12: version "1.5.12" resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-1.5.12.tgz#d9c0db2bfb8c0d769d51739e8f916bbc44e10f50"