@@ -122,10 +122,6 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.events__popup {
|
||||
margin-block-start: var(--block-space-half);
|
||||
}
|
||||
|
||||
/* Event
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
@layer components {
|
||||
.filters {
|
||||
view-transition-name: "filters";
|
||||
z-index: var(--z-popup);
|
||||
|
||||
#header:has(&) {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
z-index: var(--z-popup);
|
||||
}
|
||||
|
||||
.btn {
|
||||
@@ -94,19 +97,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.panel:is(.filter__popup) {
|
||||
--panel-size: 100ch;
|
||||
--panel-padding: var(--block-space);
|
||||
|
||||
inline-size: auto !important;
|
||||
min-inline-size: var(--panel-size);
|
||||
max-block-size: calc(90dvh - (2 * var(--block-space-double)));
|
||||
max-inline-size: calc(100dvw - (2 * var(--block-space-double)));
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.quick-filter {
|
||||
&:has(input:not(.default-value):checked) {
|
||||
&:not(.default-value):has(.checked) {
|
||||
.input--select {
|
||||
--input-background: var(--color-selected);
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
}
|
||||
|
||||
&:has(input:checked) {
|
||||
--btn-background: var(--color-ink-lightest);
|
||||
--btn-background: transparent;
|
||||
--btn-color: var(--color-ink);
|
||||
|
||||
.icon {
|
||||
|
||||
@@ -9,6 +9,11 @@ module FilterScoped
|
||||
DEFAULT_PARAMS = { indexed_by: "latest" }
|
||||
|
||||
def set_filter
|
||||
@filter = Current.user.filters.from_params params.reverse_merge(**DEFAULT_PARAMS).permit(*Filter::PERMITTED_PARAMS)
|
||||
@expand_all = params[:expand_all]
|
||||
if params[:filter_id].present?
|
||||
@filter = Current.user.filters.find(params[:filter_id])
|
||||
else
|
||||
@filter = Current.user.filters.from_params params.reverse_merge(**DEFAULT_PARAMS).permit(*Filter::PERMITTED_PARAMS)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,16 +3,17 @@ class FiltersController < ApplicationController
|
||||
|
||||
def create
|
||||
@filter = Current.user.filters.remember filter_params
|
||||
redirect_to cards_path(@filter.as_params)
|
||||
redirect_to cards_path(filter_id: @filter.id)
|
||||
end
|
||||
|
||||
def destroy
|
||||
filter_params = @filter.as_params
|
||||
@filter.destroy!
|
||||
|
||||
if request.referer == root_url
|
||||
redirect_to root_path
|
||||
else
|
||||
redirect_to cards_path(@filter.as_params)
|
||||
redirect_to cards_path(filter_params)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -21,6 +21,14 @@ module FiltersHelper
|
||||
hidden_field_tag name, value, id: nil
|
||||
end
|
||||
|
||||
def filter_selected_collections_sentence(filter)
|
||||
if filter.collections.any?
|
||||
filter.collections.collect { "<strong>#{it.name}</strong>" }.uniq.sort.to_sentence
|
||||
else
|
||||
tag.strong "All collections"
|
||||
end
|
||||
end
|
||||
|
||||
def filter_selected_collections_label(filter)
|
||||
selected_collections = if filter.collections.any?
|
||||
filter.collections.collect { "<strong>#{it.name}</strong>" }.uniq.sort.to_sentence
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
module Filter::Summarized
|
||||
def summary
|
||||
[ index_summary, tag_summary, assignee_summary, creator_summary, stage_summary, terms_summary ].compact.to_sentence + " #{collection_summary}"
|
||||
[ index_summary, tag_summary, assignee_summary, creator_summary, stage_summary, terms_summary ].compact.to_sentence
|
||||
end
|
||||
|
||||
private
|
||||
def index_summary
|
||||
indexed_by.humanize
|
||||
unless indexed_by.latest?
|
||||
indexed_by.humanize
|
||||
end
|
||||
end
|
||||
|
||||
def tag_summary
|
||||
if tags.any?
|
||||
"tagged #{tags.map(&:hashtag).to_choice_sentence}"
|
||||
"#{tags.map(&:hashtag).to_choice_sentence}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,12 +30,6 @@ module Filter::Summarized
|
||||
end
|
||||
end
|
||||
|
||||
def collection_summary
|
||||
if collections.any?
|
||||
"in #{collections.pluck(:name).to_choice_sentence}"
|
||||
end
|
||||
end
|
||||
|
||||
def terms_summary
|
||||
if terms.any?
|
||||
"matching #{terms.map { |term| %Q("#{term}") }.to_sentence}"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Recently closed
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow"
|
||||
<dialog class="margin-block-start-half popup panel flex-column align-start gap-half fill-white shadow"
|
||||
aria-label="Closed with reason…" aria-description="Closed with reason…"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half">Closed with reason…</strong>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<% end %>
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow"
|
||||
<dialog class="margin-block-start-half popup panel flex-column align-start gap-half fill-white shadow"
|
||||
aria-label="In stage…" aria-description="In stage…"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half">In stage(s)…</strong>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<strong class="txt-medium overflow-ellipsis margin-none">Fizzy</strong>
|
||||
<% end %>
|
||||
|
||||
<%= tag.dialog class: "fizzy-dialog filter events__popup popup popup--animated panel flex-column align-start fill-white",
|
||||
<%= tag.dialog class: "fizzy-dialog filter margin-block-start-half popup popup--animated panel flex-column align-start fill-white",
|
||||
data: {
|
||||
action: "turbo:before-cache@document->dialog#close keydown->navigable-list#navigate filter:changed->navigable-list#reset toggle->filter#filter",
|
||||
controller: "filter navigable-list",
|
||||
@@ -25,12 +25,12 @@
|
||||
|
||||
<%= render "events/filter/header" %>
|
||||
|
||||
<strong class="popup__group-title">Collections</strong>
|
||||
<%= form_with url: events_path, method: :get, class: "popup__list",
|
||||
data: { controller: "form" } do |form| %>
|
||||
<% if Current.user.collections.many? %>
|
||||
<ul class="popup__list">
|
||||
<%= render "events/filter/custom_collections" %>
|
||||
<strong class="popup__group-title">Collections</strong>
|
||||
<%= render "events/filter/all_collections_option", form: form, filter: filter %>
|
||||
<%= render partial: "events/filter/collection_option", collection: Current.user.collections.ordered_by_recently_accessed, as: :collection, locals: { form: form, filter: filter } %>
|
||||
</ul>
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
<div class="popup__list">
|
||||
<% @filters.each do |filter| %>
|
||||
<div class="popup__group flex align-center full-width gap-half overflow-ellipsis" data-filter-target="item" data-navigable-list-target="item">
|
||||
<%= link_to cards_path(**filter.as_params), class: "btn popup__new popup__item" do %>
|
||||
<%= icon_tag "filter" %>
|
||||
<span class="overflow-ellipsis"><%= filter.summary %></span>
|
||||
<span class="translucent flex-item-no-shrink flex-item-justify-end"> ›</span>
|
||||
<% end %>
|
||||
<strong class="popup__group-title">Saved filters</strong>
|
||||
<div class="popup__group flex align-center full-width gap-half overflow-ellipsis" data-navigable-list-target="item">
|
||||
<%= link_to cards_path(expand_all: true), class: "btn popup__new popup__item" do %>
|
||||
<%= icon_tag "bookmark" %>
|
||||
<div class="flex flex-column txt-tight-lines min-width txt-small">
|
||||
<strong class="overflow-ellipsis">Create a new filter</strong>
|
||||
</div>
|
||||
<span class="translucent flex-item-no-shrink flex-item-justify-end"> ›</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<% @filters.each do |filter| %>
|
||||
<div class="popup__group flex align-center full-width gap-half overflow-ellipsis" data-navigable-list-target="item">
|
||||
<%= link_to cards_path(filter_id: filter.id), class: "btn popup__new popup__item" do %>
|
||||
<%= icon_tag "bookmark" %>
|
||||
<div class="flex flex-column txt-tight-lines min-width txt-small">
|
||||
<span class="overflow-ellipsis"><%= filter_selected_collections_sentence(filter).html_safe %></span>
|
||||
<span class="overflow-ellipsis"><%= filter.summary %></span>
|
||||
</div>
|
||||
<span class="translucent flex-item-no-shrink flex-item-justify-end"> ›</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -1,53 +1,85 @@
|
||||
<% if filter.assignees.any? %>
|
||||
<% if filter.assignees.any? || @expand_all %>
|
||||
<div class="quick-filter position-relative" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside">
|
||||
<button class="btn input input--select flex-inline txt-x-small" data-action="click->dialog#open:stop">
|
||||
<span class="overflow-ellipsis">
|
||||
<% if filter.assignment_status.unassigned? %>
|
||||
No one
|
||||
<% elsif filter.assignees.any? %>
|
||||
Assigned to <%= filter.assignees.map(&:familiar_name).to_sentence %>
|
||||
Assigned to <%= filter.assignees.map(&:familiar_name).to_sentence(two_words_connector: " or ", last_word_connector: ", or ") %>
|
||||
<% else %>
|
||||
Assigned to…
|
||||
<% end %>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow" data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half overflow-ellipsis">Assigned to…</strong>
|
||||
<%= form_with url: cards_path, method: :get, class: "popup__list",
|
||||
data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:assignee_ids, :assignment_status).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
<%= tag.dialog class: "margin-block-start-half popup panel flex-column align-start gap-half fill-white shadow txt-small", data: {
|
||||
action: "turbo:before-cache@document->dialog#close keydown->navigable-list#navigate filter:changed->navigable-list#reset toggle->filter#filter",
|
||||
aria: { label: "Assigned to…", aria_description: "Assigned to…" },
|
||||
controller: "filter navigable-list",
|
||||
dialog_target: "dialog",
|
||||
navigable_list_focus_on_selection_value: false,
|
||||
navigable_list_actionable_items_value: true } do %>
|
||||
<strong class="popup__title txt-nowrap">Assigned to…</strong>
|
||||
|
||||
<%= link_to cards_path(filter.as_params.except(:assignee_ids, :assignment_status)), class: "btn popup__item" do %>
|
||||
<span class="overflow-ellipsis">Clear all</span>
|
||||
<% end %>
|
||||
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "assignment_status", {
|
||||
checked: filter.assignment_status.unassigned?,
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
}, "unassigned" %>
|
||||
|
||||
<%= form.label :assignment_status, "No one", class: "overflow-ellipsis" %>
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
|
||||
<% User.active.order(:name).each do |user| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "assignee_ids[]", {
|
||||
checked: filter.assignees.include?(user),
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
}, user.id %>
|
||||
|
||||
<%= form.label "assignee_ids[]", user.name, for: dom_id(user, :filter), class: "overflow-ellipsis" %>
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if User.active.many? %>
|
||||
<%= text_field_tag :search, nil, placeholder: "Filter…", class: "input input--transparent txt-small", autofocus: true,
|
||||
type: "search", autocorrect: "off", autocomplete: "off", data: { "1p-ignore": "true", filter_target: "input", action: "input->filter#filter" } %>
|
||||
<% end %>
|
||||
</dialog>
|
||||
|
||||
<ul class="popup__list" data-filter-target="list">
|
||||
<li class="popup__group flex align-center" data-value="no one" data-filter-target="item" data-navigable-list-target="item">
|
||||
<%= form_with url: cards_path, method: :get, class: "full-width", data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:assignee_ids, :assignment_status).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
<% unless filter.assignment_status.unassigned? %>
|
||||
<%= hidden_field_tag :assignment_status, "unassigned" %>
|
||||
<% end %>
|
||||
|
||||
<% if @expand_all %>
|
||||
<%= hidden_field_tag :expand_all, @expand_all %>
|
||||
<% end %>
|
||||
|
||||
<%= form.button type: "submit", class: "btn popup__item min-width full-width unpad-inline" do %>
|
||||
<span class="overflow-ellipsis flex-item-grow">No one</span>
|
||||
<% if filter.assignment_status.unassigned? %>
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% User.active.order(:name).each do |user| %>
|
||||
<li class="popup__group flex align-center" data-value="<%= user.name.downcase %>" data-filter-target="item" data-navigable-list-target="item">
|
||||
<%= form_with url: cards_path, method: :get, class: "full-width", data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:assignee_ids, :assignment_status).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
<% filter.assignees.each do |existing_assignee| %>
|
||||
<% unless existing_assignee == user %>
|
||||
<%= hidden_field_tag "assignee_ids[]", existing_assignee.id %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% unless filter.assignees.include?(user) %>
|
||||
<%= hidden_field_tag "assignee_ids[]", user.id %>
|
||||
<% end %>
|
||||
|
||||
<% if @expand_all %>
|
||||
<%= hidden_field_tag :expand_all, @expand_all %>
|
||||
<% end %>
|
||||
|
||||
<%= form.button type: "submit", class: "btn popup__item min-width full-width unpad-inline" do %>
|
||||
<span class="overflow-ellipsis flex-item-grow"><%= user.name %></span>
|
||||
<% if filter.assignees.include?(user) %>
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -1,56 +1,62 @@
|
||||
<% if filter.creators.any? %>
|
||||
<% if filter.creators.any? || @expand_all %>
|
||||
<div class="quick-filter position-relative" data-controller="dialog"
|
||||
data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside">
|
||||
<button class="btn input input--select flex-inline txt-x-small" data-action="click->dialog#open:stop">
|
||||
<span class="overflow-ellipsis">
|
||||
<% if filter.creators.any? %>
|
||||
<%= "Added by #{filter.creators.map(&:familiar_name).to_sentence}" %>
|
||||
<%= "Added by #{filter.creators.map(&:familiar_name).to_sentence(two_words_connector: " or ", last_word_connector: ", or ")}" %>
|
||||
<% else %>
|
||||
Added by…
|
||||
<% end %>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow"
|
||||
aria-label="Added by…" aria-description="Added by…"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half">Added by…</strong>
|
||||
<%= form_with url: cards_path, method: :get, class: "popup__list",
|
||||
data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:creator_ids).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
<%= tag.dialog class: "margin-block-start-half popup panel flex-column align-start gap-half fill-white shadow txt-small", data: {
|
||||
action: "turbo:before-cache@document->dialog#close keydown->navigable-list#navigate filter:changed->navigable-list#reset toggle->filter#filter",
|
||||
aria: { label: "Added by…", aria_description: "Added by…" },
|
||||
controller: "filter navigable-list",
|
||||
dialog_target: "dialog",
|
||||
navigable_list_focus_on_selection_value: false,
|
||||
navigable_list_actionable_items_value: true } do %>
|
||||
<strong class="popup__title txt-nowrap">Added by…</strong>
|
||||
|
||||
<%= link_to cards_path(filter.as_params.except(:creator_ids)), class: "btn popup__item" do %>
|
||||
<span class="overflow-ellipsis">Clear all</span>
|
||||
<% end %>
|
||||
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box :creator_ids, {
|
||||
multiple: true,
|
||||
checked: filter.creators.include?(Current.user),
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
}, Current.user.id %>
|
||||
|
||||
<%= form.label :creator_ids, "Me", for: form.field_id(:creator_ids, Current.user.id), class: "overflow-ellipsis" %>
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
|
||||
<% User.active.without(Current.user).order(:name).each do |user| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box :creator_ids, {
|
||||
multiple: true,
|
||||
checked: filter.creators.include?(user),
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
}, user.id %>
|
||||
|
||||
<%= form.label :creator_ids, user.name, for: form.field_id(:creator_ids, user.id), class: "overflow-ellipsis" %>
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if User.active.many? %>
|
||||
<%= text_field_tag :search, nil, placeholder: "Filter…", class: "input input--transparent txt-small", autofocus: true,
|
||||
type: "search", autocorrect: "off", autocomplete: "off", data: { "1p-ignore": "true", filter_target: "input", action: "input->filter#filter" } %>
|
||||
<% end %>
|
||||
</dialog>
|
||||
|
||||
<ul class="popup__list" data-filter-target="list">
|
||||
<% User.active.order(:name).each do |user| %>
|
||||
<li class="popup__group flex align-center" data-value="<%= user.name.downcase %>" data-filter-target="item" data-navigable-list-target="item">
|
||||
<%= form_with url: cards_path, method: :get, class: "full-width", data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:creator_ids).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
<% filter.creators.each do |existing_creators| %>
|
||||
<% unless existing_creators == user %>
|
||||
<%= hidden_field_tag "creator_ids[]", existing_creators.id %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% unless filter.creators.include?(user) %>
|
||||
<%= hidden_field_tag "creator_ids[]", user.id %>
|
||||
<% end %>
|
||||
|
||||
<% if @expand_all %>
|
||||
<%= hidden_field_tag :expand_all, @expand_all %>
|
||||
<% end %>
|
||||
|
||||
<%= form.button type: "submit", class: "btn popup__item min-width full-width unpad-inline" do %>
|
||||
<span class="overflow-ellipsis flex-item-grow"><%= user.name %></span>
|
||||
<% if filter.creators.include?(user) %>
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<%# Don't delete this file just yet, it's coming back soon. %>
|
||||
<dialog class="filter__popup dialog panel fill-white shadow" aria-label="Filter" aria-description="Filter" data-dialog-target="dialog">
|
||||
<dialog class="dialog panel fill-white shadow" aria-label="Filter" aria-description="Filter" data-dialog-target="dialog">
|
||||
<div class="flex flex-column gap-half">
|
||||
<div class="flex align-center gap-half justify-space-between">
|
||||
<span class="btn btn--placeholder txt-small" aria-hidden="true"></span>
|
||||
|
||||
@@ -1,32 +1,44 @@
|
||||
<% if !filter.indexed_by.latest? %>
|
||||
<div class="quick-filter position-relative" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside">
|
||||
<button class="btn input input--select flex-inline txt-small" data-action="click->dialog#open:stop">
|
||||
<% if !filter.indexed_by.latest? || @expand_all %>
|
||||
<div class="quick-filter position-relative <%= "default-value" if filter.indexed_by.latest? %>" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside">
|
||||
<button class="btn input input--select flex-inline txt-x-small" data-action="click->dialog#open:stop">
|
||||
<span class="overflow-ellipsis">
|
||||
<%= filter.indexed_by.humanize %>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow"
|
||||
aria-label="Sort by…" aria-description="Sort by…"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half">Sort by…</strong>
|
||||
<%= form_with url: cards_path, method: :get, class: "popup__list",
|
||||
data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:indexed_by).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
<%= tag.dialog class: "margin-block-start-half popup panel flex-column align-start gap-half fill-white shadow txt-small", data: {
|
||||
action: "turbo:before-cache@document->dialog#close keydown->navigable-list#navigate",
|
||||
aria: { label: "Sort by…", aria_description: "Sort by…" },
|
||||
controller: "navigable-list",
|
||||
dialog_target: "dialog",
|
||||
navigable_list_focus_on_selection_value: false,
|
||||
navigable_list_actionable_items_value: true } do %>
|
||||
<strong class="popup__title txt-nowrap">Sort by…</strong>
|
||||
|
||||
<ul class="popup__list" data-filter-target="list">
|
||||
<% Filter::INDEXES.each do |index| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.radio_button :indexed_by, index,
|
||||
checked: filter.indexed_by == index,
|
||||
data: { action: "change->form#submit" } %>
|
||||
<li class="popup__group flex align-center" data-navigable-list-target="item">
|
||||
<%= form_with url: cards_path, method: :get, class: "full-width", data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:indexed_by).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
<%= form.label :indexed_by, index.humanize, value: index, class: "overflow-ellipsis" %>
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
<%= hidden_field_tag :indexed_by, index %>
|
||||
|
||||
<% if @expand_all %>
|
||||
<%= hidden_field_tag :expand_all, @expand_all %>
|
||||
<% end %>
|
||||
|
||||
<%= form.button type: "submit", class: "btn popup__item min-width full-width unpad-inline" do %>
|
||||
<span class="overflow-ellipsis flex-item-grow"><%= index.humanize %></span>
|
||||
<% if filter.indexed_by == index %>
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</dialog>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -1,17 +1,46 @@
|
||||
<div class="filters flex align-center gap-half margin-none-block-end margin-block-start-half justify-center center">
|
||||
<div class="flex-inline center align-center gap-half">
|
||||
<% if any_filters?(filter) %>
|
||||
<% if @expand_all %>
|
||||
<%= link_to cards_path(filter.as_params), class: "btn txt-x-small btn--reversed", aria: { selected: true} do %>
|
||||
<%= icon_tag "filter" %>
|
||||
<span class="for-screen-reader">Edit filters</span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= link_to cards_path(filter.as_params.merge(expand_all: true)), class: "btn txt-x-small" do %>
|
||||
<%= icon_tag "filter" %>
|
||||
<span class="for-screen-reader">Edit filters</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= render "filters/indexed_by", filter: filter %>
|
||||
<%= render "filters/tags", filter: filter %>
|
||||
<%= render "filters/assignees", filter: filter %>
|
||||
<%= render "filters/creators", filter: filter %>
|
||||
<%= render "filters/stages", filter: filter %>
|
||||
<%# FIXME LATER: this needs to be able to allow selection of unique stages across all active workflows %>
|
||||
<%#= render "filters/stages", filter: filter %>
|
||||
<%= render "filters/cards", filter: filter %>
|
||||
<%= render "filters/indexed_by", filter: filter %>
|
||||
|
||||
|
||||
<% filter.terms.each do |term| %>
|
||||
<%= filter_chip_tag %Q("#{term}"), filter.as_params_without(:terms, term) %>
|
||||
<% end %>
|
||||
|
||||
<% if any_filters?(filter) %>
|
||||
<% if filter.persisted? %>
|
||||
<%= button_to filter_path(filter), method: :delete, class: "btn txt-x-small btn--reversed", form_class: "inline" do %>
|
||||
<%= icon_tag "bookmark" %>
|
||||
<span class="for-screen-reader">Remove saved filter</span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<% filter_params = filter.as_params.transform_values { |v| v.respond_to?(:to_str) ? v.to_str : v } %>
|
||||
<%= button_to filters_path, method: :post, params: filter_params, class: "btn txt-x-small", form_class: "inline" do %>
|
||||
<%= icon_tag "bookmark" %>
|
||||
<span class="for-screen-reader">Save filter</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to cards_path(filter.as_params.except(:assignee_ids, :assignment_status, :card_ids, :creator_ids, :stage_ids, :tag_ids, :terms, :indexed_by)), class: "btn btn--remove txt-x-small" do %>
|
||||
<%= icon_tag "close" %>
|
||||
<span class="for-screen-reader">Clear all</span>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<% if filter.stages.any? %>
|
||||
<% if filter.stages.any? || @expand_all %>
|
||||
<div class="quick-filter position-relative" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside">
|
||||
<button class="btn input input--select flex-inline txt-x-small" data-action="click->dialog#open:stop">
|
||||
<span class="overflow-ellipsis">
|
||||
@@ -10,7 +10,7 @@
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow"
|
||||
<dialog class="margin-block-start-half popup panel flex-column align-start gap-half fill-white shadow"
|
||||
aria-label="In stage…" aria-description="In stage…"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half overflow-ellipsis">In stage…</strong>
|
||||
@@ -20,6 +20,10 @@
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
<% if @expand_all %>
|
||||
<%= hidden_field_tag :expand_all, @expand_all %>
|
||||
<% end %>
|
||||
|
||||
<% filter.stages.first.workflow.stages.each do |stage| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box :stage_ids, {
|
||||
|
||||
@@ -1,40 +1,61 @@
|
||||
<% if filter.tags.any? %>
|
||||
<% if filter.tags.any?|| @expand_all %>
|
||||
<div class="quick-filter position-relative" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside">
|
||||
<button class="btn input input--select flex-inline txt-x-small" data-action="click->dialog#open:stop">
|
||||
<span class="overflow-ellipsis">
|
||||
<% if filter.tags.any? %>
|
||||
<%= filter.tags.map(&:hashtag).to_sentence %>
|
||||
<%= filter.tags.map(&:hashtag).to_sentence(two_words_connector: " or ", last_word_connector: ", or ") %>
|
||||
<% else %>
|
||||
Tagged…
|
||||
<% end %>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow" data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half overflow-ellipsis">Tagged…</strong>
|
||||
<%= form_with url: cards_path, method: :get, class: "popup__list",
|
||||
data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:tag_ids).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
<%= tag.dialog class: "margin-block-start-half popup panel flex-column align-start gap-half fill-white shadow txt-small", data: {
|
||||
action: "turbo:before-cache@document->dialog#close keydown->navigable-list#navigate filter:changed->navigable-list#reset toggle->filter#filter",
|
||||
aria: { label: "Tagged…", aria_description: "Tagged…" },
|
||||
controller: "filter navigable-list",
|
||||
dialog_target: "dialog",
|
||||
navigable_list_focus_on_selection_value: false,
|
||||
navigable_list_actionable_items_value: true } do %>
|
||||
<strong class="popup__title txt-nowrap">Tagged…</strong>
|
||||
|
||||
<%= link_to cards_path(filter.as_params.except(:tag_ids)), class: "btn popup__item" do %>
|
||||
<span class="overflow-ellipsis">Clear all</span>
|
||||
<% end %>
|
||||
|
||||
<% Tag.order(:title).each do |tag| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "tag_ids[]", {
|
||||
checked: filter.tags.include?(tag),
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
}, tag.id %>
|
||||
|
||||
<%= form.label "tag_ids[]", tag.hashtag, for: dom_id(tag, :filter), class: "overflow-ellipsis" %>
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if Tag.many? %>
|
||||
<%= text_field_tag :search, nil, placeholder: "Filter…", class: "input input--transparent txt-small", autofocus: true,
|
||||
type: "search", autocorrect: "off", autocomplete: "off", data: { "1p-ignore": "true", filter_target: "input", action: "input->filter#filter" } %>
|
||||
<% end %>
|
||||
</dialog>
|
||||
|
||||
<ul class="popup__list" data-filter-target="list">
|
||||
<% Tag.order(:title).each do |tag| %>
|
||||
<li class="popup__group flex align-center" data-value="<%= tag.title.downcase %>" data-filter-target="item" data-navigable-list-target="item">
|
||||
<%= form_with url: cards_path, method: :get, class: "full-width", data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:tag_ids).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
<% filter.tags.each do |existing_tag| %>
|
||||
<% unless existing_tag == tag %>
|
||||
<%= hidden_field_tag "tag_ids[]", existing_tag.id %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% unless filter.tags.include?(tag) %>
|
||||
<%= hidden_field_tag "tag_ids[]", tag.id %>
|
||||
<% end %>
|
||||
|
||||
<% if @expand_all %>
|
||||
<%= hidden_field_tag :expand_all, @expand_all %>
|
||||
<% end %>
|
||||
|
||||
<%= form.button type: "submit", class: "btn popup__item min-width full-width unpad-inline" do %>
|
||||
<span class="overflow-ellipsis flex-item-grow"><%= tag.hashtag %></span>
|
||||
<% if filter.tags.include?(tag) %>
|
||||
<%= icon_tag "check", class: "checked flex-item-justify-end" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -14,7 +14,7 @@ class FiltersControllerTest < ActionDispatch::IntegrationTest
|
||||
assignee_ids: [ users(:jz).id ],
|
||||
collection_ids: [ collections(:writebook).id ] }
|
||||
end
|
||||
assert_redirected_to cards_path(Filter.last.as_params)
|
||||
assert_redirected_to cards_path(filter_id: Filter.last.id)
|
||||
|
||||
filter = Filter.last
|
||||
assert_predicate filter.indexed_by, :closed?
|
||||
@@ -25,9 +25,12 @@ class FiltersControllerTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
filter = filters(:jz_assignments)
|
||||
expected_params = filter.as_params
|
||||
|
||||
assert_difference "users(:david).filters.count", -1 do
|
||||
delete filter_path(filters(:jz_assignments))
|
||||
delete filter_path(filter)
|
||||
end
|
||||
assert_redirected_to cards_path(filters(:jz_assignments).as_params)
|
||||
assert_redirected_to cards_path(expected_params)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -114,16 +114,16 @@ class FilterTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test "summary" do
|
||||
assert_equal "Newest, tagged #mobile, and assigned to JZ ", filters(:jz_assignments).summary
|
||||
assert_equal "Newest, #mobile, and assigned to JZ", filters(:jz_assignments).summary
|
||||
|
||||
filters(:jz_assignments).update!(stages: workflow_stages(:qa_triage, :qa_in_progress))
|
||||
assert_equal "Newest, tagged #mobile, assigned to JZ, and staged in Triage or In progress ", filters(:jz_assignments).summary
|
||||
assert_equal "Newest, #mobile, assigned to JZ, and staged in Triage or In progress", filters(:jz_assignments).summary
|
||||
|
||||
filters(:jz_assignments).update!(stages: [], assignees: [], tags: [], collections: [ collections(:writebook) ])
|
||||
assert_equal "Newest in Writebook", filters(:jz_assignments).summary
|
||||
assert_equal "Newest", filters(:jz_assignments).summary
|
||||
|
||||
filters(:jz_assignments).update!(indexed_by: "stalled")
|
||||
assert_equal "Stalled in Writebook", filters(:jz_assignments).summary
|
||||
assert_equal "Stalled", filters(:jz_assignments).summary
|
||||
end
|
||||
|
||||
test "get a clone with some changed params" do
|
||||
|
||||
Reference in New Issue
Block a user