rebase rework

This commit is contained in:
2026-03-09 13:19:06 +03:00
parent c7e9b5b6c5
commit 309dfdba86
12 changed files with 1010 additions and 21 deletions

View File

@@ -15,11 +15,20 @@ const API_BASE_URL = '/api';
// @POST: Returned error contains message and status fields.
async function buildApiError(response) {
const errorData = await response.json().catch(() => ({}));
const message = errorData.detail
? (typeof errorData.detail === 'string' ? errorData.detail : JSON.stringify(errorData.detail))
const detail = errorData?.detail;
const message = detail
? (
typeof detail === 'string'
? detail
: (typeof detail?.message === 'string' ? detail.message : JSON.stringify(detail))
)
: `API request failed with status ${response.status}`;
const error = new Error(message);
error.status = response.status;
/** @type {any} */ (error).status = response.status;
/** @type {any} */ (error).detail = detail;
if (detail && typeof detail === 'object' && detail.error_code) {
/** @type {any} */ (error).error_code = String(detail.error_code);
}
return error;
}
// [/DEF:buildApiError:Function]
@@ -54,7 +63,18 @@ function shouldSuppressApiErrorToast(endpoint, error) {
(error?.status === 400 || error?.status === 404) &&
/Repository for dashboard .* not found/i.test(String(error?.message || ''));
return isGitStatusEndpoint && isNoRepoError;
const isGitPullEndpoint =
typeof endpoint === 'string' &&
endpoint.startsWith('/git/repositories/') &&
endpoint.endsWith('/pull');
const isUnfinishedMergeError =
error?.status === 409 &&
(
String(error?.error_code || '') === 'GIT_UNFINISHED_MERGE' ||
String(error?.detail?.error_code || '') === 'GIT_UNFINISHED_MERGE'
);
return (isGitStatusEndpoint && isNoRepoError) || (isGitPullEndpoint && isUnfinishedMergeError);
}
// [/DEF:shouldSuppressApiErrorToast:Function]
@@ -130,7 +150,7 @@ async function fetchApiBlob(endpoint, options = {}) {
if (response.status === 202) {
const payload = await response.json().catch(() => ({ message: "Resource is being prepared" }));
const error = new Error(payload?.message || "Resource is being prepared");
error.status = 202;
/** @type {any} */ (error).status = 202;
throw error;
}
if (!response.ok) {

View File

@@ -295,6 +295,18 @@
"ahead_remote": "Ahead Remote",
"diverged": "Diverged",
"error": "Error"
},
"unfinished_merge": {
"title": "Repository has an unfinished merge",
"default_message": "An unfinished merge was detected. Resolve conflicts or abort merge manually, then retry Pull.",
"repository_path": "Repository path",
"branch": "Current branch",
"next_steps": "Recommended steps",
"manual_commands": "Manual recovery commands",
"copy_commands": "Copy commands",
"copy_success": "Commands copied to clipboard",
"copy_failed": "Failed to copy commands",
"copy_empty": "No commands to copy"
}
},
"dashboard": {

View File

@@ -294,6 +294,18 @@
"ahead_remote": "Опережает remote",
"diverged": "Расхождение",
"error": "Ошибка"
},
"unfinished_merge": {
"title": "Незавершённое слияние в репозитории",
"default_message": "В репозитории найдено незавершённое слияние. Завершите или отмените его вручную и повторите Pull.",
"repository_path": "Путь к репозиторию",
"branch": "Текущая ветка",
"next_steps": "Рекомендуемые шаги",
"manual_commands": "Команды для ручного восстановления",
"copy_commands": "Скопировать команды",
"copy_success": "Команды скопированы в буфер обмена",
"copy_failed": "Не удалось скопировать команды",
"copy_empty": "Команды для копирования отсутствуют"
}
},
"dashboard": {