Merge remote-tracking branch 'origin/main' into feat/goals-v2-architecture

# Conflicts:
#	.github/workflows/preview-deploy.yml
#	app/models/account/provider_import_adapter.rb
This commit is contained in:
Guillem Arias
2026-05-30 09:28:11 +02:00
279 changed files with 16066 additions and 1093 deletions

View File

@@ -1,10 +1,11 @@
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["messages", "form", "input"];
static targets = ["messages", "form", "input", "submit"];
connect() {
this.#configureAutoScroll();
this.#updateSubmitState();
}
disconnect() {
@@ -22,10 +23,13 @@ export default class extends Controller {
input.style.height = `${Math.min(input.scrollHeight, lineHeight * maxLines)}px`;
input.style.overflowY =
input.scrollHeight > lineHeight * maxLines ? "auto" : "hidden";
this.#updateSubmitState();
}
submitSampleQuestion(e) {
this.inputTarget.value = e.target.dataset.chatQuestionParam;
this.#updateSubmitState();
setTimeout(() => {
this.formTarget.requestSubmit();
@@ -36,10 +40,21 @@ export default class extends Controller {
handleInputKeyDown(e) {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
this.formTarget.requestSubmit();
if (this.#hasContent()) {
this.formTarget.requestSubmit();
}
}
}
#hasContent() {
return this.inputTarget.value.trim().length > 0;
}
#updateSubmitState() {
if (!this.hasSubmitTarget) return;
this.submitTarget.disabled = !this.#hasContent();
}
#configureAutoScroll() {
this.messagesObserver = new MutationObserver((_mutations) => {
if (this.hasMessagesTarget) {

View File

@@ -128,9 +128,32 @@ export default class extends Controller {
};
handleExit = (err, metadata) => {
// If there was an error during update mode, refresh the page to show latest status
if (err && metadata.status === "requires_credentials") {
// If there was an error during update mode, refresh the page to show
// latest status. Guard `metadata` (Plaid can fire onExit with it
// undefined when Link aborts very early) and gate the redirect on
// `isUpdateValue` so first-time link failures don't bounce the user
// away from whatever page they were on.
if (
err &&
metadata &&
metadata.status === "requires_credentials" &&
this.isUpdateValue
) {
window.location.href = "/accounts";
return;
}
// Promote Plaid's own error payload to the console so a silent modal
// close still leaves a breadcrumb (issue #1792). Plaid Link's own UI
// is responsible for showing a message inside the modal when this
// fires; backend link-token failures are handled server-side via the
// PlaidItemsController rescue + flash.
if (err?.error_code) {
console.error(
"Plaid Link exited with error",
err.error_code,
err.display_message || err.error_message
);
}
};

View File

@@ -511,7 +511,7 @@ export default class extends Controller {
.append("div")
.attr(
"class",
"bg-gray-700 text-white text-sm p-2 rounded pointer-events-none absolute z-50 top-0",
"bg-container text-primary text-sm font-sans p-2 border border-secondary rounded-lg pointer-events-none absolute z-50 top-0 privacy-sensitive",
)
.style("opacity", 0)
.style("pointer-events", "none");