Skip to content

[Card Grants] Home page reordering #10674

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
25 changes: 25 additions & 0 deletions app/controllers/card_grants_controller.rb
Original file line number Diff line number Diff line change
@@ -58,6 +58,31 @@ def update
redirect_to card_grant_url(@card_grant)
end

def set_index
card_grant = CardGrant.find(params[:id])
authorize card_grant

index = params[:index]

# get all the card grants as an array
card_grants = StaticPageService::Index.new(current_user:).card_grants.not_hidden.to_a

return head status: :bad_request if index < 0 || index >= card_grants.size

# switch the position *in the in-memory array*
card_grants.delete card_grant
card_grants.insert index, card_grant

# persist the sort order
ActiveRecord::Base.transaction do
card_grants.each_with_index do |cg, idx|
cg.update(sort_index: idx)
end
end

render json: card_grants.pluck(:id)
end

def clear_purpose
authorize @card_grant, :update?
@card_grant.update(purpose: nil)
30 changes: 30 additions & 0 deletions app/javascript/controllers/sort_card_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Controller } from '@hotwired/stimulus'
import csrf from '../common/csrf'

export default class extends Controller {
static values = {
order: Array,
}

async sort({ detail: { oldIndex, newIndex } }) {
if (oldIndex == newIndex) return

const copy = this.orderValue

const id = copy[oldIndex]

copy.splice(oldIndex, 1)
copy.splice(newIndex, 0, id)

this.orderValue = copy

await fetch(`/grants/${id}/set_index`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrf(),
},
body: JSON.stringify({ index: newIndex }),
})
}
}
1 change: 1 addition & 0 deletions app/models/card_grant.rb
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
# keyword_lock :string
# merchant_lock :string
# purpose :string
# sort_index :float
# status :integer default("active"), not null
# created_at :datetime not null
# updated_at :datetime not null
12 changes: 10 additions & 2 deletions app/views/static_pages/index.html.erb
Original file line number Diff line number Diff line change
@@ -32,9 +32,17 @@
<% if current_user.card_grants.activated.size > 0 %>
<h2 class="heading h2 line-height-4 mt-0 ml-0 py-2 px-4 border-none">Grants</h2>

<div class="grid grid--wide mb-12">
<div
class="grid grid--wide mb-12"
data-controller="sortable sort-card"
data-sortable-append-to-value="body"
data-sort-card-order-value='<%= current_user.card_grants.includes(:stripe_card).map(&:hashid).to_json %>'
data-action="sortable:stop->sort-card#sort"
>
<% current_user.card_grants.includes(:stripe_card).activated.each do |grant| %>
Comment on lines +39 to 42
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
data-sort-card-order-value='<%= current_user.card_grants.includes(:stripe_card).map(&:hashid).to_json %>'
data-action="sortable:stop->sort-card#sort"
>
<% current_user.card_grants.includes(:stripe_card).activated.each do |grant| %>
data-sort-card-order-value='<%= current_user.card_grants.includes(:stripe_card).map(&:hashid).to_json %>'
data-action="sortable:stop->sort-card#sort">
<% current_user.card_grants.includes(:stripe_card).activated.each do |grant| %>

<%= render grant.stripe_card, headless: true, show_purpose: true, href: card_grant_path(grant) %>
<div class="draggable">
<%= render grant.stripe_card, headless: true, show_purpose: true, href: card_grant_path(grant) %>
</div>
<% end %>
</div>
<% end %>
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -655,6 +655,7 @@
post "activate"
get "spending"
post "clear_purpose"
post "set_index"
end
end

5 changes: 5 additions & 0 deletions db/migrate/20250621234202_add_sort_index_to_card_grants.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddSortIndexToCardGrants < ActiveRecord::Migration[7.2]
def change
add_column :card_grants, :sort_index, :float
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.2].define(version: 2025_06_19_045020) do
ActiveRecord::Schema[7.2].define(version: 2025_06_21_234202) do
# These are extensions that must be enabled in order to support this database
enable_extension "citext"
enable_extension "pg_stat_statements"
@@ -432,6 +432,7 @@
t.string "keyword_lock"
t.string "purpose"
t.boolean "one_time_use"
t.float "sort_index"
t.index ["disbursement_id"], name: "index_card_grants_on_disbursement_id"
t.index ["event_id"], name: "index_card_grants_on_event_id"
t.index ["sent_by_id"], name: "index_card_grants_on_sent_by_id"