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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +188 -0
- data/Rakefile +18 -0
- data/app/assets/config/effective_work_experience_manifest.js +3 -0
- data/app/assets/javascripts/effective_work_experience/base.js +0 -0
- data/app/assets/javascripts/effective_work_experience.js +1 -0
- data/app/assets/stylesheets/effective_work_experience/base.scss +7 -0
- data/app/assets/stylesheets/effective_work_experience.scss +1 -0
- data/app/controllers/admin/work_experience_categories_controller.rb +19 -0
- data/app/controllers/admin/work_experience_projects_controller.rb +19 -0
- data/app/controllers/admin/work_experience_records_controller.rb +19 -0
- data/app/controllers/admin/work_experience_reports_controller.rb +21 -0
- data/app/controllers/admin/work_experience_subcategories_controller.rb +19 -0
- data/app/controllers/admin/work_experience_summaries_controller.rb +19 -0
- data/app/controllers/effective/work_experience_projects_controller.rb +17 -0
- data/app/controllers/effective/work_experience_records_controller.rb +17 -0
- data/app/controllers/effective/work_experience_reports_controller.rb +19 -0
- data/app/controllers/effective/work_experience_summaries_controller.rb +17 -0
- data/app/datatables/admin/effective_work_experience_categories_datatable.rb +22 -0
- data/app/datatables/admin/effective_work_experience_projects_datatable.rb +24 -0
- data/app/datatables/admin/effective_work_experience_records_datatable.rb +37 -0
- data/app/datatables/admin/effective_work_experience_reports_datatable.rb +34 -0
- data/app/datatables/admin/effective_work_experience_subcategories_datatable.rb +24 -0
- data/app/datatables/admin/effective_work_experience_summaries_datatable.rb +57 -0
- data/app/datatables/effective_work_experience_projects_datatable.rb +38 -0
- data/app/datatables/effective_work_experience_records_datatable.rb +61 -0
- data/app/datatables/effective_work_experience_reports_review_datatable.rb +15 -0
- data/app/datatables/effective_work_experience_summaries_datatable.rb +49 -0
- data/app/datatables/effective_work_experience_summaries_review_datatable.rb +43 -0
- data/app/helpers/effective_work_experience_helper.rb +46 -0
- data/app/mailers/effective/work_experience_mailer.rb +39 -0
- data/app/models/concerns/effective_work_experience_summary.rb +264 -0
- data/app/models/concerns/effective_work_experience_user.rb +135 -0
- data/app/models/effective/work_experience_category.rb +29 -0
- data/app/models/effective/work_experience_entry.rb +43 -0
- data/app/models/effective/work_experience_outside_mentor.rb +35 -0
- data/app/models/effective/work_experience_project.rb +38 -0
- data/app/models/effective/work_experience_record.rb +99 -0
- data/app/models/effective/work_experience_report.rb +50 -0
- data/app/models/effective/work_experience_subcategory.rb +31 -0
- data/app/models/effective/work_experience_summary.rb +7 -0
- data/app/views/admin/work_experience/_user_fields.html.haml +17 -0
- data/app/views/admin/work_experience/_user_work_experience.html.haml +21 -0
- data/app/views/admin/work_experience_categories/_form.html.haml +7 -0
- data/app/views/admin/work_experience_categories/_form_work_experience_category.html.haml +5 -0
- data/app/views/admin/work_experience_projects/_form.html.haml +11 -0
- data/app/views/admin/work_experience_projects/_work_experience_project.html.haml +1 -0
- data/app/views/admin/work_experience_records/_form.html.haml +12 -0
- data/app/views/admin/work_experience_records/_work_experience_record.html.haml +1 -0
- data/app/views/admin/work_experience_reports/show.html.haml +2 -0
- data/app/views/admin/work_experience_subcategories/_form.html.haml +7 -0
- data/app/views/admin/work_experience_subcategories/_form_work_experience_subcategory.html.haml +10 -0
- data/app/views/admin/work_experience_summaries/_form.html.haml +7 -0
- data/app/views/admin/work_experience_summaries/_form_work_experience_summary.html.haml +32 -0
- data/app/views/admin/work_experience_summaries/_work_experience_summary.html.haml +1 -0
- data/app/views/effective/work_experience/_dashboard_intern.html.haml +73 -0
- data/app/views/effective/work_experience/_dashboard_mentor.html.haml +28 -0
- data/app/views/effective/work_experience_mailer/work_experience_summary_reviewed.liquid +13 -0
- data/app/views/effective/work_experience_mailer/work_experience_summary_submitted.liquid +15 -0
- data/app/views/effective/work_experience_outside_mentors/_fields.html.haml +5 -0
- data/app/views/effective/work_experience_projects/_fields.html.haml +7 -0
- data/app/views/effective/work_experience_projects/_form.html.haml +3 -0
- data/app/views/effective/work_experience_projects/_work_experience_project.html.haml +2 -0
- data/app/views/effective/work_experience_records/_fields.html.haml +52 -0
- data/app/views/effective/work_experience_records/_form.html.haml +5 -0
- data/app/views/effective/work_experience_records/_work_experience_record.html.haml +63 -0
- data/app/views/effective/work_experience_reports/_work_experience_report.html.haml +103 -0
- data/app/views/effective/work_experience_reports/show.html.haml +2 -0
- data/app/views/effective/work_experience_summaries/_content.html.haml +1 -0
- data/app/views/effective/work_experience_summaries/_layout.html.haml +3 -0
- data/app/views/effective/work_experience_summaries/_projects.html.haml +5 -0
- data/app/views/effective/work_experience_summaries/_projects_datatable.html.haml +2 -0
- data/app/views/effective/work_experience_summaries/_projects_fields.html.haml +1 -0
- data/app/views/effective/work_experience_summaries/_records.html.haml +65 -0
- data/app/views/effective/work_experience_summaries/_records_datatable.html.haml +2 -0
- data/app/views/effective/work_experience_summaries/_records_fields.html.haml +1 -0
- data/app/views/effective/work_experience_summaries/_review.html.haml +4 -0
- data/app/views/effective/work_experience_summaries/_review_fields.html.haml +4 -0
- data/app/views/effective/work_experience_summaries/_reviewed.html.haml +1 -0
- data/app/views/effective/work_experience_summaries/_start_fields.html.haml +1 -0
- data/app/views/effective/work_experience_summaries/_summary.html.haml +79 -0
- data/app/views/effective/work_experience_summaries/_user.html.haml +7 -0
- data/app/views/effective/work_experience_summaries/_work_experience_summary.html.haml +7 -0
- data/app/views/effective/work_experience_summaries/projects.html.haml +14 -0
- data/app/views/effective/work_experience_summaries/records.html.haml +14 -0
- data/app/views/effective/work_experience_summaries/review.html.haml +13 -0
- data/app/views/effective/work_experience_summaries/reviewed.html.haml +11 -0
- data/app/views/effective/work_experience_summaries/start.html.haml +16 -0
- data/app/views/effective/work_experience_summaries/submit.html.haml +10 -0
- data/app/views/effective/work_experience_summaries/submitted.html.haml +19 -0
- data/config/effective_work_experience.rb +34 -0
- data/config/locales/effective_work_experience.en.yml +94 -0
- data/config/routes.rb +28 -0
- data/db/migrate/101_create_effective_work_experience.rb +120 -0
- data/db/seeds.rb +40 -0
- data/lib/effective_work_experience/engine.rb +19 -0
- data/lib/effective_work_experience/version.rb +3 -0
- data/lib/effective_work_experience.rb +34 -0
- data/lib/generators/effective_work_experience/install_generator.rb +24 -0
- data/lib/generators/templates/effective_work_experience_mailer_preview.rb +4 -0
- data/lib/tasks/effective_work_experience_tasks.rake +8 -0
- metadata +325 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# The top level grouping of work experience subcategories
|
|
2
|
+
module Effective
|
|
3
|
+
class WorkExperienceCategory < ActiveRecord::Base
|
|
4
|
+
self.table_name = (EffectiveWorkExperience.work_experience_categories_table_name || :work_experience_categories).to_s
|
|
5
|
+
|
|
6
|
+
log_changes if respond_to?(:log_changes)
|
|
7
|
+
|
|
8
|
+
has_many :work_experience_subcategories, -> { order(:position) }, class_name: 'Effective::WorkExperienceSubcategory', inverse_of: :work_experience_category
|
|
9
|
+
|
|
10
|
+
effective_resource do
|
|
11
|
+
title :string
|
|
12
|
+
minimum_hours :integer
|
|
13
|
+
position :integer
|
|
14
|
+
|
|
15
|
+
timestamps
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
scope :sorted, -> { order(:position) }
|
|
19
|
+
scope :deep, -> { all }
|
|
20
|
+
|
|
21
|
+
validates :title, presence: true, uniqueness: true
|
|
22
|
+
validates :minimum_hours, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
|
|
23
|
+
validates :position, numericality: { greater_than: 0 }
|
|
24
|
+
|
|
25
|
+
def to_s
|
|
26
|
+
title.presence || model_name.human
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# One row in a monthly work experience record
|
|
2
|
+
module Effective
|
|
3
|
+
class WorkExperienceEntry < ActiveRecord::Base
|
|
4
|
+
self.table_name = (EffectiveWorkExperience.work_experience_entries_table_name || :work_experience_entries).to_s
|
|
5
|
+
|
|
6
|
+
belongs_to :user, polymorphic: true
|
|
7
|
+
belongs_to :work_experience_record, class_name: 'Effective::WorkExperienceRecord', inverse_of: :work_experience_entries
|
|
8
|
+
belongs_to :work_experience_subcategory, class_name: 'Effective::WorkExperienceSubcategory'
|
|
9
|
+
|
|
10
|
+
log_changes(to: :user) if respond_to?(:log_changes)
|
|
11
|
+
|
|
12
|
+
effective_resource do
|
|
13
|
+
week_1 :decimal
|
|
14
|
+
week_2 :decimal
|
|
15
|
+
week_3 :decimal
|
|
16
|
+
week_4 :decimal
|
|
17
|
+
week_5 :decimal
|
|
18
|
+
|
|
19
|
+
timestamps
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
before_validation(if: -> { work_experience_record.present? }) do
|
|
23
|
+
assign_attributes(user: work_experience_record.user)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
validates :week_1, numericality: { greater_than_or_equal_to: 0.0, allow_blank: true }
|
|
27
|
+
validates :week_2, numericality: { greater_than_or_equal_to: 0.0, allow_blank: true }
|
|
28
|
+
validates :week_3, numericality: { greater_than_or_equal_to: 0.0, allow_blank: true }
|
|
29
|
+
validates :week_4, numericality: { greater_than_or_equal_to: 0.0, allow_blank: true }
|
|
30
|
+
validates :week_5, numericality: { greater_than_or_equal_to: 0.0, allow_blank: true }
|
|
31
|
+
|
|
32
|
+
scope :sorted, -> { order(:id) }
|
|
33
|
+
scope :deep, -> { includes(:user, work_experience_subcategory: :work_experience_category) }
|
|
34
|
+
|
|
35
|
+
def to_s
|
|
36
|
+
'work experience entry'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def hours
|
|
40
|
+
(week_1.to_f + week_2.to_f + week_3.to_f + week_4.to_f + week_5.to_f)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# An intern whose mentor does not have an account. We store their mentor as freeform fields.
|
|
2
|
+
module Effective
|
|
3
|
+
class WorkExperienceOutsideMentor < ActiveRecord::Base
|
|
4
|
+
self.table_name = (EffectiveWorkExperience.work_experience_outside_mentors_table_name || :work_experience_outside_mentors).to_s
|
|
5
|
+
|
|
6
|
+
belongs_to :user, polymorphic: true
|
|
7
|
+
|
|
8
|
+
log_changes(to: :user) if respond_to?(:log_changes)
|
|
9
|
+
|
|
10
|
+
effective_resource do
|
|
11
|
+
name :string
|
|
12
|
+
email :string
|
|
13
|
+
phone :string
|
|
14
|
+
regulated_profession :string
|
|
15
|
+
admin_notes :text
|
|
16
|
+
|
|
17
|
+
timestamps
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
scope :sorted, -> { order(:name) }
|
|
21
|
+
scope :deep, -> { includes(:user) }
|
|
22
|
+
|
|
23
|
+
validates :name, presence: true
|
|
24
|
+
validates :email, presence: true, email: true
|
|
25
|
+
validates :phone, presence: true
|
|
26
|
+
validates :regulated_profession, presence: true
|
|
27
|
+
|
|
28
|
+
# A user has just one outside mentor
|
|
29
|
+
validates :user_id, uniqueness: { scope: :user_type }
|
|
30
|
+
|
|
31
|
+
def to_s
|
|
32
|
+
name.presence || model_name.human
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# A work experience project
|
|
2
|
+
module Effective
|
|
3
|
+
class WorkExperienceProject < ActiveRecord::Base
|
|
4
|
+
self.table_name = (EffectiveWorkExperience.work_experience_projects_table_name || :work_experience_projects).to_s
|
|
5
|
+
|
|
6
|
+
belongs_to :user, polymorphic: true
|
|
7
|
+
|
|
8
|
+
log_changes(to: :user) if respond_to?(:log_changes)
|
|
9
|
+
|
|
10
|
+
effective_resource do
|
|
11
|
+
name :string
|
|
12
|
+
description :text
|
|
13
|
+
|
|
14
|
+
start_on :date
|
|
15
|
+
end_on :date
|
|
16
|
+
|
|
17
|
+
timestamps
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
scope :sorted, -> { order(:start_on) }
|
|
21
|
+
scope :deep, -> { includes(:user) }
|
|
22
|
+
|
|
23
|
+
scope :during, ->(months) {
|
|
24
|
+
where('start_on <= ? AND (end_on IS NULL OR end_on >= ?)', months.last, months.first)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
validates :name, presence: true, uniqueness: { scope: [:user_id, :user_type] }
|
|
28
|
+
validates :start_on, presence: true
|
|
29
|
+
|
|
30
|
+
validate(if: -> { start_on.present? && end_on.present? }) do
|
|
31
|
+
errors.add(:end_on, 'must be after the start date') if end_on < start_on
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_s
|
|
35
|
+
name.presence || model_name.human
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# A monthly record of work experience
|
|
2
|
+
module Effective
|
|
3
|
+
class WorkExperienceRecord < ActiveRecord::Base
|
|
4
|
+
self.table_name = (EffectiveWorkExperience.work_experience_records_table_name || :work_experience_records).to_s
|
|
5
|
+
|
|
6
|
+
belongs_to :user, polymorphic: true
|
|
7
|
+
|
|
8
|
+
has_many :work_experience_entries, -> { order(:id) }, class_name: 'Effective::WorkExperienceEntry', inverse_of: :work_experience_record, dependent: :destroy
|
|
9
|
+
accepts_nested_attributes_for :work_experience_entries, allow_destroy: true
|
|
10
|
+
|
|
11
|
+
log_changes(to: :user) if respond_to?(:log_changes)
|
|
12
|
+
has_many_rich_texts
|
|
13
|
+
|
|
14
|
+
acts_as_statused(
|
|
15
|
+
:draft, # In-progress submission
|
|
16
|
+
:submitted, # Submitted by intern
|
|
17
|
+
:reviewed # Reviewed by mentor
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
effective_resource do
|
|
21
|
+
month :date # The 1st day of the month of the work experience
|
|
22
|
+
total_hours :decimal # The total number of hours worked for the month
|
|
23
|
+
|
|
24
|
+
# There can only be one backdated work experience record
|
|
25
|
+
backdated :boolean, default: false
|
|
26
|
+
|
|
27
|
+
# Acts as Statused
|
|
28
|
+
status :string
|
|
29
|
+
status_steps :text
|
|
30
|
+
|
|
31
|
+
submitted_at :datetime
|
|
32
|
+
reviewed_at :datetime
|
|
33
|
+
|
|
34
|
+
timestamps
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
before_validation do
|
|
38
|
+
assign_attributes(total_hours: work_experience_entries.sum(&:hours).round(2))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
before_validation do
|
|
42
|
+
assign_attributes(month: month&.beginning_of_month)
|
|
43
|
+
assign_attributes(month: nil) if backdated?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
validates :month, presence: true, unless: -> { backdated }
|
|
47
|
+
validates :month, absence: true, if: -> { backdated }
|
|
48
|
+
|
|
49
|
+
validates :month, uniqueness: { scope: [:user_id, :user_type] }
|
|
50
|
+
validates :total_hours, numericality: { greater_than_or_equal_to: 0.0 }
|
|
51
|
+
|
|
52
|
+
validate(if: -> { month.present? }) do
|
|
53
|
+
errors.add(:month, 'must be the first day of the month') unless month.day == 1
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
scope :sorted, -> { order(:month) }
|
|
57
|
+
scope :deep, -> { includes(:user, work_experience_entries: { work_experience_subcategory: :work_experience_category }) }
|
|
58
|
+
scope :during, ->(months) { where(month: months) }
|
|
59
|
+
|
|
60
|
+
def to_s
|
|
61
|
+
month&.strftime('%B %Y') || model_name.human
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def work_experience_subcategories
|
|
65
|
+
Effective::WorkExperienceSubcategory.all.sorted
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Find or build
|
|
69
|
+
def work_experience_entry(work_experience_subcategory:)
|
|
70
|
+
entry = work_experience_entries.find { |work_experience_entry| work_experience_entry.work_experience_subcategory_id == work_experience_subcategory.id }
|
|
71
|
+
entry ||= work_experience_entries.build(work_experience_subcategory: work_experience_subcategory)
|
|
72
|
+
entry
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def week_1_total
|
|
76
|
+
work_experience_entries.sum { |work_experience_entry| work_experience_entry.week_1 || 0.0 }.round(2)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def week_2_total
|
|
80
|
+
work_experience_entries.sum { |work_experience_entry| work_experience_entry.week_2 || 0.0 }.round(2)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def week_3_total
|
|
84
|
+
work_experience_entries.sum { |work_experience_entry| work_experience_entry.week_3 || 0.0 }.round(2)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def week_4_total
|
|
88
|
+
work_experience_entries.sum { |work_experience_entry| work_experience_entry.week_4 || 0.0 }.round(2)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def week_5_total
|
|
92
|
+
work_experience_entries.sum { |work_experience_entry| work_experience_entry.week_5 || 0.0 }.round(2)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def total_hours_to_date
|
|
96
|
+
user&.work_experience_total_hours_to_date(month: month)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# The total work experience for one intern. Not an ActiveRecord model.
|
|
2
|
+
module Effective
|
|
3
|
+
class WorkExperienceReport
|
|
4
|
+
include ActiveModel::Model
|
|
5
|
+
|
|
6
|
+
attr_accessor :user # The intern
|
|
7
|
+
|
|
8
|
+
def to_s
|
|
9
|
+
'Work Experience Report'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_param
|
|
13
|
+
user&.to_param
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def mentor
|
|
17
|
+
user&.try(:work_experience_mentor)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def backdated_work_experience_record
|
|
21
|
+
work_experience_records.find(&:backdated?)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def start_on
|
|
25
|
+
work_experience_records.select { |work_experience_record| work_experience_record.month.present? }.map(&:month).sort.first
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def end_on
|
|
29
|
+
work_experience_records.select { |work_experience_record| work_experience_record.month.present? }.map(&:month).sort.last
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def years
|
|
33
|
+
return [] unless start_on.present?
|
|
34
|
+
(start_on.year..end_on.year).to_a
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def total_hours
|
|
38
|
+
work_experience_records.sum { |work_experience_record| work_experience_record.total_hours.to_f }.round(2)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def work_experience_subcategories
|
|
42
|
+
@work_experience_subcategories ||= Effective::WorkExperienceSubcategory.all.sorted
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def work_experience_records
|
|
46
|
+
return unless user.present?
|
|
47
|
+
@work_experience_records ||= user.work_experience_records
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# The subcategories of work experience. Interns record their hours against these.
|
|
2
|
+
module Effective
|
|
3
|
+
class WorkExperienceSubcategory < ActiveRecord::Base
|
|
4
|
+
self.table_name = (EffectiveWorkExperience.work_experience_subcategories_table_name || :work_experience_subcategories).to_s
|
|
5
|
+
|
|
6
|
+
belongs_to :work_experience_category, class_name: 'Effective::WorkExperienceCategory'
|
|
7
|
+
|
|
8
|
+
log_changes if respond_to?(:log_changes)
|
|
9
|
+
has_rich_text :body
|
|
10
|
+
|
|
11
|
+
effective_resource do
|
|
12
|
+
title :string
|
|
13
|
+
minimum_hours :integer
|
|
14
|
+
position :integer
|
|
15
|
+
work_experience_category_id :integer
|
|
16
|
+
|
|
17
|
+
timestamps
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
scope :sorted, -> { order(:position) }
|
|
21
|
+
scope :deep, -> { includes(:rich_text_body, :work_experience_category) }
|
|
22
|
+
|
|
23
|
+
validates :title, presence: true, uniqueness: { scope: :work_experience_category_id }
|
|
24
|
+
validates :minimum_hours, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
|
|
25
|
+
validates :position, numericality: { greater_than: 0 }, uniqueness: true
|
|
26
|
+
|
|
27
|
+
def to_s
|
|
28
|
+
[position, title].compact.join('. ').presence || model_name.human
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
-# Render this from your admin user form to assign an intern's work experience mentor
|
|
2
|
+
-# = render('admin/work_experience/user_fields', f: f, hint: 'Who can be a mentor')
|
|
3
|
+
- ajax_url = (effective_resources.users_effective_ajax_index_path unless Rails.env.test?)
|
|
4
|
+
- f.object.work_experience_outside_mentor_present = true if f.object.work_experience_outside_mentor?
|
|
5
|
+
|
|
6
|
+
= f.hide_if(:work_experience_outside_mentor_present, true) do
|
|
7
|
+
= f.select :work_experience_mentor_id, current_user.class.all, ajax_url: ajax_url,
|
|
8
|
+
label: 'Intern work experience mentor',
|
|
9
|
+
hint: local_assigns[:hint]
|
|
10
|
+
|
|
11
|
+
= f.check_box :work_experience_outside_mentor_present, label: 'Intern work experience mentor is from another regulated profession'
|
|
12
|
+
|
|
13
|
+
= f.show_if(:work_experience_outside_mentor_present, true) do
|
|
14
|
+
= card('Outside Mentor') do
|
|
15
|
+
-# One outside mentor is built. It's ignored unless the fields are filled in.
|
|
16
|
+
= f.has_many :work_experience_outside_mentors, label: false, add: false, remove: false, reorder: false do |fo|
|
|
17
|
+
= render('effective/work_experience_outside_mentors/fields', f: fo)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
-# Render this from your admin user form to display an intern's work experience
|
|
2
|
+
-# = render('admin/work_experience/user_work_experience', user: user)
|
|
3
|
+
= card(et(Effective::WorkExperienceReport)) do
|
|
4
|
+
= collapse("Show summary", card_class: 'mt-3') do
|
|
5
|
+
- work_experience_report = Effective::WorkExperienceReport.new(user: user)
|
|
6
|
+
= render('effective/work_experience_reports/work_experience_report', work_experience_report: work_experience_report)
|
|
7
|
+
|
|
8
|
+
= card(EffectiveWorkExperience.WorkExperienceSummary) do
|
|
9
|
+
%p.text-muted #{EffectiveWorkExperience.summary_months}-month work experience summaries are submitted by the intern and approved by their mentor.
|
|
10
|
+
- datatable = Admin::EffectiveWorkExperienceSummariesDatatable.new(user: user)
|
|
11
|
+
= render_datatable(datatable, inline: true)
|
|
12
|
+
|
|
13
|
+
= card(Effective::WorkExperienceRecord) do
|
|
14
|
+
%p.text-muted Monthly work experience records are used to keep track of the intern's hours each month.
|
|
15
|
+
- datatable = Admin::EffectiveWorkExperienceRecordsDatatable.new(user: user)
|
|
16
|
+
= render_datatable(datatable, inline: true)
|
|
17
|
+
|
|
18
|
+
= card(Effective::WorkExperienceProject) do
|
|
19
|
+
%p.text-muted Work experience projects are used to keep track of the intern's projects.
|
|
20
|
+
- datatable = Admin::EffectiveWorkExperienceProjectsDatatable.new(user: user)
|
|
21
|
+
= render_datatable(datatable, inline: true)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
= tabs do
|
|
2
|
+
= tab(work_experience_category) do
|
|
3
|
+
= render 'admin/work_experience_categories/form_work_experience_category', work_experience_category: work_experience_category
|
|
4
|
+
|
|
5
|
+
- if work_experience_category.persisted? && work_experience_category.respond_to?(:logs_datatable)
|
|
6
|
+
= tab 'Logs' do
|
|
7
|
+
= render_datatable(work_experience_category.logs_datatable, inline: true)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
= effective_form_with(model: [:admin, work_experience_project], engine: true) do |f|
|
|
2
|
+
= f.hidden_field :user_id
|
|
3
|
+
= f.hidden_field :user_type, value: current_user.class.name
|
|
4
|
+
|
|
5
|
+
- unless inline_datatable?
|
|
6
|
+
= f.select :user_id, current_user.class.all,
|
|
7
|
+
ajax_url: (effective_resources.users_effective_ajax_index_path unless Rails.env.test?)
|
|
8
|
+
|
|
9
|
+
= render('effective/work_experience_projects/fields', f: f)
|
|
10
|
+
|
|
11
|
+
= effective_submit(f)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
= render('effective/work_experience_projects/work_experience_project', work_experience_project: work_experience_project)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
= effective_form_with(model: [:admin, work_experience_record], engine: true) do |f|
|
|
2
|
+
= f.hidden_field :user_id
|
|
3
|
+
= f.hidden_field :user_type, value: current_user.class.name
|
|
4
|
+
|
|
5
|
+
= card(et(f.object)) do
|
|
6
|
+
- unless inline_datatable?
|
|
7
|
+
= f.select :user_id, current_user.class.all,
|
|
8
|
+
ajax_url: (effective_resources.users_effective_ajax_index_path unless Rails.env.test?)
|
|
9
|
+
|
|
10
|
+
= render('effective/work_experience_records/fields', f: f, namespace: :admin)
|
|
11
|
+
|
|
12
|
+
= effective_submit(f)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
= render('effective/work_experience_records/work_experience_record', work_experience_record: work_experience_record)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
= tabs do
|
|
2
|
+
= tab(work_experience_subcategory) do
|
|
3
|
+
= render 'admin/work_experience_subcategories/form_work_experience_subcategory', work_experience_subcategory: work_experience_subcategory
|
|
4
|
+
|
|
5
|
+
- if work_experience_subcategory.persisted? && work_experience_subcategory.respond_to?(:logs_datatable)
|
|
6
|
+
= tab 'Logs' do
|
|
7
|
+
= render_datatable(work_experience_subcategory.logs_datatable, inline: true)
|
data/app/views/admin/work_experience_subcategories/_form_work_experience_subcategory.html.haml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
= effective_form_with(model: [:admin, work_experience_subcategory], engine: true) do |f|
|
|
2
|
+
= f.select :work_experience_category_id, Effective::WorkExperienceCategory.sorted.all
|
|
3
|
+
|
|
4
|
+
= f.text_field :title
|
|
5
|
+
|
|
6
|
+
= f.number_field :minimum_hours, hint: 'Guidance target hours for this subcategory over the intern period'
|
|
7
|
+
|
|
8
|
+
= f.article_editor :body
|
|
9
|
+
|
|
10
|
+
= effective_submit(f)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
= tabs do
|
|
2
|
+
= tab(work_experience_summary) do
|
|
3
|
+
= render 'admin/work_experience_summaries/form_work_experience_summary', work_experience_summary: work_experience_summary
|
|
4
|
+
|
|
5
|
+
- if work_experience_summary.persisted? && work_experience_summary.respond_to?(:logs_datatable)
|
|
6
|
+
= tab 'Logs' do
|
|
7
|
+
= render_datatable(work_experience_summary.logs_datatable, inline: true)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
= effective_form_with(model: [:admin, work_experience_summary], engine: true) do |f|
|
|
2
|
+
= f.hidden_field :user_id
|
|
3
|
+
= f.hidden_field :user_type, value: current_user.class.name
|
|
4
|
+
= f.hidden_field :mentor_type, value: current_user.class.name
|
|
5
|
+
= f.hidden_field :supervisor_type, value: current_user.class.name
|
|
6
|
+
|
|
7
|
+
- unless inline_datatable?
|
|
8
|
+
= f.select :user_id, current_user.class.all,
|
|
9
|
+
ajax_url: (effective_resources.users_effective_ajax_index_path unless Rails.env.test?)
|
|
10
|
+
|
|
11
|
+
= f.select :mentor_id, current_user.class.all,
|
|
12
|
+
ajax_url: (effective_resources.users_effective_ajax_index_path unless Rails.env.test?)
|
|
13
|
+
|
|
14
|
+
= f.select :supervisor_id, current_user.class.all,
|
|
15
|
+
ajax_url: (effective_resources.users_effective_ajax_index_path unless Rails.env.test?)
|
|
16
|
+
|
|
17
|
+
= f.select :status, work_experience_summary_status_collection
|
|
18
|
+
|
|
19
|
+
-# Read only. These are serialized hashes and can't be submitted back as text.
|
|
20
|
+
= f.static_field :status_steps
|
|
21
|
+
= f.static_field :wizard_steps
|
|
22
|
+
|
|
23
|
+
= f.date_field :start_on
|
|
24
|
+
= f.date_field :end_on
|
|
25
|
+
= f.number_field :total_hours
|
|
26
|
+
= f.select :recommendation, work_experience_recommendation_collection
|
|
27
|
+
= f.text_area :comments
|
|
28
|
+
= f.datetime_field :submitted_at
|
|
29
|
+
= f.datetime_field :reviewed_at
|
|
30
|
+
= f.text_field :token
|
|
31
|
+
|
|
32
|
+
= effective_submit(f)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
= render('effective/work_experience_summaries/work_experience_summary', work_experience_summary: work_experience_summary)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
%h2 Work Experience
|
|
2
|
+
|
|
3
|
+
%p Please use the following tables to track your work experience.
|
|
4
|
+
|
|
5
|
+
%p
|
|
6
|
+
You can view your entire
|
|
7
|
+
= link_to("work experience summary report", effective_work_experience.work_experience_report_path(current_user))
|
|
8
|
+
at any time.
|
|
9
|
+
|
|
10
|
+
%p Interns are required to submit a record for each month of their internship. Every #{EffectiveWorkExperience.summary_months} months they are required to submit a summary report.
|
|
11
|
+
|
|
12
|
+
%hr
|
|
13
|
+
|
|
14
|
+
%h4 Mentor
|
|
15
|
+
|
|
16
|
+
- if current_user.work_experience_mentor.present?
|
|
17
|
+
%p Your mentor is #{link_to(current_user.work_experience_mentor, "mailto:#{current_user.work_experience_mentor.email}")}.
|
|
18
|
+
- elsif current_user.work_experience_outside_mentor?
|
|
19
|
+
- outside_mentor = current_user.work_experience_outside_mentor
|
|
20
|
+
%p Your outside mentor is #{link_to(outside_mentor.name, "mailto:#{outside_mentor.email}")}.
|
|
21
|
+
- else
|
|
22
|
+
%p You have not been assigned a mentor. Please contact us to be assigned one.
|
|
23
|
+
|
|
24
|
+
%hr
|
|
25
|
+
|
|
26
|
+
%h4 Monthly Records
|
|
27
|
+
%p Please use the following table to track your monthly #{etsd(Effective::WorkExperienceRecord)}.
|
|
28
|
+
|
|
29
|
+
.mb-2
|
|
30
|
+
= collapse("Show #{ets(Effective::WorkExperienceRecord)}") do
|
|
31
|
+
- datatable = EffectiveWorkExperienceRecordsDatatable.new(self, user: current_user)
|
|
32
|
+
= render_datatable(datatable)
|
|
33
|
+
|
|
34
|
+
%p= link_to "Add a new #{etd(Effective::WorkExperienceRecord)}", effective_work_experience.new_work_experience_record_path, class: 'btn btn-primary'
|
|
35
|
+
|
|
36
|
+
%hr
|
|
37
|
+
|
|
38
|
+
%h4 Projects
|
|
39
|
+
%p Please use the following table to track your #{etsd(Effective::WorkExperienceProject)}.
|
|
40
|
+
|
|
41
|
+
.mb-2
|
|
42
|
+
= collapse("Show #{ets(Effective::WorkExperienceProject)}") do
|
|
43
|
+
- datatable = EffectiveWorkExperienceProjectsDatatable.new(self, user: current_user)
|
|
44
|
+
= render_datatable(datatable)
|
|
45
|
+
|
|
46
|
+
%p= link_to "Add a new #{etd(Effective::WorkExperienceProject)}", effective_work_experience.new_work_experience_project_path, class: 'btn btn-primary'
|
|
47
|
+
|
|
48
|
+
%hr
|
|
49
|
+
|
|
50
|
+
%h4 #{EffectiveWorkExperience.summary_months}-Month Summary Submissions
|
|
51
|
+
%p Every #{EffectiveWorkExperience.summary_months} months you are required to submit a summary of your work experience to be reviewed by your mentor.
|
|
52
|
+
|
|
53
|
+
.mb-2
|
|
54
|
+
= collapse("Show #{ets(EffectiveWorkExperience.WorkExperienceSummary)}") do
|
|
55
|
+
- datatable = EffectiveWorkExperienceSummariesDatatable.new(self, user: current_user)
|
|
56
|
+
= render_datatable(datatable)
|
|
57
|
+
|
|
58
|
+
- # In progress
|
|
59
|
+
- work_experience_summary = current_user.work_experience_summaries.in_progress.first
|
|
60
|
+
|
|
61
|
+
- if work_experience_summary.present? && work_experience_summary.draft?
|
|
62
|
+
%p
|
|
63
|
+
Your submission is incomplete.
|
|
64
|
+
|
|
65
|
+
%p
|
|
66
|
+
Please
|
|
67
|
+
= link_to("Continue summary", effective_work_experience.work_experience_summary_build_path(work_experience_summary, work_experience_summary.next_step), 'data-turbolinks' => false, class: 'btn btn-primary')
|
|
68
|
+
or you can
|
|
69
|
+
= link_to('Abandon summary', effective_work_experience.work_experience_summary_path(work_experience_summary), 'data-confirm': "Really delete #{work_experience_summary}?", 'data-method': :delete, class: 'btn btn-danger')
|
|
70
|
+
to start again.
|
|
71
|
+
|
|
72
|
+
- elsif EffectiveResources.authorized?(self, :new, EffectiveWorkExperience.WorkExperienceSummary)
|
|
73
|
+
%p= link_to "Add a new #{etd(EffectiveWorkExperience.WorkExperienceSummary)}", effective_work_experience.new_work_experience_summary_path, class: 'btn btn-primary'
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
%h2 Work Experience
|
|
2
|
+
|
|
3
|
+
%p Every #{EffectiveWorkExperience.summary_months} months, interns are required to submit a summary report of their work experience for your review.
|
|
4
|
+
|
|
5
|
+
%hr
|
|
6
|
+
|
|
7
|
+
%h4 Mentees
|
|
8
|
+
|
|
9
|
+
- if current_user.work_experience_mentees.present?
|
|
10
|
+
%p You are a mentor for the following interns: #{current_user.work_experience_mentees.map(&:to_s).sort.to_sentence}.
|
|
11
|
+
- else
|
|
12
|
+
%p You are not a mentor for any interns.
|
|
13
|
+
|
|
14
|
+
%hr
|
|
15
|
+
|
|
16
|
+
%h4 #{EffectiveWorkExperience.summary_months}-Month Summary Submissions
|
|
17
|
+
%p Please review the following #{etsd(EffectiveWorkExperience.WorkExperienceSummary)}:
|
|
18
|
+
|
|
19
|
+
- datatable = EffectiveWorkExperienceSummariesReviewDatatable.new(self, mentor: current_user)
|
|
20
|
+
= render_datatable(datatable)
|
|
21
|
+
|
|
22
|
+
%hr
|
|
23
|
+
|
|
24
|
+
%h4 Summary Reports
|
|
25
|
+
%p View your intern's entire work experience hours.
|
|
26
|
+
|
|
27
|
+
- datatable = EffectiveWorkExperienceReportsReviewDatatable.new(self, mentor: current_user)
|
|
28
|
+
= render_simple_datatable(datatable)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
subject: 'Your work experience from {{ period }} has been reviewed'
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Hello {{ user.name }},
|
|
6
|
+
|
|
7
|
+
The {{ period }} Work Experience Summary was reviewed by {{ mentor.name }}.
|
|
8
|
+
|
|
9
|
+
{{ url }}
|
|
10
|
+
|
|
11
|
+
Thank you
|
|
12
|
+
|
|
13
|
+
Please contact us for assistance.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
subject: 'Work experience from {{ user.name }} is ready for review'
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Hello {{ mentor.name }},
|
|
6
|
+
|
|
7
|
+
The {{ period }} Work Experience Summary from {{ user.name }} is ready for your review:
|
|
8
|
+
|
|
9
|
+
Please start your review at this url:
|
|
10
|
+
|
|
11
|
+
{{ url }}
|
|
12
|
+
|
|
13
|
+
Thank you
|
|
14
|
+
|
|
15
|
+
Please contact us for assistance.
|