effective_memberships 0.9.7 → 0.9.8
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 +4 -4
- data/app/controllers/effective/membership_directory_controller.rb +9 -0
- data/app/datatables/admin/effective_organizations_datatable.rb +1 -1
- data/app/datatables/effective_memberships_directory_datatable.rb +12 -12
- data/app/models/concerns/effective_memberships_category.rb +3 -0
- data/app/models/concerns/effective_memberships_directory.rb +44 -18
- data/app/models/concerns/effective_memberships_organization.rb +4 -0
- data/app/models/effective/membership.rb +32 -9
- data/app/views/effective/membership_directory/_form.html.haml +8 -5
- data/app/views/effective/membership_directory/_membership.html.haml +20 -0
- data/app/views/effective/membership_directory/_membership_directory.html.haml +4 -4
- data/app/views/effective/membership_directory/show.html.haml +25 -0
- data/config/routes.rb +1 -1
- data/db/migrate/01_create_effective_memberships.rb.erb +3 -0
- data/lib/effective_memberships/version.rb +1 -1
- metadata +4 -3
- data/app/views/effective/membership_directory/_membership_owner.html.haml +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 612909b87d53748d9b3488893e419cf6f8bdcb852fdb07d3bd0f015bda89771c
|
4
|
+
data.tar.gz: 7c48d16e502036542d4f80e785986134e19466593b44ecce9cef151e76387acc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 835021e63b547f68e17ae9bd9ca6bbc523217e1f4f7c3eaf100696ef4456fb63b4f384765cad26db941aca67203ddb87e157ac64620e41220f98571a23d9074b
|
7
|
+
data.tar.gz: 706ec5a09d03a23f5495ccae6ec1f28fb930a4a1533a41b15f6f9a859f6e1bbb1d19dd9df0f83e0e6a56fb0bd6abe6d378576e5d1d439a2fa9ebaa3adfec2d69
|
@@ -16,6 +16,15 @@ module Effective
|
|
16
16
|
@memberships = @membership_directory.results(page: params[:page])
|
17
17
|
end
|
18
18
|
|
19
|
+
def show
|
20
|
+
@page_title = 'Directory'
|
21
|
+
|
22
|
+
@membership = Effective::Membership.find_by_token(params[:id])
|
23
|
+
|
24
|
+
EffectiveResources.authorize!(self, :show, @membership)
|
25
|
+
EffectiveResources.authorize!(self, :show, @membership.owner)
|
26
|
+
end
|
27
|
+
|
19
28
|
def build_membership_directory
|
20
29
|
directory = EffectiveMemberships.MembershipDirectory.new(search_params)
|
21
30
|
directory.current_user = current_user
|
@@ -63,7 +63,7 @@ module Admin
|
|
63
63
|
end
|
64
64
|
|
65
65
|
collection do
|
66
|
-
EffectiveMemberships.Organization.deep.left_joins(:membership).includes(:addresses, membership: :
|
66
|
+
EffectiveMemberships.Organization.deep.left_joins(:membership).includes(:addresses, membership: [membership_categories: :category], representatives: :user)
|
67
67
|
end
|
68
68
|
|
69
69
|
def categories
|
@@ -3,25 +3,25 @@ class EffectiveMembershipsDirectoryDatatable < Effective::Datatable
|
|
3
3
|
datatable do
|
4
4
|
length 100
|
5
5
|
|
6
|
-
col
|
7
|
-
|
6
|
+
col :owner_name, label: 'Name'
|
8
7
|
col :joined_on
|
9
8
|
col :number
|
10
|
-
col :categories, search: :string, label: 'Category'
|
11
|
-
end
|
12
|
-
|
13
|
-
collection do
|
14
|
-
scope = Effective::Membership.directory.all
|
15
9
|
|
16
|
-
|
17
|
-
|
10
|
+
col(:categories, search: categories, label: 'Category', sql_column: true).search do |collection, term|
|
11
|
+
collection.with_category(EffectiveMemberships.Category.find(term))
|
18
12
|
end
|
19
13
|
|
20
|
-
scope
|
21
14
|
end
|
22
15
|
|
23
|
-
|
24
|
-
|
16
|
+
collection do
|
17
|
+
Effective::Membership.deep.sorted
|
18
|
+
.in_good_standing
|
19
|
+
.without_archived_owners
|
20
|
+
.with_category(categories)
|
21
|
+
end
|
22
|
+
|
23
|
+
def categories
|
24
|
+
EffectiveMemberships.Category.membership_directory.all
|
25
25
|
end
|
26
26
|
|
27
27
|
end
|
@@ -114,6 +114,9 @@ module EffectiveMembershipsCategory
|
|
114
114
|
.or(where(can_apply_restricted: true))
|
115
115
|
}
|
116
116
|
|
117
|
+
# Can be used to limit which memberships are displayed in the directory
|
118
|
+
scope :membership_directory, -> { sorted }
|
119
|
+
|
117
120
|
validates :title, presence: true, uniqueness: true
|
118
121
|
validates :category_type, presence: true
|
119
122
|
validates :position, presence: true
|
@@ -19,18 +19,29 @@ module EffectiveMembershipsDirectory
|
|
19
19
|
attr_accessor :term
|
20
20
|
attr_accessor :category
|
21
21
|
|
22
|
+
# Users
|
22
23
|
attr_accessor :first_name
|
23
24
|
attr_accessor :last_name
|
24
25
|
|
26
|
+
# Organizations
|
27
|
+
attr_accessor :title
|
28
|
+
|
25
29
|
validates :term, length: { minimum: 3, allow_blank: true }
|
26
30
|
validates :first_name, length: { minimum: 2, allow_blank: true }
|
27
31
|
validates :last_name, length: { minimum: 2, allow_blank: true }
|
32
|
+
validates :title, length: { minimum: 2, allow_blank: true }
|
33
|
+
end
|
34
|
+
|
35
|
+
def categories
|
36
|
+
EffectiveMemberships.Category.membership_directory.all
|
28
37
|
end
|
29
38
|
|
30
39
|
# Base collection to search. Can be configured per tenant.
|
31
40
|
def collection
|
32
|
-
|
33
|
-
|
41
|
+
Effective::Membership.deep.sorted
|
42
|
+
.in_good_standing
|
43
|
+
.without_archived_owners
|
44
|
+
.with_category(categories)
|
34
45
|
end
|
35
46
|
|
36
47
|
# Search Users and Organizations for only these fields. Passed into search_any. Return nil for all.
|
@@ -44,21 +55,21 @@ module EffectiveMembershipsDirectory
|
|
44
55
|
end
|
45
56
|
|
46
57
|
def present?
|
47
|
-
term.present? || first_name.present? || last_name.present? || category.present?
|
58
|
+
term.present? || first_name.present? || last_name.present? || title.present? || category.present?
|
48
59
|
end
|
49
60
|
|
50
61
|
# Search and assigns the collection
|
51
62
|
# Assigns the entire collection() if there are no search terms
|
52
63
|
# Otherwise validate the search terms
|
53
64
|
def search!
|
54
|
-
@
|
55
|
-
@
|
56
|
-
@
|
65
|
+
@memberships = build_collection()
|
66
|
+
@memberships = @memberships.none if present? && !valid?
|
67
|
+
@memberships
|
57
68
|
end
|
58
69
|
|
59
70
|
# The unpaginated results of the search
|
60
|
-
def
|
61
|
-
@
|
71
|
+
def memberships
|
72
|
+
@memberships || collection
|
62
73
|
end
|
63
74
|
|
64
75
|
# The paginated results
|
@@ -66,38 +77,53 @@ module EffectiveMembershipsDirectory
|
|
66
77
|
page = (page || 1).to_i
|
67
78
|
offset = [(page - 1), 0].max * per_page
|
68
79
|
|
69
|
-
|
80
|
+
memberships.limit(per_page).offset(offset)
|
70
81
|
end
|
71
82
|
|
72
83
|
protected
|
73
84
|
|
74
85
|
def build_collection
|
75
|
-
|
76
|
-
raise('expected an ActiveRecord collection') unless
|
77
|
-
raise('expected
|
86
|
+
memberships = collection()
|
87
|
+
raise('expected an ActiveRecord collection') unless memberships.kind_of?(ActiveRecord::Relation)
|
88
|
+
raise('expected an ActiveRecord collection of Effective::Memberships') unless memberships.klass.respond_to?(:effective_membership?)
|
78
89
|
|
79
90
|
# Filter by term
|
80
91
|
if term.present?
|
81
|
-
owners = Effective::Resource.new(
|
92
|
+
owners = owner_klasses.map { |klass| Effective::Resource.new(klass).search_any(term, columns: search_any_columns) }
|
93
|
+
memberships = memberships.where(owner: owners)
|
82
94
|
end
|
83
95
|
|
84
96
|
# Filter by first name
|
85
97
|
if first_name.present?
|
86
|
-
owners = Effective::Resource.new(
|
98
|
+
owners = owner_klasses.map { |klass| Effective::Resource.new(klass).search_any(first_name, columns: :first_name) }
|
99
|
+
memberships = memberships.where(owner: owners)
|
87
100
|
end
|
88
101
|
|
89
102
|
# Filter by last name
|
90
103
|
if last_name.present?
|
91
|
-
owners = Effective::Resource.new(
|
104
|
+
owners = owner_klasses.map { |klass| Effective::Resource.new(klass).search_any(last_name, columns: :last_name) }
|
105
|
+
memberships = memberships.where(owner: owners)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Filter by title
|
109
|
+
if title.present?
|
110
|
+
owners = owner_klasses.map { |klass| Effective::Resource.new(klass).search_any(last_name, columns: :title) }
|
111
|
+
memberships = memberships.where(owner: owners)
|
92
112
|
end
|
93
113
|
|
94
114
|
# Filter by category
|
95
115
|
if category.present?
|
96
|
-
|
97
|
-
owners = owners.members_with_category(cat) if cat.present?
|
116
|
+
memberships = memberships.with_category(EffectiveMemberships.Category.where(id: category))
|
98
117
|
end
|
99
118
|
|
100
|
-
|
119
|
+
# Return an ActiveRecord::Relation of Effective::Memberships
|
120
|
+
memberships
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def owner_klasses
|
126
|
+
Effective::Membership.owner_klasses
|
101
127
|
end
|
102
128
|
|
103
129
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Effective
|
2
2
|
class Membership < ActiveRecord::Base
|
3
3
|
belongs_to :owner, polymorphic: true
|
4
|
+
has_secure_token
|
4
5
|
|
5
6
|
attr_accessor :current_action
|
6
7
|
|
@@ -24,30 +25,34 @@ module Effective
|
|
24
25
|
fees_paid_period :date # The most recent period they have paid in. Start date of period.
|
25
26
|
fees_paid_through_period :date # The most recent period they have paid in. End date of period. Kind of an expires.
|
26
27
|
|
28
|
+
# Membership Directory
|
29
|
+
owner_name :string
|
30
|
+
token :string
|
31
|
+
|
27
32
|
timestamps
|
28
33
|
end
|
29
34
|
|
30
35
|
scope :deep, -> { includes(:owner, membership_categories: :category, membership_statuses: :status) }
|
31
|
-
scope :sorted, -> { order(
|
36
|
+
scope :sorted, -> { order('lower(owner_name)') }
|
32
37
|
|
33
38
|
scope :with_status, -> (statuses) {
|
34
|
-
raise('expected an EffectiveMemberships.Status') unless Array(statuses).all? { |status| status.kind_of?(EffectiveMemberships.Status) }
|
35
|
-
where(id: MembershipStatus.where(
|
39
|
+
raise('expected an EffectiveMemberships.Status') unless statuses.class.respond_to?(:effective_memberships_status?) || Array(statuses).all? { |status| status.kind_of?(EffectiveMemberships.Status) }
|
40
|
+
where(id: MembershipStatus.where(status_id: statuses).select(:membership_id))
|
36
41
|
}
|
37
42
|
|
38
43
|
scope :without_status, -> (statuses) {
|
39
|
-
raise('expected an EffectiveMemberships.Status') unless Array(statuses).all? { |status| status.kind_of?(EffectiveMemberships.Status) }
|
40
|
-
where.not(id: MembershipStatus.where(
|
44
|
+
raise('expected an EffectiveMemberships.Status') unless statuses.class.respond_to?(:effective_memberships_status?) || Array(statuses).all? { |status| status.kind_of?(EffectiveMemberships.Status) }
|
45
|
+
where.not(id: MembershipStatus.where(status_id: statuses).select(:membership_id))
|
41
46
|
}
|
42
47
|
|
43
48
|
scope :with_category, -> (categories) {
|
44
|
-
raise('expected an EffectiveMemberships.Category') unless Array(categories).all? { |cat| cat.kind_of?(EffectiveMemberships.Category) }
|
45
|
-
where(id: MembershipCategory.where(
|
49
|
+
raise('expected an EffectiveMemberships.Category') unless categories.class.respond_to?(:effective_memberships_category?) || Array(categories).all? { |cat| cat.kind_of?(EffectiveMemberships.Category) }
|
50
|
+
where(id: MembershipCategory.where(category_id: categories).select(:membership_id))
|
46
51
|
}
|
47
52
|
|
48
53
|
scope :without_category, -> (categories) {
|
49
|
-
raise('expected an EffectiveMemberships.Category') unless Array(categories).all? { |cat| cat.kind_of?(EffectiveMemberships.Category) }
|
50
|
-
where.not(id: MembershipCategory.where(
|
54
|
+
raise('expected an EffectiveMemberships.Category') unless categories.class.respond_to?(:effective_memberships_category?) || Array(categories).all? { |cat| cat.kind_of?(EffectiveMemberships.Category) }
|
55
|
+
where.not(id: MembershipCategory.where(category_id: categories).select(:membership_id))
|
51
56
|
}
|
52
57
|
|
53
58
|
scope :joined_before, -> (date) {
|
@@ -73,14 +78,24 @@ module Effective
|
|
73
78
|
scope :not_in_good_standing, -> { with_status(EffectiveMemberships.Registrar.not_in_good_standing_status) }
|
74
79
|
scope :in_good_standing, -> { without_status(EffectiveMemberships.Registrar.not_in_good_standing_status) }
|
75
80
|
|
81
|
+
scope :without_archived_owners, -> {
|
82
|
+
where.not(owner: klass.acts_as_archived_owner_klasses.map { |klass| klass.archived })
|
83
|
+
}
|
84
|
+
|
76
85
|
before_validation do
|
77
86
|
self.registration_on ||= joined_on
|
78
87
|
end
|
79
88
|
|
89
|
+
before_validation(if: -> { owner.present? }) do
|
90
|
+
self.owner_name = owner.to_s
|
91
|
+
end
|
92
|
+
|
80
93
|
before_validation(if: -> { number_changed? }) do
|
81
94
|
self.number_as_integer = (number.present? ? (Integer(number) rescue nil) : nil)
|
82
95
|
end
|
83
96
|
|
97
|
+
validates :owner_name, presence: true
|
98
|
+
|
84
99
|
validates :number, uniqueness: { allow_blank: true }
|
85
100
|
validates :number, presence: true, if: -> { categories.any?(:membership_number_required?) }
|
86
101
|
|
@@ -100,11 +115,19 @@ module Effective
|
|
100
115
|
maximum('number_as_integer') || 0
|
101
116
|
end
|
102
117
|
|
118
|
+
def self.effective_membership?
|
119
|
+
true
|
120
|
+
end
|
121
|
+
|
103
122
|
def self.owner_klasses
|
104
123
|
klasses = Effective::Membership.distinct(:owner_type).pluck(:owner_type)
|
105
124
|
klasses.select { |klass| klass.safe_constantize }.map { |klass| klass.constantize }
|
106
125
|
end
|
107
126
|
|
127
|
+
def self.acts_as_archived_owner_klasses
|
128
|
+
owner_klasses.select { |klass| klass.try(:acts_as_archived?) }
|
129
|
+
end
|
130
|
+
|
108
131
|
def to_s
|
109
132
|
return 'membership' if owner.blank?
|
110
133
|
|
@@ -1,11 +1,14 @@
|
|
1
1
|
= effective_form_with(scope: :q, model: membership_directory, method: :get, url: request.path) do |f|
|
2
|
-
|
3
|
-
= f.search_field :term, label: 'Name'
|
2
|
+
= f.search_field :term, label: 'Name'
|
4
3
|
|
5
|
-
|
6
|
-
|
4
|
+
-# Users only
|
5
|
+
/= f.search_field :first_name
|
6
|
+
/= f.search_field :last_name
|
7
7
|
|
8
|
-
|
8
|
+
- # Organizations only
|
9
|
+
/= f.search_field :title
|
10
|
+
|
11
|
+
= f.select :category, membership_directory.categories
|
9
12
|
|
10
13
|
= f.save('Search', class: 'btn btn-primary btn-search mr-3', name: nil)
|
11
14
|
= link_to 'Reset filters', request.path
|
@@ -0,0 +1,20 @@
|
|
1
|
+
= card do
|
2
|
+
%h6= membership.owner
|
3
|
+
%p= membership.categories.map(&:membership_directory_title).to_sentence
|
4
|
+
%p= membership.statuses.map(&:membership_directory_title).to_sentence
|
5
|
+
|
6
|
+
- if membership.owner.try(:email).present?
|
7
|
+
%p= reveal_mail_to(membership.owner.email)
|
8
|
+
|
9
|
+
- if (organizations = membership.owner.try(:membership_organizations)).present?
|
10
|
+
.mb-4.membership-directory-organizations
|
11
|
+
- organizations.each do |organization|
|
12
|
+
%div= organization
|
13
|
+
|
14
|
+
- if (users = membership.owner.try(:membership_users)).present?
|
15
|
+
.mb-4.membership-directory-users
|
16
|
+
- users.each do |user|
|
17
|
+
%div= user
|
18
|
+
|
19
|
+
- if EffectiveResources.authorized?(self, :show, membership) && EffectiveResources.authorized?(self, :show, membership.owner)
|
20
|
+
= link_to 'Show more', effective_memberships.membership_directory_path(membership.token)
|
@@ -4,14 +4,14 @@
|
|
4
4
|
- results = membership_directory.results(page: params[:page])
|
5
5
|
|
6
6
|
- if membership_directory.present? && results.length == 0
|
7
|
-
.alert.alert-info There are no results for your search. Please try again.
|
7
|
+
.mt-4.alert.alert-info There are no results for your search. Please try again.
|
8
8
|
|
9
9
|
- results.in_groups_of(3).each do |group|
|
10
10
|
.row.mt-4
|
11
|
-
- group.each do |
|
12
|
-
- next unless owner
|
11
|
+
- group.each do |membership|
|
13
12
|
.col-md
|
14
|
-
|
13
|
+
- next unless membership
|
14
|
+
= render('effective/membership_directory/membership', membership: membership)
|
15
15
|
|
16
16
|
%nav.d-flex.justify-content-center
|
17
17
|
= bootstrap_paginate(results, per_page: membership_directory.per_page)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
= render 'layout' do
|
2
|
+
.effective-membership
|
3
|
+
|
4
|
+
%h6= @membership.owner
|
5
|
+
%p= @membership.categories.map(&:membership_directory_title).to_sentence
|
6
|
+
%p= @membership.statuses.map(&:membership_directory_title).to_sentence
|
7
|
+
|
8
|
+
- if @membership.owner.respond_to?(:rich_text_body)
|
9
|
+
.mb-4= @membership.owner.rich_text_body.to_s
|
10
|
+
|
11
|
+
- if @membership.owner.try(:email).present?
|
12
|
+
%p= reveal_mail_to(@membership.owner.email)
|
13
|
+
|
14
|
+
- if (organizations = @membership.owner.try(:membership_organizations)).present?
|
15
|
+
.mb-4.membership-directory-organizations
|
16
|
+
- organizations.each do |organization|
|
17
|
+
%div= organization
|
18
|
+
|
19
|
+
- if (users = @membership.owner.try(:membership_users)).present?
|
20
|
+
.mb-4.membership-directory-users
|
21
|
+
- users.each do |user|
|
22
|
+
%div= user
|
23
|
+
|
24
|
+
%hr
|
25
|
+
= link_to 'Return to Directory', effective_memberships.membership_directory_index_path, class: 'btn btn-primary'
|
data/config/routes.rb
CHANGED
@@ -26,7 +26,7 @@ EffectiveMemberships::Engine.routes.draw do
|
|
26
26
|
resources :build, controller: :fee_payments, only: [:show, :update]
|
27
27
|
end
|
28
28
|
|
29
|
-
resources :membership_directory, only: :index
|
29
|
+
resources :membership_directory, only: [:index, :show]
|
30
30
|
get '/directory', to: 'membership_directory#index'
|
31
31
|
|
32
32
|
resources :membership_cards, only: :index
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_memberships
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -483,9 +483,10 @@ files:
|
|
483
483
|
- app/views/effective/membership_cards/index.html.haml
|
484
484
|
- app/views/effective/membership_directory/_form.html.haml
|
485
485
|
- app/views/effective/membership_directory/_layout.html.haml
|
486
|
+
- app/views/effective/membership_directory/_membership.html.haml
|
486
487
|
- app/views/effective/membership_directory/_membership_directory.html.haml
|
487
|
-
- app/views/effective/membership_directory/_membership_owner.html.haml
|
488
488
|
- app/views/effective/membership_directory/index.html.haml
|
489
|
+
- app/views/effective/membership_directory/show.html.haml
|
489
490
|
- app/views/effective/memberships/_dashboard.html.haml
|
490
491
|
- app/views/effective/memberships/_membership.html.haml
|
491
492
|
- app/views/effective/memberships_mailer/applicant_approved.liquid
|