effective_committees 0.6.0 → 0.7.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 687b287a684219a3c2f0214c4639db991e8a5cb02566179c555326f4436e5a3d
4
- data.tar.gz: 28fb6cf8554ada01a148d4ceac2bb2abc453f8a20c8122ba2aee226f95b7c479
3
+ metadata.gz: 0bc2c949cff1b747488c7c18ea3def8acb9541e3278b5ae7e6f82cccf6d45c60
4
+ data.tar.gz: ea5794494521b25fa243a7c9bce9cf491cbeb49204c1d8405f0cd1a87b67ae07
5
5
  SHA512:
6
- metadata.gz: d9614f730cfc7c9bf4aa56ceb4363235e8082016273bee4c3623fac416d1ec8cdd9790f3e230bef4b20491c817ad960ff7c38c3341780dbb7136f36721f4fa0a
7
- data.tar.gz: 55379c626f837d6ed6f69698c2c7cac186af00d12021c6e1e800dd3caedb39286d66f0896f3f32db6d18e0ec923293693dd7bf0b9cf87c0fbfe6302a1750138f
6
+ metadata.gz: 7ba1a02a5ae937c6d409c7828038e2217ea94c03ef545b01d530e1309738f03a520f7cf173a0d697cbfe92daffc8202998093c29a8d3187a3bfcddced5dfde35
7
+ data.tar.gz: dfe2891d1b287231ac3a987503eb16f3b00d4a55508a073abf9ee3eaa2b444b5d43a4a8c2e44dd578e96283fe971b16bab17c87a11c262b9ad177150f5fab79e
@@ -5,6 +5,8 @@ module Admin
5
5
 
6
6
  include Effective::CrudController
7
7
 
8
+ submit :bulk_upload, 'Bulk upload'
9
+
8
10
  private
9
11
 
10
12
  def permitted_params
@@ -9,8 +9,12 @@ module Admin
9
9
  col :id, visible: false
10
10
 
11
11
  col :committee
12
- col :committee_folder, label: "Folder"
13
- col :file
12
+
13
+ col :committee_folder, label: "Folder" do |committee_file|
14
+ admin_committees_parents(committee_file.committee_folder)
15
+ end
16
+
17
+ col :file, label: "Files"
14
18
  col :title, visible: false
15
19
  col :notes
16
20
 
@@ -10,7 +10,10 @@ module Admin
10
10
 
11
11
  col :committee
12
12
 
13
- col :title, label: 'Folder'
13
+ col :parents, label: "Folders" do |committee_folder|
14
+ admin_committees_parents(committee_folder)
15
+ end
16
+
14
17
  col :slug, visible: false
15
18
  col :body, visible: false
16
19
 
@@ -21,7 +24,17 @@ module Admin
21
24
  end
22
25
 
23
26
  collection do
24
- Effective::CommitteeFolder.deep.all
27
+ folders = Effective::CommitteeFolder.deep.sorted.all
28
+
29
+ if attributes[:committee_folder_id].present?
30
+ folders = folders.where(id: committee_folder.children)
31
+ end
32
+
33
+ folders
34
+ end
35
+
36
+ def committee_folder
37
+ @committee_folder ||= Effective::CommitteeFolder.find_by_id(attributes[:committee_folder_id])
25
38
  end
26
39
 
27
40
  end
@@ -29,10 +29,16 @@ module Admin
29
29
 
30
30
  col :committee_members_count, label: "#{committee_members_label} Count", visible: false
31
31
 
32
- col :committee_folders, label: 'Folders', visible: false
32
+ col(:committee_folders, label: 'Folders', visible: false) do |committee|
33
+ committee.committee_folders.map { |folder| admin_committees_parents(folder) }.join("<br>").html_safe
34
+ end
35
+
33
36
  col :committee_folders_count, label: 'Folders Count', visible: false
34
37
 
35
- col :committee_files, label: 'Files', visible: false
38
+ col(:committee_files, label: 'Files', visible: false) do |committee|
39
+ committee.committee_files.map { |file| admin_committees_parents(file) }.join("<br>").html_safe
40
+ end
41
+
36
42
  col :committee_files_count, label: 'Files Count', visible: false
37
43
 
38
44
  actions_col do |committee|
@@ -35,4 +35,10 @@ module EffectiveCommitteesHelper
35
35
  def committee_files_label
36
36
  ets(Effective::CommitteeFile)
37
37
  end
38
+
39
+ def admin_committees_parents(resource)
40
+ parents = resource.parents + [resource]
41
+ render(partial: 'admin/committees/parents', locals: { parents: parents }, formats: [:html])
42
+ end
43
+
38
44
  end
@@ -58,5 +58,11 @@ module Effective
58
58
  committee_members.reject(&:marked_for_destruction?).select(&:active?).map(&:email).compact.join(', ')
59
59
  end
60
60
 
61
+ def children
62
+ committee_folders
63
+ .select { |folder| folder.committee_folder_id.blank? }
64
+ .flat_map { |folder| [folder] + folder.children }
65
+ end
66
+
61
67
  end
62
68
  end
@@ -43,5 +43,10 @@ module Effective
43
43
  title.presence || 'file'
44
44
  end
45
45
 
46
+ def parents
47
+ return [] if committee_folder.blank?
48
+ committee_folder.parents + [committee_folder]
49
+ end
50
+
46
51
  end
47
52
  end
@@ -8,10 +8,14 @@ module Effective
8
8
  log_changes(to: :committee) if respond_to?(:log_changes)
9
9
 
10
10
  belongs_to :committee, polymorphic: true, counter_cache: true
11
+ belongs_to :committee_folder, optional: true
11
12
 
12
13
  has_rich_text :body
14
+ has_many :committee_folders, -> { Effective::CommitteeFolder.sorted.deep }, dependent: :destroy, inverse_of: :committee_folder
13
15
  has_many :committee_files, -> { Effective::CommitteeFile.sorted.deep }, dependent: :destroy, inverse_of: :committee_folder
14
16
 
17
+ has_many_attached :files
18
+
15
19
  effective_resource do
16
20
  title :string
17
21
  slug :string
@@ -35,7 +39,32 @@ module Effective
35
39
  validates :position, presence: true
36
40
 
37
41
  def to_s
38
- title.presence || 'folder'
42
+ (parents + [self]).map { |folder| (folder.title || 'folder') }.join(' / ')
43
+ end
44
+
45
+ def bulk_upload!
46
+ files.each { |file| committee_files.create(file: file.blob) }
47
+ true
48
+ end
49
+
50
+ def parent
51
+ committee_folder || committee
52
+ end
53
+
54
+ def parents
55
+ folder = self
56
+ parents = []
57
+
58
+ while folder.committee_folder.present?
59
+ parents << folder.committee_folder
60
+ folder = folder.committee_folder
61
+ end
62
+
63
+ parents.reverse
64
+ end
65
+
66
+ def children
67
+ committee_folders.flat_map { |folder| [folder] + folder.children }
39
68
  end
40
69
 
41
70
  end
@@ -6,11 +6,16 @@
6
6
 
7
7
  - if inline_datatable? && inline_datatable.attributes[:committee_folder_id].present?
8
8
  = f.hidden_field :committee_folder_id
9
- - elsif inline_datatable?
10
- = f.select :committee_folder_id, Effective::CommitteeFolder.deep.where(committee: committee_file.committee_id), label: "Folder"
9
+ - elsif f.object.persisted?
10
+ = f.static_field :committee
11
+ = f.select :committee_folder_id, Effective::CommitteeFolder.sorted.where(committee: f.object.committee), label: "Folder"
11
12
  - else
12
- = f.select :committee_id, Effective::Committee.sorted.all
13
- = f.select :committee_folder_id, Effective::CommitteeFolder.sorted.all, label: "Folder"
13
+ = f.select :committee_id, Effective::Committee.sorted.all,
14
+ 'data-load-ajax-url': effective_committees.new_admin_committee_file_path,
15
+ 'data-load-ajax-div': '#effective-committees-ajax'
16
+
17
+ #effective-committees-ajax
18
+ = f.select :committee_folder_id, Effective::CommitteeFolder.sorted.where(committee: f.object.committee), label: "Folder"
14
19
 
15
20
  = f.file_field :file
16
21
  = f.text_area :notes
@@ -1,8 +1,15 @@
1
1
  = tabs do
2
2
  - if committee_folder.persisted?
3
- = tab 'Folder Files' do
3
+ = tab 'Folder' do
4
+ %h3 Folders
5
+ - datatable = Admin::EffectiveCommitteeFoldersDatatable.new(committee_folder: committee_folder, committee: committee_folder.committee)
6
+ = render_datatable(datatable, inline: true, simple: true)
7
+
8
+ %h3 Files
9
+ .mt-4= render('admin/committee_folders/form_bulk_upload', committee_folder: committee_folder)
10
+
4
11
  - datatable = Admin::EffectiveCommitteeFilesDatatable.new(committee_folder: committee_folder, committee: committee_folder.committee)
5
- = render_inline_datatable(datatable)
12
+ = render_datatable(datatable, inline: true, simple: true)
6
13
 
7
14
  = tab 'Folder Details' do
8
15
  = render 'admin/committee_folders/form_committee_folder', committee_folder: committee_folder
@@ -0,0 +1,3 @@
1
+ = effective_form_with(model: [:admin, committee_folder], engine: true, autosave: true) do |f|
2
+ = f.file_field :files, multiple: true, label: 'Bulk upload', hint: 'Select or drag and drop multiple files to upload'
3
+ %div{style: 'display: none;'}= f.save 'Bulk upload'
@@ -1,9 +1,21 @@
1
1
  = effective_form_with(model: [:admin, committee_folder], engine: true) do |f|
2
- - if inline_datatable?
3
- = f.hidden_field :committee_id
4
- = f.hidden_field :committee_type
2
+ - f.object.committee_type ||= Effective::Committee.name
3
+
4
+ = f.hidden_field :committee_type
5
+ = f.hidden_field :committee_id
6
+
7
+ - if inline_datatable? && inline_datatable.attributes[:committee_folder_id].present?
8
+ = f.hidden_field :committee_folder_id
9
+ - elsif f.object.persisted?
10
+ = f.static_field :committee
11
+ = f.select :committee_folder_id, Effective::CommitteeFolder.sorted.where(committee: f.object.committee), label: "Parent Folder", hint: "Leave blank to create a top-level folder"
5
12
  - else
6
- = f.select :committee, { committees_label => Effective::Committee.sorted }, polymorphic: true
13
+ = f.select :committee_id, Effective::Committee.sorted.all,
14
+ 'data-load-ajax-url': effective_committees.new_admin_committee_folder_path,
15
+ 'data-load-ajax-div': '#effective-committees-ajax'
16
+
17
+ #effective-committees-ajax
18
+ = f.select :committee_folder_id, Effective::CommitteeFolder.sorted.where(committee: f.object.committee), label: "Parent Folder", hint: "Leave blank to create a top-level folder"
7
19
 
8
20
  = f.text_field :title
9
21
 
@@ -14,4 +26,4 @@
14
26
  - else
15
27
  = f.rich_text_area :body, hint: "Displayed on the #{committee_folder_label} page"
16
28
 
17
- = effective_submit(f)
29
+ = f.submit
@@ -2,8 +2,8 @@
2
2
 
3
3
  = acts_as_slugged_fields(f, url: (effective_committees.committee_url(f.object) rescue nil))
4
4
 
5
- = f.check_box :display_on_index, label: "Show on the member-only #{link_to "Volunteers and Committees", effective_committees.volunteers_and_committees_path} page"
6
- = f.check_box :display_on_dashboard, label: "Show on the <a href='/committees'>My #{committee_label.pluralize}</a> page".html_safe
5
+ = f.check_box :display_on_index, label: "Show on the member-only #{link_to "Volunteers and Committees", effective_committees.volunteers_and_committees_path, target: '_blank'} page"
6
+ = f.check_box :display_on_dashboard, label: "Show on the #{link_to "My #{committee_label.pluralize}", effective_committees.committees_path, target: '_blank'} page".html_safe
7
7
 
8
8
  - if defined?(EffectiveArticleEditor)
9
9
  = f.article_editor :body, hint: "Shown on the #{committee_label} page."
@@ -0,0 +1,12 @@
1
+ - parents.each do |parent|
2
+ - if parent.kind_of?(Effective::CommitteeFolder)
3
+ = link_to(parent.title, effective_committees.edit_admin_committee_folder_path(parent))
4
+ - elsif parent.kind_of?(Effective::Committee)
5
+ = link_to(parent.title, effective_committees.edit_admin_committee_path(parent))
6
+ - elsif parent.kind_of?(Effective::CommitteeFile)
7
+ = link_to(parent.title, effective_committees.edit_admin_committee_file_path(parent))
8
+ - else
9
+ - raise("unexpected parent")
10
+
11
+ - if parent != parents.last
12
+ %span.mx-1 /
@@ -1,19 +1,33 @@
1
1
  = render('layout') do
2
+ - committee = committee_folder.committee
3
+
2
4
  %nav{'aria-label': 'breadcrumb'}
3
5
  %ol.breadcrumb
4
6
  %li.breadcrumb-item= link_to("My Dashboard", return_to_dashboard_path)
5
7
  %li.breadcrumb-item= link_to("My #{committees_label}", effective_committees.committees_path)
6
- %li.breadcrumb-item= link_to(committee_folder.committee, effective_committees.committee_path(committee_folder.committee))
7
- %li.breadcrumb-item.active{'aria-current': 'page'}= committee_folder
8
+ %li.breadcrumb-item= link_to(committee, effective_committees.committee_path(committee))
9
+
10
+ - committee_folder.parents.each do |parent|
11
+ %li.breadcrumb-item= link_to(parent.title, effective_committees.committee_committee_folder_path(committee, parent))
12
+
13
+ %li.breadcrumb-item.active{'aria-current': 'page'}= committee_folder.title
8
14
 
9
15
  .effective-committee-folder
10
- %h1= committee_folder
16
+ %h1= committee_folder.title
11
17
 
12
18
  - if committee_folder.rich_text_body.present?
13
19
  .mb-4= committee_folder.rich_text_body.to_s
14
20
 
15
21
  .my-4
16
22
 
23
+ - if committee_folder.committee_folders.present?
24
+ %h3 Folders
25
+ .card
26
+ .card-body
27
+ %ul
28
+ - committee_folder.committee_folders.each do |committee_folder|
29
+ %li= link_to(committee_folder.title, effective_committees.committee_committee_folder_path(committee, committee_folder))
30
+
17
31
  %h3 Files
18
32
  .card
19
33
  .card-body
@@ -20,8 +20,8 @@
20
20
  .card
21
21
  .list-group.list-group-flush
22
22
  - if committee.committee_folders.present?
23
- - committee.committee_folders.each do |folder|
24
- = link_to folder.to_s, effective_committees.committee_committee_folder_path(committee, folder), class: 'list-group-item list-group-action'
23
+ - committee.children.each do |committee_folder|
24
+ = link_to(committee_folder.to_s, effective_committees.committee_committee_folder_path(committee, committee_folder), class: 'list-group-item list-group-action')
25
25
  - else
26
26
  .list-group-item No files or folders.
27
27
 
@@ -46,6 +46,8 @@ class CreateEffectiveCommittees < ActiveRecord::Migration[6.0]
46
46
  t.integer :committee_id
47
47
  t.string :committee_type
48
48
 
49
+ t.string :committee_folder_id
50
+
49
51
  t.string :title
50
52
  t.string :slug
51
53
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveCommittees
2
- VERSION = '0.6.0'.freeze
2
+ VERSION = '0.7.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_committees
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
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: 2025-10-17 00:00:00.000000000 Z
11
+ date: 2025-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -202,6 +202,7 @@ files:
202
202
  - app/views/admin/committee_files/_form.html.haml
203
203
  - app/views/admin/committee_files/_form_committee_file.html.haml
204
204
  - app/views/admin/committee_folders/_form.html.haml
205
+ - app/views/admin/committee_folders/_form_bulk_upload.html.haml
205
206
  - app/views/admin/committee_folders/_form_committee_folder.html.haml
206
207
  - app/views/admin/committee_members/_form.html.haml
207
208
  - app/views/admin/committee_members/_form_committee_member.html.haml
@@ -209,6 +210,7 @@ files:
209
210
  - app/views/admin/committees/_fields.html.haml
210
211
  - app/views/admin/committees/_form.html.haml
211
212
  - app/views/admin/committees/_form_committee.html.haml
213
+ - app/views/admin/committees/_parents.html.haml
212
214
  - app/views/effective/committee_folders/_committee_folder.html.haml
213
215
  - app/views/effective/committee_folders/_layout.html.haml
214
216
  - app/views/effective/committee_folders/show.html.haml