feat: auto-discover container images from registries

- Add ListImages() to registry interface, implement for Gitea
- Add owner field to registry config (needed for Gitea packages API)
- GET /api/registries/:id/images endpoint
- "Browse Images" button on Projects and Quick Deploy pages
- Image dropdown with registry grouping and search
- i18n support (EN/RU) for all new UI strings
This commit is contained in:
2026-03-28 14:04:11 +03:00
parent 77251c540b
commit 37e251da85
12 changed files with 355 additions and 18 deletions
+5
View File
@@ -7,6 +7,7 @@ import type {
Project,
ProjectDetail,
Registry,
RegistryImage,
Settings,
StageEnv,
Volume
@@ -220,6 +221,10 @@ export function listRegistryTags(registryId: string, image: string): Promise<str
return get<string[]>(`/api/registries/${registryId}/tags/${encodeURIComponent(image)}`);
}
export function listRegistryImages(registryId: string): Promise<RegistryImage[]> {
return get<RegistryImage[]>(`/api/registries/${registryId}/images`);
}
// ── Settings ────────────────────────────────────────────────────────
export function getSettings(): Promise<Settings> {
+14 -2
View File
@@ -39,7 +39,12 @@
"healthcheck": "Healthcheck Path",
"nameRequired": "Name and image are required.",
"loadFailed": "Failed to load projects",
"createFailed": "Failed to create project"
"createFailed": "Failed to create project",
"browseImages": "Browse Images",
"selectImage": "Select an image",
"noImages": "No images found",
"loadingImages": "Loading images...",
"imageLoadFailed": "Failed to load images"
},
"projectDetail": {
"deleteProject": "Delete Project",
@@ -158,7 +163,12 @@
"inspectedSuccess": "Image inspected successfully",
"deployedSuccess": "Deployed {name} successfully!",
"inspectFailed": "Failed to inspect image",
"deployFailed": "Deployment failed"
"deployFailed": "Deployment failed",
"browseImages": "Browse",
"selectImage": "Select an image from a registry",
"noImages": "No images found",
"loadingImages": "Loading...",
"imageLoadFailed": "Failed to load images"
},
"settings": {
"title": "Settings",
@@ -214,6 +224,8 @@
"token": "Token",
"tokenHelpNew": "API token for authentication",
"tokenHelpEdit": "Leave empty to keep the existing token",
"owner": "Owner",
"ownerHelp": "Package owner (e.g., username or organization) for image listing",
"save": "Save",
"saving": "Saving...",
"update": "Update",
+14 -2
View File
@@ -39,7 +39,12 @@
"healthcheck": "Путь проверки здоровья",
"nameRequired": "Название и образ обязательны.",
"loadFailed": "Не удалось загрузить проекты",
"createFailed": "Не удалось создать проект"
"createFailed": "Не удалось создать проект",
"browseImages": "Обзор образов",
"selectImage": "Выберите образ",
"noImages": "Образы не найдены",
"loadingImages": "Загрузка образов...",
"imageLoadFailed": "Не удалось загрузить образы"
},
"projectDetail": {
"deleteProject": "Удалить проект",
@@ -158,7 +163,12 @@
"inspectedSuccess": "Образ успешно проверен",
"deployedSuccess": "{name} успешно развёрнут!",
"inspectFailed": "Не удалось проверить образ",
"deployFailed": "Развёртывание не удалось"
"deployFailed": "Развёртывание не удалось",
"browseImages": "Обзор",
"selectImage": "Выберите образ из реестра",
"noImages": "Образы не найдены",
"loadingImages": "Загрузка...",
"imageLoadFailed": "Не удалось загрузить образы"
},
"settings": {
"title": "Настройки",
@@ -214,6 +224,8 @@
"token": "Токен",
"tokenHelpNew": "API-токен для аутентификации",
"tokenHelpEdit": "Оставьте пустым, чтобы сохранить текущий токен",
"owner": "Владелец",
"ownerHelp": "Владелец пакетов (имя пользователя или организации) для списка образов",
"save": "Сохранить",
"saving": "Сохранение...",
"update": "Обновить",
+9
View File
@@ -79,10 +79,19 @@ export interface Registry {
url: string;
type: string;
token: string;
owner: string;
has_token?: boolean;
created_at: string;
updated_at: string;
}
/** A container image discovered from a registry. */
export interface RegistryImage {
name: string;
owner: string;
full_ref: string;
}
export interface Settings {
domain: string;
server_ip: string;