diff --git a/src/App.vue b/src/App.vue index d8352e91..7e5185ed 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,11 +1,17 @@ - - + + - + diff --git a/src/components/displays/superuser/configuration/ConfigurationCategory.vue b/src/components/displays/superuser/configuration/ConfigurationCategory.vue index b752d3d7..fbed46c4 100644 --- a/src/components/displays/superuser/configuration/ConfigurationCategory.vue +++ b/src/components/displays/superuser/configuration/ConfigurationCategory.vue @@ -9,9 +9,13 @@ const props = defineProps({ subtitle: String, icon: String, isSkeleton: Boolean, + defaultExpanded: { + type: Boolean, + default: false, + }, }); -const isExpanded = ref(false); +const isExpanded = ref(props.defaultExpanded); const skeletonSpaces = (length) => { // Create a string with non-breaking spaces return Array.from({ length }, () => '\u00A0').join(''); @@ -58,4 +62,4 @@ const skeletonSpaces = (length) => { \ No newline at end of file + diff --git a/src/components/global/ErrorReportLauncher.vue b/src/components/global/ErrorReportLauncher.vue index a9612062..e46c1823 100644 --- a/src/components/global/ErrorReportLauncher.vue +++ b/src/components/global/ErrorReportLauncher.vue @@ -56,6 +56,19 @@ const isValid = computed(() => ( const recentRequestErrors = computed(() => Array.from(requestQueueState.errorRequests || []).slice(0, 25)); const recentVueErrors = computed(() => getRecentFrontendFailureEvents().slice(0, 25)); +let html2canvasPromise = null; + +const loadHtml2Canvas = () => { + if (!html2canvasPromise) { + html2canvasPromise = import("html2canvas") + .then((module) => module.default) + .catch((error) => { + html2canvasPromise = null; + throw error; + }); + } + return html2canvasPromise; +}; const redactCurrentUrl = () => { if (typeof window === "undefined") { @@ -80,6 +93,7 @@ const open = () => { submitError.value = ""; submitted.value = false; isOpen.value = true; + void loadHtml2Canvas().catch(() => {}); }; const close = () => { @@ -105,17 +119,76 @@ const canvasToDataUrl = (canvas) => { return canvas.toDataURL("image/png"); }; -const captureScreenshot = async () => { - await nextTick(); - const html2canvas = (await import("html2canvas")).default; - const target = document.querySelector("#app") || document.body; - const canvas = await html2canvas(target, { +const getViewportCaptureOptions = (overrides = {}) => { + const scrollX = window.scrollX || window.pageXOffset || 0; + const scrollY = window.scrollY || window.pageYOffset || 0; + const width = Math.max(1, window.innerWidth || document.documentElement.clientWidth || 1); + const height = Math.max(1, window.innerHeight || document.documentElement.clientHeight || 1); + + return { backgroundColor: "#ffffff", scale: Math.min(window.devicePixelRatio || 1, 2), useCORS: true, + allowTaint: false, + imageTimeout: 3000, logging: false, + width, + height, + x: scrollX, + y: scrollY, + scrollX: -scrollX, + scrollY: -scrollY, + windowWidth: width, + windowHeight: height, ignoreElements: (element) => Boolean(element.closest?.("[data-error-report-exclude]")), + onclone: (clonedDocument) => { + clonedDocument.querySelectorAll("[data-error-report-exclude]").forEach((element) => element.remove()); + clonedDocument.querySelectorAll("img").forEach((image) => { + const source = image.currentSrc || image.src || ""; + if (!source) { + return; + } + + try { + const url = new URL(source, window.location.href); + if (url.protocol !== "data:" && url.protocol !== "blob:" && url.origin !== window.location.origin) { + image.removeAttribute("src"); + image.style.visibility = "hidden"; + } + } catch { + image.removeAttribute("src"); + image.style.visibility = "hidden"; + } + }); + }, + ...overrides, + }; +}; + +const hideCaptureExcludedElements = () => { + const originals = []; + document.querySelectorAll("[data-error-report-exclude]").forEach((element) => { + originals.push({ + element, + display: element.style.display, + priority: element.style.getPropertyPriority("display"), + }); + element.style.setProperty("display", "none", "important"); }); + + return () => { + originals.forEach(({ element, display, priority }) => { + if (display) { + element.style.setProperty("display", display, priority); + return; + } + element.style.removeProperty("display"); + }); + }; +}; + +const captureWithOptions = async (html2canvas, target, options) => { + const canvas = await html2canvas(target, options); const dataUrl = canvasToDataUrl(canvas); if (!dataUrl.startsWith("data:image/")) { throw new Error("Screenshot capture failed."); @@ -123,6 +196,30 @@ const captureScreenshot = async () => { return dataUrl; }; +const captureScreenshot = async () => { + await nextTick(); + const html2canvas = await loadHtml2Canvas(); + const restoreExcludedElements = hideCaptureExcludedElements(); + + try { + await nextTick(); + const target = document.body || document.documentElement; + try { + return await captureWithOptions(html2canvas, target, getViewportCaptureOptions()); + } catch (firstError) { + return await captureWithOptions( + html2canvas, + document.documentElement || target, + getViewportCaptureOptions({ foreignObjectRendering: true }) + ).catch(() => { + throw firstError; + }); + } + } finally { + restoreExcludedElements(); + } +}; + const buildContext = () => ({ route_path: route.path || window.location?.pathname || null, page_url: redactCurrentUrl(), diff --git a/src/components/release/ReleaseChannelSwitched.vue b/src/components/release/ReleaseChannelSwitched.vue new file mode 100644 index 00000000..76e3b6df --- /dev/null +++ b/src/components/release/ReleaseChannelSwitched.vue @@ -0,0 +1,267 @@ + + + + + diff --git a/src/components/release/ReleaseChannelUnavailable.vue b/src/components/release/ReleaseChannelUnavailable.vue new file mode 100644 index 00000000..c81717f7 --- /dev/null +++ b/src/components/release/ReleaseChannelUnavailable.vue @@ -0,0 +1,329 @@ + + + + + diff --git a/src/components/session/authenticatedRequest.vue b/src/components/session/authenticatedRequest.vue index 1cdf0b33..bcc87750 100644 --- a/src/components/session/authenticatedRequest.vue +++ b/src/components/session/authenticatedRequest.vue @@ -12,19 +12,6 @@ const getSelectedCustomerNumber = () => { return stored ? parseInt(stored) : null; }; -const isSuppressedLicensePlateExtractionError = (url, error) => { - if (url !== '/modules/scanner/lpr') { - return false; - } - - const responseMessage = error?.response?.data?.data?.message ?? error?.response?.data?.message; - if (typeof responseMessage !== 'string') { - return false; - } - - return responseMessage.toLowerCase().includes('license plate extraction failed'); -}; - export const authenticatedRequest = (url, method, data, catchCallable = null, thenCallable = null) => { const token = localStorage.getItem('token'); if (!token) { @@ -59,25 +46,10 @@ export const authenticatedRequest = (url, method, data, catchCallable = null, th params: method === 'GET' ? data : null, data: method === 'GET' ? null : data, headers, - }, - shouldRetry: (error) => !isSuppressedLicensePlateExtractionError(url, error), + } } ) .catch((error) => { - if (isSuppressedLicensePlateExtractionError(url, error)) { - return error?.response ?? { - status: 500, - data: { - success: false, - data: { - message: 'Internal server error: License plate extraction failed.' - }, - meta: [], - includes: [] - } - }; - } - if (catchCallable) { // Call the catch callable catchCallable(error); diff --git a/src/components/session/token/SessionUser.vue b/src/components/session/token/SessionUser.vue index 45fbe3a5..927912e5 100644 --- a/src/components/session/token/SessionUser.vue +++ b/src/components/session/token/SessionUser.vue @@ -1,59 +1,54 @@ diff --git a/src/config.js b/src/config.js index 280a58de..323df142 100644 --- a/src/config.js +++ b/src/config.js @@ -1,8 +1,38 @@ -export const IS_DEV = import.meta.env.VITE_IS_DEV; // Set to false in production +const parseBoolean = (value, fallback = false) => { + if (typeof value === "boolean") { + return value; + } + if (typeof value === "string") { + const normalized = value.trim().toLowerCase(); + if (["1", "true", "yes", "on"].includes(normalized)) { + return true; + } + if (["0", "false", "no", "off"].includes(normalized)) { + return false; + } + } + return fallback; +}; + +const normalizeApiUrl = (value) => String(value || "").replace(/\/+$/, ""); + +export const IS_DEV = parseBoolean(import.meta.env.VITE_IS_DEV, import.meta.env.MODE !== "production"); // Development mode export const POS_STEP_1_VERSION = 2; //(IS_DEV ? 2 : 1); -export const API_URL = IS_DEV ? "https://api.truckwash.io:4433" : "https://api.truckwash.io"; +export const API_URL = normalizeApiUrl( + import.meta.env.VITE_API_URL || (IS_DEV ? "https://api.truckwash.io:4433" : "https://api.truckwash.io") +); +export const RELEASE_MANAGER_CONTROL_API_URL = normalizeApiUrl( + import.meta.env.VITE_RELEASE_MANAGER_CONTROL_API_URL || API_URL +); +export const RELEASE_MANAGER_CONTROL_API_FALLBACK_URLS = String( + import.meta.env.VITE_RELEASE_MANAGER_CONTROL_API_FALLBACK_URLS || + (IS_DEV ? "https://api.truckwash.io:4433,https://api.truckwash.io" : "") +) + .split(",") + .map((url) => normalizeApiUrl(url.trim())) + .filter(Boolean); // Allowed origins export const ALLOWED_ORIGINS = [ diff --git a/src/i18n/generated/da-v2.json b/src/i18n/generated/da-v2.json index 70fea25b..a0eee0b5 100644 --- a/src/i18n/generated/da-v2.json +++ b/src/i18n/generated/da-v2.json @@ -2437,6 +2437,412 @@ "subtitle": "@.capitalize:{'words.generated.konfiguration'} @:{'words.generated.af'} @:{'words.generated.xlvask'} @:{'words.generated.integrationen'}", "title": "@:{'words.generated.xlvask'} @:{'words.generated.konfiguration'}", "username_desc": "@.capitalize:{'words.generated.brugernavnet'} @:{'words.generated.bruges'} @:{'words.generated.til'} @:{'words.generated.at'} @:{'words.generated.autentificere'} @:{'words.generated.api'} @:{'words.generated.forbindelsen'}." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradvise API- og Front-End-udgivelser", + "control_api": { + "title": "Kontrol-API", + "tooltip": "Release Manager-handlinger sendes til denne API. Brug produktions-API'en, medmindre du tester en staging-backend.", + "example": "Eksempel: https://api.truckwash.io:4433", + "endpoint_label": "API-endpoint", + "endpoint_message": "Skift kun dette, n?r Release Manager-endpoints er tilg?ngelige p? m?l-API'en.", + "endpoint_aria": "Release Manager kontrol-API URL", + "use_tooltip": "Indl?s release-data fra denne API", + "use": "Brug", + "reset_tooltip": "Vend tilbage til standard kontrol-API", + "reset": "Nulstil", + "known_endpoints": "Kendte kontrol-API-endpoints" + }, + "tabs": { + "overview": { + "label": "Oversigt", + "description": "Kanalstatus, ops?tningsfremdrift og seneste release-tilstand." + }, + "channels": { + "label": "Kanaler", + "description": "Opret stabile, canary- og m?lrettede kanaler med rollout-gr?nser." + }, + "assignments": { + "label": "Tildelinger", + "description": "Fastg?r brugere, subbrugere eller kunder til en bestemt release-kanal." + }, + "deployments": { + "label": "Udrulninger", + "description": "Start udrulninger og promover vellykkede builds." + }, + "replay": { + "label": "Replay", + "description": "Aktiv?r m?lrettet opsamling og s?g i release-tidslinjeh?ndelser." + }, + "integrations": { + "label": "Integrationer", + "description": "Forbind GitHub-repositories, branches og Coolify-services." + }, + "settings": { + "label": "Indstillinger", + "description": "Konfigurer Release Managers GitHub-adgang og webhook-indstillinger." + } + }, + "setup": { + "channels": "Kanaler", + "targets": "GitHub- og Coolify-m?l", + "assignments": "Pilot-tildelinger", + "deployments": "F?rste udrulning", + "replay": "Replay-opsamling" + }, + "stats": { + "channels": "Kanaler", + "targets": "M?l", + "deployments": "Udrulninger", + "timeline_events": "Tidslinjeh?ndelser" + }, + "overview": { + "title": "Oversigt", + "subtitle": "Aktuel kanalstatus, release-aktivitet og modulstatus.", + "guided_setup": "Guidet ops?tning", + "next_step": "N?ste: {step}", + "ready": "Release Manager er klar til daglig drift.", + "add_suggested_channel": "Tilføj foreslået kanal", + "module_health_empty": "Modul-health snapshots vises, når probes er blevet registreret." + }, + "settings": { + "title": "Release Manager-indstillinger", + "subtitle": "Konfigurer GitHub-tokenet, der bruges til private repositories og branch-opslag.", + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "webhook_secret": "Webhook-hemmelighed", + "github_webhook_secret": "GitHub webhook-hemmelighed", + "configured": "Konfigureret", + "not_configured": "Ikke konfigureret", + "loaded_from": "Indl?st fra {variable}", + "set_below": "Angiv {variable} nedenfor", + "private_repositories_prefix": "Private repositories l?ses med serverens milj?variabel", + "private_repositories_or": "eller modulets konfigurationsvariabel", + "github_token_message": "Eksempel: github_pat_... med adgang til de private repositories, Release Manager udruller.", + "github_token_placeholder": "Lad feltet v?re tomt for at beholde det eksisterende token", + "github_api_url_message": "Konfigureret i ReleaseManager.github_api_url. Brug https://api.github.com medmindre GitHub Enterprise bruges.", + "webhook_secret_message": "Valgfrit; lad feltet v?re tomt for at beholde den eksisterende hemmelighed.", + "webhook_secret_placeholder": "Webhook HMAC-hemmelighed", + "save": "Gem indstillinger", + "back_to_integrations": "Tilbage til integrationer", + "guide": { + "steps": { + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Gennemgang" + }, + "github_token_title": "Tilføj GitHub-token", + "github_token_description": "Release Manager bruger denne token til at vise private repositories, branches og commits, før et deployment-mål gemmes eller testes.", + "configure_this_in": "Konfigurer dette i", + "server_environment_variable": "Serverens miljøvariabel", + "takes_precedence": "har forrang, når den er sat.", + "recommended_access": "Anbefalet adgang", + "recommended_access_description": "Fine-grained GitHub-token med Contents: read-adgang til hvert release-repository.", + "github_api_url_title": "Tilføj GitHub API-URL", + "github_api_url_description": "Brug GitHub Cloud som standard, eller peg på REST API-base-URLen for en GitHub Enterprise Server-installation.", + "github_api_url_invalid": "Indtast en fuld HTTP- eller HTTPS-URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-eksempel", + "github_webhook_secret_title": "Tilføj GitHub webhook secret", + "github_webhook_secret_description": "Brug samme secret i GitHub repository-webhooks, så Release Manager kan verificere deployment-events, før de håndteres.", + "github_webhook_url": "GitHub webhook-URL:", + "store_shared_secret_in": "Gem den delte secret i", + "review_title": "Gennemgå GitHub-opsætning", + "review_description": "Gem værdierne, og brug derefter Integrationer til at vælge et privat repository, branch og specifik commit eller seneste commit før adgang testes.", + "ready": "Klar", + "needs_value": "Mangler værdi" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-kanalen er ikke klar", + "summary_prefix": "Din konto er tildelt", + "summary_suffix": ", men kanalen mangler den konfiguration, der skal bruges for at indl?se dens release-image.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Tjekker igen om {seconds}s", + "refresh_error": "Release-status kunne ikke opdateres. Det n?ste automatiske tjek pr?ver igen.", + "ignore": "Ignorer de n?ste 5 minutter", + "check_again": "Tjek igen", + "logout": "Log ud", + "base_image": "Basis-image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du er nu p? {channel}", + "summary_prefix": "Din konto er blevet tildelt release-kanalen", + "summary_suffix": "Denne enhed husker, at du har set denne besked.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-version", + "api_version": "API-version", + "assigned_channel": "Tildelt kanal", + "current_app_image": "Nuv?rende app-image", + "current_api": "Nuv?rende API", + "base_image": "Basis-image", + "continue": "Forts?t" + }, + "common": { + "yes": "ja", + "no": "nej", + "off": "fra" + }, + "actions": { + "edit": "Rediger", + "rollback": "Rul tilbage", + "update": "Opdater", + "create": "Opret", + "clear": "Ryd", + "assign": "Tildel", + "remove": "Fjern", + "test_access": "Test adgang", + "deploy": "Deploy", + "promote": "Promover", + "enable": "Aktiver", + "search": "Søg", + "save_target": "Gem mål", + "delete": "Slet", + "back": "Tilbage", + "next": "Næste" + }, + "tables": { + "channel": "Kanal", + "rollout": "Udrulning", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Handlinger", + "module": "Modul", + "status": "Status", + "checked": "Kontrolleret", + "subject": "Emne", + "reason": "Årsag", + "expires": "Udløber", + "deployment": "Deployment", + "source": "Kilde", + "started": "Startet", + "target": "Mål", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "fuldt redigeret" + }, + "subject_type": { + "user": "bruger", + "subuser": "medarbejder", + "customer": "kunde", + "channel": "kanal" + }, + "severity": { + "error": "fejl", + "warning": "advarsel", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployet", + "stable": "stabil", + "enabled": "aktiveret", + "queued": "i kø", + "deploying": "deploying", + "metadata": "metadata", + "not_configured": "ikke konfigureret", + "warning": "advarsel", + "failed": "fejlet", + "down": "nede", + "error": "fejl", + "unknown": "ukendt" + } + }, + "autocomplete": { + "suggested_value": "Foreslået værdi", + "suggestion": "Forslag", + "use_typed_value": "Brug indtastet værdi", + "custom": "Tilpasset", + "api_url": "API-URL", + "frontend_url": "Frontend-URL", + "known_release_url": "Kendt release-URL", + "deploy_here_with_coolify": "Deploy {app} her med Coolify", + "prepare_coolify_target": "Forbered et Coolify-mål med HTTPS/SSL aktiveret", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-repository", + "owner_repository": "ejer/repository", + "git_branch": "Git-branch", + "deployment_branch": "Deployment-branch", + "github_commit": "GitHub-commit", + "git_commit": "Git-commit", + "use_specific_commit_sha": "Brug specifik commit-SHA", + "custom_commit": "Tilpasset commit", + "health_url": "Health-URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify-service", + "service_uuid": "Service-UUID", + "known_coolify_service_uuid": "Kendt Coolify service-UUID", + "control_api": "Kontrol-API", + "release_manager_api_endpoint": "Release Manager API-endpoint", + "module": "Modul", + "timeline_module_key": "Timeline-modulnøgle" + }, + "errors": { + "github_repositories": "Kunne ikke indlæse GitHub-repositories.", + "github_branches": "Kunne ikke indlæse GitHub-branches.", + "repository_branch_required": "Repository og branch er påkrævet før GitHub-adgang kan testes.", + "github_access_failed": "Test af GitHub repository-adgang fejlede." + }, + "channels": { + "title": "Kanaler", + "subtitle": "Opret og juster gradvise release-kanaler.", + "rollout_percent": "{percent}% udrulning", + "already_configured": "Allerede konfigureret", + "slug": "Slug", + "slug_message": "Eksempel: canary", + "slug_placeholder": "slug", + "name": "Navn", + "name_message": "Vises til operatører, når de gennemgår en kanal.", + "name_placeholder": "Navn", + "rollout": "Udrulning", + "rollout_message": "0-100 procent af ikke-tildelt trafik.", + "frontend_url": "Frontend-URL", + "frontend_url_message": "Eksempel: https://canary.example.test", + "frontend_url_placeholder": "Frontend-URL", + "no_matching_release_url": "Ingen matchende release-URL.", + "api_url": "API-URL", + "api_url_message": "Eksempel: https://api-canary.example.test", + "api_url_placeholder": "API-URL", + "no_matching_api_url": "Ingen matchende API-URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata er sikrere til brede kanaler.", + "retention_days": "Opbevaringsdage", + "retention_days_message": "1-365 dage.", + "enabled": "Aktiveret", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktiveret", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Tildelinger", + "subtitle": "Fastgør brugere, medarbejdere eller kunder til release-kanaler.", + "subject_type": "Emnetype", + "subject_type_message": "Vælg identitetstypen, der skal fastgøres.", + "customer": "Kunde", + "customer_message": "Søg på kundenummer eller navn, og vælg derefter den præcise kunde.", + "customer_placeholder": "Søg kunde", + "subject_id": "Emne-ID", + "subject_id_message": "Eksempel: bruger-id 42", + "subject_id_placeholder": "Emne-id", + "channel": "Kanal", + "channel_message": "Fastgjorte emner springer procentudrulningen over.", + "reason": "Årsag", + "reason_message": "Eksempel: canary-validering for kundesupport.", + "reason_placeholder": "Årsag", + "expires": "Udløber", + "expires_message": "Lad feltet være tomt for ingen automatisk udløb." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Start, promover og inspicer release-deployments.", + "manual_deployment_record": "Manuel deployment-post", + "target": "Mål", + "target_message": "Vælg et gemt mål, eller behold manuelle felter redigerbare.", + "select_target_or_manual": "Vælg mål eller manuel", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/front-end-vue", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-valg", + "commit_selection_message": "Seneste slås op som branchens head med den konfigurerede GitHub-token.", + "latest_from_branch": "Seneste fra branch", + "specific_commit": "Specifik commit", + "specific_commit_message": "Eksempel: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versionslabel", + "version_label_message": "Eksempel: api-2026.05.19", + "version_label_placeholder": "versionslabel", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Bekræft token-adgang til det valgte repository, branch og commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Aktiver målrettet capture og gennemgå fejltimelines trin for trin.", + "capture_channel": "Capture {channel}", + "target_type": "Måltype", + "target": "Mål", + "target_message": "Eksempel: bruger-id 42 eller kanal-slug canary.", + "target_placeholder": "Mål-id eller kanal-slug", + "channel_scope": "Kanalafgrænsning", + "channel_scope_message": "Valgfrit; begrænser replay capture til en kanal.", + "no_channel_scope": "Ingen kanalafgrænsning", + "capture_level": "Capture-niveau", + "expires": "Udløber", + "expires_message": "Lad feltet være tomt for manuel deaktivering.", + "trace_id": "Trace-ID", + "trace_id_message": "Eksempel: trace-canary-1", + "trace_id_placeholder": "Trace-id", + "channel": "Kanal", + "channel_placeholder": "Kanal", + "principal_id": "Principal-ID", + "principal_id_placeholder": "Principal-id", + "module": "Modul", + "module_placeholder": "Modul", + "severity": "Alvorlighed", + "any_severity": "Alle alvorligheder", + "no_timeline_events": "Ingen timeline-events matcher de aktuelle filtre." + }, + "integrations": { + "title": "GitHub og Coolify", + "subtitle": "Knyt GitHub-repositories og branches til kanalspecifikke Coolify-services.", + "choose_repository": "Vælg repository", + "add_health_url": "tilføj health-URL", + "github_token_not_configured": "GitHub-token er ikke konfigureret; private repositories kan ikke vises.", + "open_github_token_settings": "Åbn GitHub token-indstillinger", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/backend-php", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Seneste: {commit}", + "coolify_instance": "Coolify-instans", + "coolify_instance_message": "Lad feltet være tomt for manuelle deployment-poster.", + "no_coolify_instance": "Ingen Coolify-instans", + "coolify_instance_placeholder": "Coolify-instans-id", + "coolify_service_uuid": "Coolify service-UUID", + "coolify_service_uuid_message": "Vælg en eksisterende service eller indsæt en UUID.", + "coolify_service_uuid_placeholder": "Coolify service-UUID", + "health_url": "Health-URL", + "health_url_message": "Eksempel: https://api-canary.example.test/ping", + "health_url_placeholder": "Health-URL", + "ssl_domain": "SSL-domæne", + "ssl_domain_message": "Eksempel: canary.example.test", + "ssl_domain_placeholder": "SSL-domæne", + "https_domain_for_coolify": "HTTPS-domæne til Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Opret automatisk deployments, når dette mål ændres.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Bed Coolify om at oprette HTTPS for det konfigurerede domæne.", + "deploy_now": "Deploy nu", + "deploy_now_tooltip": "Start en deployment straks efter målet gemmes.", + "create_missing_service": "Opret manglende service", + "create_missing_service_tooltip": "Tillad Release Manager at oprette en manglende Coolify-service.", + "test_access_tooltip": "Bekræft, at den konfigurerede GitHub-token kan læse dette repository og branch." + } } }, "connectivity": { diff --git a/src/i18n/generated/de-v2.json b/src/i18n/generated/de-v2.json index afc69f3b..25b0a80c 100644 --- a/src/i18n/generated/de-v2.json +++ b/src/i18n/generated/de-v2.json @@ -2547,6 +2547,412 @@ "subtitle": "@:{'words.generated.konfiguration'} @:{'words.generated.der'} @:{'words.generated.xlvask'}-@.capitalize:{'words.generated.integration'}", "title": "@:{'words.generated.xlvask'}-@:{'words.generated.konfiguration'}", "username_desc": "@.capitalize:{'words.generated.der'} @:{'words.generated.benutzername'} @:{'words.generated.wird'} @:{'words.generated.zur'} @:{'words.generated.authentifizierung'} @:{'words.generated.der'} @:{'words.generated.api'}-@:{'words.generated.verbindung'} @:{'words.generated.verwendet'}." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Schrittweise API- und Front-End-Releases", + "control_api": { + "title": "Kontroll-API", + "tooltip": "Release-Manager-Aktionen werden an diese API gesendet. Verwende die Produktions-Kontroll-API, au?er du testest ein Staging-Backend.", + "example": "Beispiel: https://api.truckwash.io:4433", + "endpoint_label": "API-Endpunkt", + "endpoint_message": "?ndere dies nur, wenn Release-Manager-Endpunkte auf der Ziel-API verf?gbar sind.", + "endpoint_aria": "Release Manager Kontroll-API-URL", + "use_tooltip": "Release-Daten von dieser API laden", + "use": "Verwenden", + "reset_tooltip": "Zur Standard-Kontroll-API zur?ckkehren", + "reset": "Zur?cksetzen", + "known_endpoints": "Bekannte Kontroll-API-Endpunkte" + }, + "tabs": { + "overview": { + "label": "?bersicht", + "description": "Kanalzustand, Einrichtungsfortschritt und aktueller Release-Status." + }, + "channels": { + "label": "Kan?le", + "description": "Stabile, Canary- und Zielkan?le mit Rollout-Grenzen erstellen." + }, + "assignments": { + "label": "Zuweisungen", + "description": "Benutzer, Unterbenutzer oder Kunden einem bestimmten Release-Kanal zuweisen." + }, + "deployments": { + "label": "Bereitstellungen", + "description": "Bereitstellungen starten und erfolgreiche Builds promoten." + }, + "replay": { + "label": "Replay", + "description": "Gezielte Erfassung aktivieren und Release-Timeline-Ereignisse durchsuchen." + }, + "integrations": { + "label": "Integrationen", + "description": "GitHub-Repositories, Branches und Coolify-Dienste verbinden." + }, + "settings": { + "label": "Einstellungen", + "description": "GitHub-Zugriff und Webhook-Einstellungen des Release Managers konfigurieren." + } + }, + "setup": { + "channels": "Kan?le", + "targets": "GitHub- und Coolify-Ziele", + "assignments": "Pilot-Zuweisungen", + "deployments": "Erste Bereitstellung", + "replay": "Replay-Erfassung" + }, + "stats": { + "channels": "Kan?le", + "targets": "Ziele", + "deployments": "Bereitstellungen", + "timeline_events": "Timeline-Ereignisse" + }, + "overview": { + "title": "?bersicht", + "subtitle": "Aktueller Kanalzustand, Release-Aktivit?t und Modulstatus.", + "guided_setup": "Gef?hrte Einrichtung", + "next_step": "N?chster Schritt: {step}", + "ready": "Release Manager ist f?r den t?glichen Betrieb bereit.", + "add_suggested_channel": "Vorgeschlagenen Kanal hinzufügen", + "module_health_empty": "Modul-Health-Snapshots erscheinen, nachdem Probes aufgezeichnet wurden." + }, + "settings": { + "title": "Release-Manager-Einstellungen", + "subtitle": "GitHub-Token f?r private Repositories und Branch-Abfragen konfigurieren.", + "github_token": "GitHub-Token", + "github_api_url": "GitHub-API-URL", + "webhook_secret": "Webhook-Secret", + "github_webhook_secret": "GitHub-Webhook-Secret", + "configured": "Konfiguriert", + "not_configured": "Nicht konfiguriert", + "loaded_from": "Geladen aus {variable}", + "set_below": "{variable} unten festlegen", + "private_repositories_prefix": "Private Repositories werden mit der Server-Umgebungsvariable gelesen", + "private_repositories_or": "oder der Modul-Konfigurationsvariable", + "github_token_message": "Beispiel: github_pat_... mit Zugriff auf die privaten Repositories, die Release Manager bereitstellt.", + "github_token_placeholder": "Leer lassen, um das vorhandene Token zu behalten", + "github_api_url_message": "Konfiguriert in ReleaseManager.github_api_url. https://api.github.com verwenden, sofern GitHub Enterprise nicht genutzt wird.", + "webhook_secret_message": "Optional; leer lassen, um das vorhandene Secret zu behalten.", + "webhook_secret_placeholder": "Webhook-HMAC-Secret", + "save": "Einstellungen speichern", + "back_to_integrations": "Zur?ck zu Integrationen", + "guide": { + "steps": { + "github_token": "GitHub-Token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub Webhook Secret", + "review": "Prüfung" + }, + "github_token_title": "GitHub-Token hinzufügen", + "github_token_description": "Release Manager verwendet diesen Token, um private Repositories, Branches und Commits aufzulisten, bevor ein Deployment-Ziel gespeichert oder getestet wird.", + "configure_this_in": "Dies konfigurieren in", + "server_environment_variable": "Die Server-Umgebungsvariable", + "takes_precedence": "hat Vorrang, wenn sie gesetzt ist.", + "recommended_access": "Empfohlener Zugriff", + "recommended_access_description": "Fine-grained GitHub-Token mit Contents: read-Zugriff für jedes Release-Repository.", + "github_api_url_title": "GitHub API-URL hinzufügen", + "github_api_url_description": "GitHub Cloud standardmäßig verwenden oder auf die REST-API-Basis-URL einer GitHub Enterprise Server-Installation zeigen.", + "github_api_url_invalid": "Vollständige HTTP- oder HTTPS-URL eingeben.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-Beispiel", + "github_webhook_secret_title": "GitHub Webhook Secret hinzufügen", + "github_webhook_secret_description": "Dasselbe Secret in GitHub-Repository-Webhooks verwenden, damit Release Manager Deployment-Events vor der Verarbeitung verifizieren kann.", + "github_webhook_url": "GitHub Webhook-URL:", + "store_shared_secret_in": "Geteiltes Secret speichern in", + "review_title": "GitHub-Konfiguration prüfen", + "review_description": "Werte speichern und dann unter Integrationen ein privates Repository, einen Branch und einen bestimmten Commit oder den neuesten Commit auswählen, bevor der Zugriff getestet wird.", + "ready": "Bereit", + "needs_value": "Wert fehlt" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-Kanal ist nicht bereit", + "summary_prefix": "Dein Konto ist zugewiesen zu", + "summary_suffix": ", aber diesem Kanal fehlt die Konfiguration, um sein Release-Image zu laden.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Erneute Pr?fung in {seconds}s", + "refresh_error": "Release-Status konnte nicht aktualisiert werden. Die n?chste automatische Pr?fung versucht es erneut.", + "ignore": "N?chste 5 Minuten ignorieren", + "check_again": "Erneut pr?fen", + "logout": "Abmelden", + "base_image": "Basis-Image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du bist jetzt auf {channel}", + "summary_prefix": "Dein Konto wurde dem Release-Kanal", + "summary_suffix": "zugewiesen. Dieses Ger?t merkt sich, dass du diesen Hinweis gesehen hast.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-Version", + "api_version": "API-Version", + "assigned_channel": "Zugewiesener Kanal", + "current_app_image": "Aktuelles App-Image", + "current_api": "Aktuelle API", + "base_image": "Basis-Image", + "continue": "Fortfahren" + }, + "common": { + "yes": "ja", + "no": "nein", + "off": "aus" + }, + "actions": { + "edit": "Bearbeiten", + "rollback": "Zurückrollen", + "update": "Aktualisieren", + "create": "Erstellen", + "clear": "Leeren", + "assign": "Zuweisen", + "remove": "Entfernen", + "test_access": "Zugriff testen", + "deploy": "Deployen", + "promote": "Promoten", + "enable": "Aktivieren", + "search": "Suchen", + "save_target": "Ziel speichern", + "delete": "Löschen", + "back": "Zurück", + "next": "Weiter" + }, + "tables": { + "channel": "Kanal", + "rollout": "Rollout", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Aktionen", + "module": "Module", + "status": "Status", + "checked": "Geprüft", + "subject": "Subjekt", + "reason": "Grund", + "expires": "Läuft ab", + "deployment": "Deployment", + "source": "Quelle", + "started": "Gestartet", + "target": "Ziel", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "Frontend", + "api": "API" + }, + "capture_level": { + "metadata": "Metadaten", + "full_redacted": "vollständig redigiert" + }, + "subject_type": { + "user": "Benutzer", + "subuser": "Mitarbeiter", + "customer": "Kunde", + "channel": "Kanal" + }, + "severity": { + "error": "Fehler", + "warning": "Warnung", + "info": "Info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployt", + "stable": "stabil", + "enabled": "aktiviert", + "queued": "in Warteschlange", + "deploying": "deploying", + "metadata": "Metadaten", + "not_configured": "nicht konfiguriert", + "warning": "Warnung", + "failed": "fehlgeschlagen", + "down": "down", + "error": "Fehler", + "unknown": "unbekannt" + } + }, + "autocomplete": { + "suggested_value": "Vorgeschlagener Wert", + "suggestion": "Vorschlag", + "use_typed_value": "Eingegebenen Wert verwenden", + "custom": "Benutzerdefiniert", + "api_url": "API URL", + "frontend_url": "Frontend URL", + "known_release_url": "Bekannte Release-URL", + "deploy_here_with_coolify": "{app} hier mit Coolify deployen", + "prepare_coolify_target": "Coolify-Ziel mit aktiviertem HTTPS/SSL vorbereiten", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-Repository", + "owner_repository": "owner/repository", + "git_branch": "Git branch", + "deployment_branch": "Deployment branch", + "github_commit": "GitHub commit", + "git_commit": "Git commit", + "use_specific_commit_sha": "Bestimmte Commit-SHA verwenden", + "custom_commit": "Benutzerdefinierter Commit", + "health_url": "Health URL", + "release_health_check": "Release-Health-Check", + "coolify_service": "Coolify service", + "service_uuid": "Service UUID", + "known_coolify_service_uuid": "Known Coolify service UUID", + "control_api": "Kontroll-API", + "release_manager_api_endpoint": "Release Manager API-Endpunkt", + "module": "Module", + "timeline_module_key": "Timeline-Modulschlüssel" + }, + "errors": { + "github_repositories": "GitHub-Repositories konnten nicht geladen werden.", + "github_branches": "GitHub-Branches konnten nicht geladen werden.", + "repository_branch_required": "Repository und Branch sind erforderlich, bevor GitHub-Zugriff getestet werden kann.", + "github_access_failed": "GitHub-Repository-Zugriffstest ist fehlgeschlagen." + }, + "channels": { + "title": "Kanäle", + "subtitle": "Graduale Release-Kanäle erstellen und anpassen.", + "rollout_percent": "{percent}% rollout", + "already_configured": "Bereits konfiguriert", + "slug": "Slug", + "slug_message": "Example: canary", + "slug_placeholder": "slug", + "name": "Name", + "name_message": "Wird Operatoren bei der Kanalprüfung angezeigt.", + "name_placeholder": "Name", + "rollout": "Rollout", + "rollout_message": "0-100 Prozent des nicht zugewiesenen Traffics.", + "frontend_url": "Frontend URL", + "frontend_url_message": "Example: https://canary.example.test", + "frontend_url_placeholder": "Frontend URL", + "no_matching_release_url": "Keine passende Release-URL.", + "api_url": "API URL", + "api_url_message": "Example: https://api-canary.example.test", + "api_url_placeholder": "API URL", + "no_matching_api_url": "Keine passende API-URL.", + "replay_capture": "Replay-Erfassung", + "replay_capture_message": "Metadaten sind für breite Kanäle sicherer.", + "retention_days": "Aufbewahrungstage", + "retention_days_message": "1-365 Tage.", + "enabled": "Aktiviert", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktiviert", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Zuweisungen", + "subtitle": "Benutzer, Mitarbeiter oder Kunden an Release-Kanäle binden.", + "subject_type": "Subjekttyp", + "subject_type_message": "Identitätstyp zum Binden auswählen.", + "customer": "Customer", + "customer_message": "Nach Kundennummer oder Name suchen und dann den genauen Kunden auswählen.", + "customer_placeholder": "Kunde suchen", + "subject_id": "Subjekt-ID", + "subject_id_message": "Beispiel: Benutzer-ID 42", + "subject_id_placeholder": "Subjekt-ID", + "channel": "Channel", + "channel_message": "Gebundene Subjekte umgehen den prozentualen Rollout.", + "reason": "Grund", + "reason_message": "Beispiel: Canary-Validierung für Kundensupport.", + "reason_placeholder": "Grund", + "expires": "Läuft ab", + "expires_message": "Leer lassen für kein automatisches Ablaufdatum." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Release-Deployments starten, promoten und prüfen.", + "manual_deployment_record": "Manueller Deployment-Eintrag", + "target": "Ziel", + "target_message": "Gespeichertes Ziel wählen oder manuelle Felder editierbar lassen.", + "select_target_or_manual": "Ziel oder manuell auswählen", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/front-end-vue", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-Auswahl", + "commit_selection_message": "Neueste Version wird mit dem konfigurierten GitHub-Token als Branch-Head aufgelöst.", + "latest_from_branch": "Neuester vom Branch", + "specific_commit": "Bestimmter Commit", + "specific_commit_message": "Example: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versionslabel", + "version_label_message": "Example: api-2026.05.19", + "version_label_placeholder": "Versionslabel", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Token-Zugriff auf das ausgewählte Repository, den Branch und Commit prüfen." + }, + "replay": { + "title": "Replay", + "subtitle": "Gezielte Erfassung aktivieren und Fehler-Timelines Schritt für Schritt prüfen.", + "capture_channel": "{channel} erfassen", + "target_type": "Zieltyp", + "target": "Ziel", + "target_message": "Beispiel: Benutzer-ID 42 oder Kanal-Slug canary.", + "target_placeholder": "Ziel-ID oder Kanal-Slug", + "channel_scope": "Kanalbereich", + "channel_scope_message": "Optional; begrenzt Replay-Erfassung auf einen Kanal.", + "no_channel_scope": "Kein Kanalbereich", + "capture_level": "Erfassungsstufe", + "expires": "Läuft ab", + "expires_message": "Leer lassen für manuelle Deaktivierung.", + "trace_id": "Trace ID", + "trace_id_message": "Example: trace-canary-1", + "trace_id_placeholder": "Trace id", + "channel": "Channel", + "channel_placeholder": "Channel", + "principal_id": "Principal ID", + "principal_id_placeholder": "Principal-ID", + "module": "Module", + "module_placeholder": "Module", + "severity": "Schweregrad", + "any_severity": "Beliebiger Schweregrad", + "no_timeline_events": "Keine Timeline-Events entsprechen den aktuellen Filtern." + }, + "integrations": { + "title": "GitHub und Coolify", + "subtitle": "GitHub-Repositories und Branches kanalspezifischen Coolify-Services zuordnen.", + "choose_repository": "Repository auswählen", + "add_health_url": "Health-URL hinzufügen", + "github_token_not_configured": "GitHub-Token ist nicht konfiguriert; private Repositories können nicht aufgelistet werden.", + "open_github_token_settings": "GitHub-Token-Einstellungen öffnen", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/backend-php", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Neueste: {commit}", + "coolify_instance": "Coolify-Instanz", + "coolify_instance_message": "Leer lassen für manuelle Deployment-Einträge.", + "no_coolify_instance": "Keine Coolify-Instanz", + "coolify_instance_placeholder": "Coolify-Instanz-ID", + "coolify_service_uuid": "Coolify service UUID", + "coolify_service_uuid_message": "Bestehenden Service auswählen oder UUID einfügen.", + "coolify_service_uuid_placeholder": "Coolify service UUID", + "health_url": "Health URL", + "health_url_message": "Example: https://api-canary.example.test/ping", + "health_url_placeholder": "Health URL", + "ssl_domain": "SSL-Domain", + "ssl_domain_message": "Example: canary.example.test", + "ssl_domain_placeholder": "SSL-Domain", + "https_domain_for_coolify": "HTTPS-Domain für Coolify", + "auto_deploy": "Auto-Deploy", + "auto_deploy_tooltip": "Automatisch Deployments erstellen, wenn sich dieses Ziel ändert.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Coolify anweisen, HTTPS für die konfigurierte Domain bereitzustellen.", + "deploy_now": "Jetzt deployen", + "deploy_now_tooltip": "Deployment direkt nach dem Speichern des Ziels starten.", + "create_missing_service": "Fehlenden Service erstellen", + "create_missing_service_tooltip": "Release Manager erlauben, einen fehlenden Coolify-Service zu erstellen.", + "test_access_tooltip": "Prüfen, ob der konfigurierte GitHub-Token dieses Repository und den Branch lesen kann." + } } }, "connectivity": { diff --git a/src/i18n/generated/en-v2.json b/src/i18n/generated/en-v2.json index 38aff4ae..954ebb2c 100644 --- a/src/i18n/generated/en-v2.json +++ b/src/i18n/generated/en-v2.json @@ -2271,6 +2271,412 @@ "subtitle": "@.capitalize:{'words.generated.configuration'} @:{'words.generated.of'} @:{'words.replication.article.host_mention'} @:{'words.generated.xlvask'} @:{'words.generated.integration'}", "title": "@:{'words.generated.xlvask'} @:{'words.generated.configuration'}", "username_desc": "@.capitalize:{'words.replication.article.host_mention'} @:{'words.generated.username'} @:{'words.generated.is'} @:{'words.generated.used'} @:{'words.generated.to'} @:{'words.generated.authenticate'} @:{'words.replication.article.host_mention'} @:{'words.generated.api'} @:{'words.generated.connection'}." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradual API and Front-End releases", + "control_api": { + "title": "Control API", + "tooltip": "Release Manager actions are sent to this API. Use the production control API unless testing a staged backend.", + "example": "Example: https://api.truckwash.io:4433", + "endpoint_label": "API endpoint", + "endpoint_message": "Switch this only when Release Manager endpoints are available on the target API.", + "endpoint_aria": "Release Manager control API URL", + "use_tooltip": "Load release data from this API", + "use": "Use", + "reset_tooltip": "Return to the default control API", + "reset": "Reset", + "known_endpoints": "Known control API endpoints" + }, + "tabs": { + "overview": { + "label": "Overview", + "description": "Channel health, setup progress, and the latest release state." + }, + "channels": { + "label": "Channels", + "description": "Create stable, canary, and targeted channels with rollout limits." + }, + "assignments": { + "label": "Assignments", + "description": "Pin users, subusers, or customers to a specific release channel." + }, + "deployments": { + "label": "Deployments", + "description": "Trigger deployments and promote successful builds." + }, + "replay": { + "label": "Replay", + "description": "Enable targeted capture and search release timeline events." + }, + "integrations": { + "label": "Integrations", + "description": "Connect GitHub repositories, branches, and Coolify services." + }, + "settings": { + "label": "Settings", + "description": "Configure Release Manager GitHub access and webhook settings." + } + }, + "setup": { + "channels": "Channels", + "targets": "GitHub and Coolify targets", + "assignments": "Pilot assignments", + "deployments": "First deployment", + "replay": "Replay capture" + }, + "stats": { + "channels": "Channels", + "targets": "Targets", + "deployments": "Deployments", + "timeline_events": "Timeline events" + }, + "overview": { + "title": "Overview", + "subtitle": "Current channel health, release activity, and module status.", + "guided_setup": "Guided setup", + "next_step": "Next: {step}", + "ready": "Release Manager is ready for day-to-day operations.", + "add_suggested_channel": "Add suggested channel", + "module_health_empty": "Module health snapshots appear after probes have been recorded." + }, + "settings": { + "title": "Release Manager Settings", + "subtitle": "Configure the GitHub token used for private repositories and branch lookups.", + "github_token": "GitHub token", + "github_api_url": "GitHub API URL", + "webhook_secret": "Webhook secret", + "github_webhook_secret": "GitHub webhook secret", + "configured": "Configured", + "not_configured": "Not configured", + "loaded_from": "Loaded from {variable}", + "set_below": "Set {variable} below", + "private_repositories_prefix": "Private repositories are read with the server environment variable", + "private_repositories_or": "or the module config variable", + "github_token_message": "Example: github_pat_... with access to the private repositories Release Manager deploys.", + "github_token_placeholder": "Leave blank to keep the existing token", + "github_api_url_message": "Configured in ReleaseManager.github_api_url. Use https://api.github.com unless using GitHub Enterprise.", + "webhook_secret_message": "Optional; leave blank to keep the existing secret.", + "webhook_secret_placeholder": "Webhook HMAC secret", + "save": "Save settings", + "back_to_integrations": "Back to integrations", + "guide": { + "steps": { + "github_token": "GitHub token", + "github_api_url": "GitHub API URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Review" + }, + "github_token_title": "Add GitHub token", + "github_token_description": "Release Manager uses this token to list private repositories, branches, and commits before a deployment target is saved or tested.", + "configure_this_in": "Configure this in", + "server_environment_variable": "The server environment variable", + "takes_precedence": "takes precedence when it is set.", + "recommended_access": "Recommended access", + "recommended_access_description": "Fine-grained GitHub token with Contents: read access for each release repository.", + "github_api_url_title": "Add GitHub API URL", + "github_api_url_description": "Use GitHub Cloud by default, or point this at the REST API base URL for a GitHub Enterprise Server installation.", + "github_api_url_invalid": "Enter a full HTTP or HTTPS URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise example", + "github_webhook_secret_title": "Add GitHub webhook secret", + "github_webhook_secret_description": "Use the same secret in GitHub repository webhooks so Release Manager can verify deployment events before handling them.", + "github_webhook_url": "GitHub webhook URL:", + "store_shared_secret_in": "Store the shared secret in", + "review_title": "Review GitHub setup", + "review_description": "Save the values, then use Integrations to select a private repository, branch, and specific commit or latest commit before testing access.", + "ready": "Ready", + "needs_value": "Needs value" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release channel is not ready", + "summary_prefix": "Your account is assigned to", + "summary_suffix": ", but that channel is missing the configuration needed to load its release image.", + "frontend_url": "Frontend URL", + "api_url": "API URL", + "checking_again": "Checking again in {seconds}s", + "refresh_error": "Release status could not be refreshed. The next automatic check will try again.", + "ignore": "Ignore next 5 minutes", + "check_again": "Check again", + "logout": "Logout", + "base_image": "Base image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "You are now on {channel}", + "summary_prefix": "Your account has been assigned to the", + "summary_suffix": "release channel. This device will remember that you have seen this notice.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend version", + "api_version": "API version", + "assigned_channel": "Assigned channel", + "current_app_image": "Current app image", + "current_api": "Current API", + "base_image": "Base image", + "continue": "Continue" + }, + "common": { + "yes": "yes", + "no": "no", + "off": "off" + }, + "actions": { + "edit": "Edit", + "rollback": "Rollback", + "update": "Update", + "create": "Create", + "clear": "Clear", + "assign": "Assign", + "remove": "Remove", + "test_access": "Test access", + "deploy": "Deploy", + "promote": "Promote", + "enable": "Enable", + "search": "Search", + "save_target": "Save target", + "delete": "Delete", + "back": "Back", + "next": "Next" + }, + "tables": { + "channel": "Channel", + "rollout": "Rollout", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Actions", + "module": "Module", + "status": "Status", + "checked": "Checked", + "subject": "Subject", + "reason": "Reason", + "expires": "Expires", + "deployment": "Deployment", + "source": "Source", + "started": "Started", + "target": "Target", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "full_redacted" + }, + "subject_type": { + "user": "user", + "subuser": "subuser", + "customer": "customer", + "channel": "channel" + }, + "severity": { + "error": "error", + "warning": "warning", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "active", + "deployed": "deployed", + "stable": "stable", + "enabled": "enabled", + "queued": "queued", + "deploying": "deploying", + "metadata": "metadata", + "not_configured": "not configured", + "warning": "warning", + "failed": "failed", + "down": "down", + "error": "error", + "unknown": "unknown" + } + }, + "autocomplete": { + "suggested_value": "Suggested value", + "suggestion": "Suggestion", + "use_typed_value": "Use typed value", + "custom": "Custom", + "api_url": "API URL", + "frontend_url": "Frontend URL", + "known_release_url": "Known release URL", + "deploy_here_with_coolify": "Deploy {app} here with Coolify", + "prepare_coolify_target": "Prepare a Coolify target with HTTPS/SSL enabled", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub repository", + "owner_repository": "owner/repository", + "git_branch": "Git branch", + "deployment_branch": "Deployment branch", + "github_commit": "GitHub commit", + "git_commit": "Git commit", + "use_specific_commit_sha": "Use specific commit SHA", + "custom_commit": "Custom commit", + "health_url": "Health URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify service", + "service_uuid": "Service UUID", + "known_coolify_service_uuid": "Known Coolify service UUID", + "control_api": "Control API", + "release_manager_api_endpoint": "Release Manager API endpoint", + "module": "Module", + "timeline_module_key": "Timeline module key" + }, + "errors": { + "github_repositories": "Could not load GitHub repositories.", + "github_branches": "Could not load GitHub branches.", + "repository_branch_required": "Repository and branch are required before testing GitHub access.", + "github_access_failed": "GitHub repository access test failed." + }, + "channels": { + "title": "Channels", + "subtitle": "Create and tune gradual release channels.", + "rollout_percent": "{percent}% rollout", + "already_configured": "Already configured", + "slug": "Slug", + "slug_message": "Example: canary", + "slug_placeholder": "slug", + "name": "Name", + "name_message": "Shown to operators when reviewing a channel.", + "name_placeholder": "Name", + "rollout": "Rollout", + "rollout_message": "0-100 percent of unassigned traffic.", + "frontend_url": "Frontend URL", + "frontend_url_message": "Example: https://canary.example.test", + "frontend_url_placeholder": "Frontend URL", + "no_matching_release_url": "No matching release URL.", + "api_url": "API URL", + "api_url_message": "Example: https://api-canary.example.test", + "api_url_placeholder": "API URL", + "no_matching_api_url": "No matching API URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata is safer for broad channels.", + "retention_days": "Retention days", + "retention_days_message": "1-365 days.", + "enabled": "Enabled", + "default_channel": "Default channel", + "replay_enabled": "Replay enabled", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Assignments", + "subtitle": "Pin users, subusers, or customers to release channels.", + "subject_type": "Subject type", + "subject_type_message": "Choose the identity type to pin.", + "customer": "Customer", + "customer_message": "Search by customer number or name, then select the exact customer.", + "customer_placeholder": "Search customer", + "subject_id": "Subject ID", + "subject_id_message": "Example: user id 42", + "subject_id_placeholder": "Subject id", + "channel": "Channel", + "channel_message": "Pinned subjects bypass percentage rollout.", + "reason": "Reason", + "reason_message": "Example: canary validation for customer support.", + "reason_placeholder": "Reason", + "expires": "Expires", + "expires_message": "Leave blank for no automatic expiry." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Trigger, promote, and inspect release deployments.", + "manual_deployment_record": "Manual deployment record", + "target": "Target", + "target_message": "Pick a saved target or keep manual fields editable.", + "select_target_or_manual": "Select target or manual", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/front-end-vue", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: main", + "branch_placeholder": "branch", + "commit_selection": "Commit selection", + "commit_selection_message": "Latest resolves to the branch head with the configured GitHub token.", + "latest_from_branch": "Latest from branch", + "specific_commit": "Specific commit", + "specific_commit_message": "Example: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Version label", + "version_label_message": "Example: api-2026.05.19", + "version_label_placeholder": "version label", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Verify token access to the selected repository, branch, and commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Enable targeted capture and step through failure timelines.", + "capture_channel": "Capture {channel}", + "target_type": "Target type", + "target": "Target", + "target_message": "Example: user id 42 or channel slug canary.", + "target_placeholder": "Target id or channel slug", + "channel_scope": "Channel scope", + "channel_scope_message": "Optional; limits replay capture to a channel.", + "no_channel_scope": "No channel scope", + "capture_level": "Capture level", + "expires": "Expires", + "expires_message": "Leave blank for manual disable.", + "trace_id": "Trace ID", + "trace_id_message": "Example: trace-canary-1", + "trace_id_placeholder": "Trace id", + "channel": "Channel", + "channel_placeholder": "Channel", + "principal_id": "Principal ID", + "principal_id_placeholder": "Principal id", + "module": "Module", + "module_placeholder": "Module", + "severity": "Severity", + "any_severity": "Any severity", + "no_timeline_events": "No timeline events match the current filters." + }, + "integrations": { + "title": "GitHub and Coolify", + "subtitle": "Map GitHub repositories and branches to channel-specific Coolify services.", + "choose_repository": "Choose repository", + "add_health_url": "add health URL", + "github_token_not_configured": "GitHub token is not configured; private repositories cannot be listed.", + "open_github_token_settings": "Open GitHub token settings", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/backend-php", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Latest: {commit}", + "coolify_instance": "Coolify instance", + "coolify_instance_message": "Leave empty for manual deployment records.", + "no_coolify_instance": "No Coolify instance", + "coolify_instance_placeholder": "Coolify instance id", + "coolify_service_uuid": "Coolify service UUID", + "coolify_service_uuid_message": "Select an existing service or paste a UUID.", + "coolify_service_uuid_placeholder": "Coolify service UUID", + "health_url": "Health URL", + "health_url_message": "Example: https://api-canary.example.test/ping", + "health_url_placeholder": "Health URL", + "ssl_domain": "SSL domain", + "ssl_domain_message": "Example: canary.example.test", + "ssl_domain_placeholder": "SSL domain", + "https_domain_for_coolify": "HTTPS domain for Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Automatically create deployments when this target changes.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Ask Coolify to provision HTTPS for the configured domain.", + "deploy_now": "Deploy now", + "deploy_now_tooltip": "Start a deployment immediately after saving the target.", + "create_missing_service": "Create missing service", + "create_missing_service_tooltip": "Allow Release Manager to create a missing Coolify service.", + "test_access_tooltip": "Verify the configured GitHub token can read this repository and branch." + } } }, "connectivity": { diff --git a/src/i18n/generated/global-v2.json b/src/i18n/generated/global-v2.json index 1a3686d1..d09a15ca 100644 --- a/src/i18n/generated/global-v2.json +++ b/src/i18n/generated/global-v2.json @@ -1496,6 +1496,412 @@ "title": "@:{'templates.generated.compat.configuration.xlvask.title'}", "username": "@:auth.username", "username_desc": "@:{'templates.generated.compat.configuration.xlvask.username_desc'}" + }, + "release_manager": { + "title": "@:{'templates.generated.compat.configuration.release_manager.title'}", + "subtitle": "@:{'templates.generated.compat.configuration.release_manager.subtitle'}", + "control_api": { + "title": "@:{'templates.generated.compat.configuration.release_manager.control_api.title'}", + "tooltip": "@:{'templates.generated.compat.configuration.release_manager.control_api.tooltip'}", + "example": "@:{'templates.generated.compat.configuration.release_manager.control_api.example'}", + "endpoint_label": "@:{'templates.generated.compat.configuration.release_manager.control_api.endpoint_label'}", + "endpoint_message": "@:{'templates.generated.compat.configuration.release_manager.control_api.endpoint_message'}", + "endpoint_aria": "@:{'templates.generated.compat.configuration.release_manager.control_api.endpoint_aria'}", + "use_tooltip": "@:{'templates.generated.compat.configuration.release_manager.control_api.use_tooltip'}", + "use": "@:{'templates.generated.compat.configuration.release_manager.control_api.use'}", + "reset_tooltip": "@:{'templates.generated.compat.configuration.release_manager.control_api.reset_tooltip'}", + "reset": "@:{'templates.generated.compat.configuration.release_manager.control_api.reset'}", + "known_endpoints": "@:{'templates.generated.compat.configuration.release_manager.control_api.known_endpoints'}" + }, + "tabs": { + "overview": { + "label": "@:{'templates.generated.compat.configuration.release_manager.tabs.overview.label'}", + "description": "@:{'templates.generated.compat.configuration.release_manager.tabs.overview.description'}" + }, + "channels": { + "label": "@:{'templates.generated.compat.configuration.release_manager.tabs.channels.label'}", + "description": "@:{'templates.generated.compat.configuration.release_manager.tabs.channels.description'}" + }, + "assignments": { + "label": "@:{'templates.generated.compat.configuration.release_manager.tabs.assignments.label'}", + "description": "@:{'templates.generated.compat.configuration.release_manager.tabs.assignments.description'}" + }, + "deployments": { + "label": "@:{'templates.generated.compat.configuration.release_manager.tabs.deployments.label'}", + "description": "@:{'templates.generated.compat.configuration.release_manager.tabs.deployments.description'}" + }, + "replay": { + "label": "@:{'templates.generated.compat.configuration.release_manager.tabs.replay.label'}", + "description": "@:{'templates.generated.compat.configuration.release_manager.tabs.replay.description'}" + }, + "integrations": { + "label": "@:{'templates.generated.compat.configuration.release_manager.tabs.integrations.label'}", + "description": "@:{'templates.generated.compat.configuration.release_manager.tabs.integrations.description'}" + }, + "settings": { + "label": "@:{'templates.generated.compat.configuration.release_manager.tabs.settings.label'}", + "description": "@:{'templates.generated.compat.configuration.release_manager.tabs.settings.description'}" + } + }, + "setup": { + "channels": "@:{'templates.generated.compat.configuration.release_manager.setup.channels'}", + "targets": "@:{'templates.generated.compat.configuration.release_manager.setup.targets'}", + "assignments": "@:{'templates.generated.compat.configuration.release_manager.setup.assignments'}", + "deployments": "@:{'templates.generated.compat.configuration.release_manager.setup.deployments'}", + "replay": "@:{'templates.generated.compat.configuration.release_manager.setup.replay'}" + }, + "stats": { + "channels": "@:{'templates.generated.compat.configuration.release_manager.stats.channels'}", + "targets": "@:{'templates.generated.compat.configuration.release_manager.stats.targets'}", + "deployments": "@:{'templates.generated.compat.configuration.release_manager.stats.deployments'}", + "timeline_events": "@:{'templates.generated.compat.configuration.release_manager.stats.timeline_events'}" + }, + "overview": { + "title": "@:{'templates.generated.compat.configuration.release_manager.overview.title'}", + "subtitle": "@:{'templates.generated.compat.configuration.release_manager.overview.subtitle'}", + "guided_setup": "@:{'templates.generated.compat.configuration.release_manager.overview.guided_setup'}", + "next_step": "@:{'templates.generated.compat.configuration.release_manager.overview.next_step'}", + "ready": "@:{'templates.generated.compat.configuration.release_manager.overview.ready'}", + "add_suggested_channel": "@:{'templates.generated.compat.configuration.release_manager.overview.add_suggested_channel'}", + "module_health_empty": "@:{'templates.generated.compat.configuration.release_manager.overview.module_health_empty'}" + }, + "settings": { + "title": "@:{'templates.generated.compat.configuration.release_manager.settings.title'}", + "subtitle": "@:{'templates.generated.compat.configuration.release_manager.settings.subtitle'}", + "github_token": "@:{'templates.generated.compat.configuration.release_manager.settings.github_token'}", + "github_api_url": "@:{'templates.generated.compat.configuration.release_manager.settings.github_api_url'}", + "webhook_secret": "@:{'templates.generated.compat.configuration.release_manager.settings.webhook_secret'}", + "github_webhook_secret": "@:{'templates.generated.compat.configuration.release_manager.settings.github_webhook_secret'}", + "configured": "@:{'templates.generated.compat.configuration.release_manager.settings.configured'}", + "not_configured": "@:{'templates.generated.compat.configuration.release_manager.settings.not_configured'}", + "loaded_from": "@:{'templates.generated.compat.configuration.release_manager.settings.loaded_from'}", + "set_below": "@:{'templates.generated.compat.configuration.release_manager.settings.set_below'}", + "private_repositories_prefix": "@:{'templates.generated.compat.configuration.release_manager.settings.private_repositories_prefix'}", + "private_repositories_or": "@:{'templates.generated.compat.configuration.release_manager.settings.private_repositories_or'}", + "github_token_message": "@:{'templates.generated.compat.configuration.release_manager.settings.github_token_message'}", + "github_token_placeholder": "@:{'templates.generated.compat.configuration.release_manager.settings.github_token_placeholder'}", + "github_api_url_message": "@:{'templates.generated.compat.configuration.release_manager.settings.github_api_url_message'}", + "webhook_secret_message": "@:{'templates.generated.compat.configuration.release_manager.settings.webhook_secret_message'}", + "webhook_secret_placeholder": "@:{'templates.generated.compat.configuration.release_manager.settings.webhook_secret_placeholder'}", + "save": "@:{'templates.generated.compat.configuration.release_manager.settings.save'}", + "back_to_integrations": "@:{'templates.generated.compat.configuration.release_manager.settings.back_to_integrations'}", + "guide": { + "steps": { + "github_token": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.steps.github_token'}", + "github_api_url": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.steps.github_api_url'}", + "github_webhook_secret": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.steps.github_webhook_secret'}", + "review": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.steps.review'}" + }, + "github_token_title": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.github_token_title'}", + "github_token_description": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.github_token_description'}", + "configure_this_in": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.configure_this_in'}", + "server_environment_variable": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.server_environment_variable'}", + "takes_precedence": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.takes_precedence'}", + "recommended_access": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.recommended_access'}", + "recommended_access_description": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.recommended_access_description'}", + "github_api_url_title": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.github_api_url_title'}", + "github_api_url_description": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.github_api_url_description'}", + "github_api_url_invalid": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.github_api_url_invalid'}", + "github_cloud": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.github_cloud'}", + "enterprise_example": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.enterprise_example'}", + "github_webhook_secret_title": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.github_webhook_secret_title'}", + "github_webhook_secret_description": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.github_webhook_secret_description'}", + "github_webhook_url": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.github_webhook_url'}", + "store_shared_secret_in": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.store_shared_secret_in'}", + "review_title": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.review_title'}", + "review_description": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.review_description'}", + "ready": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.ready'}", + "needs_value": "@:{'templates.generated.compat.configuration.release_manager.settings.guide.needs_value'}" + } + }, + "channel_unavailable": { + "kicker": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.kicker'}", + "title": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.title'}", + "summary_prefix": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.summary_prefix'}", + "summary_suffix": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.summary_suffix'}", + "frontend_url": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.frontend_url'}", + "api_url": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.api_url'}", + "checking_again": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.checking_again'}", + "refresh_error": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.refresh_error'}", + "ignore": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.ignore'}", + "check_again": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.check_again'}", + "logout": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.logout'}", + "base_image": "@:{'templates.generated.compat.configuration.release_manager.channel_unavailable.base_image'}" + }, + "channel_switched": { + "kicker": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.kicker'}", + "title": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.title'}", + "summary_prefix": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.summary_prefix'}", + "summary_suffix": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.summary_suffix'}", + "frontend": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.frontend'}", + "api": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.api'}", + "frontend_version": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.frontend_version'}", + "api_version": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.api_version'}", + "assigned_channel": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.assigned_channel'}", + "current_app_image": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.current_app_image'}", + "current_api": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.current_api'}", + "base_image": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.base_image'}", + "continue": "@:{'templates.generated.compat.configuration.release_manager.channel_switched.continue'}" + }, + "common": { + "yes": "@:{'templates.generated.compat.configuration.release_manager.common.yes'}", + "no": "@:{'templates.generated.compat.configuration.release_manager.common.no'}", + "off": "@:{'templates.generated.compat.configuration.release_manager.common.off'}" + }, + "actions": { + "edit": "@:{'templates.generated.compat.configuration.release_manager.actions.edit'}", + "rollback": "@:{'templates.generated.compat.configuration.release_manager.actions.rollback'}", + "update": "@:{'templates.generated.compat.configuration.release_manager.actions.update'}", + "create": "@:{'templates.generated.compat.configuration.release_manager.actions.create'}", + "clear": "@:{'templates.generated.compat.configuration.release_manager.actions.clear'}", + "assign": "@:{'templates.generated.compat.configuration.release_manager.actions.assign'}", + "remove": "@:{'templates.generated.compat.configuration.release_manager.actions.remove'}", + "test_access": "@:{'templates.generated.compat.configuration.release_manager.actions.test_access'}", + "deploy": "@:{'templates.generated.compat.configuration.release_manager.actions.deploy'}", + "promote": "@:{'templates.generated.compat.configuration.release_manager.actions.promote'}", + "enable": "@:{'templates.generated.compat.configuration.release_manager.actions.enable'}", + "search": "@:{'templates.generated.compat.configuration.release_manager.actions.search'}", + "save_target": "@:{'templates.generated.compat.configuration.release_manager.actions.save_target'}", + "delete": "@:{'templates.generated.compat.configuration.release_manager.actions.delete'}", + "back": "@:{'templates.generated.compat.configuration.release_manager.actions.back'}", + "next": "@:{'templates.generated.compat.configuration.release_manager.actions.next'}" + }, + "tables": { + "channel": "@:{'templates.generated.compat.configuration.release_manager.tables.channel'}", + "rollout": "@:{'templates.generated.compat.configuration.release_manager.tables.rollout'}", + "frontend": "@:{'templates.generated.compat.configuration.release_manager.tables.frontend'}", + "api": "@:{'templates.generated.compat.configuration.release_manager.tables.api'}", + "replay": "@:{'templates.generated.compat.configuration.release_manager.tables.replay'}", + "actions": "@:{'templates.generated.compat.configuration.release_manager.tables.actions'}", + "module": "@:{'templates.generated.compat.configuration.release_manager.tables.module'}", + "status": "@:{'templates.generated.compat.configuration.release_manager.tables.status'}", + "checked": "@:{'templates.generated.compat.configuration.release_manager.tables.checked'}", + "subject": "@:{'templates.generated.compat.configuration.release_manager.tables.subject'}", + "reason": "@:{'templates.generated.compat.configuration.release_manager.tables.reason'}", + "expires": "@:{'templates.generated.compat.configuration.release_manager.tables.expires'}", + "deployment": "@:{'templates.generated.compat.configuration.release_manager.tables.deployment'}", + "source": "@:{'templates.generated.compat.configuration.release_manager.tables.source'}", + "started": "@:{'templates.generated.compat.configuration.release_manager.tables.started'}", + "target": "@:{'templates.generated.compat.configuration.release_manager.tables.target'}", + "coolify": "@:{'templates.generated.compat.configuration.release_manager.tables.coolify'}", + "auto": "@:{'templates.generated.compat.configuration.release_manager.tables.auto'}" + }, + "values": { + "app": { + "frontend": "@:{'templates.generated.compat.configuration.release_manager.values.app.frontend'}", + "api": "@:{'templates.generated.compat.configuration.release_manager.values.app.api'}" + }, + "capture_level": { + "metadata": "@:{'templates.generated.compat.configuration.release_manager.values.capture_level.metadata'}", + "full_redacted": "@:{'templates.generated.compat.configuration.release_manager.values.capture_level.full_redacted'}" + }, + "subject_type": { + "user": "@:{'templates.generated.compat.configuration.release_manager.values.subject_type.user'}", + "subuser": "@:{'templates.generated.compat.configuration.release_manager.values.subject_type.subuser'}", + "customer": "@:{'templates.generated.compat.configuration.release_manager.values.subject_type.customer'}", + "channel": "@:{'templates.generated.compat.configuration.release_manager.values.subject_type.channel'}" + }, + "severity": { + "error": "@:{'templates.generated.compat.configuration.release_manager.values.severity.error'}", + "warning": "@:{'templates.generated.compat.configuration.release_manager.values.severity.warning'}", + "info": "@:{'templates.generated.compat.configuration.release_manager.values.severity.info'}" + }, + "status": { + "ok": "@:{'templates.generated.compat.configuration.release_manager.values.status.ok'}", + "active": "@:{'templates.generated.compat.configuration.release_manager.values.status.active'}", + "deployed": "@:{'templates.generated.compat.configuration.release_manager.values.status.deployed'}", + "stable": "@:{'templates.generated.compat.configuration.release_manager.values.status.stable'}", + "enabled": "@:{'templates.generated.compat.configuration.release_manager.values.status.enabled'}", + "queued": "@:{'templates.generated.compat.configuration.release_manager.values.status.queued'}", + "deploying": "@:{'templates.generated.compat.configuration.release_manager.values.status.deploying'}", + "metadata": "@:{'templates.generated.compat.configuration.release_manager.values.status.metadata'}", + "not_configured": "@:{'templates.generated.compat.configuration.release_manager.values.status.not_configured'}", + "warning": "@:{'templates.generated.compat.configuration.release_manager.values.status.warning'}", + "failed": "@:{'templates.generated.compat.configuration.release_manager.values.status.failed'}", + "down": "@:{'templates.generated.compat.configuration.release_manager.values.status.down'}", + "error": "@:{'templates.generated.compat.configuration.release_manager.values.status.error'}", + "unknown": "@:{'templates.generated.compat.configuration.release_manager.values.status.unknown'}" + } + }, + "autocomplete": { + "suggested_value": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.suggested_value'}", + "suggestion": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.suggestion'}", + "use_typed_value": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.use_typed_value'}", + "custom": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.custom'}", + "api_url": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.api_url'}", + "frontend_url": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.frontend_url'}", + "known_release_url": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.known_release_url'}", + "deploy_here_with_coolify": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.deploy_here_with_coolify'}", + "prepare_coolify_target": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.prepare_coolify_target'}", + "coolify_ssl": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.coolify_ssl'}", + "github_repository": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.github_repository'}", + "owner_repository": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.owner_repository'}", + "git_branch": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.git_branch'}", + "deployment_branch": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.deployment_branch'}", + "github_commit": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.github_commit'}", + "git_commit": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.git_commit'}", + "use_specific_commit_sha": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.use_specific_commit_sha'}", + "custom_commit": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.custom_commit'}", + "health_url": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.health_url'}", + "release_health_check": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.release_health_check'}", + "coolify_service": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.coolify_service'}", + "service_uuid": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.service_uuid'}", + "known_coolify_service_uuid": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.known_coolify_service_uuid'}", + "control_api": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.control_api'}", + "release_manager_api_endpoint": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.release_manager_api_endpoint'}", + "module": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.module'}", + "timeline_module_key": "@:{'templates.generated.compat.configuration.release_manager.autocomplete.timeline_module_key'}" + }, + "errors": { + "github_repositories": "@:{'templates.generated.compat.configuration.release_manager.errors.github_repositories'}", + "github_branches": "@:{'templates.generated.compat.configuration.release_manager.errors.github_branches'}", + "repository_branch_required": "@:{'templates.generated.compat.configuration.release_manager.errors.repository_branch_required'}", + "github_access_failed": "@:{'templates.generated.compat.configuration.release_manager.errors.github_access_failed'}" + }, + "channels": { + "title": "@:{'templates.generated.compat.configuration.release_manager.channels.title'}", + "subtitle": "@:{'templates.generated.compat.configuration.release_manager.channels.subtitle'}", + "rollout_percent": "@:{'templates.generated.compat.configuration.release_manager.channels.rollout_percent'}", + "already_configured": "@:{'templates.generated.compat.configuration.release_manager.channels.already_configured'}", + "slug": "@:{'templates.generated.compat.configuration.release_manager.channels.slug'}", + "slug_message": "@:{'templates.generated.compat.configuration.release_manager.channels.slug_message'}", + "slug_placeholder": "@:{'templates.generated.compat.configuration.release_manager.channels.slug_placeholder'}", + "name": "@:{'templates.generated.compat.configuration.release_manager.channels.name'}", + "name_message": "@:{'templates.generated.compat.configuration.release_manager.channels.name_message'}", + "name_placeholder": "@:{'templates.generated.compat.configuration.release_manager.channels.name_placeholder'}", + "rollout": "@:{'templates.generated.compat.configuration.release_manager.channels.rollout'}", + "rollout_message": "@:{'templates.generated.compat.configuration.release_manager.channels.rollout_message'}", + "frontend_url": "@:{'templates.generated.compat.configuration.release_manager.channels.frontend_url'}", + "frontend_url_message": "@:{'templates.generated.compat.configuration.release_manager.channels.frontend_url_message'}", + "frontend_url_placeholder": "@:{'templates.generated.compat.configuration.release_manager.channels.frontend_url_placeholder'}", + "no_matching_release_url": "@:{'templates.generated.compat.configuration.release_manager.channels.no_matching_release_url'}", + "api_url": "@:{'templates.generated.compat.configuration.release_manager.channels.api_url'}", + "api_url_message": "@:{'templates.generated.compat.configuration.release_manager.channels.api_url_message'}", + "api_url_placeholder": "@:{'templates.generated.compat.configuration.release_manager.channels.api_url_placeholder'}", + "no_matching_api_url": "@:{'templates.generated.compat.configuration.release_manager.channels.no_matching_api_url'}", + "replay_capture": "@:{'templates.generated.compat.configuration.release_manager.channels.replay_capture'}", + "replay_capture_message": "@:{'templates.generated.compat.configuration.release_manager.channels.replay_capture_message'}", + "retention_days": "@:{'templates.generated.compat.configuration.release_manager.channels.retention_days'}", + "retention_days_message": "@:{'templates.generated.compat.configuration.release_manager.channels.retention_days_message'}", + "enabled": "@:{'templates.generated.compat.configuration.release_manager.channels.enabled'}", + "default_channel": "@:{'templates.generated.compat.configuration.release_manager.channels.default_channel'}", + "replay_enabled": "@:{'templates.generated.compat.configuration.release_manager.channels.replay_enabled'}", + "frontend_chip": "@:{'templates.generated.compat.configuration.release_manager.channels.frontend_chip'}", + "api_chip": "@:{'templates.generated.compat.configuration.release_manager.channels.api_chip'}" + }, + "assignments": { + "title": "@:{'templates.generated.compat.configuration.release_manager.assignments.title'}", + "subtitle": "@:{'templates.generated.compat.configuration.release_manager.assignments.subtitle'}", + "subject_type": "@:{'templates.generated.compat.configuration.release_manager.assignments.subject_type'}", + "subject_type_message": "@:{'templates.generated.compat.configuration.release_manager.assignments.subject_type_message'}", + "customer": "@:{'templates.generated.compat.configuration.release_manager.assignments.customer'}", + "customer_message": "@:{'templates.generated.compat.configuration.release_manager.assignments.customer_message'}", + "customer_placeholder": "@:{'templates.generated.compat.configuration.release_manager.assignments.customer_placeholder'}", + "subject_id": "@:{'templates.generated.compat.configuration.release_manager.assignments.subject_id'}", + "subject_id_message": "@:{'templates.generated.compat.configuration.release_manager.assignments.subject_id_message'}", + "subject_id_placeholder": "@:{'templates.generated.compat.configuration.release_manager.assignments.subject_id_placeholder'}", + "channel": "@:{'templates.generated.compat.configuration.release_manager.assignments.channel'}", + "channel_message": "@:{'templates.generated.compat.configuration.release_manager.assignments.channel_message'}", + "reason": "@:{'templates.generated.compat.configuration.release_manager.assignments.reason'}", + "reason_message": "@:{'templates.generated.compat.configuration.release_manager.assignments.reason_message'}", + "reason_placeholder": "@:{'templates.generated.compat.configuration.release_manager.assignments.reason_placeholder'}", + "expires": "@:{'templates.generated.compat.configuration.release_manager.assignments.expires'}", + "expires_message": "@:{'templates.generated.compat.configuration.release_manager.assignments.expires_message'}" + }, + "deployments": { + "title": "@:{'templates.generated.compat.configuration.release_manager.deployments.title'}", + "subtitle": "@:{'templates.generated.compat.configuration.release_manager.deployments.subtitle'}", + "manual_deployment_record": "@:{'templates.generated.compat.configuration.release_manager.deployments.manual_deployment_record'}", + "target": "@:{'templates.generated.compat.configuration.release_manager.deployments.target'}", + "target_message": "@:{'templates.generated.compat.configuration.release_manager.deployments.target_message'}", + "select_target_or_manual": "@:{'templates.generated.compat.configuration.release_manager.deployments.select_target_or_manual'}", + "channel": "@:{'templates.generated.compat.configuration.release_manager.deployments.channel'}", + "app": "@:{'templates.generated.compat.configuration.release_manager.deployments.app'}", + "repository": "@:{'templates.generated.compat.configuration.release_manager.deployments.repository'}", + "repository_message": "@:{'templates.generated.compat.configuration.release_manager.deployments.repository_message'}", + "repository_placeholder": "@:{'templates.generated.compat.configuration.release_manager.deployments.repository_placeholder'}", + "branch": "@:{'templates.generated.compat.configuration.release_manager.deployments.branch'}", + "branch_message": "@:{'templates.generated.compat.configuration.release_manager.deployments.branch_message'}", + "branch_placeholder": "@:{'templates.generated.compat.configuration.release_manager.deployments.branch_placeholder'}", + "commit_selection": "@:{'templates.generated.compat.configuration.release_manager.deployments.commit_selection'}", + "commit_selection_message": "@:{'templates.generated.compat.configuration.release_manager.deployments.commit_selection_message'}", + "latest_from_branch": "@:{'templates.generated.compat.configuration.release_manager.deployments.latest_from_branch'}", + "specific_commit": "@:{'templates.generated.compat.configuration.release_manager.deployments.specific_commit'}", + "specific_commit_message": "@:{'templates.generated.compat.configuration.release_manager.deployments.specific_commit_message'}", + "commit_sha_placeholder": "@:{'templates.generated.compat.configuration.release_manager.deployments.commit_sha_placeholder'}", + "version_label": "@:{'templates.generated.compat.configuration.release_manager.deployments.version_label'}", + "version_label_message": "@:{'templates.generated.compat.configuration.release_manager.deployments.version_label_message'}", + "version_label_placeholder": "@:{'templates.generated.compat.configuration.release_manager.deployments.version_label_placeholder'}", + "commit_prefix": "@:{'templates.generated.compat.configuration.release_manager.deployments.commit_prefix'}", + "test_access_tooltip": "@:{'templates.generated.compat.configuration.release_manager.deployments.test_access_tooltip'}" + }, + "replay": { + "title": "@:{'templates.generated.compat.configuration.release_manager.replay.title'}", + "subtitle": "@:{'templates.generated.compat.configuration.release_manager.replay.subtitle'}", + "capture_channel": "@:{'templates.generated.compat.configuration.release_manager.replay.capture_channel'}", + "target_type": "@:{'templates.generated.compat.configuration.release_manager.replay.target_type'}", + "target": "@:{'templates.generated.compat.configuration.release_manager.replay.target'}", + "target_message": "@:{'templates.generated.compat.configuration.release_manager.replay.target_message'}", + "target_placeholder": "@:{'templates.generated.compat.configuration.release_manager.replay.target_placeholder'}", + "channel_scope": "@:{'templates.generated.compat.configuration.release_manager.replay.channel_scope'}", + "channel_scope_message": "@:{'templates.generated.compat.configuration.release_manager.replay.channel_scope_message'}", + "no_channel_scope": "@:{'templates.generated.compat.configuration.release_manager.replay.no_channel_scope'}", + "capture_level": "@:{'templates.generated.compat.configuration.release_manager.replay.capture_level'}", + "expires": "@:{'templates.generated.compat.configuration.release_manager.replay.expires'}", + "expires_message": "@:{'templates.generated.compat.configuration.release_manager.replay.expires_message'}", + "trace_id": "@:{'templates.generated.compat.configuration.release_manager.replay.trace_id'}", + "trace_id_message": "@:{'templates.generated.compat.configuration.release_manager.replay.trace_id_message'}", + "trace_id_placeholder": "@:{'templates.generated.compat.configuration.release_manager.replay.trace_id_placeholder'}", + "channel": "@:{'templates.generated.compat.configuration.release_manager.replay.channel'}", + "channel_placeholder": "@:{'templates.generated.compat.configuration.release_manager.replay.channel_placeholder'}", + "principal_id": "@:{'templates.generated.compat.configuration.release_manager.replay.principal_id'}", + "principal_id_placeholder": "@:{'templates.generated.compat.configuration.release_manager.replay.principal_id_placeholder'}", + "module": "@:{'templates.generated.compat.configuration.release_manager.replay.module'}", + "module_placeholder": "@:{'templates.generated.compat.configuration.release_manager.replay.module_placeholder'}", + "severity": "@:{'templates.generated.compat.configuration.release_manager.replay.severity'}", + "any_severity": "@:{'templates.generated.compat.configuration.release_manager.replay.any_severity'}", + "no_timeline_events": "@:{'templates.generated.compat.configuration.release_manager.replay.no_timeline_events'}" + }, + "integrations": { + "title": "@:{'templates.generated.compat.configuration.release_manager.integrations.title'}", + "subtitle": "@:{'templates.generated.compat.configuration.release_manager.integrations.subtitle'}", + "choose_repository": "@:{'templates.generated.compat.configuration.release_manager.integrations.choose_repository'}", + "add_health_url": "@:{'templates.generated.compat.configuration.release_manager.integrations.add_health_url'}", + "github_token_not_configured": "@:{'templates.generated.compat.configuration.release_manager.integrations.github_token_not_configured'}", + "open_github_token_settings": "@:{'templates.generated.compat.configuration.release_manager.integrations.open_github_token_settings'}", + "channel": "@:{'templates.generated.compat.configuration.release_manager.integrations.channel'}", + "app": "@:{'templates.generated.compat.configuration.release_manager.integrations.app'}", + "repository": "@:{'templates.generated.compat.configuration.release_manager.integrations.repository'}", + "repository_message": "@:{'templates.generated.compat.configuration.release_manager.integrations.repository_message'}", + "repository_placeholder": "@:{'templates.generated.compat.configuration.release_manager.integrations.repository_placeholder'}", + "branch": "@:{'templates.generated.compat.configuration.release_manager.integrations.branch'}", + "branch_message": "@:{'templates.generated.compat.configuration.release_manager.integrations.branch_message'}", + "branch_placeholder": "@:{'templates.generated.compat.configuration.release_manager.integrations.branch_placeholder'}", + "latest_prefix": "@:{'templates.generated.compat.configuration.release_manager.integrations.latest_prefix'}", + "coolify_instance": "@:{'templates.generated.compat.configuration.release_manager.integrations.coolify_instance'}", + "coolify_instance_message": "@:{'templates.generated.compat.configuration.release_manager.integrations.coolify_instance_message'}", + "no_coolify_instance": "@:{'templates.generated.compat.configuration.release_manager.integrations.no_coolify_instance'}", + "coolify_instance_placeholder": "@:{'templates.generated.compat.configuration.release_manager.integrations.coolify_instance_placeholder'}", + "coolify_service_uuid": "@:{'templates.generated.compat.configuration.release_manager.integrations.coolify_service_uuid'}", + "coolify_service_uuid_message": "@:{'templates.generated.compat.configuration.release_manager.integrations.coolify_service_uuid_message'}", + "coolify_service_uuid_placeholder": "@:{'templates.generated.compat.configuration.release_manager.integrations.coolify_service_uuid_placeholder'}", + "health_url": "@:{'templates.generated.compat.configuration.release_manager.integrations.health_url'}", + "health_url_message": "@:{'templates.generated.compat.configuration.release_manager.integrations.health_url_message'}", + "health_url_placeholder": "@:{'templates.generated.compat.configuration.release_manager.integrations.health_url_placeholder'}", + "ssl_domain": "@:{'templates.generated.compat.configuration.release_manager.integrations.ssl_domain'}", + "ssl_domain_message": "@:{'templates.generated.compat.configuration.release_manager.integrations.ssl_domain_message'}", + "ssl_domain_placeholder": "@:{'templates.generated.compat.configuration.release_manager.integrations.ssl_domain_placeholder'}", + "https_domain_for_coolify": "@:{'templates.generated.compat.configuration.release_manager.integrations.https_domain_for_coolify'}", + "auto_deploy": "@:{'templates.generated.compat.configuration.release_manager.integrations.auto_deploy'}", + "auto_deploy_tooltip": "@:{'templates.generated.compat.configuration.release_manager.integrations.auto_deploy_tooltip'}", + "coolify_ssl": "@:{'templates.generated.compat.configuration.release_manager.integrations.coolify_ssl'}", + "coolify_ssl_tooltip": "@:{'templates.generated.compat.configuration.release_manager.integrations.coolify_ssl_tooltip'}", + "deploy_now": "@:{'templates.generated.compat.configuration.release_manager.integrations.deploy_now'}", + "deploy_now_tooltip": "@:{'templates.generated.compat.configuration.release_manager.integrations.deploy_now_tooltip'}", + "create_missing_service": "@:{'templates.generated.compat.configuration.release_manager.integrations.create_missing_service'}", + "create_missing_service_tooltip": "@:{'templates.generated.compat.configuration.release_manager.integrations.create_missing_service_tooltip'}", + "test_access_tooltip": "@:{'templates.generated.compat.configuration.release_manager.integrations.test_access_tooltip'}" + } } }, "connectivity": { diff --git a/src/i18n/generated/no-v2.json b/src/i18n/generated/no-v2.json index ac801d00..a46f8885 100644 --- a/src/i18n/generated/no-v2.json +++ b/src/i18n/generated/no-v2.json @@ -2548,6 +2548,412 @@ "subtitle": "@.capitalize:{'words.generated.konfigurasjon'} @:{'words.generated.av'} @:{'words.generated.xlvask'}-@:{'words.generated.integrasjonen'}", "title": "@:{'words.generated.xlvask'}-@:{'words.generated.konfigurasjon'}", "username_desc": "@:{'words.generated.brukernavnet'} @:{'words.generated.brukes'} @:{'words.generated.til'} @:{'words.generated.a'} @:{'words.generated.autentisere'} @:{'words.generated.api'}-@:{'words.generated.tilkoblingen'}." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradvise API- og Front-End-utgivelser", + "control_api": { + "title": "Kontroll-API", + "tooltip": "Release Manager-handlinger sendes til denne API-en. Bruk produksjons-API-en med mindre du tester en staging-backend.", + "example": "Eksempel: https://api.truckwash.io:4433", + "endpoint_label": "API-endepunkt", + "endpoint_message": "Endre dette bare n?r Release Manager-endepunkter er tilgjengelige p? m?l-API-en.", + "endpoint_aria": "Release Manager kontroll-API URL", + "use_tooltip": "Last release-data fra denne API-en", + "use": "Bruk", + "reset_tooltip": "G? tilbake til standard kontroll-API", + "reset": "Tilbakestill", + "known_endpoints": "Kjente kontroll-API-endepunkter" + }, + "tabs": { + "overview": { + "label": "Oversikt", + "description": "Kanalhelse, oppsettsfremdrift og siste release-status." + }, + "channels": { + "label": "Kanaler", + "description": "Opprett stabile, canary- og m?lrettede kanaler med rollout-grenser." + }, + "assignments": { + "label": "Tildelinger", + "description": "Knytt brukere, underbrukere eller kunder til en bestemt release-kanal." + }, + "deployments": { + "label": "Utrullinger", + "description": "Start utrullinger og promoter vellykkede bygg." + }, + "replay": { + "label": "Replay", + "description": "Aktiver m?lrettet innsamling og s?k i release-tidslinjehendelser." + }, + "integrations": { + "label": "Integrasjoner", + "description": "Koble GitHub-repositories, branches og Coolify-tjenester." + }, + "settings": { + "label": "Innstillinger", + "description": "Konfigurer Release Managers GitHub-tilgang og webhook-innstillinger." + } + }, + "setup": { + "channels": "Kanaler", + "targets": "GitHub- og Coolify-m?l", + "assignments": "Pilottildelinger", + "deployments": "F?rste utrulling", + "replay": "Replay-innsamling" + }, + "stats": { + "channels": "Kanaler", + "targets": "M?l", + "deployments": "Utrullinger", + "timeline_events": "Tidslinjehendelser" + }, + "overview": { + "title": "Oversikt", + "subtitle": "Aktuell kanalhelse, release-aktivitet og modulstatus.", + "guided_setup": "Veiledet oppsett", + "next_step": "Neste: {step}", + "ready": "Release Manager er klar for daglig drift.", + "add_suggested_channel": "Legg til foreslått kanal", + "module_health_empty": "Modul-health snapshots vises når probes er registrert." + }, + "settings": { + "title": "Release Manager-innstillinger", + "subtitle": "Konfigurer GitHub-tokenet som brukes for private repositories og branch-oppslag.", + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "webhook_secret": "Webhook-hemmelighet", + "github_webhook_secret": "GitHub webhook-hemmelighet", + "configured": "Konfigurert", + "not_configured": "Ikke konfigurert", + "loaded_from": "Lastet fra {variable}", + "set_below": "Angi {variable} nedenfor", + "private_repositories_prefix": "Private repositories leses med serverens milj?variabel", + "private_repositories_or": "eller modulens konfigurasjonsvariabel", + "github_token_message": "Eksempel: github_pat_... med tilgang til de private repositories Release Manager ruller ut.", + "github_token_placeholder": "La st? tomt for ? beholde eksisterende token", + "github_api_url_message": "Konfigurert i ReleaseManager.github_api_url. Bruk https://api.github.com med mindre GitHub Enterprise brukes.", + "webhook_secret_message": "Valgfritt; la st? tomt for ? beholde eksisterende hemmelighet.", + "webhook_secret_placeholder": "Webhook HMAC-hemmelighet", + "save": "Lagre innstillinger", + "back_to_integrations": "Tilbake til integrasjoner", + "guide": { + "steps": { + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Gennemgang" + }, + "github_token_title": "Legg til GitHub-token", + "github_token_description": "Release Manager bruger denne token til at vise private repositories, branches og commits, før et deployment-mål gemmes eller testes.", + "configure_this_in": "Konfigurer dette i", + "server_environment_variable": "Serverens miljøvariabel", + "takes_precedence": "har forrang når den er satt.", + "recommended_access": "Anbefalt tilgang", + "recommended_access_description": "Fine-grained GitHub-token med Contents: read-adgang til hvert release-repository.", + "github_api_url_title": "Legg til GitHub API-URL", + "github_api_url_description": "Brug GitHub Cloud som standard, eller peg på REST API-base-URLen for en GitHub Enterprise Server-installation.", + "github_api_url_invalid": "Skriv inn en full HTTP- eller HTTPS-URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-eksempel", + "github_webhook_secret_title": "Legg til GitHub webhook secret", + "github_webhook_secret_description": "Brug samme secret i GitHub repository-webhooks, så Release Manager kan verificere deployment-events, før de håndteres.", + "github_webhook_url": "GitHub webhook-URL:", + "store_shared_secret_in": "Lagre den delte secreten i", + "review_title": "Gå gjennom GitHub-oppsett", + "review_description": "Gem værdierne, og brug derefter Integrationer til at vælge et privat repository, branch og specifik commit eller seneste commit før adgang testes.", + "ready": "Klar", + "needs_value": "Mangler værdi" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-kanalen er ikke klar", + "summary_prefix": "Kontoen din er tildelt", + "summary_suffix": ", men kanalen mangler konfigurasjonen som trengs for ? laste release-imaget.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Sjekker igjen om {seconds}s", + "refresh_error": "Release-status kunne ikke oppdateres. Neste automatiske sjekk pr?ver igjen.", + "ignore": "Ignorer de neste 5 minuttene", + "check_again": "Sjekk igjen", + "logout": "Logg ut", + "base_image": "Basis-image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du er n? p? {channel}", + "summary_prefix": "Kontoen din er tildelt release-kanalen", + "summary_suffix": "Denne enheten husker at du har sett denne meldingen.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-versjon", + "api_version": "API-versjon", + "assigned_channel": "Tildelt kanal", + "current_app_image": "N?v?rende app-image", + "current_api": "N?v?rende API", + "base_image": "Basis-image", + "continue": "Fortsett" + }, + "common": { + "yes": "ja", + "no": "nei", + "off": "av" + }, + "actions": { + "edit": "Rediger", + "rollback": "Rull tilbake", + "update": "Opdater", + "create": "Opprett", + "clear": "Tøm", + "assign": "Tildel", + "remove": "Fjern", + "test_access": "Test tilgang", + "deploy": "Deploy", + "promote": "Promoter", + "enable": "Aktiver", + "search": "Søk", + "save_target": "Lagre mål", + "delete": "Slett", + "back": "Tilbake", + "next": "Neste" + }, + "tables": { + "channel": "Kanal", + "rollout": "Udrulning", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Handlinger", + "module": "Modul", + "status": "Status", + "checked": "Kontrollert", + "subject": "Emne", + "reason": "Årsag", + "expires": "Utløper", + "deployment": "Deployment", + "source": "Kilde", + "started": "Startet", + "target": "Mål", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "fullt redigert" + }, + "subject_type": { + "user": "bruker", + "subuser": "medarbeider", + "customer": "kunde", + "channel": "kanal" + }, + "severity": { + "error": "feil", + "warning": "advarsel", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployet", + "stable": "stabil", + "enabled": "aktivert", + "queued": "i kø", + "deploying": "deploying", + "metadata": "metadata", + "not_configured": "ikke konfigurert", + "warning": "advarsel", + "failed": "feilet", + "down": "nede", + "error": "feil", + "unknown": "ukjent" + } + }, + "autocomplete": { + "suggested_value": "Foreslået værdi", + "suggestion": "Forslag", + "use_typed_value": "Brug indtastet værdi", + "custom": "Tilpasset", + "api_url": "API-URL", + "frontend_url": "Frontend-URL", + "known_release_url": "Kendt release-URL", + "deploy_here_with_coolify": "Deploy {app} her med Coolify", + "prepare_coolify_target": "Forbered et Coolify-mål med HTTPS/SSL aktiveret", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-repository", + "owner_repository": "ejer/repository", + "git_branch": "Git-branch", + "deployment_branch": "Deployment-branch", + "github_commit": "GitHub-commit", + "git_commit": "Git-commit", + "use_specific_commit_sha": "Brug specifik commit-SHA", + "custom_commit": "Tilpasset commit", + "health_url": "Health-URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify-service", + "service_uuid": "Service-UUID", + "known_coolify_service_uuid": "Kendt Coolify service-UUID", + "control_api": "Kontrol-API", + "release_manager_api_endpoint": "Release Manager API-endpoint", + "module": "Modul", + "timeline_module_key": "Timeline-modulnøgle" + }, + "errors": { + "github_repositories": "Kunne ikke indlæse GitHub-repositories.", + "github_branches": "Kunne ikke indlæse GitHub-branches.", + "repository_branch_required": "Repository og branch er påkrævet før GitHub-adgang kan testes.", + "github_access_failed": "Test af GitHub repository-adgang fejlede." + }, + "channels": { + "title": "Kanaler", + "subtitle": "Opprett og juster gradvise release-kanaler.", + "rollout_percent": "{percent}% udrulning", + "already_configured": "Allerede konfigurert", + "slug": "Slug", + "slug_message": "Eksempel: canary", + "slug_placeholder": "slug", + "name": "Navn", + "name_message": "Vises til operatører når de gjennomgår en kanal.", + "name_placeholder": "Navn", + "rollout": "Udrulning", + "rollout_message": "0-100 prosent av ikke-tildelt trafikk.", + "frontend_url": "Frontend-URL", + "frontend_url_message": "Eksempel: https://canary.example.test", + "frontend_url_placeholder": "Frontend-URL", + "no_matching_release_url": "Ingen matchende release-URL.", + "api_url": "API-URL", + "api_url_message": "Eksempel: https://api-canary.example.test", + "api_url_placeholder": "API-URL", + "no_matching_api_url": "Ingen matchende API-URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata er sikrere til brede kanaler.", + "retention_days": "Oppbevaringsdager", + "retention_days_message": "1-365 dage.", + "enabled": "Aktivert", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktivert", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Tildelinger", + "subtitle": "Fest brukere, medarbeidere eller kunder til release-kanaler.", + "subject_type": "Emnetype", + "subject_type_message": "Vælg identitetstypen, der skal fastgøres.", + "customer": "Kunde", + "customer_message": "Søk på kundenummer eller navn, og velg deretter nøyaktig kunde.", + "customer_placeholder": "Søk kunde", + "subject_id": "Emne-ID", + "subject_id_message": "Eksempel: bruker-id 42", + "subject_id_placeholder": "Emne-id", + "channel": "Kanal", + "channel_message": "Festede emner hopper over prosentutrullingen.", + "reason": "Årsag", + "reason_message": "Eksempel: canary-validering for kundesupport.", + "reason_placeholder": "Årsag", + "expires": "Utløper", + "expires_message": "Lad feltet være tomt for ingen automatisk udløb." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Start, promoter og inspiser release-deployments.", + "manual_deployment_record": "Manuel deployment-post", + "target": "Mål", + "target_message": "Vælg et gemt mål, eller behold manuelle felter redigerbare.", + "select_target_or_manual": "Velg mål eller manuelt", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/front-end-vue", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-valg", + "commit_selection_message": "Seneste slås op som branchens head med den konfigurerede GitHub-token.", + "latest_from_branch": "Siste fra branch", + "specific_commit": "Spesifikk commit", + "specific_commit_message": "Eksempel: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versjonsetikett", + "version_label_message": "Eksempel: api-2026.05.19", + "version_label_placeholder": "versionslabel", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Bekræft token-adgang til det valgte repository, branch og commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Aktiver målrettet capture og gennemgå fejltimelines trin for trin.", + "capture_channel": "Capture {channel}", + "target_type": "Måltype", + "target": "Mål", + "target_message": "Eksempel: bruker-id 42 eller kanal-slug canary.", + "target_placeholder": "Mål-id eller kanal-slug", + "channel_scope": "Kanalavgrensning", + "channel_scope_message": "Valgfrit; begrænser replay capture til en kanal.", + "no_channel_scope": "Ingen kanalavgrensning", + "capture_level": "Capture-niveau", + "expires": "Utløper", + "expires_message": "Lad feltet være tomt for manuel deaktivering.", + "trace_id": "Trace-ID", + "trace_id_message": "Eksempel: trace-canary-1", + "trace_id_placeholder": "Trace-id", + "channel": "Kanal", + "channel_placeholder": "Kanal", + "principal_id": "Principal-ID", + "principal_id_placeholder": "Principal-id", + "module": "Modul", + "module_placeholder": "Modul", + "severity": "Alvorlighet", + "any_severity": "Alle alvorligheder", + "no_timeline_events": "Ingen timeline-events matcher de aktuelle filtre." + }, + "integrations": { + "title": "GitHub og Coolify", + "subtitle": "Knyt GitHub-repositories og branches til kanalspecifikke Coolify-services.", + "choose_repository": "Velg repository", + "add_health_url": "legg til health-URL", + "github_token_not_configured": "GitHub-token er ikke konfigurert; private repositories kan ikke vises.", + "open_github_token_settings": "Åpne GitHub token-innstillinger", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/backend-php", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Seneste: {commit}", + "coolify_instance": "Coolify-instans", + "coolify_instance_message": "Lad feltet være tomt for manuelle deployment-poster.", + "no_coolify_instance": "Ingen Coolify-instans", + "coolify_instance_placeholder": "Coolify-instans-id", + "coolify_service_uuid": "Coolify service-UUID", + "coolify_service_uuid_message": "Vælg en eksisterende service eller indsæt en UUID.", + "coolify_service_uuid_placeholder": "Coolify service-UUID", + "health_url": "Health-URL", + "health_url_message": "Eksempel: https://api-canary.example.test/ping", + "health_url_placeholder": "Health-URL", + "ssl_domain": "SSL-domene", + "ssl_domain_message": "Eksempel: canary.example.test", + "ssl_domain_placeholder": "SSL-domene", + "https_domain_for_coolify": "HTTPS-domæne til Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Opret automatisk deployments, når dette mål ændres.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Bed Coolify om at oprette HTTPS for det konfigurerede domæne.", + "deploy_now": "Deploy nå", + "deploy_now_tooltip": "Start en deployment straks efter målet gemmes.", + "create_missing_service": "Opprett manglende service", + "create_missing_service_tooltip": "Tillad Release Manager at oprette en manglende Coolify-service.", + "test_access_tooltip": "Bekræft, at den konfigurerede GitHub-token kan læse dette repository og branch." + } } }, "connectivity": { diff --git a/src/i18n/generated/sv-v2.json b/src/i18n/generated/sv-v2.json index f50cf906..64f517a0 100644 --- a/src/i18n/generated/sv-v2.json +++ b/src/i18n/generated/sv-v2.json @@ -2598,6 +2598,412 @@ "subtitle": "@.capitalize:{'words.generated.konfiguration'} @:{'words.generated.af'} @:{'words.generated.xlvask'} @:{'words.generated.integrationen'}", "title": "@:{'words.generated.xlvask'} @:{'words.generated.konfiguration'}", "username_desc": "Användarnamnet @:{'words.generated.anvands'} @:{'words.generated.for'} @:{'words.generated.att'} @:{'words.generated.autentisera'} @:{'words.generated.api'}-@:{'words.generated.anslutningen'}." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradvisa API- och Front-End-versioner", + "control_api": { + "title": "Kontroll-API", + "tooltip": "Release Manager-?tg?rder skickas till detta API. Anv?nd produktions-API:t om du inte testar en staging-backend.", + "example": "Exempel: https://api.truckwash.io:4433", + "endpoint_label": "API-endpoint", + "endpoint_message": "?ndra detta endast n?r Release Manager-endpoints finns p? m?l-API:t.", + "endpoint_aria": "Release Manager kontroll-API URL", + "use_tooltip": "L?s in release-data fr?n detta API", + "use": "Anv?nd", + "reset_tooltip": "G? tillbaka till standard kontroll-API", + "reset": "?terst?ll", + "known_endpoints": "K?nda kontroll-API-endpoints" + }, + "tabs": { + "overview": { + "label": "?versikt", + "description": "Kanalh?lsa, installationsstatus och senaste release-l?ge." + }, + "channels": { + "label": "Kanaler", + "description": "Skapa stabila, canary- och riktade kanaler med rollout-gr?nser." + }, + "assignments": { + "label": "Tilldelningar", + "description": "Koppla anv?ndare, underanv?ndare eller kunder till en specifik release-kanal." + }, + "deployments": { + "label": "Utrullningar", + "description": "Starta utrullningar och promovera lyckade byggen." + }, + "replay": { + "label": "Replay", + "description": "Aktivera riktad insamling och s?k i release-tidslinjeh?ndelser." + }, + "integrations": { + "label": "Integrationer", + "description": "Anslut GitHub-repositories, branches och Coolify-tj?nster." + }, + "settings": { + "label": "Inst?llningar", + "description": "Konfigurera Release Managers GitHub-?tkomst och webhook-inst?llningar." + } + }, + "setup": { + "channels": "Kanaler", + "targets": "GitHub- och Coolify-m?l", + "assignments": "Pilottilldelningar", + "deployments": "F?rsta utrullningen", + "replay": "Replay-insamling" + }, + "stats": { + "channels": "Kanaler", + "targets": "M?l", + "deployments": "Utrullningar", + "timeline_events": "Tidslinjeh?ndelser" + }, + "overview": { + "title": "?versikt", + "subtitle": "Aktuell kanalh?lsa, release-aktivitet och modulstatus.", + "guided_setup": "Guidad installation", + "next_step": "N?sta: {step}", + "ready": "Release Manager ?r klar f?r daglig drift.", + "add_suggested_channel": "Lägg till föreslagen kanal", + "module_health_empty": "Modulhälsosnapshots visas när probes har registrerats." + }, + "settings": { + "title": "Release Manager-inst?llningar", + "subtitle": "Konfigurera GitHub-token som anv?nds f?r privata repositories och branch-uppslag.", + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "webhook_secret": "Webhook-hemlighet", + "github_webhook_secret": "GitHub webhook-hemlighet", + "configured": "Konfigurerad", + "not_configured": "Inte konfigurerad", + "loaded_from": "Inl?st fr?n {variable}", + "set_below": "Ange {variable} nedan", + "private_repositories_prefix": "Privata repositories l?ses med serverns milj?variabel", + "private_repositories_or": "eller modulens konfigurationsvariabel", + "github_token_message": "Exempel: github_pat_... med ?tkomst till de privata repositories som Release Manager distribuerar.", + "github_token_placeholder": "L?mna tomt f?r att beh?lla befintlig token", + "github_api_url_message": "Konfigurerad i ReleaseManager.github_api_url. Anv?nd https://api.github.com om du inte anv?nder GitHub Enterprise.", + "webhook_secret_message": "Valfritt; l?mna tomt f?r att beh?lla befintlig hemlighet.", + "webhook_secret_placeholder": "Webhook HMAC-hemlighet", + "save": "Spara inst?llningar", + "back_to_integrations": "Tillbaka till integrationer", + "guide": { + "steps": { + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Gennemgang" + }, + "github_token_title": "Lägg till GitHub-token", + "github_token_description": "Release Manager använder denna token för att lista privata repositories, branches och commits innan ett deployment-mål sparas eller testas.", + "configure_this_in": "Konfigurera detta i", + "server_environment_variable": "Serverns miljövariabel", + "takes_precedence": "har företräde när den är satt.", + "recommended_access": "Rekommenderad åtkomst", + "recommended_access_description": "Fine-grained GitHub-token med Contents: read-åtkomst till varje release-repository.", + "github_api_url_title": "Lägg till GitHub API-URL", + "github_api_url_description": "Brug GitHub Cloud som standard, eller peg på REST API-base-URLen for en GitHub Enterprise Server-installation.", + "github_api_url_invalid": "Ange en fullständig HTTP- eller HTTPS-URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-exempel", + "github_webhook_secret_title": "Lägg till GitHub webhook secret", + "github_webhook_secret_description": "Brug samme secret i GitHub repository-webhooks, så Release Manager kan verificere deployment-events, før de håndteres.", + "github_webhook_url": "GitHub webhook-URL:", + "store_shared_secret_in": "Spara den delade secret i", + "review_title": "Granska GitHub-konfiguration", + "review_description": "Gem værdierne, og brug derefter Integrationer til at vælge et privat repository, branch og specifik commit eller seneste commit før adgang testes.", + "ready": "Klar", + "needs_value": "Saknar värde" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-kanalen ?r inte klar", + "summary_prefix": "Ditt konto ?r tilldelat", + "summary_suffix": ", men kanalen saknar konfigurationen som beh?vs f?r att l?sa in dess release-image.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Kontrollerar igen om {seconds}s", + "refresh_error": "Release-status kunde inte uppdateras. N?sta automatiska kontroll f?rs?ker igen.", + "ignore": "Ignorera de kommande 5 minuterna", + "check_again": "Kontrollera igen", + "logout": "Logga ut", + "base_image": "Bas-image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du ?r nu p? {channel}", + "summary_prefix": "Ditt konto har tilldelats release-kanalen", + "summary_suffix": "Den h?r enheten kommer ih?g att du har sett detta meddelande.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-version", + "api_version": "API-version", + "assigned_channel": "Tilldelad kanal", + "current_app_image": "Nuvarande app-image", + "current_api": "Nuvarande API", + "base_image": "Bas-image", + "continue": "Forts?tt" + }, + "common": { + "yes": "ja", + "no": "nej", + "off": "av" + }, + "actions": { + "edit": "Redigera", + "rollback": "Rulla tillbaka", + "update": "Uppdatera", + "create": "Skapa", + "clear": "Rensa", + "assign": "Tilldela", + "remove": "Ta bort", + "test_access": "Testa åtkomst", + "deploy": "Deploy", + "promote": "Promota", + "enable": "Aktivera", + "search": "Sök", + "save_target": "Spara mål", + "delete": "Radera", + "back": "Tillbaka", + "next": "Nästa" + }, + "tables": { + "channel": "Kanal", + "rollout": "Udrulning", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Åtgärder", + "module": "Modul", + "status": "Status", + "checked": "Kontrollerad", + "subject": "Emne", + "reason": "Orsak", + "expires": "Upphör", + "deployment": "Deployment", + "source": "Källa", + "started": "Startet", + "target": "Mål", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "helt redigerad" + }, + "subject_type": { + "user": "användare", + "subuser": "medarbetare", + "customer": "kund", + "channel": "kanal" + }, + "severity": { + "error": "fel", + "warning": "varning", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployad", + "stable": "stabil", + "enabled": "aktiverad", + "queued": "i kö", + "deploying": "deployar", + "metadata": "metadata", + "not_configured": "inte konfigurerad", + "warning": "varning", + "failed": "misslyckad", + "down": "nere", + "error": "fel", + "unknown": "okänd" + } + }, + "autocomplete": { + "suggested_value": "Foreslået værdi", + "suggestion": "Forslag", + "use_typed_value": "Brug indtastet værdi", + "custom": "Tilpasset", + "api_url": "API-URL", + "frontend_url": "Frontend-URL", + "known_release_url": "Kendt release-URL", + "deploy_here_with_coolify": "Deploy {app} her med Coolify", + "prepare_coolify_target": "Forbered et Coolify-mål med HTTPS/SSL aktiveret", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-repository", + "owner_repository": "ejer/repository", + "git_branch": "Git-branch", + "deployment_branch": "Deployment-branch", + "github_commit": "GitHub-commit", + "git_commit": "Git-commit", + "use_specific_commit_sha": "Brug specifik commit-SHA", + "custom_commit": "Tilpasset commit", + "health_url": "Health-URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify-service", + "service_uuid": "Service-UUID", + "known_coolify_service_uuid": "Kendt Coolify service-UUID", + "control_api": "Kontrol-API", + "release_manager_api_endpoint": "Release Manager API-endpoint", + "module": "Modul", + "timeline_module_key": "Timeline-modulnøgle" + }, + "errors": { + "github_repositories": "Kunne ikke indlæse GitHub-repositories.", + "github_branches": "Kunne ikke indlæse GitHub-branches.", + "repository_branch_required": "Repository og branch er påkrævet før GitHub-adgang kan testes.", + "github_access_failed": "Test af GitHub repository-adgang fejlede." + }, + "channels": { + "title": "Kanaler", + "subtitle": "Skapa och justera gradvisa release-kanaler.", + "rollout_percent": "{percent}% utrullning", + "already_configured": "Redan konfigurerad", + "slug": "Slug", + "slug_message": "Eksempel: canary", + "slug_placeholder": "slug", + "name": "Namn", + "name_message": "Visas för operatörer när de granskar en kanal.", + "name_placeholder": "Namn", + "rollout": "Utrullning", + "rollout_message": "0-100 procent av otilldelad trafik.", + "frontend_url": "Frontend-URL", + "frontend_url_message": "Eksempel: https://canary.example.test", + "frontend_url_placeholder": "Frontend-URL", + "no_matching_release_url": "Ingen matchande release-URL.", + "api_url": "API-URL", + "api_url_message": "Eksempel: https://api-canary.example.test", + "api_url_placeholder": "API-URL", + "no_matching_api_url": "Ingen matchande API-URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata är säkrare för breda kanaler.", + "retention_days": "Lagringsdagar", + "retention_days_message": "1-365 dagar.", + "enabled": "Aktiverad", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktiverad", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Tilldelningar", + "subtitle": "Fäst användare, medarbetare eller kunder till release-kanaler.", + "subject_type": "Ämnestyp", + "subject_type_message": "Välj identitetstypen som ska fästas.", + "customer": "Kunde", + "customer_message": "Sök på kundnummer eller namn och välj sedan exakt kund.", + "customer_placeholder": "Sök kund", + "subject_id": "Ämnes-ID", + "subject_id_message": "Exempel: användar-id 42", + "subject_id_placeholder": "Ämnes-id", + "channel": "Kanal", + "channel_message": "Fästa ämnen hoppar över procentutrullningen.", + "reason": "Orsak", + "reason_message": "Exempel: canary-validering för kundsupport.", + "reason_placeholder": "Orsak", + "expires": "Upphör", + "expires_message": "Lämna tomt för ingen automatisk upphörning." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Starta, promota och inspektera release-deployments.", + "manual_deployment_record": "Manuel deployment-post", + "target": "Mål", + "target_message": "Välj ett sparat mål eller behåll manuella fält redigerbara.", + "select_target_or_manual": "Vælg mål eller manuel", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/front-end-vue", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-val", + "commit_selection_message": "Senaste slås upp som branchens head med konfigurerad GitHub-token.", + "latest_from_branch": "Senaste från branch", + "specific_commit": "Specifik commit", + "specific_commit_message": "Eksempel: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versionsetikett", + "version_label_message": "Eksempel: api-2026.05.19", + "version_label_placeholder": "versionsetikett", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Bekræft token-adgang til det valgte repository, branch og commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Aktivera riktad capture och gå igenom feltimelines steg för steg.", + "capture_channel": "Capture {channel}", + "target_type": "Måltype", + "target": "Mål", + "target_message": "Exempel: användar-id 42 eller kanal-slug canary.", + "target_placeholder": "Mål-id eller kanal-slug", + "channel_scope": "Kanalavgränsning", + "channel_scope_message": "Valgfrit; begrænser replay capture til en kanal.", + "no_channel_scope": "Ingen kanalavgränsning", + "capture_level": "Capture-niveau", + "expires": "Upphör", + "expires_message": "Lad feltet være tomt for manuel deaktivering.", + "trace_id": "Trace-ID", + "trace_id_message": "Eksempel: trace-canary-1", + "trace_id_placeholder": "Trace-id", + "channel": "Kanal", + "channel_placeholder": "Kanal", + "principal_id": "Principal-ID", + "principal_id_placeholder": "Principal-id", + "module": "Modul", + "module_placeholder": "Modul", + "severity": "Allvarlighetsgrad", + "any_severity": "Alla allvarlighetsgrader", + "no_timeline_events": "Ingen timeline-events matcher de aktuelle filtre." + }, + "integrations": { + "title": "GitHub och Coolify", + "subtitle": "Koppla GitHub-repositories och branches till kanalspecifika Coolify-tjänster.", + "choose_repository": "Välj repository", + "add_health_url": "lägg till health-URL", + "github_token_not_configured": "GitHub-token er ikke konfigureret; private repositories kan ikke vises.", + "open_github_token_settings": "Öppna GitHub token-inställningar", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/backend-php", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Seneste: {commit}", + "coolify_instance": "Coolify-instans", + "coolify_instance_message": "Lad feltet være tomt for manuelle deployment-poster.", + "no_coolify_instance": "Ingen Coolify-instans", + "coolify_instance_placeholder": "Coolify-instans-id", + "coolify_service_uuid": "Coolify service-UUID", + "coolify_service_uuid_message": "Vælg en eksisterende service eller indsæt en UUID.", + "coolify_service_uuid_placeholder": "Coolify service-UUID", + "health_url": "Health-URL", + "health_url_message": "Eksempel: https://api-canary.example.test/ping", + "health_url_placeholder": "Health-URL", + "ssl_domain": "SSL-domän", + "ssl_domain_message": "Eksempel: canary.example.test", + "ssl_domain_placeholder": "SSL-domän", + "https_domain_for_coolify": "HTTPS-domän för Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Opret automatisk deployments, når dette mål ændres.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Bed Coolify om at oprette HTTPS for det konfigurerede domæne.", + "deploy_now": "Deploy nu", + "deploy_now_tooltip": "Start en deployment straks efter målet gemmes.", + "create_missing_service": "Skapa saknad tjänst", + "create_missing_service_tooltip": "Tillad Release Manager at oprette en manglende Coolify-service.", + "test_access_tooltip": "Bekræft, at den konfigurerede GitHub-token kan læse dette repository og branch." + } } }, "connectivity": { diff --git a/src/i18n/locales/da.json b/src/i18n/locales/da.json index e381ac71..19c21495 100644 --- a/src/i18n/locales/da.json +++ b/src/i18n/locales/da.json @@ -1495,6 +1495,412 @@ }, "company_id": "Company ID", "company_id_desc": "The Workfeed company identifier used for API synchronization." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradvise API- og Front-End-udgivelser", + "control_api": { + "title": "Kontrol-API", + "tooltip": "Release Manager-handlinger sendes til denne API. Brug produktions-API'en, medmindre du tester en staging-backend.", + "example": "Eksempel: https://api.truckwash.io:4433", + "endpoint_label": "API-endpoint", + "endpoint_message": "Skift kun dette, n?r Release Manager-endpoints er tilg?ngelige p? m?l-API'en.", + "endpoint_aria": "Release Manager kontrol-API URL", + "use_tooltip": "Indl?s release-data fra denne API", + "use": "Brug", + "reset_tooltip": "Vend tilbage til standard kontrol-API", + "reset": "Nulstil", + "known_endpoints": "Kendte kontrol-API-endpoints" + }, + "tabs": { + "overview": { + "label": "Oversigt", + "description": "Kanalstatus, ops?tningsfremdrift og seneste release-tilstand." + }, + "channels": { + "label": "Kanaler", + "description": "Opret stabile, canary- og m?lrettede kanaler med rollout-gr?nser." + }, + "assignments": { + "label": "Tildelinger", + "description": "Fastg?r brugere, subbrugere eller kunder til en bestemt release-kanal." + }, + "deployments": { + "label": "Udrulninger", + "description": "Start udrulninger og promover vellykkede builds." + }, + "replay": { + "label": "Replay", + "description": "Aktiv?r m?lrettet opsamling og s?g i release-tidslinjeh?ndelser." + }, + "integrations": { + "label": "Integrationer", + "description": "Forbind GitHub-repositories, branches og Coolify-services." + }, + "settings": { + "label": "Indstillinger", + "description": "Konfigurer Release Managers GitHub-adgang og webhook-indstillinger." + } + }, + "setup": { + "channels": "Kanaler", + "targets": "GitHub- og Coolify-m?l", + "assignments": "Pilot-tildelinger", + "deployments": "F?rste udrulning", + "replay": "Replay-opsamling" + }, + "stats": { + "channels": "Kanaler", + "targets": "M?l", + "deployments": "Udrulninger", + "timeline_events": "Tidslinjeh?ndelser" + }, + "overview": { + "title": "Oversigt", + "subtitle": "Aktuel kanalstatus, release-aktivitet og modulstatus.", + "guided_setup": "Guidet ops?tning", + "next_step": "N?ste: {step}", + "ready": "Release Manager er klar til daglig drift.", + "add_suggested_channel": "Tilføj foreslået kanal", + "module_health_empty": "Modul-health snapshots vises, når probes er blevet registreret." + }, + "settings": { + "title": "Release Manager-indstillinger", + "subtitle": "Konfigurer GitHub-tokenet, der bruges til private repositories og branch-opslag.", + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "webhook_secret": "Webhook-hemmelighed", + "github_webhook_secret": "GitHub webhook-hemmelighed", + "configured": "Konfigureret", + "not_configured": "Ikke konfigureret", + "loaded_from": "Indl?st fra {variable}", + "set_below": "Angiv {variable} nedenfor", + "private_repositories_prefix": "Private repositories l?ses med serverens milj?variabel", + "private_repositories_or": "eller modulets konfigurationsvariabel", + "github_token_message": "Eksempel: github_pat_... med adgang til de private repositories, Release Manager udruller.", + "github_token_placeholder": "Lad feltet v?re tomt for at beholde det eksisterende token", + "github_api_url_message": "Konfigureret i ReleaseManager.github_api_url. Brug https://api.github.com medmindre GitHub Enterprise bruges.", + "webhook_secret_message": "Valgfrit; lad feltet v?re tomt for at beholde den eksisterende hemmelighed.", + "webhook_secret_placeholder": "Webhook HMAC-hemmelighed", + "save": "Gem indstillinger", + "back_to_integrations": "Tilbage til integrationer", + "guide": { + "steps": { + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Gennemgang" + }, + "github_token_title": "Tilføj GitHub-token", + "github_token_description": "Release Manager bruger denne token til at vise private repositories, branches og commits, før et deployment-mål gemmes eller testes.", + "configure_this_in": "Konfigurer dette i", + "server_environment_variable": "Serverens miljøvariabel", + "takes_precedence": "har forrang, når den er sat.", + "recommended_access": "Anbefalet adgang", + "recommended_access_description": "Fine-grained GitHub-token med Contents: read-adgang til hvert release-repository.", + "github_api_url_title": "Tilføj GitHub API-URL", + "github_api_url_description": "Brug GitHub Cloud som standard, eller peg på REST API-base-URLen for en GitHub Enterprise Server-installation.", + "github_api_url_invalid": "Indtast en fuld HTTP- eller HTTPS-URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-eksempel", + "github_webhook_secret_title": "Tilføj GitHub webhook secret", + "github_webhook_secret_description": "Brug samme secret i GitHub repository-webhooks, så Release Manager kan verificere deployment-events, før de håndteres.", + "github_webhook_url": "GitHub webhook-URL:", + "store_shared_secret_in": "Gem den delte secret i", + "review_title": "Gennemgå GitHub-opsætning", + "review_description": "Gem værdierne, og brug derefter Integrationer til at vælge et privat repository, branch og specifik commit eller seneste commit før adgang testes.", + "ready": "Klar", + "needs_value": "Mangler værdi" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-kanalen er ikke klar", + "summary_prefix": "Din konto er tildelt", + "summary_suffix": ", men kanalen mangler den konfiguration, der skal bruges for at indl?se dens release-image.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Tjekker igen om {seconds}s", + "refresh_error": "Release-status kunne ikke opdateres. Det n?ste automatiske tjek pr?ver igen.", + "ignore": "Ignorer de n?ste 5 minutter", + "check_again": "Tjek igen", + "logout": "Log ud", + "base_image": "Basis-image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du er nu p? {channel}", + "summary_prefix": "Din konto er blevet tildelt release-kanalen", + "summary_suffix": "Denne enhed husker, at du har set denne besked.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-version", + "api_version": "API-version", + "assigned_channel": "Tildelt kanal", + "current_app_image": "Nuv?rende app-image", + "current_api": "Nuv?rende API", + "base_image": "Basis-image", + "continue": "Forts?t" + }, + "common": { + "yes": "ja", + "no": "nej", + "off": "fra" + }, + "actions": { + "edit": "Rediger", + "rollback": "Rul tilbage", + "update": "Opdater", + "create": "Opret", + "clear": "Ryd", + "assign": "Tildel", + "remove": "Fjern", + "test_access": "Test adgang", + "deploy": "Deploy", + "promote": "Promover", + "enable": "Aktiver", + "search": "Søg", + "save_target": "Gem mål", + "delete": "Slet", + "back": "Tilbage", + "next": "Næste" + }, + "tables": { + "channel": "Kanal", + "rollout": "Udrulning", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Handlinger", + "module": "Modul", + "status": "Status", + "checked": "Kontrolleret", + "subject": "Emne", + "reason": "Årsag", + "expires": "Udløber", + "deployment": "Deployment", + "source": "Kilde", + "started": "Startet", + "target": "Mål", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "fuldt redigeret" + }, + "subject_type": { + "user": "bruger", + "subuser": "medarbejder", + "customer": "kunde", + "channel": "kanal" + }, + "severity": { + "error": "fejl", + "warning": "advarsel", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployet", + "stable": "stabil", + "enabled": "aktiveret", + "queued": "i kø", + "deploying": "deploying", + "metadata": "metadata", + "not_configured": "ikke konfigureret", + "warning": "advarsel", + "failed": "fejlet", + "down": "nede", + "error": "fejl", + "unknown": "ukendt" + } + }, + "autocomplete": { + "suggested_value": "Foreslået værdi", + "suggestion": "Forslag", + "use_typed_value": "Brug indtastet værdi", + "custom": "Tilpasset", + "api_url": "API-URL", + "frontend_url": "Frontend-URL", + "known_release_url": "Kendt release-URL", + "deploy_here_with_coolify": "Deploy {app} her med Coolify", + "prepare_coolify_target": "Forbered et Coolify-mål med HTTPS/SSL aktiveret", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-repository", + "owner_repository": "ejer/repository", + "git_branch": "Git-branch", + "deployment_branch": "Deployment-branch", + "github_commit": "GitHub-commit", + "git_commit": "Git-commit", + "use_specific_commit_sha": "Brug specifik commit-SHA", + "custom_commit": "Tilpasset commit", + "health_url": "Health-URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify-service", + "service_uuid": "Service-UUID", + "known_coolify_service_uuid": "Kendt Coolify service-UUID", + "control_api": "Kontrol-API", + "release_manager_api_endpoint": "Release Manager API-endpoint", + "module": "Modul", + "timeline_module_key": "Timeline-modulnøgle" + }, + "errors": { + "github_repositories": "Kunne ikke indlæse GitHub-repositories.", + "github_branches": "Kunne ikke indlæse GitHub-branches.", + "repository_branch_required": "Repository og branch er påkrævet før GitHub-adgang kan testes.", + "github_access_failed": "Test af GitHub repository-adgang fejlede." + }, + "channels": { + "title": "Kanaler", + "subtitle": "Opret og juster gradvise release-kanaler.", + "rollout_percent": "{percent}% udrulning", + "already_configured": "Allerede konfigureret", + "slug": "Slug", + "slug_message": "Eksempel: canary", + "slug_placeholder": "slug", + "name": "Navn", + "name_message": "Vises til operatører, når de gennemgår en kanal.", + "name_placeholder": "Navn", + "rollout": "Udrulning", + "rollout_message": "0-100 procent af ikke-tildelt trafik.", + "frontend_url": "Frontend-URL", + "frontend_url_message": "Eksempel: https://canary.example.test", + "frontend_url_placeholder": "Frontend-URL", + "no_matching_release_url": "Ingen matchende release-URL.", + "api_url": "API-URL", + "api_url_message": "Eksempel: https://api-canary.example.test", + "api_url_placeholder": "API-URL", + "no_matching_api_url": "Ingen matchende API-URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata er sikrere til brede kanaler.", + "retention_days": "Opbevaringsdage", + "retention_days_message": "1-365 dage.", + "enabled": "Aktiveret", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktiveret", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Tildelinger", + "subtitle": "Fastgør brugere, medarbejdere eller kunder til release-kanaler.", + "subject_type": "Emnetype", + "subject_type_message": "Vælg identitetstypen, der skal fastgøres.", + "customer": "Kunde", + "customer_message": "Søg på kundenummer eller navn, og vælg derefter den præcise kunde.", + "customer_placeholder": "Søg kunde", + "subject_id": "Emne-ID", + "subject_id_message": "Eksempel: bruger-id 42", + "subject_id_placeholder": "Emne-id", + "channel": "Kanal", + "channel_message": "Fastgjorte emner springer procentudrulningen over.", + "reason": "Årsag", + "reason_message": "Eksempel: canary-validering for kundesupport.", + "reason_placeholder": "Årsag", + "expires": "Udløber", + "expires_message": "Lad feltet være tomt for ingen automatisk udløb." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Start, promover og inspicer release-deployments.", + "manual_deployment_record": "Manuel deployment-post", + "target": "Mål", + "target_message": "Vælg et gemt mål, eller behold manuelle felter redigerbare.", + "select_target_or_manual": "Vælg mål eller manuel", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/front-end-vue", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-valg", + "commit_selection_message": "Seneste slås op som branchens head med den konfigurerede GitHub-token.", + "latest_from_branch": "Seneste fra branch", + "specific_commit": "Specifik commit", + "specific_commit_message": "Eksempel: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versionslabel", + "version_label_message": "Eksempel: api-2026.05.19", + "version_label_placeholder": "versionslabel", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Bekræft token-adgang til det valgte repository, branch og commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Aktiver målrettet capture og gennemgå fejltimelines trin for trin.", + "capture_channel": "Capture {channel}", + "target_type": "Måltype", + "target": "Mål", + "target_message": "Eksempel: bruger-id 42 eller kanal-slug canary.", + "target_placeholder": "Mål-id eller kanal-slug", + "channel_scope": "Kanalafgrænsning", + "channel_scope_message": "Valgfrit; begrænser replay capture til en kanal.", + "no_channel_scope": "Ingen kanalafgrænsning", + "capture_level": "Capture-niveau", + "expires": "Udløber", + "expires_message": "Lad feltet være tomt for manuel deaktivering.", + "trace_id": "Trace-ID", + "trace_id_message": "Eksempel: trace-canary-1", + "trace_id_placeholder": "Trace-id", + "channel": "Kanal", + "channel_placeholder": "Kanal", + "principal_id": "Principal-ID", + "principal_id_placeholder": "Principal-id", + "module": "Modul", + "module_placeholder": "Modul", + "severity": "Alvorlighed", + "any_severity": "Alle alvorligheder", + "no_timeline_events": "Ingen timeline-events matcher de aktuelle filtre." + }, + "integrations": { + "title": "GitHub og Coolify", + "subtitle": "Knyt GitHub-repositories og branches til kanalspecifikke Coolify-services.", + "choose_repository": "Vælg repository", + "add_health_url": "tilføj health-URL", + "github_token_not_configured": "GitHub-token er ikke konfigureret; private repositories kan ikke vises.", + "open_github_token_settings": "Åbn GitHub token-indstillinger", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/backend-php", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Seneste: {commit}", + "coolify_instance": "Coolify-instans", + "coolify_instance_message": "Lad feltet være tomt for manuelle deployment-poster.", + "no_coolify_instance": "Ingen Coolify-instans", + "coolify_instance_placeholder": "Coolify-instans-id", + "coolify_service_uuid": "Coolify service-UUID", + "coolify_service_uuid_message": "Vælg en eksisterende service eller indsæt en UUID.", + "coolify_service_uuid_placeholder": "Coolify service-UUID", + "health_url": "Health-URL", + "health_url_message": "Eksempel: https://api-canary.example.test/ping", + "health_url_placeholder": "Health-URL", + "ssl_domain": "SSL-domæne", + "ssl_domain_message": "Eksempel: canary.example.test", + "ssl_domain_placeholder": "SSL-domæne", + "https_domain_for_coolify": "HTTPS-domæne til Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Opret automatisk deployments, når dette mål ændres.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Bed Coolify om at oprette HTTPS for det konfigurerede domæne.", + "deploy_now": "Deploy nu", + "deploy_now_tooltip": "Start en deployment straks efter målet gemmes.", + "create_missing_service": "Opret manglende service", + "create_missing_service_tooltip": "Tillad Release Manager at oprette en manglende Coolify-service.", + "test_access_tooltip": "Bekræft, at den konfigurerede GitHub-token kan læse dette repository og branch." + } } }, "customer_creation": { diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index 7bebcddd..90d10984 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json @@ -1495,6 +1495,412 @@ }, "company_id": "Company ID", "company_id_desc": "The Workfeed company identifier used for API synchronization." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Schrittweise API- und Front-End-Releases", + "control_api": { + "title": "Kontroll-API", + "tooltip": "Release-Manager-Aktionen werden an diese API gesendet. Verwende die Produktions-Kontroll-API, au?er du testest ein Staging-Backend.", + "example": "Beispiel: https://api.truckwash.io:4433", + "endpoint_label": "API-Endpunkt", + "endpoint_message": "?ndere dies nur, wenn Release-Manager-Endpunkte auf der Ziel-API verf?gbar sind.", + "endpoint_aria": "Release Manager Kontroll-API-URL", + "use_tooltip": "Release-Daten von dieser API laden", + "use": "Verwenden", + "reset_tooltip": "Zur Standard-Kontroll-API zur?ckkehren", + "reset": "Zur?cksetzen", + "known_endpoints": "Bekannte Kontroll-API-Endpunkte" + }, + "tabs": { + "overview": { + "label": "?bersicht", + "description": "Kanalzustand, Einrichtungsfortschritt und aktueller Release-Status." + }, + "channels": { + "label": "Kan?le", + "description": "Stabile, Canary- und Zielkan?le mit Rollout-Grenzen erstellen." + }, + "assignments": { + "label": "Zuweisungen", + "description": "Benutzer, Unterbenutzer oder Kunden einem bestimmten Release-Kanal zuweisen." + }, + "deployments": { + "label": "Bereitstellungen", + "description": "Bereitstellungen starten und erfolgreiche Builds promoten." + }, + "replay": { + "label": "Replay", + "description": "Gezielte Erfassung aktivieren und Release-Timeline-Ereignisse durchsuchen." + }, + "integrations": { + "label": "Integrationen", + "description": "GitHub-Repositories, Branches und Coolify-Dienste verbinden." + }, + "settings": { + "label": "Einstellungen", + "description": "GitHub-Zugriff und Webhook-Einstellungen des Release Managers konfigurieren." + } + }, + "setup": { + "channels": "Kan?le", + "targets": "GitHub- und Coolify-Ziele", + "assignments": "Pilot-Zuweisungen", + "deployments": "Erste Bereitstellung", + "replay": "Replay-Erfassung" + }, + "stats": { + "channels": "Kan?le", + "targets": "Ziele", + "deployments": "Bereitstellungen", + "timeline_events": "Timeline-Ereignisse" + }, + "overview": { + "title": "?bersicht", + "subtitle": "Aktueller Kanalzustand, Release-Aktivit?t und Modulstatus.", + "guided_setup": "Gef?hrte Einrichtung", + "next_step": "N?chster Schritt: {step}", + "ready": "Release Manager ist f?r den t?glichen Betrieb bereit.", + "add_suggested_channel": "Vorgeschlagenen Kanal hinzufügen", + "module_health_empty": "Modul-Health-Snapshots erscheinen, nachdem Probes aufgezeichnet wurden." + }, + "settings": { + "title": "Release-Manager-Einstellungen", + "subtitle": "GitHub-Token f?r private Repositories und Branch-Abfragen konfigurieren.", + "github_token": "GitHub-Token", + "github_api_url": "GitHub-API-URL", + "webhook_secret": "Webhook-Secret", + "github_webhook_secret": "GitHub-Webhook-Secret", + "configured": "Konfiguriert", + "not_configured": "Nicht konfiguriert", + "loaded_from": "Geladen aus {variable}", + "set_below": "{variable} unten festlegen", + "private_repositories_prefix": "Private Repositories werden mit der Server-Umgebungsvariable gelesen", + "private_repositories_or": "oder der Modul-Konfigurationsvariable", + "github_token_message": "Beispiel: github_pat_... mit Zugriff auf die privaten Repositories, die Release Manager bereitstellt.", + "github_token_placeholder": "Leer lassen, um das vorhandene Token zu behalten", + "github_api_url_message": "Konfiguriert in ReleaseManager.github_api_url. https://api.github.com verwenden, sofern GitHub Enterprise nicht genutzt wird.", + "webhook_secret_message": "Optional; leer lassen, um das vorhandene Secret zu behalten.", + "webhook_secret_placeholder": "Webhook-HMAC-Secret", + "save": "Einstellungen speichern", + "back_to_integrations": "Zur?ck zu Integrationen", + "guide": { + "steps": { + "github_token": "GitHub-Token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub Webhook Secret", + "review": "Prüfung" + }, + "github_token_title": "GitHub-Token hinzufügen", + "github_token_description": "Release Manager verwendet diesen Token, um private Repositories, Branches und Commits aufzulisten, bevor ein Deployment-Ziel gespeichert oder getestet wird.", + "configure_this_in": "Dies konfigurieren in", + "server_environment_variable": "Die Server-Umgebungsvariable", + "takes_precedence": "hat Vorrang, wenn sie gesetzt ist.", + "recommended_access": "Empfohlener Zugriff", + "recommended_access_description": "Fine-grained GitHub-Token mit Contents: read-Zugriff für jedes Release-Repository.", + "github_api_url_title": "GitHub API-URL hinzufügen", + "github_api_url_description": "GitHub Cloud standardmäßig verwenden oder auf die REST-API-Basis-URL einer GitHub Enterprise Server-Installation zeigen.", + "github_api_url_invalid": "Vollständige HTTP- oder HTTPS-URL eingeben.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-Beispiel", + "github_webhook_secret_title": "GitHub Webhook Secret hinzufügen", + "github_webhook_secret_description": "Dasselbe Secret in GitHub-Repository-Webhooks verwenden, damit Release Manager Deployment-Events vor der Verarbeitung verifizieren kann.", + "github_webhook_url": "GitHub Webhook-URL:", + "store_shared_secret_in": "Geteiltes Secret speichern in", + "review_title": "GitHub-Konfiguration prüfen", + "review_description": "Werte speichern und dann unter Integrationen ein privates Repository, einen Branch und einen bestimmten Commit oder den neuesten Commit auswählen, bevor der Zugriff getestet wird.", + "ready": "Bereit", + "needs_value": "Wert fehlt" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-Kanal ist nicht bereit", + "summary_prefix": "Dein Konto ist zugewiesen zu", + "summary_suffix": ", aber diesem Kanal fehlt die Konfiguration, um sein Release-Image zu laden.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Erneute Pr?fung in {seconds}s", + "refresh_error": "Release-Status konnte nicht aktualisiert werden. Die n?chste automatische Pr?fung versucht es erneut.", + "ignore": "N?chste 5 Minuten ignorieren", + "check_again": "Erneut pr?fen", + "logout": "Abmelden", + "base_image": "Basis-Image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du bist jetzt auf {channel}", + "summary_prefix": "Dein Konto wurde dem Release-Kanal", + "summary_suffix": "zugewiesen. Dieses Ger?t merkt sich, dass du diesen Hinweis gesehen hast.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-Version", + "api_version": "API-Version", + "assigned_channel": "Zugewiesener Kanal", + "current_app_image": "Aktuelles App-Image", + "current_api": "Aktuelle API", + "base_image": "Basis-Image", + "continue": "Fortfahren" + }, + "common": { + "yes": "ja", + "no": "nein", + "off": "aus" + }, + "actions": { + "edit": "Bearbeiten", + "rollback": "Zurückrollen", + "update": "Aktualisieren", + "create": "Erstellen", + "clear": "Leeren", + "assign": "Zuweisen", + "remove": "Entfernen", + "test_access": "Zugriff testen", + "deploy": "Deployen", + "promote": "Promoten", + "enable": "Aktivieren", + "search": "Suchen", + "save_target": "Ziel speichern", + "delete": "Löschen", + "back": "Zurück", + "next": "Weiter" + }, + "tables": { + "channel": "Kanal", + "rollout": "Rollout", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Aktionen", + "module": "Module", + "status": "Status", + "checked": "Geprüft", + "subject": "Subjekt", + "reason": "Grund", + "expires": "Läuft ab", + "deployment": "Deployment", + "source": "Quelle", + "started": "Gestartet", + "target": "Ziel", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "Frontend", + "api": "API" + }, + "capture_level": { + "metadata": "Metadaten", + "full_redacted": "vollständig redigiert" + }, + "subject_type": { + "user": "Benutzer", + "subuser": "Mitarbeiter", + "customer": "Kunde", + "channel": "Kanal" + }, + "severity": { + "error": "Fehler", + "warning": "Warnung", + "info": "Info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployt", + "stable": "stabil", + "enabled": "aktiviert", + "queued": "in Warteschlange", + "deploying": "deploying", + "metadata": "Metadaten", + "not_configured": "nicht konfiguriert", + "warning": "Warnung", + "failed": "fehlgeschlagen", + "down": "down", + "error": "Fehler", + "unknown": "unbekannt" + } + }, + "autocomplete": { + "suggested_value": "Vorgeschlagener Wert", + "suggestion": "Vorschlag", + "use_typed_value": "Eingegebenen Wert verwenden", + "custom": "Benutzerdefiniert", + "api_url": "API URL", + "frontend_url": "Frontend URL", + "known_release_url": "Bekannte Release-URL", + "deploy_here_with_coolify": "{app} hier mit Coolify deployen", + "prepare_coolify_target": "Coolify-Ziel mit aktiviertem HTTPS/SSL vorbereiten", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-Repository", + "owner_repository": "owner/repository", + "git_branch": "Git branch", + "deployment_branch": "Deployment branch", + "github_commit": "GitHub commit", + "git_commit": "Git commit", + "use_specific_commit_sha": "Bestimmte Commit-SHA verwenden", + "custom_commit": "Benutzerdefinierter Commit", + "health_url": "Health URL", + "release_health_check": "Release-Health-Check", + "coolify_service": "Coolify service", + "service_uuid": "Service UUID", + "known_coolify_service_uuid": "Known Coolify service UUID", + "control_api": "Kontroll-API", + "release_manager_api_endpoint": "Release Manager API-Endpunkt", + "module": "Module", + "timeline_module_key": "Timeline-Modulschlüssel" + }, + "errors": { + "github_repositories": "GitHub-Repositories konnten nicht geladen werden.", + "github_branches": "GitHub-Branches konnten nicht geladen werden.", + "repository_branch_required": "Repository und Branch sind erforderlich, bevor GitHub-Zugriff getestet werden kann.", + "github_access_failed": "GitHub-Repository-Zugriffstest ist fehlgeschlagen." + }, + "channels": { + "title": "Kanäle", + "subtitle": "Graduale Release-Kanäle erstellen und anpassen.", + "rollout_percent": "{percent}% rollout", + "already_configured": "Bereits konfiguriert", + "slug": "Slug", + "slug_message": "Example: canary", + "slug_placeholder": "slug", + "name": "Name", + "name_message": "Wird Operatoren bei der Kanalprüfung angezeigt.", + "name_placeholder": "Name", + "rollout": "Rollout", + "rollout_message": "0-100 Prozent des nicht zugewiesenen Traffics.", + "frontend_url": "Frontend URL", + "frontend_url_message": "Example: https://canary.example.test", + "frontend_url_placeholder": "Frontend URL", + "no_matching_release_url": "Keine passende Release-URL.", + "api_url": "API URL", + "api_url_message": "Example: https://api-canary.example.test", + "api_url_placeholder": "API URL", + "no_matching_api_url": "Keine passende API-URL.", + "replay_capture": "Replay-Erfassung", + "replay_capture_message": "Metadaten sind für breite Kanäle sicherer.", + "retention_days": "Aufbewahrungstage", + "retention_days_message": "1-365 Tage.", + "enabled": "Aktiviert", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktiviert", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Zuweisungen", + "subtitle": "Benutzer, Mitarbeiter oder Kunden an Release-Kanäle binden.", + "subject_type": "Subjekttyp", + "subject_type_message": "Identitätstyp zum Binden auswählen.", + "customer": "Customer", + "customer_message": "Nach Kundennummer oder Name suchen und dann den genauen Kunden auswählen.", + "customer_placeholder": "Kunde suchen", + "subject_id": "Subjekt-ID", + "subject_id_message": "Beispiel: Benutzer-ID 42", + "subject_id_placeholder": "Subjekt-ID", + "channel": "Channel", + "channel_message": "Gebundene Subjekte umgehen den prozentualen Rollout.", + "reason": "Grund", + "reason_message": "Beispiel: Canary-Validierung für Kundensupport.", + "reason_placeholder": "Grund", + "expires": "Läuft ab", + "expires_message": "Leer lassen für kein automatisches Ablaufdatum." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Release-Deployments starten, promoten und prüfen.", + "manual_deployment_record": "Manueller Deployment-Eintrag", + "target": "Ziel", + "target_message": "Gespeichertes Ziel wählen oder manuelle Felder editierbar lassen.", + "select_target_or_manual": "Ziel oder manuell auswählen", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/front-end-vue", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-Auswahl", + "commit_selection_message": "Neueste Version wird mit dem konfigurierten GitHub-Token als Branch-Head aufgelöst.", + "latest_from_branch": "Neuester vom Branch", + "specific_commit": "Bestimmter Commit", + "specific_commit_message": "Example: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versionslabel", + "version_label_message": "Example: api-2026.05.19", + "version_label_placeholder": "Versionslabel", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Token-Zugriff auf das ausgewählte Repository, den Branch und Commit prüfen." + }, + "replay": { + "title": "Replay", + "subtitle": "Gezielte Erfassung aktivieren und Fehler-Timelines Schritt für Schritt prüfen.", + "capture_channel": "{channel} erfassen", + "target_type": "Zieltyp", + "target": "Ziel", + "target_message": "Beispiel: Benutzer-ID 42 oder Kanal-Slug canary.", + "target_placeholder": "Ziel-ID oder Kanal-Slug", + "channel_scope": "Kanalbereich", + "channel_scope_message": "Optional; begrenzt Replay-Erfassung auf einen Kanal.", + "no_channel_scope": "Kein Kanalbereich", + "capture_level": "Erfassungsstufe", + "expires": "Läuft ab", + "expires_message": "Leer lassen für manuelle Deaktivierung.", + "trace_id": "Trace ID", + "trace_id_message": "Example: trace-canary-1", + "trace_id_placeholder": "Trace id", + "channel": "Channel", + "channel_placeholder": "Channel", + "principal_id": "Principal ID", + "principal_id_placeholder": "Principal-ID", + "module": "Module", + "module_placeholder": "Module", + "severity": "Schweregrad", + "any_severity": "Beliebiger Schweregrad", + "no_timeline_events": "Keine Timeline-Events entsprechen den aktuellen Filtern." + }, + "integrations": { + "title": "GitHub und Coolify", + "subtitle": "GitHub-Repositories und Branches kanalspezifischen Coolify-Services zuordnen.", + "choose_repository": "Repository auswählen", + "add_health_url": "Health-URL hinzufügen", + "github_token_not_configured": "GitHub-Token ist nicht konfiguriert; private Repositories können nicht aufgelistet werden.", + "open_github_token_settings": "GitHub-Token-Einstellungen öffnen", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/backend-php", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Neueste: {commit}", + "coolify_instance": "Coolify-Instanz", + "coolify_instance_message": "Leer lassen für manuelle Deployment-Einträge.", + "no_coolify_instance": "Keine Coolify-Instanz", + "coolify_instance_placeholder": "Coolify-Instanz-ID", + "coolify_service_uuid": "Coolify service UUID", + "coolify_service_uuid_message": "Bestehenden Service auswählen oder UUID einfügen.", + "coolify_service_uuid_placeholder": "Coolify service UUID", + "health_url": "Health URL", + "health_url_message": "Example: https://api-canary.example.test/ping", + "health_url_placeholder": "Health URL", + "ssl_domain": "SSL-Domain", + "ssl_domain_message": "Example: canary.example.test", + "ssl_domain_placeholder": "SSL-Domain", + "https_domain_for_coolify": "HTTPS-Domain für Coolify", + "auto_deploy": "Auto-Deploy", + "auto_deploy_tooltip": "Automatisch Deployments erstellen, wenn sich dieses Ziel ändert.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Coolify anweisen, HTTPS für die konfigurierte Domain bereitzustellen.", + "deploy_now": "Jetzt deployen", + "deploy_now_tooltip": "Deployment direkt nach dem Speichern des Ziels starten.", + "create_missing_service": "Fehlenden Service erstellen", + "create_missing_service_tooltip": "Release Manager erlauben, einen fehlenden Coolify-Service zu erstellen.", + "test_access_tooltip": "Prüfen, ob der konfigurierte GitHub-Token dieses Repository und den Branch lesen kann." + } } }, "customer_creation": { diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 5ef952bb..0f34a2a6 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -1495,6 +1495,412 @@ }, "company_id": "Company ID", "company_id_desc": "The Workfeed company identifier used for API synchronization." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradual API and Front-End releases", + "control_api": { + "title": "Control API", + "tooltip": "Release Manager actions are sent to this API. Use the production control API unless testing a staged backend.", + "example": "Example: https://api.truckwash.io:4433", + "endpoint_label": "API endpoint", + "endpoint_message": "Switch this only when Release Manager endpoints are available on the target API.", + "endpoint_aria": "Release Manager control API URL", + "use_tooltip": "Load release data from this API", + "use": "Use", + "reset_tooltip": "Return to the default control API", + "reset": "Reset", + "known_endpoints": "Known control API endpoints" + }, + "tabs": { + "overview": { + "label": "Overview", + "description": "Channel health, setup progress, and the latest release state." + }, + "channels": { + "label": "Channels", + "description": "Create stable, canary, and targeted channels with rollout limits." + }, + "assignments": { + "label": "Assignments", + "description": "Pin users, subusers, or customers to a specific release channel." + }, + "deployments": { + "label": "Deployments", + "description": "Trigger deployments and promote successful builds." + }, + "replay": { + "label": "Replay", + "description": "Enable targeted capture and search release timeline events." + }, + "integrations": { + "label": "Integrations", + "description": "Connect GitHub repositories, branches, and Coolify services." + }, + "settings": { + "label": "Settings", + "description": "Configure Release Manager GitHub access and webhook settings." + } + }, + "setup": { + "channels": "Channels", + "targets": "GitHub and Coolify targets", + "assignments": "Pilot assignments", + "deployments": "First deployment", + "replay": "Replay capture" + }, + "stats": { + "channels": "Channels", + "targets": "Targets", + "deployments": "Deployments", + "timeline_events": "Timeline events" + }, + "overview": { + "title": "Overview", + "subtitle": "Current channel health, release activity, and module status.", + "guided_setup": "Guided setup", + "next_step": "Next: {step}", + "ready": "Release Manager is ready for day-to-day operations.", + "add_suggested_channel": "Add suggested channel", + "module_health_empty": "Module health snapshots appear after probes have been recorded." + }, + "settings": { + "title": "Release Manager Settings", + "subtitle": "Configure the GitHub token used for private repositories and branch lookups.", + "github_token": "GitHub token", + "github_api_url": "GitHub API URL", + "webhook_secret": "Webhook secret", + "github_webhook_secret": "GitHub webhook secret", + "configured": "Configured", + "not_configured": "Not configured", + "loaded_from": "Loaded from {variable}", + "set_below": "Set {variable} below", + "private_repositories_prefix": "Private repositories are read with the server environment variable", + "private_repositories_or": "or the module config variable", + "github_token_message": "Example: github_pat_... with access to the private repositories Release Manager deploys.", + "github_token_placeholder": "Leave blank to keep the existing token", + "github_api_url_message": "Configured in ReleaseManager.github_api_url. Use https://api.github.com unless using GitHub Enterprise.", + "webhook_secret_message": "Optional; leave blank to keep the existing secret.", + "webhook_secret_placeholder": "Webhook HMAC secret", + "save": "Save settings", + "back_to_integrations": "Back to integrations", + "guide": { + "steps": { + "github_token": "GitHub token", + "github_api_url": "GitHub API URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Review" + }, + "github_token_title": "Add GitHub token", + "github_token_description": "Release Manager uses this token to list private repositories, branches, and commits before a deployment target is saved or tested.", + "configure_this_in": "Configure this in", + "server_environment_variable": "The server environment variable", + "takes_precedence": "takes precedence when it is set.", + "recommended_access": "Recommended access", + "recommended_access_description": "Fine-grained GitHub token with Contents: read access for each release repository.", + "github_api_url_title": "Add GitHub API URL", + "github_api_url_description": "Use GitHub Cloud by default, or point this at the REST API base URL for a GitHub Enterprise Server installation.", + "github_api_url_invalid": "Enter a full HTTP or HTTPS URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise example", + "github_webhook_secret_title": "Add GitHub webhook secret", + "github_webhook_secret_description": "Use the same secret in GitHub repository webhooks so Release Manager can verify deployment events before handling them.", + "github_webhook_url": "GitHub webhook URL:", + "store_shared_secret_in": "Store the shared secret in", + "review_title": "Review GitHub setup", + "review_description": "Save the values, then use Integrations to select a private repository, branch, and specific commit or latest commit before testing access.", + "ready": "Ready", + "needs_value": "Needs value" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release channel is not ready", + "summary_prefix": "Your account is assigned to", + "summary_suffix": ", but that channel is missing the configuration needed to load its release image.", + "frontend_url": "Frontend URL", + "api_url": "API URL", + "checking_again": "Checking again in {seconds}s", + "refresh_error": "Release status could not be refreshed. The next automatic check will try again.", + "ignore": "Ignore next 5 minutes", + "check_again": "Check again", + "logout": "Logout", + "base_image": "Base image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "You are now on {channel}", + "summary_prefix": "Your account has been assigned to the", + "summary_suffix": "release channel. This device will remember that you have seen this notice.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend version", + "api_version": "API version", + "assigned_channel": "Assigned channel", + "current_app_image": "Current app image", + "current_api": "Current API", + "base_image": "Base image", + "continue": "Continue" + }, + "common": { + "yes": "yes", + "no": "no", + "off": "off" + }, + "actions": { + "edit": "Edit", + "rollback": "Rollback", + "update": "Update", + "create": "Create", + "clear": "Clear", + "assign": "Assign", + "remove": "Remove", + "test_access": "Test access", + "deploy": "Deploy", + "promote": "Promote", + "enable": "Enable", + "search": "Search", + "save_target": "Save target", + "delete": "Delete", + "back": "Back", + "next": "Next" + }, + "tables": { + "channel": "Channel", + "rollout": "Rollout", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Actions", + "module": "Module", + "status": "Status", + "checked": "Checked", + "subject": "Subject", + "reason": "Reason", + "expires": "Expires", + "deployment": "Deployment", + "source": "Source", + "started": "Started", + "target": "Target", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "full_redacted" + }, + "subject_type": { + "user": "user", + "subuser": "subuser", + "customer": "customer", + "channel": "channel" + }, + "severity": { + "error": "error", + "warning": "warning", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "active", + "deployed": "deployed", + "stable": "stable", + "enabled": "enabled", + "queued": "queued", + "deploying": "deploying", + "metadata": "metadata", + "not_configured": "not configured", + "warning": "warning", + "failed": "failed", + "down": "down", + "error": "error", + "unknown": "unknown" + } + }, + "autocomplete": { + "suggested_value": "Suggested value", + "suggestion": "Suggestion", + "use_typed_value": "Use typed value", + "custom": "Custom", + "api_url": "API URL", + "frontend_url": "Frontend URL", + "known_release_url": "Known release URL", + "deploy_here_with_coolify": "Deploy {app} here with Coolify", + "prepare_coolify_target": "Prepare a Coolify target with HTTPS/SSL enabled", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub repository", + "owner_repository": "owner/repository", + "git_branch": "Git branch", + "deployment_branch": "Deployment branch", + "github_commit": "GitHub commit", + "git_commit": "Git commit", + "use_specific_commit_sha": "Use specific commit SHA", + "custom_commit": "Custom commit", + "health_url": "Health URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify service", + "service_uuid": "Service UUID", + "known_coolify_service_uuid": "Known Coolify service UUID", + "control_api": "Control API", + "release_manager_api_endpoint": "Release Manager API endpoint", + "module": "Module", + "timeline_module_key": "Timeline module key" + }, + "errors": { + "github_repositories": "Could not load GitHub repositories.", + "github_branches": "Could not load GitHub branches.", + "repository_branch_required": "Repository and branch are required before testing GitHub access.", + "github_access_failed": "GitHub repository access test failed." + }, + "channels": { + "title": "Channels", + "subtitle": "Create and tune gradual release channels.", + "rollout_percent": "{percent}% rollout", + "already_configured": "Already configured", + "slug": "Slug", + "slug_message": "Example: canary", + "slug_placeholder": "slug", + "name": "Name", + "name_message": "Shown to operators when reviewing a channel.", + "name_placeholder": "Name", + "rollout": "Rollout", + "rollout_message": "0-100 percent of unassigned traffic.", + "frontend_url": "Frontend URL", + "frontend_url_message": "Example: https://canary.example.test", + "frontend_url_placeholder": "Frontend URL", + "no_matching_release_url": "No matching release URL.", + "api_url": "API URL", + "api_url_message": "Example: https://api-canary.example.test", + "api_url_placeholder": "API URL", + "no_matching_api_url": "No matching API URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata is safer for broad channels.", + "retention_days": "Retention days", + "retention_days_message": "1-365 days.", + "enabled": "Enabled", + "default_channel": "Default channel", + "replay_enabled": "Replay enabled", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Assignments", + "subtitle": "Pin users, subusers, or customers to release channels.", + "subject_type": "Subject type", + "subject_type_message": "Choose the identity type to pin.", + "customer": "Customer", + "customer_message": "Search by customer number or name, then select the exact customer.", + "customer_placeholder": "Search customer", + "subject_id": "Subject ID", + "subject_id_message": "Example: user id 42", + "subject_id_placeholder": "Subject id", + "channel": "Channel", + "channel_message": "Pinned subjects bypass percentage rollout.", + "reason": "Reason", + "reason_message": "Example: canary validation for customer support.", + "reason_placeholder": "Reason", + "expires": "Expires", + "expires_message": "Leave blank for no automatic expiry." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Trigger, promote, and inspect release deployments.", + "manual_deployment_record": "Manual deployment record", + "target": "Target", + "target_message": "Pick a saved target or keep manual fields editable.", + "select_target_or_manual": "Select target or manual", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/front-end-vue", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: main", + "branch_placeholder": "branch", + "commit_selection": "Commit selection", + "commit_selection_message": "Latest resolves to the branch head with the configured GitHub token.", + "latest_from_branch": "Latest from branch", + "specific_commit": "Specific commit", + "specific_commit_message": "Example: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Version label", + "version_label_message": "Example: api-2026.05.19", + "version_label_placeholder": "version label", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Verify token access to the selected repository, branch, and commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Enable targeted capture and step through failure timelines.", + "capture_channel": "Capture {channel}", + "target_type": "Target type", + "target": "Target", + "target_message": "Example: user id 42 or channel slug canary.", + "target_placeholder": "Target id or channel slug", + "channel_scope": "Channel scope", + "channel_scope_message": "Optional; limits replay capture to a channel.", + "no_channel_scope": "No channel scope", + "capture_level": "Capture level", + "expires": "Expires", + "expires_message": "Leave blank for manual disable.", + "trace_id": "Trace ID", + "trace_id_message": "Example: trace-canary-1", + "trace_id_placeholder": "Trace id", + "channel": "Channel", + "channel_placeholder": "Channel", + "principal_id": "Principal ID", + "principal_id_placeholder": "Principal id", + "module": "Module", + "module_placeholder": "Module", + "severity": "Severity", + "any_severity": "Any severity", + "no_timeline_events": "No timeline events match the current filters." + }, + "integrations": { + "title": "GitHub and Coolify", + "subtitle": "Map GitHub repositories and branches to channel-specific Coolify services.", + "choose_repository": "Choose repository", + "add_health_url": "add health URL", + "github_token_not_configured": "GitHub token is not configured; private repositories cannot be listed.", + "open_github_token_settings": "Open GitHub token settings", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/backend-php", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Latest: {commit}", + "coolify_instance": "Coolify instance", + "coolify_instance_message": "Leave empty for manual deployment records.", + "no_coolify_instance": "No Coolify instance", + "coolify_instance_placeholder": "Coolify instance id", + "coolify_service_uuid": "Coolify service UUID", + "coolify_service_uuid_message": "Select an existing service or paste a UUID.", + "coolify_service_uuid_placeholder": "Coolify service UUID", + "health_url": "Health URL", + "health_url_message": "Example: https://api-canary.example.test/ping", + "health_url_placeholder": "Health URL", + "ssl_domain": "SSL domain", + "ssl_domain_message": "Example: canary.example.test", + "ssl_domain_placeholder": "SSL domain", + "https_domain_for_coolify": "HTTPS domain for Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Automatically create deployments when this target changes.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Ask Coolify to provision HTTPS for the configured domain.", + "deploy_now": "Deploy now", + "deploy_now_tooltip": "Start a deployment immediately after saving the target.", + "create_missing_service": "Create missing service", + "create_missing_service_tooltip": "Allow Release Manager to create a missing Coolify service.", + "test_access_tooltip": "Verify the configured GitHub token can read this repository and branch." + } } }, "customer_creation": { diff --git a/src/i18n/locales/no.json b/src/i18n/locales/no.json index 0ccb2d9f..d6a2d0aa 100644 --- a/src/i18n/locales/no.json +++ b/src/i18n/locales/no.json @@ -1495,6 +1495,412 @@ }, "company_id": "Company ID", "company_id_desc": "The Workfeed company identifier used for API synchronization." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradvise API- og Front-End-utgivelser", + "control_api": { + "title": "Kontroll-API", + "tooltip": "Release Manager-handlinger sendes til denne API-en. Bruk produksjons-API-en med mindre du tester en staging-backend.", + "example": "Eksempel: https://api.truckwash.io:4433", + "endpoint_label": "API-endepunkt", + "endpoint_message": "Endre dette bare n?r Release Manager-endepunkter er tilgjengelige p? m?l-API-en.", + "endpoint_aria": "Release Manager kontroll-API URL", + "use_tooltip": "Last release-data fra denne API-en", + "use": "Bruk", + "reset_tooltip": "G? tilbake til standard kontroll-API", + "reset": "Tilbakestill", + "known_endpoints": "Kjente kontroll-API-endepunkter" + }, + "tabs": { + "overview": { + "label": "Oversikt", + "description": "Kanalhelse, oppsettsfremdrift og siste release-status." + }, + "channels": { + "label": "Kanaler", + "description": "Opprett stabile, canary- og m?lrettede kanaler med rollout-grenser." + }, + "assignments": { + "label": "Tildelinger", + "description": "Knytt brukere, underbrukere eller kunder til en bestemt release-kanal." + }, + "deployments": { + "label": "Utrullinger", + "description": "Start utrullinger og promoter vellykkede bygg." + }, + "replay": { + "label": "Replay", + "description": "Aktiver m?lrettet innsamling og s?k i release-tidslinjehendelser." + }, + "integrations": { + "label": "Integrasjoner", + "description": "Koble GitHub-repositories, branches og Coolify-tjenester." + }, + "settings": { + "label": "Innstillinger", + "description": "Konfigurer Release Managers GitHub-tilgang og webhook-innstillinger." + } + }, + "setup": { + "channels": "Kanaler", + "targets": "GitHub- og Coolify-m?l", + "assignments": "Pilottildelinger", + "deployments": "F?rste utrulling", + "replay": "Replay-innsamling" + }, + "stats": { + "channels": "Kanaler", + "targets": "M?l", + "deployments": "Utrullinger", + "timeline_events": "Tidslinjehendelser" + }, + "overview": { + "title": "Oversikt", + "subtitle": "Aktuell kanalhelse, release-aktivitet og modulstatus.", + "guided_setup": "Veiledet oppsett", + "next_step": "Neste: {step}", + "ready": "Release Manager er klar for daglig drift.", + "add_suggested_channel": "Legg til foreslått kanal", + "module_health_empty": "Modul-health snapshots vises når probes er registrert." + }, + "settings": { + "title": "Release Manager-innstillinger", + "subtitle": "Konfigurer GitHub-tokenet som brukes for private repositories og branch-oppslag.", + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "webhook_secret": "Webhook-hemmelighet", + "github_webhook_secret": "GitHub webhook-hemmelighet", + "configured": "Konfigurert", + "not_configured": "Ikke konfigurert", + "loaded_from": "Lastet fra {variable}", + "set_below": "Angi {variable} nedenfor", + "private_repositories_prefix": "Private repositories leses med serverens milj?variabel", + "private_repositories_or": "eller modulens konfigurasjonsvariabel", + "github_token_message": "Eksempel: github_pat_... med tilgang til de private repositories Release Manager ruller ut.", + "github_token_placeholder": "La st? tomt for ? beholde eksisterende token", + "github_api_url_message": "Konfigurert i ReleaseManager.github_api_url. Bruk https://api.github.com med mindre GitHub Enterprise brukes.", + "webhook_secret_message": "Valgfritt; la st? tomt for ? beholde eksisterende hemmelighet.", + "webhook_secret_placeholder": "Webhook HMAC-hemmelighet", + "save": "Lagre innstillinger", + "back_to_integrations": "Tilbake til integrasjoner", + "guide": { + "steps": { + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Gennemgang" + }, + "github_token_title": "Legg til GitHub-token", + "github_token_description": "Release Manager bruger denne token til at vise private repositories, branches og commits, før et deployment-mål gemmes eller testes.", + "configure_this_in": "Konfigurer dette i", + "server_environment_variable": "Serverens miljøvariabel", + "takes_precedence": "har forrang når den er satt.", + "recommended_access": "Anbefalt tilgang", + "recommended_access_description": "Fine-grained GitHub-token med Contents: read-adgang til hvert release-repository.", + "github_api_url_title": "Legg til GitHub API-URL", + "github_api_url_description": "Brug GitHub Cloud som standard, eller peg på REST API-base-URLen for en GitHub Enterprise Server-installation.", + "github_api_url_invalid": "Skriv inn en full HTTP- eller HTTPS-URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-eksempel", + "github_webhook_secret_title": "Legg til GitHub webhook secret", + "github_webhook_secret_description": "Brug samme secret i GitHub repository-webhooks, så Release Manager kan verificere deployment-events, før de håndteres.", + "github_webhook_url": "GitHub webhook-URL:", + "store_shared_secret_in": "Lagre den delte secreten i", + "review_title": "Gå gjennom GitHub-oppsett", + "review_description": "Gem værdierne, og brug derefter Integrationer til at vælge et privat repository, branch og specifik commit eller seneste commit før adgang testes.", + "ready": "Klar", + "needs_value": "Mangler værdi" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-kanalen er ikke klar", + "summary_prefix": "Kontoen din er tildelt", + "summary_suffix": ", men kanalen mangler konfigurasjonen som trengs for ? laste release-imaget.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Sjekker igjen om {seconds}s", + "refresh_error": "Release-status kunne ikke oppdateres. Neste automatiske sjekk pr?ver igjen.", + "ignore": "Ignorer de neste 5 minuttene", + "check_again": "Sjekk igjen", + "logout": "Logg ut", + "base_image": "Basis-image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du er n? p? {channel}", + "summary_prefix": "Kontoen din er tildelt release-kanalen", + "summary_suffix": "Denne enheten husker at du har sett denne meldingen.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-versjon", + "api_version": "API-versjon", + "assigned_channel": "Tildelt kanal", + "current_app_image": "N?v?rende app-image", + "current_api": "N?v?rende API", + "base_image": "Basis-image", + "continue": "Fortsett" + }, + "common": { + "yes": "ja", + "no": "nei", + "off": "av" + }, + "actions": { + "edit": "Rediger", + "rollback": "Rull tilbake", + "update": "Opdater", + "create": "Opprett", + "clear": "Tøm", + "assign": "Tildel", + "remove": "Fjern", + "test_access": "Test tilgang", + "deploy": "Deploy", + "promote": "Promoter", + "enable": "Aktiver", + "search": "Søk", + "save_target": "Lagre mål", + "delete": "Slett", + "back": "Tilbake", + "next": "Neste" + }, + "tables": { + "channel": "Kanal", + "rollout": "Udrulning", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Handlinger", + "module": "Modul", + "status": "Status", + "checked": "Kontrollert", + "subject": "Emne", + "reason": "Årsag", + "expires": "Utløper", + "deployment": "Deployment", + "source": "Kilde", + "started": "Startet", + "target": "Mål", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "fullt redigert" + }, + "subject_type": { + "user": "bruker", + "subuser": "medarbeider", + "customer": "kunde", + "channel": "kanal" + }, + "severity": { + "error": "feil", + "warning": "advarsel", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployet", + "stable": "stabil", + "enabled": "aktivert", + "queued": "i kø", + "deploying": "deploying", + "metadata": "metadata", + "not_configured": "ikke konfigurert", + "warning": "advarsel", + "failed": "feilet", + "down": "nede", + "error": "feil", + "unknown": "ukjent" + } + }, + "autocomplete": { + "suggested_value": "Foreslået værdi", + "suggestion": "Forslag", + "use_typed_value": "Brug indtastet værdi", + "custom": "Tilpasset", + "api_url": "API-URL", + "frontend_url": "Frontend-URL", + "known_release_url": "Kendt release-URL", + "deploy_here_with_coolify": "Deploy {app} her med Coolify", + "prepare_coolify_target": "Forbered et Coolify-mål med HTTPS/SSL aktiveret", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-repository", + "owner_repository": "ejer/repository", + "git_branch": "Git-branch", + "deployment_branch": "Deployment-branch", + "github_commit": "GitHub-commit", + "git_commit": "Git-commit", + "use_specific_commit_sha": "Brug specifik commit-SHA", + "custom_commit": "Tilpasset commit", + "health_url": "Health-URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify-service", + "service_uuid": "Service-UUID", + "known_coolify_service_uuid": "Kendt Coolify service-UUID", + "control_api": "Kontrol-API", + "release_manager_api_endpoint": "Release Manager API-endpoint", + "module": "Modul", + "timeline_module_key": "Timeline-modulnøgle" + }, + "errors": { + "github_repositories": "Kunne ikke indlæse GitHub-repositories.", + "github_branches": "Kunne ikke indlæse GitHub-branches.", + "repository_branch_required": "Repository og branch er påkrævet før GitHub-adgang kan testes.", + "github_access_failed": "Test af GitHub repository-adgang fejlede." + }, + "channels": { + "title": "Kanaler", + "subtitle": "Opprett og juster gradvise release-kanaler.", + "rollout_percent": "{percent}% udrulning", + "already_configured": "Allerede konfigurert", + "slug": "Slug", + "slug_message": "Eksempel: canary", + "slug_placeholder": "slug", + "name": "Navn", + "name_message": "Vises til operatører når de gjennomgår en kanal.", + "name_placeholder": "Navn", + "rollout": "Udrulning", + "rollout_message": "0-100 prosent av ikke-tildelt trafikk.", + "frontend_url": "Frontend-URL", + "frontend_url_message": "Eksempel: https://canary.example.test", + "frontend_url_placeholder": "Frontend-URL", + "no_matching_release_url": "Ingen matchende release-URL.", + "api_url": "API-URL", + "api_url_message": "Eksempel: https://api-canary.example.test", + "api_url_placeholder": "API-URL", + "no_matching_api_url": "Ingen matchende API-URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata er sikrere til brede kanaler.", + "retention_days": "Oppbevaringsdager", + "retention_days_message": "1-365 dage.", + "enabled": "Aktivert", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktivert", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Tildelinger", + "subtitle": "Fest brukere, medarbeidere eller kunder til release-kanaler.", + "subject_type": "Emnetype", + "subject_type_message": "Vælg identitetstypen, der skal fastgøres.", + "customer": "Kunde", + "customer_message": "Søk på kundenummer eller navn, og velg deretter nøyaktig kunde.", + "customer_placeholder": "Søk kunde", + "subject_id": "Emne-ID", + "subject_id_message": "Eksempel: bruker-id 42", + "subject_id_placeholder": "Emne-id", + "channel": "Kanal", + "channel_message": "Festede emner hopper over prosentutrullingen.", + "reason": "Årsag", + "reason_message": "Eksempel: canary-validering for kundesupport.", + "reason_placeholder": "Årsag", + "expires": "Utløper", + "expires_message": "Lad feltet være tomt for ingen automatisk udløb." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Start, promoter og inspiser release-deployments.", + "manual_deployment_record": "Manuel deployment-post", + "target": "Mål", + "target_message": "Vælg et gemt mål, eller behold manuelle felter redigerbare.", + "select_target_or_manual": "Velg mål eller manuelt", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/front-end-vue", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-valg", + "commit_selection_message": "Seneste slås op som branchens head med den konfigurerede GitHub-token.", + "latest_from_branch": "Siste fra branch", + "specific_commit": "Spesifikk commit", + "specific_commit_message": "Eksempel: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versjonsetikett", + "version_label_message": "Eksempel: api-2026.05.19", + "version_label_placeholder": "versionslabel", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Bekræft token-adgang til det valgte repository, branch og commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Aktiver målrettet capture og gennemgå fejltimelines trin for trin.", + "capture_channel": "Capture {channel}", + "target_type": "Måltype", + "target": "Mål", + "target_message": "Eksempel: bruker-id 42 eller kanal-slug canary.", + "target_placeholder": "Mål-id eller kanal-slug", + "channel_scope": "Kanalavgrensning", + "channel_scope_message": "Valgfrit; begrænser replay capture til en kanal.", + "no_channel_scope": "Ingen kanalavgrensning", + "capture_level": "Capture-niveau", + "expires": "Utløper", + "expires_message": "Lad feltet være tomt for manuel deaktivering.", + "trace_id": "Trace-ID", + "trace_id_message": "Eksempel: trace-canary-1", + "trace_id_placeholder": "Trace-id", + "channel": "Kanal", + "channel_placeholder": "Kanal", + "principal_id": "Principal-ID", + "principal_id_placeholder": "Principal-id", + "module": "Modul", + "module_placeholder": "Modul", + "severity": "Alvorlighet", + "any_severity": "Alle alvorligheder", + "no_timeline_events": "Ingen timeline-events matcher de aktuelle filtre." + }, + "integrations": { + "title": "GitHub og Coolify", + "subtitle": "Knyt GitHub-repositories og branches til kanalspecifikke Coolify-services.", + "choose_repository": "Velg repository", + "add_health_url": "legg til health-URL", + "github_token_not_configured": "GitHub-token er ikke konfigurert; private repositories kan ikke vises.", + "open_github_token_settings": "Åpne GitHub token-innstillinger", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/backend-php", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Seneste: {commit}", + "coolify_instance": "Coolify-instans", + "coolify_instance_message": "Lad feltet være tomt for manuelle deployment-poster.", + "no_coolify_instance": "Ingen Coolify-instans", + "coolify_instance_placeholder": "Coolify-instans-id", + "coolify_service_uuid": "Coolify service-UUID", + "coolify_service_uuid_message": "Vælg en eksisterende service eller indsæt en UUID.", + "coolify_service_uuid_placeholder": "Coolify service-UUID", + "health_url": "Health-URL", + "health_url_message": "Eksempel: https://api-canary.example.test/ping", + "health_url_placeholder": "Health-URL", + "ssl_domain": "SSL-domene", + "ssl_domain_message": "Eksempel: canary.example.test", + "ssl_domain_placeholder": "SSL-domene", + "https_domain_for_coolify": "HTTPS-domæne til Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Opret automatisk deployments, når dette mål ændres.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Bed Coolify om at oprette HTTPS for det konfigurerede domæne.", + "deploy_now": "Deploy nå", + "deploy_now_tooltip": "Start en deployment straks efter målet gemmes.", + "create_missing_service": "Opprett manglende service", + "create_missing_service_tooltip": "Tillad Release Manager at oprette en manglende Coolify-service.", + "test_access_tooltip": "Bekræft, at den konfigurerede GitHub-token kan læse dette repository og branch." + } } }, "customer_creation": { diff --git a/src/i18n/locales/sv.json b/src/i18n/locales/sv.json index 5c5159c4..e2a591b2 100644 --- a/src/i18n/locales/sv.json +++ b/src/i18n/locales/sv.json @@ -1495,6 +1495,412 @@ }, "company_id": "Company ID", "company_id_desc": "The Workfeed company identifier used for API synchronization." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradvisa API- och Front-End-versioner", + "control_api": { + "title": "Kontroll-API", + "tooltip": "Release Manager-?tg?rder skickas till detta API. Anv?nd produktions-API:t om du inte testar en staging-backend.", + "example": "Exempel: https://api.truckwash.io:4433", + "endpoint_label": "API-endpoint", + "endpoint_message": "?ndra detta endast n?r Release Manager-endpoints finns p? m?l-API:t.", + "endpoint_aria": "Release Manager kontroll-API URL", + "use_tooltip": "L?s in release-data fr?n detta API", + "use": "Anv?nd", + "reset_tooltip": "G? tillbaka till standard kontroll-API", + "reset": "?terst?ll", + "known_endpoints": "K?nda kontroll-API-endpoints" + }, + "tabs": { + "overview": { + "label": "?versikt", + "description": "Kanalh?lsa, installationsstatus och senaste release-l?ge." + }, + "channels": { + "label": "Kanaler", + "description": "Skapa stabila, canary- och riktade kanaler med rollout-gr?nser." + }, + "assignments": { + "label": "Tilldelningar", + "description": "Koppla anv?ndare, underanv?ndare eller kunder till en specifik release-kanal." + }, + "deployments": { + "label": "Utrullningar", + "description": "Starta utrullningar och promovera lyckade byggen." + }, + "replay": { + "label": "Replay", + "description": "Aktivera riktad insamling och s?k i release-tidslinjeh?ndelser." + }, + "integrations": { + "label": "Integrationer", + "description": "Anslut GitHub-repositories, branches och Coolify-tj?nster." + }, + "settings": { + "label": "Inst?llningar", + "description": "Konfigurera Release Managers GitHub-?tkomst och webhook-inst?llningar." + } + }, + "setup": { + "channels": "Kanaler", + "targets": "GitHub- och Coolify-m?l", + "assignments": "Pilottilldelningar", + "deployments": "F?rsta utrullningen", + "replay": "Replay-insamling" + }, + "stats": { + "channels": "Kanaler", + "targets": "M?l", + "deployments": "Utrullningar", + "timeline_events": "Tidslinjeh?ndelser" + }, + "overview": { + "title": "?versikt", + "subtitle": "Aktuell kanalh?lsa, release-aktivitet och modulstatus.", + "guided_setup": "Guidad installation", + "next_step": "N?sta: {step}", + "ready": "Release Manager ?r klar f?r daglig drift.", + "add_suggested_channel": "Lägg till föreslagen kanal", + "module_health_empty": "Modulhälsosnapshots visas när probes har registrerats." + }, + "settings": { + "title": "Release Manager-inst?llningar", + "subtitle": "Konfigurera GitHub-token som anv?nds f?r privata repositories och branch-uppslag.", + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "webhook_secret": "Webhook-hemlighet", + "github_webhook_secret": "GitHub webhook-hemlighet", + "configured": "Konfigurerad", + "not_configured": "Inte konfigurerad", + "loaded_from": "Inl?st fr?n {variable}", + "set_below": "Ange {variable} nedan", + "private_repositories_prefix": "Privata repositories l?ses med serverns milj?variabel", + "private_repositories_or": "eller modulens konfigurationsvariabel", + "github_token_message": "Exempel: github_pat_... med ?tkomst till de privata repositories som Release Manager distribuerar.", + "github_token_placeholder": "L?mna tomt f?r att beh?lla befintlig token", + "github_api_url_message": "Konfigurerad i ReleaseManager.github_api_url. Anv?nd https://api.github.com om du inte anv?nder GitHub Enterprise.", + "webhook_secret_message": "Valfritt; l?mna tomt f?r att beh?lla befintlig hemlighet.", + "webhook_secret_placeholder": "Webhook HMAC-hemlighet", + "save": "Spara inst?llningar", + "back_to_integrations": "Tillbaka till integrationer", + "guide": { + "steps": { + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Gennemgang" + }, + "github_token_title": "Lägg till GitHub-token", + "github_token_description": "Release Manager använder denna token för att lista privata repositories, branches och commits innan ett deployment-mål sparas eller testas.", + "configure_this_in": "Konfigurera detta i", + "server_environment_variable": "Serverns miljövariabel", + "takes_precedence": "har företräde när den är satt.", + "recommended_access": "Rekommenderad åtkomst", + "recommended_access_description": "Fine-grained GitHub-token med Contents: read-åtkomst till varje release-repository.", + "github_api_url_title": "Lägg till GitHub API-URL", + "github_api_url_description": "Brug GitHub Cloud som standard, eller peg på REST API-base-URLen for en GitHub Enterprise Server-installation.", + "github_api_url_invalid": "Ange en fullständig HTTP- eller HTTPS-URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-exempel", + "github_webhook_secret_title": "Lägg till GitHub webhook secret", + "github_webhook_secret_description": "Brug samme secret i GitHub repository-webhooks, så Release Manager kan verificere deployment-events, før de håndteres.", + "github_webhook_url": "GitHub webhook-URL:", + "store_shared_secret_in": "Spara den delade secret i", + "review_title": "Granska GitHub-konfiguration", + "review_description": "Gem værdierne, og brug derefter Integrationer til at vælge et privat repository, branch og specifik commit eller seneste commit før adgang testes.", + "ready": "Klar", + "needs_value": "Saknar värde" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-kanalen ?r inte klar", + "summary_prefix": "Ditt konto ?r tilldelat", + "summary_suffix": ", men kanalen saknar konfigurationen som beh?vs f?r att l?sa in dess release-image.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Kontrollerar igen om {seconds}s", + "refresh_error": "Release-status kunde inte uppdateras. N?sta automatiska kontroll f?rs?ker igen.", + "ignore": "Ignorera de kommande 5 minuterna", + "check_again": "Kontrollera igen", + "logout": "Logga ut", + "base_image": "Bas-image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du ?r nu p? {channel}", + "summary_prefix": "Ditt konto har tilldelats release-kanalen", + "summary_suffix": "Den h?r enheten kommer ih?g att du har sett detta meddelande.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-version", + "api_version": "API-version", + "assigned_channel": "Tilldelad kanal", + "current_app_image": "Nuvarande app-image", + "current_api": "Nuvarande API", + "base_image": "Bas-image", + "continue": "Forts?tt" + }, + "common": { + "yes": "ja", + "no": "nej", + "off": "av" + }, + "actions": { + "edit": "Redigera", + "rollback": "Rulla tillbaka", + "update": "Uppdatera", + "create": "Skapa", + "clear": "Rensa", + "assign": "Tilldela", + "remove": "Ta bort", + "test_access": "Testa åtkomst", + "deploy": "Deploy", + "promote": "Promota", + "enable": "Aktivera", + "search": "Sök", + "save_target": "Spara mål", + "delete": "Radera", + "back": "Tillbaka", + "next": "Nästa" + }, + "tables": { + "channel": "Kanal", + "rollout": "Udrulning", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Åtgärder", + "module": "Modul", + "status": "Status", + "checked": "Kontrollerad", + "subject": "Emne", + "reason": "Orsak", + "expires": "Upphör", + "deployment": "Deployment", + "source": "Källa", + "started": "Startet", + "target": "Mål", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "helt redigerad" + }, + "subject_type": { + "user": "användare", + "subuser": "medarbetare", + "customer": "kund", + "channel": "kanal" + }, + "severity": { + "error": "fel", + "warning": "varning", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployad", + "stable": "stabil", + "enabled": "aktiverad", + "queued": "i kö", + "deploying": "deployar", + "metadata": "metadata", + "not_configured": "inte konfigurerad", + "warning": "varning", + "failed": "misslyckad", + "down": "nere", + "error": "fel", + "unknown": "okänd" + } + }, + "autocomplete": { + "suggested_value": "Foreslået værdi", + "suggestion": "Forslag", + "use_typed_value": "Brug indtastet værdi", + "custom": "Tilpasset", + "api_url": "API-URL", + "frontend_url": "Frontend-URL", + "known_release_url": "Kendt release-URL", + "deploy_here_with_coolify": "Deploy {app} her med Coolify", + "prepare_coolify_target": "Forbered et Coolify-mål med HTTPS/SSL aktiveret", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-repository", + "owner_repository": "ejer/repository", + "git_branch": "Git-branch", + "deployment_branch": "Deployment-branch", + "github_commit": "GitHub-commit", + "git_commit": "Git-commit", + "use_specific_commit_sha": "Brug specifik commit-SHA", + "custom_commit": "Tilpasset commit", + "health_url": "Health-URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify-service", + "service_uuid": "Service-UUID", + "known_coolify_service_uuid": "Kendt Coolify service-UUID", + "control_api": "Kontrol-API", + "release_manager_api_endpoint": "Release Manager API-endpoint", + "module": "Modul", + "timeline_module_key": "Timeline-modulnøgle" + }, + "errors": { + "github_repositories": "Kunne ikke indlæse GitHub-repositories.", + "github_branches": "Kunne ikke indlæse GitHub-branches.", + "repository_branch_required": "Repository og branch er påkrævet før GitHub-adgang kan testes.", + "github_access_failed": "Test af GitHub repository-adgang fejlede." + }, + "channels": { + "title": "Kanaler", + "subtitle": "Skapa och justera gradvisa release-kanaler.", + "rollout_percent": "{percent}% utrullning", + "already_configured": "Redan konfigurerad", + "slug": "Slug", + "slug_message": "Eksempel: canary", + "slug_placeholder": "slug", + "name": "Namn", + "name_message": "Visas för operatörer när de granskar en kanal.", + "name_placeholder": "Namn", + "rollout": "Utrullning", + "rollout_message": "0-100 procent av otilldelad trafik.", + "frontend_url": "Frontend-URL", + "frontend_url_message": "Eksempel: https://canary.example.test", + "frontend_url_placeholder": "Frontend-URL", + "no_matching_release_url": "Ingen matchande release-URL.", + "api_url": "API-URL", + "api_url_message": "Eksempel: https://api-canary.example.test", + "api_url_placeholder": "API-URL", + "no_matching_api_url": "Ingen matchande API-URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata är säkrare för breda kanaler.", + "retention_days": "Lagringsdagar", + "retention_days_message": "1-365 dagar.", + "enabled": "Aktiverad", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktiverad", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Tilldelningar", + "subtitle": "Fäst användare, medarbetare eller kunder till release-kanaler.", + "subject_type": "Ämnestyp", + "subject_type_message": "Välj identitetstypen som ska fästas.", + "customer": "Kunde", + "customer_message": "Sök på kundnummer eller namn och välj sedan exakt kund.", + "customer_placeholder": "Sök kund", + "subject_id": "Ämnes-ID", + "subject_id_message": "Exempel: användar-id 42", + "subject_id_placeholder": "Ämnes-id", + "channel": "Kanal", + "channel_message": "Fästa ämnen hoppar över procentutrullningen.", + "reason": "Orsak", + "reason_message": "Exempel: canary-validering för kundsupport.", + "reason_placeholder": "Orsak", + "expires": "Upphör", + "expires_message": "Lämna tomt för ingen automatisk upphörning." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Starta, promota och inspektera release-deployments.", + "manual_deployment_record": "Manuel deployment-post", + "target": "Mål", + "target_message": "Välj ett sparat mål eller behåll manuella fält redigerbara.", + "select_target_or_manual": "Vælg mål eller manuel", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/front-end-vue", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-val", + "commit_selection_message": "Senaste slås upp som branchens head med konfigurerad GitHub-token.", + "latest_from_branch": "Senaste från branch", + "specific_commit": "Specifik commit", + "specific_commit_message": "Eksempel: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versionsetikett", + "version_label_message": "Eksempel: api-2026.05.19", + "version_label_placeholder": "versionsetikett", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Bekræft token-adgang til det valgte repository, branch og commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Aktivera riktad capture och gå igenom feltimelines steg för steg.", + "capture_channel": "Capture {channel}", + "target_type": "Måltype", + "target": "Mål", + "target_message": "Exempel: användar-id 42 eller kanal-slug canary.", + "target_placeholder": "Mål-id eller kanal-slug", + "channel_scope": "Kanalavgränsning", + "channel_scope_message": "Valgfrit; begrænser replay capture til en kanal.", + "no_channel_scope": "Ingen kanalavgränsning", + "capture_level": "Capture-niveau", + "expires": "Upphör", + "expires_message": "Lad feltet være tomt for manuel deaktivering.", + "trace_id": "Trace-ID", + "trace_id_message": "Eksempel: trace-canary-1", + "trace_id_placeholder": "Trace-id", + "channel": "Kanal", + "channel_placeholder": "Kanal", + "principal_id": "Principal-ID", + "principal_id_placeholder": "Principal-id", + "module": "Modul", + "module_placeholder": "Modul", + "severity": "Allvarlighetsgrad", + "any_severity": "Alla allvarlighetsgrader", + "no_timeline_events": "Ingen timeline-events matcher de aktuelle filtre." + }, + "integrations": { + "title": "GitHub och Coolify", + "subtitle": "Koppla GitHub-repositories och branches till kanalspecifika Coolify-tjänster.", + "choose_repository": "Välj repository", + "add_health_url": "lägg till health-URL", + "github_token_not_configured": "GitHub-token er ikke konfigureret; private repositories kan ikke vises.", + "open_github_token_settings": "Öppna GitHub token-inställningar", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/backend-php", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Seneste: {commit}", + "coolify_instance": "Coolify-instans", + "coolify_instance_message": "Lad feltet være tomt for manuelle deployment-poster.", + "no_coolify_instance": "Ingen Coolify-instans", + "coolify_instance_placeholder": "Coolify-instans-id", + "coolify_service_uuid": "Coolify service-UUID", + "coolify_service_uuid_message": "Vælg en eksisterende service eller indsæt en UUID.", + "coolify_service_uuid_placeholder": "Coolify service-UUID", + "health_url": "Health-URL", + "health_url_message": "Eksempel: https://api-canary.example.test/ping", + "health_url_placeholder": "Health-URL", + "ssl_domain": "SSL-domän", + "ssl_domain_message": "Eksempel: canary.example.test", + "ssl_domain_placeholder": "SSL-domän", + "https_domain_for_coolify": "HTTPS-domän för Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Opret automatisk deployments, når dette mål ændres.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Bed Coolify om at oprette HTTPS for det konfigurerede domæne.", + "deploy_now": "Deploy nu", + "deploy_now_tooltip": "Start en deployment straks efter målet gemmes.", + "create_missing_service": "Skapa saknad tjänst", + "create_missing_service_tooltip": "Tillad Release Manager at oprette en manglende Coolify-service.", + "test_access_tooltip": "Bekræft, at den konfigurerede GitHub-token kan læse dette repository og branch." + } } }, "customer_creation": { diff --git a/src/i18n/source/da/phrases/compat/configuration/index.json b/src/i18n/source/da/phrases/compat/configuration/index.json index 1ab3c820..36da9fde 100644 --- a/src/i18n/source/da/phrases/compat/configuration/index.json +++ b/src/i18n/source/da/phrases/compat/configuration/index.json @@ -298,6 +298,412 @@ "subtitle": "@.capitalize:{'terms.glossary.konfiguration'} @:{'terms.glossary.af'} @:{'terms.glossary.xlvask'} @:{'terms.glossary.integrationen'}", "title": "@:{'terms.glossary.xlvask'} @:{'terms.glossary.konfiguration'}", "username_desc": "@.capitalize:{'terms.glossary.brugernavnet'} @:{'terms.glossary.bruges'} @:{'terms.glossary.til'} @:{'terms.glossary.at'} @:{'terms.glossary.autentificere'} @:{'terms.glossary.api'} @:{'terms.glossary.forbindelsen'}." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradvise API- og Front-End-udgivelser", + "control_api": { + "title": "Kontrol-API", + "tooltip": "Release Manager-handlinger sendes til denne API. Brug produktions-API'en, medmindre du tester en staging-backend.", + "example": "Eksempel: https://api.truckwash.io:4433", + "endpoint_label": "API-endpoint", + "endpoint_message": "Skift kun dette, n?r Release Manager-endpoints er tilg?ngelige p? m?l-API'en.", + "endpoint_aria": "Release Manager kontrol-API URL", + "use_tooltip": "Indl?s release-data fra denne API", + "use": "Brug", + "reset_tooltip": "Vend tilbage til standard kontrol-API", + "reset": "Nulstil", + "known_endpoints": "Kendte kontrol-API-endpoints" + }, + "tabs": { + "overview": { + "label": "Oversigt", + "description": "Kanalstatus, ops?tningsfremdrift og seneste release-tilstand." + }, + "channels": { + "label": "Kanaler", + "description": "Opret stabile, canary- og m?lrettede kanaler med rollout-gr?nser." + }, + "assignments": { + "label": "Tildelinger", + "description": "Fastg?r brugere, subbrugere eller kunder til en bestemt release-kanal." + }, + "deployments": { + "label": "Udrulninger", + "description": "Start udrulninger og promover vellykkede builds." + }, + "replay": { + "label": "Replay", + "description": "Aktiv?r m?lrettet opsamling og s?g i release-tidslinjeh?ndelser." + }, + "integrations": { + "label": "Integrationer", + "description": "Forbind GitHub-repositories, branches og Coolify-services." + }, + "settings": { + "label": "Indstillinger", + "description": "Konfigurer Release Managers GitHub-adgang og webhook-indstillinger." + } + }, + "setup": { + "channels": "Kanaler", + "targets": "GitHub- og Coolify-m?l", + "assignments": "Pilot-tildelinger", + "deployments": "F?rste udrulning", + "replay": "Replay-opsamling" + }, + "stats": { + "channels": "Kanaler", + "targets": "M?l", + "deployments": "Udrulninger", + "timeline_events": "Tidslinjeh?ndelser" + }, + "overview": { + "title": "Oversigt", + "subtitle": "Aktuel kanalstatus, release-aktivitet og modulstatus.", + "guided_setup": "Guidet ops?tning", + "next_step": "N?ste: {step}", + "ready": "Release Manager er klar til daglig drift.", + "add_suggested_channel": "Tilføj foreslået kanal", + "module_health_empty": "Modul-health snapshots vises, når probes er blevet registreret." + }, + "settings": { + "title": "Release Manager-indstillinger", + "subtitle": "Konfigurer GitHub-tokenet, der bruges til private repositories og branch-opslag.", + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "webhook_secret": "Webhook-hemmelighed", + "github_webhook_secret": "GitHub webhook-hemmelighed", + "configured": "Konfigureret", + "not_configured": "Ikke konfigureret", + "loaded_from": "Indl?st fra {variable}", + "set_below": "Angiv {variable} nedenfor", + "private_repositories_prefix": "Private repositories l?ses med serverens milj?variabel", + "private_repositories_or": "eller modulets konfigurationsvariabel", + "github_token_message": "Eksempel: github_pat_... med adgang til de private repositories, Release Manager udruller.", + "github_token_placeholder": "Lad feltet v?re tomt for at beholde det eksisterende token", + "github_api_url_message": "Konfigureret i ReleaseManager.github_api_url. Brug https://api.github.com medmindre GitHub Enterprise bruges.", + "webhook_secret_message": "Valgfrit; lad feltet v?re tomt for at beholde den eksisterende hemmelighed.", + "webhook_secret_placeholder": "Webhook HMAC-hemmelighed", + "save": "Gem indstillinger", + "back_to_integrations": "Tilbage til integrationer", + "guide": { + "steps": { + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Gennemgang" + }, + "github_token_title": "Tilføj GitHub-token", + "github_token_description": "Release Manager bruger denne token til at vise private repositories, branches og commits, før et deployment-mål gemmes eller testes.", + "configure_this_in": "Konfigurer dette i", + "server_environment_variable": "Serverens miljøvariabel", + "takes_precedence": "har forrang, når den er sat.", + "recommended_access": "Anbefalet adgang", + "recommended_access_description": "Fine-grained GitHub-token med Contents: read-adgang til hvert release-repository.", + "github_api_url_title": "Tilføj GitHub API-URL", + "github_api_url_description": "Brug GitHub Cloud som standard, eller peg på REST API-base-URLen for en GitHub Enterprise Server-installation.", + "github_api_url_invalid": "Indtast en fuld HTTP- eller HTTPS-URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-eksempel", + "github_webhook_secret_title": "Tilføj GitHub webhook secret", + "github_webhook_secret_description": "Brug samme secret i GitHub repository-webhooks, så Release Manager kan verificere deployment-events, før de håndteres.", + "github_webhook_url": "GitHub webhook-URL:", + "store_shared_secret_in": "Gem den delte secret i", + "review_title": "Gennemgå GitHub-opsætning", + "review_description": "Gem værdierne, og brug derefter Integrationer til at vælge et privat repository, branch og specifik commit eller seneste commit før adgang testes.", + "ready": "Klar", + "needs_value": "Mangler værdi" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-kanalen er ikke klar", + "summary_prefix": "Din konto er tildelt", + "summary_suffix": ", men kanalen mangler den konfiguration, der skal bruges for at indl?se dens release-image.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Tjekker igen om {seconds}s", + "refresh_error": "Release-status kunne ikke opdateres. Det n?ste automatiske tjek pr?ver igen.", + "ignore": "Ignorer de n?ste 5 minutter", + "check_again": "Tjek igen", + "logout": "Log ud", + "base_image": "Basis-image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du er nu p? {channel}", + "summary_prefix": "Din konto er blevet tildelt release-kanalen", + "summary_suffix": "Denne enhed husker, at du har set denne besked.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-version", + "api_version": "API-version", + "assigned_channel": "Tildelt kanal", + "current_app_image": "Nuv?rende app-image", + "current_api": "Nuv?rende API", + "base_image": "Basis-image", + "continue": "Forts?t" + }, + "common": { + "yes": "ja", + "no": "nej", + "off": "fra" + }, + "actions": { + "edit": "Rediger", + "rollback": "Rul tilbage", + "update": "Opdater", + "create": "Opret", + "clear": "Ryd", + "assign": "Tildel", + "remove": "Fjern", + "test_access": "Test adgang", + "deploy": "Deploy", + "promote": "Promover", + "enable": "Aktiver", + "search": "Søg", + "save_target": "Gem mål", + "delete": "Slet", + "back": "Tilbage", + "next": "Næste" + }, + "tables": { + "channel": "Kanal", + "rollout": "Udrulning", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Handlinger", + "module": "Modul", + "status": "Status", + "checked": "Kontrolleret", + "subject": "Emne", + "reason": "Årsag", + "expires": "Udløber", + "deployment": "Deployment", + "source": "Kilde", + "started": "Startet", + "target": "Mål", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "fuldt redigeret" + }, + "subject_type": { + "user": "bruger", + "subuser": "medarbejder", + "customer": "kunde", + "channel": "kanal" + }, + "severity": { + "error": "fejl", + "warning": "advarsel", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployet", + "stable": "stabil", + "enabled": "aktiveret", + "queued": "i kø", + "deploying": "deploying", + "metadata": "metadata", + "not_configured": "ikke konfigureret", + "warning": "advarsel", + "failed": "fejlet", + "down": "nede", + "error": "fejl", + "unknown": "ukendt" + } + }, + "autocomplete": { + "suggested_value": "Foreslået værdi", + "suggestion": "Forslag", + "use_typed_value": "Brug indtastet værdi", + "custom": "Tilpasset", + "api_url": "API-URL", + "frontend_url": "Frontend-URL", + "known_release_url": "Kendt release-URL", + "deploy_here_with_coolify": "Deploy {app} her med Coolify", + "prepare_coolify_target": "Forbered et Coolify-mål med HTTPS/SSL aktiveret", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-repository", + "owner_repository": "ejer/repository", + "git_branch": "Git-branch", + "deployment_branch": "Deployment-branch", + "github_commit": "GitHub-commit", + "git_commit": "Git-commit", + "use_specific_commit_sha": "Brug specifik commit-SHA", + "custom_commit": "Tilpasset commit", + "health_url": "Health-URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify-service", + "service_uuid": "Service-UUID", + "known_coolify_service_uuid": "Kendt Coolify service-UUID", + "control_api": "Kontrol-API", + "release_manager_api_endpoint": "Release Manager API-endpoint", + "module": "Modul", + "timeline_module_key": "Timeline-modulnøgle" + }, + "errors": { + "github_repositories": "Kunne ikke indlæse GitHub-repositories.", + "github_branches": "Kunne ikke indlæse GitHub-branches.", + "repository_branch_required": "Repository og branch er påkrævet før GitHub-adgang kan testes.", + "github_access_failed": "Test af GitHub repository-adgang fejlede." + }, + "channels": { + "title": "Kanaler", + "subtitle": "Opret og juster gradvise release-kanaler.", + "rollout_percent": "{percent}% udrulning", + "already_configured": "Allerede konfigureret", + "slug": "Slug", + "slug_message": "Eksempel: canary", + "slug_placeholder": "slug", + "name": "Navn", + "name_message": "Vises til operatører, når de gennemgår en kanal.", + "name_placeholder": "Navn", + "rollout": "Udrulning", + "rollout_message": "0-100 procent af ikke-tildelt trafik.", + "frontend_url": "Frontend-URL", + "frontend_url_message": "Eksempel: https://canary.example.test", + "frontend_url_placeholder": "Frontend-URL", + "no_matching_release_url": "Ingen matchende release-URL.", + "api_url": "API-URL", + "api_url_message": "Eksempel: https://api-canary.example.test", + "api_url_placeholder": "API-URL", + "no_matching_api_url": "Ingen matchende API-URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata er sikrere til brede kanaler.", + "retention_days": "Opbevaringsdage", + "retention_days_message": "1-365 dage.", + "enabled": "Aktiveret", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktiveret", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Tildelinger", + "subtitle": "Fastgør brugere, medarbejdere eller kunder til release-kanaler.", + "subject_type": "Emnetype", + "subject_type_message": "Vælg identitetstypen, der skal fastgøres.", + "customer": "Kunde", + "customer_message": "Søg på kundenummer eller navn, og vælg derefter den præcise kunde.", + "customer_placeholder": "Søg kunde", + "subject_id": "Emne-ID", + "subject_id_message": "Eksempel: bruger-id 42", + "subject_id_placeholder": "Emne-id", + "channel": "Kanal", + "channel_message": "Fastgjorte emner springer procentudrulningen over.", + "reason": "Årsag", + "reason_message": "Eksempel: canary-validering for kundesupport.", + "reason_placeholder": "Årsag", + "expires": "Udløber", + "expires_message": "Lad feltet være tomt for ingen automatisk udløb." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Start, promover og inspicer release-deployments.", + "manual_deployment_record": "Manuel deployment-post", + "target": "Mål", + "target_message": "Vælg et gemt mål, eller behold manuelle felter redigerbare.", + "select_target_or_manual": "Vælg mål eller manuel", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/front-end-vue", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-valg", + "commit_selection_message": "Seneste slås op som branchens head med den konfigurerede GitHub-token.", + "latest_from_branch": "Seneste fra branch", + "specific_commit": "Specifik commit", + "specific_commit_message": "Eksempel: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versionslabel", + "version_label_message": "Eksempel: api-2026.05.19", + "version_label_placeholder": "versionslabel", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Bekræft token-adgang til det valgte repository, branch og commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Aktiver målrettet capture og gennemgå fejltimelines trin for trin.", + "capture_channel": "Capture {channel}", + "target_type": "Måltype", + "target": "Mål", + "target_message": "Eksempel: bruger-id 42 eller kanal-slug canary.", + "target_placeholder": "Mål-id eller kanal-slug", + "channel_scope": "Kanalafgrænsning", + "channel_scope_message": "Valgfrit; begrænser replay capture til en kanal.", + "no_channel_scope": "Ingen kanalafgrænsning", + "capture_level": "Capture-niveau", + "expires": "Udløber", + "expires_message": "Lad feltet være tomt for manuel deaktivering.", + "trace_id": "Trace-ID", + "trace_id_message": "Eksempel: trace-canary-1", + "trace_id_placeholder": "Trace-id", + "channel": "Kanal", + "channel_placeholder": "Kanal", + "principal_id": "Principal-ID", + "principal_id_placeholder": "Principal-id", + "module": "Modul", + "module_placeholder": "Modul", + "severity": "Alvorlighed", + "any_severity": "Alle alvorligheder", + "no_timeline_events": "Ingen timeline-events matcher de aktuelle filtre." + }, + "integrations": { + "title": "GitHub og Coolify", + "subtitle": "Knyt GitHub-repositories og branches til kanalspecifikke Coolify-services.", + "choose_repository": "Vælg repository", + "add_health_url": "tilføj health-URL", + "github_token_not_configured": "GitHub-token er ikke konfigureret; private repositories kan ikke vises.", + "open_github_token_settings": "Åbn GitHub token-indstillinger", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/backend-php", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Seneste: {commit}", + "coolify_instance": "Coolify-instans", + "coolify_instance_message": "Lad feltet være tomt for manuelle deployment-poster.", + "no_coolify_instance": "Ingen Coolify-instans", + "coolify_instance_placeholder": "Coolify-instans-id", + "coolify_service_uuid": "Coolify service-UUID", + "coolify_service_uuid_message": "Vælg en eksisterende service eller indsæt en UUID.", + "coolify_service_uuid_placeholder": "Coolify service-UUID", + "health_url": "Health-URL", + "health_url_message": "Eksempel: https://api-canary.example.test/ping", + "health_url_placeholder": "Health-URL", + "ssl_domain": "SSL-domæne", + "ssl_domain_message": "Eksempel: canary.example.test", + "ssl_domain_placeholder": "SSL-domæne", + "https_domain_for_coolify": "HTTPS-domæne til Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Opret automatisk deployments, når dette mål ændres.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Bed Coolify om at oprette HTTPS for det konfigurerede domæne.", + "deploy_now": "Deploy nu", + "deploy_now_tooltip": "Start en deployment straks efter målet gemmes.", + "create_missing_service": "Opret manglende service", + "create_missing_service_tooltip": "Tillad Release Manager at oprette en manglende Coolify-service.", + "test_access_tooltip": "Bekræft, at den konfigurerede GitHub-token kan læse dette repository og branch." + } } } } diff --git a/src/i18n/source/de/phrases/compat/configuration/index.json b/src/i18n/source/de/phrases/compat/configuration/index.json index 65338bb8..ed01441d 100644 --- a/src/i18n/source/de/phrases/compat/configuration/index.json +++ b/src/i18n/source/de/phrases/compat/configuration/index.json @@ -298,6 +298,412 @@ "subtitle": "@:{'terms.glossary.konfiguration'} @:{'terms.glossary.der'} @:{'terms.glossary.xlvask'}-@.capitalize:{'terms.glossary.integration'}", "title": "@:{'terms.glossary.xlvask'}-@:{'terms.glossary.konfiguration'}", "username_desc": "@.capitalize:{'terms.glossary.der'} @:{'terms.glossary.benutzername'} @:{'terms.glossary.wird'} @:{'terms.glossary.zur'} @:{'terms.glossary.authentifizierung'} @:{'terms.glossary.der'} @:{'terms.glossary.api'}-@:{'terms.glossary.verbindung'} @:{'terms.glossary.verwendet'}." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Schrittweise API- und Front-End-Releases", + "control_api": { + "title": "Kontroll-API", + "tooltip": "Release-Manager-Aktionen werden an diese API gesendet. Verwende die Produktions-Kontroll-API, au?er du testest ein Staging-Backend.", + "example": "Beispiel: https://api.truckwash.io:4433", + "endpoint_label": "API-Endpunkt", + "endpoint_message": "?ndere dies nur, wenn Release-Manager-Endpunkte auf der Ziel-API verf?gbar sind.", + "endpoint_aria": "Release Manager Kontroll-API-URL", + "use_tooltip": "Release-Daten von dieser API laden", + "use": "Verwenden", + "reset_tooltip": "Zur Standard-Kontroll-API zur?ckkehren", + "reset": "Zur?cksetzen", + "known_endpoints": "Bekannte Kontroll-API-Endpunkte" + }, + "tabs": { + "overview": { + "label": "?bersicht", + "description": "Kanalzustand, Einrichtungsfortschritt und aktueller Release-Status." + }, + "channels": { + "label": "Kan?le", + "description": "Stabile, Canary- und Zielkan?le mit Rollout-Grenzen erstellen." + }, + "assignments": { + "label": "Zuweisungen", + "description": "Benutzer, Unterbenutzer oder Kunden einem bestimmten Release-Kanal zuweisen." + }, + "deployments": { + "label": "Bereitstellungen", + "description": "Bereitstellungen starten und erfolgreiche Builds promoten." + }, + "replay": { + "label": "Replay", + "description": "Gezielte Erfassung aktivieren und Release-Timeline-Ereignisse durchsuchen." + }, + "integrations": { + "label": "Integrationen", + "description": "GitHub-Repositories, Branches und Coolify-Dienste verbinden." + }, + "settings": { + "label": "Einstellungen", + "description": "GitHub-Zugriff und Webhook-Einstellungen des Release Managers konfigurieren." + } + }, + "setup": { + "channels": "Kan?le", + "targets": "GitHub- und Coolify-Ziele", + "assignments": "Pilot-Zuweisungen", + "deployments": "Erste Bereitstellung", + "replay": "Replay-Erfassung" + }, + "stats": { + "channels": "Kan?le", + "targets": "Ziele", + "deployments": "Bereitstellungen", + "timeline_events": "Timeline-Ereignisse" + }, + "overview": { + "title": "?bersicht", + "subtitle": "Aktueller Kanalzustand, Release-Aktivit?t und Modulstatus.", + "guided_setup": "Gef?hrte Einrichtung", + "next_step": "N?chster Schritt: {step}", + "ready": "Release Manager ist f?r den t?glichen Betrieb bereit.", + "add_suggested_channel": "Vorgeschlagenen Kanal hinzufügen", + "module_health_empty": "Modul-Health-Snapshots erscheinen, nachdem Probes aufgezeichnet wurden." + }, + "settings": { + "title": "Release-Manager-Einstellungen", + "subtitle": "GitHub-Token f?r private Repositories und Branch-Abfragen konfigurieren.", + "github_token": "GitHub-Token", + "github_api_url": "GitHub-API-URL", + "webhook_secret": "Webhook-Secret", + "github_webhook_secret": "GitHub-Webhook-Secret", + "configured": "Konfiguriert", + "not_configured": "Nicht konfiguriert", + "loaded_from": "Geladen aus {variable}", + "set_below": "{variable} unten festlegen", + "private_repositories_prefix": "Private Repositories werden mit der Server-Umgebungsvariable gelesen", + "private_repositories_or": "oder der Modul-Konfigurationsvariable", + "github_token_message": "Beispiel: github_pat_... mit Zugriff auf die privaten Repositories, die Release Manager bereitstellt.", + "github_token_placeholder": "Leer lassen, um das vorhandene Token zu behalten", + "github_api_url_message": "Konfiguriert in ReleaseManager.github_api_url. https://api.github.com verwenden, sofern GitHub Enterprise nicht genutzt wird.", + "webhook_secret_message": "Optional; leer lassen, um das vorhandene Secret zu behalten.", + "webhook_secret_placeholder": "Webhook-HMAC-Secret", + "save": "Einstellungen speichern", + "back_to_integrations": "Zur?ck zu Integrationen", + "guide": { + "steps": { + "github_token": "GitHub-Token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub Webhook Secret", + "review": "Prüfung" + }, + "github_token_title": "GitHub-Token hinzufügen", + "github_token_description": "Release Manager verwendet diesen Token, um private Repositories, Branches und Commits aufzulisten, bevor ein Deployment-Ziel gespeichert oder getestet wird.", + "configure_this_in": "Dies konfigurieren in", + "server_environment_variable": "Die Server-Umgebungsvariable", + "takes_precedence": "hat Vorrang, wenn sie gesetzt ist.", + "recommended_access": "Empfohlener Zugriff", + "recommended_access_description": "Fine-grained GitHub-Token mit Contents: read-Zugriff für jedes Release-Repository.", + "github_api_url_title": "GitHub API-URL hinzufügen", + "github_api_url_description": "GitHub Cloud standardmäßig verwenden oder auf die REST-API-Basis-URL einer GitHub Enterprise Server-Installation zeigen.", + "github_api_url_invalid": "Vollständige HTTP- oder HTTPS-URL eingeben.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-Beispiel", + "github_webhook_secret_title": "GitHub Webhook Secret hinzufügen", + "github_webhook_secret_description": "Dasselbe Secret in GitHub-Repository-Webhooks verwenden, damit Release Manager Deployment-Events vor der Verarbeitung verifizieren kann.", + "github_webhook_url": "GitHub Webhook-URL:", + "store_shared_secret_in": "Geteiltes Secret speichern in", + "review_title": "GitHub-Konfiguration prüfen", + "review_description": "Werte speichern und dann unter Integrationen ein privates Repository, einen Branch und einen bestimmten Commit oder den neuesten Commit auswählen, bevor der Zugriff getestet wird.", + "ready": "Bereit", + "needs_value": "Wert fehlt" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-Kanal ist nicht bereit", + "summary_prefix": "Dein Konto ist zugewiesen zu", + "summary_suffix": ", aber diesem Kanal fehlt die Konfiguration, um sein Release-Image zu laden.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Erneute Pr?fung in {seconds}s", + "refresh_error": "Release-Status konnte nicht aktualisiert werden. Die n?chste automatische Pr?fung versucht es erneut.", + "ignore": "N?chste 5 Minuten ignorieren", + "check_again": "Erneut pr?fen", + "logout": "Abmelden", + "base_image": "Basis-Image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du bist jetzt auf {channel}", + "summary_prefix": "Dein Konto wurde dem Release-Kanal", + "summary_suffix": "zugewiesen. Dieses Ger?t merkt sich, dass du diesen Hinweis gesehen hast.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-Version", + "api_version": "API-Version", + "assigned_channel": "Zugewiesener Kanal", + "current_app_image": "Aktuelles App-Image", + "current_api": "Aktuelle API", + "base_image": "Basis-Image", + "continue": "Fortfahren" + }, + "common": { + "yes": "ja", + "no": "nein", + "off": "aus" + }, + "actions": { + "edit": "Bearbeiten", + "rollback": "Zurückrollen", + "update": "Aktualisieren", + "create": "Erstellen", + "clear": "Leeren", + "assign": "Zuweisen", + "remove": "Entfernen", + "test_access": "Zugriff testen", + "deploy": "Deployen", + "promote": "Promoten", + "enable": "Aktivieren", + "search": "Suchen", + "save_target": "Ziel speichern", + "delete": "Löschen", + "back": "Zurück", + "next": "Weiter" + }, + "tables": { + "channel": "Kanal", + "rollout": "Rollout", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Aktionen", + "module": "Module", + "status": "Status", + "checked": "Geprüft", + "subject": "Subjekt", + "reason": "Grund", + "expires": "Läuft ab", + "deployment": "Deployment", + "source": "Quelle", + "started": "Gestartet", + "target": "Ziel", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "Frontend", + "api": "API" + }, + "capture_level": { + "metadata": "Metadaten", + "full_redacted": "vollständig redigiert" + }, + "subject_type": { + "user": "Benutzer", + "subuser": "Mitarbeiter", + "customer": "Kunde", + "channel": "Kanal" + }, + "severity": { + "error": "Fehler", + "warning": "Warnung", + "info": "Info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployt", + "stable": "stabil", + "enabled": "aktiviert", + "queued": "in Warteschlange", + "deploying": "deploying", + "metadata": "Metadaten", + "not_configured": "nicht konfiguriert", + "warning": "Warnung", + "failed": "fehlgeschlagen", + "down": "down", + "error": "Fehler", + "unknown": "unbekannt" + } + }, + "autocomplete": { + "suggested_value": "Vorgeschlagener Wert", + "suggestion": "Vorschlag", + "use_typed_value": "Eingegebenen Wert verwenden", + "custom": "Benutzerdefiniert", + "api_url": "API URL", + "frontend_url": "Frontend URL", + "known_release_url": "Bekannte Release-URL", + "deploy_here_with_coolify": "{app} hier mit Coolify deployen", + "prepare_coolify_target": "Coolify-Ziel mit aktiviertem HTTPS/SSL vorbereiten", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-Repository", + "owner_repository": "owner/repository", + "git_branch": "Git branch", + "deployment_branch": "Deployment branch", + "github_commit": "GitHub commit", + "git_commit": "Git commit", + "use_specific_commit_sha": "Bestimmte Commit-SHA verwenden", + "custom_commit": "Benutzerdefinierter Commit", + "health_url": "Health URL", + "release_health_check": "Release-Health-Check", + "coolify_service": "Coolify service", + "service_uuid": "Service UUID", + "known_coolify_service_uuid": "Known Coolify service UUID", + "control_api": "Kontroll-API", + "release_manager_api_endpoint": "Release Manager API-Endpunkt", + "module": "Module", + "timeline_module_key": "Timeline-Modulschlüssel" + }, + "errors": { + "github_repositories": "GitHub-Repositories konnten nicht geladen werden.", + "github_branches": "GitHub-Branches konnten nicht geladen werden.", + "repository_branch_required": "Repository und Branch sind erforderlich, bevor GitHub-Zugriff getestet werden kann.", + "github_access_failed": "GitHub-Repository-Zugriffstest ist fehlgeschlagen." + }, + "channels": { + "title": "Kanäle", + "subtitle": "Graduale Release-Kanäle erstellen und anpassen.", + "rollout_percent": "{percent}% rollout", + "already_configured": "Bereits konfiguriert", + "slug": "Slug", + "slug_message": "Example: canary", + "slug_placeholder": "slug", + "name": "Name", + "name_message": "Wird Operatoren bei der Kanalprüfung angezeigt.", + "name_placeholder": "Name", + "rollout": "Rollout", + "rollout_message": "0-100 Prozent des nicht zugewiesenen Traffics.", + "frontend_url": "Frontend URL", + "frontend_url_message": "Example: https://canary.example.test", + "frontend_url_placeholder": "Frontend URL", + "no_matching_release_url": "Keine passende Release-URL.", + "api_url": "API URL", + "api_url_message": "Example: https://api-canary.example.test", + "api_url_placeholder": "API URL", + "no_matching_api_url": "Keine passende API-URL.", + "replay_capture": "Replay-Erfassung", + "replay_capture_message": "Metadaten sind für breite Kanäle sicherer.", + "retention_days": "Aufbewahrungstage", + "retention_days_message": "1-365 Tage.", + "enabled": "Aktiviert", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktiviert", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Zuweisungen", + "subtitle": "Benutzer, Mitarbeiter oder Kunden an Release-Kanäle binden.", + "subject_type": "Subjekttyp", + "subject_type_message": "Identitätstyp zum Binden auswählen.", + "customer": "Customer", + "customer_message": "Nach Kundennummer oder Name suchen und dann den genauen Kunden auswählen.", + "customer_placeholder": "Kunde suchen", + "subject_id": "Subjekt-ID", + "subject_id_message": "Beispiel: Benutzer-ID 42", + "subject_id_placeholder": "Subjekt-ID", + "channel": "Channel", + "channel_message": "Gebundene Subjekte umgehen den prozentualen Rollout.", + "reason": "Grund", + "reason_message": "Beispiel: Canary-Validierung für Kundensupport.", + "reason_placeholder": "Grund", + "expires": "Läuft ab", + "expires_message": "Leer lassen für kein automatisches Ablaufdatum." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Release-Deployments starten, promoten und prüfen.", + "manual_deployment_record": "Manueller Deployment-Eintrag", + "target": "Ziel", + "target_message": "Gespeichertes Ziel wählen oder manuelle Felder editierbar lassen.", + "select_target_or_manual": "Ziel oder manuell auswählen", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/front-end-vue", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-Auswahl", + "commit_selection_message": "Neueste Version wird mit dem konfigurierten GitHub-Token als Branch-Head aufgelöst.", + "latest_from_branch": "Neuester vom Branch", + "specific_commit": "Bestimmter Commit", + "specific_commit_message": "Example: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versionslabel", + "version_label_message": "Example: api-2026.05.19", + "version_label_placeholder": "Versionslabel", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Token-Zugriff auf das ausgewählte Repository, den Branch und Commit prüfen." + }, + "replay": { + "title": "Replay", + "subtitle": "Gezielte Erfassung aktivieren und Fehler-Timelines Schritt für Schritt prüfen.", + "capture_channel": "{channel} erfassen", + "target_type": "Zieltyp", + "target": "Ziel", + "target_message": "Beispiel: Benutzer-ID 42 oder Kanal-Slug canary.", + "target_placeholder": "Ziel-ID oder Kanal-Slug", + "channel_scope": "Kanalbereich", + "channel_scope_message": "Optional; begrenzt Replay-Erfassung auf einen Kanal.", + "no_channel_scope": "Kein Kanalbereich", + "capture_level": "Erfassungsstufe", + "expires": "Läuft ab", + "expires_message": "Leer lassen für manuelle Deaktivierung.", + "trace_id": "Trace ID", + "trace_id_message": "Example: trace-canary-1", + "trace_id_placeholder": "Trace id", + "channel": "Channel", + "channel_placeholder": "Channel", + "principal_id": "Principal ID", + "principal_id_placeholder": "Principal-ID", + "module": "Module", + "module_placeholder": "Module", + "severity": "Schweregrad", + "any_severity": "Beliebiger Schweregrad", + "no_timeline_events": "Keine Timeline-Events entsprechen den aktuellen Filtern." + }, + "integrations": { + "title": "GitHub und Coolify", + "subtitle": "GitHub-Repositories und Branches kanalspezifischen Coolify-Services zuordnen.", + "choose_repository": "Repository auswählen", + "add_health_url": "Health-URL hinzufügen", + "github_token_not_configured": "GitHub-Token ist nicht konfiguriert; private Repositories können nicht aufgelistet werden.", + "open_github_token_settings": "GitHub-Token-Einstellungen öffnen", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/backend-php", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Neueste: {commit}", + "coolify_instance": "Coolify-Instanz", + "coolify_instance_message": "Leer lassen für manuelle Deployment-Einträge.", + "no_coolify_instance": "Keine Coolify-Instanz", + "coolify_instance_placeholder": "Coolify-Instanz-ID", + "coolify_service_uuid": "Coolify service UUID", + "coolify_service_uuid_message": "Bestehenden Service auswählen oder UUID einfügen.", + "coolify_service_uuid_placeholder": "Coolify service UUID", + "health_url": "Health URL", + "health_url_message": "Example: https://api-canary.example.test/ping", + "health_url_placeholder": "Health URL", + "ssl_domain": "SSL-Domain", + "ssl_domain_message": "Example: canary.example.test", + "ssl_domain_placeholder": "SSL-Domain", + "https_domain_for_coolify": "HTTPS-Domain für Coolify", + "auto_deploy": "Auto-Deploy", + "auto_deploy_tooltip": "Automatisch Deployments erstellen, wenn sich dieses Ziel ändert.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Coolify anweisen, HTTPS für die konfigurierte Domain bereitzustellen.", + "deploy_now": "Jetzt deployen", + "deploy_now_tooltip": "Deployment direkt nach dem Speichern des Ziels starten.", + "create_missing_service": "Fehlenden Service erstellen", + "create_missing_service_tooltip": "Release Manager erlauben, einen fehlenden Coolify-Service zu erstellen.", + "test_access_tooltip": "Prüfen, ob der konfigurierte GitHub-Token dieses Repository und den Branch lesen kann." + } } } } diff --git a/src/i18n/source/en/phrases/compat/configuration/index.json b/src/i18n/source/en/phrases/compat/configuration/index.json index 03319353..c5b6194a 100644 --- a/src/i18n/source/en/phrases/compat/configuration/index.json +++ b/src/i18n/source/en/phrases/compat/configuration/index.json @@ -298,6 +298,412 @@ "subtitle": "@.capitalize:{'terms.glossary.configuration'} @:{'terms.glossary.of'} @:{'terms.replication.article.host_mention'} @:{'terms.glossary.xlvask'} @:{'terms.glossary.integration'}", "title": "@:{'terms.glossary.xlvask'} @:{'terms.glossary.configuration'}", "username_desc": "@.capitalize:{'terms.replication.article.host_mention'} @:{'terms.glossary.username'} @:{'terms.glossary.is'} @:{'terms.glossary.used'} @:{'terms.glossary.to'} @:{'terms.glossary.authenticate'} @:{'terms.replication.article.host_mention'} @:{'terms.glossary.api'} @:{'terms.glossary.connection'}." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradual API and Front-End releases", + "control_api": { + "title": "Control API", + "tooltip": "Release Manager actions are sent to this API. Use the production control API unless testing a staged backend.", + "example": "Example: https://api.truckwash.io:4433", + "endpoint_label": "API endpoint", + "endpoint_message": "Switch this only when Release Manager endpoints are available on the target API.", + "endpoint_aria": "Release Manager control API URL", + "use_tooltip": "Load release data from this API", + "use": "Use", + "reset_tooltip": "Return to the default control API", + "reset": "Reset", + "known_endpoints": "Known control API endpoints" + }, + "tabs": { + "overview": { + "label": "Overview", + "description": "Channel health, setup progress, and the latest release state." + }, + "channels": { + "label": "Channels", + "description": "Create stable, canary, and targeted channels with rollout limits." + }, + "assignments": { + "label": "Assignments", + "description": "Pin users, subusers, or customers to a specific release channel." + }, + "deployments": { + "label": "Deployments", + "description": "Trigger deployments and promote successful builds." + }, + "replay": { + "label": "Replay", + "description": "Enable targeted capture and search release timeline events." + }, + "integrations": { + "label": "Integrations", + "description": "Connect GitHub repositories, branches, and Coolify services." + }, + "settings": { + "label": "Settings", + "description": "Configure Release Manager GitHub access and webhook settings." + } + }, + "setup": { + "channels": "Channels", + "targets": "GitHub and Coolify targets", + "assignments": "Pilot assignments", + "deployments": "First deployment", + "replay": "Replay capture" + }, + "stats": { + "channels": "Channels", + "targets": "Targets", + "deployments": "Deployments", + "timeline_events": "Timeline events" + }, + "overview": { + "title": "Overview", + "subtitle": "Current channel health, release activity, and module status.", + "guided_setup": "Guided setup", + "next_step": "Next: {step}", + "ready": "Release Manager is ready for day-to-day operations.", + "add_suggested_channel": "Add suggested channel", + "module_health_empty": "Module health snapshots appear after probes have been recorded." + }, + "settings": { + "title": "Release Manager Settings", + "subtitle": "Configure the GitHub token used for private repositories and branch lookups.", + "github_token": "GitHub token", + "github_api_url": "GitHub API URL", + "webhook_secret": "Webhook secret", + "github_webhook_secret": "GitHub webhook secret", + "configured": "Configured", + "not_configured": "Not configured", + "loaded_from": "Loaded from {variable}", + "set_below": "Set {variable} below", + "private_repositories_prefix": "Private repositories are read with the server environment variable", + "private_repositories_or": "or the module config variable", + "github_token_message": "Example: github_pat_... with access to the private repositories Release Manager deploys.", + "github_token_placeholder": "Leave blank to keep the existing token", + "github_api_url_message": "Configured in ReleaseManager.github_api_url. Use https://api.github.com unless using GitHub Enterprise.", + "webhook_secret_message": "Optional; leave blank to keep the existing secret.", + "webhook_secret_placeholder": "Webhook HMAC secret", + "save": "Save settings", + "back_to_integrations": "Back to integrations", + "guide": { + "steps": { + "github_token": "GitHub token", + "github_api_url": "GitHub API URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Review" + }, + "github_token_title": "Add GitHub token", + "github_token_description": "Release Manager uses this token to list private repositories, branches, and commits before a deployment target is saved or tested.", + "configure_this_in": "Configure this in", + "server_environment_variable": "The server environment variable", + "takes_precedence": "takes precedence when it is set.", + "recommended_access": "Recommended access", + "recommended_access_description": "Fine-grained GitHub token with Contents: read access for each release repository.", + "github_api_url_title": "Add GitHub API URL", + "github_api_url_description": "Use GitHub Cloud by default, or point this at the REST API base URL for a GitHub Enterprise Server installation.", + "github_api_url_invalid": "Enter a full HTTP or HTTPS URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise example", + "github_webhook_secret_title": "Add GitHub webhook secret", + "github_webhook_secret_description": "Use the same secret in GitHub repository webhooks so Release Manager can verify deployment events before handling them.", + "github_webhook_url": "GitHub webhook URL:", + "store_shared_secret_in": "Store the shared secret in", + "review_title": "Review GitHub setup", + "review_description": "Save the values, then use Integrations to select a private repository, branch, and specific commit or latest commit before testing access.", + "ready": "Ready", + "needs_value": "Needs value" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release channel is not ready", + "summary_prefix": "Your account is assigned to", + "summary_suffix": ", but that channel is missing the configuration needed to load its release image.", + "frontend_url": "Frontend URL", + "api_url": "API URL", + "checking_again": "Checking again in {seconds}s", + "refresh_error": "Release status could not be refreshed. The next automatic check will try again.", + "ignore": "Ignore next 5 minutes", + "check_again": "Check again", + "logout": "Logout", + "base_image": "Base image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "You are now on {channel}", + "summary_prefix": "Your account has been assigned to the", + "summary_suffix": "release channel. This device will remember that you have seen this notice.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend version", + "api_version": "API version", + "assigned_channel": "Assigned channel", + "current_app_image": "Current app image", + "current_api": "Current API", + "base_image": "Base image", + "continue": "Continue" + }, + "common": { + "yes": "yes", + "no": "no", + "off": "off" + }, + "actions": { + "edit": "Edit", + "rollback": "Rollback", + "update": "Update", + "create": "Create", + "clear": "Clear", + "assign": "Assign", + "remove": "Remove", + "test_access": "Test access", + "deploy": "Deploy", + "promote": "Promote", + "enable": "Enable", + "search": "Search", + "save_target": "Save target", + "delete": "Delete", + "back": "Back", + "next": "Next" + }, + "tables": { + "channel": "Channel", + "rollout": "Rollout", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Actions", + "module": "Module", + "status": "Status", + "checked": "Checked", + "subject": "Subject", + "reason": "Reason", + "expires": "Expires", + "deployment": "Deployment", + "source": "Source", + "started": "Started", + "target": "Target", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "full_redacted" + }, + "subject_type": { + "user": "user", + "subuser": "subuser", + "customer": "customer", + "channel": "channel" + }, + "severity": { + "error": "error", + "warning": "warning", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "active", + "deployed": "deployed", + "stable": "stable", + "enabled": "enabled", + "queued": "queued", + "deploying": "deploying", + "metadata": "metadata", + "not_configured": "not configured", + "warning": "warning", + "failed": "failed", + "down": "down", + "error": "error", + "unknown": "unknown" + } + }, + "autocomplete": { + "suggested_value": "Suggested value", + "suggestion": "Suggestion", + "use_typed_value": "Use typed value", + "custom": "Custom", + "api_url": "API URL", + "frontend_url": "Frontend URL", + "known_release_url": "Known release URL", + "deploy_here_with_coolify": "Deploy {app} here with Coolify", + "prepare_coolify_target": "Prepare a Coolify target with HTTPS/SSL enabled", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub repository", + "owner_repository": "owner/repository", + "git_branch": "Git branch", + "deployment_branch": "Deployment branch", + "github_commit": "GitHub commit", + "git_commit": "Git commit", + "use_specific_commit_sha": "Use specific commit SHA", + "custom_commit": "Custom commit", + "health_url": "Health URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify service", + "service_uuid": "Service UUID", + "known_coolify_service_uuid": "Known Coolify service UUID", + "control_api": "Control API", + "release_manager_api_endpoint": "Release Manager API endpoint", + "module": "Module", + "timeline_module_key": "Timeline module key" + }, + "errors": { + "github_repositories": "Could not load GitHub repositories.", + "github_branches": "Could not load GitHub branches.", + "repository_branch_required": "Repository and branch are required before testing GitHub access.", + "github_access_failed": "GitHub repository access test failed." + }, + "channels": { + "title": "Channels", + "subtitle": "Create and tune gradual release channels.", + "rollout_percent": "{percent}% rollout", + "already_configured": "Already configured", + "slug": "Slug", + "slug_message": "Example: canary", + "slug_placeholder": "slug", + "name": "Name", + "name_message": "Shown to operators when reviewing a channel.", + "name_placeholder": "Name", + "rollout": "Rollout", + "rollout_message": "0-100 percent of unassigned traffic.", + "frontend_url": "Frontend URL", + "frontend_url_message": "Example: https://canary.example.test", + "frontend_url_placeholder": "Frontend URL", + "no_matching_release_url": "No matching release URL.", + "api_url": "API URL", + "api_url_message": "Example: https://api-canary.example.test", + "api_url_placeholder": "API URL", + "no_matching_api_url": "No matching API URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata is safer for broad channels.", + "retention_days": "Retention days", + "retention_days_message": "1-365 days.", + "enabled": "Enabled", + "default_channel": "Default channel", + "replay_enabled": "Replay enabled", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Assignments", + "subtitle": "Pin users, subusers, or customers to release channels.", + "subject_type": "Subject type", + "subject_type_message": "Choose the identity type to pin.", + "customer": "Customer", + "customer_message": "Search by customer number or name, then select the exact customer.", + "customer_placeholder": "Search customer", + "subject_id": "Subject ID", + "subject_id_message": "Example: user id 42", + "subject_id_placeholder": "Subject id", + "channel": "Channel", + "channel_message": "Pinned subjects bypass percentage rollout.", + "reason": "Reason", + "reason_message": "Example: canary validation for customer support.", + "reason_placeholder": "Reason", + "expires": "Expires", + "expires_message": "Leave blank for no automatic expiry." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Trigger, promote, and inspect release deployments.", + "manual_deployment_record": "Manual deployment record", + "target": "Target", + "target_message": "Pick a saved target or keep manual fields editable.", + "select_target_or_manual": "Select target or manual", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/front-end-vue", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: main", + "branch_placeholder": "branch", + "commit_selection": "Commit selection", + "commit_selection_message": "Latest resolves to the branch head with the configured GitHub token.", + "latest_from_branch": "Latest from branch", + "specific_commit": "Specific commit", + "specific_commit_message": "Example: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Version label", + "version_label_message": "Example: api-2026.05.19", + "version_label_placeholder": "version label", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Verify token access to the selected repository, branch, and commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Enable targeted capture and step through failure timelines.", + "capture_channel": "Capture {channel}", + "target_type": "Target type", + "target": "Target", + "target_message": "Example: user id 42 or channel slug canary.", + "target_placeholder": "Target id or channel slug", + "channel_scope": "Channel scope", + "channel_scope_message": "Optional; limits replay capture to a channel.", + "no_channel_scope": "No channel scope", + "capture_level": "Capture level", + "expires": "Expires", + "expires_message": "Leave blank for manual disable.", + "trace_id": "Trace ID", + "trace_id_message": "Example: trace-canary-1", + "trace_id_placeholder": "Trace id", + "channel": "Channel", + "channel_placeholder": "Channel", + "principal_id": "Principal ID", + "principal_id_placeholder": "Principal id", + "module": "Module", + "module_placeholder": "Module", + "severity": "Severity", + "any_severity": "Any severity", + "no_timeline_events": "No timeline events match the current filters." + }, + "integrations": { + "title": "GitHub and Coolify", + "subtitle": "Map GitHub repositories and branches to channel-specific Coolify services.", + "choose_repository": "Choose repository", + "add_health_url": "add health URL", + "github_token_not_configured": "GitHub token is not configured; private repositories cannot be listed.", + "open_github_token_settings": "Open GitHub token settings", + "channel": "Channel", + "app": "App", + "repository": "Repository", + "repository_message": "Example: truckwash/backend-php", + "repository_placeholder": "owner/repo", + "branch": "Branch", + "branch_message": "Example: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Latest: {commit}", + "coolify_instance": "Coolify instance", + "coolify_instance_message": "Leave empty for manual deployment records.", + "no_coolify_instance": "No Coolify instance", + "coolify_instance_placeholder": "Coolify instance id", + "coolify_service_uuid": "Coolify service UUID", + "coolify_service_uuid_message": "Select an existing service or paste a UUID.", + "coolify_service_uuid_placeholder": "Coolify service UUID", + "health_url": "Health URL", + "health_url_message": "Example: https://api-canary.example.test/ping", + "health_url_placeholder": "Health URL", + "ssl_domain": "SSL domain", + "ssl_domain_message": "Example: canary.example.test", + "ssl_domain_placeholder": "SSL domain", + "https_domain_for_coolify": "HTTPS domain for Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Automatically create deployments when this target changes.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Ask Coolify to provision HTTPS for the configured domain.", + "deploy_now": "Deploy now", + "deploy_now_tooltip": "Start a deployment immediately after saving the target.", + "create_missing_service": "Create missing service", + "create_missing_service_tooltip": "Allow Release Manager to create a missing Coolify service.", + "test_access_tooltip": "Verify the configured GitHub token can read this repository and branch." + } } } } diff --git a/src/i18n/source/global/shared/configuration/index.json b/src/i18n/source/global/shared/configuration/index.json index 9fe7ea73..eaa0da46 100644 --- a/src/i18n/source/global/shared/configuration/index.json +++ b/src/i18n/source/global/shared/configuration/index.json @@ -351,6 +351,412 @@ "title": "@:{'phrases.compat.configuration.xlvask.title'}", "username": "@:auth.username", "username_desc": "@:{'phrases.compat.configuration.xlvask.username_desc'}" + }, + "release_manager": { + "title": "@:{'phrases.compat.configuration.release_manager.title'}", + "subtitle": "@:{'phrases.compat.configuration.release_manager.subtitle'}", + "control_api": { + "title": "@:{'phrases.compat.configuration.release_manager.control_api.title'}", + "tooltip": "@:{'phrases.compat.configuration.release_manager.control_api.tooltip'}", + "example": "@:{'phrases.compat.configuration.release_manager.control_api.example'}", + "endpoint_label": "@:{'phrases.compat.configuration.release_manager.control_api.endpoint_label'}", + "endpoint_message": "@:{'phrases.compat.configuration.release_manager.control_api.endpoint_message'}", + "endpoint_aria": "@:{'phrases.compat.configuration.release_manager.control_api.endpoint_aria'}", + "use_tooltip": "@:{'phrases.compat.configuration.release_manager.control_api.use_tooltip'}", + "use": "@:{'phrases.compat.configuration.release_manager.control_api.use'}", + "reset_tooltip": "@:{'phrases.compat.configuration.release_manager.control_api.reset_tooltip'}", + "reset": "@:{'phrases.compat.configuration.release_manager.control_api.reset'}", + "known_endpoints": "@:{'phrases.compat.configuration.release_manager.control_api.known_endpoints'}" + }, + "tabs": { + "overview": { + "label": "@:{'phrases.compat.configuration.release_manager.tabs.overview.label'}", + "description": "@:{'phrases.compat.configuration.release_manager.tabs.overview.description'}" + }, + "channels": { + "label": "@:{'phrases.compat.configuration.release_manager.tabs.channels.label'}", + "description": "@:{'phrases.compat.configuration.release_manager.tabs.channels.description'}" + }, + "assignments": { + "label": "@:{'phrases.compat.configuration.release_manager.tabs.assignments.label'}", + "description": "@:{'phrases.compat.configuration.release_manager.tabs.assignments.description'}" + }, + "deployments": { + "label": "@:{'phrases.compat.configuration.release_manager.tabs.deployments.label'}", + "description": "@:{'phrases.compat.configuration.release_manager.tabs.deployments.description'}" + }, + "replay": { + "label": "@:{'phrases.compat.configuration.release_manager.tabs.replay.label'}", + "description": "@:{'phrases.compat.configuration.release_manager.tabs.replay.description'}" + }, + "integrations": { + "label": "@:{'phrases.compat.configuration.release_manager.tabs.integrations.label'}", + "description": "@:{'phrases.compat.configuration.release_manager.tabs.integrations.description'}" + }, + "settings": { + "label": "@:{'phrases.compat.configuration.release_manager.tabs.settings.label'}", + "description": "@:{'phrases.compat.configuration.release_manager.tabs.settings.description'}" + } + }, + "setup": { + "channels": "@:{'phrases.compat.configuration.release_manager.setup.channels'}", + "targets": "@:{'phrases.compat.configuration.release_manager.setup.targets'}", + "assignments": "@:{'phrases.compat.configuration.release_manager.setup.assignments'}", + "deployments": "@:{'phrases.compat.configuration.release_manager.setup.deployments'}", + "replay": "@:{'phrases.compat.configuration.release_manager.setup.replay'}" + }, + "stats": { + "channels": "@:{'phrases.compat.configuration.release_manager.stats.channels'}", + "targets": "@:{'phrases.compat.configuration.release_manager.stats.targets'}", + "deployments": "@:{'phrases.compat.configuration.release_manager.stats.deployments'}", + "timeline_events": "@:{'phrases.compat.configuration.release_manager.stats.timeline_events'}" + }, + "overview": { + "title": "@:{'phrases.compat.configuration.release_manager.overview.title'}", + "subtitle": "@:{'phrases.compat.configuration.release_manager.overview.subtitle'}", + "guided_setup": "@:{'phrases.compat.configuration.release_manager.overview.guided_setup'}", + "next_step": "@:{'phrases.compat.configuration.release_manager.overview.next_step'}", + "ready": "@:{'phrases.compat.configuration.release_manager.overview.ready'}", + "add_suggested_channel": "@:{'phrases.compat.configuration.release_manager.overview.add_suggested_channel'}", + "module_health_empty": "@:{'phrases.compat.configuration.release_manager.overview.module_health_empty'}" + }, + "settings": { + "title": "@:{'phrases.compat.configuration.release_manager.settings.title'}", + "subtitle": "@:{'phrases.compat.configuration.release_manager.settings.subtitle'}", + "github_token": "@:{'phrases.compat.configuration.release_manager.settings.github_token'}", + "github_api_url": "@:{'phrases.compat.configuration.release_manager.settings.github_api_url'}", + "webhook_secret": "@:{'phrases.compat.configuration.release_manager.settings.webhook_secret'}", + "github_webhook_secret": "@:{'phrases.compat.configuration.release_manager.settings.github_webhook_secret'}", + "configured": "@:{'phrases.compat.configuration.release_manager.settings.configured'}", + "not_configured": "@:{'phrases.compat.configuration.release_manager.settings.not_configured'}", + "loaded_from": "@:{'phrases.compat.configuration.release_manager.settings.loaded_from'}", + "set_below": "@:{'phrases.compat.configuration.release_manager.settings.set_below'}", + "private_repositories_prefix": "@:{'phrases.compat.configuration.release_manager.settings.private_repositories_prefix'}", + "private_repositories_or": "@:{'phrases.compat.configuration.release_manager.settings.private_repositories_or'}", + "github_token_message": "@:{'phrases.compat.configuration.release_manager.settings.github_token_message'}", + "github_token_placeholder": "@:{'phrases.compat.configuration.release_manager.settings.github_token_placeholder'}", + "github_api_url_message": "@:{'phrases.compat.configuration.release_manager.settings.github_api_url_message'}", + "webhook_secret_message": "@:{'phrases.compat.configuration.release_manager.settings.webhook_secret_message'}", + "webhook_secret_placeholder": "@:{'phrases.compat.configuration.release_manager.settings.webhook_secret_placeholder'}", + "save": "@:{'phrases.compat.configuration.release_manager.settings.save'}", + "back_to_integrations": "@:{'phrases.compat.configuration.release_manager.settings.back_to_integrations'}", + "guide": { + "steps": { + "github_token": "@:{'phrases.compat.configuration.release_manager.settings.guide.steps.github_token'}", + "github_api_url": "@:{'phrases.compat.configuration.release_manager.settings.guide.steps.github_api_url'}", + "github_webhook_secret": "@:{'phrases.compat.configuration.release_manager.settings.guide.steps.github_webhook_secret'}", + "review": "@:{'phrases.compat.configuration.release_manager.settings.guide.steps.review'}" + }, + "github_token_title": "@:{'phrases.compat.configuration.release_manager.settings.guide.github_token_title'}", + "github_token_description": "@:{'phrases.compat.configuration.release_manager.settings.guide.github_token_description'}", + "configure_this_in": "@:{'phrases.compat.configuration.release_manager.settings.guide.configure_this_in'}", + "server_environment_variable": "@:{'phrases.compat.configuration.release_manager.settings.guide.server_environment_variable'}", + "takes_precedence": "@:{'phrases.compat.configuration.release_manager.settings.guide.takes_precedence'}", + "recommended_access": "@:{'phrases.compat.configuration.release_manager.settings.guide.recommended_access'}", + "recommended_access_description": "@:{'phrases.compat.configuration.release_manager.settings.guide.recommended_access_description'}", + "github_api_url_title": "@:{'phrases.compat.configuration.release_manager.settings.guide.github_api_url_title'}", + "github_api_url_description": "@:{'phrases.compat.configuration.release_manager.settings.guide.github_api_url_description'}", + "github_api_url_invalid": "@:{'phrases.compat.configuration.release_manager.settings.guide.github_api_url_invalid'}", + "github_cloud": "@:{'phrases.compat.configuration.release_manager.settings.guide.github_cloud'}", + "enterprise_example": "@:{'phrases.compat.configuration.release_manager.settings.guide.enterprise_example'}", + "github_webhook_secret_title": "@:{'phrases.compat.configuration.release_manager.settings.guide.github_webhook_secret_title'}", + "github_webhook_secret_description": "@:{'phrases.compat.configuration.release_manager.settings.guide.github_webhook_secret_description'}", + "github_webhook_url": "@:{'phrases.compat.configuration.release_manager.settings.guide.github_webhook_url'}", + "store_shared_secret_in": "@:{'phrases.compat.configuration.release_manager.settings.guide.store_shared_secret_in'}", + "review_title": "@:{'phrases.compat.configuration.release_manager.settings.guide.review_title'}", + "review_description": "@:{'phrases.compat.configuration.release_manager.settings.guide.review_description'}", + "ready": "@:{'phrases.compat.configuration.release_manager.settings.guide.ready'}", + "needs_value": "@:{'phrases.compat.configuration.release_manager.settings.guide.needs_value'}" + } + }, + "channel_unavailable": { + "kicker": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.kicker'}", + "title": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.title'}", + "summary_prefix": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.summary_prefix'}", + "summary_suffix": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.summary_suffix'}", + "frontend_url": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.frontend_url'}", + "api_url": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.api_url'}", + "checking_again": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.checking_again'}", + "refresh_error": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.refresh_error'}", + "ignore": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.ignore'}", + "check_again": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.check_again'}", + "logout": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.logout'}", + "base_image": "@:{'phrases.compat.configuration.release_manager.channel_unavailable.base_image'}" + }, + "channel_switched": { + "kicker": "@:{'phrases.compat.configuration.release_manager.channel_switched.kicker'}", + "title": "@:{'phrases.compat.configuration.release_manager.channel_switched.title'}", + "summary_prefix": "@:{'phrases.compat.configuration.release_manager.channel_switched.summary_prefix'}", + "summary_suffix": "@:{'phrases.compat.configuration.release_manager.channel_switched.summary_suffix'}", + "frontend": "@:{'phrases.compat.configuration.release_manager.channel_switched.frontend'}", + "api": "@:{'phrases.compat.configuration.release_manager.channel_switched.api'}", + "frontend_version": "@:{'phrases.compat.configuration.release_manager.channel_switched.frontend_version'}", + "api_version": "@:{'phrases.compat.configuration.release_manager.channel_switched.api_version'}", + "assigned_channel": "@:{'phrases.compat.configuration.release_manager.channel_switched.assigned_channel'}", + "current_app_image": "@:{'phrases.compat.configuration.release_manager.channel_switched.current_app_image'}", + "current_api": "@:{'phrases.compat.configuration.release_manager.channel_switched.current_api'}", + "base_image": "@:{'phrases.compat.configuration.release_manager.channel_switched.base_image'}", + "continue": "@:{'phrases.compat.configuration.release_manager.channel_switched.continue'}" + }, + "common": { + "yes": "@:{'phrases.compat.configuration.release_manager.common.yes'}", + "no": "@:{'phrases.compat.configuration.release_manager.common.no'}", + "off": "@:{'phrases.compat.configuration.release_manager.common.off'}" + }, + "actions": { + "edit": "@:{'phrases.compat.configuration.release_manager.actions.edit'}", + "rollback": "@:{'phrases.compat.configuration.release_manager.actions.rollback'}", + "update": "@:{'phrases.compat.configuration.release_manager.actions.update'}", + "create": "@:{'phrases.compat.configuration.release_manager.actions.create'}", + "clear": "@:{'phrases.compat.configuration.release_manager.actions.clear'}", + "assign": "@:{'phrases.compat.configuration.release_manager.actions.assign'}", + "remove": "@:{'phrases.compat.configuration.release_manager.actions.remove'}", + "test_access": "@:{'phrases.compat.configuration.release_manager.actions.test_access'}", + "deploy": "@:{'phrases.compat.configuration.release_manager.actions.deploy'}", + "promote": "@:{'phrases.compat.configuration.release_manager.actions.promote'}", + "enable": "@:{'phrases.compat.configuration.release_manager.actions.enable'}", + "search": "@:{'phrases.compat.configuration.release_manager.actions.search'}", + "save_target": "@:{'phrases.compat.configuration.release_manager.actions.save_target'}", + "delete": "@:{'phrases.compat.configuration.release_manager.actions.delete'}", + "back": "@:{'phrases.compat.configuration.release_manager.actions.back'}", + "next": "@:{'phrases.compat.configuration.release_manager.actions.next'}" + }, + "tables": { + "channel": "@:{'phrases.compat.configuration.release_manager.tables.channel'}", + "rollout": "@:{'phrases.compat.configuration.release_manager.tables.rollout'}", + "frontend": "@:{'phrases.compat.configuration.release_manager.tables.frontend'}", + "api": "@:{'phrases.compat.configuration.release_manager.tables.api'}", + "replay": "@:{'phrases.compat.configuration.release_manager.tables.replay'}", + "actions": "@:{'phrases.compat.configuration.release_manager.tables.actions'}", + "module": "@:{'phrases.compat.configuration.release_manager.tables.module'}", + "status": "@:{'phrases.compat.configuration.release_manager.tables.status'}", + "checked": "@:{'phrases.compat.configuration.release_manager.tables.checked'}", + "subject": "@:{'phrases.compat.configuration.release_manager.tables.subject'}", + "reason": "@:{'phrases.compat.configuration.release_manager.tables.reason'}", + "expires": "@:{'phrases.compat.configuration.release_manager.tables.expires'}", + "deployment": "@:{'phrases.compat.configuration.release_manager.tables.deployment'}", + "source": "@:{'phrases.compat.configuration.release_manager.tables.source'}", + "started": "@:{'phrases.compat.configuration.release_manager.tables.started'}", + "target": "@:{'phrases.compat.configuration.release_manager.tables.target'}", + "coolify": "@:{'phrases.compat.configuration.release_manager.tables.coolify'}", + "auto": "@:{'phrases.compat.configuration.release_manager.tables.auto'}" + }, + "values": { + "app": { + "frontend": "@:{'phrases.compat.configuration.release_manager.values.app.frontend'}", + "api": "@:{'phrases.compat.configuration.release_manager.values.app.api'}" + }, + "capture_level": { + "metadata": "@:{'phrases.compat.configuration.release_manager.values.capture_level.metadata'}", + "full_redacted": "@:{'phrases.compat.configuration.release_manager.values.capture_level.full_redacted'}" + }, + "subject_type": { + "user": "@:{'phrases.compat.configuration.release_manager.values.subject_type.user'}", + "subuser": "@:{'phrases.compat.configuration.release_manager.values.subject_type.subuser'}", + "customer": "@:{'phrases.compat.configuration.release_manager.values.subject_type.customer'}", + "channel": "@:{'phrases.compat.configuration.release_manager.values.subject_type.channel'}" + }, + "severity": { + "error": "@:{'phrases.compat.configuration.release_manager.values.severity.error'}", + "warning": "@:{'phrases.compat.configuration.release_manager.values.severity.warning'}", + "info": "@:{'phrases.compat.configuration.release_manager.values.severity.info'}" + }, + "status": { + "ok": "@:{'phrases.compat.configuration.release_manager.values.status.ok'}", + "active": "@:{'phrases.compat.configuration.release_manager.values.status.active'}", + "deployed": "@:{'phrases.compat.configuration.release_manager.values.status.deployed'}", + "stable": "@:{'phrases.compat.configuration.release_manager.values.status.stable'}", + "enabled": "@:{'phrases.compat.configuration.release_manager.values.status.enabled'}", + "queued": "@:{'phrases.compat.configuration.release_manager.values.status.queued'}", + "deploying": "@:{'phrases.compat.configuration.release_manager.values.status.deploying'}", + "metadata": "@:{'phrases.compat.configuration.release_manager.values.status.metadata'}", + "not_configured": "@:{'phrases.compat.configuration.release_manager.values.status.not_configured'}", + "warning": "@:{'phrases.compat.configuration.release_manager.values.status.warning'}", + "failed": "@:{'phrases.compat.configuration.release_manager.values.status.failed'}", + "down": "@:{'phrases.compat.configuration.release_manager.values.status.down'}", + "error": "@:{'phrases.compat.configuration.release_manager.values.status.error'}", + "unknown": "@:{'phrases.compat.configuration.release_manager.values.status.unknown'}" + } + }, + "autocomplete": { + "suggested_value": "@:{'phrases.compat.configuration.release_manager.autocomplete.suggested_value'}", + "suggestion": "@:{'phrases.compat.configuration.release_manager.autocomplete.suggestion'}", + "use_typed_value": "@:{'phrases.compat.configuration.release_manager.autocomplete.use_typed_value'}", + "custom": "@:{'phrases.compat.configuration.release_manager.autocomplete.custom'}", + "api_url": "@:{'phrases.compat.configuration.release_manager.autocomplete.api_url'}", + "frontend_url": "@:{'phrases.compat.configuration.release_manager.autocomplete.frontend_url'}", + "known_release_url": "@:{'phrases.compat.configuration.release_manager.autocomplete.known_release_url'}", + "deploy_here_with_coolify": "@:{'phrases.compat.configuration.release_manager.autocomplete.deploy_here_with_coolify'}", + "prepare_coolify_target": "@:{'phrases.compat.configuration.release_manager.autocomplete.prepare_coolify_target'}", + "coolify_ssl": "@:{'phrases.compat.configuration.release_manager.autocomplete.coolify_ssl'}", + "github_repository": "@:{'phrases.compat.configuration.release_manager.autocomplete.github_repository'}", + "owner_repository": "@:{'phrases.compat.configuration.release_manager.autocomplete.owner_repository'}", + "git_branch": "@:{'phrases.compat.configuration.release_manager.autocomplete.git_branch'}", + "deployment_branch": "@:{'phrases.compat.configuration.release_manager.autocomplete.deployment_branch'}", + "github_commit": "@:{'phrases.compat.configuration.release_manager.autocomplete.github_commit'}", + "git_commit": "@:{'phrases.compat.configuration.release_manager.autocomplete.git_commit'}", + "use_specific_commit_sha": "@:{'phrases.compat.configuration.release_manager.autocomplete.use_specific_commit_sha'}", + "custom_commit": "@:{'phrases.compat.configuration.release_manager.autocomplete.custom_commit'}", + "health_url": "@:{'phrases.compat.configuration.release_manager.autocomplete.health_url'}", + "release_health_check": "@:{'phrases.compat.configuration.release_manager.autocomplete.release_health_check'}", + "coolify_service": "@:{'phrases.compat.configuration.release_manager.autocomplete.coolify_service'}", + "service_uuid": "@:{'phrases.compat.configuration.release_manager.autocomplete.service_uuid'}", + "known_coolify_service_uuid": "@:{'phrases.compat.configuration.release_manager.autocomplete.known_coolify_service_uuid'}", + "control_api": "@:{'phrases.compat.configuration.release_manager.autocomplete.control_api'}", + "release_manager_api_endpoint": "@:{'phrases.compat.configuration.release_manager.autocomplete.release_manager_api_endpoint'}", + "module": "@:{'phrases.compat.configuration.release_manager.autocomplete.module'}", + "timeline_module_key": "@:{'phrases.compat.configuration.release_manager.autocomplete.timeline_module_key'}" + }, + "errors": { + "github_repositories": "@:{'phrases.compat.configuration.release_manager.errors.github_repositories'}", + "github_branches": "@:{'phrases.compat.configuration.release_manager.errors.github_branches'}", + "repository_branch_required": "@:{'phrases.compat.configuration.release_manager.errors.repository_branch_required'}", + "github_access_failed": "@:{'phrases.compat.configuration.release_manager.errors.github_access_failed'}" + }, + "channels": { + "title": "@:{'phrases.compat.configuration.release_manager.channels.title'}", + "subtitle": "@:{'phrases.compat.configuration.release_manager.channels.subtitle'}", + "rollout_percent": "@:{'phrases.compat.configuration.release_manager.channels.rollout_percent'}", + "already_configured": "@:{'phrases.compat.configuration.release_manager.channels.already_configured'}", + "slug": "@:{'phrases.compat.configuration.release_manager.channels.slug'}", + "slug_message": "@:{'phrases.compat.configuration.release_manager.channels.slug_message'}", + "slug_placeholder": "@:{'phrases.compat.configuration.release_manager.channels.slug_placeholder'}", + "name": "@:{'phrases.compat.configuration.release_manager.channels.name'}", + "name_message": "@:{'phrases.compat.configuration.release_manager.channels.name_message'}", + "name_placeholder": "@:{'phrases.compat.configuration.release_manager.channels.name_placeholder'}", + "rollout": "@:{'phrases.compat.configuration.release_manager.channels.rollout'}", + "rollout_message": "@:{'phrases.compat.configuration.release_manager.channels.rollout_message'}", + "frontend_url": "@:{'phrases.compat.configuration.release_manager.channels.frontend_url'}", + "frontend_url_message": "@:{'phrases.compat.configuration.release_manager.channels.frontend_url_message'}", + "frontend_url_placeholder": "@:{'phrases.compat.configuration.release_manager.channels.frontend_url_placeholder'}", + "no_matching_release_url": "@:{'phrases.compat.configuration.release_manager.channels.no_matching_release_url'}", + "api_url": "@:{'phrases.compat.configuration.release_manager.channels.api_url'}", + "api_url_message": "@:{'phrases.compat.configuration.release_manager.channels.api_url_message'}", + "api_url_placeholder": "@:{'phrases.compat.configuration.release_manager.channels.api_url_placeholder'}", + "no_matching_api_url": "@:{'phrases.compat.configuration.release_manager.channels.no_matching_api_url'}", + "replay_capture": "@:{'phrases.compat.configuration.release_manager.channels.replay_capture'}", + "replay_capture_message": "@:{'phrases.compat.configuration.release_manager.channels.replay_capture_message'}", + "retention_days": "@:{'phrases.compat.configuration.release_manager.channels.retention_days'}", + "retention_days_message": "@:{'phrases.compat.configuration.release_manager.channels.retention_days_message'}", + "enabled": "@:{'phrases.compat.configuration.release_manager.channels.enabled'}", + "default_channel": "@:{'phrases.compat.configuration.release_manager.channels.default_channel'}", + "replay_enabled": "@:{'phrases.compat.configuration.release_manager.channels.replay_enabled'}", + "frontend_chip": "@:{'phrases.compat.configuration.release_manager.channels.frontend_chip'}", + "api_chip": "@:{'phrases.compat.configuration.release_manager.channels.api_chip'}" + }, + "assignments": { + "title": "@:{'phrases.compat.configuration.release_manager.assignments.title'}", + "subtitle": "@:{'phrases.compat.configuration.release_manager.assignments.subtitle'}", + "subject_type": "@:{'phrases.compat.configuration.release_manager.assignments.subject_type'}", + "subject_type_message": "@:{'phrases.compat.configuration.release_manager.assignments.subject_type_message'}", + "customer": "@:{'phrases.compat.configuration.release_manager.assignments.customer'}", + "customer_message": "@:{'phrases.compat.configuration.release_manager.assignments.customer_message'}", + "customer_placeholder": "@:{'phrases.compat.configuration.release_manager.assignments.customer_placeholder'}", + "subject_id": "@:{'phrases.compat.configuration.release_manager.assignments.subject_id'}", + "subject_id_message": "@:{'phrases.compat.configuration.release_manager.assignments.subject_id_message'}", + "subject_id_placeholder": "@:{'phrases.compat.configuration.release_manager.assignments.subject_id_placeholder'}", + "channel": "@:{'phrases.compat.configuration.release_manager.assignments.channel'}", + "channel_message": "@:{'phrases.compat.configuration.release_manager.assignments.channel_message'}", + "reason": "@:{'phrases.compat.configuration.release_manager.assignments.reason'}", + "reason_message": "@:{'phrases.compat.configuration.release_manager.assignments.reason_message'}", + "reason_placeholder": "@:{'phrases.compat.configuration.release_manager.assignments.reason_placeholder'}", + "expires": "@:{'phrases.compat.configuration.release_manager.assignments.expires'}", + "expires_message": "@:{'phrases.compat.configuration.release_manager.assignments.expires_message'}" + }, + "deployments": { + "title": "@:{'phrases.compat.configuration.release_manager.deployments.title'}", + "subtitle": "@:{'phrases.compat.configuration.release_manager.deployments.subtitle'}", + "manual_deployment_record": "@:{'phrases.compat.configuration.release_manager.deployments.manual_deployment_record'}", + "target": "@:{'phrases.compat.configuration.release_manager.deployments.target'}", + "target_message": "@:{'phrases.compat.configuration.release_manager.deployments.target_message'}", + "select_target_or_manual": "@:{'phrases.compat.configuration.release_manager.deployments.select_target_or_manual'}", + "channel": "@:{'phrases.compat.configuration.release_manager.deployments.channel'}", + "app": "@:{'phrases.compat.configuration.release_manager.deployments.app'}", + "repository": "@:{'phrases.compat.configuration.release_manager.deployments.repository'}", + "repository_message": "@:{'phrases.compat.configuration.release_manager.deployments.repository_message'}", + "repository_placeholder": "@:{'phrases.compat.configuration.release_manager.deployments.repository_placeholder'}", + "branch": "@:{'phrases.compat.configuration.release_manager.deployments.branch'}", + "branch_message": "@:{'phrases.compat.configuration.release_manager.deployments.branch_message'}", + "branch_placeholder": "@:{'phrases.compat.configuration.release_manager.deployments.branch_placeholder'}", + "commit_selection": "@:{'phrases.compat.configuration.release_manager.deployments.commit_selection'}", + "commit_selection_message": "@:{'phrases.compat.configuration.release_manager.deployments.commit_selection_message'}", + "latest_from_branch": "@:{'phrases.compat.configuration.release_manager.deployments.latest_from_branch'}", + "specific_commit": "@:{'phrases.compat.configuration.release_manager.deployments.specific_commit'}", + "specific_commit_message": "@:{'phrases.compat.configuration.release_manager.deployments.specific_commit_message'}", + "commit_sha_placeholder": "@:{'phrases.compat.configuration.release_manager.deployments.commit_sha_placeholder'}", + "version_label": "@:{'phrases.compat.configuration.release_manager.deployments.version_label'}", + "version_label_message": "@:{'phrases.compat.configuration.release_manager.deployments.version_label_message'}", + "version_label_placeholder": "@:{'phrases.compat.configuration.release_manager.deployments.version_label_placeholder'}", + "commit_prefix": "@:{'phrases.compat.configuration.release_manager.deployments.commit_prefix'}", + "test_access_tooltip": "@:{'phrases.compat.configuration.release_manager.deployments.test_access_tooltip'}" + }, + "replay": { + "title": "@:{'phrases.compat.configuration.release_manager.replay.title'}", + "subtitle": "@:{'phrases.compat.configuration.release_manager.replay.subtitle'}", + "capture_channel": "@:{'phrases.compat.configuration.release_manager.replay.capture_channel'}", + "target_type": "@:{'phrases.compat.configuration.release_manager.replay.target_type'}", + "target": "@:{'phrases.compat.configuration.release_manager.replay.target'}", + "target_message": "@:{'phrases.compat.configuration.release_manager.replay.target_message'}", + "target_placeholder": "@:{'phrases.compat.configuration.release_manager.replay.target_placeholder'}", + "channel_scope": "@:{'phrases.compat.configuration.release_manager.replay.channel_scope'}", + "channel_scope_message": "@:{'phrases.compat.configuration.release_manager.replay.channel_scope_message'}", + "no_channel_scope": "@:{'phrases.compat.configuration.release_manager.replay.no_channel_scope'}", + "capture_level": "@:{'phrases.compat.configuration.release_manager.replay.capture_level'}", + "expires": "@:{'phrases.compat.configuration.release_manager.replay.expires'}", + "expires_message": "@:{'phrases.compat.configuration.release_manager.replay.expires_message'}", + "trace_id": "@:{'phrases.compat.configuration.release_manager.replay.trace_id'}", + "trace_id_message": "@:{'phrases.compat.configuration.release_manager.replay.trace_id_message'}", + "trace_id_placeholder": "@:{'phrases.compat.configuration.release_manager.replay.trace_id_placeholder'}", + "channel": "@:{'phrases.compat.configuration.release_manager.replay.channel'}", + "channel_placeholder": "@:{'phrases.compat.configuration.release_manager.replay.channel_placeholder'}", + "principal_id": "@:{'phrases.compat.configuration.release_manager.replay.principal_id'}", + "principal_id_placeholder": "@:{'phrases.compat.configuration.release_manager.replay.principal_id_placeholder'}", + "module": "@:{'phrases.compat.configuration.release_manager.replay.module'}", + "module_placeholder": "@:{'phrases.compat.configuration.release_manager.replay.module_placeholder'}", + "severity": "@:{'phrases.compat.configuration.release_manager.replay.severity'}", + "any_severity": "@:{'phrases.compat.configuration.release_manager.replay.any_severity'}", + "no_timeline_events": "@:{'phrases.compat.configuration.release_manager.replay.no_timeline_events'}" + }, + "integrations": { + "title": "@:{'phrases.compat.configuration.release_manager.integrations.title'}", + "subtitle": "@:{'phrases.compat.configuration.release_manager.integrations.subtitle'}", + "choose_repository": "@:{'phrases.compat.configuration.release_manager.integrations.choose_repository'}", + "add_health_url": "@:{'phrases.compat.configuration.release_manager.integrations.add_health_url'}", + "github_token_not_configured": "@:{'phrases.compat.configuration.release_manager.integrations.github_token_not_configured'}", + "open_github_token_settings": "@:{'phrases.compat.configuration.release_manager.integrations.open_github_token_settings'}", + "channel": "@:{'phrases.compat.configuration.release_manager.integrations.channel'}", + "app": "@:{'phrases.compat.configuration.release_manager.integrations.app'}", + "repository": "@:{'phrases.compat.configuration.release_manager.integrations.repository'}", + "repository_message": "@:{'phrases.compat.configuration.release_manager.integrations.repository_message'}", + "repository_placeholder": "@:{'phrases.compat.configuration.release_manager.integrations.repository_placeholder'}", + "branch": "@:{'phrases.compat.configuration.release_manager.integrations.branch'}", + "branch_message": "@:{'phrases.compat.configuration.release_manager.integrations.branch_message'}", + "branch_placeholder": "@:{'phrases.compat.configuration.release_manager.integrations.branch_placeholder'}", + "latest_prefix": "@:{'phrases.compat.configuration.release_manager.integrations.latest_prefix'}", + "coolify_instance": "@:{'phrases.compat.configuration.release_manager.integrations.coolify_instance'}", + "coolify_instance_message": "@:{'phrases.compat.configuration.release_manager.integrations.coolify_instance_message'}", + "no_coolify_instance": "@:{'phrases.compat.configuration.release_manager.integrations.no_coolify_instance'}", + "coolify_instance_placeholder": "@:{'phrases.compat.configuration.release_manager.integrations.coolify_instance_placeholder'}", + "coolify_service_uuid": "@:{'phrases.compat.configuration.release_manager.integrations.coolify_service_uuid'}", + "coolify_service_uuid_message": "@:{'phrases.compat.configuration.release_manager.integrations.coolify_service_uuid_message'}", + "coolify_service_uuid_placeholder": "@:{'phrases.compat.configuration.release_manager.integrations.coolify_service_uuid_placeholder'}", + "health_url": "@:{'phrases.compat.configuration.release_manager.integrations.health_url'}", + "health_url_message": "@:{'phrases.compat.configuration.release_manager.integrations.health_url_message'}", + "health_url_placeholder": "@:{'phrases.compat.configuration.release_manager.integrations.health_url_placeholder'}", + "ssl_domain": "@:{'phrases.compat.configuration.release_manager.integrations.ssl_domain'}", + "ssl_domain_message": "@:{'phrases.compat.configuration.release_manager.integrations.ssl_domain_message'}", + "ssl_domain_placeholder": "@:{'phrases.compat.configuration.release_manager.integrations.ssl_domain_placeholder'}", + "https_domain_for_coolify": "@:{'phrases.compat.configuration.release_manager.integrations.https_domain_for_coolify'}", + "auto_deploy": "@:{'phrases.compat.configuration.release_manager.integrations.auto_deploy'}", + "auto_deploy_tooltip": "@:{'phrases.compat.configuration.release_manager.integrations.auto_deploy_tooltip'}", + "coolify_ssl": "@:{'phrases.compat.configuration.release_manager.integrations.coolify_ssl'}", + "coolify_ssl_tooltip": "@:{'phrases.compat.configuration.release_manager.integrations.coolify_ssl_tooltip'}", + "deploy_now": "@:{'phrases.compat.configuration.release_manager.integrations.deploy_now'}", + "deploy_now_tooltip": "@:{'phrases.compat.configuration.release_manager.integrations.deploy_now_tooltip'}", + "create_missing_service": "@:{'phrases.compat.configuration.release_manager.integrations.create_missing_service'}", + "create_missing_service_tooltip": "@:{'phrases.compat.configuration.release_manager.integrations.create_missing_service_tooltip'}", + "test_access_tooltip": "@:{'phrases.compat.configuration.release_manager.integrations.test_access_tooltip'}" + } } } } diff --git a/src/i18n/source/no/phrases/compat/configuration/index.json b/src/i18n/source/no/phrases/compat/configuration/index.json index 1f97d26b..3eb40b40 100644 --- a/src/i18n/source/no/phrases/compat/configuration/index.json +++ b/src/i18n/source/no/phrases/compat/configuration/index.json @@ -298,6 +298,412 @@ "subtitle": "@.capitalize:{'terms.glossary.konfigurasjon'} @:{'terms.glossary.av'} @:{'terms.glossary.xlvask'}-@:{'terms.glossary.integrasjonen'}", "title": "@:{'terms.glossary.xlvask'}-@:{'terms.glossary.konfigurasjon'}", "username_desc": "@:{'terms.glossary.brukernavnet'} @:{'terms.glossary.brukes'} @:{'terms.glossary.til'} @:{'terms.glossary.a'} @:{'terms.glossary.autentisere'} @:{'terms.glossary.api'}-@:{'terms.glossary.tilkoblingen'}." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradvise API- og Front-End-utgivelser", + "control_api": { + "title": "Kontroll-API", + "tooltip": "Release Manager-handlinger sendes til denne API-en. Bruk produksjons-API-en med mindre du tester en staging-backend.", + "example": "Eksempel: https://api.truckwash.io:4433", + "endpoint_label": "API-endepunkt", + "endpoint_message": "Endre dette bare n?r Release Manager-endepunkter er tilgjengelige p? m?l-API-en.", + "endpoint_aria": "Release Manager kontroll-API URL", + "use_tooltip": "Last release-data fra denne API-en", + "use": "Bruk", + "reset_tooltip": "G? tilbake til standard kontroll-API", + "reset": "Tilbakestill", + "known_endpoints": "Kjente kontroll-API-endepunkter" + }, + "tabs": { + "overview": { + "label": "Oversikt", + "description": "Kanalhelse, oppsettsfremdrift og siste release-status." + }, + "channels": { + "label": "Kanaler", + "description": "Opprett stabile, canary- og m?lrettede kanaler med rollout-grenser." + }, + "assignments": { + "label": "Tildelinger", + "description": "Knytt brukere, underbrukere eller kunder til en bestemt release-kanal." + }, + "deployments": { + "label": "Utrullinger", + "description": "Start utrullinger og promoter vellykkede bygg." + }, + "replay": { + "label": "Replay", + "description": "Aktiver m?lrettet innsamling og s?k i release-tidslinjehendelser." + }, + "integrations": { + "label": "Integrasjoner", + "description": "Koble GitHub-repositories, branches og Coolify-tjenester." + }, + "settings": { + "label": "Innstillinger", + "description": "Konfigurer Release Managers GitHub-tilgang og webhook-innstillinger." + } + }, + "setup": { + "channels": "Kanaler", + "targets": "GitHub- og Coolify-m?l", + "assignments": "Pilottildelinger", + "deployments": "F?rste utrulling", + "replay": "Replay-innsamling" + }, + "stats": { + "channels": "Kanaler", + "targets": "M?l", + "deployments": "Utrullinger", + "timeline_events": "Tidslinjehendelser" + }, + "overview": { + "title": "Oversikt", + "subtitle": "Aktuell kanalhelse, release-aktivitet og modulstatus.", + "guided_setup": "Veiledet oppsett", + "next_step": "Neste: {step}", + "ready": "Release Manager er klar for daglig drift.", + "add_suggested_channel": "Legg til foreslått kanal", + "module_health_empty": "Modul-health snapshots vises når probes er registrert." + }, + "settings": { + "title": "Release Manager-innstillinger", + "subtitle": "Konfigurer GitHub-tokenet som brukes for private repositories og branch-oppslag.", + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "webhook_secret": "Webhook-hemmelighet", + "github_webhook_secret": "GitHub webhook-hemmelighet", + "configured": "Konfigurert", + "not_configured": "Ikke konfigurert", + "loaded_from": "Lastet fra {variable}", + "set_below": "Angi {variable} nedenfor", + "private_repositories_prefix": "Private repositories leses med serverens milj?variabel", + "private_repositories_or": "eller modulens konfigurasjonsvariabel", + "github_token_message": "Eksempel: github_pat_... med tilgang til de private repositories Release Manager ruller ut.", + "github_token_placeholder": "La st? tomt for ? beholde eksisterende token", + "github_api_url_message": "Konfigurert i ReleaseManager.github_api_url. Bruk https://api.github.com med mindre GitHub Enterprise brukes.", + "webhook_secret_message": "Valgfritt; la st? tomt for ? beholde eksisterende hemmelighet.", + "webhook_secret_placeholder": "Webhook HMAC-hemmelighet", + "save": "Lagre innstillinger", + "back_to_integrations": "Tilbake til integrasjoner", + "guide": { + "steps": { + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Gennemgang" + }, + "github_token_title": "Legg til GitHub-token", + "github_token_description": "Release Manager bruger denne token til at vise private repositories, branches og commits, før et deployment-mål gemmes eller testes.", + "configure_this_in": "Konfigurer dette i", + "server_environment_variable": "Serverens miljøvariabel", + "takes_precedence": "har forrang når den er satt.", + "recommended_access": "Anbefalt tilgang", + "recommended_access_description": "Fine-grained GitHub-token med Contents: read-adgang til hvert release-repository.", + "github_api_url_title": "Legg til GitHub API-URL", + "github_api_url_description": "Brug GitHub Cloud som standard, eller peg på REST API-base-URLen for en GitHub Enterprise Server-installation.", + "github_api_url_invalid": "Skriv inn en full HTTP- eller HTTPS-URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-eksempel", + "github_webhook_secret_title": "Legg til GitHub webhook secret", + "github_webhook_secret_description": "Brug samme secret i GitHub repository-webhooks, så Release Manager kan verificere deployment-events, før de håndteres.", + "github_webhook_url": "GitHub webhook-URL:", + "store_shared_secret_in": "Lagre den delte secreten i", + "review_title": "Gå gjennom GitHub-oppsett", + "review_description": "Gem værdierne, og brug derefter Integrationer til at vælge et privat repository, branch og specifik commit eller seneste commit før adgang testes.", + "ready": "Klar", + "needs_value": "Mangler værdi" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-kanalen er ikke klar", + "summary_prefix": "Kontoen din er tildelt", + "summary_suffix": ", men kanalen mangler konfigurasjonen som trengs for ? laste release-imaget.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Sjekker igjen om {seconds}s", + "refresh_error": "Release-status kunne ikke oppdateres. Neste automatiske sjekk pr?ver igjen.", + "ignore": "Ignorer de neste 5 minuttene", + "check_again": "Sjekk igjen", + "logout": "Logg ut", + "base_image": "Basis-image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du er n? p? {channel}", + "summary_prefix": "Kontoen din er tildelt release-kanalen", + "summary_suffix": "Denne enheten husker at du har sett denne meldingen.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-versjon", + "api_version": "API-versjon", + "assigned_channel": "Tildelt kanal", + "current_app_image": "N?v?rende app-image", + "current_api": "N?v?rende API", + "base_image": "Basis-image", + "continue": "Fortsett" + }, + "common": { + "yes": "ja", + "no": "nei", + "off": "av" + }, + "actions": { + "edit": "Rediger", + "rollback": "Rull tilbake", + "update": "Opdater", + "create": "Opprett", + "clear": "Tøm", + "assign": "Tildel", + "remove": "Fjern", + "test_access": "Test tilgang", + "deploy": "Deploy", + "promote": "Promoter", + "enable": "Aktiver", + "search": "Søk", + "save_target": "Lagre mål", + "delete": "Slett", + "back": "Tilbake", + "next": "Neste" + }, + "tables": { + "channel": "Kanal", + "rollout": "Udrulning", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Handlinger", + "module": "Modul", + "status": "Status", + "checked": "Kontrollert", + "subject": "Emne", + "reason": "Årsag", + "expires": "Utløper", + "deployment": "Deployment", + "source": "Kilde", + "started": "Startet", + "target": "Mål", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "fullt redigert" + }, + "subject_type": { + "user": "bruker", + "subuser": "medarbeider", + "customer": "kunde", + "channel": "kanal" + }, + "severity": { + "error": "feil", + "warning": "advarsel", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployet", + "stable": "stabil", + "enabled": "aktivert", + "queued": "i kø", + "deploying": "deploying", + "metadata": "metadata", + "not_configured": "ikke konfigurert", + "warning": "advarsel", + "failed": "feilet", + "down": "nede", + "error": "feil", + "unknown": "ukjent" + } + }, + "autocomplete": { + "suggested_value": "Foreslået værdi", + "suggestion": "Forslag", + "use_typed_value": "Brug indtastet værdi", + "custom": "Tilpasset", + "api_url": "API-URL", + "frontend_url": "Frontend-URL", + "known_release_url": "Kendt release-URL", + "deploy_here_with_coolify": "Deploy {app} her med Coolify", + "prepare_coolify_target": "Forbered et Coolify-mål med HTTPS/SSL aktiveret", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-repository", + "owner_repository": "ejer/repository", + "git_branch": "Git-branch", + "deployment_branch": "Deployment-branch", + "github_commit": "GitHub-commit", + "git_commit": "Git-commit", + "use_specific_commit_sha": "Brug specifik commit-SHA", + "custom_commit": "Tilpasset commit", + "health_url": "Health-URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify-service", + "service_uuid": "Service-UUID", + "known_coolify_service_uuid": "Kendt Coolify service-UUID", + "control_api": "Kontrol-API", + "release_manager_api_endpoint": "Release Manager API-endpoint", + "module": "Modul", + "timeline_module_key": "Timeline-modulnøgle" + }, + "errors": { + "github_repositories": "Kunne ikke indlæse GitHub-repositories.", + "github_branches": "Kunne ikke indlæse GitHub-branches.", + "repository_branch_required": "Repository og branch er påkrævet før GitHub-adgang kan testes.", + "github_access_failed": "Test af GitHub repository-adgang fejlede." + }, + "channels": { + "title": "Kanaler", + "subtitle": "Opprett og juster gradvise release-kanaler.", + "rollout_percent": "{percent}% udrulning", + "already_configured": "Allerede konfigurert", + "slug": "Slug", + "slug_message": "Eksempel: canary", + "slug_placeholder": "slug", + "name": "Navn", + "name_message": "Vises til operatører når de gjennomgår en kanal.", + "name_placeholder": "Navn", + "rollout": "Udrulning", + "rollout_message": "0-100 prosent av ikke-tildelt trafikk.", + "frontend_url": "Frontend-URL", + "frontend_url_message": "Eksempel: https://canary.example.test", + "frontend_url_placeholder": "Frontend-URL", + "no_matching_release_url": "Ingen matchende release-URL.", + "api_url": "API-URL", + "api_url_message": "Eksempel: https://api-canary.example.test", + "api_url_placeholder": "API-URL", + "no_matching_api_url": "Ingen matchende API-URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata er sikrere til brede kanaler.", + "retention_days": "Oppbevaringsdager", + "retention_days_message": "1-365 dage.", + "enabled": "Aktivert", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktivert", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Tildelinger", + "subtitle": "Fest brukere, medarbeidere eller kunder til release-kanaler.", + "subject_type": "Emnetype", + "subject_type_message": "Vælg identitetstypen, der skal fastgøres.", + "customer": "Kunde", + "customer_message": "Søk på kundenummer eller navn, og velg deretter nøyaktig kunde.", + "customer_placeholder": "Søk kunde", + "subject_id": "Emne-ID", + "subject_id_message": "Eksempel: bruker-id 42", + "subject_id_placeholder": "Emne-id", + "channel": "Kanal", + "channel_message": "Festede emner hopper over prosentutrullingen.", + "reason": "Årsag", + "reason_message": "Eksempel: canary-validering for kundesupport.", + "reason_placeholder": "Årsag", + "expires": "Utløper", + "expires_message": "Lad feltet være tomt for ingen automatisk udløb." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Start, promoter og inspiser release-deployments.", + "manual_deployment_record": "Manuel deployment-post", + "target": "Mål", + "target_message": "Vælg et gemt mål, eller behold manuelle felter redigerbare.", + "select_target_or_manual": "Velg mål eller manuelt", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/front-end-vue", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-valg", + "commit_selection_message": "Seneste slås op som branchens head med den konfigurerede GitHub-token.", + "latest_from_branch": "Siste fra branch", + "specific_commit": "Spesifikk commit", + "specific_commit_message": "Eksempel: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versjonsetikett", + "version_label_message": "Eksempel: api-2026.05.19", + "version_label_placeholder": "versionslabel", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Bekræft token-adgang til det valgte repository, branch og commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Aktiver målrettet capture og gennemgå fejltimelines trin for trin.", + "capture_channel": "Capture {channel}", + "target_type": "Måltype", + "target": "Mål", + "target_message": "Eksempel: bruker-id 42 eller kanal-slug canary.", + "target_placeholder": "Mål-id eller kanal-slug", + "channel_scope": "Kanalavgrensning", + "channel_scope_message": "Valgfrit; begrænser replay capture til en kanal.", + "no_channel_scope": "Ingen kanalavgrensning", + "capture_level": "Capture-niveau", + "expires": "Utløper", + "expires_message": "Lad feltet være tomt for manuel deaktivering.", + "trace_id": "Trace-ID", + "trace_id_message": "Eksempel: trace-canary-1", + "trace_id_placeholder": "Trace-id", + "channel": "Kanal", + "channel_placeholder": "Kanal", + "principal_id": "Principal-ID", + "principal_id_placeholder": "Principal-id", + "module": "Modul", + "module_placeholder": "Modul", + "severity": "Alvorlighet", + "any_severity": "Alle alvorligheder", + "no_timeline_events": "Ingen timeline-events matcher de aktuelle filtre." + }, + "integrations": { + "title": "GitHub og Coolify", + "subtitle": "Knyt GitHub-repositories og branches til kanalspecifikke Coolify-services.", + "choose_repository": "Velg repository", + "add_health_url": "legg til health-URL", + "github_token_not_configured": "GitHub-token er ikke konfigurert; private repositories kan ikke vises.", + "open_github_token_settings": "Åpne GitHub token-innstillinger", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/backend-php", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Seneste: {commit}", + "coolify_instance": "Coolify-instans", + "coolify_instance_message": "Lad feltet være tomt for manuelle deployment-poster.", + "no_coolify_instance": "Ingen Coolify-instans", + "coolify_instance_placeholder": "Coolify-instans-id", + "coolify_service_uuid": "Coolify service-UUID", + "coolify_service_uuid_message": "Vælg en eksisterende service eller indsæt en UUID.", + "coolify_service_uuid_placeholder": "Coolify service-UUID", + "health_url": "Health-URL", + "health_url_message": "Eksempel: https://api-canary.example.test/ping", + "health_url_placeholder": "Health-URL", + "ssl_domain": "SSL-domene", + "ssl_domain_message": "Eksempel: canary.example.test", + "ssl_domain_placeholder": "SSL-domene", + "https_domain_for_coolify": "HTTPS-domæne til Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Opret automatisk deployments, når dette mål ændres.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Bed Coolify om at oprette HTTPS for det konfigurerede domæne.", + "deploy_now": "Deploy nå", + "deploy_now_tooltip": "Start en deployment straks efter målet gemmes.", + "create_missing_service": "Opprett manglende service", + "create_missing_service_tooltip": "Tillad Release Manager at oprette en manglende Coolify-service.", + "test_access_tooltip": "Bekræft, at den konfigurerede GitHub-token kan læse dette repository og branch." + } } } } diff --git a/src/i18n/source/sv/phrases/compat/configuration/index.json b/src/i18n/source/sv/phrases/compat/configuration/index.json index d516128e..4dc47b20 100644 --- a/src/i18n/source/sv/phrases/compat/configuration/index.json +++ b/src/i18n/source/sv/phrases/compat/configuration/index.json @@ -298,6 +298,412 @@ "subtitle": "@.capitalize:{'terms.glossary.konfiguration'} @:{'terms.glossary.af'} @:{'terms.glossary.xlvask'} @:{'terms.glossary.integrationen'}", "title": "@:{'terms.glossary.xlvask'} @:{'terms.glossary.konfiguration'}", "username_desc": "Användarnamnet @:{'terms.glossary.anvands'} @:{'terms.glossary.for'} @:{'terms.glossary.att'} @:{'terms.glossary.autentisera'} @:{'terms.glossary.api'}-@:{'terms.glossary.anslutningen'}." + }, + "release_manager": { + "title": "Release Manager", + "subtitle": "Gradvisa API- och Front-End-versioner", + "control_api": { + "title": "Kontroll-API", + "tooltip": "Release Manager-?tg?rder skickas till detta API. Anv?nd produktions-API:t om du inte testar en staging-backend.", + "example": "Exempel: https://api.truckwash.io:4433", + "endpoint_label": "API-endpoint", + "endpoint_message": "?ndra detta endast n?r Release Manager-endpoints finns p? m?l-API:t.", + "endpoint_aria": "Release Manager kontroll-API URL", + "use_tooltip": "L?s in release-data fr?n detta API", + "use": "Anv?nd", + "reset_tooltip": "G? tillbaka till standard kontroll-API", + "reset": "?terst?ll", + "known_endpoints": "K?nda kontroll-API-endpoints" + }, + "tabs": { + "overview": { + "label": "?versikt", + "description": "Kanalh?lsa, installationsstatus och senaste release-l?ge." + }, + "channels": { + "label": "Kanaler", + "description": "Skapa stabila, canary- och riktade kanaler med rollout-gr?nser." + }, + "assignments": { + "label": "Tilldelningar", + "description": "Koppla anv?ndare, underanv?ndare eller kunder till en specifik release-kanal." + }, + "deployments": { + "label": "Utrullningar", + "description": "Starta utrullningar och promovera lyckade byggen." + }, + "replay": { + "label": "Replay", + "description": "Aktivera riktad insamling och s?k i release-tidslinjeh?ndelser." + }, + "integrations": { + "label": "Integrationer", + "description": "Anslut GitHub-repositories, branches och Coolify-tj?nster." + }, + "settings": { + "label": "Inst?llningar", + "description": "Konfigurera Release Managers GitHub-?tkomst och webhook-inst?llningar." + } + }, + "setup": { + "channels": "Kanaler", + "targets": "GitHub- och Coolify-m?l", + "assignments": "Pilottilldelningar", + "deployments": "F?rsta utrullningen", + "replay": "Replay-insamling" + }, + "stats": { + "channels": "Kanaler", + "targets": "M?l", + "deployments": "Utrullningar", + "timeline_events": "Tidslinjeh?ndelser" + }, + "overview": { + "title": "?versikt", + "subtitle": "Aktuell kanalh?lsa, release-aktivitet och modulstatus.", + "guided_setup": "Guidad installation", + "next_step": "N?sta: {step}", + "ready": "Release Manager ?r klar f?r daglig drift.", + "add_suggested_channel": "Lägg till föreslagen kanal", + "module_health_empty": "Modulhälsosnapshots visas när probes har registrerats." + }, + "settings": { + "title": "Release Manager-inst?llningar", + "subtitle": "Konfigurera GitHub-token som anv?nds f?r privata repositories och branch-uppslag.", + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "webhook_secret": "Webhook-hemlighet", + "github_webhook_secret": "GitHub webhook-hemlighet", + "configured": "Konfigurerad", + "not_configured": "Inte konfigurerad", + "loaded_from": "Inl?st fr?n {variable}", + "set_below": "Ange {variable} nedan", + "private_repositories_prefix": "Privata repositories l?ses med serverns milj?variabel", + "private_repositories_or": "eller modulens konfigurationsvariabel", + "github_token_message": "Exempel: github_pat_... med ?tkomst till de privata repositories som Release Manager distribuerar.", + "github_token_placeholder": "L?mna tomt f?r att beh?lla befintlig token", + "github_api_url_message": "Konfigurerad i ReleaseManager.github_api_url. Anv?nd https://api.github.com om du inte anv?nder GitHub Enterprise.", + "webhook_secret_message": "Valfritt; l?mna tomt f?r att beh?lla befintlig hemlighet.", + "webhook_secret_placeholder": "Webhook HMAC-hemlighet", + "save": "Spara inst?llningar", + "back_to_integrations": "Tillbaka till integrationer", + "guide": { + "steps": { + "github_token": "GitHub-token", + "github_api_url": "GitHub API-URL", + "github_webhook_secret": "GitHub webhook secret", + "review": "Gennemgang" + }, + "github_token_title": "Lägg till GitHub-token", + "github_token_description": "Release Manager använder denna token för att lista privata repositories, branches och commits innan ett deployment-mål sparas eller testas.", + "configure_this_in": "Konfigurera detta i", + "server_environment_variable": "Serverns miljövariabel", + "takes_precedence": "har företräde när den är satt.", + "recommended_access": "Rekommenderad åtkomst", + "recommended_access_description": "Fine-grained GitHub-token med Contents: read-åtkomst till varje release-repository.", + "github_api_url_title": "Lägg till GitHub API-URL", + "github_api_url_description": "Brug GitHub Cloud som standard, eller peg på REST API-base-URLen for en GitHub Enterprise Server-installation.", + "github_api_url_invalid": "Ange en fullständig HTTP- eller HTTPS-URL.", + "github_cloud": "GitHub Cloud", + "enterprise_example": "Enterprise-exempel", + "github_webhook_secret_title": "Lägg till GitHub webhook secret", + "github_webhook_secret_description": "Brug samme secret i GitHub repository-webhooks, så Release Manager kan verificere deployment-events, før de håndteres.", + "github_webhook_url": "GitHub webhook-URL:", + "store_shared_secret_in": "Spara den delade secret i", + "review_title": "Granska GitHub-konfiguration", + "review_description": "Gem værdierne, og brug derefter Integrationer til at vælge et privat repository, branch og specifik commit eller seneste commit før adgang testes.", + "ready": "Klar", + "needs_value": "Saknar värde" + } + }, + "channel_unavailable": { + "kicker": "Release Manager", + "title": "Release-kanalen ?r inte klar", + "summary_prefix": "Ditt konto ?r tilldelat", + "summary_suffix": ", men kanalen saknar konfigurationen som beh?vs f?r att l?sa in dess release-image.", + "frontend_url": "Frontend-URL", + "api_url": "API-URL", + "checking_again": "Kontrollerar igen om {seconds}s", + "refresh_error": "Release-status kunde inte uppdateras. N?sta automatiska kontroll f?rs?ker igen.", + "ignore": "Ignorera de kommande 5 minuterna", + "check_again": "Kontrollera igen", + "logout": "Logga ut", + "base_image": "Bas-image" + }, + "channel_switched": { + "kicker": "Release Manager", + "title": "Du ?r nu p? {channel}", + "summary_prefix": "Ditt konto har tilldelats release-kanalen", + "summary_suffix": "Den h?r enheten kommer ih?g att du har sett detta meddelande.", + "frontend": "Frontend", + "api": "API", + "frontend_version": "Frontend-version", + "api_version": "API-version", + "assigned_channel": "Tilldelad kanal", + "current_app_image": "Nuvarande app-image", + "current_api": "Nuvarande API", + "base_image": "Bas-image", + "continue": "Forts?tt" + }, + "common": { + "yes": "ja", + "no": "nej", + "off": "av" + }, + "actions": { + "edit": "Redigera", + "rollback": "Rulla tillbaka", + "update": "Uppdatera", + "create": "Skapa", + "clear": "Rensa", + "assign": "Tilldela", + "remove": "Ta bort", + "test_access": "Testa åtkomst", + "deploy": "Deploy", + "promote": "Promota", + "enable": "Aktivera", + "search": "Sök", + "save_target": "Spara mål", + "delete": "Radera", + "back": "Tillbaka", + "next": "Nästa" + }, + "tables": { + "channel": "Kanal", + "rollout": "Udrulning", + "frontend": "Frontend", + "api": "API", + "replay": "Replay", + "actions": "Åtgärder", + "module": "Modul", + "status": "Status", + "checked": "Kontrollerad", + "subject": "Emne", + "reason": "Orsak", + "expires": "Upphör", + "deployment": "Deployment", + "source": "Källa", + "started": "Startet", + "target": "Mål", + "coolify": "Coolify", + "auto": "Auto" + }, + "values": { + "app": { + "frontend": "frontend", + "api": "api" + }, + "capture_level": { + "metadata": "metadata", + "full_redacted": "helt redigerad" + }, + "subject_type": { + "user": "användare", + "subuser": "medarbetare", + "customer": "kund", + "channel": "kanal" + }, + "severity": { + "error": "fel", + "warning": "varning", + "info": "info" + }, + "status": { + "ok": "ok", + "active": "aktiv", + "deployed": "deployad", + "stable": "stabil", + "enabled": "aktiverad", + "queued": "i kö", + "deploying": "deployar", + "metadata": "metadata", + "not_configured": "inte konfigurerad", + "warning": "varning", + "failed": "misslyckad", + "down": "nere", + "error": "fel", + "unknown": "okänd" + } + }, + "autocomplete": { + "suggested_value": "Foreslået værdi", + "suggestion": "Forslag", + "use_typed_value": "Brug indtastet værdi", + "custom": "Tilpasset", + "api_url": "API-URL", + "frontend_url": "Frontend-URL", + "known_release_url": "Kendt release-URL", + "deploy_here_with_coolify": "Deploy {app} her med Coolify", + "prepare_coolify_target": "Forbered et Coolify-mål med HTTPS/SSL aktiveret", + "coolify_ssl": "Coolify SSL", + "github_repository": "GitHub-repository", + "owner_repository": "ejer/repository", + "git_branch": "Git-branch", + "deployment_branch": "Deployment-branch", + "github_commit": "GitHub-commit", + "git_commit": "Git-commit", + "use_specific_commit_sha": "Brug specifik commit-SHA", + "custom_commit": "Tilpasset commit", + "health_url": "Health-URL", + "release_health_check": "Release health check", + "coolify_service": "Coolify-service", + "service_uuid": "Service-UUID", + "known_coolify_service_uuid": "Kendt Coolify service-UUID", + "control_api": "Kontrol-API", + "release_manager_api_endpoint": "Release Manager API-endpoint", + "module": "Modul", + "timeline_module_key": "Timeline-modulnøgle" + }, + "errors": { + "github_repositories": "Kunne ikke indlæse GitHub-repositories.", + "github_branches": "Kunne ikke indlæse GitHub-branches.", + "repository_branch_required": "Repository og branch er påkrævet før GitHub-adgang kan testes.", + "github_access_failed": "Test af GitHub repository-adgang fejlede." + }, + "channels": { + "title": "Kanaler", + "subtitle": "Skapa och justera gradvisa release-kanaler.", + "rollout_percent": "{percent}% utrullning", + "already_configured": "Redan konfigurerad", + "slug": "Slug", + "slug_message": "Eksempel: canary", + "slug_placeholder": "slug", + "name": "Namn", + "name_message": "Visas för operatörer när de granskar en kanal.", + "name_placeholder": "Namn", + "rollout": "Utrullning", + "rollout_message": "0-100 procent av otilldelad trafik.", + "frontend_url": "Frontend-URL", + "frontend_url_message": "Eksempel: https://canary.example.test", + "frontend_url_placeholder": "Frontend-URL", + "no_matching_release_url": "Ingen matchande release-URL.", + "api_url": "API-URL", + "api_url_message": "Eksempel: https://api-canary.example.test", + "api_url_placeholder": "API-URL", + "no_matching_api_url": "Ingen matchande API-URL.", + "replay_capture": "Replay capture", + "replay_capture_message": "Metadata är säkrare för breda kanaler.", + "retention_days": "Lagringsdagar", + "retention_days_message": "1-365 dagar.", + "enabled": "Aktiverad", + "default_channel": "Standardkanal", + "replay_enabled": "Replay aktiverad", + "frontend_chip": "Frontend: {url}", + "api_chip": "API: {url}" + }, + "assignments": { + "title": "Tilldelningar", + "subtitle": "Fäst användare, medarbetare eller kunder till release-kanaler.", + "subject_type": "Ämnestyp", + "subject_type_message": "Välj identitetstypen som ska fästas.", + "customer": "Kunde", + "customer_message": "Sök på kundnummer eller namn och välj sedan exakt kund.", + "customer_placeholder": "Sök kund", + "subject_id": "Ämnes-ID", + "subject_id_message": "Exempel: användar-id 42", + "subject_id_placeholder": "Ämnes-id", + "channel": "Kanal", + "channel_message": "Fästa ämnen hoppar över procentutrullningen.", + "reason": "Orsak", + "reason_message": "Exempel: canary-validering för kundsupport.", + "reason_placeholder": "Orsak", + "expires": "Upphör", + "expires_message": "Lämna tomt för ingen automatisk upphörning." + }, + "deployments": { + "title": "Deployments", + "subtitle": "Starta, promota och inspektera release-deployments.", + "manual_deployment_record": "Manuel deployment-post", + "target": "Mål", + "target_message": "Välj ett sparat mål eller behåll manuella fält redigerbara.", + "select_target_or_manual": "Vælg mål eller manuel", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/front-end-vue", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: main", + "branch_placeholder": "branch", + "commit_selection": "Commit-val", + "commit_selection_message": "Senaste slås upp som branchens head med konfigurerad GitHub-token.", + "latest_from_branch": "Senaste från branch", + "specific_commit": "Specifik commit", + "specific_commit_message": "Eksempel: feedface1234", + "commit_sha_placeholder": "commit sha", + "version_label": "Versionsetikett", + "version_label_message": "Eksempel: api-2026.05.19", + "version_label_placeholder": "versionsetikett", + "commit_prefix": "Commit: {commit}", + "test_access_tooltip": "Bekræft token-adgang til det valgte repository, branch og commit." + }, + "replay": { + "title": "Replay", + "subtitle": "Aktivera riktad capture och gå igenom feltimelines steg för steg.", + "capture_channel": "Capture {channel}", + "target_type": "Måltype", + "target": "Mål", + "target_message": "Exempel: användar-id 42 eller kanal-slug canary.", + "target_placeholder": "Mål-id eller kanal-slug", + "channel_scope": "Kanalavgränsning", + "channel_scope_message": "Valgfrit; begrænser replay capture til en kanal.", + "no_channel_scope": "Ingen kanalavgränsning", + "capture_level": "Capture-niveau", + "expires": "Upphör", + "expires_message": "Lad feltet være tomt for manuel deaktivering.", + "trace_id": "Trace-ID", + "trace_id_message": "Eksempel: trace-canary-1", + "trace_id_placeholder": "Trace-id", + "channel": "Kanal", + "channel_placeholder": "Kanal", + "principal_id": "Principal-ID", + "principal_id_placeholder": "Principal-id", + "module": "Modul", + "module_placeholder": "Modul", + "severity": "Allvarlighetsgrad", + "any_severity": "Alla allvarlighetsgrader", + "no_timeline_events": "Ingen timeline-events matcher de aktuelle filtre." + }, + "integrations": { + "title": "GitHub och Coolify", + "subtitle": "Koppla GitHub-repositories och branches till kanalspecifika Coolify-tjänster.", + "choose_repository": "Välj repository", + "add_health_url": "lägg till health-URL", + "github_token_not_configured": "GitHub-token er ikke konfigureret; private repositories kan ikke vises.", + "open_github_token_settings": "Öppna GitHub token-inställningar", + "channel": "Kanal", + "app": "App", + "repository": "Repository", + "repository_message": "Eksempel: truckwash/backend-php", + "repository_placeholder": "ejer/repo", + "branch": "Branch", + "branch_message": "Eksempel: release/canary", + "branch_placeholder": "branch", + "latest_prefix": "Seneste: {commit}", + "coolify_instance": "Coolify-instans", + "coolify_instance_message": "Lad feltet være tomt for manuelle deployment-poster.", + "no_coolify_instance": "Ingen Coolify-instans", + "coolify_instance_placeholder": "Coolify-instans-id", + "coolify_service_uuid": "Coolify service-UUID", + "coolify_service_uuid_message": "Vælg en eksisterende service eller indsæt en UUID.", + "coolify_service_uuid_placeholder": "Coolify service-UUID", + "health_url": "Health-URL", + "health_url_message": "Eksempel: https://api-canary.example.test/ping", + "health_url_placeholder": "Health-URL", + "ssl_domain": "SSL-domän", + "ssl_domain_message": "Eksempel: canary.example.test", + "ssl_domain_placeholder": "SSL-domän", + "https_domain_for_coolify": "HTTPS-domän för Coolify", + "auto_deploy": "Auto deploy", + "auto_deploy_tooltip": "Opret automatisk deployments, når dette mål ændres.", + "coolify_ssl": "Coolify SSL", + "coolify_ssl_tooltip": "Bed Coolify om at oprette HTTPS for det konfigurerede domæne.", + "deploy_now": "Deploy nu", + "deploy_now_tooltip": "Start en deployment straks efter målet gemmes.", + "create_missing_service": "Skapa saknad tjänst", + "create_missing_service_tooltip": "Tillad Release Manager at oprette en manglende Coolify-service.", + "test_access_tooltip": "Bekræft, at den konfigurerede GitHub-token kan læse dette repository og branch." + } } } } diff --git a/src/services/releaseChannelAvailability.js b/src/services/releaseChannelAvailability.js new file mode 100644 index 00000000..a93ab8cf --- /dev/null +++ b/src/services/releaseChannelAvailability.js @@ -0,0 +1,350 @@ +import { computed, reactive, readonly } from "vue"; +import { releaseRuntimeState } from "@/services/releaseTimeline.js"; + +export const RELEASE_CHANNEL_IGNORE_STORAGE_KEY = "release_channel_unavailable_ignore_until"; +export const RELEASE_CHANNEL_SWITCH_NOTICE_STORAGE_KEY = "release_channel_switch_notice_seen"; +export const RELEASE_CHANNEL_IGNORE_MS = 5 * 60 * 1000; +export const RELEASE_CHANNEL_CHECK_INTERVAL_MS = 10 * 1000; + +const readIgnoreMap = () => { + if (typeof window === "undefined") { + return {}; + } + + try { + const parsed = JSON.parse(window.localStorage.getItem(RELEASE_CHANNEL_IGNORE_STORAGE_KEY) || "{}"); + return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {}; + } catch { + return {}; + } +}; + +const writeIgnoreMap = (map) => { + if (typeof window === "undefined") { + return; + } + + try { + window.localStorage.setItem(RELEASE_CHANNEL_IGNORE_STORAGE_KEY, JSON.stringify(map)); + } catch { + // Ignore storage failures; the guard will simply remain active. + } +}; + +const readSwitchNoticeMap = () => { + if (typeof window === "undefined") { + return {}; + } + + try { + const parsed = JSON.parse(window.localStorage.getItem(RELEASE_CHANNEL_SWITCH_NOTICE_STORAGE_KEY) || "{}"); + return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {}; + } catch { + return {}; + } +}; + +const writeSwitchNoticeMap = (map) => { + if (typeof window === "undefined") { + return; + } + + try { + window.localStorage.setItem(RELEASE_CHANNEL_SWITCH_NOTICE_STORAGE_KEY, JSON.stringify(map)); + } catch { + // Ignore storage failures; the notice can be shown again on the next load. + } +}; + +const state = reactive({ + now: Date.now(), + ignoredUntilByChannel: readIgnoreMap(), + switchNoticeSeenByKey: readSwitchNoticeMap(), + switchNoticePrincipalKey: "", +}); + +let clockTimer = null; + +export const releaseChannelAvailabilityClock = readonly(state); + +export const setReleaseChannelSwitchNoticePrincipal = (principalKey) => { + state.switchNoticePrincipalKey = String(principalKey || "").trim(); +}; + +export const releaseChannelKey = (channel) => { + const slug = String(channel?.slug || "").trim(); + if (slug) { + return slug; + } + const id = String(channel?.id || "").trim(); + return id ? `id:${id}` : ""; +}; + +export const normalizeReleaseUrl = (value) => { + const raw = String(value || "").trim(); + if (!raw) { + return ""; + } + + try { + const url = new URL(/^https?:\/\//i.test(raw) ? raw : `https://${raw}`); + return `${url.protocol}//${url.host}`; + } catch { + return raw.replace(/\/+$/, ""); + } +}; + +const runtimeUrl = (runtime, key) => { + const camelKey = key === "frontend_base_url" ? "frontendBaseUrl" : "apiBaseUrl"; + return normalizeReleaseUrl(runtime?.[camelKey] || runtime?.[key] || runtime?.channel?.[key]); +}; + +const hasOwn = (value, key) => Boolean(value && Object.prototype.hasOwnProperty.call(value, key)); + +const hasExplicitRuntimeTargets = (runtime) => { + return ( + hasOwn(runtime, "frontend_base_url") || + hasOwn(runtime, "frontendBaseUrl") || + hasOwn(runtime, "api_base_url") || + hasOwn(runtime, "apiBaseUrl") || + hasOwn(runtime?.channel, "frontend_base_url") || + hasOwn(runtime?.channel, "api_base_url") + ); +}; + +const runtimeAvailability = (runtime, frontendBaseUrl, apiBaseUrl) => { + if (runtime?.availability && typeof runtime.availability === "object") { + const missing = Array.isArray(runtime.availability.missing) ? runtime.availability.missing : []; + const configured = + typeof runtime.availability.configured === "boolean" + ? runtime.availability.configured + : missing.length === 0 && runtime.availability.status !== "unconfigured"; + return { + configured, + missing, + status: runtime.availability.status || (configured ? "ready" : "unconfigured"), + }; + } + + if (!hasExplicitRuntimeTargets(runtime)) { + return { + configured: true, + missing: [], + status: "ready", + }; + } + + const missing = []; + if (!frontendBaseUrl) { + missing.push("frontend_base_url"); + } + if (!apiBaseUrl) { + missing.push("api_base_url"); + } + + return { + configured: missing.length === 0, + missing, + status: missing.length === 0 ? "ready" : "unconfigured", + }; +}; + +export const getReleaseChannelUnavailableStatus = (runtime = {}, now = Date.now(), ignoredUntil = 0) => { + const channel = runtime?.channel || null; + const channelSlug = String(channel?.slug || "").trim(); + const channelName = String(channel?.name || channelSlug || "Release channel").trim(); + const isDefaultChannel = + channel?.default_channel === true || channel?.default_channel === 1 || channelSlug === "stable"; + const frontendBaseUrl = runtimeUrl(runtime, "frontend_base_url"); + const apiBaseUrl = runtimeUrl(runtime, "api_base_url"); + const explicitAvailability = + runtime?.availability?.explicit === false + ? false + : Boolean(runtime?.availability && typeof runtime.availability === "object") || hasExplicitRuntimeTargets(runtime); + const availability = runtimeAvailability(runtime, frontendBaseUrl, apiBaseUrl); + const ignored = Number(ignoredUntil || 0) > now; + const unavailable = Boolean(channelSlug) && !isDefaultChannel && availability.configured === false; + + return { + channel, + channelSlug, + channelName, + defaultChannel: isDefaultChannel, + explicitAvailability, + description: channel?.description || "", + frontendBaseUrl, + apiBaseUrl, + missing: availability.missing, + configured: availability.configured, + unavailable, + ignored, + ignoredUntil: Number(ignoredUntil || 0), + shouldBlock: unavailable && !ignored, + status: availability.status, + versions: runtime?.versions || {}, + }; +}; + +export const releaseChannelUnavailableStatus = computed(() => { + const key = releaseChannelKey(releaseRuntimeState.channel); + const ignoredUntil = key ? Number(state.ignoredUntilByChannel[key] || 0) : 0; + return getReleaseChannelUnavailableStatus(releaseRuntimeState, state.now, ignoredUntil); +}); + +export const releaseChannelSwitchNoticeKey = (channel, principalKey = state.switchNoticePrincipalKey) => { + const channelKey = releaseChannelKey(channel); + const principal = String(principalKey || "").trim(); + return channelKey && principal ? `${principal}:${channelKey}` : ""; +}; + +export const getReleaseChannelSwitchedStatus = ( + runtime = {}, + principalKey = state.switchNoticePrincipalKey, + seenMap = state.switchNoticeSeenByKey +) => { + const unavailableStatus = getReleaseChannelUnavailableStatus(runtime, state.now, 0); + const noticeKey = releaseChannelSwitchNoticeKey(unavailableStatus.channel, principalKey); + const seen = noticeKey ? Boolean(seenMap[noticeKey]) : false; + const shouldShow = + Boolean(noticeKey) && + Boolean(unavailableStatus.channelSlug) && + unavailableStatus.defaultChannel === false && + unavailableStatus.explicitAvailability === true && + unavailableStatus.configured === true && + unavailableStatus.unavailable === false && + unavailableStatus.channelSlug !== "stable" && + seen === false; + + return { + ...unavailableStatus, + noticeKey, + principalKey: String(principalKey || "").trim(), + seen, + shouldShow, + }; +}; + +export const releaseChannelSwitchedStatus = computed(() => { + return getReleaseChannelSwitchedStatus( + releaseRuntimeState, + state.switchNoticePrincipalKey, + state.switchNoticeSeenByKey + ); +}); + +export const acknowledgeReleaseChannelSwitch = ( + channel = releaseChannelSwitchedStatus.value.channel, + principalKey = state.switchNoticePrincipalKey +) => { + const noticeKey = releaseChannelSwitchNoticeKey(channel, principalKey); + if (!noticeKey) { + return ""; + } + + const nextMap = { + ...state.switchNoticeSeenByKey, + [noticeKey]: new Date().toISOString(), + }; + state.switchNoticeSeenByKey = nextMap; + writeSwitchNoticeMap(nextMap); + return noticeKey; +}; + +export const ignoreUnavailableReleaseChannel = ( + channel = releaseChannelUnavailableStatus.value.channel, + durationMs = RELEASE_CHANNEL_IGNORE_MS +) => { + const key = releaseChannelKey(channel); + if (!key) { + return 0; + } + + const ignoredUntil = Date.now() + durationMs; + const nextMap = { + ...state.ignoredUntilByChannel, + [key]: ignoredUntil, + }; + state.ignoredUntilByChannel = nextMap; + state.now = Date.now(); + writeIgnoreMap(nextMap); + return ignoredUntil; +}; + +export const clearUnavailableReleaseChannelIgnore = (channel = releaseChannelUnavailableStatus.value.channel) => { + const key = releaseChannelKey(channel); + if (!key) { + return; + } + + const nextMap = { ...state.ignoredUntilByChannel }; + delete nextMap[key]; + state.ignoredUntilByChannel = nextMap; + state.now = Date.now(); + writeIgnoreMap(nextMap); +}; + +export const startReleaseChannelAvailabilityClock = () => { + if (typeof window === "undefined" || clockTimer !== null) { + return () => {}; + } + + clockTimer = window.setInterval(() => { + state.now = Date.now(); + }, 1000); + + return stopReleaseChannelAvailabilityClock; +}; + +export const stopReleaseChannelAvailabilityClock = () => { + if (typeof window === "undefined" || clockTimer === null) { + return; + } + + window.clearInterval(clockTimer); + clockTimer = null; +}; + +export const buildReleaseFrontendRedirectUrl = (runtime = releaseRuntimeState, currentLocation = window.location) => { + const frontendBaseUrl = runtimeUrl(runtime, "frontend_base_url"); + if (!frontendBaseUrl || !currentLocation) { + return null; + } + + const target = new URL(frontendBaseUrl); + const currentOrigin = currentLocation.origin || `${currentLocation.protocol}//${currentLocation.host}`; + if (target.origin === currentOrigin) { + return null; + } + + target.pathname = currentLocation.pathname || "/"; + target.search = currentLocation.search || ""; + target.hash = currentLocation.hash || ""; + return target.toString(); +}; + +export const redirectToConfiguredReleaseFrontend = (runtime = releaseRuntimeState) => { + const status = getReleaseChannelUnavailableStatus(runtime, Date.now(), 0); + if (!status.configured) { + return false; + } + + const redirectUrl = buildReleaseFrontendRedirectUrl(runtime); + if (!redirectUrl) { + return false; + } + + window.location.assign(redirectUrl); + return true; +}; + +export const __resetReleaseChannelAvailabilityForTests = () => { + state.now = Date.now(); + state.ignoredUntilByChannel = {}; + state.switchNoticeSeenByKey = {}; + state.switchNoticePrincipalKey = ""; + stopReleaseChannelAvailabilityClock(); + if (typeof window !== "undefined") { + window.localStorage.removeItem(RELEASE_CHANNEL_IGNORE_STORAGE_KEY); + window.localStorage.removeItem(RELEASE_CHANNEL_SWITCH_NOTICE_STORAGE_KEY); + } +}; diff --git a/src/services/releaseTimeline.js b/src/services/releaseTimeline.js index b9886842..d54f7706 100644 --- a/src/services/releaseTimeline.js +++ b/src/services/releaseTimeline.js @@ -43,6 +43,14 @@ const releaseRuntimeStateMutable = reactive({ frontend: null, api: null, }, + frontendBaseUrl: null, + apiBaseUrl: null, + availability: { + configured: true, + missing: [], + status: "ready", + explicit: false, + }, capturePolicy: { enabled: false, capture_level: "metadata", @@ -59,6 +67,19 @@ let customTransport = null; export const releaseRuntimeState = readonly(releaseRuntimeStateMutable); +const hasOwn = (value, key) => Boolean(value && Object.prototype.hasOwnProperty.call(value, key)); + +const hasExplicitRuntimeTargets = (runtime) => { + return ( + hasOwn(runtime, "frontend_base_url") || + hasOwn(runtime, "frontendBaseUrl") || + hasOwn(runtime, "api_base_url") || + hasOwn(runtime, "apiBaseUrl") || + hasOwn(runtime?.channel, "frontend_base_url") || + hasOwn(runtime?.channel, "api_base_url") + ); +}; + export const configureReleaseRuntime = (runtime = {}) => { if (!runtime || typeof runtime !== "object") { return releaseRuntimeStateMutable; @@ -78,6 +99,36 @@ export const configureReleaseRuntime = (runtime = {}) => { frontend: runtime?.versions?.frontend || null, api: runtime?.versions?.api || null, }; + const frontendBaseUrl = + runtime.frontend_base_url || runtime.frontendBaseUrl || runtime?.channel?.frontend_base_url || null; + const apiBaseUrl = runtime.api_base_url || runtime.apiBaseUrl || runtime?.channel?.api_base_url || null; + const missingRuntimeTargets = []; + if (!frontendBaseUrl) { + missingRuntimeTargets.push("frontend_base_url"); + } + if (!apiBaseUrl) { + missingRuntimeTargets.push("api_base_url"); + } + releaseRuntimeStateMutable.frontendBaseUrl = frontendBaseUrl; + releaseRuntimeStateMutable.apiBaseUrl = apiBaseUrl; + releaseRuntimeStateMutable.availability = runtime.availability + ? { + ...runtime.availability, + explicit: true, + } + : hasExplicitRuntimeTargets(runtime) + ? { + configured: missingRuntimeTargets.length === 0, + missing: missingRuntimeTargets, + status: missingRuntimeTargets.length === 0 ? "ready" : "unconfigured", + explicit: true, + } + : { + configured: true, + missing: [], + status: "ready", + explicit: false, + }; releaseRuntimeStateMutable.capturePolicy = { enabled: Boolean(runtime?.capture_policy?.enabled), capture_level: runtime?.capture_policy?.capture_level || "metadata", @@ -164,10 +215,11 @@ export const recordReleaseTimelineEvent = (type, payload = {}, options = {}) => return true; }; -export const getRecentFrontendFailureEvents = () => recentFrontendFailureEvents.map((event) => ({ - ...event, - payload: redactReleasePayload(event.payload), -})); +export const getRecentFrontendFailureEvents = () => + recentFrontendFailureEvents.map((event) => ({ + ...event, + payload: redactReleasePayload(event.payload), + })); const scheduleReleaseTimelineFlush = () => { if (flushTimer !== null || typeof window === "undefined") { @@ -329,6 +381,14 @@ export const __resetReleaseTimelineForTests = () => { releaseRuntimeStateMutable.traceId = "test-trace"; releaseRuntimeStateMutable.channel = null; releaseRuntimeStateMutable.versions = { frontend: null, api: null }; + releaseRuntimeStateMutable.frontendBaseUrl = null; + releaseRuntimeStateMutable.apiBaseUrl = null; + releaseRuntimeStateMutable.availability = { + configured: true, + missing: [], + status: "ready", + explicit: false, + }; releaseRuntimeStateMutable.capturePolicy = { enabled: false, capture_level: "metadata", diff --git a/src/services/superuserCoolify.js b/src/services/superuserCoolify.js index 6fad1055..36ffa6a8 100644 --- a/src/services/superuserCoolify.js +++ b/src/services/superuserCoolify.js @@ -3,6 +3,21 @@ import { authenticatedRequest } from "@/components/session/authenticatedRequest. export const getCoolifySummary = () => authenticatedRequest("/superuser/coolify", "GET", {}); +export const getCoolifyLoadBalancer = () => + authenticatedRequest("/superuser/coolify/load-balancer", "GET", {}); + +export const reconcileCoolifyLoadBalancer = (payload) => + authenticatedRequest("/superuser/coolify/load-balancer/reconcile", "POST", payload); + +export const listCoolifyGateways = () => + authenticatedRequest("/superuser/coolify/gateways", "GET", {}); + +export const saveCoolifyGateway = (payload) => + authenticatedRequest("/superuser/coolify/gateways", "POST", payload); + +export const testCoolifyGateway = (id) => + authenticatedRequest(`/superuser/coolify/gateways/${id}/test`, "POST", {}); + export const createCoolifyInstance = (payload) => authenticatedRequest("/superuser/coolify/instances", "POST", payload); diff --git a/src/services/superuserReleases.js b/src/services/superuserReleases.js index 82e1bc67..c8dabee4 100644 --- a/src/services/superuserReleases.js +++ b/src/services/superuserReleases.js @@ -1,49 +1,213 @@ -import { authenticatedRequest } from "@/components/session/authenticatedRequest.vue"; +import axios from "axios"; +import { API_URL, RELEASE_MANAGER_CONTROL_API_FALLBACK_URLS, RELEASE_MANAGER_CONTROL_API_URL } from "@/config.js"; +import { enqueueRequest } from "@/services/requestQueue.js"; -export const getReleaseSummary = () => - authenticatedRequest("/superuser/releases", "GET", {}); +export const RELEASE_MANAGER_CONTROL_API_STORAGE_KEY = "release_manager_control_api_url"; +const RELEASE_MANAGER_LAST_WORKING_CONTROL_API_STORAGE_KEY = "release_manager_last_working_control_api_url"; -export const listReleaseChannels = () => - authenticatedRequest("/superuser/releases/channels", "GET", {}); +const normalizeApiUrl = (value) => { + const url = String(value || "") + .trim() + .replace(/\/+$/, ""); + if (!/^https?:\/\//i.test(url)) { + return ""; + } + return url; +}; -export const createReleaseChannel = (payload) => - authenticatedRequest("/superuser/releases/channels", "POST", payload); +const browserStorage = (name) => { + if (typeof window === "undefined") { + return null; + } + try { + return window[name] || null; + } catch { + return null; + } +}; + +const getSelectedCustomerNumber = () => { + const stored = browserStorage("localStorage")?.getItem("selected_customer_number"); + return stored ? parseInt(stored, 10) : null; +}; + +const uniqueUrls = (urls) => { + const seen = new Set(); + return urls + .map((url) => normalizeApiUrl(url)) + .filter((url) => { + if (!url || seen.has(url)) { + return false; + } + seen.add(url); + return true; + }); +}; + +const releaseManagerLocalStorage = () => browserStorage("localStorage"); +const releaseManagerSessionStorage = () => browserStorage("sessionStorage"); + +export const getReleaseManagerControlApiUrl = () => + uniqueUrls([ + releaseManagerSessionStorage()?.getItem(RELEASE_MANAGER_LAST_WORKING_CONTROL_API_STORAGE_KEY), + releaseManagerLocalStorage()?.getItem(RELEASE_MANAGER_CONTROL_API_STORAGE_KEY), + RELEASE_MANAGER_CONTROL_API_URL, + API_URL, + ])[0] || API_URL; + +export const releaseManagerControlApiCandidates = () => + uniqueUrls([ + releaseManagerSessionStorage()?.getItem(RELEASE_MANAGER_LAST_WORKING_CONTROL_API_STORAGE_KEY), + releaseManagerLocalStorage()?.getItem(RELEASE_MANAGER_CONTROL_API_STORAGE_KEY), + RELEASE_MANAGER_CONTROL_API_URL, + ...RELEASE_MANAGER_CONTROL_API_FALLBACK_URLS, + API_URL, + ]); + +export const setReleaseManagerControlApiUrl = (url) => { + const normalized = normalizeApiUrl(url); + if (!normalized) { + return ""; + } + releaseManagerLocalStorage()?.setItem(RELEASE_MANAGER_CONTROL_API_STORAGE_KEY, normalized); + releaseManagerSessionStorage()?.setItem(RELEASE_MANAGER_LAST_WORKING_CONTROL_API_STORAGE_KEY, normalized); + return normalized; +}; + +export const clearReleaseManagerControlApiUrl = () => { + releaseManagerLocalStorage()?.removeItem(RELEASE_MANAGER_CONTROL_API_STORAGE_KEY); + releaseManagerSessionStorage()?.removeItem(RELEASE_MANAGER_LAST_WORKING_CONTROL_API_STORAGE_KEY); +}; + +const rememberWorkingControlApiUrl = (url) => { + const normalized = normalizeApiUrl(url); + if (normalized) { + releaseManagerSessionStorage()?.setItem(RELEASE_MANAGER_LAST_WORKING_CONTROL_API_STORAGE_KEY, normalized); + } +}; + +const shouldTryNextControlApi = (error, method) => { + const status = Number(error?.response?.status || 0); + return ( + status === 0 || + (method === "GET" && status === 404) || + status === 405 || + status === 501 || + error?.code === "ERR_NETWORK" + ); +}; + +const buildHeaders = () => { + const headers = {}; + const token = releaseManagerLocalStorage()?.getItem("token"); + if (token) { + headers.Authorization = `Bearer ${token}`; + } + + const isSubuser = releaseManagerLocalStorage()?.getItem("is_subuser") === "true"; + const selectedCustomerNumber = getSelectedCustomerNumber(); + if (isSubuser && selectedCustomerNumber) { + headers["X-Customer-Number"] = selectedCustomerNumber; + } + + return headers; +}; + +const requestReleaseManager = (url, method, data = {}) => { + const candidates = releaseManagerControlApiCandidates(); + const headers = buildHeaders(); + + return enqueueRequest( + async () => { + let lastError = null; + for (const baseUrl of candidates) { + try { + const response = await axios({ + method, + url: `${baseUrl}${url}`, + ...(method === "GET" ? { params: data } : { data }), + __skipRequestQueue: true, + headers, + }); + rememberWorkingControlApiUrl(baseUrl); + return response; + } catch (error) { + lastError = error; + if (!shouldTryNextControlApi(error, method)) { + throw error; + } + } + } + throw lastError; + }, + { + method, + url: `${candidates[0] || API_URL}${url}`, + requestData: { + params: method === "GET" ? data : null, + data: method === "GET" ? null : data, + headers, + }, + shouldRetry: () => false, + } + ); +}; + +export const getReleaseSummary = () => requestReleaseManager("/superuser/releases", "GET", {}); + +export const getReleaseConfig = () => requestReleaseManager("/superuser/releases/config", "GET", {}); + +export const updateReleaseConfig = (payload) => requestReleaseManager("/superuser/releases/config", "POST", payload); + +export const listReleaseChannels = () => requestReleaseManager("/superuser/releases/channels", "GET", {}); + +export const createReleaseChannel = (payload) => requestReleaseManager("/superuser/releases/channels", "POST", payload); export const updateReleaseChannel = (id, payload) => - authenticatedRequest(`/superuser/releases/channels/${id}`, "PATCH", payload); + requestReleaseManager(`/superuser/releases/channels/${id}`, "PATCH", payload); export const rollbackReleaseChannel = (id) => - authenticatedRequest(`/superuser/releases/channels/${id}/rollback`, "POST", {}); + requestReleaseManager(`/superuser/releases/channels/${id}/rollback`, "POST", {}); -export const listReleaseAssignments = () => - authenticatedRequest("/superuser/releases/assignments", "GET", {}); +export const listReleaseAssignments = () => requestReleaseManager("/superuser/releases/assignments", "GET", {}); export const createReleaseAssignment = (payload) => - authenticatedRequest("/superuser/releases/assignments", "POST", payload); + requestReleaseManager("/superuser/releases/assignments", "POST", payload); export const deleteReleaseAssignment = (id) => - authenticatedRequest(`/superuser/releases/assignments/${id}`, "DELETE", {}); + requestReleaseManager(`/superuser/releases/assignments/${id}`, "DELETE", {}); -export const listReleaseDeploymentTargets = () => - authenticatedRequest("/superuser/releases/targets", "GET", {}); +export const listReleaseDeploymentTargets = () => requestReleaseManager("/superuser/releases/targets", "GET", {}); export const saveReleaseDeploymentTarget = (payload) => - authenticatedRequest("/superuser/releases/targets", "POST", payload); + requestReleaseManager("/superuser/releases/targets", "POST", payload); export const deleteReleaseDeploymentTarget = (id) => - authenticatedRequest(`/superuser/releases/targets/${id}`, "DELETE", {}); + requestReleaseManager(`/superuser/releases/targets/${id}`, "DELETE", {}); + +export const listReleaseGithubRepositories = (params = {}) => + requestReleaseManager("/superuser/releases/github/repositories", "GET", params); + +export const listReleaseGithubBranches = (repository) => + requestReleaseManager("/superuser/releases/github/branches", "GET", { repository }); + +export const listReleaseGithubCommits = ({ repository, branch, query = "", commit_sha = "" } = {}) => + requestReleaseManager("/superuser/releases/github/commits", "GET", { repository, branch, query, commit_sha }); + +export const testReleaseGithubAccess = (payload) => + requestReleaseManager("/superuser/releases/github/test", "POST", payload); export const listReleaseDeployments = (limit = 50) => - authenticatedRequest("/superuser/releases/deployments", "GET", { limit }); + requestReleaseManager("/superuser/releases/deployments", "GET", { limit }); export const startReleaseDeployment = (payload) => - authenticatedRequest("/superuser/releases/deployments", "POST", payload); + requestReleaseManager("/superuser/releases/deployments", "POST", payload); export const promoteReleaseDeployment = (id) => - authenticatedRequest(`/superuser/releases/deployments/${id}/promote`, "POST", {}); + requestReleaseManager(`/superuser/releases/deployments/${id}/promote`, "POST", {}); export const setReleaseReplayTarget = (payload) => - authenticatedRequest("/superuser/releases/replay-targets", "POST", payload); + requestReleaseManager("/superuser/releases/replay-targets", "POST", payload); export const searchReleaseTimeline = (filters = {}) => - authenticatedRequest("/superuser/releases/timeline", "GET", filters); + requestReleaseManager("/superuser/releases/timeline", "GET", filters); diff --git a/src/views/dashboards/superUserDashboard/configuration/ConfigurationCoolify.vue b/src/views/dashboards/superUserDashboard/configuration/ConfigurationCoolify.vue index fb0075d9..8e2229d6 100644 --- a/src/views/dashboards/superUserDashboard/configuration/ConfigurationCoolify.vue +++ b/src/views/dashboards/superUserDashboard/configuration/ConfigurationCoolify.vue @@ -15,9 +15,11 @@ import { failoverCoolifyTarget, getCoolifyConfig, getCoolifySummary, + reconcileCoolifyLoadBalancer, reconcileCoolifyTarget, restartCoolifyTarget, setCoolifyConfig, + testCoolifyGateway, testCoolifyInstance, } from "@/services/superuserCoolify.js"; @@ -32,9 +34,21 @@ const instanceForm = reactive({ api_token: "", }); +const loadBalancerForm = reactive({ + lb_automation_enabled: false, + lb_automation_mode: "report_only", + hetzner_load_balancer_id: "", + hetzner_cloud_api_token: "", + public_gateway_host: "api-v2.truckwash.io", +}); + const canManage = computed(() => SessionUser.canAccessSuperUser() || SessionUser.hasPermission("superuser_coolify_manage")); const instances = computed(() => Array.isArray(summary.value?.instances) ? summary.value.instances : []); const targets = computed(() => Array.isArray(summary.value?.targets) ? summary.value.targets : []); +const loadBalancer = computed(() => summary.value?.load_balancer || {}); +const loadBalancerConfig = computed(() => loadBalancer.value?.config || {}); +const loadBalancerGateways = computed(() => Array.isArray(loadBalancer.value?.gateways) ? loadBalancer.value.gateways : []); +const loadBalancerDriftActions = computed(() => Array.isArray(loadBalancer.value?.drift?.actions) ? loadBalancer.value.drift.actions : []); function configValue(variable) { const entry = config.value.find((row) => row.variable === variable); @@ -51,16 +65,57 @@ async function load() { const rows = configResponse?.data?.data ?? []; config.value = Array.isArray(rows) ? rows : Object.values(rows); summary.value = summaryResponse?.data?.data ?? { instances: [], targets: [], availability: {} }; + hydrateLoadBalancerForm(); } catch (error) { errors.value.push(error); } } +function hydrateLoadBalancerForm() { + const automationEnabled = configValue("lb_automation_enabled"); + loadBalancerForm.lb_automation_enabled = automationEnabled === true || automationEnabled === "true"; + loadBalancerForm.lb_automation_mode = configValue("lb_automation_mode") || "report_only"; + loadBalancerForm.hetzner_load_balancer_id = String(configValue("hetzner_load_balancer_id") || ""); + loadBalancerForm.public_gateway_host = String(configValue("public_gateway_host") || "api-v2.truckwash.io"); + loadBalancerForm.hetzner_cloud_api_token = ""; +} + async function saveEnabled(value) { await setCoolifyConfig({ variable: "enabled", value }); await load(); } +async function saveLoadBalancerSettings() { + await run("lb:save", async () => { + const payload = { + lb_automation_enabled: Boolean(loadBalancerForm.lb_automation_enabled), + lb_automation_mode: loadBalancerForm.lb_automation_mode, + hetzner_load_balancer_id: String(loadBalancerForm.hetzner_load_balancer_id || "").trim(), + public_gateway_host: String(loadBalancerForm.public_gateway_host || "").trim() || "api-v2.truckwash.io", + }; + const token = String(loadBalancerForm.hetzner_cloud_api_token || "").trim(); + if (token !== "") { + payload.hetzner_cloud_api_token = token; + } + await setCoolifyConfig(payload); + await load(); + }); +} + +async function runLoadBalancerReconcile(dryRun) { + await run(dryRun ? "lb:dry-run" : "lb:enforce", async () => { + await reconcileCoolifyLoadBalancer({ dry_run: dryRun, enforce: !dryRun }); + await load(); + }); +} + +async function runGatewayTest(gateway) { + await run(`gateway:${gateway.id}:test`, async () => { + await testCoolifyGateway(gateway.id); + await load(); + }); +} + async function submitInstance() { await run("instance:create", async () => { await createCoolifyInstance({ ...instanceForm }); @@ -125,12 +180,32 @@ async function run(key, callback) { function statusClass(status) { return { - "is-ok": ["ok", "protected", "failover_ready", "in_sync", "provisioned"].includes(status), - "is-degraded": ["degraded", "pending", "deploying", "restarting", "failover_blocked", "not_configured"].includes(status), + "is-ok": ["ok", "protected", "failover_ready", "in_sync", "provisioned", "in_lb"].includes(status), + "is-degraded": ["degraded", "pending", "deploying", "restarting", "failover_blocked", "not_configured", "missing", "disabled_present", "unknown"].includes(status), "is-down": ["down", "reconcile_failed", "restart_failed", "provision_blocked", "destructive_action_required"].includes(status), }; } +function serviceLabel(service) { + return `${service.protocol || "--"} ${service.listen_port || "--"} -> ${service.destination_port || "--"}`; +} + +function driftActionLabel(action) { + if (action.type === "add_target") { + return `Add target ${action.target_ip}`; + } + if (action.type === "remove_target") { + return `Remove target ${action.target_ip}`; + } + if (action.type === "skip_remove_target") { + return `Keep target ${action.target_ip}`; + } + if (action.type === "add_service") { + return `Add service ${serviceLabel(action)}`; + } + return action.type || "planned change"; +} + onMounted(load); @@ -165,6 +240,144 @@ onMounted(load); /> + +
+
+
+ Public host + {{ loadBalancerConfig.public_gateway_host || loadBalancerForm.public_gateway_host }} +
+
+ Status + {{ loadBalancer.status || "not_configured" }} +
+
+ Token + {{ loadBalancerConfig.token_set ? `set via ${loadBalancerConfig.token_source || "config"}` : "not set" }} +
+
+ Targets + {{ loadBalancerGateways.length }} +
+
+ +
+ + + + + +
+ +
+
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
GatewayIPEnabledHealthLB stateActions
+ {{ gateway.hostname }} +
Priority {{ gateway.priority }}
+
{{ gateway.target_ip }}{{ gateway.enabled ? "yes" : "no" }}{{ gateway.health_state }}{{ gateway.lb_state }} + +
No gateway targets configured.
+
+ +
+ Drift + No planned changes. +
    +
  • + {{ driftActionLabel(action) }} + ({{ action.reason }}) +
  • +
+
+
+
+ div { + display: grid; + gap: 0.25rem; +} + +.coolify-drift { + display: grid; + gap: 0.4rem; +} + +.coolify-drift ul { + margin: 0; + padding-left: 1.25rem; +} + .coolify-muted { color: #64748b; font-size: 0.86rem; diff --git a/src/views/dashboards/superUserDashboard/configuration/ConfigurationReleaseManager.vue b/src/views/dashboards/superUserDashboard/configuration/ConfigurationReleaseManager.vue index 9ededa78..f6cbf267 100644 --- a/src/views/dashboards/superUserDashboard/configuration/ConfigurationReleaseManager.vue +++ b/src/views/dashboards/superUserDashboard/configuration/ConfigurationReleaseManager.vue @@ -1,37 +1,99 @@ @@ -323,37 +1317,167 @@ onMounted(async () => { @@ -713,18 +2750,218 @@ onMounted(async () => {