Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions app/javascript/controllers/clipboard_controller.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,17 @@
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
static targets = ["source", "iconDefault", "iconSuccess"];
static targets = ["source"];

copy(event) {
event.preventDefault();
if (this.sourceTarget?.textContent) {
navigator.clipboard
.writeText(this.sourceTarget.textContent)
.then(() => {
this.showSuccess();
})
.then(() => {})
.catch((error) => {
console.error("Failed to copy text: ", error);
});
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}

showSuccess() {
this.iconDefaultTarget.classList.add("hidden");
this.iconSuccessTarget.classList.remove("hidden");
setTimeout(() => {
this.iconDefaultTarget.classList.remove("hidden");
this.iconSuccessTarget.classList.add("hidden");
}, 3000);
}
}
10 changes: 5 additions & 5 deletions app/views/layouts/settings.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
</div>
</div>

<main class="grow flex h-full">
<div class="relative max-w-4xl mx-auto flex flex-col w-full h-full">
<div class="grow flex flex-col overflow-y-auto overflow-x-hidden overscroll-contain [-webkit-overflow-scrolling:touch]">
<main class="grow flex h-full min-w-0">
<div class="relative max-w-4xl mx-auto flex flex-col w-full h-full min-w-0">
<div class="grow flex flex-col overflow-y-auto overflow-x-hidden overscroll-contain [-webkit-overflow-scrolling:touch] min-w-0">
<div class="sticky top-0 z-10 px-3 md:px-10 pt-1.5 md:pt-3 pb-3 bg-surface border-b border-tertiary shrink-0">
<% if content_for?(:breadcrumbs) %>
<%= yield :breadcrumbs %>
<% else %>
<%= render "layouts/shared/breadcrumbs", breadcrumbs: @breadcrumbs %>
<% end %>

<div class="flex items-center justify-between gap-4 mt-1.5 min-h-9">
<div class="flex flex-wrap items-center justify-between gap-3 mt-1.5 min-h-9">
<% if content_for?(:page_title) %>
<h1 class="text-primary text-xl font-medium">
<%= content_for :page_title %>
Expand All @@ -25,7 +25,7 @@
<div></div>
<% end %>
<% if content_for?(:page_actions) %>
<div class="flex items-center gap-2 shrink-0">
<div class="flex items-center gap-2 max-w-full">
<%= yield :page_actions %>
</div>
<% end %>
Expand Down
29 changes: 19 additions & 10 deletions app/views/settings/api_keys/created.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@
<p class="text-secondary text-sm mb-3">Copy and store this key securely. You'll need it to authenticate your API requests.</p>

<div class="bg-container rounded-lg p-3 border border-primary" data-controller="clipboard">
<div class="flex items-center justify-between gap-3">
<code id="api-key-display" class="font-mono text-sm text-primary break-all" data-clipboard-target="source"><%= @api_key.plain_key %></code>
<%= render DS::Button.new(
text: "Copy API Key",
variant: "ghost",
icon: "copy",
data: { action: "clipboard#copy" }
) %>
<div class="w-full overflow-hidden">
<code id="api-key-display" class="block w-full min-w-0 overflow-x-auto font-mono text-sm text-primary break-all whitespace-pre-wrap" data-clipboard-target="source"><%= @api_key.plain_key %></code>
<div class="mt-2 flex justify-end">
<%= render DS::Button.new(
text: "Copy API Key",
variant: "ghost",
icon: "copy",
class: "shrink-0",
data: { action: "clipboard#copy" }
) %>
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -78,8 +81,14 @@
<div class="bg-surface-inset rounded-xl p-4">
<h4 class="font-medium text-primary mb-3">How to use your API key</h4>
<p class="text-secondary text-sm mb-3"><%= t("settings.api_keys.show.current_api_key.usage_instructions", product_name: product_name) %></p>
<div class="bg-container rounded-lg p-3 font-mono text-sm text-primary border border-primary">
curl -H "X-Api-Key: <%= @api_key.plain_key %>" <%= request.base_url %>/api/v1/accounts
<div class="bg-container rounded-lg p-3 font-mono text-sm text-primary border border-primary max-w-full overflow-hidden" data-controller="clipboard">
<div class="flex items-start gap-2 min-w-0">
<code class="block flex-1 min-w-0 overflow-x-auto break-all whitespace-pre-wrap" data-clipboard-target="source">curl -H "X-Api-Key: <%= @api_key.plain_key %>" <%= request.base_url %>/api/v1/accounts</code>
<button type="button" data-action="clipboard#copy" class="p-1.5 text-secondary hover:text-primary shrink-0" title="Copy curl command" aria-label="Copy curl command">
<span data-clipboard-target="iconDefault"><%= icon("copy", class: "w-4 h-4") %></span>
<span class="hidden" data-clipboard-target="iconSuccess"><%= icon("check", class: "w-4 h-4") %></span>
</button>
</div>
</div>
</div>

Expand Down
29 changes: 19 additions & 10 deletions app/views/settings/api_keys/created.turbo_stream.erb
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@
<p class="text-secondary text-sm mb-3">Copy and store this key securely. You'll need it to authenticate your API requests.</p>

<div class="bg-container rounded-lg p-3 border border-primary" data-controller="clipboard">
<div class="flex items-center justify-between gap-3">
<code id="api-key-display" class="font-mono text-sm text-primary break-all" data-clipboard-target="source"><%= @api_key.plain_key %></code>
<%= render DS::Button.new(
text: "Copy API Key",
variant: "ghost",
icon: "copy",
data: { action: "clipboard#copy" }
) %>
<div class="w-full overflow-hidden">
<code id="api-key-display" class="block w-full min-w-0 overflow-x-auto font-mono text-sm text-primary break-all whitespace-pre-wrap" data-clipboard-target="source"><%= @api_key.plain_key %></code>
<div class="mt-2 flex justify-end">
<%= render DS::Button.new(
text: "Copy API Key",
variant: "ghost",
icon: "copy",
class: "shrink-0",
data: { action: "clipboard#copy" }
) %>
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -83,8 +86,14 @@
<div class="bg-surface-inset rounded-xl p-4">
<h4 class="font-medium text-primary mb-3">How to use your API key</h4>
<p class="text-secondary text-sm mb-3">Include your API key in the X-Api-Key header when making requests:</p>
<div class="bg-container rounded-lg p-3 font-mono text-sm text-primary border border-primary">
curl -H "X-Api-Key: <%= @api_key.plain_key %>" <%= request.base_url %>/api/v1/accounts
<div class="bg-container rounded-lg p-3 font-mono text-sm text-primary border border-primary max-w-full overflow-hidden" data-controller="clipboard">
<div class="flex items-start gap-2 min-w-0">
<code class="block flex-1 min-w-0 overflow-x-auto break-all whitespace-pre-wrap" data-clipboard-target="source">curl -H "X-Api-Key: <%= @api_key.plain_key %>" <%= request.base_url %>/api/v1/accounts</code>
<button type="button" data-action="clipboard#copy" class="p-1.5 text-secondary hover:text-primary shrink-0" title="Copy curl command" aria-label="Copy curl command">
<span data-clipboard-target="iconDefault"><%= icon("copy", class: "w-4 h-4") %></span>
<span class="hidden" data-clipboard-target="iconSuccess"><%= icon("check", class: "w-4 h-4") %></span>
</button>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
</div>
</div>
</div>

Expand Down
64 changes: 44 additions & 20 deletions app/views/settings/api_keys/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,35 @@
<p class="text-secondary text-sm mb-3">Copy and store this key securely. You'll need it to authenticate your API requests.</p>

<div class="bg-container rounded-lg p-3 border border-primary" data-controller="clipboard">
<div class="flex items-center justify-between gap-3">
<code id="api-key-display" class="font-mono text-sm text-primary break-all" data-clipboard-target="source"><%= @current_api_key.plain_key %></code>
<%= render DS::Button.new(
text: "Copy API Key",
variant: "ghost",
icon: "copy",
data: { action: "clipboard#copy" }
) %>
<div class="w-full overflow-hidden">
<code id="api-key-display" class="block w-full min-w-0 overflow-x-auto font-mono text-sm text-primary break-all whitespace-pre-wrap" data-clipboard-target="source"><%= @current_api_key.plain_key %></code>
<div class="mt-2 flex justify-end">
<%= render DS::Button.new(
text: "Copy API Key",
variant: "ghost",
icon: "copy",
class: "shrink-0",
data: { action: "clipboard#copy" }
) %>
</div>
</div>
</div>
</div>

<div class="bg-surface-inset rounded-xl p-4">
<h4 class="font-medium text-primary mb-3">How to use your API key</h4>
<p class="text-secondary text-sm mb-3"><%= t(".current_api_key.usage_instructions", product_name: product_name) %></p>
<div class="bg-container rounded-lg p-3 font-mono text-sm text-primary border border-primary">
curl -H "X-Api-Key: <%= @current_api_key.plain_key %>" <%= request.base_url %>/api/v1/accounts
<div class="bg-container rounded-lg p-3 font-mono text-sm text-primary border border-primary max-w-full overflow-hidden" data-controller="clipboard">
<div class="flex items-start gap-2 min-w-0">
<code class="block flex-1 min-w-0 overflow-x-auto break-all whitespace-pre-wrap" data-clipboard-target="source">curl -H "X-Api-Key: <%= @current_api_key.plain_key %>" <%= request.base_url %>/api/v1/accounts</code>
<%= render DS::Button.new(
text: "Copy",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Localize the new “Copy” button label.

Line 47 hardcodes user-facing text, which breaks localization in non-English locales.

Proposed fix
-              text: "Copy",
+              text: t(".current_api_key.copy_key"),

As per coding guidelines, "All user-facing strings MUST use the t() i18n helper function and corresponding locale keys in config/locales/en.yml."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
text: "Copy",
text: t(".current_api_key.copy_key"),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/views/settings/api_keys/show.html.erb` at line 47, Replace the hardcoded
"Copy" label in the API keys view with an i18n lookup: change the text: "Copy"
usage in app/views/settings/api_keys/show.html.erb to use
t('settings.api_keys.copy') (or a similarly scoped key), and add that key with
the English string to config/locales/en.yml (e.g. settings: { api_keys: { copy:
"Copy" } }) so the button label is localizable across locales.

variant: "ghost",
icon: "copy",
class: "shrink-0",
data: { action: "clipboard#copy" }
) %>
</div>
</div>
</div>

Expand Down Expand Up @@ -111,23 +123,35 @@
<p class="text-secondary text-sm mb-3">Copy and store this key securely. You'll need it to authenticate your API requests.</p>

<div class="bg-container rounded-lg p-3 border border-primary" data-controller="clipboard">
<div class="flex items-center justify-between gap-3">
<code id="api-key-display" class="font-mono text-sm text-primary break-all" data-clipboard-target="source"><%= @current_api_key.plain_key %></code>
<%= render DS::Button.new(
text: "Copy API Key",
variant: "ghost",
icon: "copy",
data: { action: "clipboard#copy" }
) %>
<div class="w-full overflow-hidden">
<code id="api-key-display" class="block w-full min-w-0 overflow-x-auto font-mono text-sm text-primary break-all whitespace-pre-wrap" data-clipboard-target="source"><%= @current_api_key.plain_key %></code>
<div class="mt-2 flex justify-end">
<%= render DS::Button.new(
text: "Copy API Key",
variant: "ghost",
icon: "copy",
class: "shrink-0",
data: { action: "clipboard#copy" }
) %>
</div>
</div>
</div>
</div>

<div class="bg-surface-inset rounded-xl p-4">
<h4 class="font-medium text-primary mb-3">How to use your API key</h4>
<p class="text-secondary text-sm mb-3"><%= t(".current_api_key.usage_instructions", product_name: product_name) %></p>
<div class="bg-container rounded-lg p-3 font-mono text-sm text-primary border border-primary">
curl -H "X-Api-Key: <%= @current_api_key.plain_key %>" <%= request.base_url %>/api/v1/accounts
<div class="bg-container rounded-lg p-3 font-mono text-sm text-primary border border-primary max-w-full overflow-hidden" data-controller="clipboard">
<div class="flex items-start gap-2 min-w-0">
<code class="block flex-1 min-w-0 overflow-x-auto break-all whitespace-pre-wrap" data-clipboard-target="source">curl -H "X-Api-Key: <%= @current_api_key.plain_key %>" <%= request.base_url %>/api/v1/accounts</code>
<%= render DS::Button.new(
text: "Copy",
variant: "ghost",
icon: "copy",
class: "shrink-0",
data: { action: "clipboard#copy" }
) %>
</div>
</div>
</div>

Expand Down