effective_memberships 0.8.0 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5088dfc90ed9a12111011d7f9c8b639553abf0b03af9eea5a197c80d3b5c97f9
4
- data.tar.gz: cbedc16b06e69feac3e1921c8963d0d1e2bb3f44b4efeb4aabab0682efe582c4
3
+ metadata.gz: d55b0a5c31e8f259614c649af1fe89e2d36cb412652dc6d5ac96f051a925a7ee
4
+ data.tar.gz: 3850e9a4d2ba175becb4e0f487bc041c726516d9462470ee6c464a19ece0d559
5
5
  SHA512:
6
- metadata.gz: 8ebdebc9b7673481c1d49cca98ad7a8ead414296783dcf886e0ebdd5edec24a75f71c88d1698748b4035cfec97b14029c186c9d8e7277c6065404e3f5c837f15
7
- data.tar.gz: 3ed063f4063d1c40187b4366163dd349a4087a25e18b4083aa781ecc4b7d003c5022e1eae5db0854066ce4d48f3b3b0ba4cedbb7d21a9f3598977fc2e770c6dd
6
+ metadata.gz: d6b197509eb8ce44fd7b15230c8b55171eccf2b017017f6e38eb45917453abf96a210118fd25df35d962cf448efc3625db45f1dafe720da32c18d1ee68ab7569
7
+ data.tar.gz: 7c2e9ecd43439c7abf4a174ef1adae97938704a941e8338225b3905b38fb0e7d10aae5d075ce169b1140b77f193dc055349751569524163d5a301d65801848cf
@@ -0,0 +1,36 @@
1
+ module Effective
2
+ class MembershipDirectoryController < ApplicationController
3
+ include Effective::CrudController
4
+
5
+ def index
6
+ @page_title = 'Directory'
7
+ EffectiveResources.authorize!(self, :index, Effective::Membership)
8
+
9
+ # Sometimes we just display a Datatable for the membership directory
10
+ @datatable = EffectiveResources.best('EffectiveMembershipsDirectoryDatatable').new
11
+
12
+ # But more often we do a full membership directory search screen
13
+ @membership_directory = build_membership_directory
14
+ @membership_directory.search!
15
+
16
+ @memberships = @membership_directory.results(page: params[:page])
17
+ end
18
+
19
+ def build_membership_directory
20
+ directory = EffectiveMemberships.MembershipDirectory.new(search_params)
21
+ directory.current_user = current_user
22
+ directory
23
+ end
24
+
25
+ def search_params
26
+ return {} unless params[:q].present?
27
+
28
+ if params[:q].respond_to?(:to_h) # From the search form
29
+ params.require(:q).permit!
30
+ else
31
+ { term: params.permit(:q).fetch(:q) } # From the url /directory?q=asdf
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -11,7 +11,7 @@ class EffectiveMembershipsDirectoryDatatable < Effective::Datatable
11
11
  end
12
12
 
13
13
  collection do
14
- scope = Effective::Membership.deep.good_standing.includes(:owner)
14
+ scope = Effective::Membership.directory.all
15
15
 
16
16
  archived_klasses.each do |klass|
17
17
  scope = scope.where.not(owner_id: klass.archived.select('id'), owner_type: klass.name)
@@ -21,11 +21,7 @@ class EffectiveMembershipsDirectoryDatatable < Effective::Datatable
21
21
  end
22
22
 
23
23
  def archived_klasses
24
- @archived_klasses ||= begin
25
- klasses = Effective::Membership.distinct(:owner_type).pluck(:owner_type)
26
- klasses = klasses.select { |klass| klass.safe_constantize.try(:acts_as_archived?) }
27
- klasses.map { |klass| klass.constantize }
28
- end
24
+ @archived_klasses ||= Effective::Membership.owner_klasses.select { |klass| klass.try(:acts_as_archived?) }
29
25
  end
30
26
 
31
27
  end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is a search model for the MembershipDirectories screen
4
+ #
5
+ # EffectiveMembershipsDirectory
6
+ # Mark your directory search model with include EffectiveMembershipsDirectory
7
+
8
+ module EffectiveMembershipsDirectory
9
+ extend ActiveSupport::Concern
10
+
11
+ module ClassMethods
12
+ def effective_memberships_directory?; true; end
13
+ end
14
+
15
+ included do
16
+ include ActiveModel::Model
17
+
18
+ attr_accessor :current_user
19
+ attr_accessor :term
20
+ attr_accessor :category
21
+
22
+ attr_accessor :first_name
23
+ attr_accessor :last_name
24
+
25
+ validates :term, length: { minimum: 3, allow_blank: true }
26
+ validates :first_name, length: { minimum: 2, allow_blank: true }
27
+ validates :last_name, length: { minimum: 2, allow_blank: true }
28
+ end
29
+
30
+ # Base collection to search. Can be configured per tenant.
31
+ def collection
32
+ # Example::User.members.membership_in_good_standing.all
33
+ raise('to be implemented by app membership_directory')
34
+ end
35
+
36
+ # Search Users and Organizations for only these fields. Passed into search_any. Return nil for all.
37
+ # Should this include email?
38
+ def search_any_columns
39
+ [:title, :name, :first_name, :middle_name, :last_name]
40
+ end
41
+
42
+ def per_page
43
+ 24
44
+ end
45
+
46
+ def present?
47
+ term.present? || first_name.present? || last_name.present? || category.present?
48
+ end
49
+
50
+ # Search and assigns the collection
51
+ # Assigns the entire collection() if there are no search terms
52
+ # Otherwise validate the search terms
53
+ def search!
54
+ @membership_owners = build_collection()
55
+ @membership_owners = @membership_owners.none if present? && !valid?
56
+ @membership_owners
57
+ end
58
+
59
+ # The unpaginated results of the search
60
+ def membership_owners
61
+ @membership_owners || collection
62
+ end
63
+
64
+ # The paginated results
65
+ def results(page: nil)
66
+ page = (page || 1).to_i
67
+ offset = [(page - 1), 0].max * per_page
68
+
69
+ membership_owners.limit(per_page).offset(offset)
70
+ end
71
+
72
+ protected
73
+
74
+ def build_collection
75
+ owners = collection()
76
+ raise('expected an ActiveRecord collection') unless owners.kind_of?(ActiveRecord::Relation)
77
+ raise('expected a collection of membership_owners') unless owners.klass.respond_to?(:effective_memberships_owner?)
78
+
79
+ # Filter by term
80
+ if term.present?
81
+ owners = Effective::Resource.new(owners).search_any(term, columns: search_any_columns)
82
+ end
83
+
84
+ # Filter by first name
85
+ if first_name.present?
86
+ owners = Effective::Resource.new(owners).search_any(first_name, columns: :first_name)
87
+ end
88
+
89
+ # Filter by last name
90
+ if last_name.present?
91
+ owners = Effective::Resource.new(owners).search_any(last_name, columns: :last_name)
92
+ end
93
+
94
+ # Filter by category
95
+ if category.present?
96
+ cat = EffectiveMemberships.Category.where(id: category)
97
+ owners = owners.members_with_category(cat) if cat.present?
98
+ end
99
+
100
+ owners
101
+ end
102
+
103
+ end
@@ -7,12 +7,9 @@
7
7
  module EffectiveMembershipsOwner
8
8
  extend ActiveSupport::Concern
9
9
 
10
- mattr_accessor :descendants
11
-
12
10
  module Base
13
11
  def effective_memberships_owner
14
12
  include ::EffectiveMembershipsOwner
15
- (EffectiveMembershipsOwner.descendants ||= []) << self
16
13
  end
17
14
  end
18
15
 
@@ -27,7 +27,7 @@ module Effective
27
27
  timestamps
28
28
  end
29
29
 
30
- scope :deep, -> { includes(membership_categories: :category) }
30
+ scope :deep, -> { includes(:owner, membership_categories: :category) }
31
31
  scope :sorted, -> { order(:id) }
32
32
 
33
33
  scope :with_status, -> (statuses) {
@@ -100,6 +100,11 @@ module Effective
100
100
  maximum('number_as_integer') || 0
101
101
  end
102
102
 
103
+ def self.owner_klasses
104
+ klasses = Effective::Membership.distinct(:owner_type).pluck(:owner_type)
105
+ klasses.select { |klass| klass.safe_constantize }.map { |klass| klass.constantize }
106
+ end
107
+
103
108
  def to_s
104
109
  return 'membership' if owner.blank?
105
110
 
@@ -0,0 +1,5 @@
1
+ module Effective
2
+ class MembershipDirectory
3
+ include EffectiveMembershipsDirectory
4
+ end
5
+ end
@@ -4,7 +4,7 @@
4
4
  = f.hidden_field :owner_type
5
5
  - else
6
6
  - raise('todo')
7
- - collection = EffectiveMembershipsOwner.descendants.map { |d| [d.name.to_s, d.members.sorted] }.to_h
7
+ /- collection = EffectiveMembershipsOwner.descendants.map { |d| [d.name.to_s, d.members.sorted] }.to_h
8
8
  = f.select :owner_id, collection, polymorphic: true
9
9
 
10
10
  = f.date_field :start_on, hint: 'The start date of this period in history. Must be present.'
@@ -0,0 +1,11 @@
1
+ = effective_form_with(scope: :q, model: membership_directory, method: :get, url: request.path) do |f|
2
+ - if f.object.term.present?
3
+ = f.search_field :term, label: 'Name'
4
+
5
+ = f.search_field :first_name
6
+ = f.search_field :last_name
7
+
8
+ = f.select :category, EffectiveMemberships.Category.all
9
+
10
+ = f.save('Search', class: 'btn btn-primary btn-search mr-3', name: nil)
11
+ = link_to 'Reset filters', request.path
@@ -0,0 +1,2 @@
1
+ .effective-membership-directory
2
+ = yield
@@ -0,0 +1,17 @@
1
+ = render 'layout' do
2
+ = render('effective/membership_directory/form', membership_directory: membership_directory)
3
+
4
+ - results = membership_directory.results(page: params[:page])
5
+
6
+ - if membership_directory.present? && results.length == 0
7
+ .alert.alert-info There are no results for your search. Please try again.
8
+
9
+ - results.in_groups_of(3).each do |group|
10
+ .row.mt-4
11
+ - group.each do |owner|
12
+ - next unless owner
13
+ .col-md
14
+ = render('effective/membership_directory/membership_owner', membership: owner.membership, owner: owner)
15
+
16
+ %nav.d-flex.justify-content-center
17
+ = bootstrap_paginate(results, per_page: membership_directory.per_page)
@@ -0,0 +1,4 @@
1
+ = card do
2
+ %h6= owner
3
+ %p= membership.categories.to_sentence
4
+ %p= membership.statuses.to_sentence
@@ -0,0 +1,2 @@
1
+ /= render_datatable(@datatable, buttons: false)
2
+ = render('effective/membership_directory/membership_directory', membership_directory: @membership_directory)
@@ -20,6 +20,7 @@ EffectiveMemberships.setup do |config|
20
20
  # config.applicant_review_class_name = 'Effective::ApplicantReview'
21
21
  # config.fee_payment_class_name = 'Effective::FeePayment'
22
22
  # config.membership_card_class_name = 'Effective::MembershipCard'
23
+ # config.membership_directory_class_name = 'Effective::MembershipDirectory'
23
24
  # config.registrar_class_name = 'Effective::Registrar'
24
25
  # config.organization_class_name = 'Effective::Organization'
25
26
  # config.status_class_name = 'Effective::Status'
data/config/routes.rb CHANGED
@@ -26,7 +26,8 @@ EffectiveMemberships::Engine.routes.draw do
26
26
  resources :build, controller: :fee_payments, only: [:show, :update]
27
27
  end
28
28
 
29
- get '/directory', to: 'memberships_directory#index'
29
+ resources :membership_directory, only: :index
30
+ get '/directory', to: 'membership_directory#index'
30
31
 
31
32
  resources :membership_cards, only: :index
32
33
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveMemberships
2
- VERSION = '0.8.0'
2
+ VERSION = '0.8.2'
3
3
  end
@@ -7,7 +7,7 @@ module EffectiveMemberships
7
7
  def self.config_keys
8
8
  [
9
9
  :categories_table_name, :applicants_table_name, :applicant_reviews_table_name, :fee_payments_table_name, :organizations_table_name, :representatives_table_name, :statuses_table_name,
10
- :category_class_name, :organization_class_name, :applicant_class_name, :applicant_review_class_name, :fee_payment_class_name, :registrar_class_name, :membership_card_class_name, :status_class_name,
10
+ :category_class_name, :organization_class_name, :applicant_class_name, :applicant_review_class_name, :fee_payment_class_name, :registrar_class_name, :membership_card_class_name, :membership_directory_class_name, :status_class_name,
11
11
  :additional_fee_types, :applicant_reviews, :applicant_endorsements_endorser_collection,
12
12
  :layout,
13
13
  :mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject, :use_effective_email_templates
@@ -40,6 +40,10 @@ module EffectiveMemberships
40
40
  membership_card_class_name&.constantize || Effective::MembershipCard
41
41
  end
42
42
 
43
+ def self.MembershipDirectory
44
+ membership_directory_class_name&.constantize || Effective::MembershipDirectory
45
+ end
46
+
43
47
  def self.Status
44
48
  status_class_name&.constantize || Effective::Status
45
49
  end
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.8.0
4
+ version: 0.8.2
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-10-20 00:00:00.000000000 Z
11
+ date: 2022-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -275,7 +275,7 @@ files:
275
275
  - app/controllers/effective/applicants_controller.rb
276
276
  - app/controllers/effective/fee_payments_controller.rb
277
277
  - app/controllers/effective/membership_cards_controller.rb
278
- - app/controllers/effective/memberships_directory_controller.rb
278
+ - app/controllers/effective/membership_directory_controller.rb
279
279
  - app/controllers/effective/organizations_controller.rb
280
280
  - app/controllers/effective/representatives_controller.rb
281
281
  - app/datatables/admin/effective_applicant_course_areas_datatable.rb
@@ -312,6 +312,7 @@ files:
312
312
  - app/models/concerns/effective_memberships_applicant_review.rb
313
313
  - app/models/concerns/effective_memberships_card.rb
314
314
  - app/models/concerns/effective_memberships_category.rb
315
+ - app/models/concerns/effective_memberships_directory.rb
315
316
  - app/models/concerns/effective_memberships_fee_payment.rb
316
317
  - app/models/concerns/effective_memberships_organization.rb
317
318
  - app/models/concerns/effective_memberships_owner.rb
@@ -334,6 +335,7 @@ files:
334
335
  - app/models/effective/membership.rb
335
336
  - app/models/effective/membership_card.rb
336
337
  - app/models/effective/membership_category.rb
338
+ - app/models/effective/membership_directory.rb
337
339
  - app/models/effective/membership_history.rb
338
340
  - app/models/effective/membership_status.rb
339
341
  - app/models/effective/organization.rb
@@ -477,9 +479,13 @@ files:
477
479
  - app/views/effective/fees/_dashboard.html.haml
478
480
  - app/views/effective/fees/_fee.html.haml
479
481
  - app/views/effective/membership_cards/index.html.haml
482
+ - app/views/effective/membership_directory/_form.html.haml
483
+ - app/views/effective/membership_directory/_layout.html.haml
484
+ - app/views/effective/membership_directory/_membership_directory.html.haml
485
+ - app/views/effective/membership_directory/_membership_owner.html.haml
486
+ - app/views/effective/membership_directory/index.html.haml
480
487
  - app/views/effective/memberships/_dashboard.html.haml
481
488
  - app/views/effective/memberships/_membership.html.haml
482
- - app/views/effective/memberships_directory/index.html.haml
483
489
  - app/views/effective/memberships_mailer/applicant_approved.liquid
484
490
  - app/views/effective/memberships_mailer/applicant_completed.liquid
485
491
  - app/views/effective/memberships_mailer/applicant_declined.liquid
@@ -1,14 +0,0 @@
1
- module Effective
2
- class MembershipsDirectoryController < ApplicationController
3
- include Effective::CrudController
4
-
5
- def index
6
- @page_title = 'Directory'
7
-
8
- EffectiveResources.authorize!(self, :index, Effective::Membership)
9
-
10
- @datatable = EffectiveResources.best('EffectiveMembershipsDirectoryDatatable').new
11
- end
12
-
13
- end
14
- end
@@ -1 +0,0 @@
1
- = render_datatable(@datatable, buttons: false)