Rename Project to Bucket

This commit is contained in:
Jeffrey Hardy
2024-09-24 15:32:44 -04:00
parent e6bb6ad76b
commit 4e579e5a34
50 changed files with 194 additions and 186 deletions
@@ -1,4 +1,4 @@
.projects {
.buckets {
--gap: 2cqi;
--hover-size: 0;
--column-gap: var(--gap);
@@ -8,7 +8,7 @@
padding: var(--gap);
}
.project__windshield {
.bucket__windshield {
--border-radius: 1.5em;
margin-block: 0;
+3 -3
View File
@@ -1,16 +1,16 @@
class AssignmentsController < ApplicationController
include BubbleScoped, ProjectScoped
include BubbleScoped, BucketScoped
before_action :set_assignment, only: :update
def create
@assignment = @bubble.assignments.create!(assignment_params)
redirect_to project_bubble_url(@project, @bubble)
redirect_to bucket_bubble_url(@bucket, @bubble)
end
def update
@assignment.update!(assignment_params)
redirect_to project_bubble_url(@project, @bubble)
redirect_to bucket_bubble_url(@bucket, @bubble)
end
private
+1 -1
View File
@@ -1,5 +1,5 @@
class BoostsController < ApplicationController
include BubbleScoped, ProjectScoped
include BubbleScoped, BucketScoped
def create
@bubble.boosts.create!
+2 -2
View File
@@ -1,8 +1,8 @@
class Bubbles::ImagesController < ApplicationController
include BubbleScoped, ProjectScoped
include BubbleScoped, BucketScoped
def destroy
@bubble.image.purge_later
redirect_to project_bubble_url(@bubble.project, @bubble)
redirect_to bucket_bubble_url(@bubble.bucket, @bubble)
end
end
+8 -8
View File
@@ -1,5 +1,5 @@
class BubblesController < ApplicationController
include ProjectScoped
include BucketScoped
before_action :set_bubble, only: %i[ show edit update ]
@@ -9,18 +9,18 @@ class BubblesController < ApplicationController
@bubbles = @tag.bubbles
@most_active_bubbles = @tag.bubbles.left_joins(:comments, :boosts).group(:id).order(Arel.sql("COUNT(comments.id) + COUNT(boosts.id) DESC")).limit(10)
else
@bubbles = @project.bubbles.order(created_at: :desc)
@most_active_bubbles = @project.bubbles.left_joins(:comments, :boosts).group(:id).order(Arel.sql("COUNT(comments.id) + COUNT(boosts.id) DESC")).limit(10)
@bubbles = @bucket.bubbles.order(created_at: :desc)
@most_active_bubbles = @bucket.bubbles.left_joins(:comments, :boosts).group(:id).order(Arel.sql("COUNT(comments.id) + COUNT(boosts.id) DESC")).limit(10)
end
end
def new
@bubble = @project.bubbles.build
@bubble = @bucket.bubbles.build
end
def create
@bubble = @project.bubbles.create!(bubble_params)
redirect_to project_bubble_url(@project, @bubble)
@bubble = @bucket.bubbles.create!(bubble_params)
redirect_to bucket_bubble_url(@bucket, @bubble)
end
def show
@@ -31,13 +31,13 @@ class BubblesController < ApplicationController
def update
@bubble.update!(bubble_params)
redirect_to project_bubble_url(@project, @bubble)
redirect_to bucket_bubble_url(@bucket, @bubble)
end
private
def set_bubble
@bubble = @project.bubbles.find(params[:id])
@bubble = @bucket.bubbles.find(params[:id])
end
def bubble_params
@@ -0,0 +1,17 @@
class Buckets::AccessesController < ApplicationController
include BucketScoped
def edit
@users = @bucket.users
end
def update
@bucket.update_access [ Current.user, *find_users ]
redirect_to edit_bucket_access_url(@bucket)
end
private
def find_users
Current.account.users.active.where(id: params[:user_ids])
end
end
+38
View File
@@ -0,0 +1,38 @@
class BucketsController < ApplicationController
before_action :set_bucket, except: %i[ index new create ]
def index
@buckets = Current.user.buckets.all
end
def new
@bucket = Current.account.buckets.build
end
def create
@bucket = Current.account.buckets.create!(bucket_params)
redirect_to bucket_bubbles_url(@bucket)
end
def edit
end
def update
@bucket.update!(bucket_params)
redirect_to bucket_bubbles_url(@bucket)
end
def destroy
@bucket.destroy
redirect_to buckets_url
end
private
def set_bucket
@bucket = Current.user.buckets.find(params[:id])
end
def bucket_params
params.require(:bucket).permit(:name)
end
end
+2 -2
View File
@@ -1,9 +1,9 @@
class CommentsController < ApplicationController
include BubbleScoped, ProjectScoped
include BubbleScoped, BucketScoped
def create
@bubble.comments.create!(comment_params)
redirect_to project_bubble_url(@project, @bubble)
redirect_to bucket_bubble_url(@bucket, @bubble)
end
private
+1 -1
View File
@@ -7,6 +7,6 @@ module BubbleScoped
private
def set_bubble
@bubble = @project.bubbles.find(params[:bubble_id])
@bubble = @bucket.bubbles.find(params[:bubble_id])
end
end
+12
View File
@@ -0,0 +1,12 @@
module BucketScoped
extend ActiveSupport::Concern
included do
before_action :set_bucket
end
private
def set_bucket
@bucket = Current.user.buckets.find(params[:bucket_id])
end
end
@@ -1,12 +0,0 @@
module ProjectScoped
extend ActiveSupport::Concern
included do
before_action :set_project
end
private
def set_project
@project = Current.user.projects.find(params[:project_id])
end
end
@@ -1,17 +0,0 @@
class Projects::AccessesController < ApplicationController
include ProjectScoped
def edit
@users = @project.users
end
def update
@project.update_access [ Current.user, *find_users ]
redirect_to edit_project_access_url(@project)
end
private
def find_users
Current.account.users.active.where(id: params[:user_ids])
end
end
-38
View File
@@ -1,38 +0,0 @@
class ProjectsController < ApplicationController
before_action :set_project, except: %i[ index new create ]
def index
@projects = Current.user.projects.all
end
def new
@project = Current.account.projects.build
end
def create
@project = Current.account.projects.create!(project_params)
redirect_to project_bubbles_url(@project)
end
def edit
end
def update
@project.update!(project_params)
redirect_to project_bubbles_url(@project)
end
def destroy
@project.destroy
redirect_to projects_url
end
private
def set_project
@project = Current.user.projects.find(params[:id])
end
def project_params
params.require(:project).permit(:name)
end
end
+4 -4
View File
@@ -1,5 +1,5 @@
class TagsController < ApplicationController
include ProjectScoped
include BucketScoped
before_action :set_bubble, only: %i[ new create ]
before_action :set_tag, only: :destroy
@@ -13,12 +13,12 @@ class TagsController < ApplicationController
def create
@bubble.tags << Tag.find_or_create_by!(tag_params)
redirect_to project_bubble_url(@project, @bubble)
redirect_to bucket_bubble_url(@bucket, @bubble)
end
def destroy
@tag.destroy
redirect_to project_tags_url(@project)
redirect_to bucket_tags_url(@bucket)
end
private
@@ -31,6 +31,6 @@ class TagsController < ApplicationController
end
def set_bubble
@bubble = @project.bubbles.find(params[:bubble_id])
@bubble = @bucket.bubbles.find(params[:bubble_id])
end
end
+2
View File
@@ -0,0 +1,2 @@
module BucketsHelper
end
-2
View File
@@ -1,2 +0,0 @@
module ProjectsHelper
end
+1 -1
View File
@@ -1,4 +1,4 @@
class Access < ApplicationRecord
belongs_to :project
belongs_to :bucket
belongs_to :user
end
+2 -2
View File
@@ -3,6 +3,6 @@ class Account < ApplicationRecord
has_many :users, dependent: :destroy
has_many :projects, dependent: :destroy
has_many :bubbles, through: :projects
has_many :buckets, dependent: :destroy
has_many :bubbles, through: :buckets
end
+1 -1
View File
@@ -1,7 +1,7 @@
class Bubble < ApplicationRecord
include Colored
belongs_to :project
belongs_to :bucket
belongs_to :creator, class_name: "User", default: -> { Current.user }
has_many :comments, dependent: :destroy
@@ -1,4 +1,4 @@
class Project < ApplicationRecord
class Bucket < ApplicationRecord
include Accessible
belongs_to :account
@@ -1,4 +1,4 @@
module Project::Accessible
module Bucket::Accessible
extend ActiveSupport::Concern
included do
+2 -2
View File
@@ -5,8 +5,8 @@ class User < ApplicationRecord
has_secure_password validations: false
has_many :accesses, dependent: :destroy
has_many :projects, through: :accesses
has_many :bubbles, through: :projects
has_many :buckets, through: :accesses
has_many :bubbles, through: :buckets
has_many :assignments
has_many :assigned_bubbles, through: :assignments, source: :bubble
+1 -1
View File
@@ -1,4 +1,4 @@
<%= button_to project_bubble_boosts_path(bubble.project, bubble),
<%= button_to bucket_bubble_boosts_path(bubble.bucket, bubble),
class: "btn btn--plain",
data: { action: "toggle-class#toggle" },
form_class: "full-width" do %>
+1 -1
View File
@@ -1,5 +1,5 @@
<span class="bubble__bubble bubble__meta bubble__assignee <%= "bubble__assignee--new" if bubble.assignees.none? %>">
<%= form_with model: Assignment.new, url: project_bubble_assignments_path(bubble.project, bubble), data: { controller: "form" } do |form| %>
<%= form_with model: Assignment.new, url: bucket_bubble_assignments_path(bubble.bucket, bubble), data: { controller: "form" } do |form| %>
<label class="btn btn--plain position-relative fill-transparent" style="--btn-icon-size: 2em;">
<% if bubble.assignees.any? %>
<% if bubble.assignees.many? %>
+2 -2
View File
@@ -4,7 +4,7 @@
<h1 class="bubble__title">
<%= turbo_frame_tag bubble, :edit do %>
<%= link_to bubble.title, edit_project_bubble_path(bubble.project, bubble), class: "txt-undecorated" %>
<%= link_to bubble.title, edit_bucket_bubble_path(bubble.bucket, bubble), class: "txt-undecorated" %>
<% end %>
</h1>
@@ -13,7 +13,7 @@
<path d="m391.65 879.47c-110.52-15.95-212.21-91.86-255.92-191.23-66.78-143.65-41.62-347.61 48.08-481.17 368.33-516.3 1252.97 520.2 451.03 660.78-44.07 8.84-88.98 13.49-133.01 15.68-36.69 2-73.37 1.91-109.99-4.03z"/>
</svg>
<%= link_to project_bubble_path(bubble.project, bubble), class: "bubble__link" do %>
<%= link_to bucket_bubble_path(bubble.bucket, bubble), class: "bubble__link" do %>
<span class="for-screen-reader"><%= bubble.title %></span>
<% end %>
+1 -1
View File
@@ -5,7 +5,7 @@
</button>
<dialog class="bubble__color-picker" data-dialog-target="dialog">
<%= form_with model: bubble, url: project_bubble_path(bubble.project, bubble), data: { controller: "form", action: "change->form#submit" } do |form| %>
<%= form_with model: bubble, url: bucket_bubble_path(bubble.bucket, bubble), data: { controller: "form", action: "change->form#submit" } do |form| %>
<% Bubble::COLORS.each do |color| %>
<span class="bubble__color-picker__color">
<label class="btn btn--circle" style="--btn-background: <%= color %>" title="<%= color %>">
+1 -1
View File
@@ -1,4 +1,4 @@
<%= form_with model: bubble, url: project_bubble_path(bubble.project, bubble), data: { controller: "form" } do |form| %>
<%= form_with model: bubble, url: bucket_bubble_path(bubble.bucket, bubble), data: { controller: "form" } do |form| %>
<% if bubble.due_on.present? %>
<label class="bubble__bubble bubble__meta bubble__date">
<%= bubble.due_on.strftime("%b <br> %d").html_safe %>
+2 -2
View File
@@ -4,12 +4,12 @@
<div class="bubble__bubble bubble__meta bubble__attachment">
<% if bubble.image.attached? %>
<%= button_to project_bubble_image_path(bubble.project, bubble), method: :delete, class: "btn btn--plain", style: "--btn-icon-size: 3em; margin-block-start: -0.5em; margin-inline-end: -0.2em" do %>
<%= button_to bucket_bubble_image_path(bubble.bucket, bubble), method: :delete, class: "btn btn--plain", style: "--btn-icon-size: 3em; margin-block-start: -0.5em; margin-inline-end: -0.2em" do %>
<svg viewBox="0 0 24 20" xmlns="http://www.w3.org/2000/svg" fill="var(--bubble-color)"><path fill="var(--color-negative)" d="m19.1 0c-2.8 0-5 2.2-5 5s2.2 5 5 5 5-2.2 5-5-2.2-5-5-5zm-.8 5.7h-1.2c-.3 0-.6-.3-.6-.6s.3-.6.6-.6h1.2s1.6 0 1.6 0h1.2c.3 0 .6.3.6.6s-.3.6-.6.6h-1.2s-1.6 0-1.6 0z"/><path d="m6.7 10.5c.9 0 1.6-.7 1.6-1.6s-.7-1.6-1.6-1.6-1.6.7-1.6 1.6.7 1.6 1.6 1.6z" fill="none"/><path d="m9.7 16.9h.1l-.1-.1z"/><path d="m19.2 11.6v6.3c0 .2 0 .4-.4.4h-16.8v-13.7c0-.2 0-.4.4-.4h10.1c0-.7.3-1.3.5-1.8h-11.6c-.9.2-1.4.9-1.4 1.8v14c0 1 .8 1.8 1.8 1.8h17.5c1 0 1.8-.8 1.8-1.8v-6.9c-.6.2-1.2.3-1.8.3z"/><path d="m4.8 5.5c-.7 0-1.3.6-1.3 1.3v8.9c0 .4.2.7.5 1l2.6-3.5c.2-.3.6-.5.9-.5s0 0 0 0c.4 0 .7.2.9.5l.9 1.3 2.3-3.5c.3-.4.8-.7 1.3-.7s0 0 0 0c.5 0 1 .3 1.3.7l3.1 5c0-.1 0-.2 0-.3v-4.2c-2.8-.6-4.9-3-5.1-6h-7.6zm1.9 5c-.9 0-1.6-.7-1.6-1.6s.7-1.6 1.6-1.6 1.6.7 1.6 1.6-.7 1.6-1.6 1.6z"/><path d="m5.2 16.9h2.6l1-1.5-1.2-1.7z"/><path d="m10.4 15.8-.7 1 .1.1h1.3 5.1l-3.1-5.1z"/></svg>
<span class="for-screen-reader">Remove image</span>
<% end %>
<% else %>
<%= form_with model: bubble, url: project_bubble_path(bubble.project, bubble), data: { controller: "form" } do |form| %>
<%= form_with model: bubble, url: bucket_bubble_path(bubble.bucket, bubble), data: { controller: "form" } do |form| %>
<label class="btn btn--plain input--file" style="--btn-icon-size: 3em; margin-block-start: -0.5em; margin-inline-end: -0.2em">
<svg viewBox="0 0 24 20" xmlns="http://www.w3.org/2000/svg" fill="var(--bubble-color)"><path fill="var(--color-positive)" d="m19.1 0c-2.8 0-5 2.2-5 5s2.2 5 5 5 5-2.2 5-5-2.2-5-5-5zm-.1 2.5c.3 0 .6.3.6.6v1.2c0 .2 0 .2.2.2h1.2c.3 0 .6.3.6.6s-.3.6-.6.6h-1.2c-.2 0-.2 0-.2.2v1.2c0 .3-.3.6-.6.6s-.6-.3-.6-.6v-1.2c0-.2 0-.2-.2-.2h-1.2c-.3 0-.6-.3-.6-.6s.3-.6.6-.6h1.2c.2 0 .2 0 .2-.2v-1.2c0-.3.3-.6.6-.6z"/><path d="m6.7 10.5c.9 0 1.6-.7 1.6-1.6s-.7-1.6-1.6-1.6-1.6.7-1.6 1.6.7 1.6 1.6 1.6z" fill="none"/><path d="m9.7 16.9h.1l-.1-.1z"/><path d="m19.2 11.6v6.3c0 .2 0 .4-.4.4h-16.8v-13.7c0-.2 0-.4.4-.4h10.1c0-.7.3-1.3.5-1.8h-11.6c-.9.2-1.4.9-1.4 1.8v14c0 1 .8 1.8 1.8 1.8h17.5c1 0 1.8-.8 1.8-1.8v-6.9c-.6.2-1.2.3-1.8.3z"/><path d="m4.8 5.5c-.7 0-1.3.6-1.3 1.3v8.9c0 .4.2.7.5 1l2.6-3.5c.2-.3.6-.5.9-.5s0 0 0 0c.4 0 .7.2.9.5l.9 1.3 2.3-3.5c.3-.4.8-.7 1.3-.7s0 0 0 0c.5 0 1 .3 1.3.7l3.1 5c0-.1 0-.2 0-.3v-4.2c-2.8-.6-4.9-3-5.1-6h-7.6zm1.9 5c-.9 0-1.6-.7-1.6-1.6s.7-1.6 1.6-1.6 1.6.7 1.6 1.6-.7 1.6-1.6 1.6z"/><path d="m5.2 16.9h2.6l1-1.5-1.2-1.7z"/><path d="m10.4 15.8-.7 1 .1.1h1.3 5.1l-3.1-5.1z"/></svg>
<%= form.file_field :image, class: "input",
+2 -2
View File
@@ -1,11 +1,11 @@
<% bubble.tags.each do |tag| %>
<%= link_to "##{tag.title}", project_bubbles_path(bubble.project, tag_id: tag), class: "bubble__bubble bubble__meta bubble__tag" %>
<%= link_to "##{tag.title}", bucket_bubbles_path(bubble.bucket, tag_id: tag), class: "bubble__bubble bubble__meta bubble__tag" %>
<% end %>
<% if bubble.tags.size < 3 %>
<span class="bubble__bubble bubble__meta bubble__tag">
<%= turbo_frame_tag :new_tag do %>
<%= link_to "#", new_project_bubble_tag_path(bubble.project, bubble), class: "bubble__tag--new" %>
<%= link_to "#", new_bucket_bubble_tag_path(bubble.bucket, bubble), class: "bubble__tag--new" %>
<% end %>
</span>
<% end %>
+2 -2
View File
@@ -1,5 +1,5 @@
<%= turbo_frame_tag @bubble, :edit do %>
<%= form_with model: @bubble, url: project_bubble_path(@bubble.project, @bubble), class: "flex flex-column gap full-width", data: { controller: "form" } do |form| %>
<%= form_with model: @bubble, url: bucket_bubble_path(@bubble.bucket, @bubble), class: "flex flex-column gap full-width", data: { controller: "form" } do |form| %>
<%= form.label :title, class: "flex flex-column justify-center align-center" do %>
<%= form.text_area :title, class: "input input--textara txt-align-center full-width borderless",
required: true, rows: 5, autofocus: true, placeholder: "Name it…",
@@ -7,6 +7,6 @@
style: "color: var(--spat-color); --input-border-radius: 0" %>
<% end %>
<%= form.submit "Save", hidden: true %>
<%= link_to "Close editor and discard changes", project_bubble_path(@bubble.project, @bubble), data: { form_target: "cancel" }, hidden: true %>
<%= link_to "Close editor and discard changes", bucket_bubble_path(@bubble.bucket, @bubble), data: { form_target: "cancel" }, hidden: true %>
<% end %>
<% end %>
+7 -7
View File
@@ -1,33 +1,33 @@
<% @page_title = @project.name %>
<% @page_title = @bucket.name %>
<% content_for :header do %>
<nav>
<%= link_to projects_path, class: "btn flex-item-justify-start" do %>
<%= link_to buckets_path, class: "btn flex-item-justify-start" do %>
<%= image_tag "grid.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Projects</span>
<span class="for-screen-reader">Buckets</span>
<% end %>
<h1 class="txt-xx-large margin-none flex align-center gap-half">
Bubbled up in <%= @project.name %>
Bubbled up in <%= @bucket.name %>
<% if @tag %>
tagged <%= @tag.title %>
<%= link_to project_bubbles_path(@project), class: "btn txt-small" do %>
<%= link_to bucket_bubbles_path(@bucket), class: "btn txt-small" do %>
<%= image_tag "remove.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Clear</span>
<% end %>
<% end %>
</h1>
<%= button_to project_bubbles_path(@project), method: :post, params: { bubble: { title: "Untitled"} }, class: "btn btn--plain", form_class: "flex-item-justify-end" do %>
<%= button_to bucket_bubbles_path(@bucket), method: :post, params: { bubble: { title: "Untitled"} }, class: "btn btn--plain", form_class: "flex-item-justify-end" do %>
<%= image_tag "bubble-add.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Create a new bubble</span>
<% end %>
</nav>
<% end %>
<section class="windshield flex-inline flex-wrap gap justify-center align-end" style="view-transition-name: windshield_<%= @project.id %>">
<section class="windshield flex-inline flex-wrap gap justify-center align-end" style="view-transition-name: windshield_<%= @bucket.id %>">
<%= render @most_active_bubbles %>
</section>
+2 -2
View File
@@ -6,13 +6,13 @@
</svg>
</div>
<%= link_to project_bubble_path(bubble.project, bubble), class: "bubble__title-link flex align-center gap flex-item-grow min-width" do %>
<%= link_to bucket_bubble_path(bubble.bucket, bubble), class: "bubble__title-link flex align-center gap flex-item-grow min-width" do %>
<strong class="bubble__title-text flex--inline gap-half overflow-ellipsis"><%= bubble.title %></strong>
<% end %>
<small class="flex align-center gap flex-item-no-shrink">
<% bubble.tags.each do |tag| %>
<%= link_to "##{tag.title}", project_bubbles_path(bubble.project, tag_id: tag.id), style: "color: #{bubble.color}" %>
<%= link_to "##{tag.title}", bucket_bubbles_path(bubble.bucket, tag_id: tag.id), style: "color: #{bubble.color}" %>
<% end %>
<%= tag.time bubble.created_at, class: "txt-nowrap flex-item-justify-end" do %>
+1 -1
View File
@@ -2,7 +2,7 @@
<% content_for :header do %>
<nav>
<%= link_to project_bubbles_path(@bubble.project), class: "btn flex-item-justify-start" do %>
<%= link_to bucket_bubbles_path(@bubble.bucket), class: "btn flex-item-justify-start" do %>
<%= image_tag "arrow-left.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">All Bubbles</span>
<% end %>
+14
View File
@@ -0,0 +1,14 @@
<h1>Users on <%= @bucket.name %></h1>
<%= form_with url: bucket_access_path, method: :put do |form| %>
<ul>
<% Current.account.users.active.each do |user| %>
<li>
<%= check_box_tag "user_ids[]", user.id, @bucket.users.include?(user), id: nil, disabled: user == Current.user %>
<%= user.name %>
</li>
<% end %>
</ul>
<%= form.submit %>
<% end %>
@@ -1,6 +1,6 @@
<h1>Edit Project</h1>
<h1>Edit Bucket</h1>
<%= form_with model: @project do |form| %>
<%= form_with model: @bucket do |form| %>
<p>Name:<br><%= form.text_field :name %></p>
<p><%= form.submit %>
<% end %>
@@ -1,4 +1,4 @@
<% @page_title = "Projects" %>
<% @page_title = "Buckets" %>
<% content_for :header do %>
<nav>
@@ -7,19 +7,19 @@
<span class="for-screen-reader">Sign out</span>
<% end %>
<%= link_to new_project_path, class: "btn flex-item-justify-end" do %>
<%= link_to new_bucket_path, class: "btn flex-item-justify-end" do %>
<%= image_tag "add.svg", aria: { hidden: true }, size: 24 %>
<span class="for-screen-reader">Add a new project</span>
<span class="for-screen-reader">Add a new bucket</span>
<% end %>
</nav>
<% end %>
<menu class="projects margin-none unpad align-center justify-center flex flex-wrap gap">
<% @projects.each do |project| %>
<li class="project flex flex-column txt-align-center gap-half max-width">
<%= link_to project_bubbles_path(project), class: "windshield__container border-radius border flex justify-center align-center position-relative" do %>
<div class="windshield project__windshield flex flex-wrap gap justify-center align-end" style="view-transition-name: windshield_<%= project.id %>">
<% project.bubbles.left_joins(:comments, :boosts).group(:id).order(Arel.sql("COUNT(comments.id) + COUNT(boosts.id) DESC")).limit(10).each do |bubble| %>
<menu class="buckets margin-none unpad align-center justify-center flex flex-wrap gap">
<% @buckets.each do |bucket| %>
<li class="bucket flex flex-column txt-align-center gap-half max-width">
<%= link_to bucket_bubbles_path(bucket), class: "windshield__container border-radius border flex justify-center align-center position-relative" do %>
<div class="windshield bucket__windshield flex flex-wrap gap justify-center align-end" style="view-transition-name: windshield_<%= bucket.id %>">
<% bucket.bubbles.left_joins(:comments, :boosts).group(:id).order(Arel.sql("COUNT(comments.id) + COUNT(boosts.id) DESC")).limit(10).each do |bubble| %>
<div class="bubble" style="--bubble-color: <%= bubble.color %>; <%= bubble_rotation(bubble) %> <%= bubble_size(bubble) %>">
<svg class="bubble__svg" style="fill: <%= bubble.color %>; stroke: <%= bubble.color %>;" viewBox="0 0 990 990" xmlns="http://www.w3.org/2000/svg">
<path d="m0 0h990v990h-990z" fill="none" stroke="none" />
@@ -29,7 +29,7 @@
<% end %>
</div>
<% end %>
<strong><%= link_to project.name, project_bubbles_path(project), class: "txt-large txt-ink" %></strong>
<strong><%= link_to bucket.name, bucket_bubbles_path(bucket), class: "txt-large txt-ink" %></strong>
</li>
<% end %>
</menu>
+8
View File
@@ -0,0 +1,8 @@
<% @page_title = "Create a new bucket" %>
<h1>New Bucket</h1>
<%= form_with model: @bucket do |form| %>
<p>Name:<br><%= form.text_field :name %></p>
<p><%= form.submit %>
<% end %>
+1 -1
View File
@@ -4,7 +4,7 @@
<div class="comment__content flex flex-column full-width fill-shade border-radius">
<div class="comment__author flex align-center gap-half">
<strong><%= comment.creator.name %></strong>
<%= link_to project_bubble_path(comment.bubble.project, comment.bubble, anchor: "comment_#{comment.id}"), class: "txt-undecorated" do %>
<%= link_to bucket_bubble_path(comment.bubble.bucket, comment.bubble, anchor: "comment_#{comment.id}"), class: "txt-undecorated" do %>
<%= tag.time comment.created_at, class: "comment__timestamp" do %>
<%= comment.created_at.strftime("%b %d") %>
<% end %>
+1 -1
View File
@@ -6,7 +6,7 @@
<strong><%= Current.user.name %></strong>
</div>
<div class="comment__body txt-align-start margin-block-start-half">
<%= form_with model: Comment.new, url: project_bubble_comments_path(bubble.project, bubble), class: "flex flex-column gap full-width" do |form| %>
<%= form_with model: Comment.new, url: bucket_bubble_comments_path(bubble.bucket, bubble), class: "flex flex-column gap full-width" do |form| %>
<%= form.text_area :body, class: "input", required: true, rows: 4,
placeholder: (bubble.comments.empty? && bubble.creator == Current.user) ? "Add some notes…" : "Type your comment…" %>
-14
View File
@@ -1,14 +0,0 @@
<h1>Users on <%= @project.name %></h1>
<%= form_with url: project_access_path, method: :put do |form| %>
<ul>
<% Current.account.users.active.each do |user| %>
<li>
<%= check_box_tag "user_ids[]", user.id, @project.users.include?(user), id: nil, disabled: user == Current.user %>
<%= user.name %>
</li>
<% end %>
</ul>
<%= form.submit %>
<% end %>
-8
View File
@@ -1,8 +0,0 @@
<% @page_title = "Create a new project" %>
<h1>New Project</h1>
<%= form_with model: @project do |form| %>
<p>Name:<br><%= form.text_field :name %></p>
<p><%= form.submit %>
<% end %>
+1 -1
View File
@@ -1,5 +1,5 @@
<%= turbo_frame_tag :new_tag do %>
<%= form_with model: Tag.new, url: project_bubble_tags_path(@bubble.project, @bubble), data: { turbo_frame: "_top" } do |form| %>
<%= form_with model: Tag.new, url: bucket_bubble_tags_path(@bubble.bucket, @bubble), data: { turbo_frame: "_top" } do |form| %>
<%= form.text_field :title, class: "input borderless", autofocus: "on", list: "tags-list" %>
<%= form.submit "Create Tag", hidden: true %>
+3 -3
View File
@@ -1,5 +1,5 @@
Rails.application.routes.draw do
root "projects#index"
root "buckets#index"
resource :session
@@ -16,8 +16,8 @@ Rails.application.routes.draw do
resources :users
resources :projects do
resource :access, controller: "projects/accesses"
resources :buckets do
resource :access, controller: "buckets/accesses"
resources :bubbles do
resource :image, controller: "bubbles/images"
@@ -0,0 +1,8 @@
class RenameProjectToBucket < ActiveRecord::Migration[8.0]
def change
rename_table :projects, :buckets
rename_column :accesses, :project_id, :bucket_id
rename_column :bubbles, :project_id, :bucket_id
end
end
Generated
+16 -16
View File
@@ -10,14 +10,14 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2024_09_19_191155) do
ActiveRecord::Schema[8.0].define(version: 2024_09_24_191654) do
create_table "accesses", force: :cascade do |t|
t.integer "project_id", null: false
t.integer "bucket_id", null: false
t.integer "user_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["project_id", "user_id"], name: "index_accesses_on_project_id_and_user_id", unique: true
t.index ["project_id"], name: "index_accesses_on_project_id"
t.index ["bucket_id", "user_id"], name: "index_accesses_on_bucket_id_and_user_id", unique: true
t.index ["bucket_id"], name: "index_accesses_on_bucket_id"
t.index ["user_id"], name: "index_accesses_on_user_id"
end
@@ -82,8 +82,18 @@ ActiveRecord::Schema[8.0].define(version: 2024_09_19_191155) do
t.datetime "updated_at", null: false
t.integer "creator_id", null: false
t.date "due_on"
t.integer "project_id", null: false
t.index ["project_id"], name: "index_bubbles_on_project_id"
t.integer "bucket_id", null: false
t.index ["bucket_id"], name: "index_bubbles_on_bucket_id"
end
create_table "buckets", force: :cascade do |t|
t.integer "account_id", null: false
t.integer "creator_id", null: false
t.string "name", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["account_id"], name: "index_buckets_on_account_id"
t.index ["creator_id"], name: "index_buckets_on_creator_id"
end
create_table "comments", force: :cascade do |t|
@@ -94,16 +104,6 @@ ActiveRecord::Schema[8.0].define(version: 2024_09_19_191155) do
t.datetime "updated_at", null: false
end
create_table "projects", force: :cascade do |t|
t.integer "account_id", null: false
t.integer "creator_id", null: false
t.string "name", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["account_id"], name: "index_projects_on_account_id"
t.index ["creator_id"], name: "index_projects_on_creator_id"
end
create_table "sessions", force: :cascade do |t|
t.integer "user_id", null: false
t.string "ip_address"
@@ -1,6 +1,6 @@
require "test_helper"
class ProjectsControllerTest < ActionDispatch::IntegrationTest
class BucketsControllerTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end
+3 -3
View File
@@ -1,11 +1,11 @@
writebook_david:
project: writebook
bucket: writebook
user: david
writebook_jz:
project: writebook
bucket: writebook
user: jz
writebook_kevin:
project: writebook
bucket: writebook
user: kevin
+3 -3
View File
@@ -1,18 +1,18 @@
logo:
project: writebook
bucket: writebook
creator: david
title: The logo isn't big enough
color: "#ED8008"
due_on: <%= 3.days.from_now %>
layout:
project: writebook
bucket: writebook
creator: david
title: Layout is broken
color: "#698F9C"
text:
project: writebook
bucket: writebook
creator: kevin
title: The text is too small
color: "#3B4B59"
@@ -1,6 +1,6 @@
require "test_helper"
class ProjectTest < ActiveSupport::TestCase
class BucketTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end