Revoking a device redirected away from the storage dashboard, which closed the details modal and reloaded the page. Refreshing the affected parts instead keeps the modal open and shows the change where it happened. - Extract the card and the modal's access list into their own components, so either can be re-rendered without touching the modal's open state, and share the group summaries between the components - Derive the app's DOM ids from its client_id (the grouping key) and the device row ids from the authorization, through one helper used by both the templates and the controller - Revoke one of several devices as a Turbo Stream: remove the row and refresh the card behind the modal and the access list - Revoke an app's last device with a redirect, so the dashboard re-renders itself and grouping, sorting and the empty state stay in one place - Fade the removed row out, deferring Turbo's own removal until the animation has ended Part of #254
35 lines
1.5 KiB
ERB
35 lines
1.5 KiB
ERB
<button type="button"
|
|
id="<%= card_id %>"
|
|
class="rs-auth-card group flex h-full w-full flex-col rounded-lg border border-gray-200
|
|
bg-white p-4 text-left transition
|
|
hover:border-gray-300 hover:bg-gray-50 hover:shadow-sm
|
|
focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500"
|
|
data-action="click->modal#open">
|
|
<span class="flex items-center gap-3">
|
|
<span class="h-12 w-12 flex-none">
|
|
<%= render AppCatalog::WebAppIconComponent.new(web_app: @web_app) %>
|
|
</span>
|
|
|
|
<span class="min-w-0 flex-grow">
|
|
<span class="mb-1 block truncate text-lg font-bold"><%= @auth.display_name %></span>
|
|
<% if @auth.client_id != @auth.display_name %>
|
|
<span class="block truncate text-sm text-gray-500"><%= @auth.client_id %></span>
|
|
<% end %>
|
|
</span>
|
|
|
|
<span class="flex-none text-gray-300 transition group-hover:text-gray-500" aria-hidden="true">
|
|
<%= render partial: "icons/chevron-right", locals: { custom_class: "h-5 w-5" } %>
|
|
</span>
|
|
</span>
|
|
|
|
<span class="mt-auto flex flex-wrap items-center gap-x-4 gap-y-1 pt-4 text-sm text-gray-500">
|
|
<span class="inline-flex items-center gap-1.5">
|
|
<%= render partial: "icons/monitor", locals: { custom_class: "h-4 w-4 flex-none text-gray-400" } %>
|
|
<%= device_summary %>
|
|
</span>
|
|
<span class="inline-flex items-center gap-1.5">
|
|
<%= render partial: "icons/folder", locals: { custom_class: "h-4 w-4 flex-none text-gray-400" } %>
|
|
<%= category_summary %>
|
|
</span>
|
|
</span>
|
|
</button> |