diff --git a/app/assets/stylesheets/events.css b/app/assets/stylesheets/events.css index 7f908c4dd..f20f0b45e 100644 --- a/app/assets/stylesheets/events.css +++ b/app/assets/stylesheets/events.css @@ -25,6 +25,19 @@ } } +.events__popup { + .panel:is(&) { + max-block-size: calc(100dvh - (2 * var(--block-space-double))); + max-inline-size: calc(100dvw - (2 * var(--block-space-double))); + } + + #header:has(&) { + max-inline-size: 100%; + position: relative; + z-index: 5; + } +} + .event { --column-gap: 0.7ch; --panel-border-radius: 0.5em; diff --git a/app/controllers/concerns/bucket_filterable.rb b/app/controllers/concerns/bucket_filterable.rb new file mode 100644 index 000000000..0205a456b --- /dev/null +++ b/app/controllers/concerns/bucket_filterable.rb @@ -0,0 +1,24 @@ +module BucketFilterable + extend ActiveSupport::Concern + + included do + before_action :set_bucket_filter + end + + private + def set_bucket_filter + params[:bucket_ids] ||= cookies[:bucket_filter]&.split(",") unless params[:clear_filter] + end + + def bucket_filter + params[:bucket_ids].presence || Current.user.bucket_ids + end + + def update_bucket_filter + if params[:clear_filter] + cookies.delete(:bucket_filter) + elsif params[:bucket_ids].present? + cookies[:bucket_filter] = params[:bucket_ids].join(",") + end + end +end diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index f69e5dd69..758db65c1 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb @@ -1,7 +1,10 @@ class EventsController < ApplicationController + include BucketFilterable before_action :set_activity_day def index + update_bucket_filter + @buckets = Current.user.buckets.alphabetically @events = unique_events_by_hour_and_column @next_day = latest_event_before_today&.created_at end @@ -22,7 +25,9 @@ class EventsController < ApplicationController end def user_bubbles - Current.user.accessible_bubbles.published_or_drafted_by(Current.user) + Current.user.accessible_bubbles + .published_or_drafted_by(Current.user) + .where(bucket_id: bucket_filter) end def set_activity_day diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 3f04dfdc5..ef65651c5 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -50,6 +50,7 @@ module EventsHelper accessible_events = Event.joins(bubble: :bucket) .merge(Current.user.buckets) .where(created_at: start_time..end_time) + .where(bubbles: { bucket_id: params[:bucket_ids].presence || Current.user.bucket_ids }) headers = { "Touched" => nil, diff --git a/app/models/bucket.rb b/app/models/bucket.rb index fcc3f34c7..5a603024e 100644 --- a/app/models/bucket.rb +++ b/app/models/bucket.rb @@ -8,4 +8,6 @@ class Bucket < ApplicationRecord has_many :tags, -> { distinct }, through: :bubbles validates_presence_of :name + + scope :alphabetically, -> { order(name: :asc) } end diff --git a/app/presenters/bucket_filter_presenter.rb b/app/presenters/bucket_filter_presenter.rb new file mode 100644 index 000000000..8b4938903 --- /dev/null +++ b/app/presenters/bucket_filter_presenter.rb @@ -0,0 +1,29 @@ +class BucketFilterPresenter + def initialize(buckets, params, cookies) + @buckets = buckets + @params = params + @cookies = cookies + end + + def filter_text + if selected_bucket_ids.present? + "Showing activity for #{selected_bucket_names_bold}".html_safe + else + "Showing everything" + end + end + + private + def selected_bucket_ids + @params[:bucket_ids].presence || @cookies[:bucket_filter]&.split(",") + end + + def selected_bucket_names + @buckets.where(id: selected_bucket_ids).pluck(:name).to_sentence + end + + def selected_bucket_names_bold + names = @buckets.where(id: selected_bucket_ids).pluck(:name) + names.map { |name| "#{name}" }.to_sentence + end +end diff --git a/app/views/events/_filter.html.erb b/app/views/events/_filter.html.erb new file mode 100644 index 000000000..4dd62c76f --- /dev/null +++ b/app/views/events/_filter.html.erb @@ -0,0 +1,29 @@ +<% presenter = BucketFilterPresenter.new(@buckets, params, cookies) %> +
+ + + + Filter by projects… + <%= form_with url: events_path, method: :get, class: "flex flex-column full-width popup__list", + data: { controller: "form" } do |form| %> + <%= link_to "Show everything", events_path(clear_filter: true), class: "btn popup__item" %> + <% @buckets.each do |bucket| %> + + <% end %> + <% end %> + +
\ No newline at end of file diff --git a/app/views/events/index.html.erb b/app/views/events/index.html.erb index 6de7cf776..79adcc4a5 100644 --- a/app/views/events/index.html.erb +++ b/app/views/events/index.html.erb @@ -2,12 +2,13 @@ <% content_for :header do %> <% end %> diff --git a/test/controllers/events_controller_test.rb b/test/controllers/events_controller_test.rb index 5fa3f9bf4..d8ec4620c 100644 --- a/test/controllers/events_controller_test.rb +++ b/test/controllers/events_controller_test.rb @@ -25,4 +25,16 @@ class EventsControllerTest < ActionDispatch::IntegrationTest assert_select "strong", text: "David assigned JZ to Layout is broken" end end + + test "only displays events from filtered buckets" do + get events_path(bucket_ids: [ buckets(:writebook).id ]) + assert_response :success + + events_shown = css_select(".event").count + assert events_shown > 0, "Should show some events" + + css_select(".event").each do |event| + assert_includes event.text, buckets(:writebook).name + end + end end diff --git a/test/fixtures/buckets.yml b/test/fixtures/buckets.yml index b9c31d24a..880bedd97 100644 --- a/test/fixtures/buckets.yml +++ b/test/fixtures/buckets.yml @@ -3,3 +3,9 @@ writebook: account: 37s creator: david all_access: true + +fizzy: + name: Fizzy + account: 37s + creator: david + all_access: true