Rename Project to Bucket
This commit is contained in:
@@ -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;
|
||||
@@ -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,5 +1,5 @@
|
||||
class BoostsController < ApplicationController
|
||||
include BubbleScoped, ProjectScoped
|
||||
include BubbleScoped, BucketScoped
|
||||
|
||||
def create
|
||||
@bubble.boosts.create!
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
module BucketsHelper
|
||||
end
|
||||
@@ -1,2 +0,0 @@
|
||||
module ProjectsHelper
|
||||
end
|
||||
@@ -1,4 +1,4 @@
|
||||
class Access < ApplicationRecord
|
||||
belongs_to :project
|
||||
belongs_to :bucket
|
||||
belongs_to :user
|
||||
end
|
||||
|
||||
@@ -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,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
@@ -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,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,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? %>
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
|
||||
@@ -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,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 %>
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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>
|
||||
@@ -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 %>
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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…" %>
|
||||
|
||||
|
||||
@@ -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 %>
|
||||
@@ -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,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
@@ -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
@@ -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
-1
@@ -1,6 +1,6 @@
|
||||
require "test_helper"
|
||||
|
||||
class ProjectsControllerTest < ActionDispatch::IntegrationTest
|
||||
class BucketsControllerTest < ActionDispatch::IntegrationTest
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
Vendored
+3
-3
@@ -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
|
||||
|
||||
Vendored
+3
-3
@@ -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
|
||||
Reference in New Issue
Block a user