Merge branch 'main' into activity-score

* main:
  Truncate headings, too
  Polish filter menu
This commit is contained in:
Jose Farias
2024-11-15 18:33:35 -06:00
7 changed files with 231 additions and 113 deletions
+1 -1
View File
@@ -14,7 +14,7 @@
cursor: pointer;
display: inline-flex;
font-size: 1em;
font-weight: 600;
font-weight: var(--btn-font-weight, 600);
gap: var(--btn-gap, 0.5em);
justify-content: center;
padding: var(--btn-padding, 0.5em 1.1em);
+45
View File
@@ -0,0 +1,45 @@
:is(.dialog) {
--backdrop-speed: 150ms;
--panel-size: max-content;
--speed: 150ms;
border: 0;
opacity: 0;
transform: scale(0.2);
transform-origin: top center;
transition:
display var(--speed) allow-discrete,
opacity var(--speed),
overlay var(--speed) allow-discrete,
transform var(--speed);
&::backdrop {
background-color: var(--color-always-black);
opacity: 0;
transform: scale(1);
transition:
display var(--backdrop-speed) allow-discrete,
opacity var(--backdrop-speed),
overlay var(--backdrop-speed) allow-discrete;
}
&[open] {
opacity: 1;
transform: scale(1);
&::backdrop {
opacity: 0.5;
}
}
@starting-style {
&[open] {
opacity: 0;
transform: scale(0.2);
}
&[open]::backdrop {
opacity: 0;
}
}
}
+67 -25
View File
@@ -6,42 +6,84 @@
}
.filter__button {
border-radius: 0.5em;
color: var(--color-ink);
display: block;
overflow: hidden;
padding: 0.3em 0.7em;
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
--btn-border-size: 0;
--btn-font-weight: 400;
--btn-icon-size: 0.7em;
--btn-padding: 0.3em 0.7em;
input:checked + & {
background-color: var(--color-selected);
inline-size: 100%;
justify-content: space-between;
span {
overflow: hidden;
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
}
@media (hover: hover) {
&:hover {
background-color: var(--color-selected);
}
img {
display: none;
}
&:has(input[type=checkbox]:checked) img {
display: block;
}
}
.filter__columns {
display: grid;
grid-template-columns: repeat(5, 1fr);
}
.filter__label {
display: flex;
inline-size: 100%;
padding: 0.3em 0.7em;
strong {
overflow: hidden;
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.filter__popup {
--panel-border-radius: 0.5em;
--panel-padding: 0.5em;
--panel-size: 30ch;
.filter__menu {
display: flex;
flex-direction: column;
inline-size: 100%;
list-style: none;
margin: 0;
min-inline-size: 0;
padding: 0 var(--inline-space);
position: relative;
row-gap: 0.2em;
&::before {
block-size: 100%;
border-block: 0;
border-inline-end: 0;
border-inline-start: 1px solid var(--color-subtle);
content: "";
display: inline-flex;
inline-size: 0;
position: absolute;
inset: 0 auto 0 0;
}
&:first-child::before {
display: none;
}
li {
text-align: start;
}
}
.panel:is(.filter__popup) {
--panel-size: 100ch;
--panel-padding: var(--block-space);
inline-size: auto !important;
inset: 0 auto auto 0;
margin-block-start: 1lh;
margin-inline-start: calc((var(--panel-padding) + 0.7em) * -1);
min-inline-size: 12ch;
max-inline-size: var(--panel-size) !important;
position: absolute;
transform-origin: top left;
z-index: 1;
}
+16
View File
@@ -20,3 +20,19 @@
}
}
}
.workflow__popup {
--panel-border-radius: 0.5em;
--panel-padding: 0.5em;
--panel-size: 100%;
inline-size: auto !important;
inset: 0 auto auto 0;
margin-block-start: 1lh;
margin-inline-start: calc((var(--panel-padding) + 0.7em) * -1);
min-inline-size: 12ch;
max-inline-size: var(--panel-size) !important;
position: absolute;
transform-origin: top left;
z-index: 1;
}
+1 -1
View File
@@ -1,6 +1,6 @@
module WorkflowsHelper
def link_to_stage_picker(bubble, workflow)
link_to workflow.name, new_bucket_bubble_stage_picker_path(bubble.bucket, bubble, workflow_id: workflow)
link_to workflow.name, new_bucket_bubble_stage_picker_path(bubble.bucket, bubble, workflow_id: workflow), class: "filter__button"
end
def button_to_set_stage(bubble, stage)
+99 -84
View File
@@ -1,4 +1,5 @@
<div class="flex flex-column gap-half align-center" data-controller="dialog filter-form" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside turbo:before-cache@document->dialog#close">
<div class="flex flex-column gap-half align-center" data-controller="dialog filter-form"
data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside turbo:before-cache@document->dialog#close">
<h1 class="txt-large flex align-center gap-half">
<%= filter.buckets.first&.name || "All projects" %>
</h1>
@@ -38,13 +39,14 @@
<% end %>
</div>
<dialog class="panel fill-white shadow" style="--panel-padding: var(--block-space); --panel-size: 90ch;" data-dialog-target="dialog">
<dialog class="filter__popup dialog panel fill-white shadow" data-dialog-target="dialog" data-dialog-modal-value="true">
<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>
<h2 class="txt-large flex gap-half margin-none">
<%= filter.buckets.first&.name || "All projects" %>
<h2 class="txt-large flex align-center gap-half margin-none">
<%= image_tag "filter.svg", aria: { hidden: true }, size: 30 %>
<span>Filter</span>
</h2>
<form method="dialog">
@@ -55,101 +57,114 @@
</form>
</div>
<%= form_with url: bubbles_path, id: :filter_form, method: :get, class: "flex flex-column gap full-width", style: "--border-color: var(--color-subtle)" do %>
<%= form_with url: bubbles_path, id: :filter_form, method: :get, class: "flex flex-column gap full-width margin-block-start", style: "--border-color: var(--color-subtle)" do %>
<% Array(params[:terms]).each do |term| %>
<%= hidden_field_tag "terms[]", term, id: nil %>
<% end %>
<div class="flex gap">
<div class="flex gap flex-item-grow">
<menu class="filter__menu list-style-none unpad margin-none">
<li><strong class="filter__label">Sort by</strong></li>
<li>
<div class="filter__columns flex gap">
<menu class="filter__menu">
<li class="filter__label"><strong>Sort by</strong></li>
<li>
<%= label_tag "indexed_by_#{filter.default_indexed_by}", class: "btn filter__button" do %>
<%= radio_button_tag "indexed_by", filter.default_indexed_by, filter.default_indexed_by?, hidden: true %>
<%= label_tag "indexed_by_#{filter.default_indexed_by}", "Default", class: "btn btn--plain filter__button" %>
</li>
<span>Most active</span>
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
<% end %>
</li>
<% Filter::INDEXES.each do |index| %>
<li>
<% Filter::INDEXES.each do |index| %>
<li>
<%= label_tag "indexed_by_#{index}", class: "btn filter__button" do %>
<%= radio_button_tag "indexed_by", index, filter.indexed_by == index, hidden: true %>
<%= label_tag "indexed_by_#{index}", index.humanize, class: "btn btn--plain filter__button" %>
</li>
<% end %>
</menu>
</div>
<hr class="separator" />
<div class="flex gap flex-item-grow">
<menu class="filter__menu list-style-none unpad margin-none">
<li><strong class="filter__label">In Project</strong></li>
<li>
<%= button_tag "All projects", type: :button, class: "btn btn--plain filter__button", data: { action: "filter-form#clearCategory", filter_form_name_param: "bucket_ids[]" } %>
<span><%= index.humanize %></span>
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
<% end %>
</li>
<% end %>
</menu>
<% Current.user.buckets.order(:name).each do |bucket| %>
<li>
<menu class="filter__menu">
<li class="filter__label"><strong>In Project</strong></li>
<li>
<%= button_tag "All Projects", type: :button, class: "btn filter__button", data: { action: "filter-form#clearCategory", filter_form_name_param: "bucket_ids[]" } %>
</li>
<% Current.user.buckets.order(:name).each do |bucket| %>
<li>
<%= label_tag "bucket_ids_#{bucket.id}", class: "btn filter__button" do %>
<%= check_box_tag "bucket_ids[]", bucket.id, filter.buckets.include?(bucket), id: "bucket_ids_#{bucket.id}", hidden: true %>
<%= label_tag "bucket_ids_#{bucket.id}", bucket.name, class: "btn btn--plain filter__button" %>
</li>
<% end %>
</menu>
</div>
<span><%= bucket.name %></span>
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
<% end %>
</li>
<% end %>
</menu>
<hr class="separator" />
<div class="flex gap flex-item-grow">
<menu class="filter__menu list-style-none unpad margin-none">
<li><strong class="filter__label">Tagged</strong></li>
<% Current.account.tags.order(:title).each do |tag| %>
<li>
<menu class="filter__menu">
<li class="filter__label"><strong>Tagged</strong></li>
<% Current.account.tags.order(:title).each do |tag| %>
<li>
<%= label_tag "tag_ids_#{tag.id}", class: "btn filter__button" do %>
<%= check_box_tag "tag_ids[]", tag.id, filter.tags.include?(tag), id: "tag_ids_#{tag.id}", hidden: true %>
<%= label_tag "tag_ids_#{tag.id}", tag.hashtag, class: "btn btn--plain filter__button" %>
</li>
<% end %>
</menu>
</div>
<hr class="separator" />
<div class="flex gap flex-item-grow">
<menu class="filter__menu list-style-none unpad margin-none">
<li><strong class="filter__label">Assigned to…</strong></li>
<li>
<%= check_box_tag "assignments", "unassigned", filter.assignments.unassigned?, id: "assignments_unassigned", hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignee_ids[],assigner_ids[]" } %>
<%= label_tag "assignments_unassigned", "No one", class: "btn btn--plain filter__button" %>
<span><%= tag.hashtag %></span>
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
<% end %>
</li>
<li>
<%= check_box_tag "assignee_ids[]", Current.user.id, filter.assignees.include?(Current.user), id: "assignee_ids_me", hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %>
<%= label_tag "assignee_ids_me", "Me", class: "btn btn--plain filter__button" %>
</li>
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
<li>
<%= check_box_tag "assignee_ids[]", user.id, filter.assignees.include?(user), id: "assignee_ids_#{user.id}", hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %>
<%= label_tag "assignee_ids_#{user.id}", user.name, class: "btn btn--plain filter__button" %>
</li>
<% end %>
</menu>
</div>
<% end %>
</menu>
<hr class="separator" />
<div class="flex gap flex-item-grow">
<menu class="filter__menu list-style-none unpad margin-none">
<li><strong class="filter__label">Assigned by…</strong></li>
<li>
<%= check_box_tag "assigner_ids[]", Current.user.id, filter.assigners.include?(Current.user), id: "assigner_ids_me", hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %>
<%= label_tag "assigner_ids_me", "Me", class: "btn btn--plain filter__button" %>
</li>
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
<li>
<%= check_box_tag "assigner_ids[]", user.id, filter.assigners.include?(user), id: "assigner_ids_#{user.id}", hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %>
<%= label_tag "assigner_ids_#{user.id}", user.name, class: "btn btn--plain filter__button" %>
</li>
<menu class="filter__menu">
<li class="filter__label"><strong>Assigned to…</strong></li>
<li>
<%= label_tag "assignments_unassigned", class: "btn filter__button" do %>
<%= check_box_tag "assignments", "unassigned", filter.assignments.unassigned?, id: "assignments_unassigned",
hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignee_ids[],assigner_ids[]" } %>
<span>No one</span>
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
<% end %>
</menu>
</div>
</li>
<li>
<%= label_tag "assignee_ids_me", class: "btn filter__button" do %>
<%= check_box_tag "assignee_ids[]", Current.user.id, filter.assignees.include?(Current.user), id: "assignee_ids_me",
hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %>
<span>Me</span>
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
<% end %>
</li>
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
<li>
<%= label_tag "assignee_ids_#{user.id}", user.name, class: "btn filter__button" do %>
<%= check_box_tag "assignee_ids[]", user.id, filter.assignees.include?(user), id: "assignee_ids_#{user.id}",
hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %>
<span><%= user.name %></span>
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
<% end %>
</li>
<% end %>
</menu>
<menu class="filter__menu">
<li class="filter__label"><strong>Assigned by…</strong></li>
<li>
<%= label_tag "assigner_ids_me", class: "btn filter__button" do %>
<%= check_box_tag "assigner_ids[]", Current.user.id, filter.assigners.include?(Current.user), id: "assigner_ids_me",
hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %>
<span>Me</span>
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
<% end %>
</li>
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
<li>
<%= label_tag "assigner_ids_#{user.id}", class: "btn filter__button" do %>
<%= check_box_tag "assigner_ids[]", user.id, filter.assigners.include?(user), id: "assigner_ids_#{user.id}",
hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignments" } %>
<span><%= user.name %></span>
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
<% end %>
</li>
<% end %>
</menu>
</div>
<% end %>
+2 -2
View File
@@ -11,8 +11,8 @@
<hr class="separator--horizontal full-width" hidden />
</div>
<dialog class="filter__popup panel fill-white shadow" data-dialog-target="dialog">
<menu class="filter__menu list-style-none unpad margin-none">
<dialog class="workflow__popup panel fill-white shadow" data-dialog-target="dialog">
<menu class="list-style-none unpad margin-none">
<% @workflows.each do |workflow| %>
<li><%= link_to_stage_picker @bubble, workflow %></li>
<% end %>