Merge branch 'main' into events-revamp
* main: Account for stages where the color isn't set Choose workflows from a small preview Add missing filter display classes, style input Scroll users list, adjust layout Workflows and card perma polish Type polish and sizing constraints dep: AR::Tenanted: no implicit db migrations New layout for collections settings, stub entropy setting Adjust collection line to contrast with comment excerpts Adjust perma layout for larger cards Give the timeline a little space on each side
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
GIT
|
||||
remote: https://github.com/basecamp/active_record-tenanted
|
||||
revision: 13b60769047226d5cb10d92eb1f2e1bc19773438
|
||||
revision: f04f4f0a153ae5da65b400021aa97fdb28ac86b5
|
||||
specs:
|
||||
active_record-tenanted (0.1.0)
|
||||
activerecord (>= 8.1.alpha)
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
/* Text */
|
||||
--text-xx-small: 0.55rem;
|
||||
--text-x-small: 0.7rem;
|
||||
--text-small: 0.8rem;
|
||||
--text-x-small: 0.75rem;
|
||||
--text-small: 0.85rem;
|
||||
--text-normal: 1rem;
|
||||
--text-medium: 1.1rem;
|
||||
--text-large: 1.5rem;
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
margin: 0;
|
||||
place-items: center;
|
||||
|
||||
img {
|
||||
img,
|
||||
.icon {
|
||||
aspect-ratio: 1;
|
||||
block-size: auto;
|
||||
border-radius: var(--avatar-border-radius);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"qw notch-top we"
|
||||
"actions-left card actions-right"
|
||||
"er notch-bottom rt";
|
||||
grid-template-columns: 48px minmax(0, 960px) 48px;
|
||||
grid-template-columns: 48px minmax(0, 1120px) 48px;
|
||||
inline-size: fit-content;
|
||||
max-inline-size: 100%;
|
||||
margin-inline: auto;
|
||||
@@ -31,6 +31,15 @@
|
||||
|
||||
border: none;
|
||||
}
|
||||
|
||||
.card__meta,
|
||||
.card__stages {
|
||||
font-size: var(--text-small);
|
||||
}
|
||||
|
||||
.card__stages {
|
||||
max-inline-size: 32ch;
|
||||
}
|
||||
}
|
||||
|
||||
/* Children
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
text-align: center;
|
||||
|
||||
@media (min-width: 160ch) {
|
||||
padding-inline: calc(var(--tray-size) + var(--inline-space) * 1.5);
|
||||
padding-inline: var(--tray-size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
--grid-lines: 0.1rem;
|
||||
|
||||
margin: auto;
|
||||
max-inline-size: min(105ch, 100%);
|
||||
}
|
||||
|
||||
.events__day-header {
|
||||
@@ -82,6 +83,12 @@
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.event__collection {
|
||||
font-size: var(--text-x-small);
|
||||
font-weight: 500;
|
||||
opacity: 0.66;
|
||||
}
|
||||
|
||||
.event__grid-item {
|
||||
background-color: var(--color-container);
|
||||
block-size: 100%;
|
||||
|
||||
@@ -107,3 +107,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter--active li {
|
||||
display: none;
|
||||
|
||||
&.selected {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,4 +12,20 @@
|
||||
--panel-border-color: var(--color-subtle-dark);
|
||||
}
|
||||
}
|
||||
|
||||
.panels--two-up {
|
||||
--panel-size: auto;
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--block-space-double);
|
||||
align-content: start;
|
||||
max-inline-size: min(100ch, 100%);
|
||||
margin: auto;
|
||||
|
||||
.panel {
|
||||
flex: 1 1 33%;
|
||||
min-inline-size: 36ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
.users-list {
|
||||
max-block-size: 40dvh;
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -108,6 +108,7 @@
|
||||
.pad-inline-double { padding-inline: var(--inline-space-double); }
|
||||
|
||||
.unpad { padding: 0; }
|
||||
.unpad-block-end { padding-block-end: 0; }
|
||||
.unpad-inline { padding-inline: 0; }
|
||||
|
||||
/* Margins */
|
||||
|
||||
@@ -28,4 +28,40 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.workflow-preview {
|
||||
--border-size: 3px;
|
||||
|
||||
flex: 1 1 30%;
|
||||
max-inline-size: 33%;
|
||||
padding: 0.5em 1em;
|
||||
|
||||
button {
|
||||
--hover-size: 0;
|
||||
|
||||
appearance: none;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
inline-size: auto;
|
||||
margin: 0;
|
||||
max-inline-size: 100%;
|
||||
outline: 0;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.workflow-preview--selected {
|
||||
--border-color: var(--color-link);
|
||||
}
|
||||
|
||||
.workflow-preview__swatch {
|
||||
--btn-size: 1em;
|
||||
--btn-border-radius: 50%;
|
||||
--btn-border-size: 0;
|
||||
--hover-size: 0;
|
||||
|
||||
cursor: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module AccessesHelper
|
||||
def access_menu_tag(collection, &)
|
||||
tag.menu class: [ "flex flex-column gap margin-none pad txt-medium", { "toggler--toggled": collection.all_access? } ], data: {
|
||||
tag.menu class: [ "flex flex-column gap-half unpad margin-none txt-medium", { "toggler--toggled": collection.all_access? } ], data: {
|
||||
controller: "filter toggle-class",
|
||||
filter_active_class: "filter--active", filter_selected_class: "selected",
|
||||
toggle_class_toggle_class: "toggler--toggled" }, &
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
module Card::Closeable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
AUTO_CLOSE_OPTIONS = [
|
||||
[ "30 days", 30.days ],
|
||||
[ "60 days", 60.days ],
|
||||
[ "90 days", 90.days ],
|
||||
[ "6 months", 180.days ],
|
||||
[ "1 year", 365.days ],
|
||||
[ "Never", nil ]
|
||||
].freeze
|
||||
|
||||
AUTO_CLOSE_AFTER = 30.days
|
||||
|
||||
included do
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<li class="flex align-center gap-half margin-none unpad" data-value="<%= user.name.downcase %>">
|
||||
<li class="flex align-center gap-half margin-none unpad txt-normal" data-value="<%= user.name.downcase %>">
|
||||
<figure class="avatar flex-item-no-shrink">
|
||||
<%= avatar_tag user %>
|
||||
</figure>
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<hr class="separator--horizontal flex-item-grow" style="--border-color: var(--color-subtle-dark); --border-style: dashed" aria-hidden="true">
|
||||
|
||||
<%= icon_tag "check", class: "toggler__visible-when-on" %>
|
||||
<%= icon_tag "check", class: "toggler__visible-when-on margin-inline-end" %>
|
||||
|
||||
<label class="switch toggler__visible-when-off flex-item-no-shrink">
|
||||
<%= check_box_tag "user_ids[]", user.id, selected, class: "switch__input", id: nil %>
|
||||
|
||||
@@ -1,81 +1,118 @@
|
||||
<% @page_title = "Edit #{@collection.name}" %>
|
||||
<% @page_title = "Collection Settings" %>
|
||||
|
||||
<% content_for :header do %>
|
||||
<nav>
|
||||
<%= link_to_back fallback_path: cards_path(collection_ids: [ @bbucket ]) %>
|
||||
|
||||
<%= form_with model: @collection, class: "flex-item-justify-end", method: :delete do |form| %>
|
||||
<%= form.button class: "btn btn--negative", data: { turbo_confirm: "Are you sure you want to delete this?" } do %>
|
||||
<%= icon_tag "minus" %>
|
||||
<span class="for-screen-reader">Delete <%= @collection.name %></span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<header class="center">
|
||||
<h1 class="txt-large margin-none"><%= @page_title %></h1>
|
||||
</header>
|
||||
|
||||
<div class="btn btn--placeholder flex-item-justify-end"></div>
|
||||
</nav>
|
||||
<% end %>
|
||||
|
||||
<div class="panel shadow center" style="--panel-size: 55ch;">
|
||||
<%= form_with model: @collection, class: "flex flex-column gap txt-large", data: { controller: "form" } do |form| %>
|
||||
<div class="flex align-center gap">
|
||||
<label class="flex-item-grow txt-large">
|
||||
<strong><%= form.text_field :name, name: "collection[name]", class: "input full-width",
|
||||
required: true, autofocus: true, placeholder: "Give it a name…",
|
||||
data: { action: "keydown.enter->form#submit:prevent, keydown.esc->form#cancel" } %></strong>
|
||||
</label>
|
||||
</div>
|
||||
<section class="panels--two-up margin-block">
|
||||
<div class="panel shadow center flex flex-column txt-normal">
|
||||
<strong class="txt-large">Name and Access</strong>
|
||||
<p class="margin-none-block-start">Choose who can access this Collection.</p>
|
||||
<%= form_with model: @collection, class: "flex flex-column gap txt-large", data: { controller: "form" } do |form| %>
|
||||
<div class="flex align-center gap">
|
||||
<label class="flex-item-grow">
|
||||
<strong><%= form.text_field :name, name: "collection[name]", class: "input full-width",
|
||||
required: true, autofocus: true, placeholder: "Give it a name…",
|
||||
data: { action: "keydown.enter->form#submit:prevent, keydown.esc->form#cancel" } %></strong>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<section class="margin-block pad-inline fill-shade border-radius">
|
||||
<%= access_menu_tag @collection do %>
|
||||
<li class="flex align-center gap margin-none">
|
||||
<figure class="avatar flex-item-no-shrink" style="--avatar-border-radius: 0; --avatar-size: 4ch;">
|
||||
<%= icon_tag "everyone" %>
|
||||
<span class="for-screen-reader">Everyone</span>
|
||||
</figure>
|
||||
<section class="margin-block fill-shade border-radius">
|
||||
<%= access_menu_tag @collection do %>
|
||||
<li class="flex align-center gap pad unpad-block-end txt-normal">
|
||||
<figure class="avatar flex-item-no-shrink" style="--avatar-border-radius: 0; --avatar-size: 3.5ch; margin-inline: 0.3em;">
|
||||
<%= icon_tag "everyone" %>
|
||||
<span class="for-screen-reader">Everyone</span>
|
||||
</figure>
|
||||
|
||||
<div class="min-width">
|
||||
<div class="overflow-ellipsis fill-shade"><strong>Everyone</strong></div>
|
||||
</div>
|
||||
<div class="min-width">
|
||||
<div class="overflow-ellipsis fill-shade"><strong>Everyone</strong></div>
|
||||
</div>
|
||||
|
||||
<hr class="separator--horizontal flex-item-grow" style="--border-color: var(--color-subtle-dark); --border-style: dashed" aria-hidden="true" />
|
||||
<hr class="separator--horizontal flex-item-grow" style="--border-color: var(--color-subtle-dark); --border-style: dashed" aria-hidden="true" />
|
||||
|
||||
<label for="collection_all_access" class="switch">
|
||||
<%= form.check_box :all_access, class: "switch__input", checked: @collection.all_access?, data: { action: "change->toggle-class#toggle" } %>
|
||||
<span class="switch__btn round"></span>
|
||||
<span class="for-screen-reader">Give everyone access to this project</span>
|
||||
</label>
|
||||
</li>
|
||||
<label for="collection_all_access" class="switch">
|
||||
<%= form.check_box :all_access, class: "switch__input", checked: @collection.all_access?, data: { action: "change->toggle-class#toggle" } %>
|
||||
<span class="switch__btn round"></span>
|
||||
<span class="for-screen-reader">Give everyone access to this project</span>
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<hr class="separator--horizontal full-width" style="--border-color: var(--color-subtle-dark);" aria-hidden="true" />
|
||||
<hr class="separator--horizontal margin-inline" style="--border-color: var(--color-subtle-dark);" aria-hidden="true" />
|
||||
|
||||
<% if User.active.count > 20 %>
|
||||
<input placeholder="Filter…" class="input input--transparent full-width" type="search" autocorrect="off" autocomplete="off" data-1p-ignore="true" data-action="input->filter#filter">
|
||||
<% end %>
|
||||
|
||||
<div data-filter-target="list">
|
||||
<%= access_toggles_for @selected_users, selected: true %>
|
||||
|
||||
<% if @selected_users.any? && @unselected_users.any? %>
|
||||
<hr class="separator full-width" style="--border-style: solid">
|
||||
<% if User.active.count > 20 %>
|
||||
<div class="pad-inline">
|
||||
<input placeholder="Filter…" class="input input--transparent full-width" type="search" autocorrect="off" autocomplete="off" data-1p-ignore="true" data-action="input->filter#filter">
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= access_toggles_for @unselected_users, selected: false %>
|
||||
<div data-filter-target="list" class="users-list pad-inline">
|
||||
<% 20.times do %>
|
||||
<%= access_toggles_for @selected_users, selected: true %>
|
||||
<% end %>
|
||||
|
||||
<% if @selected_users.any? && @unselected_users.any? %>
|
||||
<hr class="separator full-width" style="--border-style: solid">
|
||||
<% end %>
|
||||
|
||||
<%= access_toggles_for @unselected_users, selected: false %>
|
||||
</div>
|
||||
<% end %>
|
||||
</section>
|
||||
|
||||
<button type="submit" id="log_in" class="btn btn--reversed center txt-normal">
|
||||
<%= icon_tag "check" %>
|
||||
<span>Save changes</span>
|
||||
</button>
|
||||
|
||||
<%= link_to "Cancel and go back", cards_path(collection_ids: [ @collection ]), data: { form_target: "cancel", turbo_frame: "_top" }, hidden: true %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="panel shadow center flex flex-column">
|
||||
<strong class="txt-large">Auto-Close Cards</strong>
|
||||
<label for="closure" class="margin-block-end">Cards automatically close when there is no activity for…</label>
|
||||
<%= select_tag :closure, options_for_select(Card::Closeable::AUTO_CLOSE_OPTIONS, Card::Closeable::AUTO_CLOSE_AFTER), { class: "input input--select full-width margin-block-end", data: { action: "change->form#submit" } } %>
|
||||
|
||||
<hr class="separator--horizontal full-width margin-block" style="--border-color: var(--color-subtle);" aria-hidden="true" />
|
||||
|
||||
<strong class="txt-large">Workflows</strong>
|
||||
<div class="flex justify-center margin-block-end">Use a Workflow to track progress in this Collection.</div>
|
||||
<div class="flex flex-wrap gap">
|
||||
<% Workflow.all.each do |workflow| %>
|
||||
<div class="workflow-preview txt-align-start border border-radius <%= 'workflow-preview--selected' if workflow == @collection.workflow %>">
|
||||
<%= button_to collection_workflow_path(@collection), method: :patch do %>
|
||||
<%= hidden_field_tag "collection[workflow_id]", workflow.id %>
|
||||
<strong class="txt-small overflow-ellipsis"><%= workflow.name %></strong>
|
||||
<ul class="list-style-none txt-xx-small ">
|
||||
<% workflow.stages.each do |stage| %>
|
||||
<li class="overflow-ellipsis flex align-center gap-half min-width">
|
||||
<span class="workflow-preview__swatch btn btn--circle" style="--btn-background: <%= stage.color.present? ? stage.color : Card::Colored::DEFAULT_COLOR %>;"></span>
|
||||
<span class="overflow-ellipsis"><%= stage.name %></span>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</section>
|
||||
</div>
|
||||
<p><%= link_to "Manage workflows", workflows_path, class: "btn btn--plain txt-link" %></p>
|
||||
|
||||
<button type="submit" id="log_in" class="btn btn--reversed center txt-medium">
|
||||
<%= icon_tag "check" %>
|
||||
<span class="for-screen-reader">Save</span>
|
||||
</button>
|
||||
<hr class="separator--horizontal full-width" style="--border-color: var(--color-subtle); margin-block-start: auto;" aria-hidden="true" />
|
||||
|
||||
<%= link_to "Cancel and go back", cards_path(collection_ids: [ @collection ]), data: { form_target: "cancel", turbo_frame: "_top" }, hidden: true %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="panel shadow center flex flex-column gap-half margin-block-double" style="--panel-size: 55ch;">
|
||||
<strong class="txt-large">Choose a workflow</strong>
|
||||
<p class="margin-none">Use a workflow to track progress in this collection.</p>
|
||||
<%= form_with model: @collection, url: collection_workflow_path(@collection), local: true, method: :patch, data: { controller: "form" } do |form| %>
|
||||
<%= form.select :workflow_id, Workflow.all.map { |w| [w.name, w.id] }, { include_blank: "Choose…" }, class: "input input--select full-width", data: { action: "change->form#submit" } %>
|
||||
<% end %>
|
||||
<p><%= link_to "Manage workflows", workflows_path, class: "btn btn--plain txt-link" %></p>
|
||||
</div>
|
||||
<%= form_with model: @collection, class: "txt-align-center", method: :delete do |form| %>
|
||||
<%= form.button class: "btn txt-negative borderless txt-small", data: { turbo_confirm: "Are you sure you want to permanently delete this Collection?" } do %>
|
||||
<%= icon_tag "trash" %>
|
||||
<span>Delete this Collection</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<div class="flex gap-half align-center">
|
||||
<div class="flex gap-half align-center min-width max-width">
|
||||
<%= render "workflows/stages/color", stage: stage %>
|
||||
|
||||
<%= turbo_frame_tag stage do %>
|
||||
<%= link_to edit_workflow_stage_path(stage.workflow, stage) do %>
|
||||
<strong class="txt-nowrap overflow-ellipsis"><%= stage.name %></strong>
|
||||
<%= link_to edit_workflow_stage_path(stage.workflow, stage), class: "txt-link overflow-ellipsis" do %>
|
||||
<strong><%= stage.name %></strong>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
Reference in New Issue
Block a user