effective_work_experience 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +188 -0
  4. data/Rakefile +18 -0
  5. data/app/assets/config/effective_work_experience_manifest.js +3 -0
  6. data/app/assets/javascripts/effective_work_experience/base.js +0 -0
  7. data/app/assets/javascripts/effective_work_experience.js +1 -0
  8. data/app/assets/stylesheets/effective_work_experience/base.scss +7 -0
  9. data/app/assets/stylesheets/effective_work_experience.scss +1 -0
  10. data/app/controllers/admin/work_experience_categories_controller.rb +19 -0
  11. data/app/controllers/admin/work_experience_projects_controller.rb +19 -0
  12. data/app/controllers/admin/work_experience_records_controller.rb +19 -0
  13. data/app/controllers/admin/work_experience_reports_controller.rb +21 -0
  14. data/app/controllers/admin/work_experience_subcategories_controller.rb +19 -0
  15. data/app/controllers/admin/work_experience_summaries_controller.rb +19 -0
  16. data/app/controllers/effective/work_experience_projects_controller.rb +17 -0
  17. data/app/controllers/effective/work_experience_records_controller.rb +17 -0
  18. data/app/controllers/effective/work_experience_reports_controller.rb +19 -0
  19. data/app/controllers/effective/work_experience_summaries_controller.rb +17 -0
  20. data/app/datatables/admin/effective_work_experience_categories_datatable.rb +22 -0
  21. data/app/datatables/admin/effective_work_experience_projects_datatable.rb +24 -0
  22. data/app/datatables/admin/effective_work_experience_records_datatable.rb +37 -0
  23. data/app/datatables/admin/effective_work_experience_reports_datatable.rb +34 -0
  24. data/app/datatables/admin/effective_work_experience_subcategories_datatable.rb +24 -0
  25. data/app/datatables/admin/effective_work_experience_summaries_datatable.rb +57 -0
  26. data/app/datatables/effective_work_experience_projects_datatable.rb +38 -0
  27. data/app/datatables/effective_work_experience_records_datatable.rb +61 -0
  28. data/app/datatables/effective_work_experience_reports_review_datatable.rb +15 -0
  29. data/app/datatables/effective_work_experience_summaries_datatable.rb +49 -0
  30. data/app/datatables/effective_work_experience_summaries_review_datatable.rb +43 -0
  31. data/app/helpers/effective_work_experience_helper.rb +46 -0
  32. data/app/mailers/effective/work_experience_mailer.rb +39 -0
  33. data/app/models/concerns/effective_work_experience_summary.rb +264 -0
  34. data/app/models/concerns/effective_work_experience_user.rb +135 -0
  35. data/app/models/effective/work_experience_category.rb +29 -0
  36. data/app/models/effective/work_experience_entry.rb +43 -0
  37. data/app/models/effective/work_experience_outside_mentor.rb +35 -0
  38. data/app/models/effective/work_experience_project.rb +38 -0
  39. data/app/models/effective/work_experience_record.rb +99 -0
  40. data/app/models/effective/work_experience_report.rb +50 -0
  41. data/app/models/effective/work_experience_subcategory.rb +31 -0
  42. data/app/models/effective/work_experience_summary.rb +7 -0
  43. data/app/views/admin/work_experience/_user_fields.html.haml +17 -0
  44. data/app/views/admin/work_experience/_user_work_experience.html.haml +21 -0
  45. data/app/views/admin/work_experience_categories/_form.html.haml +7 -0
  46. data/app/views/admin/work_experience_categories/_form_work_experience_category.html.haml +5 -0
  47. data/app/views/admin/work_experience_projects/_form.html.haml +11 -0
  48. data/app/views/admin/work_experience_projects/_work_experience_project.html.haml +1 -0
  49. data/app/views/admin/work_experience_records/_form.html.haml +12 -0
  50. data/app/views/admin/work_experience_records/_work_experience_record.html.haml +1 -0
  51. data/app/views/admin/work_experience_reports/show.html.haml +2 -0
  52. data/app/views/admin/work_experience_subcategories/_form.html.haml +7 -0
  53. data/app/views/admin/work_experience_subcategories/_form_work_experience_subcategory.html.haml +10 -0
  54. data/app/views/admin/work_experience_summaries/_form.html.haml +7 -0
  55. data/app/views/admin/work_experience_summaries/_form_work_experience_summary.html.haml +32 -0
  56. data/app/views/admin/work_experience_summaries/_work_experience_summary.html.haml +1 -0
  57. data/app/views/effective/work_experience/_dashboard_intern.html.haml +73 -0
  58. data/app/views/effective/work_experience/_dashboard_mentor.html.haml +28 -0
  59. data/app/views/effective/work_experience_mailer/work_experience_summary_reviewed.liquid +13 -0
  60. data/app/views/effective/work_experience_mailer/work_experience_summary_submitted.liquid +15 -0
  61. data/app/views/effective/work_experience_outside_mentors/_fields.html.haml +5 -0
  62. data/app/views/effective/work_experience_projects/_fields.html.haml +7 -0
  63. data/app/views/effective/work_experience_projects/_form.html.haml +3 -0
  64. data/app/views/effective/work_experience_projects/_work_experience_project.html.haml +2 -0
  65. data/app/views/effective/work_experience_records/_fields.html.haml +52 -0
  66. data/app/views/effective/work_experience_records/_form.html.haml +5 -0
  67. data/app/views/effective/work_experience_records/_work_experience_record.html.haml +63 -0
  68. data/app/views/effective/work_experience_reports/_work_experience_report.html.haml +103 -0
  69. data/app/views/effective/work_experience_reports/show.html.haml +2 -0
  70. data/app/views/effective/work_experience_summaries/_content.html.haml +1 -0
  71. data/app/views/effective/work_experience_summaries/_layout.html.haml +3 -0
  72. data/app/views/effective/work_experience_summaries/_projects.html.haml +5 -0
  73. data/app/views/effective/work_experience_summaries/_projects_datatable.html.haml +2 -0
  74. data/app/views/effective/work_experience_summaries/_projects_fields.html.haml +1 -0
  75. data/app/views/effective/work_experience_summaries/_records.html.haml +65 -0
  76. data/app/views/effective/work_experience_summaries/_records_datatable.html.haml +2 -0
  77. data/app/views/effective/work_experience_summaries/_records_fields.html.haml +1 -0
  78. data/app/views/effective/work_experience_summaries/_review.html.haml +4 -0
  79. data/app/views/effective/work_experience_summaries/_review_fields.html.haml +4 -0
  80. data/app/views/effective/work_experience_summaries/_reviewed.html.haml +1 -0
  81. data/app/views/effective/work_experience_summaries/_start_fields.html.haml +1 -0
  82. data/app/views/effective/work_experience_summaries/_summary.html.haml +79 -0
  83. data/app/views/effective/work_experience_summaries/_user.html.haml +7 -0
  84. data/app/views/effective/work_experience_summaries/_work_experience_summary.html.haml +7 -0
  85. data/app/views/effective/work_experience_summaries/projects.html.haml +14 -0
  86. data/app/views/effective/work_experience_summaries/records.html.haml +14 -0
  87. data/app/views/effective/work_experience_summaries/review.html.haml +13 -0
  88. data/app/views/effective/work_experience_summaries/reviewed.html.haml +11 -0
  89. data/app/views/effective/work_experience_summaries/start.html.haml +16 -0
  90. data/app/views/effective/work_experience_summaries/submit.html.haml +10 -0
  91. data/app/views/effective/work_experience_summaries/submitted.html.haml +19 -0
  92. data/config/effective_work_experience.rb +34 -0
  93. data/config/locales/effective_work_experience.en.yml +94 -0
  94. data/config/routes.rb +28 -0
  95. data/db/migrate/101_create_effective_work_experience.rb +120 -0
  96. data/db/seeds.rb +40 -0
  97. data/lib/effective_work_experience/engine.rb +19 -0
  98. data/lib/effective_work_experience/version.rb +3 -0
  99. data/lib/effective_work_experience.rb +34 -0
  100. data/lib/generators/effective_work_experience/install_generator.rb +24 -0
  101. data/lib/generators/templates/effective_work_experience_mailer_preview.rb +4 -0
  102. data/lib/tasks/effective_work_experience_tasks.rake +8 -0
  103. metadata +325 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9a876f18790cdca6bc9e13228ec0be8b643e4167e1e348cfaf00f09c9376f79f
4
+ data.tar.gz: c08a8257f216cb33f27760b729526b76d854a6d4f7d71ec32c21af581f78c358
5
+ SHA512:
6
+ metadata.gz: 7c4aa51ef471a77a677dfb382e4a4c190336903557b827d3b9839c93f075ad2c856b8d281692f0efbe8d6291d5c99fd797d77cf840dd8e71048ebb0104fbd597
7
+ data.tar.gz: '0788634767708d121ce06edadf1cfefd9c5150b4cfed0ae5e0e354143a3f4446b0891a0115ccf3b45c98911c426223ca0cda33af45d782c60b738e85f1128723'
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2026 Code and Effect Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,188 @@
1
+ # Effective Work Experience
2
+
3
+ Interns record their work experience hours and projects, and mentors review them.
4
+
5
+ Interns record their hours each month against a set of work experience subcategories, and record the projects they worked on. Every few months they submit a summary of that period, which is reviewed by their mentor. A work experience report totals everything to date against the minimum hours of each category.
6
+
7
+ ## Getting Started
8
+
9
+ This requires Rails 6+ and Twitter Bootstrap 4 and just works with Devise.
10
+
11
+ Please first install the [effective_datatables](https://github.com/code-and-effect/effective_datatables) gem.
12
+
13
+ Please download and install the [Twitter Bootstrap4](http://getbootstrap.com)
14
+
15
+ Add to your Gemfile:
16
+
17
+ ```ruby
18
+ gem 'effective_work_experience'
19
+ ```
20
+
21
+ Run the bundle command to install it:
22
+
23
+ ```console
24
+ bundle install
25
+ ```
26
+
27
+ Then run the generator:
28
+
29
+ ```ruby
30
+ rails generate effective_work_experience:install
31
+ ```
32
+
33
+ The generator will install an initializer which describes all configuration options and creates a database migration.
34
+
35
+ Then migrate the database:
36
+
37
+ ```ruby
38
+ rake db:migrate
39
+ ```
40
+
41
+ ## Models
42
+
43
+ - `Effective::WorkExperienceCategory` — the top level grouping, with a minimum hours target
44
+ - `Effective::WorkExperienceSubcategory` — belongs to a category. Hours are recorded against these.
45
+ - `Effective::WorkExperienceRecord` — one intern's hours for one month
46
+ - `Effective::WorkExperienceEntry` — one row of a record. Five weeks of hours for one subcategory.
47
+ - `Effective::WorkExperienceProject` — one project an intern worked on
48
+ - `Effective::WorkExperienceSummary` — one period, submitted by the intern and reviewed by their mentor
49
+ - `Effective::WorkExperienceOutsideMentor` — a mentor without an account, stored as freeform fields
50
+ - `Effective::WorkExperienceReport` — an ActiveModel report of everything to date
51
+
52
+ The work experience summary is the only swappable class. Mark your own with `effective_work_experience_summary`:
53
+
54
+ ```ruby
55
+ module Bcsla
56
+ class WorkExperienceSummary < ApplicationRecord
57
+ effective_work_experience_summary
58
+ end
59
+ end
60
+ ```
61
+
62
+ and configure it:
63
+
64
+ ```ruby
65
+ config.work_experience_summary_class_name = 'Bcsla::WorkExperienceSummary'
66
+ ```
67
+
68
+ ## User
69
+
70
+ Add the following to your User model:
71
+
72
+ ```ruby
73
+ effective_work_experience_user
74
+ ```
75
+
76
+ This requires a `work_experience_mentor_id` column on your users table, and adds:
77
+
78
+ - `work_experience_mentor` — the user who reviews my work experience summaries
79
+ - `work_experience_mentees` — the interns I am a mentor for
80
+ - `work_experience_outside_mentor` — my mentor when they don't have an account. A `has_one`.
81
+ - `work_experience_records`, `work_experience_entries`, `work_experience_projects`, `work_experience_summaries`, `mentee_work_experience_summaries`
82
+ - the `work_experience_hours`, `work_experience_hours_by_year` and `work_experience_total_hours_to_date` calculations
83
+
84
+ An intern with an outside mentor has no `work_experience_mentor`, so their summaries are reviewed automatically on submit.
85
+
86
+ The summary's `user`, `mentor` and `supervisor` are polymorphic. A summary assigns its mentor from the user's `work_experience_mentor`, and its supervisor from the user's `supervisor` when your User model defines one.
87
+
88
+ Render the mentor fields from your own admin user form:
89
+
90
+ ```haml
91
+ = render('effective/work_experience/user_fields', f: f)
92
+ ```
93
+
94
+ This is the `work_experience_mentor` select plus an `f.has_many` builder for the one outside mentor.
95
+
96
+ ## Dashboard
97
+
98
+ Render the dashboard partials from your own dashboard:
99
+
100
+ ```haml
101
+ - if current_user.work_experience_intern?
102
+ = render 'effective/work_experience/dashboard_intern'
103
+
104
+ - if current_user.work_experience_mentor?
105
+ = render 'effective/work_experience/dashboard_mentor'
106
+ ```
107
+
108
+ ## Configuration
109
+
110
+ All configuration options are documented in the `config/initializers/effective_work_experience.rb` initializer.
111
+
112
+ ## Authorization
113
+
114
+ All authorization checks are handled via the effective_resources gem found in the `config/initializers/effective_resources.rb` file.
115
+
116
+ ## Permissions
117
+
118
+ The permissions you actually want to define are as follows (using CanCan):
119
+
120
+ ```ruby
121
+ if user.persisted?
122
+ can([:index, :show, :new, :create], Effective::WorkExperienceRecord) { |record| record.user == user }
123
+ can([:edit, :update], Effective::WorkExperienceRecord) { |record| !record.backdated? && !record.was_reviewed? }
124
+ can(:destroy, Effective::WorkExperienceRecord) { |record| !record.backdated? && !record.was_submitted? }
125
+
126
+ can(crud, Effective::WorkExperienceProject) { |project| project.user == user }
127
+
128
+ can([:new, :create], EffectiveWorkExperience.WorkExperienceSummary) { |summary| summary.user == user }
129
+ can(:destroy, EffectiveWorkExperience.WorkExperienceSummary) { |summary| summary.user == user && summary.draft? }
130
+
131
+ can([:show, :index], EffectiveWorkExperience.WorkExperienceSummary) do |summary|
132
+ summary.user == user || (summary.mentor == user && summary.was_submitted?)
133
+ end
134
+
135
+ can(:update, EffectiveWorkExperience.WorkExperienceSummary) do |summary|
136
+ (summary.user == user && !summary.was_submitted?) || (summary.mentor == user && summary.was_submitted?)
137
+ end
138
+
139
+ can(:show, Effective::WorkExperienceReport) { |report| report.user == user || report.mentor == user }
140
+
141
+ if user.work_experience_mentor?
142
+ can(:index, EffectiveWorkExperienceReportsReviewDatatable)
143
+ end
144
+ end
145
+
146
+ if user.admin?
147
+ can :admin, :effective_work_experience
148
+
149
+ can([:index, :edit, :update], Effective::WorkExperienceCategory)
150
+ can([:index, :edit, :update], Effective::WorkExperienceSubcategory)
151
+ can(crud - [:show], Effective::WorkExperienceProject)
152
+ can(crud - [:show], Effective::WorkExperienceRecord)
153
+ can(crud, Effective::WorkExperienceReport)
154
+ can(crud, EffectiveWorkExperience.WorkExperienceSummary)
155
+ can(:index, Admin::EffectiveWorkExperienceReportsDatatable)
156
+ end
157
+ ```
158
+
159
+ Add a link to the admin menu:
160
+
161
+ ```haml
162
+ - if can? :admin, :effective_work_experience
163
+ = nav_link_to Effective::WorkExperienceRecord, effective_work_experience.admin_work_experience_records_path
164
+ = nav_link_to Effective::WorkExperienceProject, effective_work_experience.admin_work_experience_projects_path
165
+ = nav_link_to EffectiveWorkExperience.WorkExperienceSummary, effective_work_experience.admin_work_experience_summaries_path
166
+ = nav_link_to Effective::WorkExperienceReport, effective_work_experience.admin_work_experience_reports_path
167
+ ```
168
+
169
+ ## License
170
+
171
+ MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
172
+
173
+ ## Testing
174
+
175
+ Run tests by:
176
+
177
+ ```ruby
178
+ rails test
179
+ ```
180
+
181
+ ## Contributing
182
+
183
+ 1. Fork it
184
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
185
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
186
+ 4. Push to the branch (`git push origin my-new-feature`)
187
+ 5. Bonus points for test coverage
188
+ 6. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
9
+
10
+ require "rake/testtask"
11
+
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = false
16
+ end
17
+
18
+ task default: :test
@@ -0,0 +1,3 @@
1
+ //= link_directory ../javascripts .js
2
+ //= link_directory ../stylesheets .css
3
+ //= link_tree ../images
@@ -0,0 +1 @@
1
+ //= require_tree ./effective_work_experience
@@ -0,0 +1,7 @@
1
+ .work-experience-summary {
2
+ .resource-buttons { margin-top: 1rem; }
3
+ }
4
+
5
+ .table-valign-middle {
6
+ td, th { vertical-align: middle; }
7
+ }
@@ -0,0 +1 @@
1
+ @import 'effective_work_experience/base';
@@ -0,0 +1,19 @@
1
+ module Admin
2
+ class WorkExperienceCategoriesController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_work_experience) }
5
+
6
+ include Effective::CrudController
7
+
8
+ resource_scope -> { Effective::WorkExperienceCategory.deep.all }
9
+ datatable -> { EffectiveResources.best('Admin::EffectiveWorkExperienceCategoriesDatatable').new }
10
+
11
+ private
12
+
13
+ def permitted_params
14
+ model = (params.key?(:effective_work_experience_category) ? :effective_work_experience_category : :work_experience_category)
15
+ params.require(model).permit!
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Admin
2
+ class WorkExperienceProjectsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_work_experience) }
5
+
6
+ include Effective::CrudController
7
+
8
+ resource_scope -> { Effective::WorkExperienceProject.deep.all }
9
+ datatable -> { EffectiveResources.best('Admin::EffectiveWorkExperienceProjectsDatatable').new }
10
+
11
+ private
12
+
13
+ def permitted_params
14
+ model = (params.key?(:effective_work_experience_project) ? :effective_work_experience_project : :work_experience_project)
15
+ params.require(model).permit!
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Admin
2
+ class WorkExperienceRecordsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_work_experience) }
5
+
6
+ include Effective::CrudController
7
+
8
+ resource_scope -> { Effective::WorkExperienceRecord.deep.all }
9
+ datatable -> { EffectiveResources.best('Admin::EffectiveWorkExperienceRecordsDatatable').new }
10
+
11
+ private
12
+
13
+ def permitted_params
14
+ model = (params.key?(:effective_work_experience_record) ? :effective_work_experience_record : :work_experience_record)
15
+ params.require(model).permit!
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ module Admin
2
+ class WorkExperienceReportsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_work_experience) }
5
+
6
+ include Effective::CrudController
7
+
8
+ resource_scope -> { Effective::WorkExperienceReport }
9
+ datatable -> { EffectiveResources.best('Admin::EffectiveWorkExperienceReportsDatatable').new }
10
+
11
+ def show
12
+ @user = current_user.class.find(params[:id])
13
+ @work_experience_report = resource_scope.new(user: @user)
14
+
15
+ @page_title = "#{EffectiveResources.et(@work_experience_report)} for #{@user}"
16
+
17
+ EffectiveResources.authorize!(self, :show, @work_experience_report)
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ module Admin
2
+ class WorkExperienceSubcategoriesController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_work_experience) }
5
+
6
+ include Effective::CrudController
7
+
8
+ resource_scope -> { Effective::WorkExperienceSubcategory.deep.all }
9
+ datatable -> { EffectiveResources.best('Admin::EffectiveWorkExperienceSubcategoriesDatatable').new }
10
+
11
+ private
12
+
13
+ def permitted_params
14
+ model = (params.key?(:effective_work_experience_subcategory) ? :effective_work_experience_subcategory : :work_experience_subcategory)
15
+ params.require(model).permit!
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Admin
2
+ class WorkExperienceSummariesController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_work_experience) }
5
+
6
+ include Effective::CrudController
7
+
8
+ resource_scope -> { EffectiveWorkExperience.WorkExperienceSummary.deep.all }
9
+ datatable -> { EffectiveResources.best('Admin::EffectiveWorkExperienceSummariesDatatable').new }
10
+
11
+ private
12
+
13
+ def permitted_params
14
+ model = (params.key?(:effective_work_experience_summary) ? :effective_work_experience_summary : :work_experience_summary)
15
+ params.require(model).permit!
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ module Effective
2
+ class WorkExperienceProjectsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+
5
+ include Effective::CrudController
6
+
7
+ resource_scope -> { Effective::WorkExperienceProject.deep.where(user: current_user) }
8
+
9
+ private
10
+
11
+ def permitted_params
12
+ model = (params.key?(:effective_work_experience_project) ? :effective_work_experience_project : :work_experience_project)
13
+ params.require(model).except(:user_id, :user_type).permit!
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Effective
2
+ class WorkExperienceRecordsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+
5
+ include Effective::CrudController
6
+
7
+ resource_scope -> { Effective::WorkExperienceRecord.deep.where(user: current_user) }
8
+
9
+ private
10
+
11
+ def permitted_params
12
+ model = (params.key?(:effective_work_experience_record) ? :effective_work_experience_record : :work_experience_record)
13
+ params.require(model).except(:user_id, :user_type).permit!
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ module Effective
2
+ class WorkExperienceReportsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+
5
+ include Effective::CrudController
6
+
7
+ resource_scope -> { Effective::WorkExperienceReport }
8
+
9
+ def show
10
+ @user = current_user.class.find(params[:id])
11
+ @work_experience_report = resource_scope.new(user: @user)
12
+
13
+ @page_title = "#{EffectiveResources.et(@work_experience_report)} for #{@user}"
14
+
15
+ EffectiveResources.authorize!(self, :show, @work_experience_report)
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ module Effective
2
+ class WorkExperienceSummariesController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+
5
+ include Effective::WizardController
6
+
7
+ resource_scope -> {
8
+ collection = EffectiveWorkExperience.WorkExperienceSummary.deep
9
+ collection.where(user: current_user).or(collection.where(mentor: current_user))
10
+ }
11
+
12
+ def build_wizard_resource
13
+ resource_scope.new(user: current_user)
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ module Admin
2
+ class EffectiveWorkExperienceCategoriesDatatable < Effective::Datatable
3
+ datatable do
4
+ order :position
5
+
6
+ col :updated_at, visible: false
7
+ col :created_at, visible: false
8
+ col :id, visible: false
9
+
10
+ reorder :position
11
+ col :title
12
+ col :minimum_hours
13
+
14
+ actions_col
15
+ end
16
+
17
+ collection do
18
+ Effective::WorkExperienceCategory.deep.all
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ module Admin
2
+ class EffectiveWorkExperienceProjectsDatatable < Effective::Datatable
3
+ datatable do
4
+ order :updated_at
5
+
6
+ col :updated_at, visible: false
7
+ col :created_at, visible: false
8
+ col :id, visible: false
9
+
10
+ col :user, label: 'Intern'
11
+ col :start_on
12
+ col :end_on
13
+ col :name
14
+ col :description
15
+
16
+ actions_col
17
+ end
18
+
19
+ collection do
20
+ Effective::WorkExperienceProject.deep.all
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ module Admin
2
+ class EffectiveWorkExperienceRecordsDatatable < Effective::Datatable
3
+ datatable do
4
+ order :updated_at
5
+
6
+ col :updated_at, visible: false
7
+ col :created_at, visible: false
8
+ col :id, visible: false
9
+
10
+ col :user, label: 'Intern'
11
+
12
+ col(:month) do |work_experience_record|
13
+ work_experience_record.month&.strftime('%F') || 'Backdated'
14
+ end
15
+
16
+ col(:total_hours, label: 'Hours') do |work_experience_record|
17
+ work_experience_hours_to_s(work_experience_record.total_hours)
18
+ end.aggregate do |work_experience_records|
19
+ total = work_experience_records.sum { |work_experience_record| work_experience_record.total_hours }
20
+ work_experience_hours_to_s(total)
21
+ end
22
+
23
+ col :status, visible: false
24
+ col :submitted_at, visible: false
25
+ col :reviewed_at, visible: false
26
+
27
+ aggregate :total
28
+
29
+ actions_col
30
+ end
31
+
32
+ collection do
33
+ Effective::WorkExperienceRecord.deep.all
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ module Admin
2
+ class EffectiveWorkExperienceReportsDatatable < Effective::Datatable
3
+ datatable do
4
+ col :user, label: 'Intern'
5
+ col :mentor
6
+
7
+ col(:total_hours, label: 'Total hours to date', as: :decimal) do |hours|
8
+ work_experience_hours_to_s(hours)
9
+ end
10
+
11
+ actions_col(actions: []) do |user|
12
+ dropdown_link_to('Show', effective_work_experience.admin_work_experience_report_path(user))
13
+ end
14
+ end
15
+
16
+ collection do
17
+ user_klass = current_user.class
18
+
19
+ work_experience_records = Effective::WorkExperienceRecord.where(user_type: user_klass.name)
20
+
21
+ users = user_klass.deep_work_experience.where(id: work_experience_records.select(:user_id))
22
+
23
+ users.map do |user|
24
+ [
25
+ user,
26
+ user.work_experience_mentor,
27
+ user.work_experience_total_hours_to_date(month: Time.zone.now.end_of_year),
28
+ user
29
+ ]
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ module Admin
2
+ class EffectiveWorkExperienceSubcategoriesDatatable < Effective::Datatable
3
+ datatable do
4
+ reorder :position
5
+
6
+ col :updated_at, visible: false
7
+ col :created_at, visible: false
8
+ col :id, visible: false
9
+
10
+ col :position
11
+ col :work_experience_category, search: { collection: Effective::WorkExperienceCategory.sorted.all }
12
+ col :title
13
+ col :minimum_hours
14
+ col :body
15
+
16
+ actions_col
17
+ end
18
+
19
+ collection do
20
+ Effective::WorkExperienceSubcategory.deep.all
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,57 @@
1
+ module Admin
2
+ class EffectiveWorkExperienceSummariesDatatable < Effective::Datatable
3
+ filters do
4
+ scope :all
5
+ scope :draft
6
+ scope :submitted
7
+ scope :reviewed
8
+ end
9
+
10
+ datatable do
11
+ order :updated_at
12
+
13
+ col :updated_at, visible: false
14
+ col :created_at, visible: false
15
+ col :id, visible: false
16
+
17
+ col :start_on, search: work_experience_summary_start_on_collection()
18
+ col :end_on, visible: false
19
+ col :period
20
+ col :status
21
+
22
+ col :user, label: 'Intern'
23
+ col :mentor
24
+ col :supervisor, visible: false
25
+
26
+ col(:total_hours) do |work_experience_summary|
27
+ work_experience_hours_to_s(work_experience_summary.total_hours)
28
+ end
29
+
30
+ col(:total_hours_to_date, as: :decimal) do |work_experience_summary|
31
+ work_experience_hours_to_s(work_experience_summary.total_hours_to_date)
32
+ end
33
+
34
+ col(:submitted_at, label: 'Submitted') do |work_experience_summary|
35
+ work_experience_summary.submitted_at&.strftime('%F')
36
+ end
37
+
38
+ col(:reviewed_at, label: 'Reviewed', as: :date) do |work_experience_summary|
39
+ work_experience_summary.reviewed_at&.strftime('%F')
40
+ end
41
+
42
+ col :recommendation, visible: false
43
+ col :comments
44
+
45
+ col :status_steps, visible: false
46
+ col :wizard_steps, visible: false
47
+ col :token, visible: false
48
+
49
+ actions_col
50
+ end
51
+
52
+ collection do
53
+ EffectiveWorkExperience.WorkExperienceSummary.deep.all
54
+ end
55
+
56
+ end
57
+ end