effective_committees 0.0.2
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 +186 -0
- data/Rakefile +18 -0
- data/app/assets/config/effective_committees_manifest.js +3 -0
- data/app/assets/javascripts/effective_committees/base.js +0 -0
- data/app/assets/javascripts/effective_committeesjs +1 -0
- data/app/assets/stylesheets/effective_committees/base.scss +0 -0
- data/app/assets/stylesheets/effective_committees.scss +1 -0
- data/app/controllers/admin/committee_files_controller.rb +16 -0
- data/app/controllers/admin/committee_folders_controller.rb +16 -0
- data/app/controllers/admin/committee_members_controller.rb +16 -0
- data/app/controllers/admin/committees_controller.rb +22 -0
- data/app/controllers/effective/committee_folders_controller.rb +7 -0
- data/app/controllers/effective/committee_members_controller.rb +19 -0
- data/app/controllers/effective/committees_controller.rb +17 -0
- data/app/datatables/admin/effective_committee_files_datatable.rb +24 -0
- data/app/datatables/admin/effective_committee_folders_datatable.rb +28 -0
- data/app/datatables/admin/effective_committee_members_datatable.rb +32 -0
- data/app/datatables/admin/effective_committees_datatable.rb +34 -0
- data/app/datatables/effective_committee_members_datatable.rb +42 -0
- data/app/datatables/effective_committees_datatable.rb +31 -0
- data/app/helpers/effective_committees_helper.rb +3 -0
- data/app/models/concerns/effective_committees_user.rb +40 -0
- data/app/models/effective/committee.rb +55 -0
- data/app/models/effective/committee_file.rb +40 -0
- data/app/models/effective/committee_folder.rb +42 -0
- data/app/models/effective/committee_member.rb +76 -0
- data/app/views/admin/committee_files/_form.html.haml +14 -0
- data/app/views/admin/committee_folders/_form.html.haml +21 -0
- data/app/views/admin/committee_members/_form.html.haml +31 -0
- data/app/views/admin/committee_members/_user_fields.html.haml +7 -0
- data/app/views/admin/committees/_fields.html.haml +7 -0
- data/app/views/admin/committees/_form.html.haml +20 -0
- data/app/views/admin/committees/_form_committee.html.haml +6 -0
- data/app/views/effective/committee_folders/_committee_folder.html.haml +24 -0
- data/app/views/effective/committee_members/_form.html.haml +35 -0
- data/app/views/effective/committee_members/_user_fields.html.haml +7 -0
- data/app/views/effective/committees/_committee.html.haml +23 -0
- data/app/views/effective/committees/_dashboard.html.haml +10 -0
- data/app/views/effective/committees/_fields.html.haml +2 -0
- data/app/views/effective/committees/_form.html.haml +8 -0
- data/app/views/effective/committees/_form_committee.html.haml +11 -0
- data/app/views/effective/committees/index.html.haml +21 -0
- data/config/effective_committees.rb +13 -0
- data/config/routes.rb +24 -0
- data/db/migrate/01_create_effective_committees.rb.erb +14 -0
- data/db/seeds.rb +1 -0
- data/lib/effective_committees/engine.rb +18 -0
- data/lib/effective_committees/version.rb +3 -0
- data/lib/effective_committees.rb +18 -0
- data/lib/generators/effective_committees/install_generator.rb +31 -0
- data/lib/generators/templates/effective_committees_mailer_preview.rb +4 -0
- data/lib/tasks/effective_committees_tasks.rake +8 -0
- metadata +250 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b793fe3d40958ea8fc7e853979a10ef40cdbdfc043893b93690ad62f8d5c7604
|
4
|
+
data.tar.gz: 414192d935ae2fc8f6b5b24617a97c219e72a069728c8e3a22241ef7449301bb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 784a0ccd91b3d7fdff1023a75f41506a771b17293ad73cb4c14de8d1184cd1c580a10c46d29072302c182ed906d13910f6837e191169306e052fbf77b30a5a74
|
7
|
+
data.tar.gz: 0b09e1874e3a24d4e29b71e12ecddf4920634d4c57fcdbf0a1c5d6e49210fb5e5b18c80d9d4507d0fbec1bd8852f19b18d4c13a0befe7530c0e6924c4d5d7495
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2022 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,186 @@
|
|
1
|
+
# Effective Committees
|
2
|
+
|
3
|
+
Committees are groups of users that can all share files.
|
4
|
+
|
5
|
+
## Getting Started
|
6
|
+
|
7
|
+
This requires Rails 6+ and Twitter Bootstrap 4 and just works with Devise.
|
8
|
+
|
9
|
+
Please first install the [effective_datatables](https://github.com/code-and-effect/effective_datatables) gem.
|
10
|
+
|
11
|
+
Please download and install the [Twitter Bootstrap4](http://getbootstrap.com)
|
12
|
+
|
13
|
+
Add to your Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'haml-rails' # or try using gem 'hamlit-rails'
|
17
|
+
gem 'effective_committees'
|
18
|
+
```
|
19
|
+
|
20
|
+
Run the bundle command to install it:
|
21
|
+
|
22
|
+
```console
|
23
|
+
bundle install
|
24
|
+
```
|
25
|
+
|
26
|
+
Then run the generator:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
rails generate effective_committees:install
|
30
|
+
```
|
31
|
+
|
32
|
+
The generator will install an initializer which describes all configuration options and creates a database migration.
|
33
|
+
|
34
|
+
If you want to tweak the table names, manually adjust both the configuration file and the migration now.
|
35
|
+
|
36
|
+
Then migrate the database:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
rake db:migrate
|
40
|
+
```
|
41
|
+
|
42
|
+
Please add the following to your User model:
|
43
|
+
|
44
|
+
```
|
45
|
+
effective_committees_user
|
46
|
+
|
47
|
+
Use the following datatables to display to your user their applicants dues:
|
48
|
+
|
49
|
+
```haml
|
50
|
+
%h2 My Committees
|
51
|
+
= render 'effective/committees/dashboard'
|
52
|
+
```
|
53
|
+
|
54
|
+
and
|
55
|
+
|
56
|
+
```
|
57
|
+
Add a link to the admin menu:
|
58
|
+
|
59
|
+
```haml
|
60
|
+
- if can? :admin, :effective_committees
|
61
|
+
= nav_dropdown 'Committees' do
|
62
|
+
- if can? :index, Effective::Committee
|
63
|
+
= nav_link_to 'Committees', effective_committees.admin_committees_path
|
64
|
+
|
65
|
+
- if can? :index, Effective::CommitteeMember
|
66
|
+
= nav_link_to 'Committee Members', effective_committees.admin_committee_members_path
|
67
|
+
|
68
|
+
- if can? :index, Effective::CommitteeFolder
|
69
|
+
= nav_link_to 'Committee Folders', effective_committees.admin_committee_folders_path
|
70
|
+
|
71
|
+
- if can? :index, Effective::CommitteeFile
|
72
|
+
= nav_link_to 'Committee Files', effective_committees.admin_committee_files_path
|
73
|
+
```
|
74
|
+
|
75
|
+
## Configuration
|
76
|
+
|
77
|
+
## Authorization
|
78
|
+
|
79
|
+
All authorization checks are handled via the effective_resources gem found in the `config/initializers/effective_resources.rb` file.
|
80
|
+
|
81
|
+
## Effective Roles
|
82
|
+
|
83
|
+
This gem works with effective roles for the representative roles.
|
84
|
+
|
85
|
+
Configure your `config/initializers/effective_roles.rb` something like this:
|
86
|
+
|
87
|
+
```
|
88
|
+
EffectiveRoles.setup do |config|
|
89
|
+
config.roles = [:admin, :reserved, :owner, :billing] # Only add to the end of this array. Never prepend roles.
|
90
|
+
|
91
|
+
# config.role_descriptions
|
92
|
+
# ========================
|
93
|
+
# This setting configures the text that is displayed by form helpers (see README.md)
|
94
|
+
|
95
|
+
config.role_descriptions = {
|
96
|
+
'User' => {
|
97
|
+
# User roles
|
98
|
+
admin: 'can log in to the /admin section of the website. full access to everything.',
|
99
|
+
},
|
100
|
+
'Effective::CommitteeMember' => {
|
101
|
+
owner: 'committee owner. full access to everything.',
|
102
|
+
billing: 'the billing contact. full access to everything.'
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
# config.assignable_roles
|
107
|
+
# Which roles can be assigned by whom
|
108
|
+
# =======================
|
109
|
+
# When current_user is passed into a form helper function (see README.md)
|
110
|
+
# this setting determines which roles that current_user may assign
|
111
|
+
config.assignable_roles = {
|
112
|
+
'User' => { admin: [:admin] },
|
113
|
+
|
114
|
+
'Effective::CommitteeMember' => {
|
115
|
+
admin: [:owner, :billing],
|
116
|
+
owner: [:owner, :billing],
|
117
|
+
billing: [:billing]
|
118
|
+
}
|
119
|
+
}
|
120
|
+
end
|
121
|
+
```
|
122
|
+
|
123
|
+
## Permissions
|
124
|
+
|
125
|
+
The permissions you actually want to define are as follows (using CanCan):
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
if user.persisted?
|
129
|
+
can :index, Effective::Committee
|
130
|
+
can(:show, Effective::Committee) { |committee| user.committees.include?(committee) }
|
131
|
+
|
132
|
+
can([:edit, :update], Effective::Committee) do |committee|
|
133
|
+
user.committee_member(committee: committee)&.is?(:owner)
|
134
|
+
end
|
135
|
+
|
136
|
+
can :index, Effective::CommitteeMember
|
137
|
+
|
138
|
+
can(:show, Effective::CommitteeMember) { |member| user.committees.include?(member.committee) }
|
139
|
+
can(:new, Effective::CommitteeMember)
|
140
|
+
|
141
|
+
can([:create, :edit, :update], Effective::CommitteeMember) do |cm|
|
142
|
+
user.committee_member(committee: cm.committee)&.is?(:owner)
|
143
|
+
end
|
144
|
+
|
145
|
+
can(:destroy, Effective::CommitteeMember) do |member|
|
146
|
+
user.committee_member(committee: member.committee)&.is?(:owner) && !member.is?(:owner)
|
147
|
+
end
|
148
|
+
|
149
|
+
can(:show, Effective::CommitteeFolder) { |folder| user.committees.include?(folder.committee) }
|
150
|
+
can(:show, Effective::CommitteeFile) { |file| user.committees.include?(file.committee) }
|
151
|
+
end
|
152
|
+
|
153
|
+
if user.admin?
|
154
|
+
can :admin, :effective_committees
|
155
|
+
|
156
|
+
can(crud - [:destroy], Effective::Committee)
|
157
|
+
can(:destroy, Effective::Committee) { |committee| committee.committee_members_count == 0 }
|
158
|
+
|
159
|
+
can(crud - [:destroy], Effective::CommitteeFolder)
|
160
|
+
can(:destroy, Effective::CommitteeFolder) { |folder| folder.committee_files_count == 0 }
|
161
|
+
|
162
|
+
can(crud, Effective::CommitteeMember)
|
163
|
+
can(crud, Effective::CommitteeFile)
|
164
|
+
end
|
165
|
+
```
|
166
|
+
|
167
|
+
## License
|
168
|
+
|
169
|
+
MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
|
170
|
+
|
171
|
+
## Testing
|
172
|
+
|
173
|
+
Run tests by:
|
174
|
+
|
175
|
+
```ruby
|
176
|
+
rails test
|
177
|
+
```
|
178
|
+
|
179
|
+
## Contributing
|
180
|
+
|
181
|
+
1. Fork it
|
182
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
183
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
184
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
185
|
+
5. Bonus points for test coverage
|
186
|
+
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
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require_tree ./effective_committees
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
@import 'effective_committees/base';
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Admin
|
2
|
+
class CommitteeFilesController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_committees) }
|
5
|
+
|
6
|
+
include Effective::CrudController
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def permitted_params
|
11
|
+
model = (params.key?(:effective_committee_file) ? :effective_committee_file : :committee_file)
|
12
|
+
params.require(model).permit!
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Admin
|
2
|
+
class CommitteeFoldersController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_committees) }
|
5
|
+
|
6
|
+
include Effective::CrudController
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def permitted_params
|
11
|
+
model = (params.key?(:effective_committee_folder) ? :effective_committee_folder : :committee_folder)
|
12
|
+
params.require(model).permit!
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Admin
|
2
|
+
class CommitteeMembersController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_committees) }
|
5
|
+
|
6
|
+
include Effective::CrudController
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def permitted_params
|
11
|
+
model = (params.key?(:effective_committee_member) ? :effective_committee_member : :committee_member)
|
12
|
+
params.require(model).permit!
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Admin
|
2
|
+
class CommitteesController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_committees) }
|
5
|
+
|
6
|
+
include Effective::CrudController
|
7
|
+
|
8
|
+
submit :save, 'Save'
|
9
|
+
submit :save, 'Save and Add New', redirect: :new
|
10
|
+
submit :save, 'Save and View', redirect: -> { effective_committees.committee_path(resource) }
|
11
|
+
|
12
|
+
resource_scope -> { Effective::Committee.deep.all }
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def permitted_params
|
17
|
+
model = (params.key?(:effective_committee) ? :effective_committee : :committee)
|
18
|
+
params.require(model).permit!
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Effective
|
2
|
+
class CommitteeMembersController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
|
5
|
+
include Effective::CrudController
|
6
|
+
|
7
|
+
resource_scope -> {
|
8
|
+
committees = Effective::Committee.deep.where(id: current_user.committees)
|
9
|
+
Effective::CommitteeMember.deep.where(committee: committees)
|
10
|
+
}
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def permitted_params
|
15
|
+
params.require(:effective_committee_member).permit!
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Effective
|
2
|
+
class CommitteesController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
|
5
|
+
include Effective::CrudController
|
6
|
+
|
7
|
+
resource_scope -> { Effective::Committee.all.deep }
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def permitted_params
|
12
|
+
model = (params.key?(:effective_committee) ? :effective_committee : :committee)
|
13
|
+
params.require(model).permit!
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Admin
|
2
|
+
class EffectiveCommitteeFilesDatatable < Effective::Datatable
|
3
|
+
datatable do
|
4
|
+
col :updated_at, visible: false
|
5
|
+
col :created_at, visible: false
|
6
|
+
|
7
|
+
col :id, visible: false
|
8
|
+
|
9
|
+
col :committee, search: :string
|
10
|
+
col :committee_folder, search: :string, label: 'Folder'
|
11
|
+
|
12
|
+
col :file
|
13
|
+
col :title
|
14
|
+
col :notes
|
15
|
+
|
16
|
+
actions_col
|
17
|
+
end
|
18
|
+
|
19
|
+
collection do
|
20
|
+
Effective::CommitteeFile.deep.all
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Admin
|
2
|
+
class EffectiveCommitteeFoldersDatatable < Effective::Datatable
|
3
|
+
datatable do
|
4
|
+
reorder :position
|
5
|
+
|
6
|
+
col :updated_at, visible: false
|
7
|
+
col :created_at, visible: false
|
8
|
+
|
9
|
+
col :id, visible: false
|
10
|
+
|
11
|
+
col :committee, search: :string
|
12
|
+
|
13
|
+
col :title, label: 'Folder'
|
14
|
+
col :slug, visible: false
|
15
|
+
col :body
|
16
|
+
|
17
|
+
col :committee_files, label: 'Files', search: :string
|
18
|
+
col :committee_files_count, label: 'Files Count', visible: false
|
19
|
+
|
20
|
+
actions_col
|
21
|
+
end
|
22
|
+
|
23
|
+
collection do
|
24
|
+
Effective::CommitteeFolder.deep.all
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Admin
|
2
|
+
class EffectiveCommitteeMembersDatatable < Effective::Datatable
|
3
|
+
datatable do
|
4
|
+
col :id, visible: false
|
5
|
+
col :user_id, visible: false
|
6
|
+
|
7
|
+
col :committee
|
8
|
+
col :user
|
9
|
+
|
10
|
+
unless attributes[:user_id]
|
11
|
+
col :email do |committee_member|
|
12
|
+
mail_to(committee_member.user.email)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
if EffectiveCommittees.use_effective_roles
|
17
|
+
col :roles, search: roles_collection
|
18
|
+
end
|
19
|
+
|
20
|
+
actions_col
|
21
|
+
end
|
22
|
+
|
23
|
+
collection do
|
24
|
+
Effective::CommitteeMember.deep.all
|
25
|
+
end
|
26
|
+
|
27
|
+
def roles_collection
|
28
|
+
EffectiveRoles.roles_collection(Effective::CommitteeMember.new).map(&:second)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Admin
|
2
|
+
class EffectiveCommitteesDatatable < Effective::Datatable
|
3
|
+
datatable do
|
4
|
+
|
5
|
+
col :updated_at, visible: false
|
6
|
+
col :created_at, visible: false
|
7
|
+
|
8
|
+
col :id, visible: false
|
9
|
+
|
10
|
+
col :title, label: 'Committee'
|
11
|
+
col :slug, visible: false
|
12
|
+
col :body
|
13
|
+
|
14
|
+
col :committee_members, label: 'Members', search: :string
|
15
|
+
col :committee_members_count, label: 'Members Count', visible: false
|
16
|
+
|
17
|
+
col :committee_folders, label: 'Folders', search: :string
|
18
|
+
col :committee_folders_count, label: 'Folders Count', visible: false
|
19
|
+
|
20
|
+
col :committee_files, label: 'Files', search: :string
|
21
|
+
col :committee_files_count, label: 'Files Count', visible: false
|
22
|
+
|
23
|
+
actions_col do |committee|
|
24
|
+
dropdown_link_to('View Committee', effective_committees.committee_path(committee), target: '_blank')
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
collection do
|
30
|
+
Effective::Committee.deep.all
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class EffectiveCommitteeMembersDatatable < Effective::Datatable
|
2
|
+
datatable do
|
3
|
+
col :id, visible: false
|
4
|
+
|
5
|
+
col :committee
|
6
|
+
col :user
|
7
|
+
|
8
|
+
unless attributes[:user_id]
|
9
|
+
col :email do |committee_member|
|
10
|
+
mail_to(committee_member.user.email)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
if EffectiveCommittees.use_effective_roles
|
15
|
+
col :roles, search: roles_collection
|
16
|
+
end
|
17
|
+
|
18
|
+
unless attributes[:actions] == false
|
19
|
+
actions_col
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
collection do
|
25
|
+
scope = Effective::CommitteeMember.deep.all.where(committee: current_user.committees)
|
26
|
+
|
27
|
+
if attributes[:committee_id]
|
28
|
+
scope = scope.where(committee_id: attributes[:committee_id])
|
29
|
+
end
|
30
|
+
|
31
|
+
if attributes[:user_id]
|
32
|
+
scope = scope.where(user_id: attributes[:user_id])
|
33
|
+
end
|
34
|
+
|
35
|
+
scope
|
36
|
+
end
|
37
|
+
|
38
|
+
def roles_collection
|
39
|
+
EffectiveRoles.roles_collection(Effective::CommitteeMember.new).map(&:second)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Dashboard Committees
|
2
|
+
class EffectiveCommitteesDatatable < Effective::Datatable
|
3
|
+
datatable do
|
4
|
+
order :title
|
5
|
+
|
6
|
+
col :id, visible: false
|
7
|
+
|
8
|
+
col :title, label: 'Committee'
|
9
|
+
|
10
|
+
col :committee_members, search: :string, label: 'Members'
|
11
|
+
|
12
|
+
col :committee_folders, search: :string, label: 'Folders'
|
13
|
+
|
14
|
+
col :committee_folders_count, label: 'Folders', visible: false do |committee|
|
15
|
+
pluralize(committee.committee_folders_count, 'folders')
|
16
|
+
end
|
17
|
+
|
18
|
+
col :committee_files, search: :string, label: 'Files', visible: false
|
19
|
+
|
20
|
+
col :committee_files_count, label: 'Files' do |committee|
|
21
|
+
pluralize(committee.committee_files_count, 'files')
|
22
|
+
end
|
23
|
+
|
24
|
+
actions_col
|
25
|
+
end
|
26
|
+
|
27
|
+
collection do
|
28
|
+
Effective::Committee.deep.where(id: current_user.committees)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# EffectiveCommitteesUser
|
2
|
+
#
|
3
|
+
# Mark your user model with effective_committees_user to get all the includes
|
4
|
+
|
5
|
+
module EffectiveCommitteesUser
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module Base
|
9
|
+
def effective_committees_user
|
10
|
+
include ::EffectiveCommitteesUser
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def effective_committees_user?; true; end
|
16
|
+
end
|
17
|
+
|
18
|
+
included do
|
19
|
+
has_many :committee_members, -> { Effective::CommitteeMember.sorted },
|
20
|
+
class_name: 'Effective::CommitteeMember', inverse_of: :user, dependent: :delete_all
|
21
|
+
|
22
|
+
accepts_nested_attributes_for :committee_members, allow_destroy: true
|
23
|
+
end
|
24
|
+
|
25
|
+
# Instance Methods
|
26
|
+
|
27
|
+
def committee_member(committee:)
|
28
|
+
committee_members.find { |rep| rep.committee_id == committee.id }
|
29
|
+
end
|
30
|
+
|
31
|
+
# Find or build
|
32
|
+
def build_committee_member(committee:)
|
33
|
+
committee_member(committee: committee) || committee_members.build(committee: committee)
|
34
|
+
end
|
35
|
+
|
36
|
+
def committees
|
37
|
+
committee_members.reject(&:marked_for_destruction?).map(&:committee)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Effective
|
4
|
+
class Committee < ActiveRecord::Base
|
5
|
+
self.table_name = EffectiveCommittees.committees_table_name.to_s
|
6
|
+
|
7
|
+
acts_as_slugged
|
8
|
+
|
9
|
+
log_changes if respond_to?(:log_changes)
|
10
|
+
has_rich_text :body
|
11
|
+
|
12
|
+
has_many :committee_members, -> { Effective::CommitteeMember.sorted }, class_name: 'Effective::CommitteeMember', inverse_of: :committee, dependent: :delete_all
|
13
|
+
accepts_nested_attributes_for :committee_members, allow_destroy: true
|
14
|
+
|
15
|
+
has_many :committee_folders, -> { Effective::CommitteeFolder.sorted }, class_name: 'Effective::CommitteeFolder', inverse_of: :committee, dependent: :delete_all
|
16
|
+
accepts_nested_attributes_for :committee_folders, allow_destroy: true
|
17
|
+
|
18
|
+
has_many :committee_files, -> { Effective::CommitteeFile.sorted }, class_name: 'Effective::CommitteeFile', inverse_of: :committee, dependent: :delete_all
|
19
|
+
accepts_nested_attributes_for :committee_files, allow_destroy: true
|
20
|
+
|
21
|
+
effective_resource do
|
22
|
+
title :string
|
23
|
+
slug :string
|
24
|
+
|
25
|
+
committee_members_count :integer # Counter Cache
|
26
|
+
committee_folders_count :integer # Counter Cache
|
27
|
+
committee_files_count :integer # Counter Cache
|
28
|
+
|
29
|
+
timestamps
|
30
|
+
end
|
31
|
+
|
32
|
+
scope :sorted, -> { order(:title) }
|
33
|
+
scope :deep, -> { includes(:committee_members) }
|
34
|
+
|
35
|
+
validates :title, presence: true, uniqueness: true, length: { maximum: 255 }
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
title.presence || 'New Committee'
|
39
|
+
end
|
40
|
+
|
41
|
+
def committee_member(user:)
|
42
|
+
committee_members.find { |member| member.user_id == user.id }
|
43
|
+
end
|
44
|
+
|
45
|
+
# Find or build
|
46
|
+
def build_committee_member(user:)
|
47
|
+
committee_member(user: user) || committee_members.build(user: user)
|
48
|
+
end
|
49
|
+
|
50
|
+
def users
|
51
|
+
committee_members.reject(&:marked_for_destruction?).map(&:user)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|