From ce24096217dfdc7ad9551695b7621049eeee90e9 Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 9 May 2025 09:08:52 +0200 Subject: [PATCH 01/15] Setup controller, view, model and necessary routes. Add tab to navbar for easy navigation --- app/controllers/team_skills_controller.rb | 6 ++++++ app/helpers/tab_helper.rb | 3 ++- app/models/team_skill.rb | 3 +++ app/views/team_skills/index.html.haml | 5 +++++ config/routes.rb | 2 ++ 5 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 app/controllers/team_skills_controller.rb create mode 100644 app/models/team_skill.rb create mode 100644 app/views/team_skills/index.html.haml diff --git a/app/controllers/team_skills_controller.rb b/app/controllers/team_skills_controller.rb new file mode 100644 index 000000000..444d6c890 --- /dev/null +++ b/app/controllers/team_skills_controller.rb @@ -0,0 +1,6 @@ +class TeamSkillsController < CrudController + + def index + + end +end \ No newline at end of file diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index 23ecd85a2..94931f36c 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -18,7 +18,8 @@ def global_tabs { title: ti('navbar.skill_search'), path: people_skills_path, admin_only: false }, { title: ti('navbar.cv_search'), path: cv_search_index_path, admin_only: false }, { title: ti('navbar.skillset'), path: skills_path, admin_only: false }, - { title: ti('navbar.certificates'), path: certificates_path, admin_only: true } + { title: ti('navbar.certificates'), path: certificates_path, admin_only: true }, + { title: 'Team Skills', path: team_skills_path, admin_only: false }, ] end diff --git a/app/models/team_skill.rb b/app/models/team_skill.rb new file mode 100644 index 000000000..14e81ec7a --- /dev/null +++ b/app/models/team_skill.rb @@ -0,0 +1,3 @@ +class TeamSkill < ApplicationRecord + +end \ No newline at end of file diff --git a/app/views/team_skills/index.html.haml b/app/views/team_skills/index.html.haml new file mode 100644 index 000000000..ca96771ec --- /dev/null +++ b/app/views/team_skills/index.html.haml @@ -0,0 +1,5 @@ +%label{ for: "department_select" } Department +%select#department_select{name: "department_id"} + %option{value: ""} Select a Department + - Department.all.each do |department| + %option{value: department.id}= department.name diff --git a/config/routes.rb b/config/routes.rb index 339512201..067ebb8ef 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -67,6 +67,8 @@ end resources :certificates + + resources :team_skills, only: [:index, :show] end From 5a7bd63695dfc5b155dc4c659939b58cf6bd450e Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 9 May 2025 15:50:52 +0200 Subject: [PATCH 02/15] Add basic structure of graph --- .../controllers/chart_controller.js | 71 +++++++++++++++++++ app/views/team_skills/index.html.haml | 3 + package.json | 1 + yarn.lock | 12 ++++ 4 files changed, 87 insertions(+) create mode 100644 app/javascript/controllers/chart_controller.js diff --git a/app/javascript/controllers/chart_controller.js b/app/javascript/controllers/chart_controller.js new file mode 100644 index 000000000..a95e3ab41 --- /dev/null +++ b/app/javascript/controllers/chart_controller.js @@ -0,0 +1,71 @@ +import { Controller } from "@hotwired/stimulus" +import Chart from "chart.js/auto" + +export default class extends Controller { + static targets = ["canvas"] + + connect() { + const ctx = this.canvasTarget.getContext("2d") + + this.chart = new Chart(ctx, { + type: 'line', + data: { + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], + datasets: [ + { + label: 'Azubi', + data: [5, 10, 7, 13, 16, 20, 6, 2, 13, 22, 25, 21], + backgroundColor: 'red', + borderColor: 'red', + fill: false, + tension: 0.1 + }, + { + label: 'Junior', + data: [10, 11, 12, 6, 14, 15, 16, 17, 18, 9, 8, 7], + backgroundColor: 'blue', + borderColor: 'blue', + fill: false, + tension: 0.1 + }, + { + label: 'Senior', + data: [13, 15, 19, 12, 22, 8, 4, 16, 7, 1, 18, 19], + backgroundColor: 'green', + borderColor: 'green', + fill: false, + tension: 0.1 + }, + { + label: 'Professionell', + data: [1, 2, 3, 8, 10, 10, 14, 9, 15, 22, 22, 25], + backgroundColor: 'black', + borderColor: 'black', + fill: false, + tension: 0.1 + }, + { + label: 'Expert', + data: [18, 22, 23, 20, 18, 25, 19, 15, 13, 14, 9, 5], + backgroundColor: 'purple', + borderColor: 'purple', + fill: false, + tension: 0.1 + } + ] + }, + options: { + responsive: true, + scales: { + y: { + beginAtZero: true + } + } + } + }) + } + + disconnect() { + this.chart?.destroy() + } +} diff --git a/app/views/team_skills/index.html.haml b/app/views/team_skills/index.html.haml index ca96771ec..feabe5b9f 100644 --- a/app/views/team_skills/index.html.haml +++ b/app/views/team_skills/index.html.haml @@ -3,3 +3,6 @@ %option{value: ""} Select a Department - Department.all.each do |department| %option{value: department.id}= department.name + +%div.chart-container{ data: { controller: "chart" } } + %canvas{ "data-chart-target": "canvas", width: "500", height: "200" } diff --git a/package.json b/package.json index 57ad35f53..56d7da914 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "autoprefixer": "^10.4.17", "bootstrap": "^5.3.2", "bootstrap-icons": "^1.11.3", + "chart.js": "^4.4.9", "esbuild": "^0.25.0", "esbuild-rails": "^1.0.7", "nodemon": "^3.0.3", diff --git a/yarn.lock b/yarn.lock index c9622ee1b..10045ee6d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -145,6 +145,11 @@ resolved "https://registry.yarnpkg.com/@hotwired/turbo/-/turbo-8.0.12.tgz#50aa8345d7f62402680c6d2d9814660761837001" integrity sha512-l3BiQRkD7qrnQv6ms6sqPLczvwbQpXt5iAVwjDvX0iumrz6yEonQkNAzNjeDX25/OJMFDTxpHjkJZHGpM9ikWw== +"@kurkle/color@^0.3.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@kurkle/color/-/color-0.3.4.tgz#4d4ff677e1609214fc71c580125ddddd86abcabf" + integrity sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -263,6 +268,13 @@ caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001688: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz#a102cf330d153bf8c92bfb5be3cd44c0a89c8c12" integrity sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w== +chart.js@^4.4.9: + version "4.4.9" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.9.tgz#602e2fc2462f0f7bb7b255eaa1b51f56a43a1362" + integrity sha512-EyZ9wWKgpAU0fLJ43YAEIF8sr5F2W3LqbS40ZJyHIner2lY14ufqv2VMp69MAiZ2rpwxEUxEhIH/0U3xyRynxg== + dependencies: + "@kurkle/color" "^0.3.0" + "chokidar@>=3.0.0 <4.0.0", chokidar@^3.3.0, chokidar@^3.5.2: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" From 45c66d5d00e7dae44bc2c104d04dbe10c7781ac2 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 12 May 2025 12:56:43 +0200 Subject: [PATCH 03/15] Add selects for the needed attributes --- app/views/team_skills/index.html.haml | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/app/views/team_skills/index.html.haml b/app/views/team_skills/index.html.haml index feabe5b9f..a94476a48 100644 --- a/app/views/team_skills/index.html.haml +++ b/app/views/team_skills/index.html.haml @@ -1,8 +1,23 @@ -%label{ for: "department_select" } Department -%select#department_select{name: "department_id"} - %option{value: ""} Select a Department - - Department.all.each do |department| - %option{value: department.id}= department.name += form_tag team_skills_path, method: :get do + %label{ for: "department_select" } Department + %select#department_select{name: "department_id"} + %option{value: ""} Select a Department + - Department.all.each do |department| + %option{value: department.id}= department.name + + %label{ for: "skill_select" } Skill + %select#skill_select{name: "skill_id"} + %option{value: ""} Select a Skill + - Skill.all.each do |skill| + %option{value: skill.id}= skill.title + + %label{ for: "year_select" } Year + %select#year_select{name: "year"} + %option{value: ""} Select a Year + - (2000..Date.today.year).to_a.reverse.each do |year| + %option{value: year}= year + + %button{ type: "submit" } Submit %div.chart-container{ data: { controller: "chart" } } %canvas{ "data-chart-target": "canvas", width: "500", height: "200" } From bf698ddaedbadf2e7dfdb90ca3b6670a5ac1b7fc Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 12 May 2025 15:39:26 +0200 Subject: [PATCH 04/15] Add basic functions of graph to correctly dummy data --- app/controllers/team_skills_controller.rb | 22 +++++++- .../controllers/chart_controller.js | 51 +++---------------- app/views/team_skills/index.html.haml | 15 +++--- config/routes.rb | 2 +- 4 files changed, 36 insertions(+), 54 deletions(-) diff --git a/app/controllers/team_skills_controller.rb b/app/controllers/team_skills_controller.rb index 444d6c890..4bc15fb40 100644 --- a/app/controllers/team_skills_controller.rb +++ b/app/controllers/team_skills_controller.rb @@ -1,6 +1,26 @@ class TeamSkillsController < CrudController def index + colors = %w[red blue green purple orange] + color_index = 0 + @data = { + labels: Date::MONTHNAMES.compact, + datasets: Skill.all.map do |skill| + color = colors[color_index] + color_index = (color_index + 1) % colors.size + { + label: skill.title, + data: Array.new(12) { rand(10) }, + backgroundColor: color, + borderColor: color, + fill: false, + tension: 0.1 + } + end + }.to_json + + super end -end \ No newline at end of file +end + diff --git a/app/javascript/controllers/chart_controller.js b/app/javascript/controllers/chart_controller.js index a95e3ab41..2a43f3af5 100644 --- a/app/javascript/controllers/chart_controller.js +++ b/app/javascript/controllers/chart_controller.js @@ -3,57 +3,18 @@ import Chart from "chart.js/auto" export default class extends Controller { static targets = ["canvas"] + static values = { + dataset: String + } connect() { const ctx = this.canvasTarget.getContext("2d") + const chartData = JSON.parse(this.datasetValue) + this.chart = new Chart(ctx, { type: 'line', - data: { - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], - datasets: [ - { - label: 'Azubi', - data: [5, 10, 7, 13, 16, 20, 6, 2, 13, 22, 25, 21], - backgroundColor: 'red', - borderColor: 'red', - fill: false, - tension: 0.1 - }, - { - label: 'Junior', - data: [10, 11, 12, 6, 14, 15, 16, 17, 18, 9, 8, 7], - backgroundColor: 'blue', - borderColor: 'blue', - fill: false, - tension: 0.1 - }, - { - label: 'Senior', - data: [13, 15, 19, 12, 22, 8, 4, 16, 7, 1, 18, 19], - backgroundColor: 'green', - borderColor: 'green', - fill: false, - tension: 0.1 - }, - { - label: 'Professionell', - data: [1, 2, 3, 8, 10, 10, 14, 9, 15, 22, 22, 25], - backgroundColor: 'black', - borderColor: 'black', - fill: false, - tension: 0.1 - }, - { - label: 'Expert', - data: [18, 22, 23, 20, 18, 25, 19, 15, 13, 14, 9, 5], - backgroundColor: 'purple', - borderColor: 'purple', - fill: false, - tension: 0.1 - } - ] - }, + data: chartData, options: { responsive: true, scales: { diff --git a/app/views/team_skills/index.html.haml b/app/views/team_skills/index.html.haml index a94476a48..aa0b9a30f 100644 --- a/app/views/team_skills/index.html.haml +++ b/app/views/team_skills/index.html.haml @@ -1,23 +1,24 @@ -= form_tag team_skills_path, method: :get do += form_tag team_skills_path, {"data-turbo-frame": "team-skill-chart", method: :get} do %label{ for: "department_select" } Department - %select#department_select{name: "department_id"} + %select#department_select{name: "department_id", onChange: "this.form.requestSubmit()"} %option{value: ""} Select a Department - Department.all.each do |department| %option{value: department.id}= department.name %label{ for: "skill_select" } Skill - %select#skill_select{name: "skill_id"} + %select#skill_select{name: "skill_id", onChange: "this.form.requestSubmit()"} %option{value: ""} Select a Skill - Skill.all.each do |skill| %option{value: skill.id}= skill.title %label{ for: "year_select" } Year - %select#year_select{name: "year"} + %select#year_select{name: "year", onChange: "this.form.requestSubmit()"} %option{value: ""} Select a Year - - (2000..Date.today.year).to_a.reverse.each do |year| + - (2025..Date.today.year).to_a.reverse.each do |year| %option{value: year}= year %button{ type: "submit" } Submit -%div.chart-container{ data: { controller: "chart" } } - %canvas{ "data-chart-target": "canvas", width: "500", height: "200" } +%turbo-frame#team-skill-chart + %div.chart-container{data: {"chart-dataset-value": @data, controller: "chart" }} + %canvas{ "data-chart-target": "canvas", width: "500", height: "200" } diff --git a/config/routes.rb b/config/routes.rb index 067ebb8ef..966e04a96 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -68,7 +68,7 @@ resources :certificates - resources :team_skills, only: [:index, :show] + resources :team_skills, only: [:index] end From ef289712142f98b7941500c3c4215d45ad92953f Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 14 May 2025 09:20:05 +0200 Subject: [PATCH 05/15] Add translations for new navbar tab --- app/helpers/tab_helper.rb | 2 +- config/locales/de-CH.yml | 1 + config/locales/de.yml | 1 + config/locales/en.yml | 1 + config/locales/fr.yml | 1 + config/locales/it.yml | 1 + 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index 94931f36c..b6ea74f06 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -19,7 +19,7 @@ def global_tabs { title: ti('navbar.cv_search'), path: cv_search_index_path, admin_only: false }, { title: ti('navbar.skillset'), path: skills_path, admin_only: false }, { title: ti('navbar.certificates'), path: certificates_path, admin_only: true }, - { title: 'Team Skills', path: team_skills_path, admin_only: false }, + { title: ti('navbar.skills_tracking'), path: team_skills_path, admin_only: false }, ] end diff --git a/config/locales/de-CH.yml b/config/locales/de-CH.yml index 3ecebd76a..29ca0a7ec 100644 --- a/config/locales/de-CH.yml +++ b/config/locales/de-CH.yml @@ -232,6 +232,7 @@ de-CH: profile: Profiu skill_search: Skill Suechi skillset: Skillset + skills_tracking: Skills tracking new: Neu people_skills: certificate: Zertifikat diff --git a/config/locales/de.yml b/config/locales/de.yml index ba39c1e87..83a69eb1d 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -217,6 +217,7 @@ de: profile: Profil skill_search: Skill Suche skillset: Skillset + skills_tracking: Skills tracking new: Neu people_skills: certificate: Zertifikat diff --git a/config/locales/en.yml b/config/locales/en.yml index d78dde159..db8e721f7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -213,6 +213,7 @@ en: profile: Profile skill_search: Skill search skillset: Skillset + skills_tracking: Skills tracking new: New people_skills: certificate: Certificate diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 10d145aa9..017c49b32 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -213,6 +213,7 @@ fr: profile: Profil skill_search: Recherche de compétences skillset: Kit de compétences + skills_tracking: Suivi des compétences new: Nouveau people_skills: certificate: Certificat diff --git a/config/locales/it.yml b/config/locales/it.yml index 9fdd053fd..be0c75759 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -213,6 +213,7 @@ it: profile: Profilo skill_search: Ricerca di competenze skillset: Competenze + skills_tracking: Tracciamento delle competenze new: Nuovo people_skills: certificate: Certificato From 56ec5950c6887dac4938a3b040da439b27c3857c Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 14 May 2025 09:44:05 +0200 Subject: [PATCH 06/15] Add a bit of styling to dropdowns --- app/views/team_skills/index.html.haml | 36 ++++++++++++++------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/app/views/team_skills/index.html.haml b/app/views/team_skills/index.html.haml index aa0b9a30f..1e5a62ae8 100644 --- a/app/views/team_skills/index.html.haml +++ b/app/views/team_skills/index.html.haml @@ -1,23 +1,25 @@ = form_tag team_skills_path, {"data-turbo-frame": "team-skill-chart", method: :get} do - %label{ for: "department_select" } Department - %select#department_select{name: "department_id", onChange: "this.form.requestSubmit()"} - %option{value: ""} Select a Department - - Department.all.each do |department| - %option{value: department.id}= department.name + %div.d-flex.justify-content-evenly.mt-5.mb-5 + %div + %label.me-2{ for: "department_select" } Department + %select#department_select{name: "department_id", onChange: "this.form.requestSubmit()"} + %option{value: ""} Select a Department + - Department.all.each do |department| + %option{value: department.id}= department.name - %label{ for: "skill_select" } Skill - %select#skill_select{name: "skill_id", onChange: "this.form.requestSubmit()"} - %option{value: ""} Select a Skill - - Skill.all.each do |skill| - %option{value: skill.id}= skill.title + %div + %label.me-2{ for: "skill_select" } Skill + %select#skill_select{name: "skill_id", onChange: "this.form.requestSubmit()"} + %option{value: ""} Select a Skill + - Skill.all.each do |skill| + %option{value: skill.id}= skill.title - %label{ for: "year_select" } Year - %select#year_select{name: "year", onChange: "this.form.requestSubmit()"} - %option{value: ""} Select a Year - - (2025..Date.today.year).to_a.reverse.each do |year| - %option{value: year}= year - - %button{ type: "submit" } Submit + %div + %label.me-2{ for: "year_select" } Year + %select#year_select{name: "year", onChange: "this.form.requestSubmit()"} + %option{value: ""} Select a Year + - (2025..Date.today.year).to_a.reverse.each do |year| + %option{value: year}= year %turbo-frame#team-skill-chart %div.chart-container{data: {"chart-dataset-value": @data, controller: "chart" }} From fa1d3d4edff52c888a69a46be8446856b27e27a1 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 14 May 2025 11:07:24 +0200 Subject: [PATCH 07/15] Correctly utilize rails helper and style selects with bootstrap --- app/views/team_skills/index.html.haml | 30 ++++++++++----------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/app/views/team_skills/index.html.haml b/app/views/team_skills/index.html.haml index 1e5a62ae8..dfa282571 100644 --- a/app/views/team_skills/index.html.haml +++ b/app/views/team_skills/index.html.haml @@ -1,25 +1,17 @@ -= form_tag team_skills_path, {"data-turbo-frame": "team-skill-chart", method: :get} do - %div.d-flex.justify-content-evenly.mt-5.mb-5 += form_with url: team_skills_path, method: :get, data: { turbo_frame: "team-skill-chart" } do |f| + .d-flex.mt-4.mb-4.gap-4 %div - %label.me-2{ for: "department_select" } Department - %select#department_select{name: "department_id", onChange: "this.form.requestSubmit()"} - %option{value: ""} Select a Department - - Department.all.each do |department| - %option{value: department.id}= department.name - + = f.label :department_id, "Department", class: "text-secondary" + = f.select :department_id, + options_from_collection_for_select(Department.all, :id, :name, params[:department_id]), {}, { onchange: "this.form.requestSubmit()", class: "form-select"} %div - %label.me-2{ for: "skill_select" } Skill - %select#skill_select{name: "skill_id", onChange: "this.form.requestSubmit()"} - %option{value: ""} Select a Skill - - Skill.all.each do |skill| - %option{value: skill.id}= skill.title - + = f.label :skill_id, "Skill", class: "text-secondary" + = f.select :skill_id, + options_from_collection_for_select(Skill.all, :id, :title, params[:skill_id]), {}, { onchange: "this.form.requestSubmit()", class: "form-select" } %div - %label.me-2{ for: "year_select" } Year - %select#year_select{name: "year", onChange: "this.form.requestSubmit()"} - %option{value: ""} Select a Year - - (2025..Date.today.year).to_a.reverse.each do |year| - %option{value: year}= year + = f.label :year, "Year", class: "text-secondary" + = f.select :year, + options_for_select((2025..Date.today.year).to_a.reverse, params[:year]), {}, { onchange: "this.form.requestSubmit()", class: "form-select"} %turbo-frame#team-skill-chart %div.chart-container{data: {"chart-dataset-value": @data, controller: "chart" }} From b571a64597c50621e7cd15ad85f2b4ca4a795fe7 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 14 May 2025 11:35:41 +0200 Subject: [PATCH 08/15] Rename controller, route and everything else to better fit it's purpose --- ...controller.rb => department_skill_snapshot_controller.rb} | 2 +- app/helpers/tab_helper.rb | 3 ++- app/models/department_skill_snapshot.rb | 5 +++++ app/models/team_skill.rb | 3 --- .../index.html.haml | 2 +- config/routes.rb | 2 +- 6 files changed, 10 insertions(+), 7 deletions(-) rename app/controllers/{team_skills_controller.rb => department_skill_snapshot_controller.rb} (90%) create mode 100644 app/models/department_skill_snapshot.rb delete mode 100644 app/models/team_skill.rb rename app/views/{team_skills => department_skill_snapshot}/index.html.haml (89%) diff --git a/app/controllers/team_skills_controller.rb b/app/controllers/department_skill_snapshot_controller.rb similarity index 90% rename from app/controllers/team_skills_controller.rb rename to app/controllers/department_skill_snapshot_controller.rb index 4bc15fb40..5ff266d6d 100644 --- a/app/controllers/team_skills_controller.rb +++ b/app/controllers/department_skill_snapshot_controller.rb @@ -1,4 +1,4 @@ -class TeamSkillsController < CrudController +class DepartmentSkillSnapshotController < CrudController def index colors = %w[red blue green purple orange] diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index b6ea74f06..cbc1a0688 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -19,7 +19,8 @@ def global_tabs { title: ti('navbar.cv_search'), path: cv_search_index_path, admin_only: false }, { title: ti('navbar.skillset'), path: skills_path, admin_only: false }, { title: ti('navbar.certificates'), path: certificates_path, admin_only: true }, - { title: ti('navbar.skills_tracking'), path: team_skills_path, admin_only: false }, + { title: ti('navbar.skills_tracking'), + path: department_skill_snapshot_index_path, admin_only: false } ] end diff --git a/app/models/department_skill_snapshot.rb b/app/models/department_skill_snapshot.rb new file mode 100644 index 000000000..40536c9ad --- /dev/null +++ b/app/models/department_skill_snapshot.rb @@ -0,0 +1,5 @@ +class DepartmentSkillSnapshot < ApplicationRecord + belongs_to :department + + serialize :department_skill_levels, type: Hash, coder: JSON +end diff --git a/app/models/team_skill.rb b/app/models/team_skill.rb deleted file mode 100644 index 14e81ec7a..000000000 --- a/app/models/team_skill.rb +++ /dev/null @@ -1,3 +0,0 @@ -class TeamSkill < ApplicationRecord - -end \ No newline at end of file diff --git a/app/views/team_skills/index.html.haml b/app/views/department_skill_snapshot/index.html.haml similarity index 89% rename from app/views/team_skills/index.html.haml rename to app/views/department_skill_snapshot/index.html.haml index dfa282571..c4da12ba1 100644 --- a/app/views/team_skills/index.html.haml +++ b/app/views/department_skill_snapshot/index.html.haml @@ -1,4 +1,4 @@ -= form_with url: team_skills_path, method: :get, data: { turbo_frame: "team-skill-chart" } do |f| += form_with url: department_skill_snapshot_index_path, method: :get, data: { turbo_frame: "team-skill-chart" } do |f| .d-flex.mt-4.mb-4.gap-4 %div = f.label :department_id, "Department", class: "text-secondary" diff --git a/config/routes.rb b/config/routes.rb index 966e04a96..bfa609c09 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -68,7 +68,7 @@ resources :certificates - resources :team_skills, only: [:index] + resources :department_skill_snapshot, only: [:index] end From a4ef506ba40e17e2d5f15d66647035d7257d03bb Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 14 May 2025 15:09:11 +0200 Subject: [PATCH 09/15] Rename controller to be plural like it is supossed to be --- ...ontroller.rb => department_skill_snapshots_controller.rb} | 2 +- app/helpers/tab_helper.rb | 3 +-- .../index.html.haml | 2 +- config/routes.rb | 2 +- spec/features/tabbar_spec.rb | 5 +++-- 5 files changed, 7 insertions(+), 7 deletions(-) rename app/controllers/{department_skill_snapshot_controller.rb => department_skill_snapshots_controller.rb} (89%) rename app/views/{department_skill_snapshot => department_skill_snapshots}/index.html.haml (89%) diff --git a/app/controllers/department_skill_snapshot_controller.rb b/app/controllers/department_skill_snapshots_controller.rb similarity index 89% rename from app/controllers/department_skill_snapshot_controller.rb rename to app/controllers/department_skill_snapshots_controller.rb index 5ff266d6d..c4cc3874e 100644 --- a/app/controllers/department_skill_snapshot_controller.rb +++ b/app/controllers/department_skill_snapshots_controller.rb @@ -1,4 +1,4 @@ -class DepartmentSkillSnapshotController < CrudController +class DepartmentSkillSnapshotsController < CrudController def index colors = %w[red blue green purple orange] diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index cbc1a0688..fd5f83fb5 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -19,8 +19,7 @@ def global_tabs { title: ti('navbar.cv_search'), path: cv_search_index_path, admin_only: false }, { title: ti('navbar.skillset'), path: skills_path, admin_only: false }, { title: ti('navbar.certificates'), path: certificates_path, admin_only: true }, - { title: ti('navbar.skills_tracking'), - path: department_skill_snapshot_index_path, admin_only: false } + { title: ti('navbar.skills_tracking'), path: department_skill_snapshots_path, admin_only: false } ] end diff --git a/app/views/department_skill_snapshot/index.html.haml b/app/views/department_skill_snapshots/index.html.haml similarity index 89% rename from app/views/department_skill_snapshot/index.html.haml rename to app/views/department_skill_snapshots/index.html.haml index c4da12ba1..02a1c29b1 100644 --- a/app/views/department_skill_snapshot/index.html.haml +++ b/app/views/department_skill_snapshots/index.html.haml @@ -1,4 +1,4 @@ -= form_with url: department_skill_snapshot_index_path, method: :get, data: { turbo_frame: "team-skill-chart" } do |f| += form_with url: department_skill_snapshots_path, method: :get, data: { turbo_frame: "team-skill-chart" } do |f| .d-flex.mt-4.mb-4.gap-4 %div = f.label :department_id, "Department", class: "text-secondary" diff --git a/config/routes.rb b/config/routes.rb index bfa609c09..a082b3891 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -68,7 +68,7 @@ resources :certificates - resources :department_skill_snapshot, only: [:index] + resources :department_skill_snapshots, only: [:index] end diff --git a/spec/features/tabbar_spec.rb b/spec/features/tabbar_spec.rb index 2266ba211..8f0a8d29a 100644 --- a/spec/features/tabbar_spec.rb +++ b/spec/features/tabbar_spec.rb @@ -9,7 +9,8 @@ { title: 'global.navbar.skill_search', path_helper: "people_skills_path", admin_only: false }, { title: 'global.navbar.cv_search', path_helper: "cv_search_index_path", admin_only: false }, { title: 'global.navbar.skillset', path_helper: "skills_path", admin_only: false }, - { title: 'global.navbar.certificates', path_helper: "certificates_path", admin_only: true } + { title: 'global.navbar.certificates', path_helper: "certificates_path", admin_only: true }, + { title: 'global.navbar.skills_tracking', path_helper: "department_skill_snapshots_path", admin_only: false } ] PERSON_TABS = @@ -27,7 +28,7 @@ end after(:each) do - expect(current_path).to start_with("/#{locale}") + expect(current_path).to start_with("/#{locale}/") end describe 'Global' do From d55a3335f3384274a582f1a4722f5c41e7c7bfab Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 14 May 2025 16:54:08 +0200 Subject: [PATCH 10/15] Add missing translations and a small tes --- .../department_skill_snapshots/index.html.haml | 6 +++--- .../features/department_skill_snapshots_spec.rb | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 spec/features/department_skill_snapshots_spec.rb diff --git a/app/views/department_skill_snapshots/index.html.haml b/app/views/department_skill_snapshots/index.html.haml index 02a1c29b1..fde9771b0 100644 --- a/app/views/department_skill_snapshots/index.html.haml +++ b/app/views/department_skill_snapshots/index.html.haml @@ -1,15 +1,15 @@ = form_with url: department_skill_snapshots_path, method: :get, data: { turbo_frame: "team-skill-chart" } do |f| .d-flex.mt-4.mb-4.gap-4 %div - = f.label :department_id, "Department", class: "text-secondary" + = f.label :department_id, t('activerecord.models.department.one'), class: "text-secondary" = f.select :department_id, options_from_collection_for_select(Department.all, :id, :name, params[:department_id]), {}, { onchange: "this.form.requestSubmit()", class: "form-select"} %div - = f.label :skill_id, "Skill", class: "text-secondary" + = f.label :skill_id, t('activerecord.models.skill.one'), class: "text-secondary" = f.select :skill_id, options_from_collection_for_select(Skill.all, :id, :title, params[:skill_id]), {}, { onchange: "this.form.requestSubmit()", class: "form-select" } %div - = f.label :year, "Year", class: "text-secondary" + = f.label :year, t('global.date.year'), class: "text-secondary" = f.select :year, options_for_select((2025..Date.today.year).to_a.reverse, params[:year]), {}, { onchange: "this.form.requestSubmit()", class: "form-select"} diff --git a/spec/features/department_skill_snapshots_spec.rb b/spec/features/department_skill_snapshots_spec.rb new file mode 100644 index 000000000..01caeb2cd --- /dev/null +++ b/spec/features/department_skill_snapshots_spec.rb @@ -0,0 +1,17 @@ +require 'rails_helper' + +describe 'Department Skill Snapshots', type: :feature, js: true do + before(:each) do + admin = auth_users(:admin) + login_as(admin, scope: :auth_user) + visit department_skill_snapshots_path + end + + it 'Should display all labels correctly' do + expect(page).to have_text('Organisationseinheit') + expect(page).to have_text('Skill') + expect(page).to have_text('Jahr') + + + end +end From 55cbbed3b71db1fe1002e05049ea05f2ce742b86 Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 16 May 2025 16:09:21 +0200 Subject: [PATCH 11/15] Add a quick feature spec and clenaup code in various locations --- .../department_skill_snapshots_controller.rb | 40 ++++++++++--------- .../controllers/chart_controller.js | 3 ++ .../index.html.haml | 2 +- .../department_skill_snapshots_spec.rb | 12 ++++-- 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/app/controllers/department_skill_snapshots_controller.rb b/app/controllers/department_skill_snapshots_controller.rb index c4cc3874e..7686c6a0b 100644 --- a/app/controllers/department_skill_snapshots_controller.rb +++ b/app/controllers/department_skill_snapshots_controller.rb @@ -1,26 +1,28 @@ class DepartmentSkillSnapshotsController < CrudController - def index - colors = %w[red blue green purple orange] - color_index = 0 + @data = chart_data.to_json + super + end + + private - @data = { + def chart_data + { labels: Date::MONTHNAMES.compact, - datasets: Skill.all.map do |skill| - color = colors[color_index] - color_index = (color_index + 1) % colors.size - { - label: skill.title, - data: Array.new(12) { rand(10) }, - backgroundColor: color, - borderColor: color, - fill: false, - tension: 0.1 - } - end - }.to_json + datasets: dataset_values.map { |value| build_dataset(value) } + } + end + + def dataset_values + %w[Azubi Junior Senior Professional Expert] + end - super + def build_dataset(value) + { + label: value, + data: Array.new(12) { rand(10) }, + fill: false, + tension: 0.1 + } end end - diff --git a/app/javascript/controllers/chart_controller.js b/app/javascript/controllers/chart_controller.js index 2a43f3af5..d3873274b 100644 --- a/app/javascript/controllers/chart_controller.js +++ b/app/javascript/controllers/chart_controller.js @@ -1,5 +1,6 @@ import { Controller } from "@hotwired/stimulus" import Chart from "chart.js/auto" +import { Colors } from 'chart.js'; export default class extends Controller { static targets = ["canvas"] @@ -8,6 +9,8 @@ export default class extends Controller { } connect() { + Chart.register(Colors); + const ctx = this.canvasTarget.getContext("2d") const chartData = JSON.parse(this.datasetValue) diff --git a/app/views/department_skill_snapshots/index.html.haml b/app/views/department_skill_snapshots/index.html.haml index fde9771b0..a307220da 100644 --- a/app/views/department_skill_snapshots/index.html.haml +++ b/app/views/department_skill_snapshots/index.html.haml @@ -15,4 +15,4 @@ %turbo-frame#team-skill-chart %div.chart-container{data: {"chart-dataset-value": @data, controller: "chart" }} - %canvas{ "data-chart-target": "canvas", width: "500", height: "200" } + %canvas{ "data-chart-target": "canvas", width: "3", height: "1" } diff --git a/spec/features/department_skill_snapshots_spec.rb b/spec/features/department_skill_snapshots_spec.rb index 01caeb2cd..1cdaa9a2f 100644 --- a/spec/features/department_skill_snapshots_spec.rb +++ b/spec/features/department_skill_snapshots_spec.rb @@ -7,11 +7,15 @@ visit department_skill_snapshots_path end - it 'Should display all labels correctly' do - expect(page).to have_text('Organisationseinheit') - expect(page).to have_text('Skill') - expect(page).to have_text('Jahr') + it 'Should display all selects with the corresponding labels and the the canvas chart' do + expect(page).to have_content('Organisationseinheit') + expect(page).to have_content('Skill') + expect(page).to have_content('Jahr') + expect(page).to have_select('department_id') + expect(page).to have_select('skill_id') + expect(page).to have_select('year') + expect(page).to have_selector("canvas") end end From 7a4e222071203fb3423cf92cb88dab8991bc31e4 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 19 May 2025 08:11:48 +0200 Subject: [PATCH 12/15] Add empty controller spec --- app/controllers/department_skill_snapshots_controller.rb | 2 +- .../department_skill_snapshots_controller_spec.rb | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 spec/controllers/department_skill_snapshots_controller_spec.rb diff --git a/app/controllers/department_skill_snapshots_controller.rb b/app/controllers/department_skill_snapshots_controller.rb index 7686c6a0b..ff52f0b27 100644 --- a/app/controllers/department_skill_snapshots_controller.rb +++ b/app/controllers/department_skill_snapshots_controller.rb @@ -12,7 +12,7 @@ def chart_data datasets: dataset_values.map { |value| build_dataset(value) } } end - + def dataset_values %w[Azubi Junior Senior Professional Expert] end diff --git a/spec/controllers/department_skill_snapshots_controller_spec.rb b/spec/controllers/department_skill_snapshots_controller_spec.rb new file mode 100644 index 000000000..35f702700 --- /dev/null +++ b/spec/controllers/department_skill_snapshots_controller_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +describe DepartmentSkillSnapshotController do + +end \ No newline at end of file From 00e1d2164e6d0245d56277eb26cc3b6667f1dc86 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 19 May 2025 08:14:41 +0200 Subject: [PATCH 13/15] Fix typo --- spec/controllers/department_skill_snapshots_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/department_skill_snapshots_controller_spec.rb b/spec/controllers/department_skill_snapshots_controller_spec.rb index 35f702700..6497fdc41 100644 --- a/spec/controllers/department_skill_snapshots_controller_spec.rb +++ b/spec/controllers/department_skill_snapshots_controller_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' -describe DepartmentSkillSnapshotController do +describe DepartmentSkillSnapshotsController do end \ No newline at end of file From b4a34aa3f9fec6b6499eb5f5a3373dcbc7dcbd63 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 19 May 2025 08:31:50 +0200 Subject: [PATCH 14/15] Normalize i18n translations and fix failing test --- config/locales/de-CH.yml | 2 +- config/locales/de.yml | 2 +- config/locales/en.yml | 2 +- config/locales/fr.yml | 2 +- config/locales/it.yml | 2 +- spec/features/edit_people_skills_spec.rb | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/locales/de-CH.yml b/config/locales/de-CH.yml index 29ca0a7ec..f095c4aea 100644 --- a/config/locales/de-CH.yml +++ b/config/locales/de-CH.yml @@ -231,8 +231,8 @@ de-CH: cv_search: CV Suechi profile: Profiu skill_search: Skill Suechi - skillset: Skillset skills_tracking: Skills tracking + skillset: Skillset new: Neu people_skills: certificate: Zertifikat diff --git a/config/locales/de.yml b/config/locales/de.yml index 83a69eb1d..28fc5751d 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -216,8 +216,8 @@ de: cv_search: CV Suche profile: Profil skill_search: Skill Suche - skillset: Skillset skills_tracking: Skills tracking + skillset: Skillset new: Neu people_skills: certificate: Zertifikat diff --git a/config/locales/en.yml b/config/locales/en.yml index db8e721f7..fc2637de0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -212,8 +212,8 @@ en: cv_search: CV search profile: Profile skill_search: Skill search - skillset: Skillset skills_tracking: Skills tracking + skillset: Skillset new: New people_skills: certificate: Certificate diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 017c49b32..3b793f090 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -212,8 +212,8 @@ fr: cv_search: Recherche de CV profile: Profil skill_search: Recherche de compétences - skillset: Kit de compétences skills_tracking: Suivi des compétences + skillset: Kit de compétences new: Nouveau people_skills: certificate: Certificat diff --git a/config/locales/it.yml b/config/locales/it.yml index be0c75759..145539004 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -212,8 +212,8 @@ it: cv_search: Ricerca di CV profile: Profilo skill_search: Ricerca di competenze - skillset: Competenze skills_tracking: Tracciamento delle competenze + skillset: Competenze new: Nuovo people_skills: certificate: Certificato diff --git a/spec/features/edit_people_skills_spec.rb b/spec/features/edit_people_skills_spec.rb index ef1124a44..d7c28612f 100644 --- a/spec/features/edit_people_skills_spec.rb +++ b/spec/features/edit_people_skills_spec.rb @@ -12,7 +12,7 @@ bob = people(:bob) visit person_path(bob) - expect(page).to have_css('.nav-link', text: 'Skills', count: 2) + expect(page).to have_css('.nav-link', text: 'Skills', count: 3) page.all('.nav-link', text: 'Skills')[1].click end From 5b814288ece76e0fad948d1cd0dbae56dea19a48 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 19 May 2025 09:13:05 +0200 Subject: [PATCH 15/15] Make rubocop happy --- app/helpers/tab_helper.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index fd5f83fb5..a03db27e9 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -12,6 +12,7 @@ def person_tabs(person) ] end + # rubocop:disable Metrics/LineLength def global_tabs [ { title: ti('navbar.profile'), path: people_path, admin_only: false }, @@ -22,6 +23,7 @@ def global_tabs { title: ti('navbar.skills_tracking'), path: department_skill_snapshots_path, admin_only: false } ] end + # rubocop:enable Metrics/LineLength def extract_path(regex) request.path.match(regex)&.captures&.join