From f8a73a1847a987f87d70d12c477bc436df117bef Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 13 Feb 2024 16:24:52 +0100 Subject: [PATCH 01/80] add first tables to display profile data --- app/views/people/show.html.haml | 43 +++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index ee4a424f8..a55476215 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -4,8 +4,47 @@ %h1 = @person.name 's Profile + +%div.d-flex + %div.me-5 + %table + %tbody + %th Name: + %tr + %td= @entry.name + %th Email: + %tr + %td= @entry.email + %th Abschluss: + %tr + %td= @entry.title + %th Funktion: + %tr + %td= @entry.roles.map { |role| role.name } + %th Organisationseinheit: + %tr + %td= @entry.department.name + %th Firma: + %tr + %td= @entry.company.name %div - %h5 - This Person is from #{ @person.nationality } + %table + %tbody + %th Geburtsdatum: + %tr + %td= @entry.birthdate.to_date.strftime('%d.%m.%Y') + %th Nationalität: + %tr + %td= @entry.nationality + %th Wohnort (Stadt): + %tr + %td= @entry.location + %th Zivilstand: + %tr + %td= @entry.marital_status + %th Kürzel: + %tr + %td= @entry.shortname ? @entry.shortname : "-" + = link_to "Person bearbeiten", edit_person_path = link_to "Show all", people_path \ No newline at end of file From 8da7aad4c523169dda6b371d586cc73555fe8965 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 16 Feb 2024 11:01:20 +0100 Subject: [PATCH 02/80] add language and profile pic to view and add a new section in the view respectively. make roles display correctly --- app/views/people/show.html.haml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index a55476215..91f268a93 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -6,7 +6,9 @@ 's Profile %div.d-flex - %div.me-5 + %div.w-25 + %img.rounded-circle{src: @entry.picture, width: '141', height: '141'} + %div.w-25.pe-5 %table %tbody %th Name: @@ -19,15 +21,16 @@ %tr %td= @entry.title %th Funktion: - %tr - %td= @entry.roles.map { |role| role.name } + - @entry.roles.each do |role| + %tr + %td= role.name %th Organisationseinheit: %tr %td= @entry.department.name %th Firma: %tr %td= @entry.company.name - %div + %div.w-25.pe-5 %table %tbody %th Geburtsdatum: @@ -35,7 +38,7 @@ %td= @entry.birthdate.to_date.strftime('%d.%m.%Y') %th Nationalität: %tr - %td= @entry.nationality + %td= @entry.nationality2.blank? ? @entry.nationality : "#{@entry.nationality}, #{@entry.nationality2}" %th Wohnort (Stadt): %tr %td= @entry.location @@ -44,7 +47,9 @@ %td= @entry.marital_status %th Kürzel: %tr - %td= @entry.shortname ? @entry.shortname : "-" + %td= @entry.shortname + %div.w-25 + %div Sprachen = link_to "Person bearbeiten", edit_person_path = link_to "Show all", people_path \ No newline at end of file From 0414a9a2306ac3639a0a5803d7ff8e7c999e41ff Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 16 Feb 2024 11:25:37 +0100 Subject: [PATCH 03/80] style headers of user profile data table and move edit link --- app/views/people/show.html.haml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 91f268a93..e1b205917 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -8,48 +8,48 @@ %div.d-flex %div.w-25 %img.rounded-circle{src: @entry.picture, width: '141', height: '141'} + %div.mt-3= link_to "Bearbeiten", edit_person_path %div.w-25.pe-5 %table %tbody - %th Name: + %th.fw-light Name %tr %td= @entry.name - %th Email: + %th.fw-light Email %tr %td= @entry.email - %th Abschluss: + %th.fw-light Abschluss %tr %td= @entry.title - %th Funktion: + %th.fw-light Funktion - @entry.roles.each do |role| %tr %td= role.name - %th Organisationseinheit: + %th.fw-light Organisationseinheit %tr %td= @entry.department.name - %th Firma: + %th.fw-light Firma %tr %td= @entry.company.name %div.w-25.pe-5 %table %tbody - %th Geburtsdatum: + %th.fw-light Geburtsdatum %tr %td= @entry.birthdate.to_date.strftime('%d.%m.%Y') - %th Nationalität: + %th.fw-light Nationalität %tr %td= @entry.nationality2.blank? ? @entry.nationality : "#{@entry.nationality}, #{@entry.nationality2}" - %th Wohnort (Stadt): + %th.fw-light Wohnort (Stadt) %tr %td= @entry.location - %th Zivilstand: + %th.fw-light Zivilstand %tr %td= @entry.marital_status - %th Kürzel: + %th.fw-light Kürzel %tr %td= @entry.shortname %div.w-25 %div Sprachen -= link_to "Person bearbeiten", edit_person_path = link_to "Show all", people_path \ No newline at end of file From fd6458bf504b7f34687335e1f4ec77c397391a58 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 16 Feb 2024 12:00:36 +0100 Subject: [PATCH 04/80] display languages in a very basic way --- app/views/people/show.html.haml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index e1b205917..bf231026f 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -50,6 +50,8 @@ %tr %td= @entry.shortname %div.w-25 - %div Sprachen - + %div.fw-light Sprachen + %div.border.border-dark-subtle.mt-1.p-2 + - @entry.language_skills.each do |language| + %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" = link_to "Show all", people_path \ No newline at end of file From 86d149ca11288353ce47844c4d41a5e58fb383e8 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 16 Feb 2024 15:55:24 +0100 Subject: [PATCH 05/80] make account overview display country name instead of alpha2 code and implement most of the edit form to edit a user-profile --- app/views/people/show.html.haml | 56 +++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index bf231026f..08f17c523 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -39,7 +39,7 @@ %td= @entry.birthdate.to_date.strftime('%d.%m.%Y') %th.fw-light Nationalität %tr - %td= @entry.nationality2.blank? ? @entry.nationality : "#{@entry.nationality}, #{@entry.nationality2}" + %td= @entry.nationality2.blank? ? ISO3166::Country[@entry.nationality] : "#{ISO3166::Country[@entry.nationality]}, #{ISO3166::Country[@entry.nationality2]}" %th.fw-light Wohnort (Stadt) %tr %td= @entry.location @@ -51,7 +51,57 @@ %td= @entry.shortname %div.w-25 %div.fw-light Sprachen - %div.border.border-dark-subtle.mt-1.p-2 + %div.border.border-dark-subtle.mt-1.p-2.rounded - @entry.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" -= link_to "Show all", people_path \ No newline at end of file += link_to "Show all", people_path + += form_with model: @entry do |form| + %div.d-flex + %div.w-25.pe-5 + %table + %tbody + %th.fw-light Name + %tr + %td= form.text_field :name + %th.fw-light Email + %tr + %td= form.text_field :email + %th.fw-light Abschluss + %tr + %td= form.text_field :title + %th.fw-light Funktionen + - @entry.roles.each do + %tr + %td + %div.border.border-dark-subtle.rounded.p-1 + = form.collection_select :role, Role.order(:name), :id, :name + + %th.fw-light Organisationseinheit + %tr + %td= form.collection_select :department, Department.order(:name), :id, :name + %th.fw-light Firma + %tr + %td= form.collection_select :company, Company.order(:name), :id, :name + %th.fw-light Wohnort (Stadt) + %tr + %td= form.text_field :location + + %div.w-25.pe-5 + %table + %tbody + %th.fw-light Geburtsdatum + %tr + %td= form.date_field :birthdate + %th.fw-light Doppelbürger + %tr + %td= form.check_box :nationality2? + %th.fw-light Erste Nationalität + %tr + %td= form.collection_select :nationality, ISO3166::Country.all, :alpha2, :name + %th.fw-light Zweite Nationalität + %tr + %td= form.collection_select :nationality, ISO3166::Country.all, :alpha2, :name + %th.fw-light Zivilstand + %tr + %td= form.collection_select :marital_status, Person.marital_statuses, :second, :first \ No newline at end of file From bdd96acb33798c52a82a9646fbc85de48a23e25b Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 19 Feb 2024 15:52:32 +0100 Subject: [PATCH 06/80] fix displaying of values in dropdowns, to represent actual state of object and add fields for percentage and level --- app/views/people/show.html.haml | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 08f17c523..9cdab16e3 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -71,18 +71,19 @@ %tr %td= form.text_field :title %th.fw-light Funktionen - - @entry.roles.each do + - @entry.roles.each do |role| %tr %td %div.border.border-dark-subtle.rounded.p-1 - = form.collection_select :role, Role.order(:name), :id, :name - - %th.fw-light Organisationseinheit + = form.collection_select :role_id, Role.order(:name), :id, :name, { selected: role.id } + = form.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level + = form.number_field :percent, step: 1 + %th.fw-light Organisationseinheit : %tr - %td= form.collection_select :department, Department.order(:name), :id, :name + %td= form.collection_select :department_id, Department.order(:name), :id, :name %th.fw-light Firma %tr - %td= form.collection_select :company, Company.order(:name), :id, :name + %td= form.collection_select :company_id, Company.order(:name), :id, :name %th.fw-light Wohnort (Stadt) %tr %td= form.text_field :location @@ -95,13 +96,14 @@ %td= form.date_field :birthdate %th.fw-light Doppelbürger %tr - %td= form.check_box :nationality2? + %td= check_box :has_nationality2?, { checked: @entry.nationality2? } %th.fw-light Erste Nationalität %tr - %td= form.collection_select :nationality, ISO3166::Country.all, :alpha2, :name - %th.fw-light Zweite Nationalität - %tr - %td= form.collection_select :nationality, ISO3166::Country.all, :alpha2, :name + %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name + - if :has_nationality2? + %th.fw-light Zweite Nationalität + %tr + %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name %th.fw-light Zivilstand %tr - %td= form.collection_select :marital_status, Person.marital_statuses, :second, :first \ No newline at end of file + %td= form.collection_select :marital_status, Person.marital_statuses, :second, :first, { selected: Person.marital_statuses[@entry.marital_status] } \ No newline at end of file From 5a90a035ed8251d7f5c1f0bfdff4acac04d8284a Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 20 Feb 2024 09:03:00 +0100 Subject: [PATCH 07/80] label role form fields and correctly display role in overview --- app/views/people/show.html.haml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 9cdab16e3..80d25a401 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -22,9 +22,9 @@ %tr %td= @entry.title %th.fw-light Funktion - - @entry.roles.each do |role| + - @entry.person_roles.each do |person_role| %tr - %td= role.name + %td= "#{person_role.role.name} #{person_role.person_role_level.level} #{person_role.percent.to_i}%" %th.fw-light Organisationseinheit %tr %td= @entry.department.name @@ -39,7 +39,7 @@ %td= @entry.birthdate.to_date.strftime('%d.%m.%Y') %th.fw-light Nationalität %tr - %td= @entry.nationality2.blank? ? ISO3166::Country[@entry.nationality] : "#{ISO3166::Country[@entry.nationality]}, #{ISO3166::Country[@entry.nationality2]}" + %td= @entry.nationality2.blank? ? ISO3166::Country[@entry.nationality] : "#{ISO3166::Country[@entry.nationality]}, #{ISO3166::Country[@entry.nationality2]}" %th.fw-light Wohnort (Stadt) %tr %td= @entry.location @@ -75,9 +75,12 @@ %tr %td %div.border.border-dark-subtle.rounded.p-1 + Rolle = form.collection_select :role_id, Role.order(:name), :id, :name, { selected: role.id } - = form.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level - = form.number_field :percent, step: 1 + %div.d-flex + Stufe + = form.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level + = form.number_field :percent, step: 1 %th.fw-light Organisationseinheit : %tr %td= form.collection_select :department_id, Department.order(:name), :id, :name @@ -96,11 +99,11 @@ %td= form.date_field :birthdate %th.fw-light Doppelbürger %tr - %td= check_box :has_nationality2?, { checked: @entry.nationality2? } + %td= check_box :nationality2?, { checked: @entry.nationality2? } %th.fw-light Erste Nationalität %tr %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name - - if :has_nationality2? + - if @entry.nationality2? %th.fw-light Zweite Nationalität %tr %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name From 7d49266cb995974f6107980edfa77286680a54fe Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 20 Feb 2024 09:53:40 +0100 Subject: [PATCH 08/80] replace @entry with @person after rebase and remove nested_models and permitted_relationships from people controller --- app/controllers/people_controller.rb | 12 +++------ app/views/people/show.html.haml | 38 +++++++++++++--------------- 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 4e4430c0d..f28c7ed60 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -3,15 +3,9 @@ class PeopleController < CrudController include ExportController - # self.permitted_attrs = %i[birthdate location - # marital_status updated_by name nationality nationality2 title - # competence_notes company_id email department_id shortname] - - # self.nested_models = %i[advanced_trainings activities projects - # educations language_skills person_roles - # people_skills categories] - - # self.permitted_relationships = %i[person_roles people_skills] + self.permitted_attrs = %i[birthdate location + marital_status updated_by name nationality nationality2 title + competence_notes company_id email department_id shortname] def show if format_odt? diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 80d25a401..904aecb34 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -1,5 +1,3 @@ -=render partial:"people/search", :locals => {person: @person} - %div %h1 = @person.name @@ -7,56 +5,56 @@ %div.d-flex %div.w-25 - %img.rounded-circle{src: @entry.picture, width: '141', height: '141'} + %img.rounded-circle{src: @person.picture, width: '141', height: '141'} %div.mt-3= link_to "Bearbeiten", edit_person_path %div.w-25.pe-5 %table %tbody %th.fw-light Name %tr - %td= @entry.name + %td= @person.name %th.fw-light Email %tr - %td= @entry.email + %td= @person.email %th.fw-light Abschluss %tr - %td= @entry.title + %td= @person.title %th.fw-light Funktion - - @entry.person_roles.each do |person_role| + - @person.person_roles.each do |person_role| %tr %td= "#{person_role.role.name} #{person_role.person_role_level.level} #{person_role.percent.to_i}%" %th.fw-light Organisationseinheit %tr - %td= @entry.department.name + %td= @person.department.name %th.fw-light Firma %tr - %td= @entry.company.name + %td= @person.company.name %div.w-25.pe-5 %table %tbody %th.fw-light Geburtsdatum %tr - %td= @entry.birthdate.to_date.strftime('%d.%m.%Y') + %td= @person.birthdate.to_date.strftime('%d.%m.%Y') %th.fw-light Nationalität %tr - %td= @entry.nationality2.blank? ? ISO3166::Country[@entry.nationality] : "#{ISO3166::Country[@entry.nationality]}, #{ISO3166::Country[@entry.nationality2]}" + %td= @person.nationality2.blank? ? ISO3166::Country[@person.nationality] : "#{ISO3166::Country[@person.nationality]}, #{ISO3166::Country[@person.nationality2]}" %th.fw-light Wohnort (Stadt) %tr - %td= @entry.location + %td= @person.location %th.fw-light Zivilstand %tr - %td= @entry.marital_status + %td= @person.marital_status %th.fw-light Kürzel %tr - %td= @entry.shortname + %td= @person.shortname %div.w-25 %div.fw-light Sprachen %div.border.border-dark-subtle.mt-1.p-2.rounded - - @entry.language_skills.each do |language| + - @person.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" = link_to "Show all", people_path -= form_with model: @entry do |form| += form_with model: @person do |form| %div.d-flex %div.w-25.pe-5 %table @@ -71,7 +69,7 @@ %tr %td= form.text_field :title %th.fw-light Funktionen - - @entry.roles.each do |role| + - @person.roles.each do |role| %tr %td %div.border.border-dark-subtle.rounded.p-1 @@ -99,14 +97,14 @@ %td= form.date_field :birthdate %th.fw-light Doppelbürger %tr - %td= check_box :nationality2?, { checked: @entry.nationality2? } + %td= check_box :nationality2?, { checked: @person.nationality2? } %th.fw-light Erste Nationalität %tr %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name - - if @entry.nationality2? + - if @person.nationality2? %th.fw-light Zweite Nationalität %tr %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name %th.fw-light Zivilstand %tr - %td= form.collection_select :marital_status, Person.marital_statuses, :second, :first, { selected: Person.marital_statuses[@entry.marital_status] } \ No newline at end of file + %td= form.collection_select :marital_status, Person.marital_statuses, :second, :first, { selected: Person.marital_statuses[@person.marital_status] } \ No newline at end of file From 6feae9f4ced91f867b9fbfd72f68ea60e8f13a23 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 20 Feb 2024 13:47:52 +0100 Subject: [PATCH 09/80] move edit form to edit route and add turbo frame that loads edit form in overview when edit is clicked and remove absolute width from account overview tables --- app/views/people/edit.html.haml | 63 ++++++++++++++++++ app/views/people/show.html.haml | 114 +++++++++----------------------- 2 files changed, 93 insertions(+), 84 deletions(-) create mode 100644 app/views/people/edit.html.haml diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml new file mode 100644 index 000000000..c7d223efd --- /dev/null +++ b/app/views/people/edit.html.haml @@ -0,0 +1,63 @@ +%turbo-frame{id: "#{dom_id @person}"} + = form_with model: @person do |form| + %div.d-flex + %div + %img.rounded-circle{src: @person.picture, width: '141', height: '141'} + %div.pe-5 + %table + %tbody + %th.fw-light Name + %tr + %td= form.text_field :name, class: "w-100" + %th.fw-light Email + %tr + %td= form.text_field :email + %th.fw-light Abschluss + %tr + %td= form.text_field :title + %th.fw-light Funktionen + - @person.roles.each do |role| + %tr + %td + %div.border.border-dark-subtle.rounded.p-1 + Rolle + = form.collection_select :role_id, Role.order(:name), :id, :name, { selected: role.id } + %div.d-flex + Stufe + = form.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level + = form.number_field :percent, step: 1 + %th.fw-light Organisationseinheit : + %tr + %td= form.collection_select :department_id, Department.order(:name), :id, :name + %th.fw-light Firma + %tr + %td= form.collection_select :company_id, Company.order(:name), :id, :name + %th.fw-light Wohnort (Stadt) + %tr + %td= form.text_field :location + + %div.pe-5 + %table + %tbody + %th.fw-light Geburtsdatum + %tr + %td= form.date_field :birthdate + %th.fw-light Doppelbürger + %tr + %td= check_box :nationality2?, { checked: @person.nationality2? } + %th.fw-light Erste Nationalität + %tr + %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name + - if @person.nationality2? + %th.fw-light Zweite Nationalität + %tr + %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name + %th.fw-light Zivilstand + %tr + %td= form.collection_select :marital_status, Person.marital_statuses, :second, :first, { selected: Person.marital_statuses[@person.marital_status] } + %div + %div.fw-light Sprachen + %div.border.border-dark-subtle.mt-1.p-2.rounded + - @person.language_skills.each do |language| + %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" + = link_to "Abbrechen", person_path \ No newline at end of file diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 904aecb34..a631ff647 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -3,108 +3,54 @@ = @person.name 's Profile -%div.d-flex - %div.w-25 - %img.rounded-circle{src: @person.picture, width: '141', height: '141'} - %div.mt-3= link_to "Bearbeiten", edit_person_path - %div.w-25.pe-5 - %table - %tbody - %th.fw-light Name - %tr - %td= @person.name - %th.fw-light Email - %tr - %td= @person.email - %th.fw-light Abschluss - %tr - %td= @person.title - %th.fw-light Funktion - - @person.person_roles.each do |person_role| - %tr - %td= "#{person_role.role.name} #{person_role.person_role_level.level} #{person_role.percent.to_i}%" - %th.fw-light Organisationseinheit - %tr - %td= @person.department.name - %th.fw-light Firma - %tr - %td= @person.company.name - %div.w-25.pe-5 - %table - %tbody - %th.fw-light Geburtsdatum - %tr - %td= @person.birthdate.to_date.strftime('%d.%m.%Y') - %th.fw-light Nationalität - %tr - %td= @person.nationality2.blank? ? ISO3166::Country[@person.nationality] : "#{ISO3166::Country[@person.nationality]}, #{ISO3166::Country[@person.nationality2]}" - %th.fw-light Wohnort (Stadt) - %tr - %td= @person.location - %th.fw-light Zivilstand - %tr - %td= @person.marital_status - %th.fw-light Kürzel - %tr - %td= @person.shortname - %div.w-25 - %div.fw-light Sprachen - %div.border.border-dark-subtle.mt-1.p-2.rounded - - @person.language_skills.each do |language| - %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" -= link_to "Show all", people_path - -= form_with model: @person do |form| +%turbo-frame{id: "#{dom_id @person}"} %div.d-flex - %div.w-25.pe-5 + %div + %img.rounded-circle{src: @person.picture, width: '141', height: '141'} + %div.mt-3= link_to "Bearbeiten", edit_person_path + %div.pe-5 %table %tbody %th.fw-light Name %tr - %td= form.text_field :name + %td= @person.name %th.fw-light Email %tr - %td= form.text_field :email + %td= @person.email %th.fw-light Abschluss %tr - %td= form.text_field :title - %th.fw-light Funktionen - - @person.roles.each do |role| + %td= @person.title + %th.fw-light Funktion + - @person.person_roles.each do |person_role| %tr - %td - %div.border.border-dark-subtle.rounded.p-1 - Rolle - = form.collection_select :role_id, Role.order(:name), :id, :name, { selected: role.id } - %div.d-flex - Stufe - = form.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level - = form.number_field :percent, step: 1 - %th.fw-light Organisationseinheit : + %td= "#{person_role.role.name} #{person_role.person_role_level.level} #{person_role.percent.to_i}%" + %th.fw-light Organisationseinheit %tr - %td= form.collection_select :department_id, Department.order(:name), :id, :name + %td= @person.department.name %th.fw-light Firma %tr - %td= form.collection_select :company_id, Company.order(:name), :id, :name - %th.fw-light Wohnort (Stadt) - %tr - %td= form.text_field :location - - %div.w-25.pe-5 + %td= @person.company.name + %div.pe-5 %table %tbody %th.fw-light Geburtsdatum %tr - %td= form.date_field :birthdate - %th.fw-light Doppelbürger + %td= @person.birthdate.to_date.strftime('%d.%m.%Y') + %th.fw-light Nationalität %tr - %td= check_box :nationality2?, { checked: @person.nationality2? } - %th.fw-light Erste Nationalität + %td= @person.nationality2.blank? ? ISO3166::Country[@person.nationality] : "#{ISO3166::Country[@person.nationality]}, #{ISO3166::Country[@person.nationality2]}" + %th.fw-light Wohnort (Stadt) %tr - %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name - - if @person.nationality2? - %th.fw-light Zweite Nationalität - %tr - %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name + %td= @person.location %th.fw-light Zivilstand %tr - %td= form.collection_select :marital_status, Person.marital_statuses, :second, :first, { selected: Person.marital_statuses[@person.marital_status] } \ No newline at end of file + %td= @person.marital_status + %th.fw-light Kürzel + %tr + %td= @person.shortname + %div + %div.fw-light Sprachen + %div.border.border-dark-subtle.mt-1.p-2.rounded + - @person.language_skills.each do |language| + %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" + = link_to "Show all", people_path \ No newline at end of file From a2a154ea59a1f728a3301064d04817b472a0b0f5 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 20 Feb 2024 16:02:09 +0100 Subject: [PATCH 10/80] fix alignment of tables, set width of input fields to match table width, add save button and fix saving of form --- app/views/people/edit.html.haml | 15 ++++++++------- app/views/people/show.html.haml | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index c7d223efd..71a38debf 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -1,9 +1,9 @@ %turbo-frame{id: "#{dom_id @person}"} = form_with model: @person do |form| - %div.d-flex - %div - %img.rounded-circle{src: @person.picture, width: '141', height: '141'} + %div.d-flex.justify-content-between %div.pe-5 + %img.rounded-circle{src: @person.picture, width: '141', height: '141'} + %div.pe-5.d-flex %table %tbody %th.fw-light Name @@ -11,10 +11,10 @@ %td= form.text_field :name, class: "w-100" %th.fw-light Email %tr - %td= form.text_field :email + %td= form.text_field :email, class: "w-100" %th.fw-light Abschluss %tr - %td= form.text_field :title + %td= form.text_field :title, class: "w-100" %th.fw-light Funktionen - @person.roles.each do |role| %tr @@ -34,7 +34,7 @@ %td= form.collection_select :company_id, Company.order(:name), :id, :name %th.fw-light Wohnort (Stadt) %tr - %td= form.text_field :location + %td= form.text_field :location, class: "w-100" %div.pe-5 %table @@ -54,10 +54,11 @@ %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name %th.fw-light Zivilstand %tr - %td= form.collection_select :marital_status, Person.marital_statuses, :second, :first, { selected: Person.marital_statuses[@person.marital_status] } + %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: Person.marital_statuses[@person.marital_status] } %div %div.fw-light Sprachen %div.border.border-dark-subtle.mt-1.p-2.rounded - @person.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" + = form.submit :Submit, class: "btn" = link_to "Abbrechen", person_path \ No newline at end of file diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index a631ff647..7eddbbfc5 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -4,7 +4,7 @@ 's Profile %turbo-frame{id: "#{dom_id @person}"} - %div.d-flex + %div.d-flex.justify-content-between %div %img.rounded-circle{src: @person.picture, width: '141', height: '141'} %div.mt-3= link_to "Bearbeiten", edit_person_path From 46055cb2783bda78f1fa03ea606a4588a1edb2a0 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 23 Feb 2024 08:33:50 +0100 Subject: [PATCH 11/80] style edit form to use bootstrap form fields --- app/views/people/edit.html.haml | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index 71a38debf..29e6e6050 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -8,57 +8,58 @@ %tbody %th.fw-light Name %tr - %td= form.text_field :name, class: "w-100" + %td= form.text_field :name, class: "w-100 form-control" %th.fw-light Email %tr - %td= form.text_field :email, class: "w-100" + %td= form.text_field :email, class: "w-100, form-control" %th.fw-light Abschluss %tr - %td= form.text_field :title, class: "w-100" + %td= form.text_field :title, class: "w-100, form-control" %th.fw-light Funktionen - @person.roles.each do |role| %tr %td %div.border.border-dark-subtle.rounded.p-1 Rolle - = form.collection_select :role_id, Role.order(:name), :id, :name, { selected: role.id } - %div.d-flex + = form.collection_select :role_ids, Role.order(:name), :id, :name, { selected: role.id }, class: "form-select w-100" + %div Stufe - = form.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level - = form.number_field :percent, step: 1 + %div.d-flex + = form.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" + = form.number_field :percent, step: 1, class: "form-control w-50" %th.fw-light Organisationseinheit : %tr - %td= form.collection_select :department_id, Department.order(:name), :id, :name + %td= form.collection_select :department_id, Department.order(:name), :id, :name, {}, class: "form-select w-100" %th.fw-light Firma %tr - %td= form.collection_select :company_id, Company.order(:name), :id, :name + %td= form.collection_select :company_id, Company.order(:name), :id, :name, {}, class: "form-select w-100" %th.fw-light Wohnort (Stadt) %tr - %td= form.text_field :location, class: "w-100" + %td= form.text_field :location, class: "form-control w-100" %div.pe-5 %table %tbody %th.fw-light Geburtsdatum %tr - %td= form.date_field :birthdate + %td= form.date_field :birthdate, class: "form-control w-100" %th.fw-light Doppelbürger %tr %td= check_box :nationality2?, { checked: @person.nationality2? } %th.fw-light Erste Nationalität %tr - %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name + %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" - if @person.nationality2? %th.fw-light Zweite Nationalität %tr - %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name + %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" %th.fw-light Zivilstand %tr - %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: Person.marital_statuses[@person.marital_status] } + %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: Person.marital_statuses[@person.marital_status] }, class: "form-select w-100" %div %div.fw-light Sprachen %div.border.border-dark-subtle.mt-1.p-2.rounded - @person.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" - = form.submit :Submit, class: "btn" + = form.submit :Submit = link_to "Abbrechen", person_path \ No newline at end of file From 968d06ad5a69ceea236af6047ccaa4585b5b21cc Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 23 Feb 2024 09:08:57 +0100 Subject: [PATCH 12/80] adjust font-weights of edit form --- app/views/people/edit.html.haml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index 29e6e6050..351851ad3 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -6,60 +6,60 @@ %div.pe-5.d-flex %table %tbody - %th.fw-light Name + %th.fw-normal Name %tr %td= form.text_field :name, class: "w-100 form-control" - %th.fw-light Email + %th.fw-normal Email %tr %td= form.text_field :email, class: "w-100, form-control" - %th.fw-light Abschluss + %th.fw-normal Abschluss %tr %td= form.text_field :title, class: "w-100, form-control" - %th.fw-light Funktionen + %th.fw-normal Funktionen - @person.roles.each do |role| %tr %td - %div.border.border-dark-subtle.rounded.p-1 + %div.border.border-dark-subtle.rounded.p-1.fw-light Rolle = form.collection_select :role_ids, Role.order(:name), :id, :name, { selected: role.id }, class: "form-select w-100" %div Stufe - %div.d-flex + %div.d-flex.fw-light = form.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" = form.number_field :percent, step: 1, class: "form-control w-50" - %th.fw-light Organisationseinheit : + %th.fw-normal Organisationseinheit : %tr %td= form.collection_select :department_id, Department.order(:name), :id, :name, {}, class: "form-select w-100" - %th.fw-light Firma + %th.fw-normal Firma %tr %td= form.collection_select :company_id, Company.order(:name), :id, :name, {}, class: "form-select w-100" - %th.fw-light Wohnort (Stadt) + %th.fw-normal Wohnort (Stadt) %tr %td= form.text_field :location, class: "form-control w-100" %div.pe-5 %table %tbody - %th.fw-light Geburtsdatum + %th.fw-normal Geburtsdatum %tr %td= form.date_field :birthdate, class: "form-control w-100" - %th.fw-light Doppelbürger + %th.fw-normal Doppelbürger %tr %td= check_box :nationality2?, { checked: @person.nationality2? } - %th.fw-light Erste Nationalität + %th.fw-normal Erste Nationalität %tr %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" - if @person.nationality2? - %th.fw-light Zweite Nationalität + %th.fw-normal Zweite Nationalität %tr %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" - %th.fw-light Zivilstand + %th.fw-normal Zivilstand %tr %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: Person.marital_statuses[@person.marital_status] }, class: "form-select w-100" %div - %div.fw-light Sprachen + %div.fw-normal Sprachen %div.border.border-dark-subtle.mt-1.p-2.rounded - @person.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" - = form.submit :Submit + = form.submit :Speichern, class: "btn btn-primary" = link_to "Abbrechen", person_path \ No newline at end of file From bee42d0b934b8868998f80e9a2ede86099d1799a Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 23 Feb 2024 11:15:17 +0100 Subject: [PATCH 13/80] create controller method to load correct picture path, add uploads to assets path, move cancel button on edit view and fix view not loading when department name missing --- app/controllers/people_controller.rb | 10 ++++++++++ app/views/people/edit.html.haml | 7 ++++--- app/views/people/show.html.haml | 4 ++-- config/application.rb | 3 ++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index f28c7ed60..7b7d107ae 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -3,6 +3,8 @@ class PeopleController < CrudController include ExportController + helper_method :picture_path + self.permitted_attrs = %i[birthdate location marital_status updated_by name nationality nationality2 title competence_notes company_id email department_id shortname] @@ -40,4 +42,12 @@ def export type: 'application/vnd.oasis.opendocument.text', disposition: content_disposition('attachment', filename) end + + def picture_path + if @person.picture.file + @person.picture.url + else + "/default_avatar.png" + end + end end diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index 351851ad3..a3574b797 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -2,7 +2,8 @@ = form_with model: @person do |form| %div.d-flex.justify-content-between %div.pe-5 - %img.rounded-circle{src: @person.picture, width: '141', height: '141'} + %img.rounded-circle{src: picture_path, width: '141', height: '141'} + -# = form.file_field :picture %div.pe-5.d-flex %table %tbody @@ -61,5 +62,5 @@ %div.border.border-dark-subtle.mt-1.p-2.rounded - @person.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" - = form.submit :Speichern, class: "btn btn-primary" - = link_to "Abbrechen", person_path \ No newline at end of file + = form.submit :Speichern, class: "btn btn-primary me-3" + = link_to "Abbrechen", person_path \ No newline at end of file diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 7eddbbfc5..7fe399b81 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -6,7 +6,7 @@ %turbo-frame{id: "#{dom_id @person}"} %div.d-flex.justify-content-between %div - %img.rounded-circle{src: @person.picture, width: '141', height: '141'} + -# %img.rounded-circle{src: @person.picture, width: '141', height: '141'} %div.mt-3= link_to "Bearbeiten", edit_person_path %div.pe-5 %table @@ -26,7 +26,7 @@ %td= "#{person_role.role.name} #{person_role.person_role_level.level} #{person_role.percent.to_i}%" %th.fw-light Organisationseinheit %tr - %td= @person.department.name + %td= @person.department&.name %th.fw-light Firma %tr %td= @person.company.name diff --git a/config/application.rb b/config/application.rb index d638d4fbb..0f9850ec2 100644 --- a/config/application.rb +++ b/config/application.rb @@ -46,6 +46,7 @@ def keycloak_disabled? KEYCLOAK_ENV_VARS.none? { |e| ENV[e].present? } && ENV['KEYCLOAK_DISABLED'].present? end - + config.assets.enabled = true + config.assets.paths << Rails.root.join("uploads") end end From 37ba30f2170774e961844d4fef88b2befd5c9d72 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 23 Feb 2024 11:23:16 +0100 Subject: [PATCH 14/80] add default avatar to public directory --- public/default_avatar.png | Bin 0 -> 25878 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/default_avatar.png diff --git a/public/default_avatar.png b/public/default_avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..75749ead5d91dc843f6b709ded013486eb7614fa GIT binary patch literal 25878 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 literal 0 HcmV?d00001 From d287a2cc63be2aa8d16dad87812959f4e56cd282 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 23 Feb 2024 12:45:02 +0100 Subject: [PATCH 15/80] make view display nil properties of person as -, create picture controller and remove picture_path method from people_controller, use new picture controller to load pictures correctly in view --- app/controllers/people_controller.rb | 10 ---------- app/controllers/picture_controller.rb | 6 ++++++ app/helpers/picture_helper.rb | 2 ++ app/views/people/edit.html.haml | 4 ++-- app/views/people/show.html.haml | 20 +++++++++++++++----- public/default_avatar.png | Bin 25878 -> 0 bytes spec/helpers/picture_helper_spec.rb | 15 +++++++++++++++ spec/requests/picture_request_spec.rb | 5 +++++ 8 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 app/controllers/picture_controller.rb create mode 100644 app/helpers/picture_helper.rb delete mode 100644 public/default_avatar.png create mode 100644 spec/helpers/picture_helper_spec.rb create mode 100644 spec/requests/picture_request_spec.rb diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 7b7d107ae..f28c7ed60 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -3,8 +3,6 @@ class PeopleController < CrudController include ExportController - helper_method :picture_path - self.permitted_attrs = %i[birthdate location marital_status updated_by name nationality nationality2 title competence_notes company_id email department_id shortname] @@ -42,12 +40,4 @@ def export type: 'application/vnd.oasis.opendocument.text', disposition: content_disposition('attachment', filename) end - - def picture_path - if @person.picture.file - @person.picture.url - else - "/default_avatar.png" - end - end end diff --git a/app/controllers/picture_controller.rb b/app/controllers/picture_controller.rb new file mode 100644 index 000000000..a523f6b05 --- /dev/null +++ b/app/controllers/picture_controller.rb @@ -0,0 +1,6 @@ +class PictureController < ApplicationController + def show + picture_url = @person.picture.file.nil? ? default_avatar_path : @person.picture.url + send_file(picture_url, disposition: 'inline') + end +end diff --git a/app/helpers/picture_helper.rb b/app/helpers/picture_helper.rb new file mode 100644 index 000000000..42cb833cd --- /dev/null +++ b/app/helpers/picture_helper.rb @@ -0,0 +1,2 @@ +module PictureHelper +end diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index a3574b797..d1c75c1a2 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -2,8 +2,8 @@ = form_with model: @person do |form| %div.d-flex.justify-content-between %div.pe-5 - %img.rounded-circle{src: picture_path, width: '141', height: '141'} - -# = form.file_field :picture + %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} + = form.file_field :picture %div.pe-5.d-flex %table %tbody diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 7fe399b81..eb063c237 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -6,7 +6,7 @@ %turbo-frame{id: "#{dom_id @person}"} %div.d-flex.justify-content-between %div - -# %img.rounded-circle{src: @person.picture, width: '141', height: '141'} + %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} %div.mt-3= link_to "Bearbeiten", edit_person_path %div.pe-5 %table @@ -21,12 +21,19 @@ %tr %td= @person.title %th.fw-light Funktion - - @person.person_roles.each do |person_role| + - unless @person.person_roles.empty? + - @person.person_roles.each do |person_role| + %tr + %td= "#{person_role.role.name} #{person_role.person_role_level.level} #{person_role.percent.to_i}%" + - else %tr - %td= "#{person_role.role.name} #{person_role.person_role_level.level} #{person_role.percent.to_i}%" + %td - %th.fw-light Organisationseinheit %tr - %td= @person.department&.name + - unless @person.department.nil? + %td= @person.department.name + - else + %td - %th.fw-light Firma %tr %td= @person.company.name @@ -47,7 +54,10 @@ %td= @person.marital_status %th.fw-light Kürzel %tr - %td= @person.shortname + - unless @person.shortname.nil? + %td= @person.shortname + - else + %td - %div %div.fw-light Sprachen %div.border.border-dark-subtle.mt-1.p-2.rounded diff --git a/public/default_avatar.png b/public/default_avatar.png deleted file mode 100644 index 75749ead5d91dc843f6b709ded013486eb7614fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25878 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 diff --git a/spec/helpers/picture_helper_spec.rb b/spec/helpers/picture_helper_spec.rb new file mode 100644 index 000000000..1c022316c --- /dev/null +++ b/spec/helpers/picture_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the PictureHelper. For example: +# +# describe PictureHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe PictureHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/picture_request_spec.rb b/spec/requests/picture_request_spec.rb new file mode 100644 index 000000000..a17fc15a5 --- /dev/null +++ b/spec/requests/picture_request_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe "Pictures", type: :request do + +end From 15c315e8c6df83a7426af763ee8ed9c988199eb8 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 23 Feb 2024 13:03:07 +0100 Subject: [PATCH 16/80] add picture to permitted attrs --- app/controllers/people_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index f28c7ed60..a2fb35ce4 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -5,7 +5,7 @@ class PeopleController < CrudController self.permitted_attrs = %i[birthdate location marital_status updated_by name nationality nationality2 title - competence_notes company_id email department_id shortname] + competence_notes company_id email department_id shortname picture] def show if format_odt? From e958f7b414a145bd88859034b3114bebf1b66ce9 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 23 Feb 2024 15:15:30 +0100 Subject: [PATCH 17/80] add dummy role adding button in person edit view and make marital status dropdown have correct value selected on edit --- app/views/people/edit.html.haml | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index d1c75c1a2..0e64e4bcf 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -17,18 +17,22 @@ %tr %td= form.text_field :title, class: "w-100, form-control" %th.fw-normal Funktionen - - @person.roles.each do |role| + %div + - @person.roles.each do |role| + %tr + %td + %div.border.border-dark-subtle.rounded.p-1.fw-light + Rolle + = form.collection_select :role_ids, Role.order(:name), :id, :name, { selected: role.id }, class: "form-select w-100" + %div + Stufe + %div.d-flex.fw-light + = form.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" + = form.number_field :percent, step: 1, class: "form-control w-50" %tr %td - %div.border.border-dark-subtle.rounded.p-1.fw-light - Rolle - = form.collection_select :role_ids, Role.order(:name), :id, :name, { selected: role.id }, class: "form-select w-100" - %div - Stufe - %div.d-flex.fw-light - = form.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" - = form.number_field :percent, step: 1, class: "form-control w-50" - %th.fw-normal Organisationseinheit : + %button.btn.btn-link Neue Funktion + %th.fw-normal Organisationseinheit %tr %td= form.collection_select :department_id, Department.order(:name), :id, :name, {}, class: "form-select w-100" %th.fw-normal Firma @@ -56,7 +60,7 @@ %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" %th.fw-normal Zivilstand %tr - %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: Person.marital_statuses[@person.marital_status] }, class: "form-select w-100" + %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: @person.marital_status }, class: "form-select w-100" %div %div.fw-normal Sprachen %div.border.border-dark-subtle.mt-1.p-2.rounded From 789f0f976b8cb8dd676094f339fd7df0336ab25a Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 23 Feb 2024 15:34:14 +0100 Subject: [PATCH 18/80] start working on updating roles by renaming the params in the form and overriding the update method in the controller --- app/controllers/people_controller.rb | 8 ++++++++ app/views/people/edit.html.haml | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index a2fb35ce4..b22287abe 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -7,6 +7,14 @@ class PeopleController < CrudController marital_status updated_by name nationality nationality2 title competence_notes company_id email department_id shortname picture] + def update + binding.pry + person = params[:person] + PersonRole.create(person_id: @person.id, role_id: person.role_id, percent: ("%e" % person.role_percent), + person_role_level_id: person.role_level_id) + super + end + def show if format_odt? export diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index 0e64e4bcf..0718b3b0e 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -23,12 +23,12 @@ %td %div.border.border-dark-subtle.rounded.p-1.fw-light Rolle - = form.collection_select :role_ids, Role.order(:name), :id, :name, { selected: role.id }, class: "form-select w-100" + = form.collection_select :role_id, Role.order(:name), :id, :name, { selected: role.id }, class: "form-select w-100" %div Stufe %div.d-flex.fw-light - = form.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" - = form.number_field :percent, step: 1, class: "form-control w-50" + = form.collection_select :role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" + = form.number_field :role_percent, step: 1, class: "form-control w-50" %tr %td %button.btn.btn-link Neue Funktion @@ -50,7 +50,7 @@ %td= form.date_field :birthdate, class: "form-control w-100" %th.fw-normal Doppelbürger %tr - %td= check_box :nationality2?, { checked: @person.nationality2? } + %td= check_box :has_nationality2, {}, checked: @person.nationality2? %th.fw-normal Erste Nationalität %tr %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" From 8219d407d3343d8511d9d0b268dbbf6aec3defa9 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 26 Feb 2024 15:51:16 +0100 Subject: [PATCH 19/80] rewrite profile to use fields_for instead of a normal for loop, for saving new roles --- app/controllers/people_controller.rb | 13 ++++++++----- app/models/person.rb | 1 + app/views/people/edit.html.haml | 8 ++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index b22287abe..65ed8e48d 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -5,13 +5,16 @@ class PeopleController < CrudController self.permitted_attrs = %i[birthdate location marital_status updated_by name nationality nationality2 title - competence_notes company_id email department_id shortname picture] + competence_notes company_id email department_id shortname picture + person_roles_attributes] + + def new + super + @person.roles.build + end def update - binding.pry - person = params[:person] - PersonRole.create(person_id: @person.id, role_id: person.role_id, percent: ("%e" % person.role_percent), - person_role_level_id: person.role_level_id) + @person.roles.build if @person.roles.empty? super end diff --git a/app/models/person.rb b/app/models/person.rb index 85d09d036..a99e11bb4 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -39,6 +39,7 @@ class Person < ApplicationRecord has_many :expertise_topics, through: :expertise_topic_skill_values has_many :language_skills, dependent: :delete_all has_many :person_roles, dependent: :destroy + accepts_nested_attributes_for :person_roles, allow_destroy: true has_many :people_skills, dependent: :destroy has_many :skills, through: :people_skills has_many :roles, through: :person_roles diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index 0718b3b0e..7f7895fb7 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -18,17 +18,17 @@ %td= form.text_field :title, class: "w-100, form-control" %th.fw-normal Funktionen %div - - @person.roles.each do |role| + = form.fields_for :person_roles do |person_role| %tr %td %div.border.border-dark-subtle.rounded.p-1.fw-light Rolle - = form.collection_select :role_id, Role.order(:name), :id, :name, { selected: role.id }, class: "form-select w-100" + = person_role.collection_select :role_id, Role.order(:name), :id, :name, {}, class: "form-select w-100" %div Stufe %div.d-flex.fw-light - = form.collection_select :role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" - = form.number_field :role_percent, step: 1, class: "form-control w-50" + = person_role.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" + = person_role.number_field :percent, step: 1, class: "form-control w-50" %tr %td %button.btn.btn-link Neue Funktion From a3dfe6b27ce664740486e097f2808c73e087662e Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 27 Feb 2024 08:52:21 +0100 Subject: [PATCH 20/80] add person_roles_attributes to permitted attributes --- app/controllers/people_controller.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 65ed8e48d..5f4ad974f 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -3,10 +3,10 @@ class PeopleController < CrudController include ExportController - self.permitted_attrs = %i[birthdate location - marital_status updated_by name nationality nationality2 title - competence_notes company_id email department_id shortname picture - person_roles_attributes] + self.permitted_attrs = [:birthdate, :location, + :marital_status, :updated_by, :name, :nationality, :nationality2, :title, + :competence_notes, :company_id, :email, :department_id, :shortname, :picture, + { person_roles_attributes: [:role_id, :person_role_level_id, :percent, :id] }] def new super From 9daf507d97291be5d6a9f518cf6b6b9ab8d6ebb3 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 27 Feb 2024 10:46:24 +0100 Subject: [PATCH 21/80] make edit view conditionally display the second nationality dropdown depending on checkbox state --- app/controllers/people_controller.rb | 3 +++ app/javascript/controllers/index.js | 3 ++- .../controllers/nationality_two_controller.js | 18 ++++++++++++++++++ app/views/people/edit.html.haml | 9 ++++----- 4 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 app/javascript/controllers/nationality_two_controller.js diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 5f4ad974f..7c929c19b 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -15,6 +15,9 @@ def new def update @person.roles.build if @person.roles.empty? + if params['has_nationality2']['{}'].to_i.zero? + params['person']['nationality2'] = nil + end super end diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index d2fdc8dca..1e35601b8 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -6,6 +6,7 @@ import { application } from "./application" import DropdownLinksController from "./dropdown_controller" application.register("dropdown", DropdownLinksController) - import RemoteModalController from "./remote_modal_controller" application.register("remote-modal", RemoteModalController) +import NationalityTwoController from "./nationality_two_controller" +application.register("nationality-two", NationalityTwoController) \ No newline at end of file diff --git a/app/javascript/controllers/nationality_two_controller.js b/app/javascript/controllers/nationality_two_controller.js new file mode 100644 index 000000000..1626e5d70 --- /dev/null +++ b/app/javascript/controllers/nationality_two_controller.js @@ -0,0 +1,18 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + setVisibility() { + const natTwoElements = document.getElementsByClassName('nationality-two') + const natTwoCheckbox = document.getElementById('nat-two-checkbox') + for(const element of natTwoElements) { + !natTwoCheckbox.checked ? element.classList.add('d-none') : element.classList.remove('d-none') + } + } + + connect() { + this.setVisibility(); + } + nationalityTwoVisible() { + this.setVisibility() + } +} \ No newline at end of file diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index 7f7895fb7..b2e32a82f 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -50,14 +50,13 @@ %td= form.date_field :birthdate, class: "form-control w-100" %th.fw-normal Doppelbürger %tr - %td= check_box :has_nationality2, {}, checked: @person.nationality2? + %td{"data-controller"=>"nationality-two"}= check_box :has_nationality2, {}, {"checked" => @person.nationality2?, "data-action" => "nationality-two#nationalityTwoVisible", "id" => "nat-two-checkbox"} %th.fw-normal Erste Nationalität %tr %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" - - if @person.nationality2? - %th.fw-normal Zweite Nationalität - %tr - %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" + %th.fw-normal.nationality-two Zweite Nationalität + %tr.nationality-two + %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" %th.fw-normal Zivilstand %tr %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: @person.marital_status }, class: "form-select w-100" From 118c9a0fd5296e26aead84f50f5a4374b3a765ea Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 27 Feb 2024 11:58:04 +0100 Subject: [PATCH 22/80] make person overview and edit view responsive --- app/views/people/edit.html.haml | 7 ++++--- app/views/people/show.html.haml | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index b2e32a82f..ea4707cde 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -1,6 +1,6 @@ %turbo-frame{id: "#{dom_id @person}"} = form_with model: @person do |form| - %div.d-flex.justify-content-between + %div.d-flex.justify-content-between.flex-lg-row.flex-md-row.flex-sm-column.flex-column.overflow-scroll %div.pe-5 %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} = form.file_field :picture @@ -65,5 +65,6 @@ %div.border.border-dark-subtle.mt-1.p-2.rounded - @person.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" - = form.submit :Speichern, class: "btn btn-primary me-3" - = link_to "Abbrechen", person_path \ No newline at end of file + %div.mt-3 + = form.submit :Speichern, class: "btn btn-primary me-3" + = link_to "Abbrechen", person_path \ No newline at end of file diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index eb063c237..3394ab5ec 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -4,7 +4,7 @@ 's Profile %turbo-frame{id: "#{dom_id @person}"} - %div.d-flex.justify-content-between + %div.d-flex.justify-content-between.flex-lg-row.flex-md-row.flex-sm-column.flex-column.overflow-scroll %div %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} %div.mt-3= link_to "Bearbeiten", edit_person_path From 12ac44ab5c31357cc5ddada49d68f379327d8116 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 27 Feb 2024 13:31:07 +0100 Subject: [PATCH 23/80] remove overflow scroll from person overview and edit view --- app/views/people/edit.html.haml | 2 +- app/views/people/show.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index ea4707cde..a2c42db3d 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -1,6 +1,6 @@ %turbo-frame{id: "#{dom_id @person}"} = form_with model: @person do |form| - %div.d-flex.justify-content-between.flex-lg-row.flex-md-row.flex-sm-column.flex-column.overflow-scroll + %div.d-flex.justify-content-between.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.pe-5 %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} = form.file_field :picture diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 3394ab5ec..f2fefca11 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -4,7 +4,7 @@ 's Profile %turbo-frame{id: "#{dom_id @person}"} - %div.d-flex.justify-content-between.flex-lg-row.flex-md-row.flex-sm-column.flex-column.overflow-scroll + %div.d-flex.justify-content-between.flex-lg-row.flex-md-row.flex-sm-column.flex-column %div %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} %div.mt-3= link_to "Bearbeiten", edit_person_path From 10928cc88d2deafc37b46c8e3a2fbb2b1e09051e Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 27 Feb 2024 15:42:40 +0100 Subject: [PATCH 24/80] move fields of role form to partial and start writing logic to create new roles --- app/controllers/people_controller.rb | 2 +- app/helpers/role_form_helper.rb | 18 ++++++++++ app/javascript/nested-forms/addFields.js | 36 +++++++++++++++++++ .../people/_person_role_fields.html.haml | 9 +++++ app/views/people/edit.html.haml | 15 +++----- 5 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 app/helpers/role_form_helper.rb create mode 100644 app/javascript/nested-forms/addFields.js create mode 100644 app/views/people/_person_role_fields.html.haml diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 7c929c19b..96a4df3bf 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -6,7 +6,7 @@ class PeopleController < CrudController self.permitted_attrs = [:birthdate, :location, :marital_status, :updated_by, :name, :nationality, :nationality2, :title, :competence_notes, :company_id, :email, :department_id, :shortname, :picture, - { person_roles_attributes: [:role_id, :person_role_level_id, :percent, :id] }] + { person_roles_attributes: [:role_id, :person_role_level_id, :percent, :id, :_destroy] }] def new super diff --git a/app/helpers/role_form_helper.rb b/app/helpers/role_form_helper.rb new file mode 100644 index 000000000..94a4e73c5 --- /dev/null +++ b/app/helpers/role_form_helper.rb @@ -0,0 +1,18 @@ +module RoleFormHelper + def link_to_add_role(name, form, association) + new_role = form.object.send(association).klass.new + id = new_role.object_id + fields = form.fields_for(association, new_role, child_index: id) do |builder| + render("#{association.to_s.singularize}_fields", form: builder) + end + link_to( + name, + '#', + class: 'add_fields', + data: { + id: id, + fields: fields.gsub("\n", '') + } + ) + end +end \ No newline at end of file diff --git a/app/javascript/nested-forms/addFields.js b/app/javascript/nested-forms/addFields.js new file mode 100644 index 000000000..c7893c1de --- /dev/null +++ b/app/javascript/nested-forms/addFields.js @@ -0,0 +1,36 @@ +class addFields { + // This executes when the function is instantiated. + constructor() { + this.links = document.querySelectorAll(".add_fields"); + this.iterateLinks(); + } + + iterateLinks() { + // If there are no links on the page, stop the function from executing. + if (this.links.length === 0) return; + // Loop over each link on the page. A page could have multiple nested forms. + this.links.forEach((link) => { + link.addEventListener("click", (e) => { + this.handleClick(link, e); + }); + }); + } + + handleClick(link, e) { + // Stop the function from executing if a link or event were not passed into the function. + if (!link || !e) return; + // Prevent the browser from following the URL. + e.preventDefault(); + // Save a unique timestamp to ensure the key of the associated array is unique. + let time = new Date().getTime(); + // Save the data id attribute into a variable. This corresponds to `new_object.object_id`. + let linkId = link.dataset.id; + // Create a new regular expression needed to find any instance of the `new_object.object_id` used in the fields data attribute if there's a value in `linkId`. + let regexp = linkId ? new RegExp(linkId, "g") : null; + // Replace all instances of the `new_object.object_id` with `time`, and save markup into a variable if there's a value in `regexp`. + let newFields = regexp ? link.dataset.fields.replace(regexp, time) : null; + // Add the new markup to the form if there are fields to add. + newFields ? link.insertAdjacentHTML("beforebegin", newFields) : null; + } +} +window.addEventListener("turbolinks:load", () => new addFields()); \ No newline at end of file diff --git a/app/views/people/_person_role_fields.html.haml b/app/views/people/_person_role_fields.html.haml new file mode 100644 index 000000000..a74093fe8 --- /dev/null +++ b/app/views/people/_person_role_fields.html.haml @@ -0,0 +1,9 @@ +%div.border.border-dark-subtle.rounded.p-1.fw-light + = person_role.hidden_field :_destroy + Rolle + = person_role.collection_select :role_id, Role.order(:name), :id, :name, {}, class: "form-select w-100" + %div + Stufe + %div.d-flex.fw-light + = person_role.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" + = person_role.number_field :percent, step: 1, class: "form-control w-50" \ No newline at end of file diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index a2c42db3d..cbef5e1e1 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -19,19 +19,12 @@ %th.fw-normal Funktionen %div = form.fields_for :person_roles do |person_role| + %tr + %td= render "person_role_fields", person_role: person_role %tr %td - %div.border.border-dark-subtle.rounded.p-1.fw-light - Rolle - = person_role.collection_select :role_id, Role.order(:name), :id, :name, {}, class: "form-select w-100" - %div - Stufe - %div.d-flex.fw-light - = person_role.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" - = person_role.number_field :percent, step: 1, class: "form-control w-50" - %tr - %td - %button.btn.btn-link Neue Funktion + = link_to_add_role "Neue Funktion", @person, :person_roles + %button.btn.btn-link Neue Funktion %th.fw-normal Organisationseinheit %tr %td= form.collection_select :department_id, Department.order(:name), :id, :name, {}, class: "form-select w-100" From f202713745aa31a31cedebe89559aee1223d8987 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 1 Mar 2024 08:33:24 +0100 Subject: [PATCH 25/80] add remove button to roles in edit view and fix rendering of form --- app/helpers/role_form_helper.rb | 2 +- app/views/people/_person_role_fields.html.haml | 3 ++- app/views/people/edit.html.haml | 7 +++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/helpers/role_form_helper.rb b/app/helpers/role_form_helper.rb index 94a4e73c5..824e31fe8 100644 --- a/app/helpers/role_form_helper.rb +++ b/app/helpers/role_form_helper.rb @@ -3,7 +3,7 @@ def link_to_add_role(name, form, association) new_role = form.object.send(association).klass.new id = new_role.object_id fields = form.fields_for(association, new_role, child_index: id) do |builder| - render("#{association.to_s.singularize}_fields", form: builder) + render("#{association.to_s.singularize}_fields", person_role: builder) end link_to( name, diff --git a/app/views/people/_person_role_fields.html.haml b/app/views/people/_person_role_fields.html.haml index a74093fe8..893778c59 100644 --- a/app/views/people/_person_role_fields.html.haml +++ b/app/views/people/_person_role_fields.html.haml @@ -6,4 +6,5 @@ Stufe %div.d-flex.fw-light = person_role.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" - = person_role.number_field :percent, step: 1, class: "form-control w-50" \ No newline at end of file + = person_role.number_field :percent, step: 1, class: "form-control w-50" + = link_to "Remove", "#", class: "remove_fields" \ No newline at end of file diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index cbef5e1e1..9832d59b7 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -21,10 +21,9 @@ = form.fields_for :person_roles do |person_role| %tr %td= render "person_role_fields", person_role: person_role - %tr - %td - = link_to_add_role "Neue Funktion", @person, :person_roles - %button.btn.btn-link Neue Funktion + %tr + %td + = link_to_add_role "Neue Funktion", form, :person_roles %th.fw-normal Organisationseinheit %tr %td= form.collection_select :department_id, Department.order(:name), :id, :name, {}, class: "form-select w-100" From 8d9c5f89c7c38ce82f6bf7a5d99dd095484ab443 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 1 Mar 2024 10:50:45 +0100 Subject: [PATCH 26/80] add missing class to person role fields partial, add js method to make remove roles work and update eventlistener of add role to correctly fire and trigger --- app/javascript/application.js | 4 ++- .../{ => packs}/nested-forms/addFields.js | 2 +- .../packs/nested-forms/removeFields.js | 32 +++++++++++++++++++ .../people/_person_role_fields.html.haml | 2 +- 4 files changed, 37 insertions(+), 3 deletions(-) rename app/javascript/{ => packs}/nested-forms/addFields.js (96%) create mode 100644 app/javascript/packs/nested-forms/removeFields.js diff --git a/app/javascript/application.js b/app/javascript/application.js index d87c99527..53b44ba07 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -1,4 +1,6 @@ import "@hotwired/turbo-rails" import "./controllers" import "@puzzleitc/puzzle-shell"; -import "@puzzleitc/puzzle-shell/style.css"; \ No newline at end of file +import "@puzzleitc/puzzle-shell/style.css"; +require("./packs/nested-forms/addFields"); +require("./packs/nested-forms/removeFields"); \ No newline at end of file diff --git a/app/javascript/nested-forms/addFields.js b/app/javascript/packs/nested-forms/addFields.js similarity index 96% rename from app/javascript/nested-forms/addFields.js rename to app/javascript/packs/nested-forms/addFields.js index c7893c1de..a354258bc 100644 --- a/app/javascript/nested-forms/addFields.js +++ b/app/javascript/packs/nested-forms/addFields.js @@ -33,4 +33,4 @@ class addFields { newFields ? link.insertAdjacentHTML("beforebegin", newFields) : null; } } -window.addEventListener("turbolinks:load", () => new addFields()); \ No newline at end of file +window.addEventListener("turbo:frame-render", () => new addFields()); \ No newline at end of file diff --git a/app/javascript/packs/nested-forms/removeFields.js b/app/javascript/packs/nested-forms/removeFields.js new file mode 100644 index 000000000..adc4ba7e5 --- /dev/null +++ b/app/javascript/packs/nested-forms/removeFields.js @@ -0,0 +1,32 @@ +class removeFields { + constructor() { + this.iterateLinks(); + } + + iterateLinks() { + document.addEventListener("click", (e) => { + if (e.target && e.target.className == "remove_fields") { + this.handleClick(e.target, e); + } + }); + } + + handleClick(link, e) { + // Stop the function from executing if a link or event were not passed into the function. + if (!link || !e) return; + // Prevent the browser from following the URL. + e.preventDefault(); + // Find the parent wrapper for the set of nested fields. + let fieldParent = link.closest(".nested-fields"); + // If there is a parent wrapper, find the hidden delete field. + let deleteField = fieldParent + ? fieldParent.querySelector('input[type="hidden"]') + : null; + // If there is a delete field, update the value to `1` and hide the corresponding nested fields. + if (deleteField) { + deleteField.value = 1; + fieldParent.style.display = "none"; + } + } +} +window.addEventListener("turbo:frame-render", () => new removeFields()); \ No newline at end of file diff --git a/app/views/people/_person_role_fields.html.haml b/app/views/people/_person_role_fields.html.haml index 893778c59..9f3db5d8f 100644 --- a/app/views/people/_person_role_fields.html.haml +++ b/app/views/people/_person_role_fields.html.haml @@ -1,4 +1,4 @@ -%div.border.border-dark-subtle.rounded.p-1.fw-light +%div.border.border-dark-subtle.rounded.p-1.fw-light.nested-fields = person_role.hidden_field :_destroy Rolle = person_role.collection_select :role_id, Role.order(:name), :id, :name, {}, class: "form-select w-100" From a26f0279eb47277bebd6c0ff521295ed96aa7ebe Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 1 Mar 2024 13:04:33 +0100 Subject: [PATCH 27/80] refactor too long lines, add comments, move whole edit form to form partial and create a turbostream that is triggered when edit fails, refactor the has_nationality2 property in the edit view --- app/controllers/people_controller.rb | 8 +-- app/helpers/role_form_helper.rb | 11 ++++ .../packs/nested-forms/addFields.js | 1 - app/views/people/_form.html.haml | 61 ++++++++++++++++++ app/views/people/edit.html.haml | 62 +------------------ app/views/people/edit.turbo_stream.erb | 12 ++++ 6 files changed, 89 insertions(+), 66 deletions(-) create mode 100644 app/views/people/_form.html.haml create mode 100644 app/views/people/edit.turbo_stream.erb diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 96a4df3bf..4211b16b6 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -5,8 +5,9 @@ class PeopleController < CrudController self.permitted_attrs = [:birthdate, :location, :marital_status, :updated_by, :name, :nationality, :nationality2, :title, - :competence_notes, :company_id, :email, :department_id, :shortname, :picture, - { person_roles_attributes: [:role_id, :person_role_level_id, :percent, :id, :_destroy] }] + :competence_notes, :company_id, :email, :department_id, :shortname, + :picture, { person_roles_attributes: [:role_id, :person_role_level_id, + :percent, :id, :_destroy] }] def new super @@ -14,8 +15,7 @@ def new end def update - @person.roles.build if @person.roles.empty? - if params['has_nationality2']['{}'].to_i.zero? + if params['has_nationality2'][0].to_i.zero? params['person']['nationality2'] = nil end super diff --git a/app/helpers/role_form_helper.rb b/app/helpers/role_form_helper.rb index 824e31fe8..758f634c4 100644 --- a/app/helpers/role_form_helper.rb +++ b/app/helpers/role_form_helper.rb @@ -1,10 +1,21 @@ module RoleFormHelper + # This method creates a link with `data-id` `data-fields` attributes. These attributes are used to create new instances of the nested fields through Javascript. def link_to_add_role(name, form, association) + # Takes an object and creates a new instance of its associated model new_role = form.object.send(association).klass.new + # Saves the unique ID of the object into a variable. + # This is needed to ensure the key of the associated array is unique. This makes parsing the content in the `data-fields` attribute easier through Javascript. id = new_role.object_id + # child_index` is used to ensure the key of the associated array is unique, and that it matched the value in the `data-id` attribute. fields = form.fields_for(association, new_role, child_index: id) do |builder| render("#{association.to_s.singularize}_fields", person_role: builder) end + + + # This renders a simple link, but passes information into `data` attributes. + # This info can be named anything we want, but in this case we chose `data-id:` and `data-fields:`. + # We use `gsub("\n", "")` to remove anywhite space from the rendered partial. + # The `id:` value needs to match the value used in `child_index: id`. link_to( name, '#', diff --git a/app/javascript/packs/nested-forms/addFields.js b/app/javascript/packs/nested-forms/addFields.js index a354258bc..74bad78a4 100644 --- a/app/javascript/packs/nested-forms/addFields.js +++ b/app/javascript/packs/nested-forms/addFields.js @@ -1,5 +1,4 @@ class addFields { - // This executes when the function is instantiated. constructor() { this.links = document.querySelectorAll(".add_fields"); this.iterateLinks(); diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml new file mode 100644 index 000000000..6403892f5 --- /dev/null +++ b/app/views/people/_form.html.haml @@ -0,0 +1,61 @@ += form_with model: @person do |form| + %div.d-flex.justify-content-between.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column + %div.pe-5 + %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} + = form.file_field :picture + %div.pe-5.d-flex + %table + %tbody + %th.fw-normal Name + %tr + %td= form.text_field :name, class: "w-100 form-control" + %th.fw-normal Email + %tr + %td= form.text_field :email, class: "w-100, form-control" + %th.fw-normal Abschluss + %tr + %td= form.text_field :title, class: "w-100, form-control" + %th.fw-normal Funktionen + %div + = form.fields_for :person_roles do |person_role| + %tr + %td= render "person_role_fields", person_role: person_role + %tr + %td + = link_to_add_role "Neue Funktion", form, :person_roles + %th.fw-normal Organisationseinheit + %tr + %td= form.collection_select :department_id, Department.order(:name), :id, :name, {}, class: "form-select w-100" + %th.fw-normal Firma + %tr + %td= form.collection_select :company_id, Company.order(:name), :id, :name, {}, class: "form-select w-100" + %th.fw-normal Wohnort (Stadt) + %tr + %td= form.text_field :location, class: "form-control w-100" + + %div.pe-5 + %table + %tbody + %th.fw-normal Geburtsdatum + %tr + %td= form.date_field :birthdate, class: "form-control w-100" + %th.fw-normal Doppelbürger + %tr + %td{"data-controller"=>"nationality-two"}= check_box :has_nationality2, "", {"checked" => @person.nationality2?, "data-action" => "nationality-two#nationalityTwoVisible", "id" => "nat-two-checkbox"} + %th.fw-normal Erste Nationalität + %tr + %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" + %th.fw-normal.nationality-two Zweite Nationalität + %tr.nationality-two + %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" + %th.fw-normal Zivilstand + %tr + %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: @person.marital_status }, class: "form-select w-100" + %div + %div.fw-normal Sprachen + %div.border.border-dark-subtle.mt-1.p-2.rounded + - @person.language_skills.each do |language| + %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" + %div.mt-3 + = form.submit :Speichern, class: "btn btn-primary me-3" + = link_to "Abbrechen", person_path \ No newline at end of file diff --git a/app/views/people/edit.html.haml b/app/views/people/edit.html.haml index 9832d59b7..b8c5f218c 100644 --- a/app/views/people/edit.html.haml +++ b/app/views/people/edit.html.haml @@ -1,62 +1,2 @@ %turbo-frame{id: "#{dom_id @person}"} - = form_with model: @person do |form| - %div.d-flex.justify-content-between.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column - %div.pe-5 - %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} - = form.file_field :picture - %div.pe-5.d-flex - %table - %tbody - %th.fw-normal Name - %tr - %td= form.text_field :name, class: "w-100 form-control" - %th.fw-normal Email - %tr - %td= form.text_field :email, class: "w-100, form-control" - %th.fw-normal Abschluss - %tr - %td= form.text_field :title, class: "w-100, form-control" - %th.fw-normal Funktionen - %div - = form.fields_for :person_roles do |person_role| - %tr - %td= render "person_role_fields", person_role: person_role - %tr - %td - = link_to_add_role "Neue Funktion", form, :person_roles - %th.fw-normal Organisationseinheit - %tr - %td= form.collection_select :department_id, Department.order(:name), :id, :name, {}, class: "form-select w-100" - %th.fw-normal Firma - %tr - %td= form.collection_select :company_id, Company.order(:name), :id, :name, {}, class: "form-select w-100" - %th.fw-normal Wohnort (Stadt) - %tr - %td= form.text_field :location, class: "form-control w-100" - - %div.pe-5 - %table - %tbody - %th.fw-normal Geburtsdatum - %tr - %td= form.date_field :birthdate, class: "form-control w-100" - %th.fw-normal Doppelbürger - %tr - %td{"data-controller"=>"nationality-two"}= check_box :has_nationality2, {}, {"checked" => @person.nationality2?, "data-action" => "nationality-two#nationalityTwoVisible", "id" => "nat-two-checkbox"} - %th.fw-normal Erste Nationalität - %tr - %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" - %th.fw-normal.nationality-two Zweite Nationalität - %tr.nationality-two - %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" - %th.fw-normal Zivilstand - %tr - %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: @person.marital_status }, class: "form-select w-100" - %div - %div.fw-normal Sprachen - %div.border.border-dark-subtle.mt-1.p-2.rounded - - @person.language_skills.each do |language| - %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" - %div.mt-3 - = form.submit :Speichern, class: "btn btn-primary me-3" - = link_to "Abbrechen", person_path \ No newline at end of file + = render "form", person: @person \ No newline at end of file diff --git a/app/views/people/edit.turbo_stream.erb b/app/views/people/edit.turbo_stream.erb new file mode 100644 index 000000000..65aba761e --- /dev/null +++ b/app/views/people/edit.turbo_stream.erb @@ -0,0 +1,12 @@ +<%= turbo_stream.update "#{dom_id @person}" do %> + <%= render "form", skill: @skill %> + <% if @person.errors.any? %> +
+
    + <% @person.errors.full_messages.each do |error| %> +
  • <%= error %>
  • + <% end %> +
+
+ <% end %> +<% end %> \ No newline at end of file From 9e5677c281c1997209f59f805cf0c39f2976958d Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 1 Mar 2024 13:41:56 +0100 Subject: [PATCH 28/80] fix name attribute of contries in form --- app/views/people/_form.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 6403892f5..d44b2871a 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -44,10 +44,10 @@ %td{"data-controller"=>"nationality-two"}= check_box :has_nationality2, "", {"checked" => @person.nationality2?, "data-action" => "nationality-two#nationalityTwoVisible", "id" => "nat-two-checkbox"} %th.fw-normal Erste Nationalität %tr - %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" + %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :iso_short_name, {}, class: "form-select w-100" %th.fw-normal.nationality-two Zweite Nationalität %tr.nationality-two - %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :name, {}, class: "form-select w-100" + %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :iso_short_name, {}, class: "form-select w-100" %th.fw-normal Zivilstand %tr %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: @person.marital_status }, class: "form-select w-100" From 743f589e69f87c292986893970f7a34a2d6d4214 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 1 Mar 2024 13:57:30 +0100 Subject: [PATCH 29/80] replace pzsh container with div to prevent moving whole page to center --- app/views/layouts/application.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index dde0ec35e..606a8267b 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -10,7 +10,7 @@ = javascript_include_tag "application", "data-turbo-track": "reload", type: "module" = favicon_link_tag "favicon.png" %body.d-flex.justify-content-center - %pzsh-container.content + %div.content %div.position-sticky.top-0.z-3 %div.d-flex.justify-content-between.bg-white %div.d-flex From d6595803d0e215c6bb4d47641a37c0f884a77027 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 1 Mar 2024 14:56:55 +0100 Subject: [PATCH 30/80] style the show view of the person --- app/assets/stylesheets/styles.scss | 9 ++ app/views/people/show.html.haml | 130 +++++++++++++++-------------- 2 files changed, 76 insertions(+), 63 deletions(-) diff --git a/app/assets/stylesheets/styles.scss b/app/assets/stylesheets/styles.scss index 9305262aa..0594e01f1 100644 --- a/app/assets/stylesheets/styles.scss +++ b/app/assets/stylesheets/styles.scss @@ -42,4 +42,13 @@ pzsh-topbar { .text-gray { color: $skills-text-gray; +} + +.personals-header { + background: #f5f5f5; + max-width: 100%; + height: 3.25rem; + padding: 12px 20px 12px 20px; + font-size: 18px; + border-bottom: #d6d6d6 1px solid; } \ No newline at end of file diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index f2fefca11..82afa60b6 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -1,66 +1,70 @@ %div - %h1 - = @person.name - 's Profile - -%turbo-frame{id: "#{dom_id @person}"} - %div.d-flex.justify-content-between.flex-lg-row.flex-md-row.flex-sm-column.flex-column + %div.personals-header + Personalien + %div %div - %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} - %div.mt-3= link_to "Bearbeiten", edit_person_path - %div.pe-5 - %table - %tbody - %th.fw-light Name - %tr - %td= @person.name - %th.fw-light Email - %tr - %td= @person.email - %th.fw-light Abschluss - %tr - %td= @person.title - %th.fw-light Funktion - - unless @person.person_roles.empty? - - @person.person_roles.each do |person_role| + %h1 + = @person.name + 's Profile + + %turbo-frame{id: "#{dom_id @person}"} + %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column + %div.col-xl-3.col-12 + %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} + %div.mt-3= link_to "Bearbeiten", edit_person_path + %div.pe-5.col-xl-3.col-12 + %table + %tbody + %th.fw-light Name %tr - %td= "#{person_role.role.name} #{person_role.person_role_level.level} #{person_role.percent.to_i}%" - - else - %tr - %td - - %th.fw-light Organisationseinheit - %tr - - unless @person.department.nil? - %td= @person.department.name - - else - %td - - %th.fw-light Firma - %tr - %td= @person.company.name - %div.pe-5 - %table - %tbody - %th.fw-light Geburtsdatum - %tr - %td= @person.birthdate.to_date.strftime('%d.%m.%Y') - %th.fw-light Nationalität - %tr - %td= @person.nationality2.blank? ? ISO3166::Country[@person.nationality] : "#{ISO3166::Country[@person.nationality]}, #{ISO3166::Country[@person.nationality2]}" - %th.fw-light Wohnort (Stadt) - %tr - %td= @person.location - %th.fw-light Zivilstand - %tr - %td= @person.marital_status - %th.fw-light Kürzel - %tr - - unless @person.shortname.nil? - %td= @person.shortname - - else - %td - - %div - %div.fw-light Sprachen - %div.border.border-dark-subtle.mt-1.p-2.rounded - - @person.language_skills.each do |language| - %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" - = link_to "Show all", people_path \ No newline at end of file + %td= @person.name + %th.fw-light Email + %tr + %td= @person.email + %th.fw-light Abschluss + %tr + %td= @person.title + %th.fw-light Funktion + - unless @person.person_roles.empty? + - @person.person_roles.each do |person_role| + %tr + %td= "#{person_role.role.name} #{person_role.person_role_level.level} #{person_role.percent.to_i}%" + - else + %tr + %td - + %th.fw-light Organisationseinheit + %tr + - unless @person.department.nil? + %td= @person.department.name + - else + %td - + %th.fw-light Firma + %tr + %td= @person.company.name + %div.pe-5.col-xl-3.col-12 + %table + %tbody + %th.fw-light Geburtsdatum + %tr + %td= @person.birthdate.to_date.strftime('%d.%m.%Y') + %th.fw-light Nationalität + %tr + %td= @person.nationality2.blank? ? ISO3166::Country[@person.nationality] : "#{ISO3166::Country[@person.nationality]}, #{ISO3166::Country[@person.nationality2]}" + %th.fw-light Wohnort (Stadt) + %tr + %td= @person.location + %th.fw-light Zivilstand + %tr + %td= @person.marital_status + %th.fw-light Kürzel + %tr + - unless @person.shortname.nil? + %td= @person.shortname + - else + %td - + %div.col-xl-3.col-12 + %div.fw-light Sprachen + %div.border.border-dark-subtle.mt-1.p-2.rounded + - @person.language_skills.each do |language| + %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" + = link_to "Show all", people_path \ No newline at end of file From ad9afaa161f4a33f9952c3578b60fbd37fcd8b33 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 1 Mar 2024 15:26:07 +0100 Subject: [PATCH 31/80] fix styling of edit view --- app/views/people/_form.html.haml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index d44b2871a..faaf03b9c 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -1,9 +1,9 @@ = form_with model: @person do |form| - %div.d-flex.justify-content-between.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column - %div.pe-5 + %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column + %div.col-xl-3.col-12 %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} = form.file_field :picture - %div.pe-5.d-flex + %div.pe-5.col-xl-3.col-12 %table %tbody %th.fw-normal Name @@ -33,7 +33,7 @@ %tr %td= form.text_field :location, class: "form-control w-100" - %div.pe-5 + %div.pe-5.col-xl-3.col-12 %table %tbody %th.fw-normal Geburtsdatum @@ -51,7 +51,7 @@ %th.fw-normal Zivilstand %tr %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: @person.marital_status }, class: "form-select w-100" - %div + %div.col-xl-3.col-12.mw-100 %div.fw-normal Sprachen %div.border.border-dark-subtle.mt-1.p-2.rounded - @person.language_skills.each do |language| From df96049c322d7aeb1d2c7796a44915efbcf2144c Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 1 Mar 2024 15:34:49 +0100 Subject: [PATCH 32/80] change w-100 to mw-100 everywhere in edit view --- app/views/people/_form.html.haml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index faaf03b9c..463e48ba8 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -8,13 +8,13 @@ %tbody %th.fw-normal Name %tr - %td= form.text_field :name, class: "w-100 form-control" + %td= form.text_field :name, class: "mw-100 form-control" %th.fw-normal Email %tr - %td= form.text_field :email, class: "w-100, form-control" + %td= form.text_field :email, class: "mw-100, form-control" %th.fw-normal Abschluss %tr - %td= form.text_field :title, class: "w-100, form-control" + %td= form.text_field :title, class: "mw-100, form-control" %th.fw-normal Funktionen %div = form.fields_for :person_roles do |person_role| @@ -25,32 +25,32 @@ = link_to_add_role "Neue Funktion", form, :person_roles %th.fw-normal Organisationseinheit %tr - %td= form.collection_select :department_id, Department.order(:name), :id, :name, {}, class: "form-select w-100" + %td= form.collection_select :department_id, Department.order(:name), :id, :name, {}, class: "form-select mw-100" %th.fw-normal Firma %tr - %td= form.collection_select :company_id, Company.order(:name), :id, :name, {}, class: "form-select w-100" + %td= form.collection_select :company_id, Company.order(:name), :id, :name, {}, class: "form-select mw-100" %th.fw-normal Wohnort (Stadt) %tr - %td= form.text_field :location, class: "form-control w-100" + %td= form.text_field :location, class: "form-control mw-100" %div.pe-5.col-xl-3.col-12 %table %tbody %th.fw-normal Geburtsdatum %tr - %td= form.date_field :birthdate, class: "form-control w-100" + %td= form.date_field :birthdate, class: "form-control mw-100" %th.fw-normal Doppelbürger %tr %td{"data-controller"=>"nationality-two"}= check_box :has_nationality2, "", {"checked" => @person.nationality2?, "data-action" => "nationality-two#nationalityTwoVisible", "id" => "nat-two-checkbox"} %th.fw-normal Erste Nationalität %tr - %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :iso_short_name, {}, class: "form-select w-100" + %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :iso_short_name, {}, class: "form-select mw-100" %th.fw-normal.nationality-two Zweite Nationalität %tr.nationality-two - %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :iso_short_name, {}, class: "form-select w-100" + %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :iso_short_name, {}, class: "form-select mw-100" %th.fw-normal Zivilstand %tr - %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: @person.marital_status }, class: "form-select w-100" + %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: @person.marital_status }, class: "form-select mw-100" %div.col-xl-3.col-12.mw-100 %div.fw-normal Sprachen %div.border.border-dark-subtle.mt-1.p-2.rounded From 0bd65fa904129dbefcfa4682772145e7633612e6 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 1 Mar 2024 16:05:35 +0100 Subject: [PATCH 33/80] make image instantly update on file upload by using a stimulus controller --- .../controllers/image_upload_controller.js | 9 +++++++++ app/javascript/controllers/index.js | 13 +++++++++---- app/views/people/_form.html.haml | 4 ++-- 3 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 app/javascript/controllers/image_upload_controller.js diff --git a/app/javascript/controllers/image_upload_controller.js b/app/javascript/controllers/image_upload_controller.js new file mode 100644 index 000000000..4a29899dd --- /dev/null +++ b/app/javascript/controllers/image_upload_controller.js @@ -0,0 +1,9 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + changeImage() { + const avatarUploader = document.getElementById("avatar-uploader"); + const avatar = document.getElementById("avatar"); + avatar.src = URL.createObjectURL(avatarUploader.files[0]) + } +} \ No newline at end of file diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index 1e35601b8..860994bab 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -4,9 +4,14 @@ import { application } from "./application" -import DropdownLinksController from "./dropdown_controller" -application.register("dropdown", DropdownLinksController) +import DropdownController from "./dropdown_controller" +application.register("dropdown", DropdownController) + +import ImageUploadController from "./image_upload_controller" +application.register("image-upload", ImageUploadController) + +import NationalityTwoController from "./nationality_two_controller" +application.register("nationality-two", NationalityTwoController) + import RemoteModalController from "./remote_modal_controller" application.register("remote-modal", RemoteModalController) -import NationalityTwoController from "./nationality_two_controller" -application.register("nationality-two", NationalityTwoController) \ No newline at end of file diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 463e48ba8..7e4c71b52 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -1,8 +1,8 @@ = form_with model: @person do |form| %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.col-xl-3.col-12 - %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} - = form.file_field :picture + %img.rounded-circle#avatar{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} + %div{"data-controller"=>"image-upload"}= form.file_field :picture, { accept: "image/", "data-action" => "image-upload#changeImage", id: "avatar-uploader" } %div.pe-5.col-xl-3.col-12 %table %tbody From 9e52451f6105d74ef45fb295fa46eb6c24ea0f32 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 4 Mar 2024 09:24:19 +0100 Subject: [PATCH 34/80] fix nationality2 checkbox --- app/controllers/people_controller.rb | 2 +- app/views/people/_form.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 4211b16b6..130a746dc 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -15,7 +15,7 @@ def new end def update - if params['has_nationality2'][0].to_i.zero? + if params['has_nationality2']['has_nationality2'].to_i.zero? params['person']['nationality2'] = nil end super diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 7e4c71b52..6dd55b220 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -41,7 +41,7 @@ %td= form.date_field :birthdate, class: "form-control mw-100" %th.fw-normal Doppelbürger %tr - %td{"data-controller"=>"nationality-two"}= check_box :has_nationality2, "", {"checked" => @person.nationality2?, "data-action" => "nationality-two#nationalityTwoVisible", "id" => "nat-two-checkbox"} + %td{"data-controller"=>"nationality-two"}= check_box :has_nationality2, "has_nationality2", {"checked" => @person.nationality2?, "data-action" => "nationality-two#nationalityTwoVisible", "id" => "nat-two-checkbox"} %th.fw-normal Erste Nationalität %tr %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :iso_short_name, {}, class: "form-select mw-100" From 649019878136032dc75b8d87b9ac6c837334a401 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 4 Mar 2024 11:57:13 +0100 Subject: [PATCH 35/80] add picture cache for profile picture, style picture upload button fix error in person edit turbostream --- app/controllers/people_controller.rb | 5 +++-- app/views/people/_form.html.haml | 5 ++++- app/views/people/edit.turbo_stream.erb | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 130a746dc..f156ad306 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -6,8 +6,9 @@ class PeopleController < CrudController self.permitted_attrs = [:birthdate, :location, :marital_status, :updated_by, :name, :nationality, :nationality2, :title, :competence_notes, :company_id, :email, :department_id, :shortname, - :picture, { person_roles_attributes: [:role_id, :person_role_level_id, - :percent, :id, :_destroy] }] + :picture, :picture_cache, { person_roles_attributes: + [:role_id, :person_role_level_id, + :percent, :id, :_destroy] }] def new super diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 6dd55b220..112822874 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -2,7 +2,10 @@ %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.col-xl-3.col-12 %img.rounded-circle#avatar{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} - %div{"data-controller"=>"image-upload"}= form.file_field :picture, { accept: "image/", "data-action" => "image-upload#changeImage", id: "avatar-uploader" } + %br + %label.btn.btn-primary{for: "avatar-uploader"} Bild ändern + %div.visually-hidden{"data-controller"=>"image-upload"}= form.file_field :picture, { accept: "image/", "data-action" => "image-upload#changeImage", id: "avatar-uploader" } + = form.hidden_field :picture_cache %div.pe-5.col-xl-3.col-12 %table %tbody diff --git a/app/views/people/edit.turbo_stream.erb b/app/views/people/edit.turbo_stream.erb index 65aba761e..64cee993c 100644 --- a/app/views/people/edit.turbo_stream.erb +++ b/app/views/people/edit.turbo_stream.erb @@ -1,5 +1,5 @@ <%= turbo_stream.update "#{dom_id @person}" do %> - <%= render "form", skill: @skill %> + <%= render "form", person: @person %> <% if @person.errors.any? %>
    From 8b6fce7db388eb915df1530e3c6dc0953b97b494 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 4 Mar 2024 12:54:51 +0100 Subject: [PATCH 36/80] adjust color of buttons in person edit view --- app/assets/stylesheets/styles.scss | 8 ++++++++ app/views/people/_form.html.haml | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/styles.scss b/app/assets/stylesheets/styles.scss index 0594e01f1..e485d83d0 100644 --- a/app/assets/stylesheets/styles.scss +++ b/app/assets/stylesheets/styles.scss @@ -51,4 +51,12 @@ pzsh-topbar { padding: 12px 20px 12px 20px; font-size: 18px; border-bottom: #d6d6d6 1px solid; +} + +.bg-skills-blue { + background-color: $skills-blue; +} + +.bg-skills-blue:hover { + background-color: #3268a1; } \ No newline at end of file diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 112822874..95ac35b2e 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -3,7 +3,7 @@ %div.col-xl-3.col-12 %img.rounded-circle#avatar{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} %br - %label.btn.btn-primary{for: "avatar-uploader"} Bild ändern + %label.btn.btn-primary.bg-skills-blue{for: "avatar-uploader"} Bild ändern %div.visually-hidden{"data-controller"=>"image-upload"}= form.file_field :picture, { accept: "image/", "data-action" => "image-upload#changeImage", id: "avatar-uploader" } = form.hidden_field :picture_cache %div.pe-5.col-xl-3.col-12 @@ -60,5 +60,5 @@ - @person.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" %div.mt-3 - = form.submit :Speichern, class: "btn btn-primary me-3" + = form.submit :Speichern, class: "btn btn-primary me-3 bg-skills-blue" = link_to "Abbrechen", person_path \ No newline at end of file From 0c6b0f4dc6ddfeb7a50d34e57bbedbb4e7100adc Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 5 Mar 2024 09:11:06 +0100 Subject: [PATCH 37/80] fix loading of profile picture after saving and style profile picture upload button --- app/views/people/_form.html.haml | 6 +++--- app/views/people/show.html.haml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 95ac35b2e..dee7a6e39 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -1,10 +1,10 @@ = form_with model: @person do |form| %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.col-xl-3.col-12 - %img.rounded-circle#avatar{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} + %img.rounded-circle#avatar{src: "/api/people/#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} %br - %label.btn.btn-primary.bg-skills-blue{for: "avatar-uploader"} Bild ändern - %div.visually-hidden{"data-controller"=>"image-upload"}= form.file_field :picture, { accept: "image/", "data-action" => "image-upload#changeImage", id: "avatar-uploader" } + %label.btn.btn-link{for: "avatar-uploader"} Bild ändern + %div.visually-hidden{"data-controller"=>"image-upload"}= form.file_field :picture, { accept: "image/", "data-action" => "image-upload#changeImage", id: "avatar-uploader" } = form.hidden_field :picture_cache %div.pe-5.col-xl-3.col-12 %table diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 82afa60b6..3e5cefcfb 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -10,7 +10,7 @@ %turbo-frame{id: "#{dom_id @person}"} %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.col-xl-3.col-12 - %img.rounded-circle{src: "/api/people/#{@person.id}/picture", width: '141', height: '141'} + %img.rounded-circle{src: "/api/people/#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} %div.mt-3= link_to "Bearbeiten", edit_person_path %div.pe-5.col-xl-3.col-12 %table From 5cb14ffb4d7c5921223cd8d25b07b8d9d7521fe0 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 5 Mar 2024 15:52:27 +0100 Subject: [PATCH 38/80] fix template error in show view of person, when person role level or percent are nil, add classes to person templates for testing purposes and write first test to test if person is editable --- .../people/_person_role_fields.html.haml | 6 ++-- app/views/people/show.html.haml | 5 +-- spec/features/people_controller_spec.rb | 36 +++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/app/views/people/_person_role_fields.html.haml b/app/views/people/_person_role_fields.html.haml index 9f3db5d8f..cc427862e 100644 --- a/app/views/people/_person_role_fields.html.haml +++ b/app/views/people/_person_role_fields.html.haml @@ -1,10 +1,10 @@ %div.border.border-dark-subtle.rounded.p-1.fw-light.nested-fields = person_role.hidden_field :_destroy Rolle - = person_role.collection_select :role_id, Role.order(:name), :id, :name, {}, class: "form-select w-100" + = person_role.collection_select :role_id, Role.order(:name), :id, :name, {}, class: "form-select w-100 role-select" %div Stufe %div.d-flex.fw-light - = person_role.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1" - = person_role.number_field :percent, step: 1, class: "form-control w-50" + = person_role.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1 role-level-select" + = person_role.number_field :percent, step: 1, class: "form-control w-50 person-role-percent" = link_to "Remove", "#", class: "remove_fields" \ No newline at end of file diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 3e5cefcfb..43482b479 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -1,4 +1,5 @@ %div + =render partial:"people/search", :locals => {person: @person} %div.personals-header Personalien %div @@ -11,7 +12,7 @@ %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.col-xl-3.col-12 %img.rounded-circle{src: "/api/people/#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} - %div.mt-3= link_to "Bearbeiten", edit_person_path + %div.mt-3= link_to "Bearbeiten", edit_person_path, class: "edit_button" %div.pe-5.col-xl-3.col-12 %table %tbody @@ -28,7 +29,7 @@ - unless @person.person_roles.empty? - @person.person_roles.each do |person_role| %tr - %td= "#{person_role.role.name} #{person_role.person_role_level.level} #{person_role.percent.to_i}%" + %td= "#{person_role.role.name} #{person_role.person_role_level&.level} #{person_role.percent&.to_i}%" - else %tr %td - diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index 7b7428d62..365328757 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -39,4 +39,40 @@ expect(page).to have_select('person_id', selected: list.first.name) end end + + describe 'Edit person', type: :feature, js: true do + it 'can edit person' do + bob = people(:bob) + visit person_path(bob) + page.first('.edit_button').click + expect(page).to have_field('person_name', with: bob.name) + expect(page).to have_field('person_email', with: bob.email) + expect(page).to have_field('person_title', with: bob.title) + person_roles = bob.person_roles + role_selects = page.all('.role-select') + role_level_selects = page.all('.role-level-select') + role_percent_selects = page.all('.person-role-percent') + expect(role_selects.count).to equal(person_roles.count) + expect(role_level_selects.count).to equal(person_roles.count) + expect(role_percent_selects.count).to equal(person_roles.count) + role_selects.each_with_index do |role_select, i| + expect(role_select.value.to_i).to equal(person_roles[i].role_id) + end + role_level_selects.each_with_index do |role_level_select, i| + person_roles[i].person_role_level_id.nil? ? (expect(role_level_select.value.to_i).to equal(PersonRoleLevel.first.id)) : (expect(role_level_select.value.to_i).to equal(person_roles[i].person_role_level_id)) + end + role_percent_selects.each_with_index do |role_percent_select, i| + expect(role_percent_select.value.to_i).to equal(person_roles[i].percent.to_i) + end + expect(page).to have_select('person_department_id', selected: bob.department.name) + expect(page).to have_select('person_company_id', selected: bob.company.name) + expect(page).to have_field('person_location', with: bob.location) + expect(page).to have_field('person_birthdate', with: bob.birthdate.to_date.strftime) + expect(page).to have_field('nat-two-checkbox', with: bob.nationality2.nil? ? "0" : "1") + expect(page.all('.nationality-two').count).to equal(bob.nationality2.nil? ? 0 : 2) + expect(page).to have_select('person_nationality', selected: ISO3166::Country[bob.nationality]&.iso_short_name) + bob.nationality2.nil? ? (expect(page).not_to have_select('person_nationality2')) : (expect(page).to have_select('person_nationality2', selected: ISO3166::Country[bob.nationality2]&.iso_short_name)) + expect(page).to have_select('person_marital_status', selected: bob.marital_status) + end + end end From e1c510518043babef67202442819138bac3d4460 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 07:44:00 +0100 Subject: [PATCH 39/80] fix rubocop offenses --- app/controllers/picture_controller.rb | 1 + app/helpers/picture_helper.rb | 2 ++ app/helpers/role_form_helper.rb | 25 +++++++++++-------------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/controllers/picture_controller.rb b/app/controllers/picture_controller.rb index a523f6b05..f4421c50f 100644 --- a/app/controllers/picture_controller.rb +++ b/app/controllers/picture_controller.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true class PictureController < ApplicationController def show picture_url = @person.picture.file.nil? ? default_avatar_path : @person.picture.url diff --git a/app/helpers/picture_helper.rb b/app/helpers/picture_helper.rb index 42cb833cd..ee3b2a770 100644 --- a/app/helpers/picture_helper.rb +++ b/app/helpers/picture_helper.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + module PictureHelper end diff --git a/app/helpers/role_form_helper.rb b/app/helpers/role_form_helper.rb index 758f634c4..fbf3b4411 100644 --- a/app/helpers/role_form_helper.rb +++ b/app/helpers/role_form_helper.rb @@ -1,29 +1,26 @@ +# frozen_string_literal: true module RoleFormHelper - # This method creates a link with `data-id` `data-fields` attributes. These attributes are used to create new instances of the nested fields through Javascript. + # This method creates a link with `data-id` `data-fields` attributes. These attributes are used + # to create new instances of the nested fields through Javascript. def link_to_add_role(name, form, association) # Takes an object and creates a new instance of its associated model new_role = form.object.send(association).klass.new # Saves the unique ID of the object into a variable. - # This is needed to ensure the key of the associated array is unique. This makes parsing the content in the `data-fields` attribute easier through Javascript. + # This is needed to ensure the key of the associated array is unique. This makes parsing the + # content in the `data-fields` attribute easier through Javascript. id = new_role.object_id - # child_index` is used to ensure the key of the associated array is unique, and that it matched the value in the `data-id` attribute. + # child_index` is used to ensure the key of the associated array is unique, and that it matched + # the value in the `data-id` attribute. fields = form.fields_for(association, new_role, child_index: id) do |builder| render("#{association.to_s.singularize}_fields", person_role: builder) end # This renders a simple link, but passes information into `data` attributes. - # This info can be named anything we want, but in this case we chose `data-id:` and `data-fields:`. + # This info can be named anything we want, but in this case + # we chose `data-id:` and `data-fields:`. # We use `gsub("\n", "")` to remove anywhite space from the rendered partial. # The `id:` value needs to match the value used in `child_index: id`. - link_to( - name, - '#', - class: 'add_fields', - data: { - id: id, - fields: fields.gsub("\n", '') - } - ) + link_to(name, '#', class: 'add_fields', data: { id: id, fields: fields.gsub("\n", '') }) end -end \ No newline at end of file +end From bc470f6c9c95fb3274adef47b911986da1caeb8d Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 07:46:45 +0100 Subject: [PATCH 40/80] fix last rubocop offenses --- app/controllers/picture_controller.rb | 1 + app/helpers/role_form_helper.rb | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/picture_controller.rb b/app/controllers/picture_controller.rb index f4421c50f..51d84bf7e 100644 --- a/app/controllers/picture_controller.rb +++ b/app/controllers/picture_controller.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + class PictureController < ApplicationController def show picture_url = @person.picture.file.nil? ? default_avatar_path : @person.picture.url diff --git a/app/helpers/role_form_helper.rb b/app/helpers/role_form_helper.rb index fbf3b4411..739b04421 100644 --- a/app/helpers/role_form_helper.rb +++ b/app/helpers/role_form_helper.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true + module RoleFormHelper - # This method creates a link with `data-id` `data-fields` attributes. These attributes are used + # This method creates a link with `data-id` `data-fields` attributes. These attributes are used # to create new instances of the nested fields through Javascript. def link_to_add_role(name, form, association) # Takes an object and creates a new instance of its associated model From 38b38e0b3e9412d172fc82878edb865287841d10 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 11:35:26 +0100 Subject: [PATCH 41/80] write test that tests if editing a person is possible, assign id to save and edit buttons for testing, make editing shortname possible --- app/views/people/_form.html.haml | 5 ++- app/views/people/show.html.haml | 2 +- spec/features/people_controller_spec.rb | 56 ++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index dee7a6e39..e88618f79 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -54,11 +54,14 @@ %th.fw-normal Zivilstand %tr %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: @person.marital_status }, class: "form-select mw-100" + %th.fw-normal Kürzel + %tr + %td= form.text_field :shortname, class: "mw-100 form-control" %div.col-xl-3.col-12.mw-100 %div.fw-normal Sprachen %div.border.border-dark-subtle.mt-1.p-2.rounded - @person.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" %div.mt-3 - = form.submit :Speichern, class: "btn btn-primary me-3 bg-skills-blue" + = form.submit :Speichern, { class: "btn btn-primary me-3 bg-skills-blue", id: "save_button" } = link_to "Abbrechen", person_path \ No newline at end of file diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 43482b479..e76c85903 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -12,7 +12,7 @@ %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.col-xl-3.col-12 %img.rounded-circle{src: "/api/people/#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} - %div.mt-3= link_to "Bearbeiten", edit_person_path, class: "edit_button" + %div.mt-3= link_to "Bearbeiten", edit_person_path, id: "edit_button" %div.pe-5.col-xl-3.col-12 %table %tbody diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index 365328757..e4e1c45d9 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -40,11 +40,34 @@ end end + def fill_out_person_form + fill_in 'person_name', with: 'Hansjakobli' + fill_in 'person_email', with: 'hanswurst@somemail.com' + fill_in 'person_title', with: 'Wurstexperte' + page.first(".add_fields").click + role_select = page.all('.role-select').last + role_level_select = page.all('.role-level-select').last + role_percent_select = page.all('.person-role-percent').last + select 'System-Engineer', from: role_select[:id] + select 'S3', from: role_level_select[:id] + fill_in role_percent_select[:id], with: '80' + + select '/ux', from: 'person_department_id' + select 'Partner', from: 'person_company_id' + fill_in 'person_location', with: 'Las Vegas' + fill_in 'person_birthdate', with: '28.03.1979'.to_date.strftime + check 'nat-two-checkbox' + select ISO3166::Country["DE"]&.iso_short_name, from: 'person_nationality' + select ISO3166::Country["US"]&.iso_short_name, from: 'person_nationality2' + select 'married', from: 'person_marital_status' + fill_in 'person_shortname', with: 'bb' + end + describe 'Edit person', type: :feature, js: true do - it 'can edit person' do + it 'should have all edit fields' do bob = people(:bob) visit person_path(bob) - page.first('.edit_button').click + page.find('#edit_button').click expect(page).to have_field('person_name', with: bob.name) expect(page).to have_field('person_email', with: bob.email) expect(page).to have_field('person_title', with: bob.title) @@ -73,6 +96,35 @@ expect(page).to have_select('person_nationality', selected: ISO3166::Country[bob.nationality]&.iso_short_name) bob.nationality2.nil? ? (expect(page).not_to have_select('person_nationality2')) : (expect(page).to have_select('person_nationality2', selected: ISO3166::Country[bob.nationality2]&.iso_short_name)) expect(page).to have_select('person_marital_status', selected: bob.marital_status) + expect(page).to have_field('person_shortname', with: bob.shortname) + end + + it 'should edit and save changes' do + bob = people(:bob) + visit person_path(bob) + page.find('#edit_button').click + fill_out_person_form + page.find("#save_button").click + + expect(page).to have_content("Hansjakobli") + + edited_person = Person.where(name: 'Hansjakobli')[0] + expect(edited_person.email).to eql('hanswurst@somemail.com') + expect(edited_person.title).to eql('Wurstexperte') + expect(edited_person.person_roles.count).to equal(3) + + edited_person_role = edited_person.person_roles.last + expect(edited_person_role.role.name).to eql('System-Engineer') + expect(edited_person_role.person_role_level.level).to eql('S3') + expect(edited_person_role.percent).to eq(80) + expect(edited_person.department.name).to eql('/ux') + expect(edited_person.company.name).to eql('Partner') + expect(edited_person.location).to eql('Las Vegas') + expect(edited_person.birthdate.to_date.strftime).to eql('1979-03-28') + expect(edited_person.nationality).to eql('DE') + expect(edited_person.nationality2).to eql('US') + expect(edited_person.marital_status).to eql('married') + expect(edited_person.shortname).to eql('bb') end end end From 4b4e4cca257b8329c1f54daa9a8f00cdc4d1fb29 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 11:38:44 +0100 Subject: [PATCH 42/80] remove unwanted header from person profile --- app/views/people/show.html.haml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index e76c85903..8691589dc 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -2,12 +2,7 @@ =render partial:"people/search", :locals => {person: @person} %div.personals-header Personalien - %div - %div - %h1 - = @person.name - 's Profile - + %div.mt-4 %turbo-frame{id: "#{dom_id @person}"} %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.col-xl-3.col-12 From 285019631a6b7d8aebb557d2e6707db45ec4cdb6 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 11:43:52 +0100 Subject: [PATCH 43/80] change dateformat in equal check of feature spec to make test work across all systems --- spec/features/people_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index e4e1c45d9..32b5c4455 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -120,7 +120,7 @@ def fill_out_person_form expect(edited_person.department.name).to eql('/ux') expect(edited_person.company.name).to eql('Partner') expect(edited_person.location).to eql('Las Vegas') - expect(edited_person.birthdate.to_date.strftime).to eql('1979-03-28') + expect(edited_person.birthdate.to_date.strftime('%d.%m.%Y')).to eql('28.03.1979') expect(edited_person.nationality).to eql('DE') expect(edited_person.nationality2).to eql('US') expect(edited_person.marital_status).to eql('married') From 243278e834eef2253900dd143316f9120e31f208 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 12:52:08 +0100 Subject: [PATCH 44/80] change _ to - in ids of save cancel and edit buttons and write test that tests if canceling really doesnt save the person --- app/views/people/_form.html.haml | 4 ++-- app/views/people/show.html.haml | 2 +- spec/features/people_controller_spec.rb | 15 ++++++++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index e88618f79..ed7e6e79e 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -63,5 +63,5 @@ - @person.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" %div.mt-3 - = form.submit :Speichern, { class: "btn btn-primary me-3 bg-skills-blue", id: "save_button" } - = link_to "Abbrechen", person_path \ No newline at end of file + = form.submit :Speichern, { class: "btn btn-primary me-3 bg-skills-blue", id: "save-button" } + = link_to "Abbrechen", person_path, { id: "cancel-button" } \ No newline at end of file diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 8691589dc..15d118398 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -7,7 +7,7 @@ %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.col-xl-3.col-12 %img.rounded-circle{src: "/api/people/#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} - %div.mt-3= link_to "Bearbeiten", edit_person_path, id: "edit_button" + %div.mt-3= link_to "Bearbeiten", edit_person_path, id: "edit-button" %div.pe-5.col-xl-3.col-12 %table %tbody diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index 32b5c4455..51aa5c8eb 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -67,7 +67,7 @@ def fill_out_person_form it 'should have all edit fields' do bob = people(:bob) visit person_path(bob) - page.find('#edit_button').click + page.find('#edit-button').click expect(page).to have_field('person_name', with: bob.name) expect(page).to have_field('person_email', with: bob.email) expect(page).to have_field('person_title', with: bob.title) @@ -102,9 +102,9 @@ def fill_out_person_form it 'should edit and save changes' do bob = people(:bob) visit person_path(bob) - page.find('#edit_button').click + page.find('#edit-button').click fill_out_person_form - page.find("#save_button").click + page.find("#save-button").click expect(page).to have_content("Hansjakobli") @@ -126,5 +126,14 @@ def fill_out_person_form expect(edited_person.marital_status).to eql('married') expect(edited_person.shortname).to eql('bb') end + + it 'should edit and cancel without saving' do + person = Person.first + visit person_path(person) + page.find('#edit-button').click + fill_out_person_form + page.find('#cancel-button').click + expect(person.attributes).to eql(Person.first.attributes) + end end end From d393baf687faf8044c1754c3a6c4acf5913ad985 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 12:58:56 +0100 Subject: [PATCH 45/80] revert formating of date in test --- spec/features/people_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index 51aa5c8eb..af97fec00 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -120,7 +120,7 @@ def fill_out_person_form expect(edited_person.department.name).to eql('/ux') expect(edited_person.company.name).to eql('Partner') expect(edited_person.location).to eql('Las Vegas') - expect(edited_person.birthdate.to_date.strftime('%d.%m.%Y')).to eql('28.03.1979') + expect(edited_person.birthdate.to_date.strftime).to eql('28.03.1979') expect(edited_person.nationality).to eql('DE') expect(edited_person.nationality2).to eql('US') expect(edited_person.marital_status).to eql('married') From ef03dfa86479cf4af0752534a1be23397c19029e Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 13:09:27 +0100 Subject: [PATCH 46/80] bring back formatting of date in test --- spec/features/people_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index af97fec00..51aa5c8eb 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -120,7 +120,7 @@ def fill_out_person_form expect(edited_person.department.name).to eql('/ux') expect(edited_person.company.name).to eql('Partner') expect(edited_person.location).to eql('Las Vegas') - expect(edited_person.birthdate.to_date.strftime).to eql('28.03.1979') + expect(edited_person.birthdate.to_date.strftime('%d.%m.%Y')).to eql('28.03.1979') expect(edited_person.nationality).to eql('DE') expect(edited_person.nationality2).to eql('US') expect(edited_person.marital_status).to eql('married') From bb6855928ef71630105751266accc832dda6a26e Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 13:46:07 +0100 Subject: [PATCH 47/80] Change filling of date input in test to default html --- spec/features/people_controller_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index 51aa5c8eb..57a857f55 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -55,7 +55,7 @@ def fill_out_person_form select '/ux', from: 'person_department_id' select 'Partner', from: 'person_company_id' fill_in 'person_location', with: 'Las Vegas' - fill_in 'person_birthdate', with: '28.03.1979'.to_date.strftime + fill_in 'person_birthdate', with: '1979-03-28' check 'nat-two-checkbox' select ISO3166::Country["DE"]&.iso_short_name, from: 'person_nationality' select ISO3166::Country["US"]&.iso_short_name, from: 'person_nationality2' @@ -108,7 +108,7 @@ def fill_out_person_form expect(page).to have_content("Hansjakobli") - edited_person = Person.where(name: 'Hansjakobli')[0] + edited_person = Person.find_by(name: 'Hansjakobli') expect(edited_person.email).to eql('hanswurst@somemail.com') expect(edited_person.title).to eql('Wurstexperte') expect(edited_person.person_roles.count).to equal(3) From 3af92e5bd9ae8cfd1c30e593dab8eef1798c2ff7 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 14:04:18 +0100 Subject: [PATCH 48/80] Fix date formating for filling form in test --- spec/features/people_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index 57a857f55..2b19ea333 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -55,7 +55,7 @@ def fill_out_person_form select '/ux', from: 'person_department_id' select 'Partner', from: 'person_company_id' fill_in 'person_location', with: 'Las Vegas' - fill_in 'person_birthdate', with: '1979-03-28' + fill_in 'person_birthdate', with: '1979-03-28'.to_date check 'nat-two-checkbox' select ISO3166::Country["DE"]&.iso_short_name, from: 'person_nationality' select ISO3166::Country["US"]&.iso_short_name, from: 'person_nationality2' From 0fcc97fa6e51c7152ad53c3fb9d12022aa8c3606 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 15:24:55 +0100 Subject: [PATCH 49/80] make test also upload new image and check if avatar upload field exists --- spec/features/people_controller_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index 2b19ea333..da76f217e 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -41,6 +41,7 @@ end def fill_out_person_form + page.attach_file("avatar-uploader", Rails.root + 'app/assets/images/1.png') fill_in 'person_name', with: 'Hansjakobli' fill_in 'person_email', with: 'hanswurst@somemail.com' fill_in 'person_title', with: 'Wurstexperte' @@ -68,6 +69,7 @@ def fill_out_person_form bob = people(:bob) visit person_path(bob) page.find('#edit-button').click + expect(page).to have_field('avatar-uploader') expect(page).to have_field('person_name', with: bob.name) expect(page).to have_field('person_email', with: bob.email) expect(page).to have_field('person_title', with: bob.title) From 89cc571bf968be43846dae7544f0add85f3284bb Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 8 Mar 2024 16:29:17 +0100 Subject: [PATCH 50/80] rename method of has_nationality2 checkbox to checked and start writing people_controller spec --- app/controllers/people_controller.rb | 2 +- app/views/people/_form.html.haml | 2 +- spec/controllers/people_controller_spec.rb | 12 ++++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 spec/controllers/people_controller_spec.rb diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index f156ad306..ba1738396 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -16,7 +16,7 @@ def new end def update - if params['has_nationality2']['has_nationality2'].to_i.zero? + if params['has_nationality2']['checked'].to_i.zero? params['person']['nationality2'] = nil end super diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index ed7e6e79e..4a0c22a12 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -44,7 +44,7 @@ %td= form.date_field :birthdate, class: "form-control mw-100" %th.fw-normal Doppelbürger %tr - %td{"data-controller"=>"nationality-two"}= check_box :has_nationality2, "has_nationality2", {"checked" => @person.nationality2?, "data-action" => "nationality-two#nationalityTwoVisible", "id" => "nat-two-checkbox"} + %td{"data-controller"=>"nationality-two"}= check_box :has_nationality2, "checked", {"checked" => @person.nationality2?, "data-action" => "nationality-two#nationalityTwoVisible", "id" => "nat-two-checkbox"} %th.fw-normal Erste Nationalität %tr %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :iso_short_name, {}, class: "form-select mw-100" diff --git a/spec/controllers/people_controller_spec.rb b/spec/controllers/people_controller_spec.rb new file mode 100644 index 000000000..de6ca7d77 --- /dev/null +++ b/spec/controllers/people_controller_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' + +describe PeopleController do + describe 'Update Person' do + render_views + it 'should save nationality2 as nil if checkbox is unchecked and save it if it is checked' do + person = people(:bob) + patch :update, params: {id: person.id, person: person.attributes, has_nationality2: {checked: "1"}} + expect(JSON.parse(response.body)['nationality2']).to eql(person.nationality2) + end + end +end \ No newline at end of file From 0a724e7dfec1ef2513db8a823279353ad205bcf4 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 11 Mar 2024 11:44:07 +0100 Subject: [PATCH 51/80] Add param converter concerns to check if param is false, use new false method to check if person has nationality2, write test to test if nationality2 is set according to checkbox --- app/controllers/concerns/param_converters.rb | 18 ++++++++++++++++++ app/controllers/people_controller.rb | 14 +++++++------- spec/controllers/people_controller_spec.rb | 11 ++++++++--- 3 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 app/controllers/concerns/param_converters.rb diff --git a/app/controllers/concerns/param_converters.rb b/app/controllers/concerns/param_converters.rb new file mode 100644 index 000000000..f7b298de9 --- /dev/null +++ b/app/controllers/concerns/param_converters.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module ParamConverters + + private + + def true?(value) + %w[1 yes true].include?(value.to_s.downcase) + end + + def false?(value) + %w[0 no false].include?(value.to_s.downcase) + end + + def nil_param?(value) + value == 'null' ? nil : value + end +end \ No newline at end of file diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index ba1738396..12884f562 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -2,13 +2,13 @@ class PeopleController < CrudController include ExportController + include ParamConverters - self.permitted_attrs = [:birthdate, :location, - :marital_status, :updated_by, :name, :nationality, :nationality2, :title, - :competence_notes, :company_id, :email, :department_id, :shortname, - :picture, :picture_cache, { person_roles_attributes: - [:role_id, :person_role_level_id, - :percent, :id, :_destroy] }] + self.permitted_attrs = [:birthdate, :location, :marital_status, :updated_by, :name, :nationality, + :nationality2, :title, :competence_notes, :company_id, :email, + :department_id, :shortname, :picture, :picture_cache, + { person_roles_attributes: [:role_id, :person_role_level_id, + :percent, :id, :_destroy] }] def new super @@ -16,7 +16,7 @@ def new end def update - if params['has_nationality2']['checked'].to_i.zero? + if false?(params['has_nationality2']['checked']) params['person']['nationality2'] = nil end super diff --git a/spec/controllers/people_controller_spec.rb b/spec/controllers/people_controller_spec.rb index de6ca7d77..3533aff30 100644 --- a/spec/controllers/people_controller_spec.rb +++ b/spec/controllers/people_controller_spec.rb @@ -3,10 +3,15 @@ describe PeopleController do describe 'Update Person' do render_views + let(:person) { people(:bob).attributes } + it 'should save nationality2 as nil if checkbox is unchecked and save it if it is checked' do - person = people(:bob) - patch :update, params: {id: person.id, person: person.attributes, has_nationality2: {checked: "1"}} - expect(JSON.parse(response.body)['nationality2']).to eql(person.nationality2) + put :update, params: {id: person["id"], person: person, has_nationality2: {checked: "0"}} + + response.code.should == "302" + response.should redirect_to(person_path(person["id"])) + + expect(people(:bob).reload.nationality2).to be(nil) end end end \ No newline at end of file From dfca71b21e31c99e91cae769e96d8f1135c23298 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 11 Mar 2024 12:02:55 +0100 Subject: [PATCH 52/80] Remove rubocop offense and check if nationality2 is not null initially in person controller test --- app/controllers/concerns/param_converters.rb | 2 +- spec/controllers/people_controller_spec.rb | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/concerns/param_converters.rb b/app/controllers/concerns/param_converters.rb index f7b298de9..8325fcbb3 100644 --- a/app/controllers/concerns/param_converters.rb +++ b/app/controllers/concerns/param_converters.rb @@ -15,4 +15,4 @@ def false?(value) def nil_param?(value) value == 'null' ? nil : value end -end \ No newline at end of file +end diff --git a/spec/controllers/people_controller_spec.rb b/spec/controllers/people_controller_spec.rb index 3533aff30..721500dea 100644 --- a/spec/controllers/people_controller_spec.rb +++ b/spec/controllers/people_controller_spec.rb @@ -6,6 +6,8 @@ let(:person) { people(:bob).attributes } it 'should save nationality2 as nil if checkbox is unchecked and save it if it is checked' do + expect(person["nationality2"]).not_to be(nil) + put :update, params: {id: person["id"], person: person, has_nationality2: {checked: "0"}} response.code.should == "302" From c01f61abe730d6c50f988f33ae9acc85f644cf60 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 11 Mar 2024 13:30:16 +0100 Subject: [PATCH 53/80] style person show view to wrap text and replace some unless statements with ternary operators --- app/assets/stylesheets/styles.scss | 5 +++++ app/views/people/show.html.haml | 25 ++++++++++--------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/assets/stylesheets/styles.scss b/app/assets/stylesheets/styles.scss index e485d83d0..c86d47508 100644 --- a/app/assets/stylesheets/styles.scss +++ b/app/assets/stylesheets/styles.scss @@ -59,4 +59,9 @@ pzsh-topbar { .bg-skills-blue:hover { background-color: #3268a1; +} + +.fixed-table { + table-layout: fixed; + width: 100%; } \ No newline at end of file diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 15d118398..a7b218c85 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -9,17 +9,17 @@ %img.rounded-circle{src: "/api/people/#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} %div.mt-3= link_to "Bearbeiten", edit_person_path, id: "edit-button" %div.pe-5.col-xl-3.col-12 - %table + %table.fixed-table %tbody %th.fw-light Name %tr - %td= @person.name + %td.text-break= @person.name %th.fw-light Email %tr - %td= @person.email + %td.text-break= @person.email %th.fw-light Abschluss %tr - %td= @person.title + %td.text-break= @person.title %th.fw-light Funktion - unless @person.person_roles.empty? - @person.person_roles.each do |person_role| @@ -30,34 +30,29 @@ %td - %th.fw-light Organisationseinheit %tr - - unless @person.department.nil? - %td= @person.department.name - - else - %td - + %td= @person.department.nil? ? '-' : @person.department.name %th.fw-light Firma %tr %td= @person.company.name %div.pe-5.col-xl-3.col-12 - %table + %table.fixed-table %tbody %th.fw-light Geburtsdatum %tr %td= @person.birthdate.to_date.strftime('%d.%m.%Y') %th.fw-light Nationalität %tr - %td= @person.nationality2.blank? ? ISO3166::Country[@person.nationality] : "#{ISO3166::Country[@person.nationality]}, #{ISO3166::Country[@person.nationality2]}" + %td.text-break= @person.nationality2.blank? ? ISO3166::Country[@person.nationality] : "#{ISO3166::Country[@person.nationality]}, #{ISO3166::Country[@person.nationality2]}" %th.fw-light Wohnort (Stadt) %tr - %td= @person.location + %td.text-break= @person.location %th.fw-light Zivilstand %tr %td= @person.marital_status %th.fw-light Kürzel %tr - - unless @person.shortname.nil? - %td= @person.shortname - - else - %td - + %td= @person.shortname.blank? ? '-' : @person.shortname + %div.col-xl-3.col-12 %div.fw-light Sprachen %div.border.border-dark-subtle.mt-1.p-2.rounded From 6dfda1e8a2cf8ba01e031fdfe502cd80a5e1cb6e Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 11 Mar 2024 14:44:52 +0100 Subject: [PATCH 54/80] reimplement whole picture controller from api namespace, cleanup code --- app/controllers/people/picture_controller.rb | 28 ++++++++++++++++++++ app/controllers/people_controller.rb | 5 ---- app/controllers/picture_controller.rb | 8 ------ app/views/people/_form.html.haml | 2 +- app/views/people/show.html.haml | 2 +- config/routes.rb | 13 +++++---- spec/features/people_controller_spec.rb | 1 - 7 files changed, 38 insertions(+), 21 deletions(-) create mode 100644 app/controllers/people/picture_controller.rb delete mode 100644 app/controllers/picture_controller.rb diff --git a/app/controllers/people/picture_controller.rb b/app/controllers/people/picture_controller.rb new file mode 100644 index 000000000..5efae200c --- /dev/null +++ b/app/controllers/people/picture_controller.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module People + class PictureController < Api::CrudController + + self.permitted_attrs = %i[picture] + + def update + person.update!(picture: params[:picture]) + render json: { data: { picture_path: picture_api_person_path(params[:id]) } } + end + + def show + picture_url = person.picture.file.nil? ? default_avatar_path : person.picture.url + send_file(picture_url, disposition: 'inline') + end + + private + + def person + @person ||= Person.find(params[:id]) + end + + def default_avatar_path + get_asset_path 'default_avatar.png' + end + end +end \ No newline at end of file diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 12884f562..5e6a6d8c9 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -10,11 +10,6 @@ class PeopleController < CrudController { person_roles_attributes: [:role_id, :person_role_level_id, :percent, :id, :_destroy] }] - def new - super - @person.roles.build - end - def update if false?(params['has_nationality2']['checked']) params['person']['nationality2'] = nil diff --git a/app/controllers/picture_controller.rb b/app/controllers/picture_controller.rb deleted file mode 100644 index 51d84bf7e..000000000 --- a/app/controllers/picture_controller.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -class PictureController < ApplicationController - def show - picture_url = @person.picture.file.nil? ? default_avatar_path : @person.picture.url - send_file(picture_url, disposition: 'inline') - end -end diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 4a0c22a12..9f4d66cc5 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -1,7 +1,7 @@ = form_with model: @person do |form| %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.col-xl-3.col-12 - %img.rounded-circle#avatar{src: "/api/people/#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} + %img.rounded-circle#avatar{src: "#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} %br %label.btn.btn-link{for: "avatar-uploader"} Bild ändern %div.visually-hidden{"data-controller"=>"image-upload"}= form.file_field :picture, { accept: "image/", "data-action" => "image-upload#changeImage", id: "avatar-uploader" } diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index a7b218c85..faa6c5b70 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -6,7 +6,7 @@ %turbo-frame{id: "#{dom_id @person}"} %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.col-xl-3.col-12 - %img.rounded-circle{src: "/api/people/#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} + %img.rounded-circle{src: "#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} %div.mt-3= link_to "Bearbeiten", edit_person_path, id: "edit-button" %div.pe-5.col-xl-3.col-12 %table.fixed-table diff --git a/config/routes.rb b/config/routes.rb index 896fac8c8..7b930ff00 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -21,17 +21,20 @@ get 'readiness', to: 'status#readiness' end + resources :people do + member do + put 'picture', to: 'people/picture#update' + get 'picture', to: 'people/picture#show' + end + end + resources :skills + # Outdated api routes namespace :api do resources :people do collection do get 'search', to: 'people/search#index' end - - member do - put 'picture', to: 'people/picture#update' - get 'picture', to: 'people/picture#show' - end end resources :skills do diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index da76f217e..7ae572434 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -114,7 +114,6 @@ def fill_out_person_form expect(edited_person.email).to eql('hanswurst@somemail.com') expect(edited_person.title).to eql('Wurstexperte') expect(edited_person.person_roles.count).to equal(3) - edited_person_role = edited_person.person_roles.last expect(edited_person_role.role.name).to eql('System-Engineer') expect(edited_person_role.person_role_level.level).to eql('S3') From 920eadd6a9015696f2bfafc4f93c2f6a1ab67ee9 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 11 Mar 2024 14:57:16 +0100 Subject: [PATCH 55/80] move picture test from api namespace to people namespace and xdescribe old test --- app/controllers/people/picture_controller.rb | 2 +- .../api/people/picture_controller_spec.rb | 2 +- .../people/picture_controller_spec.rb | 37 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 spec/controllers/people/picture_controller_spec.rb diff --git a/app/controllers/people/picture_controller.rb b/app/controllers/people/picture_controller.rb index 5efae200c..d45bd2bf3 100644 --- a/app/controllers/people/picture_controller.rb +++ b/app/controllers/people/picture_controller.rb @@ -7,7 +7,7 @@ class PictureController < Api::CrudController def update person.update!(picture: params[:picture]) - render json: { data: { picture_path: picture_api_person_path(params[:id]) } } + render json: { data: { picture_path: picture_person_path(params[:id]) } } end def show diff --git a/spec/controllers/api/people/picture_controller_spec.rb b/spec/controllers/api/people/picture_controller_spec.rb index 924c2a4b4..9dc69621b 100644 --- a/spec/controllers/api/people/picture_controller_spec.rb +++ b/spec/controllers/api/people/picture_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe Api::People::PictureController do +xdescribe Api::People::PictureController do it 'should show default_avatar' do get :show, params:{ id: bob.id } diff --git a/spec/controllers/people/picture_controller_spec.rb b/spec/controllers/people/picture_controller_spec.rb new file mode 100644 index 000000000..ba68f5f81 --- /dev/null +++ b/spec/controllers/people/picture_controller_spec.rb @@ -0,0 +1,37 @@ +require 'rails_helper' + +describe People::PictureController do + + it 'should show default_avatar' do + get :show, params:{ id: bob.id } + + default_avatar_md5 = '96643270fe346cc83165128dfcfccd4c' + + expect(response.status).to eq(200) + expect(Digest::MD5.hexdigest(response.body)).to eq(default_avatar_md5) + end + + it 'should update picture' do + process :update, method: :put, params: { id: bob.id, picture: fixture_file_upload('picture.png', 'image/png') } + + path = json['data']['picture_path'] + + bob.reload + + expect(response.status).to eq(200) + expect(bob['picture']).to eq('picture.png') + expect(path).to eq('/people/902541635/picture') + + process :show, method: :get , params: { id: bob.id } + + new_picture_md5 = 'c903aeff2bec840bd7c028631bd56596' + + expect(Digest::MD5.hexdigest(response.body)).to eq(new_picture_md5) + end + + private + + def bob + @bob ||= people(:bob) + end +end From f2f07a16ad3ee2b79da43ea6ba69e3e7f53ad0fd Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 11 Mar 2024 15:01:27 +0100 Subject: [PATCH 56/80] fix rubocop offense --- app/controllers/people/picture_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/people/picture_controller.rb b/app/controllers/people/picture_controller.rb index d45bd2bf3..c54451c48 100644 --- a/app/controllers/people/picture_controller.rb +++ b/app/controllers/people/picture_controller.rb @@ -25,4 +25,4 @@ def default_avatar_path get_asset_path 'default_avatar.png' end end -end \ No newline at end of file +end From 03879f4e90c369bf9ef0a7f84729050130352c04 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 11 Mar 2024 15:16:28 +0100 Subject: [PATCH 57/80] Dont display role percentage if there is no role percentage in person overview --- app/views/people/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index faa6c5b70..551c15c4d 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -24,7 +24,7 @@ - unless @person.person_roles.empty? - @person.person_roles.each do |person_role| %tr - %td= "#{person_role.role.name} #{person_role.person_role_level&.level} #{person_role.percent&.to_i}%" + %td= "#{person_role.role.name} #{person_role.person_role_level&.level} #{person_role.percent.nil? ? '' : person_role.percent.to_i.to_s + '%'}" - else %tr %td - From fd9699a77f8157f047619767dadffa9c7cb48be3 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 11 Mar 2024 15:46:17 +0100 Subject: [PATCH 58/80] revert unnecessary file change --- config/application.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/application.rb b/config/application.rb index 0f9850ec2..808f185c3 100644 --- a/config/application.rb +++ b/config/application.rb @@ -46,6 +46,7 @@ def keycloak_disabled? KEYCLOAK_ENV_VARS.none? { |e| ENV[e].present? } && ENV['KEYCLOAK_DISABLED'].present? end + config.assets.enabled = true config.assets.paths << Rails.root.join("uploads") end From 10911d43f14d7be5fb579b60f631d1fa92ba66ba Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 11 Mar 2024 15:51:16 +0100 Subject: [PATCH 59/80] remove unneeded picture helpers and specs --- app/helpers/picture_helper.rb | 4 ---- spec/helpers/picture_helper_spec.rb | 15 --------------- spec/requests/picture_request_spec.rb | 5 ----- 3 files changed, 24 deletions(-) delete mode 100644 app/helpers/picture_helper.rb delete mode 100644 spec/helpers/picture_helper_spec.rb delete mode 100644 spec/requests/picture_request_spec.rb diff --git a/app/helpers/picture_helper.rb b/app/helpers/picture_helper.rb deleted file mode 100644 index ee3b2a770..000000000 --- a/app/helpers/picture_helper.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true - -module PictureHelper -end diff --git a/spec/helpers/picture_helper_spec.rb b/spec/helpers/picture_helper_spec.rb deleted file mode 100644 index 1c022316c..000000000 --- a/spec/helpers/picture_helper_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'rails_helper' - -# Specs in this file have access to a helper object that includes -# the PictureHelper. For example: -# -# describe PictureHelper do -# describe "string concat" do -# it "concats two strings with spaces" do -# expect(helper.concat_strings("this","that")).to eq("this that") -# end -# end -# end -RSpec.describe PictureHelper, type: :helper do - pending "add some examples to (or delete) #{__FILE__}" -end diff --git a/spec/requests/picture_request_spec.rb b/spec/requests/picture_request_spec.rb deleted file mode 100644 index a17fc15a5..000000000 --- a/spec/requests/picture_request_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -RSpec.describe "Pictures", type: :request do - -end From bdcd91f16ae43994e878100073ffcb74ed37aaa7 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 11 Mar 2024 16:46:12 +0100 Subject: [PATCH 60/80] add translations for marital statuses --- config/locales/de.yml | 6 ++++++ config/locales/en.yml | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/config/locales/de.yml b/config/locales/de.yml index 232b55be0..6022d84c3 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -8,3 +8,9 @@ de: default_set: Default-Set radar: Radar modify: Ändern + ms: + single: ledig + married: verheiratet + widowed: verwitwet + registered_partnership: eingetragene partnerschaft + divorced: geschieden diff --git a/config/locales/en.yml b/config/locales/en.yml index 8a9c0d5b7..a83f43d94 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -8,3 +8,9 @@ en: default_set: Defaultset radar: Radar modify: Modify + martial_statuses: + single: single + married: married + widowed: widowed + registered_partnership: registered partnership + divorced: divorced \ No newline at end of file From 7213b45c9a32975fa72a4fb029892b9e0b55e9b2 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 12 Mar 2024 07:32:07 +0100 Subject: [PATCH 61/80] fix loading of avatar because it vanished in specific cases --- app/views/people/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 551c15c4d..1cc8309b0 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -6,7 +6,7 @@ %turbo-frame{id: "#{dom_id @person}"} %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column %div.col-xl-3.col-12 - %img.rounded-circle{src: "#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} + %img.rounded-circle{src: "/people/#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} %div.mt-3= link_to "Bearbeiten", edit_person_path, id: "edit-button" %div.pe-5.col-xl-3.col-12 %table.fixed-table From f494fecef5d886f5179583c50adc40e4bd1e7fde Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 12 Mar 2024 08:14:45 +0100 Subject: [PATCH 62/80] fix translation yml files and translate marital status and nationality --- app/views/people/_form.html.haml | 6 +++--- app/views/people/show.html.haml | 4 ++-- config/locales/de.yml | 2 +- config/locales/en.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 9f4d66cc5..20bd665de 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -47,13 +47,13 @@ %td{"data-controller"=>"nationality-two"}= check_box :has_nationality2, "checked", {"checked" => @person.nationality2?, "data-action" => "nationality-two#nationalityTwoVisible", "id" => "nat-two-checkbox"} %th.fw-normal Erste Nationalität %tr - %td= form.collection_select :nationality, ISO3166::Country.all.sort, :alpha2, :iso_short_name, {}, class: "form-select mw-100" + %td= form.collection_select :nationality, ISO3166::Country.all.sort.map { |country| [country.alpha2, country.translations[I18n.locale]] }, :first, :last, {}, class: "form-select mw-100" %th.fw-normal.nationality-two Zweite Nationalität %tr.nationality-two - %td= form.collection_select :nationality2, ISO3166::Country.all.sort, :alpha2, :iso_short_name, {}, class: "form-select mw-100" + %td= form.collection_select :nationality2, ISO3166::Country.all.sort.map { |country| [country.alpha2, country.translations[I18n.locale]] }, :first, :last, {}, class: "form-select mw-100" %th.fw-normal Zivilstand %tr - %td= form.collection_select :marital_status, Person.marital_statuses, :first, :first, { selected: @person.marital_status }, class: "form-select mw-100" + %td= form.collection_select :marital_status, Person.marital_statuses.keys.map { |ms| [ms, t("ms.#{ms}")] }, :first, :last, { selected: @person.marital_status }, class: "form-select mw-100" %th.fw-normal Kürzel %tr %td= form.text_field :shortname, class: "mw-100 form-control" diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 1cc8309b0..8b803e2cf 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -42,13 +42,13 @@ %td= @person.birthdate.to_date.strftime('%d.%m.%Y') %th.fw-light Nationalität %tr - %td.text-break= @person.nationality2.blank? ? ISO3166::Country[@person.nationality] : "#{ISO3166::Country[@person.nationality]}, #{ISO3166::Country[@person.nationality2]}" + %td.text-break= @person.nationality2.blank? ? ISO3166::Country[@person.nationality].alpha2 : "#{ISO3166::Country[@person.nationality].translations[I18n.locale]}, #{ISO3166::Country[@person.nationality2].translations[I18n.locale]}" %th.fw-light Wohnort (Stadt) %tr %td.text-break= @person.location %th.fw-light Zivilstand %tr - %td= @person.marital_status + %td= t("ms.#{@person.marital_status}") %th.fw-light Kürzel %tr %td= @person.shortname.blank? ? '-' : @person.shortname diff --git a/config/locales/de.yml b/config/locales/de.yml index 6022d84c3..9e35a05a0 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -12,5 +12,5 @@ de: single: ledig married: verheiratet widowed: verwitwet - registered_partnership: eingetragene partnerschaft + registered_partnership: eingetragene Partnerschaft divorced: geschieden diff --git a/config/locales/en.yml b/config/locales/en.yml index a83f43d94..9f0d1c52f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -8,7 +8,7 @@ en: default_set: Defaultset radar: Radar modify: Modify - martial_statuses: + ms: single: single married: married widowed: widowed From 287e1c9c0b5400d0ddfcc045e17ab35624c14324 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 12 Mar 2024 08:48:46 +0100 Subject: [PATCH 63/80] fix tests after localization and test if avatar is saved in feature spec --- spec/features/people_controller_spec.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index 7ae572434..00b9d6f3c 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -58,9 +58,9 @@ def fill_out_person_form fill_in 'person_location', with: 'Las Vegas' fill_in 'person_birthdate', with: '1979-03-28'.to_date check 'nat-two-checkbox' - select ISO3166::Country["DE"]&.iso_short_name, from: 'person_nationality' - select ISO3166::Country["US"]&.iso_short_name, from: 'person_nationality2' - select 'married', from: 'person_marital_status' + select ISO3166::Country["DE"].translations[I18n.locale], from: 'person_nationality' + select ISO3166::Country["US"].translations[I18n.locale], from: 'person_nationality2' + select I18n.t('ms.married'), from: 'person_marital_status' fill_in 'person_shortname', with: 'bb' end @@ -95,9 +95,9 @@ def fill_out_person_form expect(page).to have_field('person_birthdate', with: bob.birthdate.to_date.strftime) expect(page).to have_field('nat-two-checkbox', with: bob.nationality2.nil? ? "0" : "1") expect(page.all('.nationality-two').count).to equal(bob.nationality2.nil? ? 0 : 2) - expect(page).to have_select('person_nationality', selected: ISO3166::Country[bob.nationality]&.iso_short_name) - bob.nationality2.nil? ? (expect(page).not_to have_select('person_nationality2')) : (expect(page).to have_select('person_nationality2', selected: ISO3166::Country[bob.nationality2]&.iso_short_name)) - expect(page).to have_select('person_marital_status', selected: bob.marital_status) + expect(page).to have_select('person_nationality', selected: ISO3166::Country[bob.nationality].translations[I18n.locale]) + bob.nationality2.nil? ? (expect(page).not_to have_select('person_nationality2')) : (expect(page).to have_select('person_nationality2', selected: ISO3166::Country[bob.nationality2].translations[I18n.locale])) + expect(page).to have_select('person_marital_status', selected: I18n.t("ms.#{bob.marital_status}")) expect(page).to have_field('person_shortname', with: bob.shortname) end @@ -111,9 +111,10 @@ def fill_out_person_form expect(page).to have_content("Hansjakobli") edited_person = Person.find_by(name: 'Hansjakobli') + expect(edited_person.picture.identifier).to eql('1.png') expect(edited_person.email).to eql('hanswurst@somemail.com') expect(edited_person.title).to eql('Wurstexperte') - expect(edited_person.person_roles.count).to equal(3) + expect(edited_person.person_roles.count).to eql(3) edited_person_role = edited_person.person_roles.last expect(edited_person_role.role.name).to eql('System-Engineer') expect(edited_person_role.person_role_level.level).to eql('S3') From 2ffd1ec6e38205c3d281e49b61c7511da7b60754 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 12 Mar 2024 08:53:05 +0100 Subject: [PATCH 64/80] replace alpha2 code with actual country name in people show view --- app/views/people/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 8b803e2cf..eac471484 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -42,7 +42,7 @@ %td= @person.birthdate.to_date.strftime('%d.%m.%Y') %th.fw-light Nationalität %tr - %td.text-break= @person.nationality2.blank? ? ISO3166::Country[@person.nationality].alpha2 : "#{ISO3166::Country[@person.nationality].translations[I18n.locale]}, #{ISO3166::Country[@person.nationality2].translations[I18n.locale]}" + %td.text-break= @person.nationality2.blank? ? ISO3166::Country[@person.nationality].translations[I18n.locale] : "#{ISO3166::Country[@person.nationality].translations[I18n.locale]}, #{ISO3166::Country[@person.nationality2].translations[I18n.locale]}" %th.fw-light Wohnort (Stadt) %tr %td.text-break= @person.location From 51df4003dbe5b9150e81d006762945d2538b9f19 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 12 Mar 2024 10:27:50 +0100 Subject: [PATCH 65/80] make picture controller inherit from new crud controller instead of api crud controller --- app/controllers/crud_controller.rb | 9 +++++++++ app/controllers/people/picture_controller.rb | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/controllers/crud_controller.rb b/app/controllers/crud_controller.rb index 6ce7f425a..e2bdcd269 100644 --- a/app/controllers/crud_controller.rb +++ b/app/controllers/crud_controller.rb @@ -244,6 +244,15 @@ def error_messages # rubocop:enable Rails/OutputSafety end + def get_asset_path(filename) + manifest_file = Rails.application.assets_manifest.assets[filename] + if manifest_file + File.join(Rails.application.assets_manifest.directory, manifest_file) + else + Rails.application.assets&.[](filename)&.filename + end + end + # Class methods for CrudActions. class << self # Convenience callback to apply a callback on both form actions diff --git a/app/controllers/people/picture_controller.rb b/app/controllers/people/picture_controller.rb index c54451c48..d9d5521bb 100644 --- a/app/controllers/people/picture_controller.rb +++ b/app/controllers/people/picture_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module People - class PictureController < Api::CrudController + class PictureController < CrudController self.permitted_attrs = %i[picture] @@ -17,6 +17,10 @@ def show private + def model_class + Person + end + def person @person ||= Person.find(params[:id]) end From a9cae8ac8d4677c101dd373eaeb157ca91360c42 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 12 Mar 2024 10:39:36 +0100 Subject: [PATCH 66/80] make people controller test also test if nationality is saved correctly --- spec/controllers/people_controller_spec.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spec/controllers/people_controller_spec.rb b/spec/controllers/people_controller_spec.rb index 721500dea..03be463e9 100644 --- a/spec/controllers/people_controller_spec.rb +++ b/spec/controllers/people_controller_spec.rb @@ -7,13 +7,17 @@ it 'should save nationality2 as nil if checkbox is unchecked and save it if it is checked' do expect(person["nationality2"]).not_to be(nil) - put :update, params: {id: person["id"], person: person, has_nationality2: {checked: "0"}} - response.code.should == "302" response.should redirect_to(person_path(person["id"])) - expect(people(:bob).reload.nationality2).to be(nil) + + edited_person = person + edited_person["nationality2"] = "DE" + put :update, params: {id: person["id"], person: edited_person, has_nationality2: {checked: "1"}} + response.code.should == "302" + response.should redirect_to(person_path(person["id"])) + expect(people(:bob).reload.nationality2).to eql("DE") end end end \ No newline at end of file From eef824223810f624d4e472b7dfc3c16ecb1e17df Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 12 Mar 2024 12:39:33 +0100 Subject: [PATCH 67/80] fix specs after rebase --- spec/controllers/people_controller_spec.rb | 3 +++ spec/features/people_controller_spec.rb | 7 +++++-- spec/rails_helper.rb | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/spec/controllers/people_controller_spec.rb b/spec/controllers/people_controller_spec.rb index 03be463e9..150dc4a9c 100644 --- a/spec/controllers/people_controller_spec.rb +++ b/spec/controllers/people_controller_spec.rb @@ -1,6 +1,9 @@ require 'rails_helper' describe PeopleController do + before(:each) do + sign_in auth_users(:user), scope: :auth_user + end describe 'Update Person' do render_views let(:person) { people(:bob).attributes } diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_controller_spec.rb index 00b9d6f3c..d0d7e46e1 100644 --- a/spec/features/people_controller_spec.rb +++ b/spec/features/people_controller_spec.rb @@ -4,8 +4,7 @@ describe 'People Search', type: :feature, js: true do before(:each) do - user = auth_users(:user) - login_as(user, scope: :auth_user) + sign_in auth_users(:user), scope: :auth_user end let(:list) {Person.all.sort_by(&:name) } @@ -65,6 +64,10 @@ def fill_out_person_form end describe 'Edit person', type: :feature, js: true do + before(:each) do + sign_in auth_users(:user), scope: :auth_user + end + it 'should have all edit fields' do bob = people(:bob) visit person_path(bob) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 6dd694bba..9fa6b62df 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -61,6 +61,7 @@ config.include(JsonAssertion, type: :controller) config.include(ControllerHelpers, type: :controller) config.include(Devise::Test::IntegrationHelpers, type: :feature) + config.include(Devise::Test::ControllerHelpers, type: :controller) config.infer_spec_type_from_file_location! config.filter_rails_from_backtrace! From dc88a096f087619da41554d287418eaf5f6e1b2e Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 12 Mar 2024 14:21:16 +0100 Subject: [PATCH 68/80] move functions to add and remove roles to stimulus controller --- app/helpers/role_form_helper.rb | 4 +- app/javascript/application.js | 4 +- app/javascript/controllers/index.js | 3 ++ .../person_roles_controller.js} | 43 +++++++++++-------- .../packs/nested-forms/removeFields.js | 32 -------------- app/views/people/_form.html.haml | 2 +- .../people/_person_role_fields.html.haml | 2 +- 7 files changed, 33 insertions(+), 57 deletions(-) rename app/javascript/{packs/nested-forms/addFields.js => controllers/person_roles_controller.js} (53%) delete mode 100644 app/javascript/packs/nested-forms/removeFields.js diff --git a/app/helpers/role_form_helper.rb b/app/helpers/role_form_helper.rb index 739b04421..1b06d48b2 100644 --- a/app/helpers/role_form_helper.rb +++ b/app/helpers/role_form_helper.rb @@ -22,6 +22,8 @@ def link_to_add_role(name, form, association) # we chose `data-id:` and `data-fields:`. # We use `gsub("\n", "")` to remove anywhite space from the rendered partial. # The `id:` value needs to match the value used in `child_index: id`. - link_to(name, '#', class: 'add_fields', data: { id: id, fields: fields.gsub("\n", '') }) + link_to(name, '#', + { class: 'add_fields', 'data-action' => 'person-roles#addField', + data: { id: id, fields: fields.gsub("\n", '') } }) end end diff --git a/app/javascript/application.js b/app/javascript/application.js index 53b44ba07..d87c99527 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -1,6 +1,4 @@ import "@hotwired/turbo-rails" import "./controllers" import "@puzzleitc/puzzle-shell"; -import "@puzzleitc/puzzle-shell/style.css"; -require("./packs/nested-forms/addFields"); -require("./packs/nested-forms/removeFields"); \ No newline at end of file +import "@puzzleitc/puzzle-shell/style.css"; \ No newline at end of file diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index 860994bab..2046c521f 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -13,5 +13,8 @@ application.register("image-upload", ImageUploadController) import NationalityTwoController from "./nationality_two_controller" application.register("nationality-two", NationalityTwoController) +import PersonRolesController from "./person_roles_controller" +application.register("person-roles", PersonRolesController) + import RemoteModalController from "./remote_modal_controller" application.register("remote-modal", RemoteModalController) diff --git a/app/javascript/packs/nested-forms/addFields.js b/app/javascript/controllers/person_roles_controller.js similarity index 53% rename from app/javascript/packs/nested-forms/addFields.js rename to app/javascript/controllers/person_roles_controller.js index 74bad78a4..2ce8187d8 100644 --- a/app/javascript/packs/nested-forms/addFields.js +++ b/app/javascript/controllers/person_roles_controller.js @@ -1,21 +1,8 @@ -class addFields { - constructor() { - this.links = document.querySelectorAll(".add_fields"); - this.iterateLinks(); - } - - iterateLinks() { - // If there are no links on the page, stop the function from executing. - if (this.links.length === 0) return; - // Loop over each link on the page. A page could have multiple nested forms. - this.links.forEach((link) => { - link.addEventListener("click", (e) => { - this.handleClick(link, e); - }); - }); - } +import { Controller } from "@hotwired/stimulus" - handleClick(link, e) { +export default class extends Controller { + addField(e) { + let link = e.target // Stop the function from executing if a link or event were not passed into the function. if (!link || !e) return; // Prevent the browser from following the URL. @@ -31,5 +18,23 @@ class addFields { // Add the new markup to the form if there are fields to add. newFields ? link.insertAdjacentHTML("beforebegin", newFields) : null; } -} -window.addEventListener("turbo:frame-render", () => new addFields()); \ No newline at end of file + + removeField(e) { + let link = e.target + // Stop the function from executing if a link or event were not passed into the function. + if (!link || !e) return; + // Prevent the browser from following the URL. + e.preventDefault(); + // Find the parent wrapper for the set of nested fields. + let fieldParent = link.closest(".nested-fields"); + // If there is a parent wrapper, find the hidden delete field. + let deleteField = fieldParent + ? fieldParent.querySelector('input[type="hidden"]') + : null; + // If there is a delete field, update the value to `1` and hide the corresponding nested fields. + if (deleteField) { + deleteField.value = 1; + fieldParent.style.display = "none"; + } + } +} \ No newline at end of file diff --git a/app/javascript/packs/nested-forms/removeFields.js b/app/javascript/packs/nested-forms/removeFields.js deleted file mode 100644 index adc4ba7e5..000000000 --- a/app/javascript/packs/nested-forms/removeFields.js +++ /dev/null @@ -1,32 +0,0 @@ -class removeFields { - constructor() { - this.iterateLinks(); - } - - iterateLinks() { - document.addEventListener("click", (e) => { - if (e.target && e.target.className == "remove_fields") { - this.handleClick(e.target, e); - } - }); - } - - handleClick(link, e) { - // Stop the function from executing if a link or event were not passed into the function. - if (!link || !e) return; - // Prevent the browser from following the URL. - e.preventDefault(); - // Find the parent wrapper for the set of nested fields. - let fieldParent = link.closest(".nested-fields"); - // If there is a parent wrapper, find the hidden delete field. - let deleteField = fieldParent - ? fieldParent.querySelector('input[type="hidden"]') - : null; - // If there is a delete field, update the value to `1` and hide the corresponding nested fields. - if (deleteField) { - deleteField.value = 1; - fieldParent.style.display = "none"; - } - } -} -window.addEventListener("turbo:frame-render", () => new removeFields()); \ No newline at end of file diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 20bd665de..6ba2d3dce 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -24,7 +24,7 @@ %tr %td= render "person_role_fields", person_role: person_role %tr - %td + %td{"data-controller"=>"person-roles"} = link_to_add_role "Neue Funktion", form, :person_roles %th.fw-normal Organisationseinheit %tr diff --git a/app/views/people/_person_role_fields.html.haml b/app/views/people/_person_role_fields.html.haml index cc427862e..a7f075d8f 100644 --- a/app/views/people/_person_role_fields.html.haml +++ b/app/views/people/_person_role_fields.html.haml @@ -7,4 +7,4 @@ %div.d-flex.fw-light = person_role.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1 role-level-select" = person_role.number_field :percent, step: 1, class: "form-control w-50 person-role-percent" - = link_to "Remove", "#", class: "remove_fields" \ No newline at end of file + %div{"data-controller"=>"person-roles"}= link_to "Remove", "#", { class: "remove_fields", 'data-action' => 'person-roles#removeField' } \ No newline at end of file From 42b8ec9e22807fe34ca46effaa2b02bf8f325779 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 12 Mar 2024 14:27:13 +0100 Subject: [PATCH 69/80] Fix picture controller spec and rename feature spec --- spec/controllers/people/picture_controller_spec.rb | 3 +++ spec/features/{people_controller_spec.rb => people_spec.rb} | 0 2 files changed, 3 insertions(+) rename spec/features/{people_controller_spec.rb => people_spec.rb} (100%) diff --git a/spec/controllers/people/picture_controller_spec.rb b/spec/controllers/people/picture_controller_spec.rb index ba68f5f81..5351f5d86 100644 --- a/spec/controllers/people/picture_controller_spec.rb +++ b/spec/controllers/people/picture_controller_spec.rb @@ -1,6 +1,9 @@ require 'rails_helper' describe People::PictureController do + before(:each) do + sign_in auth_users(:user), scope: :auth_user + end it 'should show default_avatar' do get :show, params:{ id: bob.id } diff --git a/spec/features/people_controller_spec.rb b/spec/features/people_spec.rb similarity index 100% rename from spec/features/people_controller_spec.rb rename to spec/features/people_spec.rb From aebcbd303a5c7d64f912701332edccafc3281604 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 12 Mar 2024 14:38:13 +0100 Subject: [PATCH 70/80] make show all link not display in edit view --- app/views/people/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index eac471484..22f4260af 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -58,4 +58,4 @@ %div.border.border-dark-subtle.mt-1.p-2.rounded - @person.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" - = link_to "Show all", people_path \ No newline at end of file + = link_to "Show all", people_path, {"data-turbo"=>false} \ No newline at end of file From a36806088593ac40cfc71b469a6a10a10c90ba9e Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 15 Mar 2024 08:11:58 +0100 Subject: [PATCH 71/80] resolve styling conversations --- app/assets/stylesheets/styles.scss | 7 +++---- app/views/people/_form.html.haml | 2 +- app/views/people/_person_role_fields.html.haml | 2 +- app/views/people/show.html.haml | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/styles.scss b/app/assets/stylesheets/styles.scss index c86d47508..e2c9b4a45 100644 --- a/app/assets/stylesheets/styles.scss +++ b/app/assets/stylesheets/styles.scss @@ -1,5 +1,6 @@ $skills-blue: #3b7bbe; $skills-text-gray: #8e8e8e; +$skills-gray: #f5f5f5; @import "bootstrap"; @@ -44,13 +45,11 @@ pzsh-topbar { color: $skills-text-gray; } -.personals-header { - background: #f5f5f5; - max-width: 100%; +.person-profile-header { + background: $skills-gray; height: 3.25rem; padding: 12px 20px 12px 20px; font-size: 18px; - border-bottom: #d6d6d6 1px solid; } .bg-skills-blue { diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 6ba2d3dce..8f1cad9b7 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -1,5 +1,5 @@ = form_with model: @person do |form| - %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column + %div.d-flex.flex-xl-row.flex-column %div.col-xl-3.col-12 %img.rounded-circle#avatar{src: "#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} %br diff --git a/app/views/people/_person_role_fields.html.haml b/app/views/people/_person_role_fields.html.haml index a7f075d8f..9b4b24cca 100644 --- a/app/views/people/_person_role_fields.html.haml +++ b/app/views/people/_person_role_fields.html.haml @@ -6,5 +6,5 @@ Stufe %div.d-flex.fw-light = person_role.collection_select :person_role_level_id, PersonRoleLevel.order(:level), :id, :level, {}, class: "form-select w-50 me-1 role-level-select" - = person_role.number_field :percent, step: 1, class: "form-control w-50 person-role-percent" + = person_role.number_field :percent, in: 0..200, step: 1, class: "form-control w-50 person-role-percent" %div{"data-controller"=>"person-roles"}= link_to "Remove", "#", { class: "remove_fields", 'data-action' => 'person-roles#removeField' } \ No newline at end of file diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 22f4260af..a5db1ffe2 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -1,10 +1,10 @@ %div =render partial:"people/search", :locals => {person: @person} - %div.personals-header + %div.person-profile-header.mw-100.border-bottom Personalien %div.mt-4 %turbo-frame{id: "#{dom_id @person}"} - %div.d-flex.flex-xl-row.flex-lg-column.flex-md-column.flex-sm-column.flex-column + %div.d-flex.flex-xl-row.flex-column %div.col-xl-3.col-12 %img.rounded-circle{src: "/people/#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} %div.mt-3= link_to "Bearbeiten", edit_person_path, id: "edit-button" From 999499d3594ba64d78d44bb08e327dcfa07069cd Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 15 Mar 2024 08:19:18 +0100 Subject: [PATCH 72/80] Rename ms translations to marital_statuses and refactor all its usages, interpolate bobs id in picture controller test --- app/views/people/_form.html.haml | 2 +- app/views/people/show.html.haml | 2 +- config/locales/de.yml | 2 +- config/locales/en.yml | 2 +- spec/controllers/people/picture_controller_spec.rb | 2 +- spec/features/people_spec.rb | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 8f1cad9b7..905077900 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -53,7 +53,7 @@ %td= form.collection_select :nationality2, ISO3166::Country.all.sort.map { |country| [country.alpha2, country.translations[I18n.locale]] }, :first, :last, {}, class: "form-select mw-100" %th.fw-normal Zivilstand %tr - %td= form.collection_select :marital_status, Person.marital_statuses.keys.map { |ms| [ms, t("ms.#{ms}")] }, :first, :last, { selected: @person.marital_status }, class: "form-select mw-100" + %td= form.collection_select :marital_status, Person.marital_statuses.keys.map { |marital_status| [marital_status, t("marital_statuses.#{marital_status}")] }, :first, :last, { selected: @person.marital_status }, class: "form-select mw-100" %th.fw-normal Kürzel %tr %td= form.text_field :shortname, class: "mw-100 form-control" diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index a5db1ffe2..869981142 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -48,7 +48,7 @@ %td.text-break= @person.location %th.fw-light Zivilstand %tr - %td= t("ms.#{@person.marital_status}") + %td= t("marital_statuses.#{@person.marital_status}") %th.fw-light Kürzel %tr %td= @person.shortname.blank? ? '-' : @person.shortname diff --git a/config/locales/de.yml b/config/locales/de.yml index 9e35a05a0..dd9767842 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -8,7 +8,7 @@ de: default_set: Default-Set radar: Radar modify: Ändern - ms: + marital_statuses: single: ledig married: verheiratet widowed: verwitwet diff --git a/config/locales/en.yml b/config/locales/en.yml index 9f0d1c52f..9e353989a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -8,7 +8,7 @@ en: default_set: Defaultset radar: Radar modify: Modify - ms: + marital_statuses: single: single married: married widowed: widowed diff --git a/spec/controllers/people/picture_controller_spec.rb b/spec/controllers/people/picture_controller_spec.rb index 5351f5d86..7a1298f1d 100644 --- a/spec/controllers/people/picture_controller_spec.rb +++ b/spec/controllers/people/picture_controller_spec.rb @@ -23,7 +23,7 @@ expect(response.status).to eq(200) expect(bob['picture']).to eq('picture.png') - expect(path).to eq('/people/902541635/picture') + expect(path).to eq("/people/#{bob.id}/picture") process :show, method: :get , params: { id: bob.id } diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index d0d7e46e1..23292e025 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -59,7 +59,7 @@ def fill_out_person_form check 'nat-two-checkbox' select ISO3166::Country["DE"].translations[I18n.locale], from: 'person_nationality' select ISO3166::Country["US"].translations[I18n.locale], from: 'person_nationality2' - select I18n.t('ms.married'), from: 'person_marital_status' + select I18n.t('marital_statuses.married'), from: 'person_marital_status' fill_in 'person_shortname', with: 'bb' end @@ -100,7 +100,7 @@ def fill_out_person_form expect(page.all('.nationality-two').count).to equal(bob.nationality2.nil? ? 0 : 2) expect(page).to have_select('person_nationality', selected: ISO3166::Country[bob.nationality].translations[I18n.locale]) bob.nationality2.nil? ? (expect(page).not_to have_select('person_nationality2')) : (expect(page).to have_select('person_nationality2', selected: ISO3166::Country[bob.nationality2].translations[I18n.locale])) - expect(page).to have_select('person_marital_status', selected: I18n.t("ms.#{bob.marital_status}")) + expect(page).to have_select('person_marital_status', selected: I18n.t("marital_statuses.#{bob.marital_status}")) expect(page).to have_field('person_shortname', with: bob.shortname) end From 07f24f47ce645fcfa09aad031b345607730b5d7e Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 15 Mar 2024 08:27:27 +0100 Subject: [PATCH 73/80] Bring back api route to un-xdescribe api test --- config/routes.rb | 7 +++++++ spec/controllers/api/people/picture_controller_spec.rb | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 7b930ff00..120f4ffb7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -37,6 +37,13 @@ end end + resources :people do + member do + put 'picture', to: 'people/picture#update' + get 'picture', to: 'people/picture#show' + end + end + resources :skills do collection do get 'unrated_by_person' diff --git a/spec/controllers/api/people/picture_controller_spec.rb b/spec/controllers/api/people/picture_controller_spec.rb index 9dc69621b..b23054202 100644 --- a/spec/controllers/api/people/picture_controller_spec.rb +++ b/spec/controllers/api/people/picture_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -xdescribe Api::People::PictureController do +describe Api::People::PictureController do it 'should show default_avatar' do get :show, params:{ id: bob.id } @@ -20,7 +20,7 @@ expect(response.status).to eq(200) expect(bob['picture']).to eq('picture.png') - expect(path).to eq('/api/people/902541635/picture') + expect(path).to eq("/api/people/#{bob.id}/picture") process :show, method: :get , params: { id: bob.id } From cdf6d6df4e352f7e9d5d53fbb9cb6ba22f3f0745 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 15 Mar 2024 09:02:18 +0100 Subject: [PATCH 74/80] move some stuff from view to helper methods in new person_helper --- app/helpers/person_helper.rb | 29 +++++++++++++++++++++++++++++ app/views/people/_form.html.haml | 6 +++--- app/views/people/show.html.haml | 4 ++-- 3 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 app/helpers/person_helper.rb diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb new file mode 100644 index 000000000..0c2c97477 --- /dev/null +++ b/app/helpers/person_helper.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module PersonHelper + def nationality_string(nationality, nationality2) + if nationality2.blank? + ISO3166::Country[nationality].translations[I18n.locale] + else + "#{ISO3166::Country[nationality].translations[I18n.locale]}, + #{ISO3166::Country[nationality2].translations[I18n.locale]}" + end + end + + def person_role_string(person_role) + "#{person_role.role.name} #{person_role.person_role_level&.level} + #{person_role.percent.nil? ? '' : "#{person_role.percent.to_i}%"}" + end + + def marital_status_translation_map + Person.marital_statuses.keys.map do |marital_status| + [marital_status, t("marital_statuses.#{marital_status}")] + end + end + + def country_alpha2_translation_map + ISO3166::Country.all.sort.map do |country| + [country.alpha2, country.translations[I18n.locale]] + end + end +end diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index 905077900..becc1b760 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -47,13 +47,13 @@ %td{"data-controller"=>"nationality-two"}= check_box :has_nationality2, "checked", {"checked" => @person.nationality2?, "data-action" => "nationality-two#nationalityTwoVisible", "id" => "nat-two-checkbox"} %th.fw-normal Erste Nationalität %tr - %td= form.collection_select :nationality, ISO3166::Country.all.sort.map { |country| [country.alpha2, country.translations[I18n.locale]] }, :first, :last, {}, class: "form-select mw-100" + %td= form.collection_select :nationality, country_alpha2_translation_map, :first, :last, {}, class: "form-select mw-100" %th.fw-normal.nationality-two Zweite Nationalität %tr.nationality-two - %td= form.collection_select :nationality2, ISO3166::Country.all.sort.map { |country| [country.alpha2, country.translations[I18n.locale]] }, :first, :last, {}, class: "form-select mw-100" + %td= form.collection_select :nationality2, country_alpha2_translation_map, :first, :last, {}, class: "form-select mw-100" %th.fw-normal Zivilstand %tr - %td= form.collection_select :marital_status, Person.marital_statuses.keys.map { |marital_status| [marital_status, t("marital_statuses.#{marital_status}")] }, :first, :last, { selected: @person.marital_status }, class: "form-select mw-100" + %td= form.collection_select :marital_status, marital_status_translation_map, :first, :last, { selected: @person.marital_status }, class: "form-select mw-100" %th.fw-normal Kürzel %tr %td= form.text_field :shortname, class: "mw-100 form-control" diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 869981142..04bbc9f0f 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -24,7 +24,7 @@ - unless @person.person_roles.empty? - @person.person_roles.each do |person_role| %tr - %td= "#{person_role.role.name} #{person_role.person_role_level&.level} #{person_role.percent.nil? ? '' : person_role.percent.to_i.to_s + '%'}" + %td= person_role_string(person_role) - else %tr %td - @@ -42,7 +42,7 @@ %td= @person.birthdate.to_date.strftime('%d.%m.%Y') %th.fw-light Nationalität %tr - %td.text-break= @person.nationality2.blank? ? ISO3166::Country[@person.nationality].translations[I18n.locale] : "#{ISO3166::Country[@person.nationality].translations[I18n.locale]}, #{ISO3166::Country[@person.nationality2].translations[I18n.locale]}" + %td.text-break= nationality_string(@person.nationality, @person.nationality2) %th.fw-light Wohnort (Stadt) %tr %td.text-break= @person.location From 1b2e35a5f5257f490ee4780a57e664068ad7d6f6 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 15 Mar 2024 09:10:10 +0100 Subject: [PATCH 75/80] make attribute headers in view look like in old skills --- app/views/people/show.html.haml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 04bbc9f0f..2d038a22e 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -11,16 +11,16 @@ %div.pe-5.col-xl-3.col-12 %table.fixed-table %tbody - %th.fw-light Name + %th.fw-normal.text-gray Name %tr %td.text-break= @person.name - %th.fw-light Email + %th.fw-normal.text-gray Email %tr %td.text-break= @person.email - %th.fw-light Abschluss + %th.fw-normal.text-gray Abschluss %tr %td.text-break= @person.title - %th.fw-light Funktion + %th.fw-normal.text-gray Funktion - unless @person.person_roles.empty? - @person.person_roles.each do |person_role| %tr @@ -28,33 +28,33 @@ - else %tr %td - - %th.fw-light Organisationseinheit + %th.fw-normal.text-gray Organisationseinheit %tr %td= @person.department.nil? ? '-' : @person.department.name - %th.fw-light Firma + %th.fw-normal.text-gray Firma %tr %td= @person.company.name %div.pe-5.col-xl-3.col-12 %table.fixed-table %tbody - %th.fw-light Geburtsdatum + %th.fw-normal.text-gray Geburtsdatum %tr %td= @person.birthdate.to_date.strftime('%d.%m.%Y') - %th.fw-light Nationalität + %th.fw-normal.text-gray Nationalität %tr %td.text-break= nationality_string(@person.nationality, @person.nationality2) - %th.fw-light Wohnort (Stadt) + %th.fw-normal.text-gray Wohnort (Stadt) %tr %td.text-break= @person.location - %th.fw-light Zivilstand + %th.fw-normal.text-gray Zivilstand %tr %td= t("marital_statuses.#{@person.marital_status}") - %th.fw-light Kürzel + %th.fw-normal.text-gray Kürzel %tr %td= @person.shortname.blank? ? '-' : @person.shortname %div.col-xl-3.col-12 - %div.fw-light Sprachen + %div.fw-normal.text-gray Sprachen %div.border.border-dark-subtle.mt-1.p-2.rounded - @person.language_skills.each do |language| %div.mb-1= "#{language.language}: #{language.level} - #{language.certificate}" From 2f767043d92450ff364b974d3a578a6e62302393 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 15 Mar 2024 10:30:16 +0100 Subject: [PATCH 76/80] fix loading of picture on form validation failure --- app/views/people/_form.html.haml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index becc1b760..ea207754b 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -1,7 +1,10 @@ = form_with model: @person do |form| %div.d-flex.flex-xl-row.flex-column %div.col-xl-3.col-12 - %img.rounded-circle#avatar{src: "#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} + - if @person.picture&.file&.file&.include? "tmp" + %img.rounded-circle#avatar{src: "#{@person.picture}?#{Time.now.to_f}", width: '141', height: '141'} + - else + %img.rounded-circle#avatar{src: "#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} %br %label.btn.btn-link{for: "avatar-uploader"} Bild ändern %div.visually-hidden{"data-controller"=>"image-upload"}= form.file_field :picture, { accept: "image/", "data-action" => "image-upload#changeImage", id: "avatar-uploader" } From 4986d9d00998b27642ef074ae5eacc969eb5299f Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 15 Mar 2024 10:38:38 +0100 Subject: [PATCH 77/80] Move code to check if picture is cached to helper method --- app/helpers/person_helper.rb | 6 ++++++ app/views/people/_form.html.haml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 0c2c97477..168c81ddd 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -26,4 +26,10 @@ def country_alpha2_translation_map [country.alpha2, country.translations[I18n.locale]] end end + + # If the path of the avatar includes tmp, the picture is cached + # and we can load it directly without the picture controller + def avatar_cached(picture) + picture&.file&.file&.include? 'tmp' + end end diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index ea207754b..bd572d1a6 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -1,7 +1,7 @@ = form_with model: @person do |form| %div.d-flex.flex-xl-row.flex-column %div.col-xl-3.col-12 - - if @person.picture&.file&.file&.include? "tmp" + - if avatar_cached(@person.picture) %img.rounded-circle#avatar{src: "#{@person.picture}?#{Time.now.to_f}", width: '141', height: '141'} - else %img.rounded-circle#avatar{src: "#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} From 1cbc9371eac3b7839ad2779e673cb201a92d7ecb Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 15 Mar 2024 10:43:32 +0100 Subject: [PATCH 78/80] rename method from avatar_cached to avatar_cached? --- app/helpers/person_helper.rb | 2 +- app/views/people/_form.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 168c81ddd..33613661c 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -29,7 +29,7 @@ def country_alpha2_translation_map # If the path of the avatar includes tmp, the picture is cached # and we can load it directly without the picture controller - def avatar_cached(picture) + def avatar_cached?(picture) picture&.file&.file&.include? 'tmp' end end diff --git a/app/views/people/_form.html.haml b/app/views/people/_form.html.haml index bd572d1a6..e3ede064e 100644 --- a/app/views/people/_form.html.haml +++ b/app/views/people/_form.html.haml @@ -1,7 +1,7 @@ = form_with model: @person do |form| %div.d-flex.flex-xl-row.flex-column %div.col-xl-3.col-12 - - if avatar_cached(@person.picture) + - if avatar_cached?(@person.picture) %img.rounded-circle#avatar{src: "#{@person.picture}?#{Time.now.to_f}", width: '141', height: '141'} - else %img.rounded-circle#avatar{src: "#{@person.id}/picture?#{Time.now.to_f}", width: '141', height: '141'} From 48c2893825175cfc47ef44c7652c535b6291838c Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 15 Mar 2024 10:53:44 +0100 Subject: [PATCH 79/80] add paddings to information of person for improved distinguishability --- app/views/people/show.html.haml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 2d038a22e..bc9089d84 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -13,24 +13,24 @@ %tbody %th.fw-normal.text-gray Name %tr - %td.text-break= @person.name + %td.text-break.pb-1= @person.name %th.fw-normal.text-gray Email %tr - %td.text-break= @person.email + %td.text-break.pb-1= @person.email %th.fw-normal.text-gray Abschluss %tr - %td.text-break= @person.title + %td.text-break.pb-1= @person.title %th.fw-normal.text-gray Funktion - unless @person.person_roles.empty? - @person.person_roles.each do |person_role| %tr - %td= person_role_string(person_role) + %td.pb-1= person_role_string(person_role) - else %tr %td - %th.fw-normal.text-gray Organisationseinheit %tr - %td= @person.department.nil? ? '-' : @person.department.name + %td.pb-1= @person.department.nil? ? '-' : @person.department.name %th.fw-normal.text-gray Firma %tr %td= @person.company.name @@ -39,16 +39,16 @@ %tbody %th.fw-normal.text-gray Geburtsdatum %tr - %td= @person.birthdate.to_date.strftime('%d.%m.%Y') + %td.pb-1= @person.birthdate.to_date.strftime('%d.%m.%Y') %th.fw-normal.text-gray Nationalität %tr - %td.text-break= nationality_string(@person.nationality, @person.nationality2) + %td.text-break.pb-1= nationality_string(@person.nationality, @person.nationality2) %th.fw-normal.text-gray Wohnort (Stadt) %tr - %td.text-break= @person.location + %td.text-break.pb-1= @person.location %th.fw-normal.text-gray Zivilstand %tr - %td= t("marital_statuses.#{@person.marital_status}") + %td.pb-1= t("marital_statuses.#{@person.marital_status}") %th.fw-normal.text-gray Kürzel %tr %td= @person.shortname.blank? ? '-' : @person.shortname From efbd8374826a8b4b78cda5ad4b2115b572ce6092 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 15 Mar 2024 11:03:24 +0100 Subject: [PATCH 80/80] fix deleting of roles when edit form fails --- app/javascript/controllers/person_roles_controller.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/javascript/controllers/person_roles_controller.js b/app/javascript/controllers/person_roles_controller.js index 2ce8187d8..15a7f57cf 100644 --- a/app/javascript/controllers/person_roles_controller.js +++ b/app/javascript/controllers/person_roles_controller.js @@ -1,6 +1,13 @@ import { Controller } from "@hotwired/stimulus" export default class extends Controller { + connect() { + for(let nested_field of document.getElementsByClassName("nested-fields")) { + if(nested_field.querySelector('input[type="hidden"]').value === "true") { + nested_field.style.display = "none"; + } + } + } addField(e) { let link = e.target // Stop the function from executing if a link or event were not passed into the function.