1- < tr >
2- < td >
3- <%# Status indicator (no text originally, keeping it that way unless specified otherwise) %>
4- <% if key . active? %>
5- < span style ="color: green; "> </ span >
6- <% elsif key . revoked? %>
7- < span style ="color: orange; "> [Revoked]</ span >
8- <% elsif key . expired? %>
9- < span style ="color: red; "> [Expired]</ span >
10- <% end %>
1+ <%# Partial for displaying a single API key row in the table %>
2+ <%# Locals: key (required) - The ApiKey record %>
3+
4+ < tr class ="api-keys-row <%= 'api-keys-row-inactive' if defined? ( inactive ) && inactive %> ">
5+ < td class ="api-keys-cell-name ">
6+ <%= render partial : 'api_keys/keys/key_status' , locals : { key : key } %>
117 <%= key . name . presence || ( key . key_type . present? ? "#{ key . key_type . humanize } key" : "API key" ) %>
12- <%# Key type and environment badges %>
13- <% if key . key_type . present? %>
14- <% type_config = key . key_type_config %>
15- < span style ="display: inline-block; padding: 2px 6px; font-size: 0.75em; border-radius: 3px; background-color: <%= type_config &.dig ( :revocable ) == false ? '#fef3cd' : '#e7f1ff' %> ; color: <%= type_config &.dig ( :revocable ) == false ? '#856404' : '#004085' %> ; margin-left: 4px; ">
16- <%= key . key_type . humanize %>
17- </ span >
18- <% end %>
19- <% if key . environment . present? %>
20- < span style ="display: inline-block; padding: 2px 6px; font-size: 0.75em; border-radius: 3px; background-color: <%= key . environment == 'live' ? '#d4edda' : '#f8d7da' %> ; color: <%= key . environment == 'live' ? '#155724' : '#721c24' %> ; margin-left: 4px; ">
21- <%= key . environment . upcase %>
22- </ span >
23- <% end %>
24- </ td >
25- < td class ="api-keys-token-cell ">
26- <% if key . public_key_type? && key . viewable_token . present? %>
27- < span class ="token-masked "> < code > <%= key . masked_token %> </ code > </ span >
28- < span class ="token-full " style ="display: none; "> < code style ="word-break: break-all; "> <%= key . viewable_token %> </ code > </ span >
29- < button type ="button " class ="btn-show-token " style ="margin-left: 8px; font-size: 0.75em; padding: 2px 6px; cursor: pointer; " title ="Show full token "> Show</ button >
30- < button type ="button " class ="btn-copy-token " style ="display: none; margin-left: 4px; font-size: 0.75em; padding: 2px 6px; cursor: pointer; " title ="Copy to clipboard " data-token ="<%= key . viewable_token %> "> Copy</ button >
31- <% else %>
32- < code > <%= key . masked_token %> </ code >
33- <% end %>
8+ <%= render partial : 'api_keys/keys/key_badges' , locals : { key : key } %>
349 </ td >
3510
11+ < td class ="api-keys-cell-token api-keys-token-cell ">
12+ <%= render partial : 'api_keys/keys/token_display' , locals : { key : key } %>
13+ </ td >
3614
37- < td title ="<%= key . created_at . strftime ( '%Y-%m-%d %H:%M:%S %Z' ) %> ">
15+ < td class =" api-keys-cell-created " title ="<%= key . created_at . strftime ( '%Y-%m-%d %H:%M:%S %Z' ) %> ">
3816 <%= time_ago_in_words ( key . created_at ) %> ago
3917 </ td >
4018
41-
42- < td >
19+ < td class ="api-keys-cell-expires ">
4320 <% if key . expires_at? %>
4421 <% if key . expired? %>
45- < strong style ="color: red ; " title ="<%= key . expires_at . strftime ( '%Y-%m-%d %H:%M:%S %Z' ) %> ">
22+ < strong style ="color: var(--api-keys-status-expired-color) ; " title ="<%= key . expires_at . strftime ( '%Y-%m-%d %H:%M:%S %Z' ) %> ">
4623 Expired <%= time_ago_in_words ( key . expires_at ) %> ago
4724 </ strong >
4825 <% else %>
5532 <% end %>
5633 </ td >
5734
58-
59- < td >
35+ < td class ="api-keys-cell-last-used ">
6036 <% if key . last_used_at? %>
6137 < span title ="<%= key . last_used_at . strftime ( '%Y-%m-%d %H:%M:%S %Z' ) %> ">
6238 <%= time_ago_in_words ( key . last_used_at ) %> ago
6339 </ span >
64- <%# TODO: Add relative time check (e.g., "within last 3 months") %>
6540 <% else %>
6641 < em > Never used</ em >
6742 <% end %>
6843 </ td >
6944
70-
71- < td >
45+ < td class ="api-keys-cell-scopes ">
7246 <% if key . scopes . present? %>
7347 <% key . scopes . each do |scope | %>
74- < kbd class ="tag is-small "> <%= scope %> </ kbd >
48+ < kbd class ="api-keys-scope-tag tag is-small "> <%= scope %> </ kbd >
7549 <% end %>
7650 <% else %>
7751 —
7852 <% end %>
7953 </ td >
80- < td class ="api-keys-action-buttons ">
81- <% if key . active? %>
82- <%= link_to api_keys . edit_key_path ( key ) , title : "Edit Key" do %>
83- < svg xmlns ="http://www.w3.org/2000/svg " width ="1em " height ="1em " fill ="currentColor " viewBox ="0 0 24 24 "> < path fill-rule ="evenodd " d ="M16.793 2.793a3.121 3.121 0 1 1 4.414 4.414l-8.5 8.5A1 1 0 0 1 12 16H9a1 1 0 0 1-1-1v-3a1 1 0 0 1 .293-.707l8.5-8.5Zm3 1.414a1.121 1.121 0 0 0-1.586 0L10 12.414V14h1.586l8.207-8.207a1.121 1.121 0 0 0 0-1.586ZM6 5a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-4a1 1 0 1 1 2 0v4a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h4a1 1 0 1 1 0 2H6Z " clip-rule ="evenodd "> </ path > </ svg >
84- <% end %>
85- <%# Only show revoke button for revocable keys %>
86- <% if key . revocable? %>
87- <%= button_to api_keys . revoke_key_path ( key ) , title : "Revoke Key" , data : { turbo_method : :post , turbo_confirm : "Are you sure you want to revoke this key? It will stop working immediately." } do %>
88- < svg xmlns ="http://www.w3.org/2000/svg " width ="1em " height ="1em " fill ="currentColor " viewBox ="0 0 24 24 "> < path fill-rule ="evenodd " d ="M10.556 4a1 1 0 0 0-.97.751l-.292 1.14h5.421l-.293-1.14A1 1 0 0 0 13.453 4h-2.897Zm6.224 1.892-.421-1.639A3 3 0 0 0 13.453 2h-2.897A3 3 0 0 0 7.65 4.253l-.421 1.639H4a1 1 0 1 0 0 2h.1l1.215 11.425A3 3 0 0 0 8.3 22h7.4a3 3 0 0 0 2.984-2.683l1.214-11.425H20a1 1 0 1 0 0-2h-3.22Zm1.108 2H6.112l1.192 11.214A1 1 0 0 0 8.3 20h7.4a1 1 0 0 0 .995-.894l1.192-11.214ZM10 10a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0v-5a1 1 0 0 1 1-1Zm4 0a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0v-5a1 1 0 0 1 1-1Z " clip-rule ="evenodd "> </ path > </ svg >
89- <% end %>
90- <% else %>
91- < span title ="This key cannot be revoked " style ="color: #999; cursor: help; ">
92- < svg xmlns ="http://www.w3.org/2000/svg " width ="1em " height ="1em " fill ="currentColor " viewBox ="0 0 24 24 "> < path fill-rule ="evenodd " d ="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z " clip-rule ="evenodd "> </ path > </ svg >
93- </ span >
94- <% end %>
95- <% else %>
96- <%# No actions available for inactive/revoked/expired keys %>
97- —
98- <% end %>
54+
55+ < td class ="api-keys-cell-actions api-keys-action-buttons ">
56+ <%= render partial : 'api_keys/keys/key_actions' , locals : { key : key } %>
9957 </ td >
100- </ tr >
58+ </ tr >
0 commit comments