Skip to content

Commit

Permalink
Feature/650-default-skills (#676)
Browse files Browse the repository at this point in the history
* squash branch

* Replace if ! with unless

* Remove duplicate keys from translation file

* Fix validate_interest helper function, to match rgb or rgba value

* Make people skills model set skill level and interest to 1 if they are 0 but not unrated

* Bring back missing translation in de.yml

* Bring back people skills rating filter

* Fix tests after reimplementing people rating filter

* Fix specs

* Test reset button on people skills edit view

* Implement test to test if interest is changed to 1 when level is chagned

* disable caching for specifi page

* Prevent resorting of skills after updating their value

---------

Co-authored-by: Yanick Minder <[email protected]>
  • Loading branch information
RandomTannenbaum and kcinay055679 authored Jun 11, 2024
1 parent 018004c commit 3e6a5c0
Show file tree
Hide file tree
Showing 26 changed files with 430 additions and 220 deletions.
25 changes: 21 additions & 4 deletions app/controllers/people/people_skills_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@

class People::PeopleSkillsController < CrudController
include ParamConverters
self.permitted_attrs = [{ people_skills_attributes: [:id, :certificate, :level,
:interest, :core_competence, :_destroy] }]
self.permitted_attrs = [{ people_skills_attributes: [:id, :certificate, :level, :interest,
:core_competence, :skill_id, :unrated,
:_destroy] }]
before_action :set_person

def self.model_class
Person
end

def update
@people_skills = filtered_people_skills
if params[:person].blank?
render(:index, status: :ok)
else
super
return
end
super do |format, success|
format.turbo_stream { render 'people/people_skills/update', status: :ok } if success
end
end

Expand All @@ -27,4 +31,17 @@ def show_path
def set_person
@person = Person.find(params[:id])
end

def filtered_people_skills
return @person.people_skills if params[:rating].blank?

filter_by_rating(@person.people_skills, params[:rating])
end

def filter_by_rating(people_skills, rating)
return people_skills.where('level > ?', 0) if rating == '0'
return people_skills.where(level: 0) if rating == '-1'

people_skills
end
end
5 changes: 0 additions & 5 deletions app/controllers/people/people_skills_create_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ class People::PeopleSkillsCreateController < CrudController
{ skill_attributes:
[:id, :title, :radar, :portfolio, :default_set, :category_id] }]
self.nesting = Person
helper_method :people_skills_of_category
layout 'person'

def index
Expand Down Expand Up @@ -45,8 +44,4 @@ def filter_by_rating(people_skills, rating)
def self.controller_path
'people/people_skills'
end

def people_skills_of_category(category)
@people_skills.where(skill_id: category.skills.ids)
end
end
16 changes: 14 additions & 2 deletions app/helpers/person_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,19 @@ def language_skill_levels
%w[Keine A1 A2 B1 B2 C1 C2 Muttersprache]
end

def people_skills_of_category(person, category)
person.people_skills.where(skill_id: category.skills.pluck(:id))
def people_skills_of_category(category)
@people_skills.where(skill_id: category.skills.pluck(:id)).sort_by(&:id)
end

def not_rated_default_skills(person)
rated_skills = person.skills
not_rated_default_skills = Skill.all.filter do |skill|
skill.default_set && rated_skills.exclude?(skill)
end

not_rated_default_skills.map do |skill|
PeopleSkill.new({ person_id: person.id, skill_id: skill.id, level: 1, interest: 1,
certificate: false, core_competence: false })
end
end
end
32 changes: 31 additions & 1 deletion app/javascript/controllers/people_skills_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@ import SlimSelect from 'slim-select'
export default class extends Controller {
static targets = ['switch', 'label', 'skillsDropdown', 'categoriesDropdown', 'skillTitle']
levels = ["Nicht Bewertet", "Trainee", "Junior", "Professional", "Senior", "Expert"]
skills = Array.from(this.skillsDropdownTarget.options).map(e => { return { id: e.value, title: e.innerHTML } })
skills = Array.from(this.hasSkillsDropdownTarget ? this.skillsDropdownTarget.options : []).map(e => { return { id: e.value, title: e.innerHTML } })


connect() {
if (!this.hasSkillsDropdownTarget){
Turbo.cache.exemptPageFromCache()
return;
}


const select = new SlimSelect({
select: this.skillsDropdownTarget,
events: {
Expand Down Expand Up @@ -53,4 +59,28 @@ export default class extends Controller {
Array.from(this.categoriesDropdownTarget.parentElement.children).forEach(e => e.hidden = is_existing_skill);
this.categoriesDropdownTarget.value = is_existing_skill ? skill_category_id : ""
}

unrateSkill(e) {
e.preventDefault();
this.setUnratedField(e, true);
e.target.form.requestSubmit();
}

rateSkill(e) {
e.preventDefault();
if(!this.isEditMode(e)) return;
this.setUnratedField(e, false);
e.target.form.requestSubmit();
}

setUnratedField(e, value) {
const formElements = Array.from(e.target.form.elements);
const unratedField = formElements.find(e=> e.id.startsWith("unrated-field"))
unratedField.value = value;
}

isEditMode(e) {
const formElements = Array.from(e.target.form.elements);
return formElements.some(e=> e.id === "person_people_skills_attributes_0_id");
}
}
19 changes: 19 additions & 0 deletions app/models/people_skill.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class PeopleSkill < ApplicationRecord
belongs_to :skill
accepts_nested_attributes_for :skill

before_create :before_actions
before_update :before_actions

validates :certificate, :core_competence, exclusion: { in: [nil],
message: 'muss ausgefüllt werden' }

Expand All @@ -43,4 +46,20 @@ def skill_attributes=(attributes)
end
super
end

def before_actions
self.level = 1 if level.zero? && !unrated
self.interest = 1 if interest.zero? && !unrated

if unrated
unrate
end
end

def unrate
self.level = 0
self.interest = 0
self.certificate = false
self.core_competence = false
end
end
13 changes: 13 additions & 0 deletions app/views/application/_edit_interest_stars.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
%label.form-label.text-gray= t "people-skills.interest"
.rate
= ff.radio_button :interest, 5, { checked: ff.object.interest == 5, id: "star5#{ff.object.skill.id}", "data-action": "change->people-skills#rateSkill" }
%label{for: "star5#{ff.object.skill.id}", title: "text", id: "star-label5#{ff.object.skill.id}", class: "star5"} 5 stars
= ff.radio_button :interest, 4, { checked: ff.object.interest == 4, id: "star4#{ff.object.skill.id}", "data-action": "change->people-skills#rateSkill" }
%label{for: "star4#{ff.object.skill.id}", title: "text", id: "star-label4#{ff.object.skill.id}", class: "star4"} 4 stars
= ff.radio_button :interest, 3, { checked: ff.object.interest == 3, id: "star3#{ff.object.skill.id}", "data-action": "change->people-skills#rateSkill" }
%label{for: "star3#{ff.object.skill.id}", title: "text", id: "star-label3#{ff.object.skill.id}", class: "star3"} 3 stars
= ff.radio_button :interest, 2, { checked: ff.object.interest == 2, id: "star2#{ff.object.skill.id}", "data-action": "change->people-skills#rateSkill" }
%label{for: "star2#{ff.object.skill.id}", title: "text", id: "star-label2#{ff.object.skill.id}", class: "star2"} 2 stars
= ff.radio_button :interest, 1, { checked: (ff.object.id.nil? && ff.object.interest.nil?) || ff.object.interest == 1, id: "star1#{ff.object.skill.id}", "data-action": "change->people-skills#rateSkill" }
%label{for: "star1#{ff.object.skill.id}", title: "text", id: "star-label1#{ff.object.skill.id}", class: "star1"} 1 star
= ff.radio_button :interest, 0, id: "default-star-#{ff.object.skill.id}", class: "visually-hidden"
17 changes: 17 additions & 0 deletions app/views/application/_show_interest_stars.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
%label.form-label.text-gray= t "people-skills.interest"
.rate.rate-show
%input{type: "radio", value: 5, id: "star5#{person_skill.id}",
checked: person_skill.interest == 5, disabled: true}/
%label{for: "star5#{person_skill.id}", title: "text", id: "star-label5#{person_skill.id}"} 5 stars
%input{type: "radio", value: 4, id: "star4#{person_skill.id}",
checked: person_skill.interest == 4, disabled: true}/
%label{for: "star4#{person_skill.id}", title: "text", id: "star-label4#{person_skill.id}"} 4 stars
%input{type: "radio", value: 3, id: "star3#{person_skill.id}",
checked: person_skill.interest == 3, disabled: true}/
%label{for: "star3#{person_skill.id}", title: "text", id: "star-label3#{person_skill.id}"} 3 stars
%input{type: "radio", value: 2, id: "star2#{person_skill.id}",
checked: person_skill.interest == 2, disabled: true}/
%label{for: "star2#{person_skill.id}", title: "text", id: "star-label2#{person_skill.id}"} 2 stars
%input{type: "radio", value: 1, id: "star1#{person_skill.id}",
checked: person_skill.interest == 1, disabled: true}/
%label{for: "star1#{person_skill.id}", title: "text", id: "star-label1#{person_skill.id}"} 1 star
31 changes: 31 additions & 0 deletions app/views/people/people_skills/_edit_form.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
%div.mw-100.border-bottom.text-black.ps-5.border{id: "default-skill-#{ff.object.skill.id}"}
%div.d-flex.flex-row.align-items-center.mt-3.mb-3.w-100{data: {controller: "people-skills"}}
%div.col-2
= ff.object.skill.title
= ff.hidden_field :interest
= ff.hidden_field :unrated, value: false, id: "unrated-field-#{ff.object.skill.id}"
%div.col-2
%div.d-flex.flex-column.align-items-center
%label.form-label.text-gray= t "people-skills.levels.level"
%label.form-label.text-gray{"data-people-skills-target": "label"}= t "people-skills.levels.#{ExpertiseTopicSkillValue.skill_levels.key(ff.object.level - 1)}"
- range_min = (ff.object.id.nil? || ff.object.level != 0) ? 1 : 0
= ff.range_field :level, min: range_min, max: 5, class: "form-range w-75",
"data-action": "change->people-skills#displayLevelLabel people-skills#rateSkill",
"data-people-skills-target": "switch"
%div.col-2
%div.d-flex.flex-column.align-items-center
= render partial: "edit_interest_stars", locals: { ff: ff }
%div.col-2
%div.d-flex.flex-row.form-check
= ff.check_box :certificate, { class: "form-check-input me-2", "data-action": "change->people-skills#rateSkill" }
%label.form-label.text-gray= t "people-skills.certificate"
%div.col-2
%div.d-flex.flex-row.form-check
= ff.check_box :core_competence, { class: "form-check-input me-2", "data-action": "change->people-skills#rateSkill" }
%label.form-label.text-gray= t "people-skills.core-competence"
= ff.hidden_field :skill_id
%div.col-2
- if ff.object.id.nil?
= ff.submit "Bewerten", { class: "btn btn-link" }
- unless ff.object.unrated
= ff.submit "Nicht bewerten", { class: "btn btn-link", "data-action": "people-skills#unrateSkill"}
8 changes: 2 additions & 6 deletions app/views/people/people_skills/_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,8 @@

%label.form-label.text-gray#skill-level-label{"data-people-skills-target": "label"}

%label.form-label.text-gray= t "people-skills.interest"
%div.rate
- 5.downto(1) do |i|
= f.radio_button :interest, i, checked: f.object.interest == i, id: "star#{i}#{f.object.id}"
%label{for: "star#{i}#{f.object.id}", title: "text", id: "star-label#{i}#{f.object.id}", class: "star#{i}"}
= "#{i} stars"
%div
= render partial: "edit_interest_stars", locals: { ff: f }

%div
= f.check_box :certificate, class: "form-check-input me-2"
Expand Down
33 changes: 33 additions & 0 deletions app/views/people/people_skills/_overview.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
%p.d-flex.align-items-center.profile-header
Skills
="(#{@person.people_skills.count})"

%div.ms-3
= form_with(url: person_people_skills_path(@person), method: :get, data: {controller: "filter", turbo_frame: "people-skills"}) do |f|
%span.btn-group
- rating = request.query_parameters[:rating]
= f.radio_button :rating, 1, class: "btn-check", checked: rating == "1",
onClick: "this.form.requestSubmit()", data: {action: "change->filter#submit"}
= f.label :rating, t("people-skills.filter.all"), value: 1, class: "btn btn-outline-primary"

= f.radio_button :rating, 0, class: "btn-check", checked: rating == "0",
onClick: "this.form.requestSubmit()", data: {action: "change->filter#submit"}
= f.label :rating, t("people-skills.filter.rated"), value: 0, class: "btn btn-outline-primary"

= f.radio_button :rating, -1, class: "btn-check", checked: rating == "-1",
onClick: "this.form.requestSubmit()", data: {action: "change->filter#submit"}
= f.label :rating, t("people-skills.filter.unrated"), value: -1, class: "btn btn-outline-primary"

= turbo_frame_tag 'people-skills' do
- Category.all_parents.each do |category|
%div.profile-header.mw-100.border-bottom.mt-4{id: category.title, "data-scroll-target": "scrollItem"}
= category.title
- ([category] + category.children.to_a).each do |category_child|
- people_skills_of_category = people_skills_of_category(category_child)
%div.white-header.mw-100.border-bottom.text-gray
=category_child.title + " (#{people_skills_of_category.count})"
- people_skills_of_category.each do |person_skill|
- @person_skill = person_skill
= form_with model: @person, url: people_skills_person_path(@person, rating: params["rating"]) do |form|
= form.fields_for :people_skills, @person_skill do |ff|
= render "people/people_skills/edit_form", ff: ff
49 changes: 0 additions & 49 deletions app/views/people/people_skills/edit.html.haml

This file was deleted.

2 changes: 2 additions & 0 deletions app/views/people/people_skills/edit.turbo_stream.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
= turbo_stream.update "default-skill-errors" do
= render "application/error_banners", errors: @person.errors
Loading

0 comments on commit 3e6a5c0

Please sign in to comment.