Skip to content

Commit

Permalink
Update to support broadcasting list changes
Browse files Browse the repository at this point in the history
Also, change all broadcasts to use "later", which requires
removing all conditional logic from partials that isn't
available when put in a turbo stream.
  • Loading branch information
jbigler committed Mar 4, 2024
1 parent 0b99e5b commit 2d60707
Show file tree
Hide file tree
Showing 12 changed files with 56 additions and 57 deletions.
26 changes: 15 additions & 11 deletions app/controllers/cards_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,34 @@
class CardsController < ApplicationController
before_action :set_card, only: %i[show edit update destroy]
before_action :set_list, only: %i[index new create]
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized

# GET /cards or /cards.json
def index
@cards = @list.cards.rank(:row_order)
end

# GET /cards/1 or /cards/1.json
def show; end
def show
end

# GET /cards/new
def new
@card = @list.cards.new
authorize @card
@card = authorize @list.cards.new
end

# GET /cards/1/edit
def edit; end

# POST /cards or /cards.json
def create
@card = @list.cards.new(card_params)
authorize @card
@card = authorize @list.cards.new(card_params)

respond_to do |format|
if @card.save
format.turbo_stream do
elem = "cards_for_#{helpers.dom_id(@list)}"
@card.broadcast_append_to @list, :cards, target: elem, partial: "cards/card"
@card.broadcast_append_later_to @list, :cards, target: elem, partial: "cards/card"
end
format.html { redirect_to card_url(@card), notice: "Card was successfully created." }
format.json { render :show, status: :created, location: @card }
Expand All @@ -52,13 +52,13 @@ def update
format.turbo_stream do
if prev_row_order != @card.row_order
# Reload the entire list
@card.list.broadcast_replace_to @card.list.board, :lists, partial: "lists/list"
@card.list.broadcast_replace_later_to @card.list.board, :lists, partial: "lists/list"
if prev_list_id != @card.list_id
# Reload previous list as well
List.find_by(id: prev_list_id).broadcast_replace_to @card.list.board, :lists, partial: "lists/list"
List.find_by(id: prev_list_id).broadcast_replace_later_to @card.list.board, :lists, partial: "lists/list"
end
else
@card.broadcast_replace_to @card.list, :cards, partial: "cards/card"
@card.broadcast_replace_later_to @card.list, :cards, partial: "cards/card"
end

# TODO refresh affected lists
Expand Down Expand Up @@ -90,14 +90,18 @@ def destroy
private
# Use callbacks to share common setup or constraints between actions.
def set_card
@card = Card.find(params[:id])
authorize @card
@card = authorize Card.find(params[:id])
end

def set_list
@list = List.find(params[:list_id])
end

def user_not_authorized
@card = Card.find(params[:id])
render :show
end

# Only allow a list of trusted parameters through.
def card_params
params.require(:card).permit(:row_order_position, :list_id, :title, :description)
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/lists_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ def update
respond_to do |format|
if @list.update(list_params)
format.turbo_stream do
render turbo_stream: turbo_stream.update("label_#{helpers.dom_id(@list)}", @list.title)
role = Current.user.memberships.where(workspace_id: @list.board.workspace.id).first.role
@list.broadcast_replace_to @list.board, :lists, target: "lists_frame", html: %Q[<turbo-frame id="lists_frame" src="#{board_lists_url(@list.board)}" data-role="#{role}" class="contents">]
end
format.html { redirect_to list_url(@list), notice: "List was successfully updated." }
format.json { render :show, status: :ok, location: @list }
Expand Down Expand Up @@ -77,8 +78,7 @@ def update_position; end
private
# Use callbacks to share common setup or constraints between actions.
def set_list
@list = List.find(params[:id])
authorize @list
@list = authorize List.find(params[:id])
end

def set_board
Expand Down
13 changes: 8 additions & 5 deletions app/javascript/controllers/sortable_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ export default class extends Controller {
}

connect() {
this.sortable = Sortable.create(this.element, {
onEnd: this.onEnd.bind(this),
group: this.groupValue,
draggable: ".draggable"
})
var role = document.getElementById("lists_frame").dataset.role
if (role !== "viewer") {
this.sortable = Sortable.create(this.element, {
onEnd: this.onEnd.bind(this),
group: this.groupValue,
draggable: ".draggable"
})
}
}

onEnd(event) {
Expand Down
2 changes: 1 addition & 1 deletion app/policies/card_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def destroy?
end

def allowed?(permitted_roles)
role = @user.memberships.where(workspace_id: record.list.board.workspace.id).first.role
role = user.memberships.where(workspace_id: record.list.board.workspace.id).first.role
permitted_roles.include?(role)
end
end
21 changes: 3 additions & 18 deletions app/views/boards/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="h-full max-h-full flex flex-col overflow-hidden">
<div class="h-full max-h-full flex flex-col overflow-hidden" <%= 'data-admin' if policy(@board).update? %>>
<div class="self-center flex flex-row w-full gap-10 pb-2">

<button id="board-dropdown"
Expand All @@ -24,23 +24,8 @@
<% end %>
<%= link_to "Back to workspace", workspace_path(@board.workspace), class: "rounded-lg bg-blue-700 px-5 py-2.5 text-sm font-medium text-white hover:bg-blue-800 focus:outline-none focus:ring-4 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800" %>
</div>

<% role = Current.user.memberships.where(workspace_id: @board.workspace.id).first.role %>
<%= turbo_stream_from @board, :lists %>
<div id="lists"
<% if policy(@board.lists.build(title: "New List")).update? %>
data-controller="sortable"
data-sortable-type-value="list"
<% end %>
class="flex-grow max-h-full flex flex-row bg-gray-400 overflow-x-scroll">

<% @board.lists.rank(:row_order).each do |list| %>
<%= render list %>
<% end %>
<% if policy(@board.lists.build(title: "New List")).new? %>
<div id="new-list" class="min-w-72 max-w-72 p-3 m-2 bg-gray-200 border border-gray-400 rounded-lg shadow hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700 flex flex-col">
<%= link_to "+ Add New List", new_board_list_path(@board), data: { turbo_frame: "modal" }, class: "font-bold dark:text-white text-center" %>
</div>
<% end %>
</div>
<%= turbo_frame_tag "lists_frame", src: board_lists_path(@board), data: { role: role }, class: "contents" %>
<%= turbo_frame_tag "modal" %>
</div>
3 changes: 1 addition & 2 deletions app/views/cards/_card.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<% url = policy(card).update? ? edit_card_path(card) : card_path(card) %>
<li id="<%= dom_id card %>"
class="draggable"
data-sortable-update-url="<%= card_path(card) %>">
<a href="<%= url %>" data-turbo-frame="modal">
<a href="<%= edit_card_path(card) %>" data-turbo-frame="modal">
<div class="block shadow-gray-500 max-w-sm p-3 m-2 bg-white border border-gray-200 rounded-lg shadow hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700">
<p class="line-clamp-3 font-normal text-gray-700 dark:text-gray-400"><%= card.title %></p>
</div>
Expand Down
4 changes: 2 additions & 2 deletions app/views/cards/_modal_show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
</div>
</div>
<div class="flex flex-row gap-2 justify-end">
<% if card.persisted? && policy(card).destroy? %>
<%= link_to "Delete", card_path(@card), data: { turbo_method: :delete, turbo_confirm: "Are you sure?", action: "turbo-modal#hideModal" }, class: "text-white inline-flex items-center bg-red-700 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-800" %>
<% if card.persisted? %>
<%= link_to "Delete", card_path(@card), data: { turbo_method: :delete, turbo_confirm: "Are you sure?", action: "turbo-modal#hideModal" }, class: "admin:block hidden text-white inline-flex items-center bg-red-700 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-800" %>
<% end %>
<%= link_to "Close", "#", data: { action: "turbo-modal#hideModal" }, class: "text-white inline-flex items-center bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800" %>
</div>
Expand Down
13 changes: 3 additions & 10 deletions app/views/lists/_list.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,20 @@
data-sortable-update-url="<%= list_path(list) %>"
class="draggable min-w-72 max-w-72 p-3 m-2 bg-gray-200 border border-gray-400 rounded-lg shadow hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700 flex flex-col">

<% if policy(list).update? %>
<%= link_to list.title, edit_list_path(list), id: "label_#{ dom_id list}", class: "font-bold dark:text-white text-center", data: { turbo_frame: "modal" } %>
<% else %>
<p class="font-bold dark:text-white text-center"><%= list.title %></p>
<% end %>
<%= link_to list.title, edit_list_path(list), id: "label_#{ dom_id list}", class: "admin:block hidden font-bold dark:text-white text-center", data: { turbo_frame: "modal" } %>
<p class="admin:hidden block font-bold dark:text-white text-center"><%= list.title %></p>

<%= turbo_stream_from list, :cards %>
<ul id="cards_for_<%= dom_id(list) %>"
<% if policy(list.cards.build(title: "New Card")).update? %>
data-controller="sortable"
data-sortable-list-id="<%= list.id %>"
data-sortable-group-value="cards"
data-sortable-type-value="card"
<% end %>
class="list full flex-grow overflow-y-scroll">

<% list.cards.rank(:row_order).each do |card| %>
<%= render card %>
<% end %>
</ul>
<% if policy(list.cards.build(title: "New Card")).new? %>
<%= link_to "Add Card", new_list_card_path(list), data: { turbo_frame: "modal" }, class: "font-bold dark:text-white text-center" %>
<% end %>
<%= link_to "Add Card", new_list_card_path(list), data: { turbo_frame: "modal" }, class: "admin:block hidden font-bold dark:text-white text-center" %>
</div>
18 changes: 15 additions & 3 deletions app/views/lists/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,19 @@
<%= link_to "New list", new_board_list_path, class: "rounded-lg py-3 px-5 bg-blue-600 text-white block font-medium" %>
</div>

<div id="lists" class="min-w-full">
<%= render @lists %>
</div>
<% role = Current.user.memberships.where(workspace_id: @board.workspace.id).first.role %>
<%= turbo_frame_tag "lists_frame", class: "contents", data: { role: role } do %>
<div id="lists"
data-controller="sortable"
data-sortable-type-value="list"
class="flex-grow max-h-full flex flex-row bg-gray-400 overflow-x-scroll">

<% @board.lists.rank(:row_order).each do |list| %>
<%= render list %>
<% end %>
<div id="new-list" class="admin:flex flex-col hidden min-w-72 max-w-72 p-3 m-2 bg-gray-200 border border-gray-400 rounded-lg shadow hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700">
<%= link_to "+ Add New List", new_board_list_path(@board), data: { turbo_frame: "modal" }, class: "font-bold dark:text-white text-center" %>
</div>
</div>
<% end %>
</div>
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
resources :workspaces, shallow: true do
resources :members
resources :boards do
resources :lists, except: [:index] do
resources :lists do
resources :cards, except: [:index]
end
end
Expand Down
3 changes: 3 additions & 0 deletions config/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@ module.exports = {
require('@tailwindcss/aspect-ratio'),
require('@tailwindcss/typography'),
require('@tailwindcss/container-queries'),
function({ addVariant }) {
addVariant('admin', 'div[data-admin] &')
}
]
}
2 changes: 1 addition & 1 deletion test/system/cards_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class CardsTest < ApplicationSystemTestCase
setup do
@user = sign_in_as(create(:user_with_3_workspaces))
@user = sign_in_as(create(:user_with_workspace))
@workspace = @user.workspaces.first
@board = @workspace.boards.create(name: "Test Board")
@list1 = @board.lists.create(title: "First List")
Expand Down

0 comments on commit 2d60707

Please sign in to comment.