effective_organizations 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 +106 -0
- data/Rakefile +18 -0
- data/app/assets/config/effective_organizations_manifest.js +3 -0
- data/app/assets/javascripts/effective_organizations/base.js +0 -0
- data/app/assets/javascripts/effective_organizations.js +1 -0
- data/app/assets/stylesheets/effective_organizations/base.scss +0 -0
- data/app/assets/stylesheets/effective_organizations.scss +1 -0
- data/app/controllers/admin/organizations_controller.rb +19 -0
- data/app/controllers/admin/representatives_controller.rb +19 -0
- data/app/controllers/effective/organizations_controller.rb +16 -0
- data/app/controllers/effective/representatives_controller.rb +19 -0
- data/app/datatables/admin/effective_organizations_datatable.rb +31 -0
- data/app/datatables/admin/effective_representatives_datatable.rb +28 -0
- data/app/datatables/effective_organizations_datatable.rb +18 -0
- data/app/datatables/effective_representatives_datatable.rb +25 -0
- data/app/helpers/effective_organizations_helper.rb +3 -0
- data/app/models/concerns/effective_organizations_organization.rb +56 -0
- data/app/models/concerns/effective_organizations_user.rb +31 -0
- data/app/models/effective/organization.rb +7 -0
- data/app/models/effective/representative.rb +44 -0
- data/app/views/admin/organizations/_form.html.haml +8 -0
- data/app/views/admin/organizations/_form_organization.html.haml +14 -0
- data/app/views/admin/representatives/_form.html.haml +37 -0
- data/app/views/admin/representatives/_user_fields.html.haml +7 -0
- data/app/views/effective/organizations/_dashboard.html.haml +10 -0
- data/app/views/effective/organizations/_form.html.haml +8 -0
- data/app/views/effective/organizations/_form_organization.html.haml +16 -0
- data/app/views/effective/representatives/_form.html.haml +32 -0
- data/app/views/effective/representatives/_user_fields.html.haml +7 -0
- data/config/effective_organizations.rb +12 -0
- data/config/routes.rb +19 -0
- data/db/migrate/01_create_effective_organizations.rb.erb +36 -0
- data/db/seeds.rb +1 -0
- data/lib/effective_organizations/engine.rb +19 -0
- data/lib/effective_organizations/version.rb +3 -0
- data/lib/effective_organizations.rb +21 -0
- data/lib/generators/effective_organizations/install_generator.rb +31 -0
- data/lib/generators/templates/effective_organizations_mailer_preview.rb +4 -0
- data/lib/tasks/effective_organizations_tasks.rake +8 -0
- metadata +223 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bcbee46f5235da4b9d6fa04d84daab02383cfe373532138dc6ec601fc3110ced
|
4
|
+
data.tar.gz: a400d6e2ecec13c3a98b6e58beda724471628e9262100dbeb5f9b414940fd417
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c7a6df31f4b94032905653c0ba44489ba4ac87b47f7e48e488726e4e9c9d8a26b41a02211f94f277ce91c871765ef0bce77a33ebf4aa0dbaef9a5f71ddf83520
|
7
|
+
data.tar.gz: 84dfedd0a963e6080faac3e7e8553e7739d9179d9e13d4aabb251516848fae840668d02c627884d6acb78d12588d5a221a3d287ee0d63d9b75f7f4b0389dce30
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2021 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,106 @@
|
|
1
|
+
# Effective Organizations
|
2
|
+
|
3
|
+
Users have many organizations through representatives.
|
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_organizations'
|
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_organizations: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_organizations_user
|
46
|
+
|
47
|
+
Use the following datatables to display to your user their applicants dues:
|
48
|
+
|
49
|
+
```haml
|
50
|
+
%h2 My Organizations
|
51
|
+
- datatable = EffectiveOrganizationsDatatable.new(self)
|
52
|
+
```
|
53
|
+
|
54
|
+
and
|
55
|
+
|
56
|
+
```
|
57
|
+
Add a link to the admin menu:
|
58
|
+
|
59
|
+
```haml
|
60
|
+
- if can? :admin, :effective_organizations
|
61
|
+
- if can? :index, Effective::Organization
|
62
|
+
= nav_link_to 'Organizations', effective_organizations.admin_organizations_path
|
63
|
+
|
64
|
+
- if can? :index, Effective::Representative
|
65
|
+
= nav_link_to 'Representatives', effective_organizations.admin_representatives_path
|
66
|
+
```
|
67
|
+
|
68
|
+
## Configuration
|
69
|
+
|
70
|
+
## Authorization
|
71
|
+
|
72
|
+
All authorization checks are handled via the effective_resources gem found in the `config/initializers/effective_resources.rb` file.
|
73
|
+
|
74
|
+
## Permissions
|
75
|
+
|
76
|
+
The permissions you actually want to define are as follows (using CanCan):
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
|
80
|
+
if user.admin?
|
81
|
+
can :admin, :effective_organizations
|
82
|
+
can :manage, Effective::Organization
|
83
|
+
can :manage, Effective::Representative
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
## License
|
88
|
+
|
89
|
+
MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
|
90
|
+
|
91
|
+
## Testing
|
92
|
+
|
93
|
+
Run tests by:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
rails test
|
97
|
+
```
|
98
|
+
|
99
|
+
## Contributing
|
100
|
+
|
101
|
+
1. Fork it
|
102
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
103
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
104
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
105
|
+
5. Bonus points for test coverage
|
106
|
+
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_organizations
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
@import 'effective_organizations/base';
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Admin
|
2
|
+
class OrganizationsController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_organizations) }
|
5
|
+
|
6
|
+
include Effective::CrudController
|
7
|
+
|
8
|
+
resource_scope -> { EffectiveOrganizations.Organization.deep.all }
|
9
|
+
datatable -> { Admin::EffectiveOrganizationsDatatable.new }
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def permitted_params
|
14
|
+
model = (params.key?(:effective_organization) ? :effective_organization : :organization)
|
15
|
+
params.require(model).permit!
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Admin
|
2
|
+
class RepresentativesController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_organizations) }
|
5
|
+
|
6
|
+
include Effective::CrudController
|
7
|
+
|
8
|
+
resource_scope -> { Effective::Representative.deep.all }
|
9
|
+
datatable -> { Admin::EffectiveRepresentativesDatatable.new }
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def permitted_params
|
14
|
+
model = (params.key?(:effective_representative) ? :effective_representative : :representative)
|
15
|
+
params.require(model).permit!
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Effective
|
2
|
+
class OrganizationsController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
|
5
|
+
include Effective::CrudController
|
6
|
+
|
7
|
+
resource_scope -> { EffectiveOrganizations.Organization.deep.where(id: current_user.organizations) }
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def permitted_params
|
12
|
+
params.require(:organization).permit!
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Effective
|
2
|
+
class RepresentativesController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
|
5
|
+
include Effective::CrudController
|
6
|
+
|
7
|
+
resource_scope -> {
|
8
|
+
organizations = EffectiveOrganizations.Organization.deep.where(id: current_user.organizations)
|
9
|
+
Effective::Representative.deep.where(organization: organizations)
|
10
|
+
}
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def permitted_params
|
15
|
+
params.require(:effective_representative).permit!
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Admin
|
2
|
+
class EffectiveOrganizationsDatatable < 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
|
+
if categories.present?
|
11
|
+
col :category, search: categories
|
12
|
+
end
|
13
|
+
|
14
|
+
col :title
|
15
|
+
|
16
|
+
col :representatives_count
|
17
|
+
col :representatives
|
18
|
+
|
19
|
+
actions_col
|
20
|
+
end
|
21
|
+
|
22
|
+
collection do
|
23
|
+
EffectiveOrganizations.Organization.deep.all
|
24
|
+
end
|
25
|
+
|
26
|
+
def categories
|
27
|
+
EffectiveOrganizations.Organization.categories
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Admin
|
2
|
+
class EffectiveRepresentativesDatatable < Effective::Datatable
|
3
|
+
datatable do
|
4
|
+
col :id, visible: false
|
5
|
+
col :user_id, visible: false
|
6
|
+
|
7
|
+
col :organization
|
8
|
+
col :user
|
9
|
+
|
10
|
+
col :email do |representative|
|
11
|
+
mail_to(representative.user.email)
|
12
|
+
end
|
13
|
+
|
14
|
+
col :roles, search: roles_collection
|
15
|
+
|
16
|
+
actions_col
|
17
|
+
end
|
18
|
+
|
19
|
+
collection do
|
20
|
+
Effective::Representative.deep.all
|
21
|
+
end
|
22
|
+
|
23
|
+
def roles_collection
|
24
|
+
EffectiveRoles.roles_collection(Effective::Representative.new).map(&:second)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Dashboard Organizations
|
2
|
+
class EffectiveOrganizationsDatatable < Effective::Datatable
|
3
|
+
datatable do
|
4
|
+
order :title
|
5
|
+
|
6
|
+
col :id, visible: false
|
7
|
+
|
8
|
+
col :title
|
9
|
+
col :representatives
|
10
|
+
|
11
|
+
actions_col
|
12
|
+
end
|
13
|
+
|
14
|
+
collection do
|
15
|
+
EffectiveOrganizations.Organization.deep.where(id: current_user.organizations)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class EffectiveRepresentativesDatatable < Effective::Datatable
|
2
|
+
datatable do
|
3
|
+
col :id, visible: false
|
4
|
+
|
5
|
+
col :organization
|
6
|
+
col :user
|
7
|
+
|
8
|
+
col :email do |representative|
|
9
|
+
mail_to(representative.user.email)
|
10
|
+
end
|
11
|
+
|
12
|
+
col :roles, search: roles_collection
|
13
|
+
|
14
|
+
actions_col
|
15
|
+
end
|
16
|
+
|
17
|
+
collection do
|
18
|
+
Effective::Representative.deep.all.where(organization: current_user.organizations)
|
19
|
+
end
|
20
|
+
|
21
|
+
def roles_collection
|
22
|
+
EffectiveRoles.roles_collection(Effective::Representative.new).map(&:second)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# EffectiveOrganizationsOrganization
|
2
|
+
#
|
3
|
+
# Mark your category model with effective_organizations_organization to get all the includes
|
4
|
+
|
5
|
+
module EffectiveOrganizationsOrganization
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module Base
|
9
|
+
def effective_organizations_organization
|
10
|
+
include ::EffectiveOrganizationsOrganization
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def effective_organizations_organization?; true; end
|
16
|
+
|
17
|
+
def categories
|
18
|
+
[]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
included do
|
23
|
+
log_changes(except: :representatives) if respond_to?(:log_changes)
|
24
|
+
|
25
|
+
# rich_text_body
|
26
|
+
# has_many_rich_texts
|
27
|
+
|
28
|
+
has_many :representatives, -> { Effective::Representative.sorted },
|
29
|
+
class_name: 'Effective::Representative', inverse_of: :organization, dependent: :delete_all
|
30
|
+
|
31
|
+
has_many :users, through: :representatives
|
32
|
+
|
33
|
+
effective_resource do
|
34
|
+
title :string
|
35
|
+
category :string
|
36
|
+
|
37
|
+
notes :text
|
38
|
+
|
39
|
+
representatives_count :integer # Counter cache
|
40
|
+
|
41
|
+
timestamps
|
42
|
+
end
|
43
|
+
|
44
|
+
scope :deep, -> { includes(:representatives) }
|
45
|
+
scope :sorted, -> { order(:title) }
|
46
|
+
|
47
|
+
validates :title, presence: true, uniqueness: true
|
48
|
+
end
|
49
|
+
|
50
|
+
# Instance Methods
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
title.presence || 'New Organization'
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# EffectiveOrganizationsUser
|
2
|
+
#
|
3
|
+
# Mark your user model with effective_organizations_user to get all the includes
|
4
|
+
|
5
|
+
module EffectiveOrganizationsUser
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module Base
|
9
|
+
def effective_organizations_user
|
10
|
+
include ::EffectiveOrganizationsUser
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def effective_organizations_user?; true; end
|
16
|
+
end
|
17
|
+
|
18
|
+
included do
|
19
|
+
# My teams
|
20
|
+
has_many :representatives, -> { Effective::Representative.sorted },
|
21
|
+
class_name: 'Effective::Representative', inverse_of: :user, dependent: :delete_all
|
22
|
+
|
23
|
+
# App scoped
|
24
|
+
has_many :organizations, through: :representatives
|
25
|
+
end
|
26
|
+
|
27
|
+
def representative(organization:)
|
28
|
+
representatives.find { |rep| rep.organization_id == organization.id }
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Effective
|
4
|
+
class Representative < ActiveRecord::Base
|
5
|
+
attr_accessor :new_representative_user_action
|
6
|
+
acts_as_role_restricted
|
7
|
+
|
8
|
+
log_changes(to: :organization) if respond_to?(:log_changes)
|
9
|
+
|
10
|
+
belongs_to :organization, counter_cache: true
|
11
|
+
belongs_to :user, polymorphic: true
|
12
|
+
|
13
|
+
accepts_nested_attributes_for :user
|
14
|
+
|
15
|
+
effective_resource do
|
16
|
+
roles_mask :integer
|
17
|
+
|
18
|
+
timestamps
|
19
|
+
end
|
20
|
+
|
21
|
+
scope :sorted, -> { order(:id) }
|
22
|
+
scope :deep, -> { includes(:user, :organization) }
|
23
|
+
|
24
|
+
before_validation(if: -> { user && user.new_record? }) do
|
25
|
+
user.password ||= SecureRandom.base64(12) + '!@#123abcABC-'
|
26
|
+
end
|
27
|
+
|
28
|
+
validates :organization, presence: true
|
29
|
+
validates :user, presence: true
|
30
|
+
|
31
|
+
validates :user_id, if: -> { user_id && user_type && organization_id },
|
32
|
+
uniqueness: { scope: [:organization_id], message: 'already belongs to this organization' }
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
user.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def build_user(attributes = {})
|
39
|
+
raise('please assign user_type first') if user_type.blank?
|
40
|
+
self.user = user_type.constantize.new(attributes)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
= tabs do
|
2
|
+
= tab 'Organization' do
|
3
|
+
= render 'admin/organizations/form_organization', organization: organization
|
4
|
+
|
5
|
+
- if organization.persisted?
|
6
|
+
- if organization.respond_to?(:log_changes_datatable)
|
7
|
+
= tab 'Logs' do
|
8
|
+
= render_inline_datatable(organization.log_changes_datatable)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
= effective_form_with(model: [:admin, organization], engine: true) do |f|
|
2
|
+
- categories = EffectiveOrganizations.Organization.categories
|
3
|
+
|
4
|
+
- if categories.present?
|
5
|
+
= f.select :category, categories, required: true
|
6
|
+
|
7
|
+
= f.text_field :title
|
8
|
+
|
9
|
+
= effective_submit(f)
|
10
|
+
|
11
|
+
- if organization.persisted?
|
12
|
+
%h2 Representatives
|
13
|
+
- datatable = Admin::EffectiveRepresentativesDatatable.new(organization_id: organization.id)
|
14
|
+
= render_inline_datatable(datatable)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
= effective_form_with(model: [:admin, representative], engine: true) do |f|
|
2
|
+
- f.object.user_type ||= current_user.class.name
|
3
|
+
|
4
|
+
= f.hidden_field :user_id
|
5
|
+
= f.hidden_field :user_type
|
6
|
+
= f.hidden_field :organization_id
|
7
|
+
|
8
|
+
- if f.object.new_record?
|
9
|
+
- unless inline_datatable? && inline_datatable.attributes[:organization_id].present?
|
10
|
+
= f.select :organization_id, EffectiveOrganizations.Organization.sorted
|
11
|
+
|
12
|
+
= f.checks :roles, EffectiveRoles.roles_collection(f.object)
|
13
|
+
|
14
|
+
- unless inline_datatable? && inline_datatable.attributes[:user_id].present?
|
15
|
+
= f.radios :new_representative_user_action, ['Invite new user', 'Add existing user'], inline: true, label: 'Representative'
|
16
|
+
|
17
|
+
= f.show_if :new_representative_user_action, 'Add existing user' do
|
18
|
+
= f.select :user, {'Users' => current_user.class.sorted }, polymorphic: true
|
19
|
+
|
20
|
+
= f.show_if :new_representative_user_action, 'Invite new user' do
|
21
|
+
= f.fields_for :user, (f.object.user || f.object.build_user) do |fu|
|
22
|
+
= render 'admin/representatives/user_fields', f: fu
|
23
|
+
|
24
|
+
- if f.object.persisted?
|
25
|
+
- unless inline_datatable? && inline_datatable.attributes[:organization_id].present?
|
26
|
+
= f.static_field :organization
|
27
|
+
|
28
|
+
- unless inline_datatable? && inline_datatable.attributes[:user_id].present?
|
29
|
+
= f.static_field :user
|
30
|
+
|
31
|
+
= f.checks :roles, EffectiveRoles.roles_collection(f.object)
|
32
|
+
|
33
|
+
- unless inline_datatable? && inline_datatable.attributes[:user_id].present?
|
34
|
+
= f.fields_for :user, f.object.user do |fu|
|
35
|
+
= render 'admin/representatives/user_fields', f: fu
|
36
|
+
|
37
|
+
= f.submit
|
@@ -0,0 +1,10 @@
|
|
1
|
+
%h2 Organizations
|
2
|
+
|
3
|
+
- if current_user.organizations.present?
|
4
|
+
%p You belong to #{pluralize(current_user.organizations.length, 'organization')}
|
5
|
+
|
6
|
+
- datatable = EffectiveResources.best('EffectiveOrganizationsDatatable').new(self, namespace: :effective)
|
7
|
+
= render_datatable(datatable)
|
8
|
+
|
9
|
+
- else
|
10
|
+
%p You do not belong to any organizations.
|
@@ -0,0 +1,8 @@
|
|
1
|
+
= tabs do
|
2
|
+
= tab 'Organization' do
|
3
|
+
= render 'effective/organizations/form_organization', organization: organization
|
4
|
+
|
5
|
+
- if organization.persisted?
|
6
|
+
- if organization.respond_to?(:log_changes_datatable)
|
7
|
+
= tab 'Logs' do
|
8
|
+
= render_inline_datatable(organization.log_changes_datatable)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
- url = (organization.persisted? ? effective_organizations.organization_path(organization) : effective_organizations.organizations_path)
|
2
|
+
|
3
|
+
= effective_form_with(model: organization, url: url) do |f|
|
4
|
+
- categories = EffectiveOrganizations.Organization.categories
|
5
|
+
|
6
|
+
- if categories.present?
|
7
|
+
= f.select :category, categories, required: true
|
8
|
+
|
9
|
+
= f.text_field :title
|
10
|
+
|
11
|
+
= f.submit
|
12
|
+
|
13
|
+
- if organization.persisted?
|
14
|
+
%h2 Representatives
|
15
|
+
- datatable = EffectiveRepresentativesDatatable.new(organization_id: organization.id)
|
16
|
+
= render_inline_datatable(datatable)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
= effective_form_with(model: representative, engine: true) do |f|
|
2
|
+
- f.object.user_type ||= current_user.class.name
|
3
|
+
|
4
|
+
= f.hidden_field :user_id
|
5
|
+
= f.hidden_field :user_type
|
6
|
+
= f.hidden_field :organization_id
|
7
|
+
|
8
|
+
- if f.object.new_record?
|
9
|
+
- unless inline_datatable? && inline_datatable.attributes[:organization_id].present?
|
10
|
+
= f.select :organization_id, EffectiveOrganizations.Organization.sorted
|
11
|
+
|
12
|
+
= f.checks :roles, EffectiveRoles.roles_collection(f.object)
|
13
|
+
|
14
|
+
- unless inline_datatable? && inline_datatable.attributes[:user_id].present?
|
15
|
+
= f.hidden_field :new_representative_user_action, value: 'Invite new user'
|
16
|
+
|
17
|
+
= f.fields_for :user, (f.object.user || f.object.build_user) do |fu|
|
18
|
+
= render 'effective/representatives/user_fields', f: fu
|
19
|
+
|
20
|
+
- if f.object.persisted?
|
21
|
+
- unless inline_datatable? && inline_datatable.attributes[:organization_id].present?
|
22
|
+
= f.static_field :organization
|
23
|
+
|
24
|
+
- unless inline_datatable? && inline_datatable.attributes[:user_id].present?
|
25
|
+
= f.static_field :user
|
26
|
+
|
27
|
+
= f.checks :roles, EffectiveRoles.roles_collection(f.object)
|
28
|
+
|
29
|
+
= f.fields_for :user, f.object.user do |fu|
|
30
|
+
= render 'effective/representatives/user_fields', f: fu
|
31
|
+
|
32
|
+
= f.submit
|
@@ -0,0 +1,12 @@
|
|
1
|
+
EffectiveOrganizations.setup do |config|
|
2
|
+
config.organizations_table_name = :organizations
|
3
|
+
config.representatives_table_name = :representatives
|
4
|
+
|
5
|
+
# Layout Settings
|
6
|
+
# Configure the Layout per controller, or all at once
|
7
|
+
# config.layout = { application: 'application', admin: 'admin' }
|
8
|
+
|
9
|
+
# Membership Categories Settings
|
10
|
+
# Configure the class responsible for the organization.
|
11
|
+
# config.organization_class_name = 'Effective::Organization'
|
12
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Rails.application.routes.draw do
|
4
|
+
mount EffectiveOrganizations::Engine => '/', as: 'effective_organizations'
|
5
|
+
end
|
6
|
+
|
7
|
+
EffectiveOrganizations::Engine.routes.draw do
|
8
|
+
# Public routes
|
9
|
+
scope module: 'effective' do
|
10
|
+
resources :organizations, except: [:show, :destroy]
|
11
|
+
resources :representatives, except: [:show]
|
12
|
+
end
|
13
|
+
|
14
|
+
namespace :admin do
|
15
|
+
resources :organizations, except: [:show]
|
16
|
+
resources :representatives, except: [:show]
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class CreateEffectiveOrganizations < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
# Organizations
|
4
|
+
create_table :organizations do |t|
|
5
|
+
t.string :title
|
6
|
+
|
7
|
+
t.string :category
|
8
|
+
t.text :notes
|
9
|
+
|
10
|
+
t.integer :representatives_count, default: 0
|
11
|
+
|
12
|
+
t.datetime :updated_at
|
13
|
+
t.datetime :created_at
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :organizations, :title
|
17
|
+
|
18
|
+
# Representatives
|
19
|
+
create_table :representatives do |t|
|
20
|
+
t.integer :organization_id
|
21
|
+
t.string :organization_type
|
22
|
+
|
23
|
+
t.integer :user_id
|
24
|
+
t.string :user_type
|
25
|
+
|
26
|
+
t.integer :roles_mask
|
27
|
+
|
28
|
+
t.datetime :updated_at
|
29
|
+
t.datetime :created_at
|
30
|
+
end
|
31
|
+
|
32
|
+
add_index :representatives, [:organization_id, :organization_type]
|
33
|
+
add_index :representatives, [:user_id, :user_type]
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
data/db/seeds.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
puts "Running effective_organizations seeds"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module EffectiveOrganizations
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
engine_name 'effective_organizations'
|
4
|
+
|
5
|
+
# Set up our default configuration options.
|
6
|
+
initializer 'effective_organizations.defaults', before: :load_config_initializers do |app|
|
7
|
+
eval File.read("#{config.root}/config/effective_organizations.rb")
|
8
|
+
end
|
9
|
+
|
10
|
+
# Include acts_as_addressable concern and allow any ActiveRecord object to call it
|
11
|
+
initializer 'effective_organizations.active_record' do |app|
|
12
|
+
ActiveSupport.on_load :active_record do
|
13
|
+
ActiveRecord::Base.extend(EffectiveOrganizationsUser::Base)
|
14
|
+
ActiveRecord::Base.extend(EffectiveOrganizationsOrganization::Base)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'effective_resources'
|
2
|
+
require 'effective_datatables'
|
3
|
+
require 'effective_organizations/engine'
|
4
|
+
require 'effective_organizations/version'
|
5
|
+
|
6
|
+
module EffectiveOrganizations
|
7
|
+
|
8
|
+
def self.config_keys
|
9
|
+
[
|
10
|
+
:organizations_table_name, :representatives_table_name, :layout,
|
11
|
+
:organization_class_name
|
12
|
+
]
|
13
|
+
end
|
14
|
+
|
15
|
+
include EffectiveGem
|
16
|
+
|
17
|
+
def self.Organization
|
18
|
+
organization_class_name&.constantize || Effective::Organization
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module EffectiveMemberships
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
|
6
|
+
desc 'Creates an EffectiveOrganizations initializer in your application.'
|
7
|
+
|
8
|
+
source_root File.expand_path('../../templates', __FILE__)
|
9
|
+
|
10
|
+
def self.next_migration_number(dirname)
|
11
|
+
if not ActiveRecord::Base.timestamped_migrations
|
12
|
+
Time.new.utc.strftime("%Y%m%d%H%M%S")
|
13
|
+
else
|
14
|
+
'%.3d' % (current_migration_number(dirname) + 1)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def copy_initializer
|
19
|
+
template ('../' * 3) + 'config/effective_organizations.rb', 'config/initializers/effective_organizations.rb'
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_migration_file
|
23
|
+
@organizations_table_name = ':' + EffectiveOrganizations.organizations_table_name.to_s
|
24
|
+
@representatives_table_name = ':' + EffectiveOrganizations.organizations_table_name.to_s
|
25
|
+
|
26
|
+
migration_template ('../' * 3) + 'db/migrate/01_create_effective_organizations.rb.erb', 'db/migrate/create_effective_organizations.rb'
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: effective_organizations
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Code and Effect
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-12-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 6.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: effective_bootstrap
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: effective_datatables
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 4.0.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.0.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: effective_resources
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sqlite3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: devise
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: haml-rails
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry-byebug
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: effective_test_bot
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: effective_developer
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description: Users have many organizations through representatives.
|
154
|
+
email:
|
155
|
+
- info@codeandeffect.com
|
156
|
+
executables: []
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- MIT-LICENSE
|
161
|
+
- README.md
|
162
|
+
- Rakefile
|
163
|
+
- app/assets/config/effective_organizations_manifest.js
|
164
|
+
- app/assets/javascripts/effective_organizations.js
|
165
|
+
- app/assets/javascripts/effective_organizations/base.js
|
166
|
+
- app/assets/stylesheets/effective_organizations.scss
|
167
|
+
- app/assets/stylesheets/effective_organizations/base.scss
|
168
|
+
- app/controllers/admin/organizations_controller.rb
|
169
|
+
- app/controllers/admin/representatives_controller.rb
|
170
|
+
- app/controllers/effective/organizations_controller.rb
|
171
|
+
- app/controllers/effective/representatives_controller.rb
|
172
|
+
- app/datatables/admin/effective_organizations_datatable.rb
|
173
|
+
- app/datatables/admin/effective_representatives_datatable.rb
|
174
|
+
- app/datatables/effective_organizations_datatable.rb
|
175
|
+
- app/datatables/effective_representatives_datatable.rb
|
176
|
+
- app/helpers/effective_organizations_helper.rb
|
177
|
+
- app/models/concerns/effective_organizations_organization.rb
|
178
|
+
- app/models/concerns/effective_organizations_user.rb
|
179
|
+
- app/models/effective/organization.rb
|
180
|
+
- app/models/effective/representative.rb
|
181
|
+
- app/views/admin/organizations/_form.html.haml
|
182
|
+
- app/views/admin/organizations/_form_organization.html.haml
|
183
|
+
- app/views/admin/representatives/_form.html.haml
|
184
|
+
- app/views/admin/representatives/_user_fields.html.haml
|
185
|
+
- app/views/effective/organizations/_dashboard.html.haml
|
186
|
+
- app/views/effective/organizations/_form.html.haml
|
187
|
+
- app/views/effective/organizations/_form_organization.html.haml
|
188
|
+
- app/views/effective/representatives/_form.html.haml
|
189
|
+
- app/views/effective/representatives/_user_fields.html.haml
|
190
|
+
- config/effective_organizations.rb
|
191
|
+
- config/routes.rb
|
192
|
+
- db/migrate/01_create_effective_organizations.rb.erb
|
193
|
+
- db/seeds.rb
|
194
|
+
- lib/effective_organizations.rb
|
195
|
+
- lib/effective_organizations/engine.rb
|
196
|
+
- lib/effective_organizations/version.rb
|
197
|
+
- lib/generators/effective_organizations/install_generator.rb
|
198
|
+
- lib/generators/templates/effective_organizations_mailer_preview.rb
|
199
|
+
- lib/tasks/effective_organizations_tasks.rake
|
200
|
+
homepage: https://github.com/code-and-effect/effective_organizations
|
201
|
+
licenses:
|
202
|
+
- MIT
|
203
|
+
metadata: {}
|
204
|
+
post_install_message:
|
205
|
+
rdoc_options: []
|
206
|
+
require_paths:
|
207
|
+
- lib
|
208
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
209
|
+
requirements:
|
210
|
+
- - ">="
|
211
|
+
- !ruby/object:Gem::Version
|
212
|
+
version: '0'
|
213
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
214
|
+
requirements:
|
215
|
+
- - ">="
|
216
|
+
- !ruby/object:Gem::Version
|
217
|
+
version: '0'
|
218
|
+
requirements: []
|
219
|
+
rubygems_version: 3.1.2
|
220
|
+
signing_key:
|
221
|
+
specification_version: 4
|
222
|
+
summary: Users have many organizations through representatives.
|
223
|
+
test_files: []
|