-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add first tables to display profile data * add language and profile pic to view and add a new section in the view respectively. make roles display correctly * style headers of user profile data table and move edit link * display languages in a very basic way * make account overview display country name instead of alpha2 code and implement most of the edit form to edit a user-profile * fix displaying of values in dropdowns, to represent actual state of object and add fields for percentage and level * label role form fields and correctly display role in overview * replace @entry with @person after rebase and remove nested_models and permitted_relationships from people controller * 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 * fix alignment of tables, set width of input fields to match table width, add save button and fix saving of form * style edit form to use bootstrap form fields * adjust font-weights of edit form * 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 * add default avatar to public directory * 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 * add picture to permitted attrs * add dummy role adding button in person edit view and make marital status dropdown have correct value selected on edit * start working on updating roles by renaming the params in the form and overriding the update method in the controller * rewrite profile to use fields_for instead of a normal for loop, for saving new roles * add person_roles_attributes to permitted attributes * make edit view conditionally display the second nationality dropdown depending on checkbox state * make person overview and edit view responsive * remove overflow scroll from person overview and edit view * move fields of role form to partial and start writing logic to create new roles * add remove button to roles in edit view and fix rendering of form * 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 * 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 * fix name attribute of contries in form * replace pzsh container with div to prevent moving whole page to center * style the show view of the person * fix styling of edit view * change w-100 to mw-100 everywhere in edit view * make image instantly update on file upload by using a stimulus controller * fix nationality2 checkbox * add picture cache for profile picture, style picture upload button fix error in person edit turbostream * adjust color of buttons in person edit view * fix loading of profile picture after saving and style profile picture upload button * 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 * fix rubocop offenses * fix last rubocop offenses * write test that tests if editing a person is possible, assign id to save and edit buttons for testing, make editing shortname possible * remove unwanted header from person profile * change dateformat in equal check of feature spec to make test work across all systems * change _ to - in ids of save cancel and edit buttons and write test that tests if canceling really doesnt save the person * revert formating of date in test * bring back formatting of date in test * Change filling of date input in test to default html * Fix date formating for filling form in test * make test also upload new image and check if avatar upload field exists * rename method of has_nationality2 checkbox to checked and start writing people_controller spec * 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 * Remove rubocop offense and check if nationality2 is not null initially in person controller test * style person show view to wrap text and replace some unless statements with ternary operators * reimplement whole picture controller from api namespace, cleanup code * move picture test from api namespace to people namespace and xdescribe old test * fix rubocop offense * Dont display role percentage if there is no role percentage in person overview * revert unnecessary file change * remove unneeded picture helpers and specs * add translations for marital statuses * fix loading of avatar because it vanished in specific cases * fix translation yml files and translate marital status and nationality * fix tests after localization and test if avatar is saved in feature spec * replace alpha2 code with actual country name in people show view * make picture controller inherit from new crud controller instead of api crud controller * make people controller test also test if nationality is saved correctly * fix specs after rebase * move functions to add and remove roles to stimulus controller * Fix picture controller spec and rename feature spec * make show all link not display in edit view * resolve styling conversations * Rename ms translations to marital_statuses and refactor all its usages, interpolate bobs id in picture controller test * Bring back api route to un-xdescribe api test * move some stuff from view to helper methods in new person_helper * make attribute headers in view look like in old skills * fix loading of picture on form validation failure * Move code to check if picture is cached to helper method * rename method from avatar_cached to avatar_cached? * add paddings to information of person for improved distinguishability * fix deleting of roles when edit form fails
- Loading branch information
1 parent
c49643b
commit 69f4f08
Showing
28 changed files
with
633 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# frozen_string_literal: true | ||
|
||
module People | ||
class PictureController < CrudController | ||
|
||
self.permitted_attrs = %i[picture] | ||
|
||
def update | ||
person.update!(picture: params[:picture]) | ||
render json: { data: { picture_path: picture_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 model_class | ||
Person | ||
end | ||
|
||
def person | ||
@person ||= Person.find(params[:id]) | ||
end | ||
|
||
def default_avatar_path | ||
get_asset_path 'default_avatar.png' | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# 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 | ||
|
||
# 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# 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. | ||
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, '#', | ||
{ class: 'add_fields', 'data-action' => 'person-roles#addField', | ||
data: { id: id, fields: fields.gsub("\n", '') } }) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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]) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
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. | ||
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; | ||
} | ||
|
||
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"; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
= 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) | ||
%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" } | ||
= form.hidden_field :picture_cache | ||
%div.pe-5.col-xl-3.col-12 | ||
%table | ||
%tbody | ||
%th.fw-normal Name | ||
%tr | ||
%td= form.text_field :name, class: "mw-100 form-control" | ||
%th.fw-normal Email | ||
%tr | ||
%td= form.text_field :email, class: "mw-100, form-control" | ||
%th.fw-normal Abschluss | ||
%tr | ||
%td= form.text_field :title, class: "mw-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{"data-controller"=>"person-roles"} | ||
= 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 mw-100" | ||
%th.fw-normal Firma | ||
%tr | ||
%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 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 mw-100" | ||
%th.fw-normal Doppelbürger | ||
%tr | ||
%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, 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, country_alpha2_translation_map, :first, :last, {}, class: "form-select mw-100" | ||
%th.fw-normal Zivilstand | ||
%tr | ||
%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" | ||
%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", id: "save-button" } | ||
= link_to "Abbrechen", person_path, { id: "cancel-button" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +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 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 role-level-select" | ||
= 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' } |
Oops, something went wrong.