From 94e71f86b84aa4a81ee189f2f4ce8d860b28745c Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Tue, 6 Oct 2026 20:37:00 -0300 Subject: [PATCH 1/3] fix(frontend): fold what the migration rehearsal found into the page A rehearsal of the whole move on real instances found these. The document itself could scroll on the migration page and hide the top bar. Each locked step holds a line that only a screen reader hears. It is positioned out of the flow, and nothing between it and the document was positioned, so it was placed against the document and made it taller than the window. The page's root is positioned now. The knowledge bases test of "Where your data goes" has two more reasons with a line each: the server has no pgvector package, and an instance that already runs on PostgreSQL has no PGVECTOR_CONNECTION_STRING. On such an instance the note at the test says the knowledge bases go to the store that variable names, where it said the new instance's database, and the refusal under it is what to do. The missing variable also stops "Copy knowledge bases" and refuses its start. No note stands there, so that line says why as well, and it ends with the copy. A pause that is refused because changes under way had not finished says to try again in a moment, and trying again does not ask twice. The walks cover the document that stays put, a backup confirmed with no place named, which the browser's own message stops, and a destination step on an instance that has knowledge bases. --- .secrets.baseline | 230 +++++++++--------- src/frontend/src/locales/de.json | 5 + src/frontend/src/locales/en.json | 5 + src/frontend/src/locales/es.json | 5 + src/frontend/src/locales/fr.json | 5 + src/frontend/src/locales/ja.json | 5 + src/frontend/src/locales/ko.json | 5 + src/frontend/src/locales/pt.json | 5 + src/frontend/src/locales/zh-Hans.json | 5 + .../pages/MigrationPage/DestinationsStep.tsx | 5 +- .../pages/MigrationPage/PauseStep.tsx | 20 +- .../MigrationPage/__tests__/catalog.test.ts | 3 + .../MigrationPage/__tests__/steps.test.tsx | 161 +++++++++++- .../pages/MigrationPage/catalog.ts | 5 + .../pages/MigrationPage/index.tsx | 4 +- .../core/features/migration-checks.spec.ts | 9 + .../core/features/migration-pause.spec.ts | 14 +- .../core/features/migration-prepare.spec.ts | 16 +- 18 files changed, 372 insertions(+), 135 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index a728570b6d71..f810f6ac190a 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3023,7 +3023,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "2a24f50d36559883d2bc391e4e99f9a7afd56ef9", "is_verified": false, - "line_number": 2198, + "line_number": 2203, "is_secret": false }, { @@ -3031,7 +3031,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "fd0543de99a00bd6e67f3e522a18ed417089b6b4", "is_verified": false, - "line_number": 2209, + "line_number": 2214, "is_secret": false }, { @@ -3039,7 +3039,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "fa4b98297401af5e6ab7a402330a12715e891325", "is_verified": false, - "line_number": 2361, + "line_number": 2366, "is_secret": false }, { @@ -3047,7 +3047,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "9c46c22e7a8ff423706b990fc02c85e0d324f134", "is_verified": false, - "line_number": 2374, + "line_number": 2379, "is_secret": false }, { @@ -3055,7 +3055,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "91cde4236a3754b4b57733682edfc50571d954c6", "is_verified": false, - "line_number": 2376, + "line_number": 2381, "is_secret": false }, { @@ -3063,7 +3063,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "9625c6b66710b648d27ee284940849a6b5abf3f0", "is_verified": false, - "line_number": 2379, + "line_number": 2384, "is_secret": false }, { @@ -3071,7 +3071,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "370c53187d8e550db85edabdcb86547dab96e300", "is_verified": false, - "line_number": 2384, + "line_number": 2389, "is_secret": false }, { @@ -3079,7 +3079,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "cc57a2140542893b4c9396b6a7186b26351c6fe5", "is_verified": false, - "line_number": 2393, + "line_number": 2398, "is_secret": false }, { @@ -3087,7 +3087,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "d922d16c3bbc818b6fab4e8d2662fa361309fa9d", "is_verified": false, - "line_number": 2622, + "line_number": 2627, "is_secret": false }, { @@ -3095,7 +3095,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "8ea601e5cac549eef50d2743f915e4af54135789", "is_verified": false, - "line_number": 2623, + "line_number": 2628, "is_secret": false }, { @@ -3103,7 +3103,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "e498ebe977c948f4d1b7eddd6bb77be398ed4d7c", "is_verified": false, - "line_number": 2629, + "line_number": 2634, "is_secret": false }, { @@ -3111,7 +3111,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "02e680473cb1ee7473e2cdb5b0b6c48cd8aae081", "is_verified": false, - "line_number": 2630, + "line_number": 2635, "is_secret": false }, { @@ -3119,7 +3119,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "cc50b2aac5d886516a06afb79b4931f4ee66422d", "is_verified": false, - "line_number": 2640, + "line_number": 2645, "is_secret": false }, { @@ -3127,7 +3127,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "07039cae9ab794b348576619cb3ec72eab24b781", "is_verified": false, - "line_number": 2683, + "line_number": 2688, "is_secret": false }, { @@ -3135,7 +3135,7 @@ "filename": "src/frontend/src/locales/de.json", "hashed_secret": "0070d28a258282ddfc1e1addf78aa9d773735c5e", "is_verified": false, - "line_number": 2684, + "line_number": 2689, "is_secret": false } ], @@ -3329,7 +3329,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "76b33d23eee6aaa96f11abb4cbf1e5abd66aa46d", "is_verified": false, - "line_number": 894, + "line_number": 899, "is_secret": false }, { @@ -3337,7 +3337,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "e9013532fd4966ed4b3aab1ae711b21f180e4c26", "is_verified": false, - "line_number": 895, + "line_number": 900, "is_secret": false }, { @@ -3345,7 +3345,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "8f16563f8a1751c141fd1c47148369ca1c380bb1", "is_verified": false, - "line_number": 938, + "line_number": 943, "is_secret": false }, { @@ -3353,7 +3353,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "2c4e1babc2d1448dfcfdd24fb92068644227d6f1", "is_verified": false, - "line_number": 1031, + "line_number": 1036, "is_secret": false }, { @@ -3361,7 +3361,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "7ce9180d54b399cafbe6515ca2ca4710a6b9554c", "is_verified": false, - "line_number": 1037, + "line_number": 1042, "is_secret": false }, { @@ -3369,7 +3369,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "924cf2c6cefbba9e88dc676bd2575b7f21f9661e", "is_verified": false, - "line_number": 1044, + "line_number": 1049, "is_secret": false }, { @@ -3377,7 +3377,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "9d6bd29f94e1e565bd5de8f44c875638b26e85b6", "is_verified": false, - "line_number": 1045, + "line_number": 1050, "is_secret": false }, { @@ -3385,7 +3385,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "8e77e1ff96d9be727f25fc393a48f767935660db", "is_verified": false, - "line_number": 1565, + "line_number": 1570, "is_secret": false }, { @@ -3393,7 +3393,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "4a7c565d4c4430e3bb8fa6c560125d5eb37e7c3d", "is_verified": false, - "line_number": 1818, + "line_number": 1823, "is_secret": false }, { @@ -3401,7 +3401,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "29538b53771fff5bad78e3a48a3a8f88c2f141d2", "is_verified": false, - "line_number": 1903, + "line_number": 1908, "is_secret": false }, { @@ -3409,7 +3409,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "8d24e5afd2e9b40d21e4300c893a486aab979795", "is_verified": false, - "line_number": 1904, + "line_number": 1909, "is_secret": false }, { @@ -3417,7 +3417,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "ed05045c1666dd556d9a09f9eb6889f42a81aa5a", "is_verified": false, - "line_number": 2012, + "line_number": 2017, "is_secret": false }, { @@ -3425,7 +3425,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "8f616a4d4abc959d505a5b83f1b3fa1a6bce6b2e", "is_verified": false, - "line_number": 2014, + "line_number": 2019, "is_secret": false }, { @@ -3433,7 +3433,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "1bbb8fd38e8fef4280c7218b961ae2ceeb83bbc9", "is_verified": false, - "line_number": 2015, + "line_number": 2020, "is_secret": false }, { @@ -3441,7 +3441,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "0b8eacdde75bb24c6f29adf660f50ca4d9846358", "is_verified": false, - "line_number": 2017, + "line_number": 2022, "is_secret": false }, { @@ -3449,7 +3449,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "8cde7462c1ce55676dc45124068d844ad3b86dcf", "is_verified": false, - "line_number": 2038, + "line_number": 2043, "is_secret": false }, { @@ -3457,7 +3457,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "afbf9aed8c22c3faf4d92dccadabe324d49bc5a8", "is_verified": false, - "line_number": 2279, + "line_number": 2284, "is_secret": false }, { @@ -3465,7 +3465,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "651f66f27bbfaed040c836e22515162e20c4fa0d", "is_verified": false, - "line_number": 2293, + "line_number": 2298, "is_secret": false }, { @@ -3473,7 +3473,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "e38ef0e653c39ce1a4dde13da87333c43ced6cab", "is_verified": false, - "line_number": 2378, + "line_number": 2383, "is_secret": false }, { @@ -3481,7 +3481,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "044b852f30b636aa923b18a61a35c79abc87556f", "is_verified": false, - "line_number": 2686, + "line_number": 2691, "is_secret": false }, { @@ -3489,7 +3489,7 @@ "filename": "src/frontend/src/locales/en.json", "hashed_secret": "e40123b4e7879a56fc22171a9ae637d418288daa", "is_verified": false, - "line_number": 2687, + "line_number": 2692, "is_secret": false } ], @@ -3747,7 +3747,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "5c324bbf8f0a15d640a2ca93b4bb0183d106edd8", "is_verified": false, - "line_number": 2198, + "line_number": 2203, "is_secret": false }, { @@ -3755,7 +3755,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "49d8b438094e36554d1d2ec73dbc4adbdca1a891", "is_verified": false, - "line_number": 2209, + "line_number": 2214, "is_secret": false }, { @@ -3763,7 +3763,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "bdd17febdd742a928650952ec63b0ab0d7eeddac", "is_verified": false, - "line_number": 2374, + "line_number": 2379, "is_secret": false }, { @@ -3771,7 +3771,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "15e4f8d5f1d2759b1e83f9082a8ce8e194eb5600", "is_verified": false, - "line_number": 2376, + "line_number": 2381, "is_secret": false }, { @@ -3779,7 +3779,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "c8700cb4716f270e7c37191104366e7b1cadc9de", "is_verified": false, - "line_number": 2379, + "line_number": 2384, "is_secret": false }, { @@ -3787,7 +3787,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "60b0610326aa371e079775047f4e66c77aabb0a2", "is_verified": false, - "line_number": 2384, + "line_number": 2389, "is_secret": false }, { @@ -3795,7 +3795,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "0147f29ee8d8343d8d70f94b71b0053b268461e3", "is_verified": false, - "line_number": 2393, + "line_number": 2398, "is_secret": false }, { @@ -3803,7 +3803,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "3c89182cf4fc330080cfb2352105827a904d5691", "is_verified": false, - "line_number": 2622, + "line_number": 2627, "is_secret": false }, { @@ -3811,7 +3811,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "998c11b06dfd04593f289507da2b499cf4bca6e8", "is_verified": false, - "line_number": 2623, + "line_number": 2628, "is_secret": false }, { @@ -3819,7 +3819,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "ccaa726ee57e4ccdab0a28886273feee26d647ec", "is_verified": false, - "line_number": 2629, + "line_number": 2634, "is_secret": false }, { @@ -3827,7 +3827,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "2e329e7c25daa340c17b719f5371248f691de123", "is_verified": false, - "line_number": 2630, + "line_number": 2635, "is_secret": false }, { @@ -3835,7 +3835,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "6e09157ed6a7516c860d26d0747fb229badf190a", "is_verified": false, - "line_number": 2640, + "line_number": 2645, "is_secret": false }, { @@ -3843,7 +3843,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "3d04be8b9cef8a2743fc91a6e34c0272a1b3a194", "is_verified": false, - "line_number": 2683, + "line_number": 2688, "is_secret": false }, { @@ -3851,7 +3851,7 @@ "filename": "src/frontend/src/locales/es.json", "hashed_secret": "a0e898048bbec1b000a6a80fb85068f85bae1cc2", "is_verified": false, - "line_number": 2684, + "line_number": 2689, "is_secret": false } ], @@ -4061,7 +4061,7 @@ "filename": "src/frontend/src/locales/fr.json", "hashed_secret": "b1df0ac48f734b370fc58c591ef0772266f88bb4", "is_verified": false, - "line_number": 2198, + "line_number": 2203, "is_secret": false }, { @@ -4069,7 +4069,7 @@ "filename": "src/frontend/src/locales/fr.json", "hashed_secret": "541b6268f8abceae80c498212280ee7136eba255", "is_verified": false, - "line_number": 2209, + "line_number": 2214, "is_secret": false }, { @@ -4077,7 +4077,7 @@ "filename": "src/frontend/src/locales/fr.json", "hashed_secret": "ff959bbe348ba1b8176852cd2e3d6ba8dbf4062d", "is_verified": false, - "line_number": 2374, + "line_number": 2379, "is_secret": false }, { @@ -4085,7 +4085,7 @@ "filename": "src/frontend/src/locales/fr.json", "hashed_secret": "73f311b6a3b5bb2b45eccad848db62d85ae37b58", "is_verified": false, - "line_number": 2384, + "line_number": 2389, "is_secret": false }, { @@ -4093,7 +4093,7 @@ "filename": "src/frontend/src/locales/fr.json", "hashed_secret": "7294ab5b6d4cf3ea2deab49cecb0a7baacd16447", "is_verified": false, - "line_number": 2629, + "line_number": 2634, "is_secret": false }, { @@ -4101,7 +4101,7 @@ "filename": "src/frontend/src/locales/fr.json", "hashed_secret": "8dfdd0969287ef24a795d71e17f53f148d37d766", "is_verified": false, - "line_number": 2640, + "line_number": 2645, "is_secret": false }, { @@ -4109,7 +4109,7 @@ "filename": "src/frontend/src/locales/fr.json", "hashed_secret": "64153b3b2beefe87ab8c005b00b731785d31b4ea", "is_verified": false, - "line_number": 2683, + "line_number": 2688, "is_secret": false }, { @@ -4117,7 +4117,7 @@ "filename": "src/frontend/src/locales/fr.json", "hashed_secret": "6ef3c010ee446fee1446618f12c9a38262ac8e42", "is_verified": false, - "line_number": 2684, + "line_number": 2689, "is_secret": false } ], @@ -4295,7 +4295,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "b7cd1a2885e8998336c89a87d4df110a6b66e2f2", "is_verified": false, - "line_number": 2209, + "line_number": 2214, "is_secret": false }, { @@ -4303,7 +4303,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "5e8bcadfaab440649c70e43a015503e9109a7bfa", "is_verified": false, - "line_number": 2361, + "line_number": 2366, "is_secret": false }, { @@ -4311,7 +4311,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "44ed46c9ee10a3a7308c6d1a5df4cb082c57b9e0", "is_verified": false, - "line_number": 2374, + "line_number": 2379, "is_secret": false }, { @@ -4319,7 +4319,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "20e6aa34a3dd984dd602c294ee85714b53a0a872", "is_verified": false, - "line_number": 2376, + "line_number": 2381, "is_secret": false }, { @@ -4327,7 +4327,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "b5426a913c9da60eff621ee15e0b195bf6aaa8da", "is_verified": false, - "line_number": 2379, + "line_number": 2384, "is_secret": false }, { @@ -4335,7 +4335,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "415c03a82cd5f390ad3e28dd82c88e36fb540548", "is_verified": false, - "line_number": 2384, + "line_number": 2389, "is_secret": false }, { @@ -4343,7 +4343,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "9e7ba6c71dc246eee615e88e31861a563e33b42d", "is_verified": false, - "line_number": 2393, + "line_number": 2398, "is_secret": false }, { @@ -4351,7 +4351,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "18a887dd97555ab726e7f4d4d999dedd236763eb", "is_verified": false, - "line_number": 2622, + "line_number": 2627, "is_secret": false }, { @@ -4359,7 +4359,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "e4777a4b7b9c6fd1911762e35405c0b6b80ae735", "is_verified": false, - "line_number": 2623, + "line_number": 2628, "is_secret": false }, { @@ -4367,7 +4367,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "8847d054d32b57b7a5633fed58444d7237209e24", "is_verified": false, - "line_number": 2629, + "line_number": 2634, "is_secret": false }, { @@ -4375,7 +4375,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "369cb27892790b429dacabb4ee12cdfd63d6c250", "is_verified": false, - "line_number": 2630, + "line_number": 2635, "is_secret": false }, { @@ -4383,7 +4383,7 @@ "filename": "src/frontend/src/locales/ja.json", "hashed_secret": "b9743a370a7e12046cbb762dda96137a0327fc28", "is_verified": false, - "line_number": 2640, + "line_number": 2645, "is_secret": false } ], @@ -4497,7 +4497,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "c9d6e376c30dbaaf2142fae361283ea0667358fa", "is_verified": false, - "line_number": 893, + "line_number": 898, "is_secret": false }, { @@ -4505,7 +4505,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "39ff30e476f5d150e3e57d3b05f958e11ece81c1", "is_verified": false, - "line_number": 894, + "line_number": 899, "is_secret": false }, { @@ -4513,7 +4513,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "78eb85e1be91197a49c929c9fd4a5a72835150d7", "is_verified": false, - "line_number": 895, + "line_number": 900, "is_secret": false }, { @@ -4521,7 +4521,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "165c88c7ec06f8d48f2362de61d591d5d41b72fe", "is_verified": false, - "line_number": 938, + "line_number": 943, "is_secret": false }, { @@ -4529,7 +4529,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "60eb4bb0f2a3ace6de3da60369f70602bd112fe9", "is_verified": false, - "line_number": 1044, + "line_number": 1049, "is_secret": false }, { @@ -4537,7 +4537,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "9c5b4c8b9cebe87bd33fe4c9413cf75059da92c8", "is_verified": false, - "line_number": 1045, + "line_number": 1050, "is_secret": false }, { @@ -4545,7 +4545,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "450789a827b2a299f08abc20469945926bbfe969", "is_verified": false, - "line_number": 1408, + "line_number": 1413, "is_secret": false }, { @@ -4553,7 +4553,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "6f5f8b14277a6d648f25cf462f85bcdf7c6dadda", "is_verified": false, - "line_number": 1565, + "line_number": 1570, "is_secret": false }, { @@ -4561,7 +4561,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "a3ec89f4eadb02663999f07df46f6757a4815e37", "is_verified": false, - "line_number": 1903, + "line_number": 1908, "is_secret": false }, { @@ -4569,7 +4569,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "5736978315ed308f81b8b2051af651f79cbbe7f4", "is_verified": false, - "line_number": 1904, + "line_number": 1909, "is_secret": false }, { @@ -4577,7 +4577,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "ed05045c1666dd556d9a09f9eb6889f42a81aa5a", "is_verified": false, - "line_number": 2012, + "line_number": 2017, "is_secret": false }, { @@ -4585,7 +4585,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "8188d6827255f313a42dc29ebebfb29e04eb3531", "is_verified": false, - "line_number": 2014, + "line_number": 2019, "is_secret": false }, { @@ -4593,7 +4593,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "1bbb8fd38e8fef4280c7218b961ae2ceeb83bbc9", "is_verified": false, - "line_number": 2015, + "line_number": 2020, "is_secret": false }, { @@ -4601,7 +4601,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "f4016d49eebd49624cb4a4918e634bc4d38ccf8b", "is_verified": false, - "line_number": 2017, + "line_number": 2022, "is_secret": false }, { @@ -4609,7 +4609,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "88b0c4cc0c8ec5b42da4e12265df55824b30ee60", "is_verified": false, - "line_number": 2038, + "line_number": 2043, "is_secret": false }, { @@ -4617,7 +4617,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "72c9efe2f4665310c55a9146c4113a188d313d56", "is_verified": false, - "line_number": 2279, + "line_number": 2284, "is_secret": false }, { @@ -4625,7 +4625,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "da3ba116b30c3b2e0251bb1f213951a8b5503a28", "is_verified": false, - "line_number": 2293, + "line_number": 2298, "is_secret": false }, { @@ -4633,7 +4633,7 @@ "filename": "src/frontend/src/locales/ko.json", "hashed_secret": "7ee6d673f5c394c8e0a36c15d26e1ab809da5c92", "is_verified": false, - "line_number": 2378, + "line_number": 2383, "is_secret": false } ], @@ -4899,7 +4899,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "e5de519e1707a85ae531c311d440ee66c9d92013", "is_verified": false, - "line_number": 2198, + "line_number": 2203, "is_secret": false }, { @@ -4907,7 +4907,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "5e210e2b1f3abec2110bc9be8e64d7f330fa1077", "is_verified": false, - "line_number": 2209, + "line_number": 2214, "is_secret": false }, { @@ -4915,7 +4915,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "0f0b397ea447a3fa2ad71bf2275fef3c57c19ced", "is_verified": false, - "line_number": 2361, + "line_number": 2366, "is_secret": false }, { @@ -4923,7 +4923,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "9a36a9b7c6bfc059b4f02372fff29d59a7d28956", "is_verified": false, - "line_number": 2374, + "line_number": 2379, "is_secret": false }, { @@ -4931,7 +4931,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "d041f1238574c9fda80f329a69df103dd0362201", "is_verified": false, - "line_number": 2376, + "line_number": 2381, "is_secret": false }, { @@ -4939,7 +4939,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "cb9c85cb748ddd0400375630f5ec0206759ddb89", "is_verified": false, - "line_number": 2379, + "line_number": 2384, "is_secret": false }, { @@ -4947,7 +4947,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "0f426df5e9101c108190dccfd037a953d0d402f2", "is_verified": false, - "line_number": 2384, + "line_number": 2389, "is_secret": false }, { @@ -4955,7 +4955,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "01817544892d96dedca2ad884fa493fea87ba133", "is_verified": false, - "line_number": 2393, + "line_number": 2398, "is_secret": false }, { @@ -4963,7 +4963,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "187a0dc92fd69a86bd0e675941e7f1898e3b55e1", "is_verified": false, - "line_number": 2622, + "line_number": 2627, "is_secret": false }, { @@ -4971,7 +4971,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "685a15b5a75fafecd74ad06561f50711e97d7275", "is_verified": false, - "line_number": 2623, + "line_number": 2628, "is_secret": false }, { @@ -4979,7 +4979,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "47a5deeb29d9b4f9d88464d050560a7f7b294ddd", "is_verified": false, - "line_number": 2629, + "line_number": 2634, "is_secret": false }, { @@ -4987,7 +4987,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "32c3af10cab241e0b425cebc42831cbaa236f1c6", "is_verified": false, - "line_number": 2630, + "line_number": 2635, "is_secret": false }, { @@ -4995,7 +4995,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "4cb21cbeac2b9488b0fde6c6291caf37245c54c2", "is_verified": false, - "line_number": 2640, + "line_number": 2645, "is_secret": false }, { @@ -5003,7 +5003,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "eb352ce61357f4686f0bd96845cda822bc6e8f78", "is_verified": false, - "line_number": 2683, + "line_number": 2688, "is_secret": false }, { @@ -5011,7 +5011,7 @@ "filename": "src/frontend/src/locales/pt.json", "hashed_secret": "4fadcd6a2e084d2c9a962254f1944a5b11bd272d", "is_verified": false, - "line_number": 2684, + "line_number": 2689, "is_secret": false } ], @@ -5173,7 +5173,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "74a3dd23222f2bc1888171506f585281009f79a4", "is_verified": false, - "line_number": 2209, + "line_number": 2214, "is_secret": false }, { @@ -5181,7 +5181,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "c10e8dbe79654ae8ed496c4c50f5e188b7924a4e", "is_verified": false, - "line_number": 2361, + "line_number": 2366, "is_secret": false }, { @@ -5189,7 +5189,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "7223cfc50b72fe9b091b46275f561526aba9e705", "is_verified": false, - "line_number": 2374, + "line_number": 2379, "is_secret": false }, { @@ -5197,7 +5197,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "4aa9a3231780af9a37413cb7034ecdf72d43cfec", "is_verified": false, - "line_number": 2376, + "line_number": 2381, "is_secret": false }, { @@ -5205,7 +5205,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "68af7627d36cc6b923f5928a198165857f1ba5f1", "is_verified": false, - "line_number": 2379, + "line_number": 2384, "is_secret": false }, { @@ -5213,7 +5213,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "7acd3659ef48c980ce4aef1d0f2f218ff25efc89", "is_verified": false, - "line_number": 2384, + "line_number": 2389, "is_secret": false }, { @@ -5221,7 +5221,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "7443c6e0ef4c013461140fb1aa2a7a60b40a0b89", "is_verified": false, - "line_number": 2393, + "line_number": 2398, "is_secret": false }, { @@ -5229,7 +5229,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "3c274d81d83ceba5bfaaaf2ac4f6b0aedcf431a0", "is_verified": false, - "line_number": 2622, + "line_number": 2627, "is_secret": false }, { @@ -5237,7 +5237,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "583ddc85a613ceef2e54f9d2251113f3acef73a3", "is_verified": false, - "line_number": 2623, + "line_number": 2628, "is_secret": false }, { @@ -5245,7 +5245,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "8494b7db80f8bfedeef8cc5697bed5339cd1a4ee", "is_verified": false, - "line_number": 2629, + "line_number": 2634, "is_secret": false }, { @@ -5253,7 +5253,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "d45af2467cb991008a273eb0c4590fa9a96fc497", "is_verified": false, - "line_number": 2630, + "line_number": 2635, "is_secret": false }, { @@ -5261,7 +5261,7 @@ "filename": "src/frontend/src/locales/zh-Hans.json", "hashed_secret": "8da5daf1ef780fe5e37ae02bee48cbdb023c7101", "is_verified": false, - "line_number": 2640, + "line_number": 2645, "is_secret": false } ], diff --git a/src/frontend/src/locales/de.json b/src/frontend/src/locales/de.json index 7e0cadba1e23..7478625d50e3 100644 --- a/src/frontend/src/locales/de.json +++ b/src/frontend/src/locales/de.json @@ -2048,6 +2048,7 @@ "settings.migration.dest.db.shared": "Die neue Instanz nutzt die Datenbank dieser Instanz ({{location}}). Stellen Sie sicher, dass die neue Instanz diese Adresse erreicht.", "settings.migration.dest.kb.title": "Wissensdatenbanken", "settings.migration.dest.kb.pgvector": "Wissensdatenbanken werden in die Datenbank der neuen Instanz kopiert. Diese benötigt die Erweiterung pgvector.", + "settings.migration.dest.kb.pgvectorOwn": "Diese Instanz nutzt bereits PostgreSQL. Ihre Wissensdatenbanken werden in den Speicher kopiert, aus dem dieser Server sie liest, also den, den PGVECTOR_CONNECTION_STRING angibt. Diese Datenbank benötigt die Erweiterung pgvector.", "settings.migration.dest.files.title": "Dateien", "settings.migration.dest.files.bucket": "Bucket", "settings.migration.dest.files.folder": "Ordner im Bucket", @@ -2069,6 +2070,8 @@ "settings.migration.probe.dbNotEmpty": "Diese Datenbank ist nicht leer. Verwenden Sie eine neue, leere Datenbank.", "settings.migration.probe.unreachable": "Verbindung zu dieser Datenbank nicht möglich.", "settings.migration.probe.pgvector": "Die Datenbank benötigt die Erweiterung pgvector. Bitten Sie die Person, die Ihre Datenbank verwaltet, sie zu aktivieren.", + "settings.migration.probe.pgvectorPackage": "Auf diesem Langflow-Server fehlt das Paket pgvector. Installieren Sie es, starten Sie Langflow neu und testen Sie dann erneut.", + "settings.migration.probe.pgvectorEnv": "Setzen Sie PGVECTOR_CONNECTION_STRING auf diesem Server auf diese Datenbank, starten Sie Langflow neu und testen Sie dann erneut.", "settings.migration.probe.noCreate": "Der Datenbankbenutzer darf keine Tabellen anlegen. Bitten Sie die Person, die Ihre Datenbank verwaltet, das zu erlauben.", "settings.migration.probe.bucketMissing": "Dieser Bucket wurde nicht gefunden.", "settings.migration.probe.bucketUnreachable": "Dieser Bucket ist nicht erreichbar. Prüfen Sie den Endpunkt.", @@ -2103,6 +2106,7 @@ "settings.migration.pause.cancelFailed": "Abbrechen nicht möglich. Bitten Sie den Besitzer, sie abzubrechen, oder warten Sie, bis sie fertig ist.", "settings.migration.pause.noCancel": "Lässt sich hier nicht abbrechen. Bitten Sie den Besitzer darum, oder warten Sie, bis sie fertig ist.", "settings.migration.pause.listeners": "Trigger-Listener laufen noch: {{count}}. Beenden Sie jeden Prozess „langflow listeners“ und prüfen Sie dann erneut.", + "settings.migration.pause.requestsActive": "Bereits laufende Änderungen sind noch nicht abgeschlossen. Versuchen Sie es gleich noch einmal.", "settings.migration.pause.checkAgain": "Erneut prüfen", "settings.migration.pause.rechecking": "Änderungen sind pausiert. Die Prüfung läuft erneut…", "settings.migration.pause.recheckIdle": "Änderungen sind pausiert. Die Prüfung muss erneut bestanden werden, bevor Sie fortfahren.", @@ -2163,6 +2167,7 @@ "settings.migration.copy.attentionMore": "Angezeigt werden die ersten {{shown}} von {{count}}.", "settings.migration.kb.progress": "Einträge: {{done}} von {{total}}", "settings.migration.kb.postgresNote": "Diese Instanz verwendet PostgreSQL und wechselt daher ebenfalls zum neuen Speicher. Das Wiederherstellen der Sicherung macht das rückgängig.", + "settings.migration.kb.postgresEnv": "Diese Instanz nutzt bereits PostgreSQL, daher werden ihre Wissensdatenbanken in den Speicher kopiert, aus dem dieser Server sie liest. Setzen Sie PGVECTOR_CONNECTION_STRING auf diesem Server auf diese Datenbank, starten Sie Langflow neu und kopieren Sie dann erneut.", "settings.migration.kb.ranking.body": "Die neue Instanz sortiert die Suchergebnisse dieser Wissensdatenbank anders.", "settings.migration.files.progress": "Dateien: {{done}} von {{total}}. Bisher kopiert: {{bytes}}.", "settings.migration.files.conflict": "Der Bucket enthält bereits eine andere Datei mit diesem Namen. Es wird nichts überschrieben.", diff --git a/src/frontend/src/locales/en.json b/src/frontend/src/locales/en.json index 48261dddf216..96b4875c8ba2 100644 --- a/src/frontend/src/locales/en.json +++ b/src/frontend/src/locales/en.json @@ -675,6 +675,7 @@ "settings.migration.dest.db.shared": "The new instance will use this instance's database ({{location}}). Make sure the new instance can reach that address.", "settings.migration.dest.kb.title": "Knowledge bases", "settings.migration.dest.kb.pgvector": "Knowledge bases are copied into the new instance's database, which needs the pgvector extension.", + "settings.migration.dest.kb.pgvectorOwn": "This instance already uses PostgreSQL. Its knowledge bases are copied to the store this server reads them from, the one PGVECTOR_CONNECTION_STRING names. That database needs the pgvector extension.", "settings.migration.dest.files.title": "Files", "settings.migration.dest.files.bucket": "Bucket", "settings.migration.dest.files.folder": "Folder in the bucket", @@ -696,6 +697,8 @@ "settings.migration.probe.dbNotEmpty": "This database isn't empty. Use a new, empty database.", "settings.migration.probe.unreachable": "Can't connect to this database.", "settings.migration.probe.pgvector": "The database needs the pgvector extension. Ask your database admin to turn it on.", + "settings.migration.probe.pgvectorPackage": "This Langflow server doesn't have the pgvector package. Install it, restart Langflow, then test again.", + "settings.migration.probe.pgvectorEnv": "Set PGVECTOR_CONNECTION_STRING on this server to that database and restart Langflow, then test again.", "settings.migration.probe.noCreate": "The database user can't create tables. Ask your database admin to allow it.", "settings.migration.probe.bucketMissing": "Can't find this bucket.", "settings.migration.probe.bucketUnreachable": "Can't reach this bucket. Check the endpoint.", @@ -730,6 +733,7 @@ "settings.migration.pause.cancelFailed": "Couldn't cancel it. Ask its owner to cancel it, or wait for it to finish.", "settings.migration.pause.noCancel": "You can't cancel this one from here. Ask its owner, or wait for it to finish.", "settings.migration.pause.listeners": "Trigger listeners still running: {{count}}. Stop each langflow listeners process, then check again.", + "settings.migration.pause.requestsActive": "Changes that were already under way haven't finished yet. Try again in a moment.", "settings.migration.pause.checkAgain": "Check again", "settings.migration.pause.rechecking": "Changes are paused. Running the check again…", "settings.migration.pause.recheckIdle": "Changes are paused. The check has to pass again before you continue.", @@ -790,6 +794,7 @@ "settings.migration.copy.attentionMore": "Showing the first {{shown}} of {{count}}.", "settings.migration.kb.progress": "Entries: {{done}} of {{total}}", "settings.migration.kb.postgresNote": "This instance uses PostgreSQL, so it switches to the new store too. Restoring the backup undoes it.", + "settings.migration.kb.postgresEnv": "This instance already uses PostgreSQL, so its knowledge bases are copied to the store this server reads them from. Set PGVECTOR_CONNECTION_STRING on this server to that database and restart Langflow, then copy again.", "settings.migration.kb.ranking.body": "The new instance ranks search results a different way for this one.", "settings.migration.files.progress": "Files: {{done}} of {{total}}. Copied so far: {{bytes}}.", "settings.migration.files.conflict": "The bucket already holds a different file with this name. Nothing is overwritten.", diff --git a/src/frontend/src/locales/es.json b/src/frontend/src/locales/es.json index 7e793e4c81c2..24f1de33ee48 100644 --- a/src/frontend/src/locales/es.json +++ b/src/frontend/src/locales/es.json @@ -2048,6 +2048,7 @@ "settings.migration.dest.db.shared": "La nueva instancia usará la base de datos de esta instancia ({{location}}). Asegúrate de que la nueva instancia pueda acceder a esa dirección.", "settings.migration.dest.kb.title": "Bases de conocimientos", "settings.migration.dest.kb.pgvector": "Las bases de conocimientos se copian en la base de datos de la nueva instancia, que necesita la extensión pgvector.", + "settings.migration.dest.kb.pgvectorOwn": "Esta instancia ya usa PostgreSQL. Sus bases de conocimientos se copian al almacén del que este servidor las lee, el que indica PGVECTOR_CONNECTION_STRING. Esa base de datos necesita la extensión pgvector.", "settings.migration.dest.files.title": "Archivos", "settings.migration.dest.files.bucket": "Bucket", "settings.migration.dest.files.folder": "Carpeta dentro del bucket", @@ -2069,6 +2070,8 @@ "settings.migration.probe.dbNotEmpty": "Esta base de datos no está vacía. Usa una base de datos nueva y vacía.", "settings.migration.probe.unreachable": "No se puede conectar a esta base de datos.", "settings.migration.probe.pgvector": "La base de datos necesita la extensión pgvector. Pide a quien administre la base de datos que la active.", + "settings.migration.probe.pgvectorPackage": "Este servidor de Langflow no tiene el paquete pgvector. Instálalo, reinicia Langflow y vuelve a probar.", + "settings.migration.probe.pgvectorEnv": "Define PGVECTOR_CONNECTION_STRING en este servidor con esa base de datos, reinicia Langflow y vuelve a probar.", "settings.migration.probe.noCreate": "El usuario de la base de datos no puede crear tablas. Pide a quien administre la base de datos que lo permita.", "settings.migration.probe.bucketMissing": "No se encuentra este bucket.", "settings.migration.probe.bucketUnreachable": "No se puede conectar con este bucket. Revisa el endpoint.", @@ -2103,6 +2106,7 @@ "settings.migration.pause.cancelFailed": "No se ha podido cancelar. Pide a su propietario que la cancele o espera a que termine.", "settings.migration.pause.noCancel": "No puedes cancelarla desde aquí. Pídeselo a su propietario o espera a que termine.", "settings.migration.pause.listeners": "Listeners de triggers aún en ejecución: {{count}}. Detén cada proceso langflow listeners y vuelve a comprobar.", + "settings.migration.pause.requestsActive": "Los cambios que ya estaban en curso aún no han terminado. Inténtalo de nuevo en un momento.", "settings.migration.pause.checkAgain": "Volver a comprobar", "settings.migration.pause.rechecking": "Los cambios están en pausa. Ejecutando de nuevo la comprobación…", "settings.migration.pause.recheckIdle": "Los cambios están en pausa. La comprobación tiene que pasar de nuevo antes de continuar.", @@ -2163,6 +2167,7 @@ "settings.migration.copy.attentionMore": "Se muestran los primeros {{shown}} de {{count}}.", "settings.migration.kb.progress": "Entradas: {{done}} de {{total}}", "settings.migration.kb.postgresNote": "Esta instancia usa PostgreSQL, así que también pasa al nuevo almacén. Restaurar la copia de seguridad lo deshace.", + "settings.migration.kb.postgresEnv": "Esta instancia ya usa PostgreSQL, así que sus bases de conocimientos se copian al almacén del que este servidor las lee. Define PGVECTOR_CONNECTION_STRING en este servidor con esa base de datos, reinicia Langflow y copia de nuevo.", "settings.migration.kb.ranking.body": "La nueva instancia ordena los resultados de búsqueda de otra forma en esta.", "settings.migration.files.progress": "Archivos: {{done}} de {{total}}. Copiado hasta ahora: {{bytes}}.", "settings.migration.files.conflict": "El bucket ya contiene un archivo distinto con este nombre. No se sobrescribe nada.", diff --git a/src/frontend/src/locales/fr.json b/src/frontend/src/locales/fr.json index 0a2c439ec491..50b360cb89a2 100644 --- a/src/frontend/src/locales/fr.json +++ b/src/frontend/src/locales/fr.json @@ -2048,6 +2048,7 @@ "settings.migration.dest.db.shared": "La nouvelle instance utilisera la base de données de cette instance ({{location}}). Vérifiez que la nouvelle instance peut atteindre cette adresse.", "settings.migration.dest.kb.title": "Bases de connaissances", "settings.migration.dest.kb.pgvector": "Les bases de connaissances sont copiées dans la base de données de la nouvelle instance, qui a besoin de l'extension pgvector.", + "settings.migration.dest.kb.pgvectorOwn": "Cette instance utilise déjà PostgreSQL. Ses bases de connaissances sont copiées dans le stockage où ce serveur les lit, celui qu'indique PGVECTOR_CONNECTION_STRING. Cette base de données a besoin de l'extension pgvector.", "settings.migration.dest.files.title": "Fichiers", "settings.migration.dest.files.bucket": "Bucket", "settings.migration.dest.files.folder": "Dossier dans le bucket", @@ -2069,6 +2070,8 @@ "settings.migration.probe.dbNotEmpty": "Cette base de données n'est pas vide. Utilisez une base de données neuve et vide.", "settings.migration.probe.unreachable": "Connexion à cette base de données impossible.", "settings.migration.probe.pgvector": "La base de données a besoin de l'extension pgvector. Demandez à la personne qui administre la base de données de l'activer.", + "settings.migration.probe.pgvectorPackage": "Ce serveur Langflow n'a pas le paquet pgvector. Installez-le, redémarrez Langflow, puis testez à nouveau.", + "settings.migration.probe.pgvectorEnv": "Définissez PGVECTOR_CONNECTION_STRING sur ce serveur avec cette base de données, redémarrez Langflow, puis testez à nouveau.", "settings.migration.probe.noCreate": "L'utilisateur de la base de données ne peut pas créer de tables. Demandez à la personne qui administre la base de données de l'y autoriser.", "settings.migration.probe.bucketMissing": "Ce bucket est introuvable.", "settings.migration.probe.bucketUnreachable": "Impossible de joindre ce bucket. Vérifiez le point de terminaison.", @@ -2103,6 +2106,7 @@ "settings.migration.pause.cancelFailed": "Impossible de l'annuler. Demandez à son propriétaire de l'annuler, ou attendez qu'elle se termine.", "settings.migration.pause.noCancel": "Vous ne pouvez pas l'annuler d'ici. Demandez à son propriétaire, ou attendez qu'elle se termine.", "settings.migration.pause.listeners": "Listeners de déclencheurs encore en cours : {{count}}. Arrêtez chaque processus langflow listeners, puis vérifiez à nouveau.", + "settings.migration.pause.requestsActive": "Les modifications déjà en cours ne sont pas encore terminées. Réessayez dans un instant.", "settings.migration.pause.checkAgain": "Vérifier à nouveau", "settings.migration.pause.rechecking": "Les modifications sont suspendues. Nouvelle vérification en cours…", "settings.migration.pause.recheckIdle": "Les modifications sont suspendues. La vérification doit réussir à nouveau avant de continuer.", @@ -2163,6 +2167,7 @@ "settings.migration.copy.attentionMore": "Affichage des {{shown}} premiers sur {{count}}.", "settings.migration.kb.progress": "Entrées : {{done}} sur {{total}}", "settings.migration.kb.postgresNote": "Cette instance utilise PostgreSQL : elle passe donc elle aussi au nouveau stockage. La restauration de la sauvegarde annule ce changement.", + "settings.migration.kb.postgresEnv": "Cette instance utilise déjà PostgreSQL, ses bases de connaissances sont donc copiées dans le stockage où ce serveur les lit. Définissez PGVECTOR_CONNECTION_STRING sur ce serveur avec cette base de données, redémarrez Langflow, puis copiez à nouveau.", "settings.migration.kb.ranking.body": "La nouvelle instance classe différemment les résultats de recherche de celle-ci.", "settings.migration.files.progress": "Fichiers : {{done}} sur {{total}}. Déjà copié : {{bytes}}.", "settings.migration.files.conflict": "Le bucket contient déjà un autre fichier portant ce nom. Rien n'est écrasé.", diff --git a/src/frontend/src/locales/ja.json b/src/frontend/src/locales/ja.json index c61df2aff4b3..5cfea91b5679 100644 --- a/src/frontend/src/locales/ja.json +++ b/src/frontend/src/locales/ja.json @@ -2048,6 +2048,7 @@ "settings.migration.dest.db.shared": "新しいインスタンスは、このインスタンスのデータベース ({{location}}) を使用します。新しいインスタンスからこのアドレスに接続できることを確認してください。", "settings.migration.dest.kb.title": "ナレッジベース", "settings.migration.dest.kb.pgvector": "ナレッジベースは新しいインスタンスのデータベースにコピーされます。このデータベースには pgvector 拡張機能が必要です。", + "settings.migration.dest.kb.pgvectorOwn": "このインスタンスはすでに PostgreSQL を使用しています。ナレッジベースは、このサーバーが読み取るストア (PGVECTOR_CONNECTION_STRING が指すストア) にコピーされます。そのデータベースには pgvector 拡張機能が必要です。", "settings.migration.dest.files.title": "ファイル", "settings.migration.dest.files.bucket": "バケット", "settings.migration.dest.files.folder": "バケット内のフォルダー", @@ -2069,6 +2070,8 @@ "settings.migration.probe.dbNotEmpty": "このデータベースは空ではありません。新しい空のデータベースを使用してください。", "settings.migration.probe.unreachable": "このデータベースに接続できません。", "settings.migration.probe.pgvector": "データベースに pgvector 拡張機能が必要です。データベース管理者に有効化を依頼してください。", + "settings.migration.probe.pgvectorPackage": "この Langflow サーバーには pgvector パッケージがありません。インストールして Langflow を再起動してから、もう一度テストしてください。", + "settings.migration.probe.pgvectorEnv": "このサーバーで PGVECTOR_CONNECTION_STRING をそのデータベースに設定し、Langflow を再起動してから、もう一度テストしてください。", "settings.migration.probe.noCreate": "データベースユーザーにテーブルを作成する権限がありません。データベース管理者に許可を依頼してください。", "settings.migration.probe.bucketMissing": "このバケットが見つかりません。", "settings.migration.probe.bucketUnreachable": "このバケットに接続できません。エンドポイントを確認してください。", @@ -2103,6 +2106,7 @@ "settings.migration.pause.cancelFailed": "キャンセルできませんでした。所有者にキャンセルを依頼するか、完了するまでお待ちください。", "settings.migration.pause.noCancel": "ここからはキャンセルできません。所有者に依頼するか、完了するまでお待ちください。", "settings.migration.pause.listeners": "実行中のトリガーリスナー: {{count}}。langflow listeners プロセスをそれぞれ停止してから、もう一度確認してください。", + "settings.migration.pause.requestsActive": "すでに進行中だった変更がまだ完了していません。しばらくしてからもう一度お試しください。", "settings.migration.pause.checkAgain": "もう一度確認", "settings.migration.pause.rechecking": "変更は一時停止されています。確認を再実行しています…", "settings.migration.pause.recheckIdle": "変更は一時停止されています。続行する前に、確認にもう一度合格する必要があります。", @@ -2163,6 +2167,7 @@ "settings.migration.copy.attentionMore": "{{count}} 件中、最初の {{shown}} 件を表示しています。", "settings.migration.kb.progress": "エントリ: {{done}} / {{total}}", "settings.migration.kb.postgresNote": "このインスタンスは PostgreSQL を使用しているため、こちらも新しいストアに切り替わります。バックアップを復元すると元に戻ります。", + "settings.migration.kb.postgresEnv": "このインスタンスはすでに PostgreSQL を使用しているため、ナレッジベースはこのサーバーが読み取るストアにコピーされます。このサーバーで PGVECTOR_CONNECTION_STRING をそのデータベースに設定し、Langflow を再起動してから、もう一度コピーしてください。", "settings.migration.kb.ranking.body": "新しいインスタンスでは、このナレッジベースの検索結果の順位付けが変わります。", "settings.migration.files.progress": "ファイル: {{done}} / {{total}}。これまでにコピーした量: {{bytes}}。", "settings.migration.files.conflict": "バケットには同じ名前の別のファイルがすでにあります。上書きはしません。", diff --git a/src/frontend/src/locales/ko.json b/src/frontend/src/locales/ko.json index 2514c10cc1da..c78a04a15c00 100644 --- a/src/frontend/src/locales/ko.json +++ b/src/frontend/src/locales/ko.json @@ -675,6 +675,7 @@ "settings.migration.dest.db.shared": "새 인스턴스는 이 인스턴스의 데이터베이스({{location}})를 씁니다. 새 인스턴스가 이 주소에 연결할 수 있는지 확인하세요.", "settings.migration.dest.kb.title": "Knowledge Base", "settings.migration.dest.kb.pgvector": "Knowledge Base는 새 인스턴스의 데이터베이스로 복사합니다. 이 데이터베이스에는 pgvector 확장이 필요합니다.", + "settings.migration.dest.kb.pgvectorOwn": "이 인스턴스는 이미 PostgreSQL을 씁니다. Knowledge Base는 이 서버가 읽는 저장소, 곧 PGVECTOR_CONNECTION_STRING이 가리키는 저장소로 복사합니다. 그 데이터베이스에는 pgvector 확장이 필요합니다.", "settings.migration.dest.files.title": "파일", "settings.migration.dest.files.bucket": "버킷", "settings.migration.dest.files.folder": "버킷 안의 폴더", @@ -696,6 +697,8 @@ "settings.migration.probe.dbNotEmpty": "이 데이터베이스는 비어 있지 않습니다. 비어 있는 새 데이터베이스를 쓰세요.", "settings.migration.probe.unreachable": "이 데이터베이스에 연결할 수 없습니다.", "settings.migration.probe.pgvector": "데이터베이스에 pgvector 확장이 필요합니다. 데이터베이스 관리자에게 켜 달라고 요청하세요.", + "settings.migration.probe.pgvectorPackage": "이 Langflow 서버에 pgvector 패키지가 없습니다. 설치하고 Langflow를 다시 시작한 뒤 다시 테스트하세요.", + "settings.migration.probe.pgvectorEnv": "이 서버에서 PGVECTOR_CONNECTION_STRING을 그 데이터베이스로 설정하고 Langflow를 다시 시작한 뒤 다시 테스트하세요.", "settings.migration.probe.noCreate": "데이터베이스 사용자가 테이블을 만들 수 없습니다. 데이터베이스 관리자에게 허용해 달라고 요청하세요.", "settings.migration.probe.bucketMissing": "이 버킷을 찾을 수 없습니다.", "settings.migration.probe.bucketUnreachable": "이 버킷에 연결할 수 없습니다. 엔드포인트를 확인하세요.", @@ -730,6 +733,7 @@ "settings.migration.pause.cancelFailed": "취소하지 못했습니다. 소유자에게 취소를 요청하거나 끝날 때까지 기다리세요.", "settings.migration.pause.noCancel": "여기서는 취소할 수 없습니다. 소유자에게 요청하거나 끝날 때까지 기다리세요.", "settings.migration.pause.listeners": "아직 실행 중인 트리거 리스너: {{count}}개. langflow listeners 프로세스를 모두 중지한 뒤 다시 확인하세요.", + "settings.migration.pause.requestsActive": "이미 진행 중이던 변경이 아직 끝나지 않았습니다. 잠시 후 다시 시도하세요.", "settings.migration.pause.checkAgain": "다시 확인", "settings.migration.pause.rechecking": "변경을 일시 중지했습니다. 점검을 다시 실행하고 있습니다…", "settings.migration.pause.recheckIdle": "변경을 일시 중지했습니다. 계속하려면 점검을 다시 통과해야 합니다.", @@ -790,6 +794,7 @@ "settings.migration.copy.attentionMore": "{{count}}개 중 처음 {{shown}}개를 표시합니다.", "settings.migration.kb.progress": "항목: {{done}} / {{total}}", "settings.migration.kb.postgresNote": "이 인스턴스는 PostgreSQL을 쓰므로 이 인스턴스도 새 저장소로 전환됩니다. 백업을 복원하면 되돌릴 수 있습니다.", + "settings.migration.kb.postgresEnv": "이 인스턴스는 이미 PostgreSQL을 쓰므로 Knowledge Base는 이 서버가 읽는 저장소로 복사합니다. 이 서버에서 PGVECTOR_CONNECTION_STRING을 그 데이터베이스로 설정하고 Langflow를 다시 시작한 뒤 다시 복사하세요.", "settings.migration.kb.ranking.body": "새 인스턴스는 이 Knowledge Base의 검색 결과 순위를 다른 방식으로 매깁니다.", "settings.migration.files.progress": "파일: {{done}} / {{total}}. 지금까지 복사한 양: {{bytes}}.", "settings.migration.files.conflict": "버킷에 같은 이름의 다른 파일이 이미 있습니다. 덮어쓰지 않습니다.", diff --git a/src/frontend/src/locales/pt.json b/src/frontend/src/locales/pt.json index 476b572bedc7..113f072d12cd 100644 --- a/src/frontend/src/locales/pt.json +++ b/src/frontend/src/locales/pt.json @@ -2048,6 +2048,7 @@ "settings.migration.dest.db.shared": "A nova instância vai usar o banco de dados desta instância ({{location}}). Confirme que a nova instância consegue acessar esse endereço.", "settings.migration.dest.kb.title": "Bases de conhecimento", "settings.migration.dest.kb.pgvector": "As bases de conhecimento são copiadas para o banco de dados da nova instância, que precisa da extensão pgvector.", + "settings.migration.dest.kb.pgvectorOwn": "Esta instância já usa PostgreSQL. As bases de conhecimento dela são copiadas para o armazenamento de onde este servidor as lê, o que PGVECTOR_CONNECTION_STRING indica. Esse banco de dados precisa da extensão pgvector.", "settings.migration.dest.files.title": "Arquivos", "settings.migration.dest.files.bucket": "Bucket", "settings.migration.dest.files.folder": "Pasta no bucket", @@ -2069,6 +2070,8 @@ "settings.migration.probe.dbNotEmpty": "Este banco de dados não está vazio. Use um banco de dados novo e vazio.", "settings.migration.probe.unreachable": "Não foi possível conectar a este banco de dados.", "settings.migration.probe.pgvector": "O banco de dados precisa da extensão pgvector. Peça a quem administra o banco de dados para ativá-la.", + "settings.migration.probe.pgvectorPackage": "Este servidor do Langflow não tem o pacote pgvector. Instale-o, reinicie o Langflow e teste novamente.", + "settings.migration.probe.pgvectorEnv": "Defina PGVECTOR_CONNECTION_STRING neste servidor com esse banco de dados, reinicie o Langflow e teste novamente.", "settings.migration.probe.noCreate": "O usuário do banco de dados não pode criar tabelas. Peça a quem administra o banco de dados para permitir.", "settings.migration.probe.bucketMissing": "Este bucket não foi encontrado.", "settings.migration.probe.bucketUnreachable": "Não foi possível conectar a este bucket. Verifique o endpoint.", @@ -2103,6 +2106,7 @@ "settings.migration.pause.cancelFailed": "Não foi possível cancelar. Peça ao proprietário para cancelar ou espere terminar.", "settings.migration.pause.noCancel": "Não dá para cancelar daqui. Peça ao proprietário ou espere terminar.", "settings.migration.pause.listeners": "Listeners de gatilhos ainda em execução: {{count}}. Encerre cada processo langflow listeners e verifique de novo.", + "settings.migration.pause.requestsActive": "As alterações que já estavam em andamento ainda não terminaram. Tente novamente em instantes.", "settings.migration.pause.checkAgain": "Verificar de novo", "settings.migration.pause.rechecking": "As alterações estão pausadas. Executando a verificação de novo…", "settings.migration.pause.recheckIdle": "As alterações estão pausadas. A verificação precisa passar de novo antes de você continuar.", @@ -2163,6 +2167,7 @@ "settings.migration.copy.attentionMore": "Mostrando os primeiros {{shown}} de {{count}}.", "settings.migration.kb.progress": "Entradas: {{done}} de {{total}}", "settings.migration.kb.postgresNote": "Esta instância usa PostgreSQL, então ela também passa a usar o novo armazenamento. Restaurar o backup desfaz isso.", + "settings.migration.kb.postgresEnv": "Esta instância já usa PostgreSQL, então as bases de conhecimento dela são copiadas para o armazenamento de onde este servidor as lê. Defina PGVECTOR_CONNECTION_STRING neste servidor com esse banco de dados, reinicie o Langflow e copie novamente.", "settings.migration.kb.ranking.body": "A nova instância classifica os resultados de busca de outra forma para esta.", "settings.migration.files.progress": "Arquivos: {{done}} de {{total}}. Copiado até agora: {{bytes}}.", "settings.migration.files.conflict": "O bucket já tem um arquivo diferente com este nome. Nada é sobrescrito.", diff --git a/src/frontend/src/locales/zh-Hans.json b/src/frontend/src/locales/zh-Hans.json index 342630a843ee..0b0c7ebef53d 100644 --- a/src/frontend/src/locales/zh-Hans.json +++ b/src/frontend/src/locales/zh-Hans.json @@ -2048,6 +2048,7 @@ "settings.migration.dest.db.shared": "新实例将使用此实例的数据库({{location}})。请确保新实例可以访问该地址。", "settings.migration.dest.kb.title": "知识库", "settings.migration.dest.kb.pgvector": "知识库会复制到新实例的数据库中,该数据库需要 pgvector 扩展。", + "settings.migration.dest.kb.pgvectorOwn": "此实例已在使用 PostgreSQL。它的知识库会复制到此服务器读取知识库的存储,即 PGVECTOR_CONNECTION_STRING 指向的存储。该数据库需要 pgvector 扩展。", "settings.migration.dest.files.title": "文件", "settings.migration.dest.files.bucket": "存储桶", "settings.migration.dest.files.folder": "存储桶中的文件夹", @@ -2069,6 +2070,8 @@ "settings.migration.probe.dbNotEmpty": "此数据库不为空。请使用全新的空数据库。", "settings.migration.probe.unreachable": "无法连接到此数据库。", "settings.migration.probe.pgvector": "数据库需要 pgvector 扩展。请让数据库管理员启用它。", + "settings.migration.probe.pgvectorPackage": "此 Langflow 服务器没有 pgvector 软件包。请安装并重启 Langflow,然后重新测试。", + "settings.migration.probe.pgvectorEnv": "请在此服务器上将 PGVECTOR_CONNECTION_STRING 设置为该数据库,重启 Langflow,然后重新测试。", "settings.migration.probe.noCreate": "数据库用户无法创建表。请让数据库管理员授予此权限。", "settings.migration.probe.bucketMissing": "找不到此存储桶。", "settings.migration.probe.bucketUnreachable": "无法连接到此存储桶。请检查端点。", @@ -2103,6 +2106,7 @@ "settings.migration.pause.cancelFailed": "无法取消。请让其所有者取消,或等待它完成。", "settings.migration.pause.noCancel": "无法在此处取消。请让其所有者取消,或等待它完成。", "settings.migration.pause.listeners": "仍在运行的触发器监听器:{{count}}。请停止每个 langflow listeners 进程,然后再次检查。", + "settings.migration.pause.requestsActive": "已在进行中的更改尚未完成。请稍后重试。", "settings.migration.pause.checkAgain": "再次检查", "settings.migration.pause.rechecking": "更改已暂停。正在重新运行检查…", "settings.migration.pause.recheckIdle": "更改已暂停。检查必须再次通过,您才能继续。", @@ -2163,6 +2167,7 @@ "settings.migration.copy.attentionMore": "共 {{count}} 项,显示前 {{shown}} 项。", "settings.migration.kb.progress": "条目:{{done}} / {{total}}", "settings.migration.kb.postgresNote": "此实例使用 PostgreSQL,因此它也会切换到新的存储。恢复备份即可撤销。", + "settings.migration.kb.postgresEnv": "此实例已在使用 PostgreSQL,因此它的知识库会复制到此服务器读取知识库的存储。请在此服务器上将 PGVECTOR_CONNECTION_STRING 设置为该数据库,重启 Langflow,然后再次复制。", "settings.migration.kb.ranking.body": "新实例对此知识库的搜索结果采用不同的排序方式。", "settings.migration.files.progress": "文件:{{done}} / {{total}}。已复制:{{bytes}}。", "settings.migration.files.conflict": "存储桶中已有同名的其他文件。不会覆盖任何内容。", diff --git a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/DestinationsStep.tsx b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/DestinationsStep.tsx index 82e3d36fd347..f3410c2fde21 100644 --- a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/DestinationsStep.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/DestinationsStep.tsx @@ -98,7 +98,10 @@ export function DestinationsStep({ {instance.knowledge_bases.local && (

- {t("settings.migration.dest.kb.pgvector")} + {/* An instance on PostgreSQL copies them to the store its own server reads, which is no database of the new instance's. */} + {instance.database.type === "sqlite" + ? t("settings.migration.dest.kb.pgvector") + : t("settings.migration.dest.kb.pgvectorOwn")}

diff --git a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/PauseStep.tsx b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/PauseStep.tsx index b720417219f1..07a4b96ad0ee 100644 --- a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/PauseStep.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/PauseStep.tsx @@ -110,6 +110,8 @@ export function PauseStep({ const refusal = pause.error?.response?.data?.detail; const waiting = refusal?.code === "jobs_active" ? refusal : undefined; + // Changes that were already under way had not finished. They do in a moment, with nothing for the admin to do. + const unfinished = refusal?.code === "requests_active"; return (

@@ -118,18 +120,22 @@ export function PauseStep({ {waiting && } {pause.isError && !waiting && (

- {t( - refusal?.code === "pause_ended" - ? "settings.migration.pause.ended" - : "settings.migration.failed", - )} + {unfinished + ? t("settings.migration.pause.requestsActive") + : t( + refusal?.code === "pause_ended" + ? "settings.migration.pause.ended" + : "settings.migration.failed", + )}

)} + {/* A test run takes the copy's place in the record, so a done step offers none. */} + {testRun && state.state !== "done" && ( + + )} +
+ + ) : ( +

{t("settings.migration.notStarted")}

)} -
- - {/* A test run takes the copy's place in the record, so a done step offers none. */} - {testRun && state.state !== "done" && ( - - )} -
)} diff --git a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/catalog.test.ts b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/catalog.test.ts index 498fa6030af1..97d6eb5b2150 100644 --- a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/catalog.test.ts +++ b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/catalog.test.ts @@ -249,6 +249,7 @@ describe("COPY_CODES", () => { "crashed", "destination_changed", "interrupted", + "locked", "orphans_droppable", "orphans_no_rule", "pgvector_env_missing", diff --git a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/steps.test.tsx b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/steps.test.tsx index 46e58935a240..b70a1c352849 100644 --- a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/steps.test.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/__tests__/steps.test.tsx @@ -1243,6 +1243,8 @@ describe("Copy the database", () => { "Langflow no longer holds the passwords and keys of the new instance. Enter them again in 'Where your data goes'.", ], ["run_active", "Another step is running. Wait for it to finish."], + // A step above opened again in another tab, and this page has not read that yet. + ["locked", "Finish the steps above first."], ])("says why the server would not start it: %s", async (code, line) => { jest.spyOn(api, "post").mockRejectedValue(refused(409, { code })); show(panel(undefined, "current")); @@ -1609,6 +1611,82 @@ describe("Copy knowledge bases and files", () => { expect(post).toHaveBeenNthCalledWith(2, runs, { dry_run: false }); }); + // Every step above the knowledge base copy, as the server lists them. + const above = ( + check: MigrationStepState, + database = step("copy_database", "done"), + ) => [ + check, + step("connect_target", "done"), + step("secret_key", "done"), + step( + "pause", + check.state === "done" ? "done" : "blocked", + "recheck_failed", + ), + step("backup", "done"), + database, + ]; + + it("offers no start, real or test, while a step before it is open again, and says why", () => { + // The check failed again after this copy. The copy keeps its place, and the server would refuse to start it. + show( + , + ); + + // What the copy did is still there to read. + expect( + screen.getByText("Copied: 3. Already copied: 0. Not copied: 0."), + ).toBeInTheDocument(); + expect(screen.queryByRole("button")).not.toBeInTheDocument(); + expect( + screen.getByText("Finish the steps above first."), + ).toBeInTheDocument(); + }); + + it("offers the start when every step before it is done or not needed, whatever comes after it", () => { + show( + , + ); + + expect( + screen.getByRole("button", { name: "Copy knowledge bases" }), + ).toBeInTheDocument(); + expect( + screen.getByRole("button", { name: "Test run" }), + ).toBeInTheDocument(); + expect( + screen.queryByText("Finish the steps above first."), + ).not.toBeInTheDocument(); + }); + it("says what a test run found, and still offers the first copy", () => { show( { // Nothing says it was decided until it is. expect(screen.queryByText(/^Accepted by /)).not.toBeInTheDocument(); expect( - screen.queryByText("Copy again for this to apply."), + screen.queryByText("This applies to the next copy."), ).not.toBeInTheDocument(); await userEvent.click(leaveOut); @@ -2181,7 +2259,7 @@ describe("What the admin decides about a copy", () => { ).not.toHaveTextContent("2026-10-06T12:30:00Z"); // An option changes the next copy, and nothing about the one that asked. expect( - screen.getByText("Copy again for this to apply."), + screen.getByText("This applies to the next copy."), ).toBeInTheDocument(); await userEvent.click(leaveOut); @@ -2252,7 +2330,7 @@ describe("What the admin decides about a copy", () => { expect(screen.getAllByText(/^Accepted by /)).toHaveLength(1); // Leaving one behind settles it at once, so nothing waits for another copy. expect( - screen.queryByText("Copy again for this to apply."), + screen.queryByText("This applies to the next copy."), ).not.toBeInTheDocument(); await userEvent.click(option); @@ -2433,7 +2511,7 @@ describe("What the admin decides about a copy", () => { screen.getByRole("checkbox", { name: /^Accept the new ranking/ }), ).toBeChecked(); expect( - screen.getByText("Copy again for this to apply."), + screen.getByText("This applies to the next copy."), ).toBeInTheDocument(); }); diff --git a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/catalog.ts b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/catalog.ts index 16305778a918..f7f0d4739baa 100644 --- a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/catalog.ts +++ b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/catalog.ts @@ -205,6 +205,8 @@ export const isCopy = (id: MigrationStepId): id is CopyStepId => id in COPIES; export const COPY_CODES: Record = { secrets_missing: "error.enterAgain", // pragma: allowlist secret run_active: "error.runningElsewhere", + // A step above opened again after the page last read the state. The page then stops offering the start. + locked: "notStarted", cancelled: "error.interrupted", interrupted: "error.interrupted", crashed: "error.crashed", From 2c8e98233e4e375ec3079fd8a801fd2556b90ab5 Mon Sep 17 00:00:00 2001 From: Eric Hare Date: Thu, 8 Oct 2026 09:43:05 -0700 Subject: [PATCH 3/3] fix(frontend): keep the focus when the copy gate closes under its start When a read of the state reopens a step above a copy, the start buttons go away. Focus then fell to the document body and the line in their place was not announced. That line is now a status, and it takes the focus when the buttons it replaces held it. Also correct the comments on the knowledge bases line for a missing PGVECTOR_CONNECTION_STRING: the PostgreSQL note always stands above it, and the test now asserts that note. --- .../pages/MigrationPage/CopyStep.tsx | 48 +++++++++--- .../MigrationPage/__tests__/steps.test.tsx | 75 ++++++++++++++++++- .../pages/MigrationPage/catalog.ts | 3 +- 3 files changed, 115 insertions(+), 11 deletions(-) diff --git a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/CopyStep.tsx b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/CopyStep.tsx index ca79178a1579..dd1d51c61657 100644 --- a/src/frontend/src/pages/SettingsPage/pages/MigrationPage/CopyStep.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/MigrationPage/CopyStep.tsx @@ -1,6 +1,6 @@ import { useQueryClient } from "@tanstack/react-query"; import type { AxiosError } from "axios"; -import { useEffect, useId, useState } from "react"; +import { useEffect, useId, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; @@ -64,6 +64,22 @@ export function CopyStep({ step: destinations, }); const refusal = start.error?.response?.data?.detail?.code ?? ""; + // The server starts a copy only when every step before it is done or skipped. A copy that ran keeps its + // place when one of them opens again, so the page offers no start until that step is finished. + const place = migration.steps.findIndex(({ id }) => id === step); + const reached = migration.steps + .slice(0, place) + .every((earlier) => ["done", "skipped"].includes(earlier.state)); + // The state can close the gate under a focused start button: a refused start reads it again, and so does the + // poll. The button is then gone and the browser drops focus on , so focus goes to the line in its place. + const gate = useRef(null); + const focused = useRef(false); + useEffect(() => { + if (reached || !focused.current) return; + focused.current = false; + if (!document.activeElement || document.activeElement === document.body) + gate.current?.focus(); + }, [reached]); const running = run?.status === "running"; const [key, counts] = progress ? copyProgress(step, progress, i18n.language) @@ -93,12 +109,6 @@ export function CopyStep({ : run?.dry_run ? run.error?.code : undefined; - // The server starts a copy only when every step before it is done or skipped. A copy that ran keeps its - // place when one of them opens again, so the page offers no start until that step is finished. - const place = migration.steps.findIndex(({ id }) => id === step); - const reached = migration.steps - .slice(0, place) - .every((earlier) => ["done", "skipped"].includes(earlier.state)); // A copy that ended in a step that waits again no longer counts, so it is history. A test run never counted. const stale = state.state === "current" && Boolean(run) && !run?.dry_run; // What the last run found. A copy that is history has no result to show. @@ -325,7 +335,20 @@ export function CopyStep({ : t("settings.migration.failed")}

)} -
+
{ + focused.current = true; + }} + onBlur={(event) => { + // A button that is removed leaves no element behind, so only a move to another one counts. + if (event.relatedTarget) + focused.current = event.currentTarget.contains( + event.relatedTarget, + ); + }} + >