mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
feat(mobile): localize tasks, new workspaces and source control (#35646)
* feat(mobile): localize tasks, new workspaces and source control Moves the last ~670 strings (task lists and boards, issue and PR sources, the new-workspace flow, and source control) to the translation API, with all ten translations. What remains in the coverage baseline is reviewed non-copy: key names, schema errors and log lines. - Source control section titles recompute on a language change * fix(mobile): align catalog terminology across screens A whole-catalog pass per language reconciled terms that differed between batches (host/desktop, dictation, transcripts, address form) with the glossaries and the desktop catalogs. The page bundle verifier now reports catalog bytes separately. * fix(mobile): keep fetched history and source error slugs language-independent History rows are derived from the fetched page at render so relative times follow a language switch; quality-gate follow-ups for the tasks and source control migration. * fix(mobile): name Android notification channels in the UI language * chore(mobile): drop catalog entries for removed source-control copy * fix(mobile): re-localize the composer source hook on current main --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -230,7 +230,7 @@ export async function verifyMobileWebAppBundle({ bundleDir = defaultBundleDir }
|
||||
`budget of ${String(MOBILE_WEB_APP_BUNDLE_MAX_ENTRY_BYTES)}`
|
||||
)
|
||||
}
|
||||
return manifest
|
||||
return { ...manifest, catalogBytes: first.catalogBytes }
|
||||
}
|
||||
|
||||
if (isDirectInvocation(import.meta.url, process.argv[1])) {
|
||||
@@ -239,7 +239,8 @@ if (isDirectInvocation(import.meta.url, process.argv[1])) {
|
||||
console.log(
|
||||
`[verify-mobile-web-app-bundle] OK — ${String(manifest.assets.length)} asset(s), ` +
|
||||
`${String(manifest.totalBytes)} total bytes, ` +
|
||||
`${String(mobileWebAppBundleBudgetBytes(manifest))}/${String(MOBILE_WEB_APP_BUNDLE_MAX_TOTAL_BYTES)} bytes excluding the approved font, ` +
|
||||
`${String(mobileWebAppBundleBudgetBytes(manifest) - manifest.catalogBytes)}/${String(MOBILE_WEB_APP_BUNDLE_MAX_TOTAL_BYTES)} bytes excluding the approved font, ` +
|
||||
`${String(manifest.catalogBytes)}/${String(MOBILE_WEB_APP_BUNDLE_MAX_CATALOG_BYTES)} bytes of language catalogs, ` +
|
||||
`reproducible buildId ${manifest.buildId}`
|
||||
)
|
||||
} catch (error) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import { appUpdateChecker } from '../src/app-update/app-update-runtime'
|
||||
import { SideSafeArea } from '../src/layout/side-safe-area'
|
||||
import { useFollowDeviceUiLocale } from '../src/i18n/use-follow-device-ui-locale'
|
||||
import { startMobileUiLanguage } from '../src/i18n/ui-language-preference'
|
||||
import { subscribeMobileUiLanguage } from '../src/i18n/mobile-i18n'
|
||||
|
||||
// Keep splash visible until React content is ready to avoid a blank frame.
|
||||
SplashScreen.preventAutoHideAsync()
|
||||
@@ -41,6 +42,10 @@ const languageReady = startMobileUiLanguage()
|
||||
|
||||
// Create orca-desktop channel at boot: background FCM can arrive before socket subscription, and Android drops unknown-channel pushes.
|
||||
void ensureDesktopNotificationChannel().catch(() => {})
|
||||
// Channel names show in Android settings; rename them in the active language.
|
||||
subscribeMobileUiLanguage(() => {
|
||||
void ensureDesktopNotificationChannel().catch(() => {})
|
||||
})
|
||||
void registerPushDismissalTask().catch(() => {})
|
||||
|
||||
// Register before scheduling so foreground delivery uses the same suppression policy.
|
||||
|
||||
@@ -199,6 +199,18 @@
|
||||
}
|
||||
},
|
||||
"sourceControl": {
|
||||
"actions": {
|
||||
"pullCommits_one": "Pull {{count}} commit.",
|
||||
"pullCommits_other": "Pull {{count}} commits.",
|
||||
"pushCommits_one": "Push {{count}} commit.",
|
||||
"pushCommits_other": "Push {{count}} commits."
|
||||
},
|
||||
"branchCompare": {
|
||||
"commits_one": "{{count}} commit",
|
||||
"commits_other": "{{count}} commits",
|
||||
"files_one": "{{count}} file",
|
||||
"files_other": "{{count}} files"
|
||||
},
|
||||
"dropdownCounts": {
|
||||
"fastForwardCount_one": "Fast-forward {{count}} commit",
|
||||
"fastForwardCount_other": "Fast-forward {{count}} commits",
|
||||
@@ -214,6 +226,58 @@
|
||||
"titleManualForcePush_other": "Force push {{count}} local commits with lease to update {{upstreamName}}.",
|
||||
"titleUnpublishedForcePushCount_one": "Force push {{count}} branch commit with lease and set an upstream if needed.",
|
||||
"titleUnpublishedForcePushCount_other": "Force push {{count}} branch commits with lease and set an upstream if needed."
|
||||
},
|
||||
"gitHistory": {
|
||||
"days_one": "{{count}}d",
|
||||
"days_other": "{{count}}d",
|
||||
"hours_one": "{{count}}h",
|
||||
"hours_other": "{{count}}h",
|
||||
"minutes_one": "{{count}}m",
|
||||
"minutes_other": "{{count}}m",
|
||||
"months_one": "{{count}}mo",
|
||||
"months_other": "{{count}}mo",
|
||||
"years_one": "{{count}}y",
|
||||
"years_other": "{{count}}y"
|
||||
},
|
||||
"prChip": {
|
||||
"openWithComments_one": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request.",
|
||||
"openWithComments_other": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request."
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"detailCommentRenderers": {
|
||||
"comments_one": "{{count}} comment",
|
||||
"comments_other": "{{count}} comments"
|
||||
},
|
||||
"filterPickers": {
|
||||
"teams_one": "{{count}} team",
|
||||
"teams_other": "{{count}} teams"
|
||||
},
|
||||
"githubProjectList": {
|
||||
"moreFields_one": "+{{count}} field",
|
||||
"moreFields_other": "+{{count}} fields"
|
||||
},
|
||||
"itemDetailContent": {
|
||||
"pipelineJobs_one": "{{count}} jobs",
|
||||
"pipelineJobs_other": "{{count}} jobs"
|
||||
},
|
||||
"pickerProjection": {
|
||||
"repos_one": "{{count}} repo",
|
||||
"repos_other": "{{count}} repos",
|
||||
"sources_one": "{{count}} source",
|
||||
"sources_other": "{{count}} sources"
|
||||
},
|
||||
"projectComments": {
|
||||
"comments_one": "{{count}} comment",
|
||||
"comments_other": "{{count}} comments"
|
||||
},
|
||||
"providerViewProjection": {
|
||||
"teams_one": "{{count}} team",
|
||||
"teams_other": "{{count}} teams"
|
||||
},
|
||||
"workspaceTrustDrawers": {
|
||||
"directories_one": "{{count}} directory",
|
||||
"directories_other": "{{count}} directories"
|
||||
}
|
||||
},
|
||||
"worktree": {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"connectingTo": "Verbindung zu {{name}} wird hergestellt…",
|
||||
"default": "Systemstandard",
|
||||
"hostNotFound": "Host nicht gefunden",
|
||||
"invalidSnapshot": "Ungültiger Kontodaten-Snapshot vom Host",
|
||||
"invalidSnapshot": "Ungültige Momentaufnahme der Konten vom Host",
|
||||
"loadingAccounts": "Konten werden geladen…",
|
||||
"manageAccountsHint": "Konten auf dem Desktop unter Einstellungen → Konten hinzufügen oder erneut authentifizieren.",
|
||||
"refreshAccounts": "Konten aktualisieren",
|
||||
@@ -572,10 +572,10 @@
|
||||
"codexResetCreditAction": {
|
||||
"activeAccountHint": "Verbraucht einen verdienten Credit zum Zurücksetzen des Ratenlimits für das aktive Codex-Konto",
|
||||
"earnedReset": "Verdienter Credit zum Zurücksetzen des Codex-Ratenlimits",
|
||||
"resetting": "Einlösen…",
|
||||
"resetting": "Wird zurückgesetzt…",
|
||||
"resettingLabel": "Codex-Ratenlimits werden zurückgesetzt",
|
||||
"scopedHint": "Verbraucht einen verdienten Credit zum Zurücksetzen des Ratenlimits für {{scopeLabel}}",
|
||||
"useReset": "Einlösen",
|
||||
"useReset": "Jetzt zurücksetzen",
|
||||
"useResetLabel": "Zurücksetzung des Codex-Ratenlimits verwenden"
|
||||
},
|
||||
"customKeyModal": {
|
||||
@@ -1495,7 +1495,21 @@
|
||||
"workspace": "Arbeitsbereich"
|
||||
}
|
||||
},
|
||||
"newWorkspace": {
|
||||
"hostPicker": {
|
||||
"title": "Arbeitsbereich auf Host erstellen"
|
||||
},
|
||||
"loadingDrawer": {
|
||||
"downloadProgress": "Wird heruntergeladen… {{progress}}",
|
||||
"downloading": "Wird heruntergeladen",
|
||||
"loading": "Wird geladen"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"desktopChannel": {
|
||||
"name": "Desktop-Benachrichtigungen",
|
||||
"silentName": "Lautlose Orca-Benachrichtigungen"
|
||||
},
|
||||
"notificationDeliverySection": {
|
||||
"footer": "Die Benachrichtigungsarten richten sich nach den Benachrichtigungseinstellungen des jeweiligen gekoppelten Computers. Nach 7 Tagen ohne Nutzung dieser App werden Benachrichtigungen pausiert; zum Fortsetzen die App öffnen und erneut verbinden.",
|
||||
"onlyWhenAway": "Nur bei Abwesenheit vom Computer",
|
||||
@@ -1785,10 +1799,10 @@
|
||||
"dismissed": "Verworfen",
|
||||
"loadFailed": "Prüfer konnten nicht geladen werden. Zum erneuten Laden auf „Aktualisieren“ tippen.",
|
||||
"loading": "Prüfer werden geladen…",
|
||||
"noReviewers": "Keine Prüfer angefragt",
|
||||
"noReviewers": "Keine Prüfer angefordert",
|
||||
"pending": "Ausstehend",
|
||||
"removeReviewer": "{{login}} entfernen",
|
||||
"requested": "Angefragt",
|
||||
"requested": "Angefordert",
|
||||
"reviewed": "Geprüft",
|
||||
"title": "Prüfer"
|
||||
}
|
||||
@@ -2217,7 +2231,7 @@
|
||||
},
|
||||
"terminalLiveInputStatus": {
|
||||
"listening": "Hört zu",
|
||||
"liveInput": "Live-Eingabe",
|
||||
"liveInput": "Direkte Eingabe",
|
||||
"preparingMic": "Mikrofon wird vorbereitet",
|
||||
"processing": "Wird verarbeitet",
|
||||
"releaseMicHint": "Zum Stoppen Mikrofon loslassen",
|
||||
@@ -2524,11 +2538,67 @@
|
||||
}
|
||||
},
|
||||
"sourceControl": {
|
||||
"actionSheetRunners": {
|
||||
"noBaseBranch": "Kein Basis-Branch für den Rebase vorhanden",
|
||||
"waitingForDesktop": "Warten auf den Desktop…"
|
||||
},
|
||||
"actions": {
|
||||
"checkingReviewStatus": "Review-Status wird geprüft.",
|
||||
"checkoutBeforePublish": "Vor dem Veröffentlichen von Commits einen Branch auschecken.",
|
||||
"commitStagedChanges": "Vorgemerkte Änderungen committen.",
|
||||
"commits": "Commits",
|
||||
"committing": "Commit läuft.",
|
||||
"createPr": "PR erstellen",
|
||||
"enterCommitMessage": "Zum Committen eine Commit-Nachricht eingeben.",
|
||||
"forcePushWithLease": "Push mit Lease erzwingen, um den entfernten Branch zu aktualisieren.",
|
||||
"forcePushing": "Push wird erzwungen.",
|
||||
"linkedReviewUnavailable": "Der verknüpfte Review-Branch ist nicht verfügbar.",
|
||||
"publishToOrigin": "Diesen Branch auf origin veröffentlichen.",
|
||||
"pullCommits_one": "{{count}} Commit pullen.",
|
||||
"pullCommits_other": "{{count}} Commits pullen.",
|
||||
"pushAndCreatePr": "Pushen & PR erstellen",
|
||||
"switchBranch": "Branch wechseln"
|
||||
"pushCommits_one": "{{count}} Commit pushen.",
|
||||
"pushCommits_other": "{{count}} Commits pushen.",
|
||||
"pushLinkedReview": "Änderungen auf den verknüpften Review-Branch pushen.",
|
||||
"remoteOperationInProgress": "Remote-Vorgang läuft.",
|
||||
"resolveConflicts": "Vor dem Committen Konflikte lösen.",
|
||||
"reviewAlreadyMerged": "Nichts zu committen. Das Review wurde bereits gemergt.",
|
||||
"stageAllChanges": "Alle Änderungen vormerken.",
|
||||
"stageFileToCommit": "Zum Committen mindestens eine Datei vormerken.",
|
||||
"switchBranch": "Branch wechseln",
|
||||
"syncCounts": "{{behind}} pullen, {{ahead}} pushen.",
|
||||
"upToDate": "Nichts zu committen. Branch ist aktuell.",
|
||||
"waitForRemoteOperation": "Nach Abschluss des Remote-Vorgangs erneut versuchen."
|
||||
},
|
||||
"branchBaseRef": {
|
||||
"resolveFailed": "Branch-Basis konnte nicht ermittelt werden."
|
||||
},
|
||||
"branchCard": {
|
||||
"branchCount": "{{count}} auf Branch",
|
||||
"changedCount": "{{count}} geändert",
|
||||
"cherryPickState": "Cherry-pick",
|
||||
"mergeState": "Merge",
|
||||
"rebaseState": "Rebase",
|
||||
"stagedCount": "{{count}} vorgemerkt"
|
||||
},
|
||||
"branchCompare": {
|
||||
"commits_one": "{{count}} Commit",
|
||||
"commits_other": "{{count}} Commits",
|
||||
"files_one": "{{count}} Datei",
|
||||
"files_other": "{{count}} Dateien",
|
||||
"sectionTitle": "Auf Branch committet",
|
||||
"summary": "{{files}} – gegenüber {{baseRef}}",
|
||||
"summaryWithCommits": "{{files}} – {{commits}} – gegenüber {{baseRef}}"
|
||||
},
|
||||
"branchCompareOutcome": {
|
||||
"baseBranchUnavailable": "Basis-Branch für den Vergleich konnte nicht ermittelt werden.",
|
||||
"loadFailed": "Committete Änderungen konnten nicht geladen werden."
|
||||
},
|
||||
"branchDiffPreviewDrawer": {
|
||||
"closePreview": "Diff-Vorschau der committeten Änderungen schließen",
|
||||
"committedOnBranch": "Auf Branch committet",
|
||||
"loadFailed": "Laden des Diffs fehlgeschlagen",
|
||||
"truncated": "Diff für die mobile Vorschau gekürzt."
|
||||
},
|
||||
"commitDropdown": {
|
||||
"checkOutBranchToPush": "Vor dem Pushen von Commits einen Branch auschecken",
|
||||
@@ -2553,8 +2623,49 @@
|
||||
"stageFile": "Zum Committen mindestens eine Datei vormerken",
|
||||
"useCommitAndForcePush": "„Committen & Push erzwingen“ verwenden — das Remote enthält nur ältere Kopien lokaler Commits"
|
||||
},
|
||||
"commitFailurePanel": {
|
||||
"fix": "Beheben",
|
||||
"fixWithAi": "Commit-Fehler mit KI beheben",
|
||||
"hideDetails": "Details ausblenden",
|
||||
"hideFailureDetails": "Details zum Commit-Fehler ausblenden",
|
||||
"showDetails": "Details anzeigen",
|
||||
"showFailureDetails": "Details zum Commit-Fehler anzeigen",
|
||||
"summary": "Commit fehlgeschlagen.",
|
||||
"title": "Commit fehlgeschlagen"
|
||||
},
|
||||
"commitMessageAi": {
|
||||
"generateFailed": "Commit-Nachricht konnte nicht generiert werden."
|
||||
},
|
||||
"commitRunners": {
|
||||
"actionFailed": "Aktion der Quellcodeverwaltung fehlgeschlagen",
|
||||
"commitFailed": "Commit fehlgeschlagen"
|
||||
},
|
||||
"conflictAbort": {
|
||||
"abortMerge": "Merge abbrechen",
|
||||
"abortOperation": "{{operation}} abbrechen",
|
||||
"abortRebase": "Rebase abbrechen",
|
||||
"aborting": "Wird abgebrochen…"
|
||||
},
|
||||
"content": {
|
||||
"cancelGeneration": "Generierung der Commit-Nachricht abbrechen",
|
||||
"commitMessageDisabled": "Commit-Nachricht deaktiviert. Keine vorgemerkten Dateien.",
|
||||
"commitMessagePlaceholder": "Commit-Nachricht",
|
||||
"emptyMessage": "Der Worktree ist sauber.",
|
||||
"emptyTitle": "Keine lokalen Änderungen",
|
||||
"generateMessage": "Commit-Nachricht mit KI generieren",
|
||||
"noStagedFiles": "Keine vorgemerkten Dateien",
|
||||
"openActions": "Aktionen der Quellcodeverwaltung öffnen",
|
||||
"reconnecting": "Verbindung zum Desktop wird wiederhergestellt…",
|
||||
"regenerateHint": "Nachricht leeren, um sie neu zu generieren.",
|
||||
"stageAll": "Alle vormerken",
|
||||
"unstageAll": "Alle Vormerkungen aufheben"
|
||||
},
|
||||
"createPrAction": {
|
||||
"createReview": "{{titleLabel}} erstellen"
|
||||
"checkingStatus": "Review-Status wird geprüft…",
|
||||
"createPullRequest": "Pull Request erstellen",
|
||||
"createReview": "{{titleLabel}} erstellen",
|
||||
"providerUnavailable": "Review-Erstellung bei diesem Anbieter nicht verfügbar",
|
||||
"statusUnavailable": "Review-Status nicht verfügbar"
|
||||
},
|
||||
"dropdownCounts": {
|
||||
"fastForwardCount_one": "{{count}} Commit per Fast-Forward übernehmen",
|
||||
@@ -2576,6 +2687,64 @@
|
||||
"titleUnpublishedForcePushCount_one": "Push von {{count}} Branch-Commit mit Lease erzwingen und bei Bedarf einen Upstream festlegen.",
|
||||
"titleUnpublishedForcePushCount_other": "Push von {{count}} Branch-Commits mit Lease erzwingen und bei Bedarf einen Upstream festlegen."
|
||||
},
|
||||
"fileList": {
|
||||
"committedSection": "Auf Branch committet"
|
||||
},
|
||||
"fileRows": {
|
||||
"addedByThem": "Von ihnen hinzugefügt",
|
||||
"addedByUs": "Von uns hinzugefügt",
|
||||
"bothAdded": "Beidseitig hinzugefügt",
|
||||
"bothDeleted": "Beidseitig gelöscht",
|
||||
"bothModified": "Beidseitig geändert",
|
||||
"committedSection": "Auf Branch committet",
|
||||
"committedUnavailable": "Committete Änderungen nicht verfügbar.",
|
||||
"deletedByThem": "Von ihnen gelöscht",
|
||||
"deletedByUs": "Von uns gelöscht",
|
||||
"discardFile": "Änderungen an {{path}} verwerfen",
|
||||
"loadingCommitted": "Committete Änderungen werden geladen…",
|
||||
"openChangedFile": "Geänderte Datei {{path}} öffnen",
|
||||
"openCommittedChange": "Committete Änderung an {{path}} öffnen",
|
||||
"renamedFrom": "von {{path}}",
|
||||
"stageFile": "{{path}} vormerken",
|
||||
"unresolvedConflict": "Ungelöster Konflikt",
|
||||
"unstageFile": "Vormerkung für {{path}} aufheben"
|
||||
},
|
||||
"gitHistory": {
|
||||
"days_one": "{{count}} T.",
|
||||
"days_other": "{{count}} T.",
|
||||
"hours_one": "{{count}} Std.",
|
||||
"hours_other": "{{count}} Std.",
|
||||
"justNow": "gerade eben",
|
||||
"loadFailed": "Commit-Verlauf konnte nicht geladen werden.",
|
||||
"minutes_one": "{{count}} Min.",
|
||||
"minutes_other": "{{count}} Min.",
|
||||
"months_one": "{{count}} Mon.",
|
||||
"months_other": "{{count}} Mon.",
|
||||
"noCommitMessage": "(keine Commit-Nachricht)",
|
||||
"years_one": "{{count}} J.",
|
||||
"years_other": "{{count}} J."
|
||||
},
|
||||
"gitHistoryList": {
|
||||
"loadFailed": "Verlauf konnte nicht geladen werden.",
|
||||
"loadFilesFailed": "Commit-Dateien konnten nicht geladen werden.",
|
||||
"noCommits": "Keine Commits.",
|
||||
"noFileChanges": "Keine Dateiänderungen",
|
||||
"retryFiles": "Commit-Dateien erneut laden",
|
||||
"waitingForDesktop": "Warten auf Desktop…"
|
||||
},
|
||||
"gitStatus": {
|
||||
"changes": "Änderungen",
|
||||
"conflicts": "Konflikte",
|
||||
"stagedChanges": "Vorgemerkte Änderungen"
|
||||
},
|
||||
"header": {
|
||||
"backToSession": "Zurück zur Sitzung",
|
||||
"close": "Quellcodeverwaltung schließen",
|
||||
"openNumberedPrWeb": "Pull Request #{{number}} im Web öffnen",
|
||||
"openPrWeb": "Pull Request im Web öffnen",
|
||||
"refresh": "Quellcodeverwaltung aktualisieren",
|
||||
"title": "Quellcodeverwaltung"
|
||||
},
|
||||
"hostedReview": {
|
||||
"mrCopy": {
|
||||
"reviewLabel": "Merge Request",
|
||||
@@ -2588,9 +2757,81 @@
|
||||
"titleLabel": "Pull Request"
|
||||
}
|
||||
},
|
||||
"hostedReviewCopy": {
|
||||
"committingChanges": "Änderungen werden committet…",
|
||||
"creatingReview": "Review wird erstellt…",
|
||||
"forcePushing": "Push mit Lease wird erzwungen…",
|
||||
"generatingCommitMessage": "Commit-Nachricht wird generiert…",
|
||||
"publishingBranch": "Branch wird veröffentlicht…",
|
||||
"pushingCommits": "Commits werden gepusht…",
|
||||
"stagingChanges": "Änderungen werden vorgemerkt…",
|
||||
"updatingBranch": "Branch wird aktualisiert…"
|
||||
},
|
||||
"hostedReviewCreate": {
|
||||
"pushSucceeded": "Push erfolgreich, aber der {{shortLabel}} konnte nicht erstellt werden: {{error}}"
|
||||
},
|
||||
"hostedReviewCreateIntent": {
|
||||
"branchChanged": "Branch wurde während der Vorbereitung des Pull Requests geändert.",
|
||||
"generateMessageFailed": "Commit-Nachricht konnte nicht generiert werden. In der Quellcodeverwaltung eine hinzufügen und erneut versuchen.",
|
||||
"resolveConflicts": "Vor dem Erstellen eines Pull Requests Konflikte lösen.",
|
||||
"resolveOrStageChanges": "Vor dem Erstellen eines Pull Requests Änderungen bereinigen oder vormerken.",
|
||||
"reviewCommitMessage": "Commit-Nachricht prüfen und anschließend „PR erstellen“ erneut versuchen."
|
||||
},
|
||||
"hostedReviewGitPreparation": {
|
||||
"commitFailed": "Commit fehlgeschlagen",
|
||||
"refreshFailed": "Quellcodeverwaltung konnte nicht aktualisiert werden.",
|
||||
"stageFailed": "Änderungen konnten nicht vorgemerkt werden.",
|
||||
"updateBranchFailed": "Entfernter Branch konnte nicht aktualisiert werden. „PR erstellen“ erneut versuchen."
|
||||
},
|
||||
"hostedReviewRemotePrerequisite": {
|
||||
"forcePushFailed": "Push mit Lease konnte nicht erzwungen werden.",
|
||||
"publishFailed": "Branch konnte nicht veröffentlicht werden.",
|
||||
"pushFailed": "Commits konnten nicht gepusht werden."
|
||||
},
|
||||
"hostedReviewService": {
|
||||
"createFailed": "Pull Request konnte nicht erstellt werden.",
|
||||
"pushBeforeCreateFailed": "Push fehlgeschlagen. Den Push-Fehler beheben und erneut versuchen."
|
||||
},
|
||||
"hubTab": {
|
||||
"changes": "Änderungen",
|
||||
"commits": "Commits",
|
||||
"pullRequest": "Pull Request"
|
||||
},
|
||||
"loaders": {
|
||||
"connectingToDesktop": "Verbindung zum Desktop wird hergestellt…",
|
||||
"loadFailed": "Quellcodeverwaltung konnte nicht geladen werden.",
|
||||
"updateDesktop": "Orca auf dem Desktop aktualisieren, um die Quellcodeverwaltung mobil zu nutzen.",
|
||||
"waitingForDesktop": "Warten auf den Desktop…"
|
||||
},
|
||||
"modals": {
|
||||
"actionsTitle": "Quellcodeverwaltung",
|
||||
"currentBranch": "aktuell",
|
||||
"discardButton": "Verwerfen",
|
||||
"discardConfirmMessage": "Änderungen an „{{path}}“ verwerfen? Dies kann nicht rückgängig gemacht werden.",
|
||||
"discardTitle": "Änderung verwerfen?",
|
||||
"openPrMessage": "Im Browser öffnen?",
|
||||
"openPrWithWarning": "Im Browser öffnen?\n\n{{warning}}",
|
||||
"prCreatedTitle": "Pull Request erstellt",
|
||||
"switchBranchTitle": "Branch wechseln"
|
||||
},
|
||||
"openers": {
|
||||
"openDiffFailed": "Diff konnte nicht geöffnet werden.",
|
||||
"tabNotReady": "Die Datei wurde geöffnet, aber ihr Tab ist noch nicht bereit. Erneut versuchen.",
|
||||
"waitingForDesktop": "Warten auf den Desktop…"
|
||||
},
|
||||
"panel": {
|
||||
"loadFailedTitle": "Laden fehlgeschlagen",
|
||||
"unavailableTitle": "Quellcodeverwaltung nicht verfügbar"
|
||||
},
|
||||
"prChip": {
|
||||
"createPr": "Pull Request erstellen",
|
||||
"loading": "Pull Request wird geladen…",
|
||||
"loadingLabel": "Pull Request wird geladen",
|
||||
"openLabel": "Pull Request #{{number}}, {{state}}, {{checks}}. Pull Request öffnen.",
|
||||
"openWithComments_one": "Pull Request #{{number}}, {{state}}, {{checks}}, {{count}} ungelöster Kommentar. Pull Request öffnen.",
|
||||
"openWithComments_other": "Pull Request #{{number}}, {{state}}, {{checks}}, {{count}} ungelöste Kommentare. Pull Request öffnen.",
|
||||
"unavailableLabel": "Pull Request nicht verfügbar: {{message}}"
|
||||
},
|
||||
"prCreate": {
|
||||
"authRequired": "Vor dem Erstellen eines {{reviewLabel}}s ist eine Authentifizierung erforderlich.",
|
||||
"baseNotOnRemote": "Den Basis-Branch pushen, bevor ein {{reviewLabel}} erstellt wird.",
|
||||
@@ -2609,8 +2850,19 @@
|
||||
"unsupportedMergeRequests": "Das Erstellen von Merge Requests wird für dieses Repo nicht unterstützt.",
|
||||
"unsupportedPullRequests": "Das Erstellen von Pull Requests wird für dieses Repo nicht unterstützt."
|
||||
},
|
||||
"prLink": {
|
||||
"updatePullRequestFailed": "Verknüpfter Pull Request konnte nicht aktualisiert werden.",
|
||||
"updateReviewFailed": "Verknüpftes Review konnte nicht aktualisiert werden."
|
||||
},
|
||||
"primaryAction": {
|
||||
"forcePushFromDesktop": "Push für den Branch dieses Pull Requests vom Desktop aus erzwingen"
|
||||
"commit": "Committen",
|
||||
"forcePush": "Push erzwingen",
|
||||
"forcePushFromDesktop": "Push für den Branch dieses Pull Requests vom Desktop aus erzwingen",
|
||||
"publishBranch": "Branch veröffentlichen",
|
||||
"pull": "Pullen",
|
||||
"push": "Pushen",
|
||||
"stageAll": "Alle vormerken",
|
||||
"sync": "Synchronisieren"
|
||||
},
|
||||
"remoteDropdown": {
|
||||
"branchAlreadyPublished": "Branch ist bereits veröffentlicht",
|
||||
@@ -2660,6 +2912,591 @@
|
||||
"tryFastForwardPull": "Pull per Fast-Forward versuchen; git lehnt lokale Commits eventuell ab",
|
||||
"tryRegularPush": "Regulären Push versuchen; git erfordert eventuell einen erzwungenen Push",
|
||||
"useForcePushToSync": "„Push erzwingen“ verwenden – das Remote enthält nur ältere Kopien lokaler Commits"
|
||||
},
|
||||
"runners": {
|
||||
"actionFailed": "Aktion der Quellcodeverwaltung fehlgeschlagen"
|
||||
},
|
||||
"screenState": {
|
||||
"noBranch": "Kein Branch"
|
||||
},
|
||||
"state": {
|
||||
"noUpstream": "Kein Upstream",
|
||||
"syncStatus": "{{ahead}} voraus, {{behind}} zurück"
|
||||
},
|
||||
"useMobileCommitFailureRecovery": {
|
||||
"launchFailed": "Agent konnte nicht gestartet werden.",
|
||||
"waitingForDesktop": "Warten auf den Desktop…"
|
||||
},
|
||||
"useMobileCommitMessageGeneration": {
|
||||
"generateFailed": "Commit-Nachricht konnte nicht generiert werden."
|
||||
},
|
||||
"useMobileCreatePrRunner": {
|
||||
"branchRequired": "Vor dem Erstellen eines Pull Requests einen Branch auschecken."
|
||||
},
|
||||
"useMobileGitRequests": {
|
||||
"actionFailed": "Aktion der Quellcodeverwaltung fehlgeschlagen",
|
||||
"branchUnavailable": "Branch-Status nicht verfügbar",
|
||||
"commitFailed": "Commit fehlgeschlagen",
|
||||
"waitingForDesktop": "Warten auf den Desktop…"
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"composerSource": {
|
||||
"baseFailed": "Der Basis-Branch konnte nicht ermittelt werden.",
|
||||
"forkPushWarning": "Bei diesem PR ist „Allow edits from maintainers“ deaktiviert; GitHub könnte einen Push zum Fork ablehnen."
|
||||
},
|
||||
"detailCommentRenderers": {
|
||||
"commentPlaceholder": "Kommentar hinzufügen",
|
||||
"comments_one": "{{count}} Kommentar",
|
||||
"comments_other": "{{count}} Kommentare",
|
||||
"reopenThread": "Thread wieder öffnen",
|
||||
"reply": "Antworten",
|
||||
"resolveThread": "Thread als erledigt markieren",
|
||||
"resolvedCommentBy": "Erledigter Kommentar von {{author}}",
|
||||
"resolvedThreadBy": "Erledigter Thread von {{author}}",
|
||||
"sendComment": "Kommentar senden",
|
||||
"show": "Anzeigen"
|
||||
},
|
||||
"filterPickers": {
|
||||
"allTeams": "Alle Teams",
|
||||
"changeStatus": "Status ändern",
|
||||
"fieldHidden": "Auf Karten ausgeblendet",
|
||||
"fieldShown": "Auf Karten angezeigt",
|
||||
"fieldsSubtitle": "Auswählen, welche Projektfelder auf Eintragskarten angezeigt werden.",
|
||||
"fieldsTitle": "Projektfelder",
|
||||
"gitlabFilter": "GitLab-Filter",
|
||||
"gitlabView": "GitLab-Ansicht",
|
||||
"jiraFilter": "Jira-Filter",
|
||||
"jiraSite": "Jira-Site",
|
||||
"linearFilter": "Linear-Filter",
|
||||
"linearIssue": "Linear-Issue",
|
||||
"linearWorkspace": "Linear-Arbeitsbereich",
|
||||
"loadingStates": "Statusoptionen werden geladen…",
|
||||
"noFields": "Diese Ansicht enthält keine zusätzlichen Felder.",
|
||||
"noStates": "Keine Statusoptionen verfügbar",
|
||||
"switchWorkspaceFailed": "Arbeitsbereich konnte nicht gewechselt werden.",
|
||||
"teamsSubtitle": "Auswählen, welche Teams unter „Aufgaben“ angezeigt werden.",
|
||||
"teamsTitle": "Linear-Teams",
|
||||
"teams_one": "{{count}} Team",
|
||||
"teams_other": "{{count}} Teams"
|
||||
},
|
||||
"githubProjectList": {
|
||||
"browseProjects": "Projekte durchsuchen",
|
||||
"chooseProject": "GitHub-Projekt auswählen",
|
||||
"emptyField": "Leer",
|
||||
"issueSubtitle": "Issue · {{repository}}{{number}}",
|
||||
"itemSubtitle": "Projekteintrag · {{repository}}{{number}}",
|
||||
"items": "Einträge",
|
||||
"moreFields_one": "+{{count}} Feld",
|
||||
"moreFields_other": "+{{count}} Felder",
|
||||
"noItems": "Keine Projekteinträge",
|
||||
"pullRequestSubtitle": "Pull Request · {{repository}}{{number}}"
|
||||
},
|
||||
"githubProjectPickers": {
|
||||
"add": "Hinzufügen",
|
||||
"addByUrlHint": "Fehlende Projekte lassen sich per URL hinzufügen.",
|
||||
"addPlaceholder": "Per URL oder owner/number hinzufügen",
|
||||
"adding": "Wird hinzugefügt…",
|
||||
"browseAll": "Alle durchsuchen",
|
||||
"browseLoading": "Alle durchsuchen (wird geladen…)",
|
||||
"chooseView": "Projektansicht auswählen",
|
||||
"loadFailed": "Laden der Projekte fehlgeschlagen",
|
||||
"noMatches": "Keine passenden Projekte.",
|
||||
"noMoreProjects": "Keine weiteren Projekte.",
|
||||
"noProjects": "Keine Projekte geladen",
|
||||
"organizationsError": "Organisationen: {{message}}",
|
||||
"organizationsLoadFailed": "Einige Organisationen konnten nicht geladen werden ({{count}}).",
|
||||
"ownerLoadFailed": "Projekte von {{owner}} konnten nicht geladen werden.",
|
||||
"pin": "Anheften",
|
||||
"pinned": "Angeheftet",
|
||||
"recent": "Zuletzt verwendet",
|
||||
"retryHint": "Zum Wiederholen tippen.",
|
||||
"searchProjects": "Projekte suchen",
|
||||
"sort": "Projektsortierung",
|
||||
"subtitle": "Eine Projektansicht für die Seite „Aufgaben“ auswählen.",
|
||||
"title": "GitHub Projects",
|
||||
"unsupportedLayout": "Orca unterstützt dieses Layout in GitHub Projects noch nicht.",
|
||||
"view": "Projektansicht"
|
||||
},
|
||||
"githubViewControls": {
|
||||
"fields": "Felder: {{fields}}",
|
||||
"openView": "Ansicht in GitHub öffnen",
|
||||
"sort": "Sortierung: {{sort}}",
|
||||
"source": "Quelle: {{source}}"
|
||||
},
|
||||
"itemActions": {
|
||||
"changeStatus": "Status ändern",
|
||||
"copyGitHubLink": "GitHub-Link kopieren",
|
||||
"copyLinearLink": "Linear-Link kopieren",
|
||||
"createWorkspace": "Arbeitsbereich erstellen",
|
||||
"creating": "Wird erstellt…",
|
||||
"mergeConflicts": "GitHub meldet Merge-Konflikte.",
|
||||
"mergeMergeRequest": "Merge Request mergen",
|
||||
"mergePullRequest": "Pull Request mergen"
|
||||
},
|
||||
"itemDetailContent": {
|
||||
"addSubIssue": "Unter-Issue hinzufügen",
|
||||
"assignee": "Zuständige Person",
|
||||
"assignees": "Zuständige Personen",
|
||||
"checks": "Checks",
|
||||
"description": "Beschreibung",
|
||||
"discussion": "Diskussion",
|
||||
"noChecks": "Keine Checks gefunden.",
|
||||
"noComments": "Keine Kommentare.",
|
||||
"noPipelineRuns": "Keine Pipeline-Ausführungen für diesen MR.",
|
||||
"noSubIssues": "Keine untergeordneten Issues.",
|
||||
"none": "Keine",
|
||||
"pipeline": "Pipeline",
|
||||
"pipelineJobs_one": "{{count}} Job",
|
||||
"pipelineJobs_other": "{{count}} Jobs",
|
||||
"project": "Projekt",
|
||||
"rerunAll": "Alle erneut ausführen",
|
||||
"rerunFailed": "Fehlgeschlagene erneut ausführen",
|
||||
"status": "Status",
|
||||
"subIssueTitle": "Titel des Unter-Issues",
|
||||
"subIssues": "Untergeordnete Issues",
|
||||
"type": "Typ"
|
||||
},
|
||||
"itemDetailDrawer": {
|
||||
"refreshDetails": "Details aktualisieren"
|
||||
},
|
||||
"itemFieldEditors": {
|
||||
"addLabels": "Labels hinzufügen, kommagetrennt",
|
||||
"addUsernames": "Benutzernamen hinzufügen, kommagetrennt",
|
||||
"assignees": "Zuständige Personen",
|
||||
"labels": "Labels",
|
||||
"loadingAssignees": "Zuständige Personen werden geladen…",
|
||||
"loadingLabels": "Labels werden geladen…",
|
||||
"noAssignableUsers": "Keine zuweisbaren Benutzer für dieses Repository gefunden.",
|
||||
"noLabels": "Keine Labels in diesem Repository.",
|
||||
"none": "Keine",
|
||||
"removeLabels": "Labels entfernen, kommagetrennt",
|
||||
"removeUsernames": "Benutzernamen entfernen, kommagetrennt",
|
||||
"saveTitle": "Titel speichern",
|
||||
"title": "Titel",
|
||||
"updateAssignees": "Zuständige Personen aktualisieren",
|
||||
"updateLabels": "Labels aktualisieren"
|
||||
},
|
||||
"itemReviewSections": {
|
||||
"binaryFile": "Binärdatei.",
|
||||
"changedFilesTitle": "Geänderte Dateien",
|
||||
"descriptionPlaceholder": "Beschreibung",
|
||||
"fileContentsUnavailable": "Dateiinhalt nicht verfügbar.",
|
||||
"hideFile": "Ausblenden",
|
||||
"loadingReviewers": "Prüfer werden geladen…",
|
||||
"markUnviewed": "Als nicht angesehen markieren",
|
||||
"markViewed": "Als angesehen markieren",
|
||||
"noDescription": "Keine Beschreibung.",
|
||||
"noReviewerSuggestions": "Keine Vorschläge für Prüfer gefunden.",
|
||||
"noReviewersRequested": "Keine Prüfer angefordert.",
|
||||
"requestReview": "Review anfordern",
|
||||
"reviewersPlaceholder": "Prüfer anfordern",
|
||||
"reviewersTitle": "Prüfer",
|
||||
"saveDescription": "Beschreibung speichern",
|
||||
"viewFile": "Anzeigen"
|
||||
},
|
||||
"legacySurface": {
|
||||
"loadIssuesFailed": "Issues aus {{source}} konnten nicht geladen werden.",
|
||||
"mergeAction": "Mergen",
|
||||
"mergeMethodTitle": "Merge-Methode",
|
||||
"mergePullRequestTitle": "Pull Request mergen?",
|
||||
"mergeRequestMergeMessage": "Auswählen, wie dieser Merge Request gemergt werden soll.",
|
||||
"mergeRequestTitle": "Merge Request mergen?",
|
||||
"pullRequestMergeMessage": "Auswählen, wie dieser Pull Request gemergt werden soll.",
|
||||
"retryLoadingIssues": "Issues aus {{source}} erneut laden",
|
||||
"retrying": "Erneuter Versuch…",
|
||||
"sourceFallback": "Die bevorzugte Issue-Quelle upstream ist für {{repo}} nicht verfügbar. Stattdessen wird origin verwendet.",
|
||||
"subIssueDataUnavailable": "Daten zu untergeordneten Issues sind für diesen Token nicht verfügbar.",
|
||||
"updateItemTitle": "Eintrag aktualisieren?"
|
||||
},
|
||||
"linearList": {
|
||||
"changeStatusFrom": "Status ändern (aktuell: {{status}})"
|
||||
},
|
||||
"linearViewControls": {
|
||||
"displayButton": "Anzeige",
|
||||
"groupLabel": "Gruppierung: {{group}}",
|
||||
"orderLabel": "Sortierung: {{order}}"
|
||||
},
|
||||
"listDisplayPickers": {
|
||||
"displayPropertiesTitle": "Angezeigte Eigenschaften",
|
||||
"linearGroupTitle": "Linear-Issues gruppieren",
|
||||
"linearOrderTitle": "Linear-Issues sortieren",
|
||||
"linearViewTitle": "Linear-Ansicht",
|
||||
"sortTasksTitle": "Aufgaben sortieren"
|
||||
},
|
||||
"listSurface": {
|
||||
"connectLinearButton": "Linear verbinden",
|
||||
"connectLinearMessage": "Dir zugewiesene Linear-Issues direkt unter „Aufgaben“ durchsuchen und die Arbeit daran starten.",
|
||||
"connectLinearTitle": "Linear-Konto verbinden",
|
||||
"jiraStatusFailed": "Jira-Status konnte nicht gelesen werden.",
|
||||
"updateDesktopMessage": "Diese mobile Aufgabenansicht benötigt eine neuere Version von Orca auf dem Desktop.",
|
||||
"updateDesktopTitle": "Orca-Desktop-App aktualisieren"
|
||||
},
|
||||
"options": {
|
||||
"all": "Alle",
|
||||
"assignedToMe": "Mir zugewiesen",
|
||||
"assignee": "Zuständige Person",
|
||||
"board": "Board",
|
||||
"boardDescription": "Gruppierte Spalten",
|
||||
"closedState": "Geschlossen",
|
||||
"completedState": "Abgeschlossen",
|
||||
"createdState": "Erstellt",
|
||||
"githubAssignedIssuesDescription": "Offene Issues, die dir zugewiesen sind",
|
||||
"githubDescription": "Issues und Pull Requests",
|
||||
"githubIssuesDescription": "GitHub-Issues",
|
||||
"githubOpenIssuesDescription": "Offene GitHub-Issues",
|
||||
"githubProjectsDescription": "Ansichten in GitHub Projects",
|
||||
"githubPullRequestsDescription": "GitHub-Pull-Requests",
|
||||
"gitlabAllDescription": "Alle GitLab-Status",
|
||||
"gitlabClosedDescription": "Geschlossene Issues und Merge Requests",
|
||||
"gitlabDescription": "Issues und Merge Requests",
|
||||
"gitlabMergedDescription": "Gemergte Merge Requests",
|
||||
"gitlabOpenDescription": "Offene Issues und Merge Requests",
|
||||
"identifier": "Kennung",
|
||||
"issues": "Issues",
|
||||
"jiraDescription": "Zugewiesene und gemeldete Issues",
|
||||
"labels": "Labels",
|
||||
"linearAllDescription": "Offene Issues aus verbundenen Arbeitsbereichen",
|
||||
"linearAssignedDescription": "Dir zugewiesene Issues",
|
||||
"linearCompletedDescription": "Kürzlich abgeschlossene Issues",
|
||||
"linearCreatedDescription": "Von dir erstellte Issues",
|
||||
"linearDescription": "Zugewiesene Issues und Team-Issues",
|
||||
"list": "Liste",
|
||||
"listDescription": "Kompakte Issue-Zeilen",
|
||||
"mergedState": "Gemergt",
|
||||
"mine": "Eigene",
|
||||
"myIssues": "Meine Issues",
|
||||
"myPullRequestsDescription": "Selbst erstellte Pull Requests",
|
||||
"myTodos": "Meine To-dos",
|
||||
"myTodosDescription": "Ausstehende GitLab-To-dos",
|
||||
"needsReview": "Review erforderlich",
|
||||
"noGrouping": "Keine Gruppierung",
|
||||
"openPullRequestsDescription": "Offene Pull Requests",
|
||||
"openState": "Offen",
|
||||
"priority": "Priorität",
|
||||
"projectMergeRequests": "Projekt-MRs",
|
||||
"projectMergeRequestsDescription": "Merge Requests und Issues nach Repository",
|
||||
"projects": "Projekte",
|
||||
"pullRequests": "PRs",
|
||||
"repository": "Repository",
|
||||
"repositorySortDescription": "Nach Repository gruppieren, dann neueste Aktivität zuerst",
|
||||
"reviewRequestsDescription": "Review-Anfragen, die dir zugewiesen sind",
|
||||
"status": "Status",
|
||||
"team": "Team",
|
||||
"updated": "Aktualisiert",
|
||||
"updatedSortDescription": "Neueste Aktivität zuerst"
|
||||
},
|
||||
"pickerProjection": {
|
||||
"allRepos": "Alle Repos",
|
||||
"allSites": "Alle Websites",
|
||||
"currentlyAscending": "Aktuell aufsteigend · für absteigende Sortierung tippen",
|
||||
"currentlyDescending": "Aktuell absteigend · für aufsteigende Sortierung tippen",
|
||||
"fieldAscending": "{{field}} aufsteigend",
|
||||
"fieldDescending": "{{field}} absteigend",
|
||||
"fields": "Felder",
|
||||
"repos_one": "{{count}} Repo",
|
||||
"repos_other": "{{count}} Repos",
|
||||
"selectTarget": "Ziel auswählen",
|
||||
"selectedFields": "{{selected}}/{{total}} Felder",
|
||||
"sortAscending": "Aufsteigend sortieren",
|
||||
"sources_one": "{{count}} Quelle",
|
||||
"sources_other": "{{count}} Quellen",
|
||||
"unsupportedLayout": "Layout auf Mobilgeräten nicht unterstützt",
|
||||
"updatedSort": "Aktualisiert",
|
||||
"usesFieldAscending": "Nach {{field}} aufsteigend sortiert",
|
||||
"usesFieldDescending": "Nach {{field}} absteigend sortiert",
|
||||
"usesGitHubRankOrder": "Verwendet die GitHub-Rangfolge",
|
||||
"viewNumber": "Ansicht #{{number}}",
|
||||
"viewOrder": "Reihenfolge der Ansicht"
|
||||
},
|
||||
"prFileDiff": {
|
||||
"commentOnLine": "Zeile {{line}} kommentieren",
|
||||
"commentPlaceholder": "Review-Kommentar hinzufügen",
|
||||
"noTextChanges": "Keine Textänderungen gefunden.",
|
||||
"showingDiffLines": "Die ersten {{limit}} von {{total}} Diff-Zeilen werden angezeigt."
|
||||
},
|
||||
"projectComments": {
|
||||
"comments_one": "{{count}} Kommentar",
|
||||
"comments_other": "{{count}} Kommentare",
|
||||
"discussion": "Diskussion",
|
||||
"editComment": "Kommentar bearbeiten",
|
||||
"noComments": "Keine Kommentare.",
|
||||
"reopenThread": "Thread erneut öffnen",
|
||||
"reply": "Antworten",
|
||||
"resolveThread": "Thread als erledigt markieren",
|
||||
"resolvedCommentBy": "Erledigter Kommentar von {{author}}",
|
||||
"resolvedThreadBy": "Erledigter Thread von {{author}}",
|
||||
"show": "Anzeigen"
|
||||
},
|
||||
"projectDetailDrawer": {
|
||||
"addRepositoryFromDesktop": "{{repository}} wurde Orca noch nicht hinzugefügt. Das Repository in der Desktop-App hinzufügen und anschließend die Aufgaben in der mobilen App aktualisieren.",
|
||||
"clearType": "Typ entfernen",
|
||||
"closeItem": "Eintrag schließen",
|
||||
"copyGitHubLink": "GitHub-Link kopieren",
|
||||
"copyRepository": "Repository kopieren",
|
||||
"createWorkspace": "Arbeitsbereich erstellen",
|
||||
"draftIssue": "Issue-Entwurf",
|
||||
"issue": "Issue",
|
||||
"issueType": "Issue-Typ",
|
||||
"loadingIssueTypes": "Issue-Typen werden geladen…",
|
||||
"mergePullRequest": "Pull Request mergen",
|
||||
"mergeRepositoryRequirement": "Für den Merge muss dieses Repository in Orca vorhanden sein.",
|
||||
"noIssueTypes": "Für dieses Repository sind keine Issue-Typen konfiguriert.",
|
||||
"noType": "Kein Typ",
|
||||
"openInGitHub": "In GitHub öffnen",
|
||||
"projectItem": "Projekteintrag",
|
||||
"projectSubtitle": "GitHub-Projekt · {{repository}}{{itemNumber}}",
|
||||
"pullRequest": "Pull Request",
|
||||
"reopenItem": "Eintrag erneut öffnen",
|
||||
"repositoryNotInOrca": "Repository nicht in Orca",
|
||||
"status": "Status",
|
||||
"type": "Typ",
|
||||
"workspaceCreationRequirement": "Arbeitsbereiche können nur aus GitHub-Issues und Pull Requests erstellt werden."
|
||||
},
|
||||
"projectFieldEditors": {
|
||||
"clearField": "Feld leeren",
|
||||
"completedIteration": "Abgeschlossen · {{startDate}} · {{duration}} T.",
|
||||
"datePlaceholder": "YYYY-MM-DD",
|
||||
"invalidDate": "Ein Datum im Format YYYY-MM-DD eingeben.",
|
||||
"invalidNumber": "Eine gültige Zahl eingeben.",
|
||||
"noIterations": "Keine Iterationen verfügbar.",
|
||||
"numberPlaceholder": "Zahl",
|
||||
"projectFields": "Projektfelder",
|
||||
"saveField": "Feld speichern",
|
||||
"textPlaceholder": "Text",
|
||||
"upcomingIteration": "Aktuell & anstehend · {{startDate}} · {{duration}} T."
|
||||
},
|
||||
"projectMetadataEditors": {
|
||||
"assignees": "Zuständige Personen",
|
||||
"description": "Beschreibung",
|
||||
"labels": "Labels",
|
||||
"loadingAssignees": "Zuständige Personen werden geladen…",
|
||||
"loadingLabels": "Labels werden geladen…",
|
||||
"noAssignableUsers": "Keine zuweisbaren Benutzer für dieses Repository gefunden.",
|
||||
"noDescription": "Keine Beschreibung.",
|
||||
"noLabels": "Keine Labels in diesem Repository.",
|
||||
"none": "Keine",
|
||||
"saveDescription": "Beschreibung speichern",
|
||||
"saveTitle": "Titel speichern",
|
||||
"title": "Titel"
|
||||
},
|
||||
"projectReviewPanels": {
|
||||
"binaryFile": "Binärdatei.",
|
||||
"changedFiles": "Geänderte Dateien",
|
||||
"checks": "Checks",
|
||||
"fileUnavailable": "Dateiinhalt nicht verfügbar.",
|
||||
"hideFile": "Ausblenden",
|
||||
"loadingReviewers": "Prüfer werden geladen…",
|
||||
"markUnviewed": "Als nicht angesehen markieren",
|
||||
"markViewed": "Als angesehen markieren",
|
||||
"noChecks": "Keine Checks gefunden.",
|
||||
"noReviewers": "Keine Prüfer angefordert.",
|
||||
"noSuggestions": "Keine Prüfervorschläge gefunden.",
|
||||
"requestReview": "Review anfordern",
|
||||
"requestReviewers": "Prüfer anfordern",
|
||||
"rerunAll": "Alle erneut ausführen",
|
||||
"rerunFailed": "Fehlgeschlagene erneut ausführen",
|
||||
"reviewers": "Prüfer",
|
||||
"viewFile": "Anzeigen"
|
||||
},
|
||||
"providerControls": {
|
||||
"myTodos": "Meine To-dos",
|
||||
"projectMergeRequests": "Projekt-MRs",
|
||||
"sort": "Sortierung: {{sortLabel}}"
|
||||
},
|
||||
"providerItemList": {
|
||||
"intoBranch": "in {{base}}",
|
||||
"nextPage": "Nächste Seite",
|
||||
"page": "Seite {{page}}",
|
||||
"pageOfTotal": "Seite {{page}} von {{total}}",
|
||||
"previousPage": "Vorherige Seite",
|
||||
"selectPage": "Seite auswählen, Seite {{page}}",
|
||||
"selectPageOfTotal": "Seite auswählen, Seite {{page}} von {{total}}"
|
||||
},
|
||||
"providerPickers": {
|
||||
"allRepositories": "Alle Repositorys",
|
||||
"githubView": "GitHub-Ansicht",
|
||||
"issueSources": "GitHub-Issue-Quellen",
|
||||
"issueSourcesDescription": "Für jedes Repository auswählen, ob upstream oder origin für das Abfragen und Erstellen von Issues verwendet wird.",
|
||||
"issues": "Issues",
|
||||
"noIssueSources": "Keine alternativen Issue-Quellen verfügbar.",
|
||||
"origin": "Origin",
|
||||
"pageHint": "Zu einer geladenen oder verfügbaren Ergebnisseite wechseln.",
|
||||
"pageLoaded": "Geladen",
|
||||
"pageNotLoaded": "Lädt ältere Ergebnisse",
|
||||
"pageNumber": "Seite {{page}}",
|
||||
"pages": "GitHub-Seiten",
|
||||
"pullRequests": "Pull Requests",
|
||||
"queryingSource": "Abfrage von {{source}}",
|
||||
"repoDescription": "Abzufragende Repositorys auswählen.",
|
||||
"repos": "Repositorys",
|
||||
"taskSource": "Aufgabenquelle",
|
||||
"upstream": "Upstream"
|
||||
},
|
||||
"providerViewProjection": {
|
||||
"all": "Alle",
|
||||
"allSites": "Alle Websites",
|
||||
"allTeams": "Alle Teams",
|
||||
"allWorkspaces": "Alle Arbeitsbereiche",
|
||||
"chooseProject": "Projekt auswählen",
|
||||
"default": "Standard",
|
||||
"defaultSubtitle": "{{subtitle}} · Standard",
|
||||
"issues": "Issues",
|
||||
"list": "Liste",
|
||||
"noGrouping": "Keine Gruppierung",
|
||||
"openState": "Offen",
|
||||
"priority": "Priorität",
|
||||
"projects": "Projekte",
|
||||
"pullRequests": "PRs",
|
||||
"teams_one": "{{count}} Team",
|
||||
"teams_other": "{{count}} Teams",
|
||||
"workspace": "Arbeitsbereich"
|
||||
},
|
||||
"reviewerLinear": {
|
||||
"issues": "Issues",
|
||||
"unassigned": "Nicht zugewiesen"
|
||||
},
|
||||
"screenChrome": {
|
||||
"connectLinear": "Linear verbinden",
|
||||
"newGitHubIssue": "Neues GitHub-Issue",
|
||||
"newLinearIssue": "Neues Linear-Issue",
|
||||
"refreshGitHub": "GitHub-Aufgaben aktualisieren",
|
||||
"refreshGitLab": "GitLab-Arbeitselemente aktualisieren",
|
||||
"refreshJira": "Jira-Issues aktualisieren",
|
||||
"refreshLinear": "Linear aktualisieren",
|
||||
"title": "Aufgaben"
|
||||
},
|
||||
"searchControl": {
|
||||
"jiraPlaceholder": "Jira JQL, z. B. project = ABC AND statusCategory != Done",
|
||||
"projectPlaceholder": "Projektansicht durchsuchen…",
|
||||
"providerPlaceholder": "{{provider}}-Aufgaben suchen…"
|
||||
},
|
||||
"smartSourceModes": {
|
||||
"allStates": "Alle",
|
||||
"branch": "Branch",
|
||||
"closedState": "Geschlossen",
|
||||
"mergedState": "Gemergt",
|
||||
"name": "Name",
|
||||
"openState": "Offen",
|
||||
"smart": "Intelligent"
|
||||
},
|
||||
"sparsePresetDraft": {
|
||||
"directoryRequired": "Mindestens ein Verzeichnis hinzufügen.",
|
||||
"repoRelativeDirectoriesRequired": "Verzeichnisse relativ zum Repo verwenden, keine Stammverzeichnisse, absoluten Pfade oder Pfadsegmente für übergeordnete Verzeichnisse."
|
||||
},
|
||||
"taskViewOptions": {
|
||||
"allSubtitle": "Ungelöste Issues auf den ausgewählten Sites",
|
||||
"assignedSubtitle": "Dir zugewiesene ungelöste Issues",
|
||||
"doneSubtitle": "Eigene kürzlich gelöste Issues",
|
||||
"noGitHubTasks": "Keine GitHub-Aufgaben",
|
||||
"noGitLabTasks": "Keine GitLab-Aufgaben",
|
||||
"noJiraTasks": "Keine Jira-Aufgaben",
|
||||
"noLinearTasks": "Keine Linear-Aufgaben",
|
||||
"reportedSubtitle": "Von dir gemeldete ungelöste Issues"
|
||||
},
|
||||
"tasksCreateDrawers": {
|
||||
"connect": "Verbinden",
|
||||
"connectLinearWorkspace": "Linear-Arbeitsbereich verbinden",
|
||||
"createIssue": "Issue erstellen",
|
||||
"createWorkspaceIn": "Arbeitsbereich im Repository erstellen",
|
||||
"description": "Beschreibung",
|
||||
"descriptionPlaceholder": "Kontext hinzufügen",
|
||||
"fileIn": "In {{slug}} erstellen",
|
||||
"issueSource": "Issue-Quelle",
|
||||
"keySecurityHint": "Der Schlüssel wird über den Schlüsselbund des Host-Betriebssystems verschlüsselt und lokal gespeichert.",
|
||||
"linearConnectSubtitle": "Persönlichen API-Schlüssel einfügen, um Issues aus diesem Arbeitsbereich anzuzeigen.",
|
||||
"linearSettingsLink": "Linear Settings / Security / New API key",
|
||||
"linearTeam": "Linear-Team",
|
||||
"linearTeamSubtitle": "Issue im ausgewählten Linear-Team erstellen.",
|
||||
"newIssueTitle": "Neues {{providerLabel}}-Issue",
|
||||
"origin": "Origin",
|
||||
"personalApiKey": "Persönlicher API-Schlüssel",
|
||||
"repository": "Repository",
|
||||
"repositorySubtitle": "Issue im ausgewählten Repository erstellen.",
|
||||
"team": "Team",
|
||||
"title": "Titel",
|
||||
"titlePlaceholder": "Aufgabentitel",
|
||||
"upstream": "Upstream"
|
||||
},
|
||||
"workspaceAgentSelection": {
|
||||
"blankTerminal": "Leeres Terminal"
|
||||
},
|
||||
"workspaceCreateDrawer": {
|
||||
"addRepository": "Vor dem Erstellen eines Linear-Arbeitsbereichs ein Git-Repository hinzufügen.",
|
||||
"advanced": "Erweitert",
|
||||
"agent": "Agent",
|
||||
"connect": "Verbinden",
|
||||
"connectFirst": "Zuerst Repository verbinden",
|
||||
"connectRepository": "Repository verbinden",
|
||||
"connecting": "Verbindung wird hergestellt…",
|
||||
"createFrom": "Aus {{branch}} erstellen",
|
||||
"defaultBranch": "Standard-Branch",
|
||||
"detectingAgents": "Agenten werden erkannt…",
|
||||
"optional": "[Optional]",
|
||||
"remoteRepository": "Entferntes Repository",
|
||||
"repository": "Repository",
|
||||
"repositoryNotFound": "Repository nicht gefunden.",
|
||||
"selectRepository": "Repository auswählen",
|
||||
"sshConnection": "SSH-Verbindung",
|
||||
"startFrom": "Ausgangspunkt",
|
||||
"title": "Arbeitsbereich erstellen",
|
||||
"workspaceName": "Arbeitsbereichsname"
|
||||
},
|
||||
"workspaceCreateProjection": {
|
||||
"nameAlreadyExists": "„{{name}}“ ist bereits vorhanden.",
|
||||
"nameRequired": "Ein Name ist erforderlich.",
|
||||
"nameTooLong": "Der Name darf höchstens 80 Zeichen lang sein.",
|
||||
"openShell": "Shell öffnen"
|
||||
},
|
||||
"workspaceOptionPickers": {
|
||||
"baseBranchSubtitle": "Vorhandenen Branch oder Ref auswählen.",
|
||||
"baseBranchTitle": "Ausgangspunkt",
|
||||
"branchName": "Branch-Name: {{name}}",
|
||||
"defaultBranch": "Standard-Branch",
|
||||
"defaultBranchSubtitle": "Konfigurierten Basis-Branch des Repositorys verwenden",
|
||||
"editPreset": "{{name}} bearbeiten",
|
||||
"fullCheckout": "Vollständiger Checkout",
|
||||
"fullCheckoutSubtitle": "Gesamtes Repository verwenden",
|
||||
"newPreset": "Voreinstellung erstellen",
|
||||
"noBranches": "Keine passenden Branches.",
|
||||
"searchBranches": "Branches suchen",
|
||||
"sparseCheckoutTitle": "Partieller Checkout"
|
||||
},
|
||||
"workspaceSshGate": {
|
||||
"authenticationFailed": "Authentifizierung fehlgeschlagen",
|
||||
"connected": "Verbunden",
|
||||
"connecting": "Verbindung wird hergestellt",
|
||||
"connectionFailed": "Verbindung fehlgeschlagen",
|
||||
"deployingRelay": "Relay wird bereitgestellt",
|
||||
"disconnected": "Getrennt",
|
||||
"reconnectFailed": "Erneute Verbindung fehlgeschlagen",
|
||||
"reconnecting": "Wird erneut verbunden"
|
||||
},
|
||||
"workspaceTrustDrawers": {
|
||||
"alwaysTrustAndRun": "Immer vertrauen und ausführen",
|
||||
"creating": "Wird erstellt…",
|
||||
"directoriesLabel": "Verzeichnisse",
|
||||
"directories_one": "{{count}} Verzeichnis",
|
||||
"directories_other": "{{count}} Verzeichnisse",
|
||||
"dontRun": "Nicht ausführen",
|
||||
"editSparsePreset": "Voreinstellung für partiellen Checkout bearbeiten",
|
||||
"nameLabel": "Name",
|
||||
"namePlaceholder": "Renderer-Oberfläche",
|
||||
"newSetupScript": "Neues Einrichtungsskript",
|
||||
"newSparsePreset": "Neue Voreinstellung für partiellen Checkout",
|
||||
"runHooks": "Hooks ausführen",
|
||||
"runSetupAndCreate": "Einrichten und erstellen",
|
||||
"runSetupTitle": "Einrichtung von {{name}} ausführen?",
|
||||
"setupChangedTitle": "Einrichtungsskript von {{name}} geändert",
|
||||
"setupScript": "Einrichtungsskript",
|
||||
"setupSubtitle": "Für {{name}} muss vor dem Erstellen dieses Arbeitsbereichs eine Einrichtungsoption gewählt werden.",
|
||||
"setupTitle": "Einrichtungsskript ausführen?",
|
||||
"skipSetupAndCreate": "Ohne Einrichtung erstellen",
|
||||
"trustFailed": "Das Einrichtungsskript konnte nicht als vertrauenswürdig markiert werden.",
|
||||
"trustSubtitle": "Die orca.yaml dieses Repositorys wird vor dem Start des Arbeitsbereichs auf deinem Rechner ausgeführt. Nur ausführen, wenn du diesem Repository vertraust."
|
||||
},
|
||||
"worktreeCreateRetry": {
|
||||
"createFailed": "Arbeitsbereich konnte nicht erstellt werden."
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
@@ -695,6 +695,10 @@
|
||||
"suppressWhileFocused": "Suppress while focused",
|
||||
"suppressWhileFocusedHint": "Skip alerts for the workspace open on this phone.",
|
||||
"footer": "Alert types follow each paired desktop’s notification settings. Notifications pause after 7 days without using this app; open it and reconnect to resume."
|
||||
},
|
||||
"desktopChannel": {
|
||||
"silentName": "Orca silent notifications",
|
||||
"name": "Desktop Notifications"
|
||||
}
|
||||
},
|
||||
"onboarding": {
|
||||
@@ -2622,7 +2626,11 @@
|
||||
"enterMessage": "Enter a commit message to commit"
|
||||
},
|
||||
"createPrAction": {
|
||||
"createReview": "Create {{titleLabel}}"
|
||||
"createReview": "Create {{titleLabel}}",
|
||||
"createPullRequest": "Create Pull Request",
|
||||
"statusUnavailable": "Review status unavailable",
|
||||
"checkingStatus": "Checking review status…",
|
||||
"providerUnavailable": "Review creation unavailable for this provider"
|
||||
},
|
||||
"prCreate": {
|
||||
"notReady": "This branch is not ready for a {{reviewLabel}} yet.",
|
||||
@@ -2698,7 +2706,29 @@
|
||||
"createPr": "Create PR",
|
||||
"pushAndCreatePr": "Push & Create PR",
|
||||
"switchBranch": "Switch branch",
|
||||
"commits": "Commits"
|
||||
"commits": "Commits",
|
||||
"committing": "Commit in progress.",
|
||||
"forcePushing": "Force push in progress.",
|
||||
"remoteOperationInProgress": "Remote operation in progress.",
|
||||
"waitForRemoteOperation": "Try again once the remote operation finishes.",
|
||||
"resolveConflicts": "Resolve conflicts before committing.",
|
||||
"commitStagedChanges": "Commit staged changes.",
|
||||
"enterCommitMessage": "Enter a commit message to commit.",
|
||||
"stageAllChanges": "Stage all changes.",
|
||||
"stageFileToCommit": "Stage at least one file to commit.",
|
||||
"checkoutBeforePublish": "Check out a branch before publishing commits.",
|
||||
"checkingReviewStatus": "Checking review status.",
|
||||
"reviewAlreadyMerged": "Nothing to commit. The review is already merged.",
|
||||
"publishToOrigin": "Publish this branch to origin.",
|
||||
"pushLinkedReview": "Push updates to the linked review branch.",
|
||||
"linkedReviewUnavailable": "The linked review branch is unavailable.",
|
||||
"forcePushWithLease": "Force push with lease to update the remote branch.",
|
||||
"syncCounts": "Pull {{behind}}, push {{ahead}}.",
|
||||
"pullCommits_one": "Pull {{count}} commit.",
|
||||
"pullCommits_other": "Pull {{count}} commits.",
|
||||
"pushCommits_one": "Push {{count}} commit.",
|
||||
"pushCommits_other": "Push {{count}} commits.",
|
||||
"upToDate": "Nothing to commit. Branch is up to date."
|
||||
},
|
||||
"dropdownCounts": {
|
||||
"pushCount_one": "Push {{count}} commit",
|
||||
@@ -2721,7 +2751,814 @@
|
||||
"titleUnpublishedForcePushCount_other": "Force push {{count}} branch commits with lease and set an upstream if needed."
|
||||
},
|
||||
"primaryAction": {
|
||||
"forcePushFromDesktop": "Force push this pull request's branch from desktop"
|
||||
"forcePushFromDesktop": "Force push this pull request's branch from desktop",
|
||||
"forcePush": "Force Push",
|
||||
"commit": "Commit",
|
||||
"stageAll": "Stage All",
|
||||
"push": "Push",
|
||||
"pull": "Pull",
|
||||
"sync": "Sync",
|
||||
"publishBranch": "Publish Branch"
|
||||
},
|
||||
"branchDiffPreviewDrawer": {
|
||||
"committedOnBranch": "Committed on branch",
|
||||
"closePreview": "Close committed diff preview",
|
||||
"loadFailed": "Unable to Load Diff",
|
||||
"truncated": "Diff truncated for mobile preview."
|
||||
},
|
||||
"commitFailurePanel": {
|
||||
"title": "Commit failed",
|
||||
"summary": "Commit failed.",
|
||||
"fixWithAi": "Fix commit failure with AI",
|
||||
"fix": "Fix",
|
||||
"hideFailureDetails": "Hide commit failure details",
|
||||
"showFailureDetails": "Show commit failure details",
|
||||
"hideDetails": "Hide details",
|
||||
"showDetails": "Show details"
|
||||
},
|
||||
"gitHistoryList": {
|
||||
"loadFailed": "Failed to load history",
|
||||
"loadFilesFailed": "Unable to load commit files",
|
||||
"retryFiles": "Retry commit files",
|
||||
"waitingForDesktop": "Waiting for desktop...",
|
||||
"noFileChanges": "No file changes",
|
||||
"noCommits": "No commits."
|
||||
},
|
||||
"branchCard": {
|
||||
"mergeState": "merge",
|
||||
"rebaseState": "rebase",
|
||||
"cherryPickState": "cherry-pick",
|
||||
"changedCount": "{{count}} changed",
|
||||
"stagedCount": "{{count}} staged",
|
||||
"branchCount": "{{count}} on branch"
|
||||
},
|
||||
"content": {
|
||||
"reconnecting": "Reconnecting to desktop...",
|
||||
"stageAll": "Stage All",
|
||||
"unstageAll": "Unstage All",
|
||||
"openActions": "Open source control actions",
|
||||
"emptyTitle": "No local changes",
|
||||
"emptyMessage": "Working tree is clean.",
|
||||
"commitMessageDisabled": "Commit message disabled. No staged files.",
|
||||
"noStagedFiles": "No staged files",
|
||||
"commitMessagePlaceholder": "Commit message",
|
||||
"regenerateHint": "Clear the message to regenerate.",
|
||||
"cancelGeneration": "Cancel commit message generation",
|
||||
"generateMessage": "Generate commit message with AI"
|
||||
},
|
||||
"fileList": {
|
||||
"committedSection": "Committed on Branch"
|
||||
},
|
||||
"fileRows": {
|
||||
"bothModified": "Both modified",
|
||||
"bothAdded": "Both added",
|
||||
"deletedByUs": "Deleted by us",
|
||||
"deletedByThem": "Deleted by them",
|
||||
"addedByUs": "Added by us",
|
||||
"addedByThem": "Added by them",
|
||||
"bothDeleted": "Both deleted",
|
||||
"unresolvedConflict": "Unresolved conflict",
|
||||
"openChangedFile": "Open changed file {{path}}",
|
||||
"renamedFrom": "from {{path}}",
|
||||
"unstageFile": "Unstage {{path}}",
|
||||
"stageFile": "Stage {{path}}",
|
||||
"discardFile": "Discard {{path}}",
|
||||
"committedSection": "Committed on Branch",
|
||||
"loadingCommitted": "Loading committed changes...",
|
||||
"committedUnavailable": "Committed changes unavailable.",
|
||||
"openCommittedChange": "Open committed change {{path}}"
|
||||
},
|
||||
"header": {
|
||||
"close": "Close source control",
|
||||
"backToSession": "Back to session",
|
||||
"title": "Source Control",
|
||||
"openNumberedPrWeb": "Open pull request #{{number}} on the web",
|
||||
"openPrWeb": "Open pull request on the web",
|
||||
"refresh": "Refresh source control"
|
||||
},
|
||||
"modals": {
|
||||
"actionsTitle": "Source Control",
|
||||
"discardTitle": "Discard Change",
|
||||
"discardConfirmMessage": "Discard changes to \"{{path}}\"? This cannot be undone.",
|
||||
"discardButton": "Discard",
|
||||
"switchBranchTitle": "Switch Branch",
|
||||
"currentBranch": "current",
|
||||
"prCreatedTitle": "Pull Request Created",
|
||||
"openPrWithWarning": "Open it in your browser?\n\n{{warning}}",
|
||||
"openPrMessage": "Open it in your browser?"
|
||||
},
|
||||
"panel": {
|
||||
"unavailableTitle": "Source Control Unavailable",
|
||||
"loadFailedTitle": "Unable to Load"
|
||||
},
|
||||
"prChip": {
|
||||
"loading": "Loading pull request…",
|
||||
"createPr": "Create pull request",
|
||||
"loadingLabel": "Loading pull request",
|
||||
"unavailableLabel": "Pull request unavailable: {{message}}",
|
||||
"openWithComments_one": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request.",
|
||||
"openWithComments_other": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request.",
|
||||
"openLabel": "Pull request #{{number}}, {{state}}, {{checks}}. Open pull request."
|
||||
},
|
||||
"hostedReviewCopy": {
|
||||
"updatingBranch": "Updating branch...",
|
||||
"stagingChanges": "Staging changes...",
|
||||
"generatingCommitMessage": "Generating commit message...",
|
||||
"committingChanges": "Committing changes...",
|
||||
"publishingBranch": "Publishing branch...",
|
||||
"pushingCommits": "Pushing commits...",
|
||||
"forcePushing": "Force pushing with lease...",
|
||||
"creatingReview": "Creating review..."
|
||||
},
|
||||
"branchBaseRef": {
|
||||
"resolveFailed": "Unable to resolve branch base"
|
||||
},
|
||||
"branchCompareOutcome": {
|
||||
"baseBranchUnavailable": "Unable to resolve the base branch for comparison.",
|
||||
"loadFailed": "Unable to load committed changes"
|
||||
},
|
||||
"branchCompare": {
|
||||
"sectionTitle": "Committed on Branch",
|
||||
"summary": "{{files}} - vs {{baseRef}}",
|
||||
"summaryWithCommits": "{{files}} - {{commits}} - vs {{baseRef}}",
|
||||
"files_one": "{{count}} file",
|
||||
"files_other": "{{count}} files",
|
||||
"commits_one": "{{count}} commit",
|
||||
"commits_other": "{{count}} commits"
|
||||
},
|
||||
"commitMessageAi": {
|
||||
"generateFailed": "Failed to generate commit message"
|
||||
},
|
||||
"gitHistory": {
|
||||
"justNow": "just now",
|
||||
"minutes_one": "{{count}}m",
|
||||
"minutes_other": "{{count}}m",
|
||||
"hours_one": "{{count}}h",
|
||||
"hours_other": "{{count}}h",
|
||||
"days_one": "{{count}}d",
|
||||
"days_other": "{{count}}d",
|
||||
"months_one": "{{count}}mo",
|
||||
"months_other": "{{count}}mo",
|
||||
"years_one": "{{count}}y",
|
||||
"years_other": "{{count}}y",
|
||||
"noCommitMessage": "(no commit message)",
|
||||
"loadFailed": "Failed to load commit history"
|
||||
},
|
||||
"gitStatus": {
|
||||
"conflicts": "Conflicts",
|
||||
"changes": "Changes",
|
||||
"stagedChanges": "Staged Changes"
|
||||
},
|
||||
"hostedReviewCreateIntent": {
|
||||
"resolveConflicts": "Resolve conflicts before creating a pull request.",
|
||||
"branchChanged": "Branch changed while preparing the pull request.",
|
||||
"resolveOrStageChanges": "Resolve or stage changes before creating a pull request.",
|
||||
"generateMessageFailed": "Could not generate a commit message. Add one in Source Control, then retry.",
|
||||
"reviewCommitMessage": "Review the commit message, then retry Create PR."
|
||||
},
|
||||
"hostedReviewGitPreparation": {
|
||||
"refreshFailed": "Unable to refresh source control",
|
||||
"updateBranchFailed": "Could not update the remote branch. Retry Create PR.",
|
||||
"stageFailed": "Failed to stage changes",
|
||||
"commitFailed": "Commit failed"
|
||||
},
|
||||
"hostedReviewRemotePrerequisite": {
|
||||
"publishFailed": "Failed to publish branch",
|
||||
"pushFailed": "Failed to push commits",
|
||||
"forcePushFailed": "Failed to force push with lease"
|
||||
},
|
||||
"hostedReviewService": {
|
||||
"pushBeforeCreateFailed": "Push failed. Resolve the push error, then try again.",
|
||||
"createFailed": "Failed to create pull request"
|
||||
},
|
||||
"prLink": {
|
||||
"updatePullRequestFailed": "Failed to update linked pull request",
|
||||
"updateReviewFailed": "Failed to update linked review"
|
||||
},
|
||||
"conflictAbort": {
|
||||
"aborting": "Aborting…",
|
||||
"abortMerge": "Abort merge",
|
||||
"abortRebase": "Abort rebase",
|
||||
"abortOperation": "Abort {{operation}}"
|
||||
},
|
||||
"hubTab": {
|
||||
"changes": "Changes",
|
||||
"pullRequest": "Pull Request",
|
||||
"commits": "Commits"
|
||||
},
|
||||
"screenState": {
|
||||
"noBranch": "No branch"
|
||||
},
|
||||
"useMobileCommitFailureRecovery": {
|
||||
"waitingForDesktop": "Waiting for desktop...",
|
||||
"launchFailed": "Failed to launch agent"
|
||||
},
|
||||
"useMobileCommitMessageGeneration": {
|
||||
"generateFailed": "Failed to generate commit message"
|
||||
},
|
||||
"useMobileCreatePrRunner": {
|
||||
"branchRequired": "Check out a branch before creating a pull request."
|
||||
},
|
||||
"useMobileGitRequests": {
|
||||
"waitingForDesktop": "Waiting for desktop...",
|
||||
"actionFailed": "Source control action failed",
|
||||
"commitFailed": "Commit failed",
|
||||
"branchUnavailable": "Branch status unavailable"
|
||||
},
|
||||
"actionSheetRunners": {
|
||||
"waitingForDesktop": "Waiting for desktop...",
|
||||
"noBaseBranch": "No base branch to rebase onto"
|
||||
},
|
||||
"commitRunners": {
|
||||
"commitFailed": "Commit failed",
|
||||
"actionFailed": "Source control action failed"
|
||||
},
|
||||
"loaders": {
|
||||
"connectingToDesktop": "Connecting to desktop...",
|
||||
"waitingForDesktop": "Waiting for desktop...",
|
||||
"updateDesktop": "Update Orca desktop to use Source Control on mobile.",
|
||||
"loadFailed": "Unable to load source control"
|
||||
},
|
||||
"openers": {
|
||||
"waitingForDesktop": "Waiting for desktop...",
|
||||
"openDiffFailed": "Unable to open diff",
|
||||
"tabNotReady": "The file opened, but its tab isn't ready yet. Try again."
|
||||
},
|
||||
"runners": {
|
||||
"actionFailed": "Source control action failed"
|
||||
},
|
||||
"state": {
|
||||
"syncStatus": "{{ahead}} ahead, {{behind}} behind",
|
||||
"noUpstream": "No upstream"
|
||||
}
|
||||
},
|
||||
"newWorkspace": {
|
||||
"hostPicker": {
|
||||
"title": "Create Workspace On"
|
||||
},
|
||||
"loadingDrawer": {
|
||||
"loading": "Loading",
|
||||
"downloading": "Downloading",
|
||||
"downloadProgress": "Downloading… {{progress}}"
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"legacySurface": {
|
||||
"sourceFallback": "Preferred issue source upstream is unavailable for {{repo}}. Using origin.",
|
||||
"loadIssuesFailed": "Couldn't load issues from {{source}}.",
|
||||
"retryLoadingIssues": "Retry loading issues from {{source}}",
|
||||
"retrying": "Retrying...",
|
||||
"subIssueDataUnavailable": "Sub-issue data is unavailable for your token.",
|
||||
"mergeMethodTitle": "Merge method",
|
||||
"pullRequestMergeMessage": "Choose how this pull request should be merged.",
|
||||
"mergeRequestMergeMessage": "Choose how this merge request should be merged.",
|
||||
"mergeAction": "Merge",
|
||||
"mergeRequestTitle": "Merge Request",
|
||||
"mergePullRequestTitle": "Merge Pull Request",
|
||||
"updateItemTitle": "Update Item"
|
||||
},
|
||||
"prFileDiff": {
|
||||
"noTextChanges": "No text changes found.",
|
||||
"showingDiffLines": "Showing first {{limit}} of {{total}} diff lines.",
|
||||
"commentPlaceholder": "Add review comment",
|
||||
"commentOnLine": "Comment on line {{line}}"
|
||||
},
|
||||
"smartSourceModes": {
|
||||
"smart": "Smart",
|
||||
"branch": "Branch",
|
||||
"name": "Name",
|
||||
"openState": "Open",
|
||||
"mergedState": "Merged",
|
||||
"closedState": "Closed",
|
||||
"allStates": "All"
|
||||
},
|
||||
"taskViewOptions": {
|
||||
"noGitHubTasks": "No GitHub tasks",
|
||||
"noGitLabTasks": "No GitLab tasks",
|
||||
"noLinearTasks": "No Linear tasks",
|
||||
"noJiraTasks": "No Jira tasks",
|
||||
"assignedSubtitle": "Unresolved issues assigned to you",
|
||||
"reportedSubtitle": "Unresolved issues you reported",
|
||||
"allSubtitle": "Unresolved issues across the selected sites",
|
||||
"doneSubtitle": "Your recently resolved issues"
|
||||
},
|
||||
"tasksCreateDrawers": {
|
||||
"newIssueTitle": "New {{providerLabel}} Issue",
|
||||
"repositorySubtitle": "Create an issue in the selected repository.",
|
||||
"linearTeamSubtitle": "Create an issue in the selected Linear team.",
|
||||
"repository": "Repository",
|
||||
"team": "Team",
|
||||
"issueSource": "Issue source",
|
||||
"fileIn": "File in {{slug}}",
|
||||
"upstream": "Upstream",
|
||||
"origin": "Origin",
|
||||
"title": "Title",
|
||||
"titlePlaceholder": "Task title",
|
||||
"description": "Description",
|
||||
"descriptionPlaceholder": "Add context",
|
||||
"createIssue": "Create Issue",
|
||||
"linearTeam": "Linear Team",
|
||||
"connectLinearWorkspace": "Connect Linear workspace",
|
||||
"linearConnectSubtitle": "Paste a Personal API key to browse issues from that workspace.",
|
||||
"personalApiKey": "Personal API key",
|
||||
"linearSettingsLink": "Linear Settings / Security / New API key",
|
||||
"keySecurityHint": "Your key is encrypted via the host OS keychain and stored locally.",
|
||||
"connect": "Connect",
|
||||
"createWorkspaceIn": "Create Workspace In"
|
||||
},
|
||||
"filterPickers": {
|
||||
"fieldsTitle": "Project Fields",
|
||||
"fieldsSubtitle": "Choose which Project fields appear on item cards.",
|
||||
"noFields": "This view has no extra fields to show.",
|
||||
"fieldShown": "Shown on cards",
|
||||
"fieldHidden": "Hidden from cards",
|
||||
"gitlabView": "GitLab View",
|
||||
"gitlabFilter": "GitLab Filter",
|
||||
"linearFilter": "Linear Filter",
|
||||
"linearWorkspace": "Linear Workspace",
|
||||
"switchWorkspaceFailed": "Failed to switch workspace",
|
||||
"teamsTitle": "Linear Teams",
|
||||
"teamsSubtitle": "Choose which teams appear in Tasks.",
|
||||
"allTeams": "All teams",
|
||||
"teams_one": "{{count}} team",
|
||||
"teams_other": "{{count}} teams",
|
||||
"changeStatus": "Change Status",
|
||||
"linearIssue": "Linear issue",
|
||||
"loadingStates": "Loading states...",
|
||||
"noStates": "No states available",
|
||||
"jiraFilter": "Jira Filter",
|
||||
"jiraSite": "Jira Site"
|
||||
},
|
||||
"githubProjectList": {
|
||||
"chooseProject": "Choose a GitHub project",
|
||||
"browseProjects": "Browse projects",
|
||||
"noItems": "No project items",
|
||||
"items": "Items",
|
||||
"pullRequestSubtitle": "Pull request · {{repository}}{{number}}",
|
||||
"issueSubtitle": "Issue · {{repository}}{{number}}",
|
||||
"itemSubtitle": "Project item · {{repository}}{{number}}",
|
||||
"emptyField": "Empty",
|
||||
"moreFields_one": "+{{count}} field",
|
||||
"moreFields_other": "+{{count}} fields"
|
||||
},
|
||||
"githubProjectPickers": {
|
||||
"title": "GitHub Projects",
|
||||
"subtitle": "Choose a project view for the Tasks page.",
|
||||
"searchProjects": "Search projects",
|
||||
"addPlaceholder": "Add by URL or owner/number",
|
||||
"adding": "Adding...",
|
||||
"add": "Add",
|
||||
"ownerLoadFailed": "Couldn't load projects from {{owner}}.",
|
||||
"organizationsLoadFailed": "Some organizations didn't load ({{count}}).",
|
||||
"addByUrlHint": "Use Add by URL to reach missing projects.",
|
||||
"organizationsError": "orgs: {{message}}",
|
||||
"loadFailed": "Failed to load projects",
|
||||
"noProjects": "No projects loaded",
|
||||
"retryHint": "Tap to retry.",
|
||||
"pinned": "Pinned",
|
||||
"recent": "Recent",
|
||||
"pin": "Pin",
|
||||
"browseLoading": "Browse all (loading...)",
|
||||
"browseAll": "Browse all",
|
||||
"noMatches": "No matching projects.",
|
||||
"noMoreProjects": "No more projects.",
|
||||
"chooseView": "Choose Project View",
|
||||
"view": "Project View",
|
||||
"unsupportedLayout": "Orca doesn't support this GitHub Project layout yet.",
|
||||
"sort": "Project Sort"
|
||||
},
|
||||
"githubViewControls": {
|
||||
"source": "Source: {{source}}",
|
||||
"sort": "Sort: {{sort}}",
|
||||
"fields": "Fields: {{fields}}",
|
||||
"openView": "Open view in GitHub"
|
||||
},
|
||||
"itemActions": {
|
||||
"creating": "Creating...",
|
||||
"createWorkspace": "Create Workspace",
|
||||
"copyLinearLink": "Copy Linear link",
|
||||
"copyGitHubLink": "Copy GitHub link",
|
||||
"mergePullRequest": "Merge pull request",
|
||||
"mergeConflicts": "GitHub reports merge conflicts.",
|
||||
"mergeMergeRequest": "Merge merge request",
|
||||
"changeStatus": "Change status"
|
||||
},
|
||||
"itemDetailContent": {
|
||||
"pipelineJobs_one": "{{count}} jobs",
|
||||
"pipelineJobs_other": "{{count}} jobs",
|
||||
"type": "Type",
|
||||
"status": "Status",
|
||||
"assignee": "Assignee",
|
||||
"project": "Project",
|
||||
"assignees": "Assignees",
|
||||
"description": "Description",
|
||||
"checks": "Checks",
|
||||
"rerunFailed": "Rerun failed",
|
||||
"rerunAll": "Rerun all",
|
||||
"noChecks": "No checks found.",
|
||||
"pipeline": "Pipeline",
|
||||
"none": "None",
|
||||
"noPipelineRuns": "No pipeline runs for this MR.",
|
||||
"subIssues": "Sub-issues",
|
||||
"noSubIssues": "No sub-issues.",
|
||||
"subIssueTitle": "Sub-issue title",
|
||||
"addSubIssue": "Add sub-issue",
|
||||
"discussion": "Discussion",
|
||||
"noComments": "No comments."
|
||||
},
|
||||
"itemDetailDrawer": {
|
||||
"refreshDetails": "Refresh details"
|
||||
},
|
||||
"itemFieldEditors": {
|
||||
"title": "Title",
|
||||
"saveTitle": "Save title",
|
||||
"labels": "Labels",
|
||||
"none": "None",
|
||||
"loadingLabels": "Loading labels...",
|
||||
"noLabels": "No labels in this repository.",
|
||||
"addLabels": "Add labels, comma separated",
|
||||
"removeLabels": "Remove labels, comma separated",
|
||||
"updateLabels": "Update labels",
|
||||
"assignees": "Assignees",
|
||||
"loadingAssignees": "Loading assignees...",
|
||||
"noAssignableUsers": "No assignable users found for this repository.",
|
||||
"addUsernames": "Add usernames, comma separated",
|
||||
"removeUsernames": "Remove usernames, comma separated",
|
||||
"updateAssignees": "Update assignees"
|
||||
},
|
||||
"itemReviewSections": {
|
||||
"descriptionPlaceholder": "Description",
|
||||
"saveDescription": "Save description",
|
||||
"noDescription": "No description.",
|
||||
"reviewersTitle": "Reviewers",
|
||||
"noReviewersRequested": "No reviewers requested.",
|
||||
"loadingReviewers": "Loading reviewers...",
|
||||
"noReviewerSuggestions": "No reviewer suggestions found.",
|
||||
"reviewersPlaceholder": "Request reviewers",
|
||||
"requestReview": "Request review",
|
||||
"changedFilesTitle": "Changed files",
|
||||
"hideFile": "Hide",
|
||||
"viewFile": "View",
|
||||
"markUnviewed": "Mark unviewed",
|
||||
"markViewed": "Mark viewed",
|
||||
"binaryFile": "Binary file.",
|
||||
"fileContentsUnavailable": "File contents unavailable."
|
||||
},
|
||||
"linearList": {
|
||||
"changeStatusFrom": "Change status from {{status}}"
|
||||
},
|
||||
"linearViewControls": {
|
||||
"groupLabel": "Group: {{group}}",
|
||||
"orderLabel": "Order: {{order}}",
|
||||
"displayButton": "Display"
|
||||
},
|
||||
"listDisplayPickers": {
|
||||
"linearViewTitle": "Linear View",
|
||||
"linearGroupTitle": "Group Linear Issues",
|
||||
"linearOrderTitle": "Order Linear Issues",
|
||||
"displayPropertiesTitle": "Display Properties",
|
||||
"sortTasksTitle": "Sort Tasks"
|
||||
},
|
||||
"listSurface": {
|
||||
"updateDesktopTitle": "Update Orca desktop",
|
||||
"updateDesktopMessage": "This mobile Tasks view needs a newer desktop runtime.",
|
||||
"jiraStatusFailed": "Failed to read Jira status",
|
||||
"connectLinearTitle": "Connect your Linear account",
|
||||
"connectLinearMessage": "Browse and start work on your assigned Linear issues directly from Tasks.",
|
||||
"connectLinearButton": "Connect Linear"
|
||||
},
|
||||
"options": {
|
||||
"githubDescription": "Issues and pull requests",
|
||||
"gitlabDescription": "Issues and merge requests",
|
||||
"linearDescription": "Assigned and team issues",
|
||||
"jiraDescription": "Assigned and reported issues",
|
||||
"openState": "Open",
|
||||
"gitlabOpenDescription": "Open issues and merge requests",
|
||||
"mergedState": "Merged",
|
||||
"gitlabMergedDescription": "Merged merge requests",
|
||||
"closedState": "Closed",
|
||||
"gitlabClosedDescription": "Closed issues and merge requests",
|
||||
"all": "All",
|
||||
"gitlabAllDescription": "Any GitLab state",
|
||||
"linearAllDescription": "Open issues across connected workspaces",
|
||||
"myIssues": "My Issues",
|
||||
"linearAssignedDescription": "Issues assigned to you",
|
||||
"createdState": "Created",
|
||||
"linearCreatedDescription": "Issues created by you",
|
||||
"completedState": "Completed",
|
||||
"linearCompletedDescription": "Recently completed issues",
|
||||
"list": "List",
|
||||
"listDescription": "Compact issue rows",
|
||||
"board": "Board",
|
||||
"boardDescription": "Grouped columns",
|
||||
"noGrouping": "No grouping",
|
||||
"status": "Status",
|
||||
"assignee": "Assignee",
|
||||
"priority": "Priority",
|
||||
"team": "Team",
|
||||
"updated": "Updated",
|
||||
"identifier": "Identifier",
|
||||
"labels": "Labels",
|
||||
"issues": "Issues",
|
||||
"githubIssuesDescription": "GitHub issues",
|
||||
"pullRequests": "PRs",
|
||||
"githubPullRequestsDescription": "GitHub pull requests",
|
||||
"projects": "Projects",
|
||||
"githubProjectsDescription": "GitHub Projects views",
|
||||
"githubOpenIssuesDescription": "Open GitHub issues",
|
||||
"assignedToMe": "Assigned to me",
|
||||
"githubAssignedIssuesDescription": "Open issues assigned to you",
|
||||
"openPullRequestsDescription": "Open pull requests",
|
||||
"mine": "Mine",
|
||||
"myPullRequestsDescription": "Pull requests authored by you",
|
||||
"needsReview": "Needs review",
|
||||
"reviewRequestsDescription": "Review requests assigned to you",
|
||||
"projectMergeRequests": "Project MRs",
|
||||
"projectMergeRequestsDescription": "Merge requests and issues by repository",
|
||||
"myTodos": "My Todos",
|
||||
"myTodosDescription": "Pending GitLab todos",
|
||||
"updatedSortDescription": "Newest activity first",
|
||||
"repository": "Repository",
|
||||
"repositorySortDescription": "Group by repository, then newest activity"
|
||||
},
|
||||
"projectComments": {
|
||||
"comments_one": "{{count}} comment",
|
||||
"comments_other": "{{count}} comments",
|
||||
"discussion": "Discussion",
|
||||
"noComments": "No comments.",
|
||||
"resolvedThreadBy": "Resolved thread by {{author}}",
|
||||
"resolvedCommentBy": "Resolved comment by {{author}}",
|
||||
"show": "Show",
|
||||
"editComment": "Edit comment",
|
||||
"reopenThread": "Reopen thread",
|
||||
"resolveThread": "Resolve thread",
|
||||
"reply": "Reply"
|
||||
},
|
||||
"projectDetailDrawer": {
|
||||
"repositoryNotInOrca": "Repository not in Orca",
|
||||
"addRepositoryFromDesktop": "{{repository}} is not added to Orca. Add this repository from the desktop app, then refresh mobile Tasks.",
|
||||
"openInGitHub": "Open in GitHub",
|
||||
"copyRepository": "Copy repository",
|
||||
"projectSubtitle": "GitHub Project · {{repository}}{{itemNumber}}",
|
||||
"type": "Type",
|
||||
"pullRequest": "Pull request",
|
||||
"issue": "Issue",
|
||||
"draftIssue": "Draft issue",
|
||||
"projectItem": "Project item",
|
||||
"status": "Status",
|
||||
"issueType": "Issue type",
|
||||
"noType": "No type",
|
||||
"loadingIssueTypes": "Loading issue types...",
|
||||
"noIssueTypes": "No issue types configured for this repository.",
|
||||
"clearType": "Clear type",
|
||||
"createWorkspace": "Create Workspace",
|
||||
"workspaceCreationRequirement": "Workspaces can only be created from GitHub issues and pull requests.",
|
||||
"copyGitHubLink": "Copy GitHub link",
|
||||
"reopenItem": "Reopen item",
|
||||
"closeItem": "Close item",
|
||||
"mergePullRequest": "Merge pull request",
|
||||
"mergeRepositoryRequirement": "Merge requires this repository in Orca."
|
||||
},
|
||||
"projectFieldEditors": {
|
||||
"projectFields": "Project fields",
|
||||
"invalidNumber": "Enter a valid number.",
|
||||
"invalidDate": "Enter a date as YYYY-MM-DD.",
|
||||
"noIterations": "No iterations available.",
|
||||
"completedIteration": "Completed · {{startDate}} · {{duration}}d",
|
||||
"upcomingIteration": "Current & upcoming · {{startDate}} · {{duration}}d",
|
||||
"datePlaceholder": "YYYY-MM-DD",
|
||||
"numberPlaceholder": "Number",
|
||||
"textPlaceholder": "Text",
|
||||
"saveField": "Save field",
|
||||
"clearField": "Clear field"
|
||||
},
|
||||
"projectMetadataEditors": {
|
||||
"labels": "Labels",
|
||||
"none": "None",
|
||||
"loadingLabels": "Loading labels...",
|
||||
"noLabels": "No labels in this repository.",
|
||||
"assignees": "Assignees",
|
||||
"loadingAssignees": "Loading assignees...",
|
||||
"noAssignableUsers": "No assignable users found for this repository.",
|
||||
"title": "Title",
|
||||
"saveTitle": "Save title",
|
||||
"description": "Description",
|
||||
"saveDescription": "Save description",
|
||||
"noDescription": "No description."
|
||||
},
|
||||
"projectReviewPanels": {
|
||||
"reviewers": "Reviewers",
|
||||
"noReviewers": "No reviewers requested.",
|
||||
"loadingReviewers": "Loading reviewers...",
|
||||
"noSuggestions": "No reviewer suggestions found.",
|
||||
"requestReviewers": "Request reviewers",
|
||||
"requestReview": "Request review",
|
||||
"checks": "Checks",
|
||||
"rerunFailed": "Rerun failed",
|
||||
"rerunAll": "Rerun all",
|
||||
"noChecks": "No checks found.",
|
||||
"changedFiles": "Changed files",
|
||||
"hideFile": "Hide",
|
||||
"viewFile": "View",
|
||||
"markUnviewed": "Mark unviewed",
|
||||
"markViewed": "Mark viewed",
|
||||
"binaryFile": "Binary file.",
|
||||
"fileUnavailable": "File contents unavailable."
|
||||
},
|
||||
"providerControls": {
|
||||
"projectMergeRequests": "Project MRs",
|
||||
"myTodos": "My Todos",
|
||||
"sort": "Sort: {{sortLabel}}"
|
||||
},
|
||||
"providerItemList": {
|
||||
"previousPage": "Previous page",
|
||||
"selectPage": "Select page, Page {{page}}",
|
||||
"selectPageOfTotal": "Select page, Page {{page}} of {{total}}",
|
||||
"page": "Page {{page}}",
|
||||
"pageOfTotal": "Page {{page}} of {{total}}",
|
||||
"nextPage": "Next page",
|
||||
"intoBranch": "into {{base}}"
|
||||
},
|
||||
"providerPickers": {
|
||||
"taskSource": "Task Source",
|
||||
"repos": "Repositories",
|
||||
"repoDescription": "Choose which repositories to query.",
|
||||
"allRepositories": "All repositories",
|
||||
"issueSources": "GitHub Issue Sources",
|
||||
"issueSourcesDescription": "Choose whether each repository queries and creates work from upstream or origin.",
|
||||
"noIssueSources": "No alternate issue sources available.",
|
||||
"queryingSource": "Querying {{source}}",
|
||||
"upstream": "Upstream",
|
||||
"origin": "Origin",
|
||||
"githubView": "GitHub View",
|
||||
"pullRequests": "Pull Requests",
|
||||
"issues": "Issues",
|
||||
"pages": "GitHub Pages",
|
||||
"pageHint": "Jump to a loaded or available result page.",
|
||||
"pageNumber": "Page {{page}}",
|
||||
"pageLoaded": "Loaded",
|
||||
"pageNotLoaded": "Loads older results"
|
||||
},
|
||||
"reviewerLinear": {
|
||||
"unassigned": "Unassigned",
|
||||
"issues": "Issues"
|
||||
},
|
||||
"screenChrome": {
|
||||
"refreshGitHub": "Refresh GitHub work",
|
||||
"refreshGitLab": "Refresh GitLab work items",
|
||||
"refreshLinear": "Refresh Linear",
|
||||
"refreshJira": "Refresh Jira issues",
|
||||
"title": "Tasks",
|
||||
"newGitHubIssue": "New GitHub issue",
|
||||
"newLinearIssue": "New Linear issue",
|
||||
"connectLinear": "Connect Linear"
|
||||
},
|
||||
"searchControl": {
|
||||
"projectPlaceholder": "Search project view...",
|
||||
"jiraPlaceholder": "Jira JQL, e.g. project = ABC AND statusCategory != Done",
|
||||
"providerPlaceholder": "Search {{provider}} tasks..."
|
||||
},
|
||||
"workspaceCreateDrawer": {
|
||||
"title": "Create Workspace",
|
||||
"repository": "Repository",
|
||||
"selectRepository": "Select a repository",
|
||||
"sshConnection": "SSH Connection",
|
||||
"remoteRepository": "Remote repository",
|
||||
"connecting": "Connecting...",
|
||||
"connect": "Connect",
|
||||
"workspaceName": "Workspace Name",
|
||||
"optional": "[Optional]",
|
||||
"agent": "Agent",
|
||||
"connectFirst": "Connect repository first",
|
||||
"detectingAgents": "Detecting agents...",
|
||||
"advanced": "Advanced",
|
||||
"startFrom": "Start from",
|
||||
"defaultBranch": "Default branch",
|
||||
"createFrom": "Create from {{branch}}",
|
||||
"addRepository": "Add a Git repository before creating a Linear workspace.",
|
||||
"repositoryNotFound": "Repository not found.",
|
||||
"connectRepository": "Connect Repository"
|
||||
},
|
||||
"workspaceOptionPickers": {
|
||||
"baseBranchTitle": "Start From",
|
||||
"baseBranchSubtitle": "Pick an existing branch or ref.",
|
||||
"searchBranches": "Search branches",
|
||||
"defaultBranch": "Default branch",
|
||||
"defaultBranchSubtitle": "Use this repository's configured base",
|
||||
"noBranches": "No branches match.",
|
||||
"branchName": "Branch name: {{name}}",
|
||||
"sparseCheckoutTitle": "Sparse Checkout",
|
||||
"fullCheckout": "Full checkout",
|
||||
"fullCheckoutSubtitle": "Use the whole repository",
|
||||
"editPreset": "Edit {{name}}",
|
||||
"newPreset": "New preset"
|
||||
},
|
||||
"workspaceTrustDrawers": {
|
||||
"newSparsePreset": "New Sparse Preset",
|
||||
"editSparsePreset": "Edit Sparse Preset",
|
||||
"nameLabel": "Name",
|
||||
"namePlaceholder": "Renderer UI",
|
||||
"directoriesLabel": "Directories",
|
||||
"directories_one": "{{count}} directory",
|
||||
"directories_other": "{{count}} directories",
|
||||
"setupTitle": "Run Setup Script?",
|
||||
"setupSubtitle": "{{name}} requires a setup choice before creating this workspace.",
|
||||
"creating": "Creating...",
|
||||
"runSetupAndCreate": "Run setup and create",
|
||||
"skipSetupAndCreate": "Skip setup and create",
|
||||
"setupChangedTitle": "{{name}}'s setup script changed",
|
||||
"runSetupTitle": "Run setup from {{name}}?",
|
||||
"trustSubtitle": "This repository's orca.yaml runs on your machine before the workspace starts. Only run it if you trust this repository.",
|
||||
"newSetupScript": "New setup script",
|
||||
"setupScript": "Setup script",
|
||||
"trustFailed": "Failed to trust setup script.",
|
||||
"runHooks": "Run hooks",
|
||||
"alwaysTrustAndRun": "Always trust and run",
|
||||
"dontRun": "Don't run"
|
||||
},
|
||||
"sparsePresetDraft": {
|
||||
"repoRelativeDirectoriesRequired": "Use repo-relative directories, not root, absolute paths, or parent segments.",
|
||||
"directoryRequired": "Add at least one directory."
|
||||
},
|
||||
"composerSource": {
|
||||
"baseFailed": "Failed to resolve base branch.",
|
||||
"forkPushWarning": "This PR has \"Allow edits from maintainers\" off; pushing to the fork may be rejected by GitHub."
|
||||
},
|
||||
"detailCommentRenderers": {
|
||||
"commentPlaceholder": "Add a comment",
|
||||
"sendComment": "Send comment",
|
||||
"reopenThread": "Reopen thread",
|
||||
"resolveThread": "Resolve thread",
|
||||
"reply": "Reply",
|
||||
"comments_one": "{{count}} comment",
|
||||
"comments_other": "{{count}} comments",
|
||||
"resolvedThreadBy": "Resolved thread by {{author}}",
|
||||
"resolvedCommentBy": "Resolved comment by {{author}}",
|
||||
"show": "Show"
|
||||
},
|
||||
"pickerProjection": {
|
||||
"sources_one": "{{count}} source",
|
||||
"sources_other": "{{count}} sources",
|
||||
"repos_one": "{{count}} repo",
|
||||
"repos_other": "{{count}} repos",
|
||||
"selectTarget": "Select target",
|
||||
"allSites": "All sites",
|
||||
"allRepos": "All repos",
|
||||
"updatedSort": "Updated",
|
||||
"fieldDescending": "{{field}} desc",
|
||||
"fieldAscending": "{{field}} asc",
|
||||
"viewOrder": "View order",
|
||||
"selectedFields": "{{selected}}/{{total}} fields",
|
||||
"fields": "Fields",
|
||||
"usesFieldDescending": "Uses {{field}} desc",
|
||||
"usesFieldAscending": "Uses {{field}} asc",
|
||||
"usesGitHubRankOrder": "Uses GitHub rank order",
|
||||
"currentlyDescending": "Currently desc · tap for ascending",
|
||||
"currentlyAscending": "Currently asc · tap for descending",
|
||||
"sortAscending": "Sort ascending",
|
||||
"viewNumber": "View #{{number}}",
|
||||
"unsupportedLayout": "Unsupported layout on mobile"
|
||||
},
|
||||
"providerViewProjection": {
|
||||
"defaultSubtitle": "{{subtitle}} · Default",
|
||||
"default": "Default",
|
||||
"openState": "Open",
|
||||
"allSites": "All sites",
|
||||
"all": "All",
|
||||
"list": "List",
|
||||
"noGrouping": "No grouping",
|
||||
"priority": "Priority",
|
||||
"allWorkspaces": "All workspaces",
|
||||
"workspace": "Workspace",
|
||||
"allTeams": "All teams",
|
||||
"teams_one": "{{count}} team",
|
||||
"teams_other": "{{count}} teams",
|
||||
"projects": "Projects",
|
||||
"pullRequests": "PRs",
|
||||
"issues": "Issues",
|
||||
"chooseProject": "Choose project"
|
||||
},
|
||||
"workspaceCreateProjection": {
|
||||
"nameRequired": "Name is required.",
|
||||
"nameTooLong": "Name must be 80 characters or fewer.",
|
||||
"nameAlreadyExists": "\"{{name}}\" already exists.",
|
||||
"openShell": "Open a shell"
|
||||
},
|
||||
"workspaceAgentSelection": {
|
||||
"blankTerminal": "Blank Terminal"
|
||||
},
|
||||
"workspaceSshGate": {
|
||||
"connected": "Connected",
|
||||
"connecting": "Connecting",
|
||||
"deployingRelay": "Deploying relay",
|
||||
"reconnecting": "Reconnecting",
|
||||
"authenticationFailed": "Authentication failed",
|
||||
"reconnectFailed": "Reconnect failed",
|
||||
"connectionFailed": "Connection failed",
|
||||
"disconnected": "Disconnected"
|
||||
},
|
||||
"worktreeCreateRetry": {
|
||||
"createFailed": "Failed to create workspace"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
"autocompleteOn": "Activado",
|
||||
"defaultText": "Predeterminado (100%)",
|
||||
"keepPhoneSize": "Mantener en tamaño de teléfono (predeterminado)",
|
||||
"keyboardInputDescription": "El autocompletado, la autocorrección y las sugerencias ortográficas solo se aplican a los comandos que se editan antes de enviarlos. Usa el botón de doble flecha situado encima del teclado para salir del modo de entrada en directo y edita el comando antes de tocar Enviar. Estas funciones están desactivadas por defecto para evitar que se modifiquen comandos, opciones o rutas.",
|
||||
"keyboardInputDescription": "El autocompletado, la autocorrección y las sugerencias ortográficas solo se aplican a los comandos que se editan antes de enviarlos. Usa el botón de doble flecha situado encima del teclado para salir del modo de entrada directa y edita el comando antes de tocar Enviar. Estas funciones están desactivadas por defecto para evitar que se modifiquen comandos, opciones o rutas.",
|
||||
"keyboardInputHeading": "ENTRADA DE TECLADO",
|
||||
"largeText": "Grande (125%)",
|
||||
"largerText": "Más grande (150%)",
|
||||
@@ -1532,7 +1532,21 @@
|
||||
"workspace": "Espacio de trabajo"
|
||||
}
|
||||
},
|
||||
"newWorkspace": {
|
||||
"hostPicker": {
|
||||
"title": "Crear espacio de trabajo en"
|
||||
},
|
||||
"loadingDrawer": {
|
||||
"downloadProgress": "Descargando… {{progress}}",
|
||||
"downloading": "Descargando",
|
||||
"loading": "Cargando"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"desktopChannel": {
|
||||
"name": "Notificaciones del escritorio",
|
||||
"silentName": "Notificaciones silenciosas de Orca"
|
||||
},
|
||||
"notificationDeliverySection": {
|
||||
"footer": "Los tipos de alerta dependen de la configuración de notificaciones de cada escritorio emparejado. Las notificaciones se pausan tras 7 días sin usar esta aplicación; ábrela y vuelve a conectarte para reanudarlas.",
|
||||
"onlyWhenAway": "Solo cuando no uses el escritorio",
|
||||
@@ -2278,7 +2292,7 @@
|
||||
},
|
||||
"terminalLiveInputStatus": {
|
||||
"listening": "Escuchando",
|
||||
"liveInput": "Entrada en tiempo real",
|
||||
"liveInput": "Entrada directa",
|
||||
"preparingMic": "Preparando micrófono",
|
||||
"processing": "Procesando",
|
||||
"releaseMicHint": "Suelta el micrófono para detener la grabación",
|
||||
@@ -2590,11 +2604,71 @@
|
||||
}
|
||||
},
|
||||
"sourceControl": {
|
||||
"actionSheetRunners": {
|
||||
"noBaseBranch": "No hay una rama base sobre la que hacer rebase",
|
||||
"waitingForDesktop": "Esperando al escritorio…"
|
||||
},
|
||||
"actions": {
|
||||
"checkingReviewStatus": "Comprobando estado de revisión.",
|
||||
"checkoutBeforePublish": "Haz checkout de una rama antes de publicar commits.",
|
||||
"commitStagedChanges": "Haz commit de los cambios preparados.",
|
||||
"commits": "Commits",
|
||||
"committing": "Commit en curso.",
|
||||
"createPr": "Crear PR",
|
||||
"enterCommitMessage": "Introduce un mensaje de commit para hacer commit.",
|
||||
"forcePushWithLease": "Haz force push con lease para actualizar la rama remota.",
|
||||
"forcePushing": "Force push en curso.",
|
||||
"linkedReviewUnavailable": "La rama de la revisión vinculada no está disponible.",
|
||||
"publishToOrigin": "Publica esta rama en origin.",
|
||||
"pullCommits_many": "Haz pull de {{count}} commits.",
|
||||
"pullCommits_one": "Haz pull de {{count}} commit.",
|
||||
"pullCommits_other": "Haz pull de {{count}} commits.",
|
||||
"pushAndCreatePr": "Push y crear PR",
|
||||
"switchBranch": "Cambiar de rama"
|
||||
"pushCommits_many": "Haz push de {{count}} commits.",
|
||||
"pushCommits_one": "Haz push de {{count}} commit.",
|
||||
"pushCommits_other": "Haz push de {{count}} commits.",
|
||||
"pushLinkedReview": "Haz push de las actualizaciones a la rama de la revisión vinculada.",
|
||||
"remoteOperationInProgress": "Operación remota en curso.",
|
||||
"resolveConflicts": "Resuelve los conflictos antes de hacer commit.",
|
||||
"reviewAlreadyMerged": "No hay nada para hacer commit. La revisión ya está mergeada.",
|
||||
"stageAllChanges": "Agrega todos los cambios al stage.",
|
||||
"stageFileToCommit": "Agrega al stage al menos un archivo para hacer commit.",
|
||||
"switchBranch": "Cambiar de rama",
|
||||
"syncCounts": "Haz pull de {{behind}} y push de {{ahead}}.",
|
||||
"upToDate": "No hay nada para hacer commit. La rama está actualizada.",
|
||||
"waitForRemoteOperation": "Vuelve a intentarlo cuando termine la operación remota."
|
||||
},
|
||||
"branchBaseRef": {
|
||||
"resolveFailed": "No se pudo determinar la base de la rama"
|
||||
},
|
||||
"branchCard": {
|
||||
"branchCount": "{{count}} en la rama",
|
||||
"changedCount": "{{count}} con cambios",
|
||||
"cherryPickState": "cherry-pick",
|
||||
"mergeState": "merge",
|
||||
"rebaseState": "rebase",
|
||||
"stagedCount": "{{count}} en stage"
|
||||
},
|
||||
"branchCompare": {
|
||||
"commits_many": "{{count}} commits",
|
||||
"commits_one": "{{count}} commit",
|
||||
"commits_other": "{{count}} commits",
|
||||
"files_many": "{{count}} archivos",
|
||||
"files_one": "{{count}} archivo",
|
||||
"files_other": "{{count}} archivos",
|
||||
"sectionTitle": "Commits en la rama",
|
||||
"summary": "{{files}} - frente a {{baseRef}}",
|
||||
"summaryWithCommits": "{{files}} - {{commits}} - frente a {{baseRef}}"
|
||||
},
|
||||
"branchCompareOutcome": {
|
||||
"baseBranchUnavailable": "No se pudo determinar la rama base para la comparación.",
|
||||
"loadFailed": "No se pudieron cargar los cambios confirmados"
|
||||
},
|
||||
"branchDiffPreviewDrawer": {
|
||||
"closePreview": "Cerrar vista previa del diff de los commits",
|
||||
"committedOnBranch": "Commits en la rama",
|
||||
"loadFailed": "No se pudo cargar el diff",
|
||||
"truncated": "Diff truncado para la vista previa móvil."
|
||||
},
|
||||
"commitDropdown": {
|
||||
"checkOutBranchToPush": "Haz checkout de una rama antes de hacer push de commits",
|
||||
@@ -2619,8 +2693,49 @@
|
||||
"stageFile": "Haz stage de al menos un archivo para crear un commit",
|
||||
"useCommitAndForcePush": "Usa Commit y Force Push — el remoto solo tiene copias antiguas de commits locales"
|
||||
},
|
||||
"commitFailurePanel": {
|
||||
"fix": "Arreglar",
|
||||
"fixWithAi": "Solucionar error de commit con IA",
|
||||
"hideDetails": "Ocultar detalles",
|
||||
"hideFailureDetails": "Ocultar detalles del error de commit",
|
||||
"showDetails": "Mostrar detalles",
|
||||
"showFailureDetails": "Mostrar detalles del error de commit",
|
||||
"summary": "No se pudo hacer commit.",
|
||||
"title": "No se pudo hacer commit"
|
||||
},
|
||||
"commitMessageAi": {
|
||||
"generateFailed": "No se pudo generar el mensaje de commit"
|
||||
},
|
||||
"commitRunners": {
|
||||
"actionFailed": "No se pudo realizar la acción de control de código fuente",
|
||||
"commitFailed": "No se pudo hacer commit"
|
||||
},
|
||||
"conflictAbort": {
|
||||
"abortMerge": "Cancelar fusión",
|
||||
"abortOperation": "Abortar {{operation}}",
|
||||
"abortRebase": "Abortar rebase",
|
||||
"aborting": "Abortando…"
|
||||
},
|
||||
"content": {
|
||||
"cancelGeneration": "Cancelar la generación del mensaje de commit",
|
||||
"commitMessageDisabled": "Mensaje de commit deshabilitado. No hay archivos preparados.",
|
||||
"commitMessagePlaceholder": "Mensaje de commit",
|
||||
"emptyMessage": "El árbol de trabajo está limpio.",
|
||||
"emptyTitle": "No hay cambios locales",
|
||||
"generateMessage": "Generar mensaje de commit con IA",
|
||||
"noStagedFiles": "No hay archivos preparados",
|
||||
"openActions": "Abrir acciones de control de código fuente",
|
||||
"reconnecting": "Reconectando con el escritorio…",
|
||||
"regenerateHint": "Borre el mensaje para regenerar.",
|
||||
"stageAll": "Hacer stage de todo",
|
||||
"unstageAll": "Quitar todo del stage"
|
||||
},
|
||||
"createPrAction": {
|
||||
"createReview": "Crear {{titleLabel}}"
|
||||
"checkingStatus": "Comprobando estado de revisión…",
|
||||
"createPullRequest": "Crear pull request",
|
||||
"createReview": "Crear {{titleLabel}}",
|
||||
"providerUnavailable": "Creación de revisiones no disponible para este proveedor",
|
||||
"statusUnavailable": "Estado de revisión no disponible"
|
||||
},
|
||||
"dropdownCounts": {
|
||||
"fastForwardCount_many": "Hacer fast-forward de {{count}} commits",
|
||||
@@ -2649,6 +2764,69 @@
|
||||
"titleUnpublishedForcePushCount_one": "Haz force push con lease de {{count}} commit de la rama y configura un upstream si es necesario.",
|
||||
"titleUnpublishedForcePushCount_other": "Haz force push con lease de {{count}} commits de la rama y configura un upstream si es necesario."
|
||||
},
|
||||
"fileList": {
|
||||
"committedSection": "Commits en la rama"
|
||||
},
|
||||
"fileRows": {
|
||||
"addedByThem": "Agregado por ellos",
|
||||
"addedByUs": "Agregado por nosotros",
|
||||
"bothAdded": "Agregado por ambos",
|
||||
"bothDeleted": "Eliminado por ambos",
|
||||
"bothModified": "Modificado por ambos",
|
||||
"committedSection": "Commits en la rama",
|
||||
"committedUnavailable": "Los cambios confirmados no están disponibles.",
|
||||
"deletedByThem": "Eliminado por ellos",
|
||||
"deletedByUs": "Eliminado por nosotros",
|
||||
"discardFile": "Descartar {{path}}",
|
||||
"loadingCommitted": "Cargando cambios confirmados…",
|
||||
"openChangedFile": "Abrir archivo modificado {{path}}",
|
||||
"openCommittedChange": "Abrir cambio confirmado en {{path}}",
|
||||
"renamedFrom": "de {{path}}",
|
||||
"stageFile": "Agregar {{path}} al stage",
|
||||
"unresolvedConflict": "Conflicto sin resolver",
|
||||
"unstageFile": "Quitar {{path}} del stage"
|
||||
},
|
||||
"gitHistory": {
|
||||
"days_many": "{{count}} d",
|
||||
"days_one": "{{count}} d",
|
||||
"days_other": "{{count}} d",
|
||||
"hours_many": "{{count}} h",
|
||||
"hours_one": "{{count}} h",
|
||||
"hours_other": "{{count}} h",
|
||||
"justNow": "ahora mismo",
|
||||
"loadFailed": "No se pudo cargar el historial de commits",
|
||||
"minutes_many": "{{count}} min",
|
||||
"minutes_one": "{{count}} min",
|
||||
"minutes_other": "{{count}} min",
|
||||
"months_many": "{{count}} meses",
|
||||
"months_one": "{{count}} mes",
|
||||
"months_other": "{{count}} meses",
|
||||
"noCommitMessage": "(sin mensaje de commit)",
|
||||
"years_many": "{{count}} años",
|
||||
"years_one": "{{count}} año",
|
||||
"years_other": "{{count}} años"
|
||||
},
|
||||
"gitHistoryList": {
|
||||
"loadFailed": "No se pudo cargar el historial",
|
||||
"loadFilesFailed": "No se pudieron cargar los archivos del commit",
|
||||
"noCommits": "No hay commits.",
|
||||
"noFileChanges": "No hay cambios en los archivos",
|
||||
"retryFiles": "Reintentar la carga de los archivos del commit",
|
||||
"waitingForDesktop": "Esperando al escritorio…"
|
||||
},
|
||||
"gitStatus": {
|
||||
"changes": "Cambios",
|
||||
"conflicts": "Conflictos",
|
||||
"stagedChanges": "Cambios preparados"
|
||||
},
|
||||
"header": {
|
||||
"backToSession": "Volver a la sesión",
|
||||
"close": "Cerrar el control de código fuente",
|
||||
"openNumberedPrWeb": "Abrir la pull request #{{number}} en la web",
|
||||
"openPrWeb": "Abrir la pull request en la web",
|
||||
"refresh": "Actualizar el control de código fuente",
|
||||
"title": "Control de código fuente"
|
||||
},
|
||||
"hostedReview": {
|
||||
"mrCopy": {
|
||||
"reviewLabel": "solicitud de fusión",
|
||||
@@ -2661,9 +2839,82 @@
|
||||
"titleLabel": "Solicitud de extracción"
|
||||
}
|
||||
},
|
||||
"hostedReviewCopy": {
|
||||
"committingChanges": "Confirmando cambios…",
|
||||
"creatingReview": "Creando revisión…",
|
||||
"forcePushing": "Haciendo force push con lease…",
|
||||
"generatingCommitMessage": "Generando mensaje de commit…",
|
||||
"publishingBranch": "Publicando rama…",
|
||||
"pushingCommits": "Haciendo push de commits…",
|
||||
"stagingChanges": "Agregando cambios al stage…",
|
||||
"updatingBranch": "Actualizando rama…"
|
||||
},
|
||||
"hostedReviewCreate": {
|
||||
"pushSucceeded": "El push se completó, pero no se pudo crear {{shortLabel}}: {{error}}"
|
||||
},
|
||||
"hostedReviewCreateIntent": {
|
||||
"branchChanged": "La rama cambió mientras se preparaba la pull request.",
|
||||
"generateMessageFailed": "No se pudo generar un mensaje de commit. Añade uno en Control de código fuente y vuelve a intentarlo.",
|
||||
"resolveConflicts": "Resuelve los conflictos antes de crear una pull request.",
|
||||
"resolveOrStageChanges": "Resuelve los conflictos o agrega los cambios al stage antes de crear una pull request.",
|
||||
"reviewCommitMessage": "Revisa el mensaje de commit y vuelve a intentar Crear PR."
|
||||
},
|
||||
"hostedReviewGitPreparation": {
|
||||
"commitFailed": "No se pudo hacer commit",
|
||||
"refreshFailed": "No se pudo actualizar el control de código fuente",
|
||||
"stageFailed": "No se pudieron agregar los cambios al stage",
|
||||
"updateBranchFailed": "No se pudo actualizar la rama remota. Vuelve a intentar Crear PR."
|
||||
},
|
||||
"hostedReviewRemotePrerequisite": {
|
||||
"forcePushFailed": "No se pudo hacer force push con lease",
|
||||
"publishFailed": "No se pudo publicar la rama",
|
||||
"pushFailed": "No se pudo hacer push de los commits"
|
||||
},
|
||||
"hostedReviewService": {
|
||||
"createFailed": "No se pudo crear la pull request",
|
||||
"pushBeforeCreateFailed": "El push falló. Resuelve el error de push y vuelve a intentarlo."
|
||||
},
|
||||
"hubTab": {
|
||||
"changes": "Cambios",
|
||||
"commits": "Commits",
|
||||
"pullRequest": "Solicitud de extracción"
|
||||
},
|
||||
"loaders": {
|
||||
"connectingToDesktop": "Conectando con el escritorio…",
|
||||
"loadFailed": "No se pudo cargar el control de código fuente",
|
||||
"updateDesktop": "Actualiza Orca en el escritorio para usar el control de código fuente en el móvil.",
|
||||
"waitingForDesktop": "Esperando al escritorio…"
|
||||
},
|
||||
"modals": {
|
||||
"actionsTitle": "Control de código fuente",
|
||||
"currentBranch": "actual",
|
||||
"discardButton": "Descartar",
|
||||
"discardConfirmMessage": "¿Descartar los cambios de \"{{path}}\"? Esta acción no se puede deshacer.",
|
||||
"discardTitle": "Descartar cambio",
|
||||
"openPrMessage": "¿Abrirla en tu navegador?",
|
||||
"openPrWithWarning": "¿Abrirla en tu navegador?\n\n{{warning}}",
|
||||
"prCreatedTitle": "Solicitud de extracción creada",
|
||||
"switchBranchTitle": "Cambiar de rama"
|
||||
},
|
||||
"openers": {
|
||||
"openDiffFailed": "No se pudo abrir el diff",
|
||||
"tabNotReady": "El archivo se abrió, pero su pestaña aún no está lista. Vuelve a intentarlo.",
|
||||
"waitingForDesktop": "Esperando al escritorio…"
|
||||
},
|
||||
"panel": {
|
||||
"loadFailedTitle": "No se pudo cargar",
|
||||
"unavailableTitle": "Control de código fuente no disponible"
|
||||
},
|
||||
"prChip": {
|
||||
"createPr": "Crear pull request",
|
||||
"loading": "Cargando pull request…",
|
||||
"loadingLabel": "Cargando pull request",
|
||||
"openLabel": "Pull request #{{number}}, {{state}}, {{checks}}. Abrir pull request.",
|
||||
"openWithComments_many": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentarios sin resolver. Abrir pull request.",
|
||||
"openWithComments_one": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentario sin resolver. Abrir pull request.",
|
||||
"openWithComments_other": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentarios sin resolver. Abrir pull request.",
|
||||
"unavailableLabel": "Pull request no disponible: {{message}}"
|
||||
},
|
||||
"prCreate": {
|
||||
"authRequired": "Autentícate antes de crear una {{reviewLabel}}.",
|
||||
"baseNotOnRemote": "Haz push de la rama base antes de crear una {{reviewLabel}}.",
|
||||
@@ -2682,8 +2933,19 @@
|
||||
"unsupportedMergeRequests": "No se pueden crear merge requests en este repositorio.",
|
||||
"unsupportedPullRequests": "No se pueden crear pull requests en este repositorio."
|
||||
},
|
||||
"prLink": {
|
||||
"updatePullRequestFailed": "No se pudo actualizar la pull request vinculada",
|
||||
"updateReviewFailed": "No se pudo actualizar la revisión vinculada"
|
||||
},
|
||||
"primaryAction": {
|
||||
"forcePushFromDesktop": "Haz force push de la rama de esta pull request desde el escritorio"
|
||||
"commit": "Commit",
|
||||
"forcePush": "Force Push",
|
||||
"forcePushFromDesktop": "Haz force push de la rama de esta pull request desde el escritorio",
|
||||
"publishBranch": "Publicar rama",
|
||||
"pull": "Pull",
|
||||
"push": "Push",
|
||||
"stageAll": "Hacer stage de todo",
|
||||
"sync": "Sincronizar"
|
||||
},
|
||||
"remoteDropdown": {
|
||||
"branchAlreadyPublished": "La rama ya está publicada",
|
||||
@@ -2733,6 +2995,600 @@
|
||||
"tryFastForwardPull": "Intenta un pull con fast-forward; git puede rechazar los commits locales",
|
||||
"tryRegularPush": "Intenta un push normal; git puede requerir force push",
|
||||
"useForcePushToSync": "Usa Force Push — el remoto solo tiene copias antiguas de commits locales"
|
||||
},
|
||||
"runners": {
|
||||
"actionFailed": "No se pudo realizar la acción de control de código fuente"
|
||||
},
|
||||
"screenState": {
|
||||
"noBranch": "Sin rama"
|
||||
},
|
||||
"state": {
|
||||
"noUpstream": "Sin upstream",
|
||||
"syncStatus": "{{ahead}} por delante, {{behind}} por detrás"
|
||||
},
|
||||
"useMobileCommitFailureRecovery": {
|
||||
"launchFailed": "No se pudo iniciar el agente",
|
||||
"waitingForDesktop": "Esperando al escritorio…"
|
||||
},
|
||||
"useMobileCommitMessageGeneration": {
|
||||
"generateFailed": "No se pudo generar el mensaje de commit"
|
||||
},
|
||||
"useMobileCreatePrRunner": {
|
||||
"branchRequired": "Haz checkout de una rama antes de crear una pull request."
|
||||
},
|
||||
"useMobileGitRequests": {
|
||||
"actionFailed": "No se pudo realizar la acción de control de código fuente",
|
||||
"branchUnavailable": "Estado de la rama no disponible",
|
||||
"commitFailed": "No se pudo hacer commit",
|
||||
"waitingForDesktop": "Esperando al escritorio…"
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"composerSource": {
|
||||
"baseFailed": "No se pudo resolver la rama base.",
|
||||
"forkPushWarning": "Esta PR tiene desactivada la opción \"Allow edits from maintainers\"; GitHub podría rechazar el push al fork."
|
||||
},
|
||||
"detailCommentRenderers": {
|
||||
"commentPlaceholder": "Agregar un comentario",
|
||||
"comments_many": "{{count}} comentarios",
|
||||
"comments_one": "{{count}} comentario",
|
||||
"comments_other": "{{count}} comentarios",
|
||||
"reopenThread": "Reabrir hilo",
|
||||
"reply": "Responder",
|
||||
"resolveThread": "Resolver hilo",
|
||||
"resolvedCommentBy": "Comentario de {{author}} resuelto",
|
||||
"resolvedThreadBy": "Hilo de {{author}} resuelto",
|
||||
"sendComment": "Enviar comentario",
|
||||
"show": "Mostrar"
|
||||
},
|
||||
"filterPickers": {
|
||||
"allTeams": "Todos los equipos",
|
||||
"changeStatus": "Cambiar estado",
|
||||
"fieldHidden": "Oculto en las tarjetas",
|
||||
"fieldShown": "Visible en las tarjetas",
|
||||
"fieldsSubtitle": "Elige qué campos del proyecto aparecen en las tarjetas de los elementos.",
|
||||
"fieldsTitle": "Campos del proyecto",
|
||||
"gitlabFilter": "Filtro de GitLab",
|
||||
"gitlabView": "Vista de GitLab",
|
||||
"jiraFilter": "Filtro de Jira",
|
||||
"jiraSite": "Sitio de Jira",
|
||||
"linearFilter": "Filtro de Linear",
|
||||
"linearIssue": "Issue de Linear",
|
||||
"linearWorkspace": "Espacio de trabajo de Linear",
|
||||
"loadingStates": "Cargando estados…",
|
||||
"noFields": "Esta vista no tiene campos adicionales que mostrar.",
|
||||
"noStates": "No hay estados disponibles",
|
||||
"switchWorkspaceFailed": "No se pudo cambiar de espacio de trabajo",
|
||||
"teamsSubtitle": "Elige qué equipos aparecen en Tareas.",
|
||||
"teamsTitle": "Equipos de Linear",
|
||||
"teams_many": "{{count}} equipos",
|
||||
"teams_one": "{{count}} equipo",
|
||||
"teams_other": "{{count}} equipos"
|
||||
},
|
||||
"githubProjectList": {
|
||||
"browseProjects": "Explorar proyectos",
|
||||
"chooseProject": "Elige un proyecto de GitHub",
|
||||
"emptyField": "Vacío",
|
||||
"issueSubtitle": "Issue · {{repository}}{{number}}",
|
||||
"itemSubtitle": "Elemento del proyecto · {{repository}}{{number}}",
|
||||
"items": "Elementos",
|
||||
"moreFields_many": "+{{count}} campos",
|
||||
"moreFields_one": "+{{count}} campo",
|
||||
"moreFields_other": "+{{count}} campos",
|
||||
"noItems": "No hay elementos en el proyecto",
|
||||
"pullRequestSubtitle": "Pull request · {{repository}}{{number}}"
|
||||
},
|
||||
"githubProjectPickers": {
|
||||
"add": "Agregar",
|
||||
"addByUrlHint": "Usa Agregar por URL para acceder a los proyectos que faltan.",
|
||||
"addPlaceholder": "Agregar por URL u owner/number",
|
||||
"adding": "Agregando…",
|
||||
"browseAll": "Explorar todo",
|
||||
"browseLoading": "Explorar todo (cargando…)",
|
||||
"chooseView": "Elegir vista del proyecto",
|
||||
"loadFailed": "No se pudieron cargar los proyectos",
|
||||
"noMatches": "No hay proyectos que coincidan.",
|
||||
"noMoreProjects": "No hay más proyectos.",
|
||||
"noProjects": "No hay proyectos cargados",
|
||||
"organizationsError": "organizaciones: {{message}}",
|
||||
"organizationsLoadFailed": "No se pudieron cargar algunas organizaciones ({{count}}).",
|
||||
"ownerLoadFailed": "No se pudieron cargar los proyectos de {{owner}}.",
|
||||
"pin": "Fijar",
|
||||
"pinned": "Fijado",
|
||||
"recent": "Recientes",
|
||||
"retryHint": "Toca para reintentar.",
|
||||
"searchProjects": "Buscar proyectos",
|
||||
"sort": "Orden del proyecto",
|
||||
"subtitle": "Elige una vista de proyecto para la página Tareas.",
|
||||
"title": "GitHub Projects",
|
||||
"unsupportedLayout": "Orca aún no admite este diseño de proyecto de GitHub.",
|
||||
"view": "Vista del proyecto"
|
||||
},
|
||||
"githubViewControls": {
|
||||
"fields": "Campos: {{fields}}",
|
||||
"openView": "Abrir vista en GitHub",
|
||||
"sort": "Orden: {{sort}}",
|
||||
"source": "Origen: {{source}}"
|
||||
},
|
||||
"itemActions": {
|
||||
"changeStatus": "Cambiar estado",
|
||||
"copyGitHubLink": "Copiar enlace de GitHub",
|
||||
"copyLinearLink": "Copiar enlace de Linear",
|
||||
"createWorkspace": "Crear espacio de trabajo",
|
||||
"creating": "Creando…",
|
||||
"mergeConflicts": "GitHub informa de conflictos de merge.",
|
||||
"mergeMergeRequest": "Hacer merge de la merge request",
|
||||
"mergePullRequest": "Hacer merge del pull request"
|
||||
},
|
||||
"itemDetailContent": {
|
||||
"addSubIssue": "Añadir sub-issue",
|
||||
"assignee": "Asignado",
|
||||
"assignees": "Asignados",
|
||||
"checks": "Checks",
|
||||
"description": "Descripción",
|
||||
"discussion": "Discusión",
|
||||
"noChecks": "No se encontraron checks.",
|
||||
"noComments": "No hay comentarios.",
|
||||
"noPipelineRuns": "No hay ejecuciones de pipeline para este MR.",
|
||||
"noSubIssues": "No hay sub-issues.",
|
||||
"none": "Ninguno",
|
||||
"pipeline": "Pipeline",
|
||||
"pipelineJobs_many": "{{count}} trabajos",
|
||||
"pipelineJobs_one": "{{count}} trabajo",
|
||||
"pipelineJobs_other": "{{count}} trabajos",
|
||||
"project": "Proyecto",
|
||||
"rerunAll": "Reejecutar todos",
|
||||
"rerunFailed": "Reejecutar fallidos",
|
||||
"status": "Estado",
|
||||
"subIssueTitle": "Título del sub-issue",
|
||||
"subIssues": "Sub-issues",
|
||||
"type": "Tipo"
|
||||
},
|
||||
"itemDetailDrawer": {
|
||||
"refreshDetails": "Actualizar detalles"
|
||||
},
|
||||
"itemFieldEditors": {
|
||||
"addLabels": "Añade etiquetas, separadas por comas",
|
||||
"addUsernames": "Añade nombres de usuario, separados por comas",
|
||||
"assignees": "Asignados",
|
||||
"labels": "Etiquetas",
|
||||
"loadingAssignees": "Cargando asignados…",
|
||||
"loadingLabels": "Cargando etiquetas…",
|
||||
"noAssignableUsers": "No se encontraron usuarios asignables en este repositorio.",
|
||||
"noLabels": "No hay etiquetas en este repositorio.",
|
||||
"none": "Sin selección",
|
||||
"removeLabels": "Quita etiquetas, separadas por comas",
|
||||
"removeUsernames": "Quita nombres de usuario, separados por comas",
|
||||
"saveTitle": "Guardar título",
|
||||
"title": "Título",
|
||||
"updateAssignees": "Actualizar asignados",
|
||||
"updateLabels": "Actualizar etiquetas"
|
||||
},
|
||||
"itemReviewSections": {
|
||||
"binaryFile": "Archivo binario.",
|
||||
"changedFilesTitle": "Archivos modificados",
|
||||
"descriptionPlaceholder": "Descripción",
|
||||
"fileContentsUnavailable": "El contenido del archivo no está disponible.",
|
||||
"hideFile": "Ocultar",
|
||||
"loadingReviewers": "Cargando revisores…",
|
||||
"markUnviewed": "Marcar no visto",
|
||||
"markViewed": "Marcar visto",
|
||||
"noDescription": "Sin descripción.",
|
||||
"noReviewerSuggestions": "No se encontraron sugerencias de revisores.",
|
||||
"noReviewersRequested": "No se solicitaron revisores.",
|
||||
"requestReview": "Solicitar revisión",
|
||||
"reviewersPlaceholder": "Solicitar revisores",
|
||||
"reviewersTitle": "Revisores",
|
||||
"saveDescription": "Guardar descripción",
|
||||
"viewFile": "Ver"
|
||||
},
|
||||
"legacySurface": {
|
||||
"loadIssuesFailed": "No se pudieron cargar los issues de {{source}}.",
|
||||
"mergeAction": "Merge",
|
||||
"mergeMethodTitle": "Método de merge",
|
||||
"mergePullRequestTitle": "Fusionar pull request",
|
||||
"mergeRequestMergeMessage": "Elige cómo hacer merge de esta merge request.",
|
||||
"mergeRequestTitle": "Solicitud de fusión",
|
||||
"pullRequestMergeMessage": "Elige cómo hacer merge de esta pull request.",
|
||||
"retryLoadingIssues": "Reintentar cargar los issues de {{source}}",
|
||||
"retrying": "Reintentando…",
|
||||
"sourceFallback": "La fuente de issues preferida, upstream, no está disponible para {{repo}}. Se usa origin.",
|
||||
"subIssueDataUnavailable": "Los datos de sub-issues no están disponibles para tu token.",
|
||||
"updateItemTitle": "Actualizar elemento"
|
||||
},
|
||||
"linearList": {
|
||||
"changeStatusFrom": "Cambiar el estado actual: {{status}}"
|
||||
},
|
||||
"linearViewControls": {
|
||||
"displayButton": "Mostrar",
|
||||
"groupLabel": "Agrupar: {{group}}",
|
||||
"orderLabel": "Orden: {{order}}"
|
||||
},
|
||||
"listDisplayPickers": {
|
||||
"displayPropertiesTitle": "Propiedades visibles",
|
||||
"linearGroupTitle": "Agrupar issues de Linear",
|
||||
"linearOrderTitle": "Ordenar issues de Linear",
|
||||
"linearViewTitle": "Vista de Linear",
|
||||
"sortTasksTitle": "Ordenar tareas"
|
||||
},
|
||||
"listSurface": {
|
||||
"connectLinearButton": "Conectar Linear",
|
||||
"connectLinearMessage": "Consulta los issues de Linear que tienes asignados y empieza a trabajar en ellos directamente desde Tareas.",
|
||||
"connectLinearTitle": "Conecta tu cuenta Linear",
|
||||
"jiraStatusFailed": "No se pudo leer el estado de Jira",
|
||||
"updateDesktopMessage": "Esta vista móvil de Tareas necesita un entorno de ejecución de escritorio más reciente.",
|
||||
"updateDesktopTitle": "Actualiza Orca en el escritorio"
|
||||
},
|
||||
"options": {
|
||||
"all": "Todo",
|
||||
"assignedToMe": "Asignado a mí",
|
||||
"assignee": "Asignado",
|
||||
"board": "Tablero",
|
||||
"boardDescription": "Columnas agrupadas",
|
||||
"closedState": "Cerrado",
|
||||
"completedState": "Completado",
|
||||
"createdState": "Creado",
|
||||
"githubAssignedIssuesDescription": "Issues abiertos asignados a ti",
|
||||
"githubDescription": "Issues y pull requests",
|
||||
"githubIssuesDescription": "Issues de GitHub",
|
||||
"githubOpenIssuesDescription": "Issues abiertos de GitHub",
|
||||
"githubProjectsDescription": "Vistas de GitHub Projects",
|
||||
"githubPullRequestsDescription": "Pull requests de GitHub",
|
||||
"gitlabAllDescription": "Cualquier estado de GitLab",
|
||||
"gitlabClosedDescription": "Issues y merge requests cerrados",
|
||||
"gitlabDescription": "Issues y merge requests",
|
||||
"gitlabMergedDescription": "Merge requests mergeados",
|
||||
"gitlabOpenDescription": "Issues y merge requests abiertos",
|
||||
"identifier": "Identificador",
|
||||
"issues": "Issues",
|
||||
"jiraDescription": "Issues asignados y reportados",
|
||||
"labels": "Etiquetas",
|
||||
"linearAllDescription": "Issues abiertos en los espacios de trabajo conectados",
|
||||
"linearAssignedDescription": "Issues que tienes asignados",
|
||||
"linearCompletedDescription": "Issues completados recientemente",
|
||||
"linearCreatedDescription": "Issues que has creado",
|
||||
"linearDescription": "Issues asignados y del equipo",
|
||||
"list": "Lista",
|
||||
"listDescription": "Filas compactas de issues",
|
||||
"mergedState": "Mergeado",
|
||||
"mine": "Mío",
|
||||
"myIssues": "Mis issues",
|
||||
"myPullRequestsDescription": "Pull requests creadas por ti",
|
||||
"myTodos": "Mis pendientes",
|
||||
"myTodosDescription": "Tareas pendientes de GitLab",
|
||||
"needsReview": "Necesita revisión",
|
||||
"noGrouping": "Sin agrupación",
|
||||
"openPullRequestsDescription": "Pull requests abiertas",
|
||||
"openState": "Abierto",
|
||||
"priority": "Prioridad",
|
||||
"projectMergeRequests": "MRs del proyecto",
|
||||
"projectMergeRequestsDescription": "Solicitudes de fusión e issues por repositorio",
|
||||
"projects": "Proyectos",
|
||||
"pullRequests": "PRs",
|
||||
"repository": "Repositorio",
|
||||
"repositorySortDescription": "Agrupar por repositorio y luego por actividad más reciente",
|
||||
"reviewRequestsDescription": "Solicitudes de revisión asignadas a ti",
|
||||
"status": "Estado",
|
||||
"team": "Equipo",
|
||||
"updated": "Actualizado",
|
||||
"updatedSortDescription": "Actividad más reciente primero"
|
||||
},
|
||||
"pickerProjection": {
|
||||
"allRepos": "Todos los repositorios",
|
||||
"allSites": "Todos los sitios",
|
||||
"currentlyAscending": "Ascendente · toca para cambiar a descendente",
|
||||
"currentlyDescending": "Descendente · toca para cambiar a ascendente",
|
||||
"fieldAscending": "{{field}} ascendente",
|
||||
"fieldDescending": "{{field}} descendente",
|
||||
"fields": "Campos",
|
||||
"repos_many": "{{count}} repositorios",
|
||||
"repos_one": "{{count}} repositorio",
|
||||
"repos_other": "{{count}} repositorios",
|
||||
"selectTarget": "Seleccionar destino",
|
||||
"selectedFields": "{{selected}}/{{total}} campos",
|
||||
"sortAscending": "Ordenar de forma ascendente",
|
||||
"sources_many": "{{count}} orígenes",
|
||||
"sources_one": "{{count}} origen",
|
||||
"sources_other": "{{count}} orígenes",
|
||||
"unsupportedLayout": "Diseño no compatible en móviles",
|
||||
"updatedSort": "Actualizado",
|
||||
"usesFieldAscending": "Usa {{field}} en orden ascendente",
|
||||
"usesFieldDescending": "Usa {{field}} en orden descendente",
|
||||
"usesGitHubRankOrder": "Usa el orden de clasificación de GitHub",
|
||||
"viewNumber": "Vista #{{number}}",
|
||||
"viewOrder": "Orden de la vista"
|
||||
},
|
||||
"prFileDiff": {
|
||||
"commentOnLine": "Comentar en la línea {{line}}",
|
||||
"commentPlaceholder": "Añade un comentario de revisión",
|
||||
"noTextChanges": "No se encontraron cambios de texto.",
|
||||
"showingDiffLines": "Se muestran las primeras {{limit}} de {{total}} líneas del diff."
|
||||
},
|
||||
"projectComments": {
|
||||
"comments_many": "{{count}} comentarios",
|
||||
"comments_one": "{{count}} comentario",
|
||||
"comments_other": "{{count}} comentarios",
|
||||
"discussion": "Conversación",
|
||||
"editComment": "Editar comentario",
|
||||
"noComments": "No hay comentarios.",
|
||||
"reopenThread": "Reabrir hilo",
|
||||
"reply": "Responder",
|
||||
"resolveThread": "Resolver hilo",
|
||||
"resolvedCommentBy": "Comentario de {{author}} resuelto",
|
||||
"resolvedThreadBy": "Hilo de {{author}} resuelto",
|
||||
"show": "Mostrar"
|
||||
},
|
||||
"projectDetailDrawer": {
|
||||
"addRepositoryFromDesktop": "{{repository}} no se ha añadido a Orca. Añade este repositorio desde la aplicación de escritorio y luego actualiza Tareas en el móvil.",
|
||||
"clearType": "Quitar tipo",
|
||||
"closeItem": "Cerrar elemento",
|
||||
"copyGitHubLink": "Copiar enlace de GitHub",
|
||||
"copyRepository": "Copiar repositorio",
|
||||
"createWorkspace": "Crear espacio de trabajo",
|
||||
"draftIssue": "Issue en borrador",
|
||||
"issue": "Issue",
|
||||
"issueType": "Tipo de issue",
|
||||
"loadingIssueTypes": "Cargando tipos de issue…",
|
||||
"mergePullRequest": "Hacer merge de la pull request",
|
||||
"mergeRepositoryRequirement": "Para hacer merge, el repositorio debe estar en Orca.",
|
||||
"noIssueTypes": "No hay tipos de issue configurados para este repositorio.",
|
||||
"noType": "Sin tipo",
|
||||
"openInGitHub": "Abrir en GitHub",
|
||||
"projectItem": "Elemento del proyecto",
|
||||
"projectSubtitle": "Proyecto de GitHub · {{repository}}{{itemNumber}}",
|
||||
"pullRequest": "Pull request",
|
||||
"reopenItem": "Reabrir elemento",
|
||||
"repositoryNotInOrca": "Repositorio no está en Orca",
|
||||
"status": "Estado",
|
||||
"type": "Tipo",
|
||||
"workspaceCreationRequirement": "Solo se pueden crear espacios de trabajo a partir de issues y pull requests de GitHub."
|
||||
},
|
||||
"projectFieldEditors": {
|
||||
"clearField": "Vaciar campo",
|
||||
"completedIteration": "Completada · {{startDate}} · {{duration}}d",
|
||||
"datePlaceholder": "YYYY-MM-DD",
|
||||
"invalidDate": "Introduce una fecha con el formato YYYY-MM-DD.",
|
||||
"invalidNumber": "Introduce un número válido.",
|
||||
"noIterations": "No hay iteraciones disponibles.",
|
||||
"numberPlaceholder": "Número",
|
||||
"projectFields": "Campos del proyecto",
|
||||
"saveField": "Guardar campo",
|
||||
"textPlaceholder": "Texto",
|
||||
"upcomingIteration": "En curso o próxima · {{startDate}} · {{duration}}d"
|
||||
},
|
||||
"projectMetadataEditors": {
|
||||
"assignees": "Asignados",
|
||||
"description": "Descripción",
|
||||
"labels": "Etiquetas",
|
||||
"loadingAssignees": "Cargando asignados…",
|
||||
"loadingLabels": "Cargando etiquetas…",
|
||||
"noAssignableUsers": "No se encontraron usuarios asignables en este repositorio.",
|
||||
"noDescription": "Sin descripción.",
|
||||
"noLabels": "No hay etiquetas en este repositorio.",
|
||||
"none": "Sin selección",
|
||||
"saveDescription": "Guardar descripción",
|
||||
"saveTitle": "Guardar título",
|
||||
"title": "Título"
|
||||
},
|
||||
"projectReviewPanels": {
|
||||
"binaryFile": "Archivo binario.",
|
||||
"changedFiles": "Archivos modificados",
|
||||
"checks": "Checks",
|
||||
"fileUnavailable": "Contenido del archivo no disponible.",
|
||||
"hideFile": "Ocultar",
|
||||
"loadingReviewers": "Cargando revisores…",
|
||||
"markUnviewed": "Marcar no visto",
|
||||
"markViewed": "Marcar visto",
|
||||
"noChecks": "No se encontraron checks.",
|
||||
"noReviewers": "No se solicitaron revisores.",
|
||||
"noSuggestions": "No se encontraron sugerencias de revisores.",
|
||||
"requestReview": "Solicitar revisión",
|
||||
"requestReviewers": "Solicitar revisores",
|
||||
"rerunAll": "Reejecutar todos",
|
||||
"rerunFailed": "Reejecutar fallidos",
|
||||
"reviewers": "Revisores",
|
||||
"viewFile": "Ver"
|
||||
},
|
||||
"providerControls": {
|
||||
"myTodos": "Mis tareas pendientes",
|
||||
"projectMergeRequests": "MR del proyecto",
|
||||
"sort": "Ordenar: {{sortLabel}}"
|
||||
},
|
||||
"providerItemList": {
|
||||
"intoBranch": "en {{base}}",
|
||||
"nextPage": "Página siguiente",
|
||||
"page": "Página {{page}}",
|
||||
"pageOfTotal": "Página {{page}} de {{total}}",
|
||||
"previousPage": "Página anterior",
|
||||
"selectPage": "Seleccionar página, página {{page}}",
|
||||
"selectPageOfTotal": "Seleccionar página, página {{page}} de {{total}}"
|
||||
},
|
||||
"providerPickers": {
|
||||
"allRepositories": "Todos los repositorios",
|
||||
"githubView": "Vista de GitHub",
|
||||
"issueSources": "Fuentes de issues de GitHub",
|
||||
"issueSourcesDescription": "Elige si usar upstream u origin para consultar y crear issues en cada repositorio.",
|
||||
"issues": "Issues",
|
||||
"noIssueSources": "No hay fuentes alternativas de issues disponibles.",
|
||||
"origin": "Origen",
|
||||
"pageHint": "Ve a una página de resultados cargada o disponible.",
|
||||
"pageLoaded": "Cargada",
|
||||
"pageNotLoaded": "Carga resultados anteriores",
|
||||
"pageNumber": "Página {{page}}",
|
||||
"pages": "Páginas de GitHub",
|
||||
"pullRequests": "Pull requests",
|
||||
"queryingSource": "Consultando {{source}}",
|
||||
"repoDescription": "Elige qué repositorios consultar.",
|
||||
"repos": "Repositorios",
|
||||
"taskSource": "Fuente de tareas",
|
||||
"upstream": "Upstream"
|
||||
},
|
||||
"providerViewProjection": {
|
||||
"all": "Todo",
|
||||
"allSites": "Todos los sitios",
|
||||
"allTeams": "Todos los equipos",
|
||||
"allWorkspaces": "Todos los espacios de trabajo",
|
||||
"chooseProject": "Elige proyecto",
|
||||
"default": "Predeterminado",
|
||||
"defaultSubtitle": "{{subtitle}} · Predeterminado",
|
||||
"issues": "Issues",
|
||||
"list": "Lista",
|
||||
"noGrouping": "Sin agrupación",
|
||||
"openState": "Abierto",
|
||||
"priority": "Prioridad",
|
||||
"projects": "Proyectos",
|
||||
"pullRequests": "PRs",
|
||||
"teams_many": "{{count}} equipos",
|
||||
"teams_one": "{{count}} equipo",
|
||||
"teams_other": "{{count}} equipos",
|
||||
"workspace": "Espacio de trabajo"
|
||||
},
|
||||
"reviewerLinear": {
|
||||
"issues": "Issues",
|
||||
"unassigned": "Sin asignar"
|
||||
},
|
||||
"screenChrome": {
|
||||
"connectLinear": "Conectar Linear",
|
||||
"newGitHubIssue": "Nuevo issue de GitHub",
|
||||
"newLinearIssue": "Nuevo issue de Linear",
|
||||
"refreshGitHub": "Actualizar trabajo de GitHub",
|
||||
"refreshGitLab": "Actualizar elementos de trabajo de GitLab",
|
||||
"refreshJira": "Actualizar issues de Jira",
|
||||
"refreshLinear": "Actualizar Linear",
|
||||
"title": "Tareas"
|
||||
},
|
||||
"searchControl": {
|
||||
"jiraPlaceholder": "JQL de Jira, p. ej. project = ABC AND statusCategory != Done",
|
||||
"projectPlaceholder": "Buscar en la vista del proyecto…",
|
||||
"providerPlaceholder": "Buscar tareas de {{provider}}…"
|
||||
},
|
||||
"smartSourceModes": {
|
||||
"allStates": "Todo",
|
||||
"branch": "Rama",
|
||||
"closedState": "Cerrado",
|
||||
"mergedState": "Mergeado",
|
||||
"name": "Nombre",
|
||||
"openState": "Abierto",
|
||||
"smart": "Inteligente"
|
||||
},
|
||||
"sparsePresetDraft": {
|
||||
"directoryRequired": "Agrega al menos un directorio.",
|
||||
"repoRelativeDirectoriesRequired": "Usa directorios relativos al repositorio, no la raíz, rutas absolutas ni segmentos padre."
|
||||
},
|
||||
"taskViewOptions": {
|
||||
"allSubtitle": "Issues sin resolver en los sitios seleccionados",
|
||||
"assignedSubtitle": "Issues sin resolver asignados a ti",
|
||||
"doneSubtitle": "Tus issues resueltos recientemente",
|
||||
"noGitHubTasks": "No hay tareas de GitHub",
|
||||
"noGitLabTasks": "No hay tareas de GitLab",
|
||||
"noJiraTasks": "No hay tareas de Jira",
|
||||
"noLinearTasks": "No hay tareas de Linear",
|
||||
"reportedSubtitle": "Issues sin resolver que has reportado"
|
||||
},
|
||||
"tasksCreateDrawers": {
|
||||
"connect": "Conectar",
|
||||
"connectLinearWorkspace": "Conectar espacio de trabajo de Linear",
|
||||
"createIssue": "Crear issue",
|
||||
"createWorkspaceIn": "Crear espacio de trabajo en",
|
||||
"description": "Descripción",
|
||||
"descriptionPlaceholder": "Añade contexto",
|
||||
"fileIn": "Crear en {{slug}}",
|
||||
"issueSource": "Fuente de issues",
|
||||
"keySecurityHint": "Tu clave se cifra con el llavero del sistema operativo del host y se guarda localmente.",
|
||||
"linearConnectSubtitle": "Pega una clave API personal para consultar los issues de ese espacio de trabajo.",
|
||||
"linearSettingsLink": "Ajustes de Linear / Seguridad / Nueva clave API",
|
||||
"linearTeam": "Equipo de Linear",
|
||||
"linearTeamSubtitle": "Crea un issue en el equipo de Linear seleccionado.",
|
||||
"newIssueTitle": "Nuevo issue de {{providerLabel}}",
|
||||
"origin": "Origen",
|
||||
"personalApiKey": "Clave API personal",
|
||||
"repository": "Repositorio",
|
||||
"repositorySubtitle": "Crea un issue en el repositorio seleccionado.",
|
||||
"team": "Equipo",
|
||||
"title": "Título",
|
||||
"titlePlaceholder": "Título de la tarea",
|
||||
"upstream": "Upstream"
|
||||
},
|
||||
"workspaceAgentSelection": {
|
||||
"blankTerminal": "Terminal en blanco"
|
||||
},
|
||||
"workspaceCreateDrawer": {
|
||||
"addRepository": "Añade un repositorio Git antes de crear un espacio de trabajo de Linear.",
|
||||
"advanced": "Avanzado",
|
||||
"agent": "Agente",
|
||||
"connect": "Conectar",
|
||||
"connectFirst": "Conecta primero el repositorio",
|
||||
"connectRepository": "Conectar repositorio",
|
||||
"connecting": "Conectando…",
|
||||
"createFrom": "Crear desde {{branch}}",
|
||||
"defaultBranch": "Rama predeterminada",
|
||||
"detectingAgents": "Detectando agentes…",
|
||||
"optional": "[Opcional]",
|
||||
"remoteRepository": "Repositorio remoto",
|
||||
"repository": "Repositorio",
|
||||
"repositoryNotFound": "No se encontró el repositorio.",
|
||||
"selectRepository": "Selecciona un repositorio",
|
||||
"sshConnection": "Conexión SSH",
|
||||
"startFrom": "Iniciar desde",
|
||||
"title": "Crear espacio de trabajo",
|
||||
"workspaceName": "Nombre del espacio de trabajo"
|
||||
},
|
||||
"workspaceCreateProjection": {
|
||||
"nameAlreadyExists": "\"{{name}}\" ya existe.",
|
||||
"nameRequired": "El nombre es obligatorio.",
|
||||
"nameTooLong": "El nombre debe tener 80 caracteres o menos.",
|
||||
"openShell": "Abrir un shell"
|
||||
},
|
||||
"workspaceOptionPickers": {
|
||||
"baseBranchSubtitle": "Elige una rama o referencia existente.",
|
||||
"baseBranchTitle": "Iniciar desde",
|
||||
"branchName": "Nombre de la rama: {{name}}",
|
||||
"defaultBranch": "Rama predeterminada",
|
||||
"defaultBranchSubtitle": "Usar la rama base configurada para este repositorio",
|
||||
"editPreset": "Editar {{name}}",
|
||||
"fullCheckout": "Checkout completo",
|
||||
"fullCheckoutSubtitle": "Usar todo el repositorio",
|
||||
"newPreset": "Nuevo preset",
|
||||
"noBranches": "No hay ramas que coincidan.",
|
||||
"searchBranches": "Buscar ramas",
|
||||
"sparseCheckoutTitle": "Checkout disperso"
|
||||
},
|
||||
"workspaceSshGate": {
|
||||
"authenticationFailed": "Autenticación fallida",
|
||||
"connected": "Conectado",
|
||||
"connecting": "Conectando",
|
||||
"connectionFailed": "La conexión falló",
|
||||
"deployingRelay": "Desplegando Relay",
|
||||
"disconnected": "Desconectado",
|
||||
"reconnectFailed": "Falló la reconexión",
|
||||
"reconnecting": "Reconectando"
|
||||
},
|
||||
"workspaceTrustDrawers": {
|
||||
"alwaysTrustAndRun": "Confiar siempre y ejecutar",
|
||||
"creating": "Creando…",
|
||||
"directoriesLabel": "Directorios",
|
||||
"directories_many": "{{count}} directorios",
|
||||
"directories_one": "{{count}} directorio",
|
||||
"directories_other": "{{count}} directorios",
|
||||
"dontRun": "No ejecutar",
|
||||
"editSparsePreset": "Editar preajuste de checkout disperso",
|
||||
"nameLabel": "Nombre",
|
||||
"namePlaceholder": "Interfaz del renderizador",
|
||||
"newSetupScript": "Nuevo script de configuración",
|
||||
"newSparsePreset": "Nuevo preajuste de checkout disperso",
|
||||
"runHooks": "Ejecutar hooks",
|
||||
"runSetupAndCreate": "Ejecutar configuración y crear",
|
||||
"runSetupTitle": "¿Ejecutar la configuración de {{name}}?",
|
||||
"setupChangedTitle": "El script de configuración de {{name}} ha cambiado",
|
||||
"setupScript": "Script de configuración",
|
||||
"setupSubtitle": "{{name}} requiere que decidas si ejecutar la configuración antes de crear este espacio de trabajo.",
|
||||
"setupTitle": "¿Ejecutar script de configuración?",
|
||||
"skipSetupAndCreate": "Omitir configuración y crear",
|
||||
"trustFailed": "No se pudo marcar el script de configuración como de confianza.",
|
||||
"trustSubtitle": "El archivo orca.yaml de este repositorio se ejecuta en tu equipo antes de iniciar el espacio de trabajo. Ejecútalo solo si confías en este repositorio."
|
||||
},
|
||||
"worktreeCreateRetry": {
|
||||
"createFailed": "No se pudo crear el espacio de trabajo"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
@@ -623,7 +623,7 @@
|
||||
"moreKeys": "Autres touches — Tab, flèches, F1–F12…",
|
||||
"navigation": "Navigation",
|
||||
"pickKey": "Choisir une touche",
|
||||
"pressEnter": "Appuyer sur Enter",
|
||||
"pressEnter": "Appuyer sur Entrée",
|
||||
"shortcutCombo": "Combinaison de touches",
|
||||
"shortcutComboHint": "Créer des combinaisons avec Ctrl, Alt et Shift",
|
||||
"textMacro": "Macro de texte",
|
||||
@@ -1532,7 +1532,21 @@
|
||||
"workspace": "Espace de travail"
|
||||
}
|
||||
},
|
||||
"newWorkspace": {
|
||||
"hostPicker": {
|
||||
"title": "Créer un espace de travail sur"
|
||||
},
|
||||
"loadingDrawer": {
|
||||
"downloadProgress": "Téléchargement… {{progress}}",
|
||||
"downloading": "Téléchargement",
|
||||
"loading": "Chargement"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"desktopChannel": {
|
||||
"name": "Notifications de l'ordinateur",
|
||||
"silentName": "Notifications silencieuses Orca"
|
||||
},
|
||||
"notificationDeliverySection": {
|
||||
"footer": "Les types d'alertes suivent les paramètres de notification de chaque ordinateur appairé. Les notifications sont suspendues après 7 jours sans utilisation de cette application ; ouvrez-la et reconnectez-vous pour les réactiver.",
|
||||
"onlyWhenAway": "Uniquement si vous n'êtes pas à l'ordinateur",
|
||||
@@ -2148,7 +2162,7 @@
|
||||
"advanced": "Avancé",
|
||||
"agent": "Agent",
|
||||
"agentPrompt": "Prompt d'agent",
|
||||
"appendEnter": "Ajouter Enter",
|
||||
"appendEnter": "Ajouter Entrée",
|
||||
"appendEnterDescription": "Envoie immédiatement au lieu de simplement insérer le texte.",
|
||||
"chooseAgent": "Choisir un agent",
|
||||
"commandText": "Texte de la commande",
|
||||
@@ -2521,7 +2535,7 @@
|
||||
"defaultViewHeading": "VUE PAR DÉFAUT",
|
||||
"off": "Désactivé",
|
||||
"on": "Activé",
|
||||
"openInChatUi": "Ouvrir les sessions dans Chat UI",
|
||||
"openInChatUi": "Ouvrir les sessions dans l'interface de chat",
|
||||
"title": "Chat UI"
|
||||
},
|
||||
"nativeNotificationDeliverySettings": {
|
||||
@@ -2590,11 +2604,71 @@
|
||||
}
|
||||
},
|
||||
"sourceControl": {
|
||||
"actionSheetRunners": {
|
||||
"noBaseBranch": "Aucune branche de base sur laquelle rebaser",
|
||||
"waitingForDesktop": "En attente de l'ordinateur…"
|
||||
},
|
||||
"actions": {
|
||||
"checkingReviewStatus": "Vérification du statut de revue.",
|
||||
"checkoutBeforePublish": "Effectuez un checkout d'une branche avant de publier des commits.",
|
||||
"commitStagedChanges": "Committer les modifications indexées.",
|
||||
"commits": "Commits",
|
||||
"committing": "Commit en cours.",
|
||||
"createPr": "Créer une PR",
|
||||
"enterCommitMessage": "Saisissez un message de commit pour committer.",
|
||||
"forcePushWithLease": "Faites un force push avec lease pour mettre à jour la branche distante.",
|
||||
"forcePushing": "Force Push en cours.",
|
||||
"linkedReviewUnavailable": "La branche de la revue liée est indisponible.",
|
||||
"publishToOrigin": "Publier cette branche sur origin.",
|
||||
"pullCommits_many": "Tirer {{count}} commits.",
|
||||
"pullCommits_one": "Tirer {{count}} commit.",
|
||||
"pullCommits_other": "Tirer {{count}} commits.",
|
||||
"pushAndCreatePr": "Pousser et créer une PR",
|
||||
"switchBranch": "Changer de branche"
|
||||
"pushCommits_many": "Pousser {{count}} commits.",
|
||||
"pushCommits_one": "Pousser {{count}} commit.",
|
||||
"pushCommits_other": "Pousser {{count}} commits.",
|
||||
"pushLinkedReview": "Pousser les mises à jour vers la branche de la revue liée.",
|
||||
"remoteOperationInProgress": "Opération distante en cours.",
|
||||
"resolveConflicts": "Résolvez les conflits avant de committer.",
|
||||
"reviewAlreadyMerged": "Rien à committer. La revue est déjà fusionnée.",
|
||||
"stageAllChanges": "Indexer toutes les modifications.",
|
||||
"stageFileToCommit": "Indexez au moins un fichier pour committer.",
|
||||
"switchBranch": "Changer de branche",
|
||||
"syncCounts": "Tirer {{behind}}, pousser {{ahead}}.",
|
||||
"upToDate": "Rien à commiter. La branche est à jour.",
|
||||
"waitForRemoteOperation": "Réessayez une fois l'opération distante terminée."
|
||||
},
|
||||
"branchBaseRef": {
|
||||
"resolveFailed": "Impossible de déterminer la base de la branche"
|
||||
},
|
||||
"branchCard": {
|
||||
"branchCount": "{{count}} sur la branche",
|
||||
"changedCount": "Modifiés : {{count}}",
|
||||
"cherryPickState": "cherry-pick",
|
||||
"mergeState": "merge",
|
||||
"rebaseState": "rebase",
|
||||
"stagedCount": "Indexés : {{count}}"
|
||||
},
|
||||
"branchCompare": {
|
||||
"commits_many": "{{count}} commits",
|
||||
"commits_one": "{{count}} commit",
|
||||
"commits_other": "{{count}} commits",
|
||||
"files_many": "{{count}} fichiers",
|
||||
"files_one": "{{count}} fichier",
|
||||
"files_other": "{{count}} fichiers",
|
||||
"sectionTitle": "Committé sur la branche",
|
||||
"summary": "{{files}} - par rapport à {{baseRef}}",
|
||||
"summaryWithCommits": "{{files}} - {{commits}} - par rapport à {{baseRef}}"
|
||||
},
|
||||
"branchCompareOutcome": {
|
||||
"baseBranchUnavailable": "Impossible de déterminer la branche de base pour la comparaison.",
|
||||
"loadFailed": "Impossible de charger les modifications committées"
|
||||
},
|
||||
"branchDiffPreviewDrawer": {
|
||||
"closePreview": "Fermer l'aperçu du diff committé",
|
||||
"committedOnBranch": "Committé sur la branche",
|
||||
"loadFailed": "Impossible de charger le diff",
|
||||
"truncated": "Diff tronqué pour l'aperçu mobile."
|
||||
},
|
||||
"commitDropdown": {
|
||||
"checkOutBranchToPush": "Effectuez un checkout d'une branche avant de pousser des commits",
|
||||
@@ -2619,8 +2693,49 @@
|
||||
"stageFile": "Indexez au moins un fichier pour commiter",
|
||||
"useCommitAndForcePush": "Utilisez Commit & Force Push — le remote n'a que d'anciennes copies des commits locaux"
|
||||
},
|
||||
"commitFailurePanel": {
|
||||
"fix": "Corriger",
|
||||
"fixWithAi": "Corriger l'échec du commit avec l'IA",
|
||||
"hideDetails": "Masquer les détails",
|
||||
"hideFailureDetails": "Masquer les détails de l'échec du commit",
|
||||
"showDetails": "Afficher les détails",
|
||||
"showFailureDetails": "Afficher les détails de l'échec du commit",
|
||||
"summary": "Échec du commit.",
|
||||
"title": "Échec du commit"
|
||||
},
|
||||
"commitMessageAi": {
|
||||
"generateFailed": "Impossible de générer le message de commit"
|
||||
},
|
||||
"commitRunners": {
|
||||
"actionFailed": "Échec de l'action de contrôle de code source",
|
||||
"commitFailed": "Échec du commit"
|
||||
},
|
||||
"conflictAbort": {
|
||||
"abortMerge": "Abandonner le merge",
|
||||
"abortOperation": "Abandonner {{operation}}",
|
||||
"abortRebase": "Abandonner le rebase",
|
||||
"aborting": "Abandon en cours…"
|
||||
},
|
||||
"content": {
|
||||
"cancelGeneration": "Annuler la génération du message de commit",
|
||||
"commitMessageDisabled": "Message de commit désactivé. Aucun fichier indexé.",
|
||||
"commitMessagePlaceholder": "Message de commit",
|
||||
"emptyMessage": "Le worktree est propre.",
|
||||
"emptyTitle": "Aucune modification locale",
|
||||
"generateMessage": "Générer le message de commit avec l'IA",
|
||||
"noStagedFiles": "Aucun fichier indexé",
|
||||
"openActions": "Ouvrir les actions de contrôle de code source",
|
||||
"reconnecting": "Reconnexion à l'ordinateur…",
|
||||
"regenerateHint": "Effacez le message pour le régénérer.",
|
||||
"stageAll": "Tout indexer",
|
||||
"unstageAll": "Tout désindexer"
|
||||
},
|
||||
"createPrAction": {
|
||||
"createReview": "Créer une {{titleLabel}}"
|
||||
"checkingStatus": "Vérification du statut de revue…",
|
||||
"createPullRequest": "Créer la pull request",
|
||||
"createReview": "Créer une {{titleLabel}}",
|
||||
"providerUnavailable": "Création de revue indisponible pour ce fournisseur",
|
||||
"statusUnavailable": "Statut de revue indisponible"
|
||||
},
|
||||
"dropdownCounts": {
|
||||
"fastForwardCount_many": "Faire un fast-forward de {{count}} commits",
|
||||
@@ -2649,6 +2764,69 @@
|
||||
"titleUnpublishedForcePushCount_one": "Faites un force push avec lease de {{count}} commit de la branche et définissez un upstream si nécessaire.",
|
||||
"titleUnpublishedForcePushCount_other": "Faites un force push avec lease de {{count}} commits de la branche et définissez un upstream si nécessaire."
|
||||
},
|
||||
"fileList": {
|
||||
"committedSection": "Committé sur la branche"
|
||||
},
|
||||
"fileRows": {
|
||||
"addedByThem": "Ajouté chez eux",
|
||||
"addedByUs": "Ajouté chez nous",
|
||||
"bothAdded": "Ajouté des deux côtés",
|
||||
"bothDeleted": "Supprimé des deux côtés",
|
||||
"bothModified": "Modifié des deux côtés",
|
||||
"committedSection": "Committé sur la branche",
|
||||
"committedUnavailable": "Modifications committées indisponibles.",
|
||||
"deletedByThem": "Supprimé chez eux",
|
||||
"deletedByUs": "Supprimé chez nous",
|
||||
"discardFile": "Abandonner les modifications de {{path}}",
|
||||
"loadingCommitted": "Chargement des modifications committées…",
|
||||
"openChangedFile": "Ouvrir le fichier modifié {{path}}",
|
||||
"openCommittedChange": "Ouvrir la modification committée de {{path}}",
|
||||
"renamedFrom": "anciennement {{path}}",
|
||||
"stageFile": "Indexer {{path}}",
|
||||
"unresolvedConflict": "Conflit non résolu",
|
||||
"unstageFile": "Désindexer {{path}}"
|
||||
},
|
||||
"gitHistory": {
|
||||
"days_many": "{{count}} j",
|
||||
"days_one": "{{count}} j",
|
||||
"days_other": "{{count}} j",
|
||||
"hours_many": "{{count}} h",
|
||||
"hours_one": "{{count}} h",
|
||||
"hours_other": "{{count}} h",
|
||||
"justNow": "à l'instant",
|
||||
"loadFailed": "Impossible de charger l'historique des commits",
|
||||
"minutes_many": "{{count}} m",
|
||||
"minutes_one": "{{count}} m",
|
||||
"minutes_other": "{{count}} m",
|
||||
"months_many": "{{count}} mois",
|
||||
"months_one": "{{count}} mois",
|
||||
"months_other": "{{count}} mois",
|
||||
"noCommitMessage": "(aucun message de commit)",
|
||||
"years_many": "{{count}} ans",
|
||||
"years_one": "{{count}} an",
|
||||
"years_other": "{{count}} ans"
|
||||
},
|
||||
"gitHistoryList": {
|
||||
"loadFailed": "Échec du chargement de l'historique",
|
||||
"loadFilesFailed": "Impossible de charger les fichiers du commit",
|
||||
"noCommits": "Aucun commit.",
|
||||
"noFileChanges": "Aucun fichier modifié",
|
||||
"retryFiles": "Réessayer de charger les fichiers du commit",
|
||||
"waitingForDesktop": "En attente de l'ordinateur…"
|
||||
},
|
||||
"gitStatus": {
|
||||
"changes": "Modifications",
|
||||
"conflicts": "Conflits",
|
||||
"stagedChanges": "Modifications stagées"
|
||||
},
|
||||
"header": {
|
||||
"backToSession": "Retour à la session",
|
||||
"close": "Fermer le contrôle de code source",
|
||||
"openNumberedPrWeb": "Ouvrir la pull request #{{number}} sur le Web",
|
||||
"openPrWeb": "Ouvrir la pull request sur le Web",
|
||||
"refresh": "Actualiser le contrôle de code source",
|
||||
"title": "Contrôle de code source"
|
||||
},
|
||||
"hostedReview": {
|
||||
"mrCopy": {
|
||||
"reviewLabel": "merge request",
|
||||
@@ -2661,9 +2839,82 @@
|
||||
"titleLabel": "Pull Request"
|
||||
}
|
||||
},
|
||||
"hostedReviewCopy": {
|
||||
"committingChanges": "Commit des modifications…",
|
||||
"creatingReview": "Création de la revue…",
|
||||
"forcePushing": "Force push avec lease…",
|
||||
"generatingCommitMessage": "Génération du message de commit…",
|
||||
"publishingBranch": "Publication de la branche…",
|
||||
"pushingCommits": "Push des commits…",
|
||||
"stagingChanges": "Indexation des modifications…",
|
||||
"updatingBranch": "Mise à jour de la branche…"
|
||||
},
|
||||
"hostedReviewCreate": {
|
||||
"pushSucceeded": "Le push a réussi, mais la création de la {{shortLabel}} a échoué : {{error}}"
|
||||
},
|
||||
"hostedReviewCreateIntent": {
|
||||
"branchChanged": "La branche a changé pendant la préparation de la pull request.",
|
||||
"generateMessageFailed": "Impossible de générer un message de commit. Ajoutez-en un dans « Contrôle de code source », puis réessayez.",
|
||||
"resolveConflicts": "Résolvez les conflits avant de créer une pull request.",
|
||||
"resolveOrStageChanges": "Résolvez les conflits ou indexez les modifications avant de créer une pull request.",
|
||||
"reviewCommitMessage": "Relisez le message de commit, puis réessayez Créer une PR."
|
||||
},
|
||||
"hostedReviewGitPreparation": {
|
||||
"commitFailed": "Échec du commit",
|
||||
"refreshFailed": "Impossible d'actualiser le contrôle de code source",
|
||||
"stageFailed": "Impossible d'indexer les modifications",
|
||||
"updateBranchFailed": "Impossible de mettre à jour la branche distante. Réessayez Créer une PR."
|
||||
},
|
||||
"hostedReviewRemotePrerequisite": {
|
||||
"forcePushFailed": "Échec du force push avec lease",
|
||||
"publishFailed": "Impossible de publier la branche",
|
||||
"pushFailed": "Impossible de pousser les commits"
|
||||
},
|
||||
"hostedReviewService": {
|
||||
"createFailed": "Impossible de créer la pull request",
|
||||
"pushBeforeCreateFailed": "Le push a échoué. Résolvez l'erreur de push, puis réessayez."
|
||||
},
|
||||
"hubTab": {
|
||||
"changes": "Modifications",
|
||||
"commits": "Commits",
|
||||
"pullRequest": "Pull Request"
|
||||
},
|
||||
"loaders": {
|
||||
"connectingToDesktop": "Connexion à l'ordinateur…",
|
||||
"loadFailed": "Impossible de charger le contrôle de code source",
|
||||
"updateDesktop": "Mettez à jour Orca sur votre ordinateur pour utiliser le contrôle de code source sur mobile.",
|
||||
"waitingForDesktop": "En attente de l'ordinateur…"
|
||||
},
|
||||
"modals": {
|
||||
"actionsTitle": "Contrôle de code source",
|
||||
"currentBranch": "actuelle",
|
||||
"discardButton": "Abandonner",
|
||||
"discardConfirmMessage": "Abandonner les modifications de « {{path}} » ? Cette action est irréversible.",
|
||||
"discardTitle": "Abandonner la modification",
|
||||
"openPrMessage": "L'ouvrir dans votre navigateur ?",
|
||||
"openPrWithWarning": "L'ouvrir dans votre navigateur ?\n\n{{warning}}",
|
||||
"prCreatedTitle": "Pull request créée",
|
||||
"switchBranchTitle": "Changer de branche"
|
||||
},
|
||||
"openers": {
|
||||
"openDiffFailed": "Impossible d'ouvrir le diff",
|
||||
"tabNotReady": "Le fichier est ouvert, mais son onglet n'est pas encore prêt. Réessayez.",
|
||||
"waitingForDesktop": "En attente de l'ordinateur…"
|
||||
},
|
||||
"panel": {
|
||||
"loadFailedTitle": "Chargement impossible",
|
||||
"unavailableTitle": "Contrôle de code source indisponible"
|
||||
},
|
||||
"prChip": {
|
||||
"createPr": "Créer la pull request",
|
||||
"loading": "Chargement de la pull request…",
|
||||
"loadingLabel": "Chargement de la pull request",
|
||||
"openLabel": "Pull request #{{number}}, {{state}}, {{checks}}. Ouvrir la pull request.",
|
||||
"openWithComments_many": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} commentaires non résolus. Ouvrir la pull request.",
|
||||
"openWithComments_one": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} commentaire non résolu. Ouvrir la pull request.",
|
||||
"openWithComments_other": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} commentaires non résolus. Ouvrir la pull request.",
|
||||
"unavailableLabel": "Pull request indisponible : {{message}}"
|
||||
},
|
||||
"prCreate": {
|
||||
"authRequired": "Authentifiez-vous avant de créer une {{reviewLabel}}.",
|
||||
"baseNotOnRemote": "Poussez la branche de base avant de créer une {{reviewLabel}}.",
|
||||
@@ -2682,8 +2933,19 @@
|
||||
"unsupportedMergeRequests": "La création de merge requests n'est pas prise en charge pour ce dépôt.",
|
||||
"unsupportedPullRequests": "La création de pull requests n'est pas prise en charge pour ce dépôt."
|
||||
},
|
||||
"prLink": {
|
||||
"updatePullRequestFailed": "Impossible de mettre à jour la pull request liée",
|
||||
"updateReviewFailed": "Impossible de mettre à jour la revue liée"
|
||||
},
|
||||
"primaryAction": {
|
||||
"forcePushFromDesktop": "Faites un force push de la branche de cette pull request depuis l'ordinateur"
|
||||
"commit": "Commit",
|
||||
"forcePush": "Force Push",
|
||||
"forcePushFromDesktop": "Faites un force push de la branche de cette pull request depuis l'ordinateur",
|
||||
"publishBranch": "Publier la branche",
|
||||
"pull": "Pull",
|
||||
"push": "Push",
|
||||
"stageAll": "Tout indexer",
|
||||
"sync": "Synchroniser"
|
||||
},
|
||||
"remoteDropdown": {
|
||||
"branchAlreadyPublished": "La branche est déjà publiée",
|
||||
@@ -2733,6 +2995,600 @@
|
||||
"tryFastForwardPull": "Tentez un pull en fast-forward ; git peut rejeter les commits locaux",
|
||||
"tryRegularPush": "Tentez un push normal ; git peut exiger un force push",
|
||||
"useForcePushToSync": "Utilisez Force Push — le remote n'a que d'anciennes copies des commits locaux"
|
||||
},
|
||||
"runners": {
|
||||
"actionFailed": "Échec de l'action de contrôle de code source"
|
||||
},
|
||||
"screenState": {
|
||||
"noBranch": "Aucune branche"
|
||||
},
|
||||
"state": {
|
||||
"noUpstream": "Aucune branche de suivi",
|
||||
"syncStatus": "{{ahead}} en avance, {{behind}} en retard"
|
||||
},
|
||||
"useMobileCommitFailureRecovery": {
|
||||
"launchFailed": "Échec du lancement de l'agent",
|
||||
"waitingForDesktop": "En attente de l'ordinateur…"
|
||||
},
|
||||
"useMobileCommitMessageGeneration": {
|
||||
"generateFailed": "Impossible de générer le message de commit"
|
||||
},
|
||||
"useMobileCreatePrRunner": {
|
||||
"branchRequired": "Effectuez un checkout sur une branche avant de créer une pull request."
|
||||
},
|
||||
"useMobileGitRequests": {
|
||||
"actionFailed": "Échec de l'action de contrôle de code source",
|
||||
"branchUnavailable": "État de la branche indisponible",
|
||||
"commitFailed": "Échec du commit",
|
||||
"waitingForDesktop": "En attente de l'ordinateur…"
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"composerSource": {
|
||||
"baseFailed": "Échec de la résolution de la branche de base.",
|
||||
"forkPushWarning": "L'option « Autoriser les modifications des mainteneurs » est désactivée pour cette PR ; le push vers le fork peut être refusé par GitHub."
|
||||
},
|
||||
"detailCommentRenderers": {
|
||||
"commentPlaceholder": "Ajouter un commentaire",
|
||||
"comments_many": "{{count}} commentaires",
|
||||
"comments_one": "{{count}} commentaire",
|
||||
"comments_other": "{{count}} commentaires",
|
||||
"reopenThread": "Rouvrir le fil",
|
||||
"reply": "Répondre",
|
||||
"resolveThread": "Résoudre le fil",
|
||||
"resolvedCommentBy": "Commentaire de {{author}} résolu",
|
||||
"resolvedThreadBy": "Fil de {{author}} résolu",
|
||||
"sendComment": "Envoyer le commentaire",
|
||||
"show": "Afficher"
|
||||
},
|
||||
"filterPickers": {
|
||||
"allTeams": "Toutes les équipes",
|
||||
"changeStatus": "Changer le statut",
|
||||
"fieldHidden": "Masqué sur les cartes",
|
||||
"fieldShown": "Affiché sur les cartes",
|
||||
"fieldsSubtitle": "Choisissez les champs du projet à afficher sur les cartes des éléments.",
|
||||
"fieldsTitle": "Champs du projet",
|
||||
"gitlabFilter": "Filtre GitLab",
|
||||
"gitlabView": "Vue GitLab",
|
||||
"jiraFilter": "Filtre Jira",
|
||||
"jiraSite": "Site Jira",
|
||||
"linearFilter": "Filtre Linear",
|
||||
"linearIssue": "Ticket Linear",
|
||||
"linearWorkspace": "Espace de travail Linear",
|
||||
"loadingStates": "Chargement des statuts…",
|
||||
"noFields": "Cette vue n'a aucun champ supplémentaire à afficher.",
|
||||
"noStates": "Aucun statut disponible",
|
||||
"switchWorkspaceFailed": "Impossible de changer d'espace de travail",
|
||||
"teamsSubtitle": "Choisissez les équipes à afficher dans Tâches.",
|
||||
"teamsTitle": "Équipes Linear",
|
||||
"teams_many": "{{count}} équipes",
|
||||
"teams_one": "{{count}} équipe",
|
||||
"teams_other": "{{count}} équipes"
|
||||
},
|
||||
"githubProjectList": {
|
||||
"browseProjects": "Parcourir les projets",
|
||||
"chooseProject": "Choisissez un projet GitHub",
|
||||
"emptyField": "Vide",
|
||||
"issueSubtitle": "Issue · {{repository}}{{number}}",
|
||||
"itemSubtitle": "Élément de projet · {{repository}}{{number}}",
|
||||
"items": "Éléments",
|
||||
"moreFields_many": "+{{count}} champs",
|
||||
"moreFields_one": "+{{count}} champ",
|
||||
"moreFields_other": "+{{count}} champs",
|
||||
"noItems": "Aucun élément de projet",
|
||||
"pullRequestSubtitle": "Pull request · {{repository}}{{number}}"
|
||||
},
|
||||
"githubProjectPickers": {
|
||||
"add": "Ajouter",
|
||||
"addByUrlHint": "Utilisez « Ajouter par URL » pour accéder aux projets manquants.",
|
||||
"addPlaceholder": "Ajouter par URL ou propriétaire/numéro",
|
||||
"adding": "Ajout…",
|
||||
"browseAll": "Tout parcourir",
|
||||
"browseLoading": "Tout parcourir (chargement…)",
|
||||
"chooseView": "Choisir une vue de projet",
|
||||
"loadFailed": "Échec du chargement des projets",
|
||||
"noMatches": "Aucun projet correspondant.",
|
||||
"noMoreProjects": "Aucun autre projet.",
|
||||
"noProjects": "Aucun projet chargé",
|
||||
"organizationsError": "organisations : {{message}}",
|
||||
"organizationsLoadFailed": "Certaines organisations n'ont pas pu être chargées ({{count}}).",
|
||||
"ownerLoadFailed": "Impossible de charger les projets de {{owner}}.",
|
||||
"pin": "Épingler",
|
||||
"pinned": "Épinglés",
|
||||
"recent": "Récents",
|
||||
"retryHint": "Touchez pour réessayer.",
|
||||
"searchProjects": "Rechercher des projets",
|
||||
"sort": "Tri du projet",
|
||||
"subtitle": "Choisissez une vue de projet pour la page Tâches.",
|
||||
"title": "GitHub Projects",
|
||||
"unsupportedLayout": "Orca ne prend pas encore en charge cette disposition de projet GitHub.",
|
||||
"view": "Vue de projet"
|
||||
},
|
||||
"githubViewControls": {
|
||||
"fields": "Champs : {{fields}}",
|
||||
"openView": "Ouvrir la vue dans GitHub",
|
||||
"sort": "Tri : {{sort}}",
|
||||
"source": "Source : {{source}}"
|
||||
},
|
||||
"itemActions": {
|
||||
"changeStatus": "Changer le statut",
|
||||
"copyGitHubLink": "Copier le lien GitHub",
|
||||
"copyLinearLink": "Copier le lien Linear",
|
||||
"createWorkspace": "Créer un espace de travail",
|
||||
"creating": "Création…",
|
||||
"mergeConflicts": "GitHub signale des conflits de fusion.",
|
||||
"mergeMergeRequest": "Fusionner la merge request",
|
||||
"mergePullRequest": "Fusionner la pull request"
|
||||
},
|
||||
"itemDetailContent": {
|
||||
"addSubIssue": "Ajouter un sous-ticket",
|
||||
"assignee": "Assigné",
|
||||
"assignees": "Assignés",
|
||||
"checks": "Vérifications",
|
||||
"description": "Description",
|
||||
"discussion": "Discussion",
|
||||
"noChecks": "Aucune vérification trouvée.",
|
||||
"noComments": "Aucun commentaire.",
|
||||
"noPipelineRuns": "Aucune exécution de pipeline pour cette MR.",
|
||||
"noSubIssues": "Aucun sous-ticket.",
|
||||
"none": "Aucun",
|
||||
"pipeline": "Pipeline",
|
||||
"pipelineJobs_many": "{{count}} jobs",
|
||||
"pipelineJobs_one": "{{count}} job",
|
||||
"pipelineJobs_other": "{{count}} jobs",
|
||||
"project": "Projet",
|
||||
"rerunAll": "Tout relancer",
|
||||
"rerunFailed": "Relancer les vérifications échouées",
|
||||
"status": "Statut",
|
||||
"subIssueTitle": "Titre du sous-ticket",
|
||||
"subIssues": "Sous-tickets",
|
||||
"type": "Type"
|
||||
},
|
||||
"itemDetailDrawer": {
|
||||
"refreshDetails": "Actualiser les détails"
|
||||
},
|
||||
"itemFieldEditors": {
|
||||
"addLabels": "Étiquettes à ajouter, séparées par des virgules",
|
||||
"addUsernames": "Noms d'utilisateur à ajouter, séparés par des virgules",
|
||||
"assignees": "Assignés",
|
||||
"labels": "Étiquettes",
|
||||
"loadingAssignees": "Chargement des assignés…",
|
||||
"loadingLabels": "Chargement des étiquettes…",
|
||||
"noAssignableUsers": "Aucun utilisateur assignable trouvé pour ce dépôt.",
|
||||
"noLabels": "Aucune étiquette dans ce dépôt.",
|
||||
"none": "Aucun élément",
|
||||
"removeLabels": "Étiquettes à supprimer, séparées par des virgules",
|
||||
"removeUsernames": "Noms d'utilisateur à supprimer, séparés par des virgules",
|
||||
"saveTitle": "Enregistrer le titre",
|
||||
"title": "Titre",
|
||||
"updateAssignees": "Mettre à jour les assignés",
|
||||
"updateLabels": "Mettre à jour les étiquettes"
|
||||
},
|
||||
"itemReviewSections": {
|
||||
"binaryFile": "Fichier binaire.",
|
||||
"changedFilesTitle": "Fichiers modifiés",
|
||||
"descriptionPlaceholder": "Description",
|
||||
"fileContentsUnavailable": "Contenu du fichier indisponible.",
|
||||
"hideFile": "Masquer",
|
||||
"loadingReviewers": "Chargement des reviewers…",
|
||||
"markUnviewed": "Marquer comme non consulté",
|
||||
"markViewed": "Marquer comme consulté",
|
||||
"noDescription": "Aucune description.",
|
||||
"noReviewerSuggestions": "Aucune suggestion de reviewer trouvée.",
|
||||
"noReviewersRequested": "Aucun reviewer demandé.",
|
||||
"requestReview": "Demander une revue",
|
||||
"reviewersPlaceholder": "Demander des reviewers",
|
||||
"reviewersTitle": "Reviewers",
|
||||
"saveDescription": "Enregistrer la description",
|
||||
"viewFile": "Afficher"
|
||||
},
|
||||
"legacySurface": {
|
||||
"loadIssuesFailed": "Impossible de charger les issues de {{source}}.",
|
||||
"mergeAction": "Merge",
|
||||
"mergeMethodTitle": "Méthode de merge",
|
||||
"mergePullRequestTitle": "Merger la pull request",
|
||||
"mergeRequestMergeMessage": "Choisissez comment fusionner cette merge request.",
|
||||
"mergeRequestTitle": "Merge Request",
|
||||
"pullRequestMergeMessage": "Choisissez comment merger cette pull request.",
|
||||
"retryLoadingIssues": "Réessayer de charger les issues de {{source}}",
|
||||
"retrying": "Nouvelle tentative…",
|
||||
"sourceFallback": "La source d'issues privilégiée upstream est indisponible pour {{repo}}. Utilisation d'origin.",
|
||||
"subIssueDataUnavailable": "Les données de sub-issues ne sont pas disponibles avec votre token.",
|
||||
"updateItemTitle": "Mettre à jour l'élément"
|
||||
},
|
||||
"linearList": {
|
||||
"changeStatusFrom": "Changer le statut actuel : {{status}}"
|
||||
},
|
||||
"linearViewControls": {
|
||||
"displayButton": "Affichage",
|
||||
"groupLabel": "Grouper par : {{group}}",
|
||||
"orderLabel": "Trier par : {{order}}"
|
||||
},
|
||||
"listDisplayPickers": {
|
||||
"displayPropertiesTitle": "Propriétés affichées",
|
||||
"linearGroupTitle": "Grouper les issues Linear",
|
||||
"linearOrderTitle": "Trier les issues Linear",
|
||||
"linearViewTitle": "Vue Linear",
|
||||
"sortTasksTitle": "Trier les tâches"
|
||||
},
|
||||
"listSurface": {
|
||||
"connectLinearButton": "Connecter Linear",
|
||||
"connectLinearMessage": "Parcourez les issues Linear qui vous sont assignées et commencez à y travailler directement depuis Tâches.",
|
||||
"connectLinearTitle": "Connectez votre compte Linear",
|
||||
"jiraStatusFailed": "Impossible de lire le statut Jira",
|
||||
"updateDesktopMessage": "Cette vue Tâches sur mobile nécessite une version plus récente d'Orca Desktop.",
|
||||
"updateDesktopTitle": "Mettre à jour Orca Desktop"
|
||||
},
|
||||
"options": {
|
||||
"all": "Tous",
|
||||
"assignedToMe": "Assignés à moi",
|
||||
"assignee": "Assigné",
|
||||
"board": "Tableau",
|
||||
"boardDescription": "Issues regroupées en colonnes",
|
||||
"closedState": "Fermé",
|
||||
"completedState": "Terminé",
|
||||
"createdState": "Créé",
|
||||
"githubAssignedIssuesDescription": "Issues ouvertes qui vous sont assignées",
|
||||
"githubDescription": "Issues et pull requests",
|
||||
"githubIssuesDescription": "Issues GitHub",
|
||||
"githubOpenIssuesDescription": "Issues GitHub ouvertes",
|
||||
"githubProjectsDescription": "Vues GitHub Projects",
|
||||
"githubPullRequestsDescription": "Pull requests GitHub",
|
||||
"gitlabAllDescription": "Tous les états GitLab",
|
||||
"gitlabClosedDescription": "Issues et merge requests fermées",
|
||||
"gitlabDescription": "Issues et merge requests",
|
||||
"gitlabMergedDescription": "Merge requests fusionnées",
|
||||
"gitlabOpenDescription": "Issues et merge requests ouvertes",
|
||||
"identifier": "Identifiant",
|
||||
"issues": "Tickets",
|
||||
"jiraDescription": "Tickets assignés et signalés",
|
||||
"labels": "Étiquettes",
|
||||
"linearAllDescription": "Issues ouvertes dans les espaces de travail connectés",
|
||||
"linearAssignedDescription": "Issues qui vous sont assignées",
|
||||
"linearCompletedDescription": "Issues récemment terminées",
|
||||
"linearCreatedDescription": "Issues créées par vous",
|
||||
"linearDescription": "Issues assignées et issues d'équipe",
|
||||
"list": "Liste",
|
||||
"listDescription": "Lignes d'issues compactes",
|
||||
"mergedState": "Fusionnés",
|
||||
"mine": "À moi",
|
||||
"myIssues": "Mes issues",
|
||||
"myPullRequestsDescription": "Pull requests créées par vous",
|
||||
"myTodos": "Mes tâches à faire",
|
||||
"myTodosDescription": "Tâches à faire GitLab en attente",
|
||||
"needsReview": "En attente de relecture",
|
||||
"noGrouping": "Aucun regroupement",
|
||||
"openPullRequestsDescription": "Pull requests ouvertes",
|
||||
"openState": "Ouvert",
|
||||
"priority": "Priorité",
|
||||
"projectMergeRequests": "MR du projet",
|
||||
"projectMergeRequestsDescription": "Merge requests et issues par dépôt",
|
||||
"projects": "Projets",
|
||||
"pullRequests": "PRs",
|
||||
"repository": "Dépôt",
|
||||
"repositorySortDescription": "Par dépôt, puis par activité la plus récente",
|
||||
"reviewRequestsDescription": "Demandes de revue qui vous sont assignées",
|
||||
"status": "Statut",
|
||||
"team": "Équipe",
|
||||
"updated": "Mis à jour",
|
||||
"updatedSortDescription": "Activité la plus récente d'abord"
|
||||
},
|
||||
"pickerProjection": {
|
||||
"allRepos": "Tous les dépôts",
|
||||
"allSites": "Tous les sites",
|
||||
"currentlyAscending": "Tri croissant · touchez pour passer en décroissant",
|
||||
"currentlyDescending": "Tri décroissant · touchez pour passer en croissant",
|
||||
"fieldAscending": "{{field}} · ordre croissant",
|
||||
"fieldDescending": "{{field}} · ordre décroissant",
|
||||
"fields": "Champs",
|
||||
"repos_many": "{{count}} dépôts",
|
||||
"repos_one": "{{count}} dépôt",
|
||||
"repos_other": "{{count}} dépôts",
|
||||
"selectTarget": "Sélectionner la cible",
|
||||
"selectedFields": "{{selected}}/{{total}} champs",
|
||||
"sortAscending": "Trier par ordre croissant",
|
||||
"sources_many": "{{count}} sources",
|
||||
"sources_one": "{{count}} source",
|
||||
"sources_other": "{{count}} sources",
|
||||
"unsupportedLayout": "Disposition non prise en charge sur mobile",
|
||||
"updatedSort": "Mis à jour",
|
||||
"usesFieldAscending": "Tri croissant par {{field}}",
|
||||
"usesFieldDescending": "Tri décroissant par {{field}}",
|
||||
"usesGitHubRankOrder": "Utilise l'ordre de classement GitHub",
|
||||
"viewNumber": "Vue n° {{number}}",
|
||||
"viewOrder": "Ordre de la vue"
|
||||
},
|
||||
"prFileDiff": {
|
||||
"commentOnLine": "Commenter la ligne {{line}}",
|
||||
"commentPlaceholder": "Ajouter un commentaire de revue",
|
||||
"noTextChanges": "Aucune modification de texte trouvée.",
|
||||
"showingDiffLines": "Affichage des {{limit}} premières lignes du diff sur {{total}}."
|
||||
},
|
||||
"projectComments": {
|
||||
"comments_many": "{{count}} commentaires",
|
||||
"comments_one": "{{count}} commentaire",
|
||||
"comments_other": "{{count}} commentaires",
|
||||
"discussion": "Discussion",
|
||||
"editComment": "Modifier le commentaire",
|
||||
"noComments": "Aucun commentaire.",
|
||||
"reopenThread": "Rouvrir le fil",
|
||||
"reply": "Répondre",
|
||||
"resolveThread": "Résoudre le fil",
|
||||
"resolvedCommentBy": "Commentaire de {{author}} résolu",
|
||||
"resolvedThreadBy": "Fil de {{author}} résolu",
|
||||
"show": "Afficher"
|
||||
},
|
||||
"projectDetailDrawer": {
|
||||
"addRepositoryFromDesktop": "{{repository}} n'a pas été ajouté à Orca. Ajoutez ce dépôt depuis l'application de bureau, puis actualisez la section Tâches sur mobile.",
|
||||
"clearType": "Effacer le type",
|
||||
"closeItem": "Fermer l'élément",
|
||||
"copyGitHubLink": "Copier le lien GitHub",
|
||||
"copyRepository": "Copier le nom du dépôt",
|
||||
"createWorkspace": "Créer un espace de travail",
|
||||
"draftIssue": "Issue en brouillon",
|
||||
"issue": "Issue",
|
||||
"issueType": "Type de ticket",
|
||||
"loadingIssueTypes": "Chargement des types de tickets…",
|
||||
"mergePullRequest": "Merger la pull request",
|
||||
"mergeRepositoryRequirement": "Ce dépôt doit être ajouté à Orca pour effectuer le merge.",
|
||||
"noIssueTypes": "Aucun type de ticket configuré pour ce dépôt.",
|
||||
"noType": "Aucun type",
|
||||
"openInGitHub": "Ouvrir dans GitHub",
|
||||
"projectItem": "Élément du projet",
|
||||
"projectSubtitle": "Projet GitHub · {{repository}}{{itemNumber}}",
|
||||
"pullRequest": "Pull request",
|
||||
"reopenItem": "Rouvrir l'élément",
|
||||
"repositoryNotInOrca": "Dépôt absent d'Orca",
|
||||
"status": "Statut",
|
||||
"type": "Type",
|
||||
"workspaceCreationRequirement": "Les espaces de travail ne peuvent être créés qu'à partir d'issues et de pull requests GitHub."
|
||||
},
|
||||
"projectFieldEditors": {
|
||||
"clearField": "Effacer le champ",
|
||||
"completedIteration": "Terminée · {{startDate}} · {{duration}} j",
|
||||
"datePlaceholder": "YYYY-MM-DD",
|
||||
"invalidDate": "Saisissez une date au format YYYY-MM-DD.",
|
||||
"invalidNumber": "Saisissez un nombre valide.",
|
||||
"noIterations": "Aucune itération disponible.",
|
||||
"numberPlaceholder": "Nombre",
|
||||
"projectFields": "Champs du projet",
|
||||
"saveField": "Enregistrer le champ",
|
||||
"textPlaceholder": "Texte",
|
||||
"upcomingIteration": "En cours et à venir · {{startDate}} · {{duration}} j"
|
||||
},
|
||||
"projectMetadataEditors": {
|
||||
"assignees": "Assignés",
|
||||
"description": "Description",
|
||||
"labels": "Étiquettes",
|
||||
"loadingAssignees": "Chargement des assignés…",
|
||||
"loadingLabels": "Chargement des étiquettes…",
|
||||
"noAssignableUsers": "Aucun utilisateur à qui assigner des éléments dans ce dépôt.",
|
||||
"noDescription": "Aucune description.",
|
||||
"noLabels": "Aucune étiquette dans ce dépôt.",
|
||||
"none": "Aucun élément",
|
||||
"saveDescription": "Enregistrer la description",
|
||||
"saveTitle": "Enregistrer le titre",
|
||||
"title": "Titre"
|
||||
},
|
||||
"projectReviewPanels": {
|
||||
"binaryFile": "Fichier binaire.",
|
||||
"changedFiles": "Fichiers modifiés",
|
||||
"checks": "Vérifications",
|
||||
"fileUnavailable": "Contenu du fichier indisponible.",
|
||||
"hideFile": "Masquer",
|
||||
"loadingReviewers": "Chargement des reviewers…",
|
||||
"markUnviewed": "Marquer comme non consulté",
|
||||
"markViewed": "Marquer comme consulté",
|
||||
"noChecks": "Aucune vérification trouvée.",
|
||||
"noReviewers": "Aucun reviewer demandé.",
|
||||
"noSuggestions": "Aucune suggestion de reviewer trouvée.",
|
||||
"requestReview": "Demander une revue",
|
||||
"requestReviewers": "Demander des reviewers",
|
||||
"rerunAll": "Tout relancer",
|
||||
"rerunFailed": "Relancer celles en échec",
|
||||
"reviewers": "Reviewers",
|
||||
"viewFile": "Afficher"
|
||||
},
|
||||
"providerControls": {
|
||||
"myTodos": "Mes tâches à faire",
|
||||
"projectMergeRequests": "MR du projet",
|
||||
"sort": "Tri : {{sortLabel}}"
|
||||
},
|
||||
"providerItemList": {
|
||||
"intoBranch": "vers {{base}}",
|
||||
"nextPage": "Page suivante",
|
||||
"page": "Page {{page}}",
|
||||
"pageOfTotal": "Page {{page}} sur {{total}}",
|
||||
"previousPage": "Page précédente",
|
||||
"selectPage": "Sélectionner une page, page {{page}}",
|
||||
"selectPageOfTotal": "Sélectionner une page, page {{page}} sur {{total}}"
|
||||
},
|
||||
"providerPickers": {
|
||||
"allRepositories": "Tous les dépôts",
|
||||
"githubView": "Vue GitHub",
|
||||
"issueSources": "Sources des tickets GitHub",
|
||||
"issueSourcesDescription": "Pour chaque dépôt, choisissez upstream ou origin pour rechercher et créer des tickets.",
|
||||
"issues": "Tickets",
|
||||
"noIssueSources": "Aucune autre source de tickets disponible.",
|
||||
"origin": "Origine",
|
||||
"pageHint": "Accédez à une page de résultats chargée ou disponible.",
|
||||
"pageLoaded": "Chargée",
|
||||
"pageNotLoaded": "Charge des résultats plus anciens",
|
||||
"pageNumber": "Page {{page}}",
|
||||
"pages": "Pages GitHub",
|
||||
"pullRequests": "Pull requests",
|
||||
"queryingSource": "Recherche dans {{source}}",
|
||||
"repoDescription": "Choisissez les dépôts à interroger.",
|
||||
"repos": "Dépôts",
|
||||
"taskSource": "Source des tâches",
|
||||
"upstream": "Upstream"
|
||||
},
|
||||
"providerViewProjection": {
|
||||
"all": "Tous",
|
||||
"allSites": "Tous les sites",
|
||||
"allTeams": "Toutes les équipes",
|
||||
"allWorkspaces": "Tous les espaces de travail",
|
||||
"chooseProject": "Choisir le projet",
|
||||
"default": "Par défaut",
|
||||
"defaultSubtitle": "{{subtitle}} · Par défaut",
|
||||
"issues": "Tickets",
|
||||
"list": "Liste",
|
||||
"noGrouping": "Aucun regroupement",
|
||||
"openState": "Ouvert",
|
||||
"priority": "Priorité",
|
||||
"projects": "Projets",
|
||||
"pullRequests": "PRs",
|
||||
"teams_many": "{{count}} équipes",
|
||||
"teams_one": "{{count}} équipe",
|
||||
"teams_other": "{{count}} équipes",
|
||||
"workspace": "Espace de travail"
|
||||
},
|
||||
"reviewerLinear": {
|
||||
"issues": "Tickets",
|
||||
"unassigned": "Non assigné"
|
||||
},
|
||||
"screenChrome": {
|
||||
"connectLinear": "Connecter Linear",
|
||||
"newGitHubIssue": "Nouveau ticket GitHub",
|
||||
"newLinearIssue": "Nouveau ticket Linear",
|
||||
"refreshGitHub": "Actualiser le travail GitHub",
|
||||
"refreshGitLab": "Actualiser les éléments de travail GitLab",
|
||||
"refreshJira": "Actualiser les tickets Jira",
|
||||
"refreshLinear": "Actualiser Linear",
|
||||
"title": "Tâches"
|
||||
},
|
||||
"searchControl": {
|
||||
"jiraPlaceholder": "JQL Jira, p. ex. project = ABC AND statusCategory != Done",
|
||||
"projectPlaceholder": "Rechercher dans la vue du projet…",
|
||||
"providerPlaceholder": "Rechercher des tâches {{provider}}…"
|
||||
},
|
||||
"smartSourceModes": {
|
||||
"allStates": "Toutes",
|
||||
"branch": "Branche",
|
||||
"closedState": "Fermées",
|
||||
"mergedState": "Fusionnées",
|
||||
"name": "Nom",
|
||||
"openState": "Ouvertes",
|
||||
"smart": "Intelligent"
|
||||
},
|
||||
"sparsePresetDraft": {
|
||||
"directoryRequired": "Ajoutez au moins un répertoire.",
|
||||
"repoRelativeDirectoriesRequired": "Utilisez des répertoires relatifs au dépôt, pas la racine, des chemins absolus ni des segments parent."
|
||||
},
|
||||
"taskViewOptions": {
|
||||
"allSubtitle": "Tickets non résolus sur les sites sélectionnés",
|
||||
"assignedSubtitle": "Tickets non résolus qui vous sont assignés",
|
||||
"doneSubtitle": "Vos tickets récemment résolus",
|
||||
"noGitHubTasks": "Aucune tâche GitHub",
|
||||
"noGitLabTasks": "Aucune tâche GitLab",
|
||||
"noJiraTasks": "Aucune tâche Jira",
|
||||
"noLinearTasks": "Aucune tâche Linear",
|
||||
"reportedSubtitle": "Tickets non résolus que vous avez signalés"
|
||||
},
|
||||
"tasksCreateDrawers": {
|
||||
"connect": "Se connecter",
|
||||
"connectLinearWorkspace": "Connecter un espace de travail Linear",
|
||||
"createIssue": "Créer un ticket",
|
||||
"createWorkspaceIn": "Créer un espace de travail dans",
|
||||
"description": "Description",
|
||||
"descriptionPlaceholder": "Ajouter du contexte",
|
||||
"fileIn": "Créer dans {{slug}}",
|
||||
"issueSource": "Source des issues",
|
||||
"keySecurityHint": "Votre clé est chiffrée via le trousseau du système d'exploitation de l'hôte et stockée localement.",
|
||||
"linearConnectSubtitle": "Collez une clé d'API personnelle pour parcourir les tickets de cet espace de travail.",
|
||||
"linearSettingsLink": "Paramètres Linear / Sécurité / Nouvelle clé d'API",
|
||||
"linearTeam": "Équipe Linear",
|
||||
"linearTeamSubtitle": "Créez un ticket dans l'équipe Linear sélectionnée.",
|
||||
"newIssueTitle": "Nouveau ticket {{providerLabel}}",
|
||||
"origin": "Origine",
|
||||
"personalApiKey": "Clé d'API personnelle",
|
||||
"repository": "Dépôt",
|
||||
"repositorySubtitle": "Créez un ticket dans le dépôt sélectionné.",
|
||||
"team": "Équipe",
|
||||
"title": "Titre",
|
||||
"titlePlaceholder": "Titre de la tâche",
|
||||
"upstream": "Upstream"
|
||||
},
|
||||
"workspaceAgentSelection": {
|
||||
"blankTerminal": "Terminal vierge"
|
||||
},
|
||||
"workspaceCreateDrawer": {
|
||||
"addRepository": "Ajoutez un dépôt Git avant de créer un espace de travail Linear.",
|
||||
"advanced": "Avancé",
|
||||
"agent": "Agent",
|
||||
"connect": "Se connecter",
|
||||
"connectFirst": "Connectez d'abord le dépôt",
|
||||
"connectRepository": "Connecter le dépôt",
|
||||
"connecting": "Connexion…",
|
||||
"createFrom": "Créer à partir de {{branch}}",
|
||||
"defaultBranch": "Branche par défaut",
|
||||
"detectingAgents": "Détection des agents…",
|
||||
"optional": "[Optionnel]",
|
||||
"remoteRepository": "Dépôt distant",
|
||||
"repository": "Dépôt",
|
||||
"repositoryNotFound": "Dépôt introuvable.",
|
||||
"selectRepository": "Sélectionner un dépôt",
|
||||
"sshConnection": "Connexion SSH",
|
||||
"startFrom": "À partir de",
|
||||
"title": "Créer un espace de travail",
|
||||
"workspaceName": "Nom de l'espace de travail"
|
||||
},
|
||||
"workspaceCreateProjection": {
|
||||
"nameAlreadyExists": "Un préréglage nommé « {{name}} » existe déjà.",
|
||||
"nameRequired": "Le nom est obligatoire.",
|
||||
"nameTooLong": "Le nom doit contenir au maximum 80 caractères.",
|
||||
"openShell": "Ouvrir un shell"
|
||||
},
|
||||
"workspaceOptionPickers": {
|
||||
"baseBranchSubtitle": "Choisissez une branche ou une référence existante.",
|
||||
"baseBranchTitle": "À partir de",
|
||||
"branchName": "Nom de la branche : {{name}}",
|
||||
"defaultBranch": "Branche par défaut",
|
||||
"defaultBranchSubtitle": "Utiliser la branche de base configurée pour ce dépôt",
|
||||
"editPreset": "Modifier {{name}}",
|
||||
"fullCheckout": "Extraction complète",
|
||||
"fullCheckoutSubtitle": "Utiliser l'ensemble du dépôt",
|
||||
"newPreset": "Nouveau préréglage",
|
||||
"noBranches": "Aucune branche correspondante.",
|
||||
"searchBranches": "Rechercher des branches",
|
||||
"sparseCheckoutTitle": "Extraction partielle"
|
||||
},
|
||||
"workspaceSshGate": {
|
||||
"authenticationFailed": "Échec de l'authentification",
|
||||
"connected": "Connecté",
|
||||
"connecting": "Connexion",
|
||||
"connectionFailed": "Échec de la connexion",
|
||||
"deployingRelay": "Déploiement du relais",
|
||||
"disconnected": "Déconnecté",
|
||||
"reconnectFailed": "Échec de la reconnexion",
|
||||
"reconnecting": "Reconnexion"
|
||||
},
|
||||
"workspaceTrustDrawers": {
|
||||
"alwaysTrustAndRun": "Toujours faire confiance et exécuter",
|
||||
"creating": "Création…",
|
||||
"directoriesLabel": "Répertoires",
|
||||
"directories_many": "{{count}} répertoires",
|
||||
"directories_one": "{{count}} répertoire",
|
||||
"directories_other": "{{count}} répertoires",
|
||||
"dontRun": "Ne pas exécuter",
|
||||
"editSparsePreset": "Modifier le préréglage de checkout partiel",
|
||||
"nameLabel": "Nom",
|
||||
"namePlaceholder": "Interface de rendu",
|
||||
"newSetupScript": "Nouveau script de setup",
|
||||
"newSparsePreset": "Nouveau préréglage de checkout partiel",
|
||||
"runHooks": "Exécuter les hooks",
|
||||
"runSetupAndCreate": "Exécuter le setup et créer",
|
||||
"runSetupTitle": "Exécuter le setup de {{name}} ?",
|
||||
"setupChangedTitle": "Le script de setup de {{name}} a changé",
|
||||
"setupScript": "Script de setup",
|
||||
"setupSubtitle": "Choisissez si vous souhaitez exécuter le setup de {{name}} avant de créer cet espace de travail.",
|
||||
"setupTitle": "Exécuter le script de setup ?",
|
||||
"skipSetupAndCreate": "Ignorer le setup et créer",
|
||||
"trustFailed": "Échec de l'approbation du script de setup.",
|
||||
"trustSubtitle": "Le fichier orca.yaml de ce dépôt s'exécute sur votre machine avant le démarrage de l'espace de travail. Ne l'exécutez que si vous faites confiance à ce dépôt."
|
||||
},
|
||||
"worktreeCreateRetry": {
|
||||
"createFailed": "Échec de la création de l'espace de travail"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
+847
-10
@@ -117,7 +117,7 @@
|
||||
"autocompleteOn": "オン",
|
||||
"defaultText": "標準(100%)",
|
||||
"keepPhoneSize": "スマートフォンサイズを維持(デフォルト)",
|
||||
"keyboardInputDescription": "自動補完、自動修正、スペル候補は、バッファー方式のコマンド入力にのみ適用されます。キーボード上部の二重矢印ボタンでライブ入力から切り替えると、「送信」をタップする前にコマンドを編集できます。コマンド、フラグ、パスが書き換わるのを防ぐため、デフォルトではオフです。",
|
||||
"keyboardInputDescription": "自動補完、自動修正、スペル候補は、バッファー方式のコマンド入力にのみ適用されます。キーボード上部の二重矢印ボタンでリアルタイム入力から切り替えると、「送信」をタップする前にコマンドを編集できます。コマンド、フラグ、パスが書き換わるのを防ぐため、デフォルトではオフです。",
|
||||
"keyboardInputHeading": "キーボード入力",
|
||||
"largeText": "大(125%)",
|
||||
"largerText": "特大(150%)",
|
||||
@@ -277,7 +277,7 @@
|
||||
"notice": {
|
||||
"compaction": "コンテキストを圧縮しました",
|
||||
"contextCleared": "コンテキストをクリアしました",
|
||||
"plan": "計画",
|
||||
"plan": "プラン",
|
||||
"stoppedManually": "手動で停止しました"
|
||||
},
|
||||
"orcaStop": {
|
||||
@@ -388,10 +388,10 @@
|
||||
"empty": "タスクがありません",
|
||||
"finished": "{{task}} を完了しました",
|
||||
"inProgress": "進行中",
|
||||
"pending": "未着手",
|
||||
"pending": "保留中",
|
||||
"progress": "{{total}} 件中 {{completed}} 件のタスクが完了しました",
|
||||
"removed": "{{task}} を削除しました",
|
||||
"reset": "未着手に変更しました:{{task}}",
|
||||
"reset": "保留中としてマーク: {{task}}",
|
||||
"showAll": "完全なタスクリスト",
|
||||
"started": "{{task}} を開始しました",
|
||||
"taskStatus": "{{status}}:{{task}}",
|
||||
@@ -1491,7 +1491,21 @@
|
||||
"workspace": "ワークスペース"
|
||||
}
|
||||
},
|
||||
"newWorkspace": {
|
||||
"hostPicker": {
|
||||
"title": "ワークスペースの作成先ホスト"
|
||||
},
|
||||
"loadingDrawer": {
|
||||
"downloadProgress": "ダウンロード中… {{progress}}",
|
||||
"downloading": "ダウンロード中",
|
||||
"loading": "読み込み中"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"desktopChannel": {
|
||||
"name": "デスクトップ通知",
|
||||
"silentName": "Orca のサイレント通知"
|
||||
},
|
||||
"notificationDeliverySection": {
|
||||
"footer": "通知の種類は、ペアリング済みの各デスクトップの通知設定に従います。このアプリを7日間使用しないと通知が一時停止します。再開するには、アプリを開いて再接続してください。",
|
||||
"onlyWhenAway": "デスクトップから離れているときのみ",
|
||||
@@ -1700,7 +1714,7 @@
|
||||
"stackChangesRequested": "#{{number}} で変更が要求されています。",
|
||||
"stackClosed": "#{{number}} はクローズされています。",
|
||||
"stackConflicts": "#{{number}} にマージの競合があります。",
|
||||
"stackDraft": "#{{number}} はまだドラフトです。",
|
||||
"stackDraft": "#{{number}} はまだ下書きです。",
|
||||
"stackReviewRequired": "#{{number}} はまだレビューの承認が必要です。"
|
||||
},
|
||||
"prCheckDetail": {
|
||||
@@ -2162,7 +2176,7 @@
|
||||
"draftsHint": "画面を離れる前に、スマートフォンの下書きをコピーするか破棄してください。",
|
||||
"file": "ファイル",
|
||||
"markdown": "Markdown",
|
||||
"markdownNote": "Markdown メモ",
|
||||
"markdownNote": "Markdown ノート",
|
||||
"newBrowser": "新規ブラウザ",
|
||||
"newTab": "新規タブ",
|
||||
"notesCopied": "メモをコピーしました。",
|
||||
@@ -2452,7 +2466,7 @@
|
||||
"defaultViewHeading": "デフォルトの表示",
|
||||
"off": "オフ",
|
||||
"on": "オン",
|
||||
"openInChatUi": "セッションを Chat UI で開く",
|
||||
"openInChatUi": "セッションをチャット UI で開く",
|
||||
"title": "Chat UI"
|
||||
},
|
||||
"nativeNotificationDeliverySettings": {
|
||||
@@ -2520,11 +2534,67 @@
|
||||
}
|
||||
},
|
||||
"sourceControl": {
|
||||
"actionSheetRunners": {
|
||||
"noBaseBranch": "リベース先のベースブランチがありません。",
|
||||
"waitingForDesktop": "デスクトップへの接続を待機中…"
|
||||
},
|
||||
"actions": {
|
||||
"checkingReviewStatus": "レビュー状態を確認中です。",
|
||||
"checkoutBeforePublish": "コミットを公開する前にブランチをチェックアウトしてください。",
|
||||
"commitStagedChanges": "ステージ済みの変更をコミットします。",
|
||||
"commits": "コミット",
|
||||
"committing": "コミット中です。",
|
||||
"createPr": "PR を作成",
|
||||
"enterCommitMessage": "コミットするには、コミットメッセージを入力してください。",
|
||||
"forcePushWithLease": "lease 付きで強制プッシュしてリモートブランチを更新します。",
|
||||
"forcePushing": "強制プッシュ中です。",
|
||||
"linkedReviewUnavailable": "リンクされたレビューのブランチを利用できません。",
|
||||
"publishToOrigin": "このブランチを origin に公開します。",
|
||||
"pullCommits_one": "{{count}} 件のコミットをプルします。",
|
||||
"pullCommits_other": "{{count}} 件のコミットをプルします。",
|
||||
"pushAndCreatePr": "プッシュして PR を作成",
|
||||
"switchBranch": "ブランチを切り替え"
|
||||
"pushCommits_one": "{{count}} 件のコミットをプッシュします。",
|
||||
"pushCommits_other": "{{count}} 件のコミットをプッシュします。",
|
||||
"pushLinkedReview": "リンクされたレビューのブランチに更新をプッシュします。",
|
||||
"remoteOperationInProgress": "リモート操作を実行中です。",
|
||||
"resolveConflicts": "コミットする前に競合を解決してください。",
|
||||
"reviewAlreadyMerged": "コミットするものがありません。レビューはすでにマージ済みです。",
|
||||
"stageAllChanges": "すべての変更をステージします。",
|
||||
"stageFileToCommit": "コミットするには、ファイルを 1 つ以上ステージしてください。",
|
||||
"switchBranch": "ブランチを切り替え",
|
||||
"syncCounts": "{{behind}} 件をプルし、{{ahead}} 件をプッシュします。",
|
||||
"upToDate": "コミットするものがありません。ブランチは最新です。",
|
||||
"waitForRemoteOperation": "リモート操作が完了してから再試行してください。"
|
||||
},
|
||||
"branchBaseRef": {
|
||||
"resolveFailed": "ベースブランチを特定できませんでした。"
|
||||
},
|
||||
"branchCard": {
|
||||
"branchCount": "ブランチ内 {{count}} 件",
|
||||
"changedCount": "変更 {{count}} 件",
|
||||
"cherryPickState": "チェリーピック",
|
||||
"mergeState": "マージ",
|
||||
"rebaseState": "リベース",
|
||||
"stagedCount": "ステージ済み {{count}} 件"
|
||||
},
|
||||
"branchCompare": {
|
||||
"commits_one": "{{count}} 件のコミット",
|
||||
"commits_other": "{{count}} 件のコミット",
|
||||
"files_one": "{{count}} 個のファイル",
|
||||
"files_other": "{{count}} 個のファイル",
|
||||
"sectionTitle": "ブランチのコミット済み変更",
|
||||
"summary": "{{files}} - {{baseRef}} との比較",
|
||||
"summaryWithCommits": "{{files}} - {{commits}} - {{baseRef}} との比較"
|
||||
},
|
||||
"branchCompareOutcome": {
|
||||
"baseBranchUnavailable": "比較用のベースブランチを特定できませんでした。",
|
||||
"loadFailed": "コミット済みの変更を読み込めませんでした。"
|
||||
},
|
||||
"branchDiffPreviewDrawer": {
|
||||
"closePreview": "コミット済みの差分プレビューを閉じる",
|
||||
"committedOnBranch": "ブランチでコミット済み",
|
||||
"loadFailed": "差分を読み込めません",
|
||||
"truncated": "モバイルでのプレビュー用に差分を一部省略しています。"
|
||||
},
|
||||
"commitDropdown": {
|
||||
"checkOutBranchToPush": "コミットをプッシュする前にブランチをチェックアウトしてください",
|
||||
@@ -2549,8 +2619,49 @@
|
||||
"stageFile": "コミットするには、少なくとも 1 つのファイルをステージングしてください",
|
||||
"useCommitAndForcePush": "「コミットとフォースプッシュ」を使用してください — リモートにはローカルコミットの古いコピーしかありません"
|
||||
},
|
||||
"commitFailurePanel": {
|
||||
"fix": "修正",
|
||||
"fixWithAi": "AI によるコミット失敗の修正",
|
||||
"hideDetails": "詳細を非表示",
|
||||
"hideFailureDetails": "コミット失敗の詳細を非表示",
|
||||
"showDetails": "詳細を表示",
|
||||
"showFailureDetails": "コミット失敗の詳細を表示",
|
||||
"summary": "コミットに失敗しました。",
|
||||
"title": "コミットに失敗しました"
|
||||
},
|
||||
"commitMessageAi": {
|
||||
"generateFailed": "コミットメッセージの生成に失敗しました。"
|
||||
},
|
||||
"commitRunners": {
|
||||
"actionFailed": "ソース管理の操作に失敗しました。",
|
||||
"commitFailed": "コミットに失敗しました。"
|
||||
},
|
||||
"conflictAbort": {
|
||||
"abortMerge": "マージを中止する",
|
||||
"abortOperation": "{{operation}} を中止する",
|
||||
"abortRebase": "リベースを中止する",
|
||||
"aborting": "中止中…"
|
||||
},
|
||||
"content": {
|
||||
"cancelGeneration": "コミットメッセージの生成をキャンセル",
|
||||
"commitMessageDisabled": "コミットメッセージは入力できません。ステージ済みのファイルがありません。",
|
||||
"commitMessagePlaceholder": "コミットメッセージ",
|
||||
"emptyMessage": "ワークツリーに変更はありません。",
|
||||
"emptyTitle": "ローカルの変更なし",
|
||||
"generateMessage": "AIでコミットメッセージを生成",
|
||||
"noStagedFiles": "ステージ済みのファイルなし",
|
||||
"openActions": "ソース管理の操作を開く",
|
||||
"reconnecting": "デスクトップに再接続中…",
|
||||
"regenerateHint": "再生成するには、メッセージをクリアしてください。",
|
||||
"stageAll": "ステージオール",
|
||||
"unstageAll": "すべてステージ解除"
|
||||
},
|
||||
"createPrAction": {
|
||||
"createReview": "{{titleLabel}} を作成"
|
||||
"checkingStatus": "レビュー状態を確認中…",
|
||||
"createPullRequest": "PR の作成",
|
||||
"createReview": "{{titleLabel}} を作成",
|
||||
"providerUnavailable": "このプロバイダーではレビューを作成できません",
|
||||
"statusUnavailable": "レビュー状態を取得できません"
|
||||
},
|
||||
"dropdownCounts": {
|
||||
"fastForwardCount_one": "{{count}} 件のコミットを fast-forward",
|
||||
@@ -2572,6 +2683,64 @@
|
||||
"titleUnpublishedForcePushCount_one": "{{count}} 件のブランチコミットを lease 付きで強制プッシュし、必要に応じてアップストリームを設定します。",
|
||||
"titleUnpublishedForcePushCount_other": "{{count}} 件のブランチコミットを lease 付きで強制プッシュし、必要に応じてアップストリームを設定します。"
|
||||
},
|
||||
"fileList": {
|
||||
"committedSection": "ブランチのコミット済み変更"
|
||||
},
|
||||
"fileRows": {
|
||||
"addedByThem": "相手側で追加",
|
||||
"addedByUs": "こちら側で追加",
|
||||
"bothAdded": "双方で追加",
|
||||
"bothDeleted": "双方で削除",
|
||||
"bothModified": "双方で変更",
|
||||
"committedSection": "ブランチのコミット済み変更",
|
||||
"committedUnavailable": "コミット済みの変更を表示できません。",
|
||||
"deletedByThem": "相手側で削除",
|
||||
"deletedByUs": "こちら側で削除",
|
||||
"discardFile": "{{path}} の変更を破棄",
|
||||
"loadingCommitted": "コミット済みの変更を読み込み中…",
|
||||
"openChangedFile": "変更されたファイル {{path}} を開く",
|
||||
"openCommittedChange": "{{path}} のコミット済みの変更を開く",
|
||||
"renamedFrom": "変更前: {{path}}",
|
||||
"stageFile": "{{path}} をステージ",
|
||||
"unresolvedConflict": "未解決の競合",
|
||||
"unstageFile": "{{path}} のステージを解除"
|
||||
},
|
||||
"gitHistory": {
|
||||
"days_one": "{{count}}日",
|
||||
"days_other": "{{count}}日",
|
||||
"hours_one": "{{count}}時間",
|
||||
"hours_other": "{{count}}時間",
|
||||
"justNow": "たった今",
|
||||
"loadFailed": "コミット履歴の読み込みに失敗しました。",
|
||||
"minutes_one": "{{count}}分",
|
||||
"minutes_other": "{{count}}分",
|
||||
"months_one": "{{count}}か月",
|
||||
"months_other": "{{count}}か月",
|
||||
"noCommitMessage": "(コミットメッセージなし)",
|
||||
"years_one": "{{count}}年",
|
||||
"years_other": "{{count}}年"
|
||||
},
|
||||
"gitHistoryList": {
|
||||
"loadFailed": "履歴の読み込みに失敗しました。",
|
||||
"loadFilesFailed": "コミット内のファイルを読み込めません。",
|
||||
"noCommits": "コミットがありません。",
|
||||
"noFileChanges": "ファイルの変更なし",
|
||||
"retryFiles": "コミット内のファイルの読み込みを再試行",
|
||||
"waitingForDesktop": "デスクトップからの応答を待機中…"
|
||||
},
|
||||
"gitStatus": {
|
||||
"changes": "変更点",
|
||||
"conflicts": "競合",
|
||||
"stagedChanges": "ステージ済みの変更"
|
||||
},
|
||||
"header": {
|
||||
"backToSession": "セッションに戻る",
|
||||
"close": "ソース管理を閉じる",
|
||||
"openNumberedPrWeb": "PR #{{number}} をウェブで開く",
|
||||
"openPrWeb": "PR をウェブで開く",
|
||||
"refresh": "ソース管理を更新",
|
||||
"title": "ソース管理"
|
||||
},
|
||||
"hostedReview": {
|
||||
"mrCopy": {
|
||||
"reviewLabel": "MR",
|
||||
@@ -2584,9 +2753,81 @@
|
||||
"titleLabel": "PR"
|
||||
}
|
||||
},
|
||||
"hostedReviewCopy": {
|
||||
"committingChanges": "変更をコミット中…",
|
||||
"creatingReview": "レビューを作成中…",
|
||||
"forcePushing": "lease 付きで強制プッシュ中…",
|
||||
"generatingCommitMessage": "コミットメッセージを生成中…",
|
||||
"publishingBranch": "ブランチを公開中…",
|
||||
"pushingCommits": "コミットをプッシュ中…",
|
||||
"stagingChanges": "変更をステージング中…",
|
||||
"updatingBranch": "ブランチを更新中…"
|
||||
},
|
||||
"hostedReviewCreate": {
|
||||
"pushSucceeded": "プッシュは成功しましたが、{{shortLabel}} の作成に失敗しました: {{error}}"
|
||||
},
|
||||
"hostedReviewCreateIntent": {
|
||||
"branchChanged": "PR の準備中にブランチが変更されました。",
|
||||
"generateMessageFailed": "コミットメッセージを生成できませんでした。「ソース管理」で入力してから再試行してください。",
|
||||
"resolveConflicts": "PR を作成する前に、競合を解決してください。",
|
||||
"resolveOrStageChanges": "PR を作成する前に、競合を解決するか、変更をステージングしてください。",
|
||||
"reviewCommitMessage": "コミットメッセージを確認してから、「PR を作成」を再試行してください。"
|
||||
},
|
||||
"hostedReviewGitPreparation": {
|
||||
"commitFailed": "コミットに失敗しました。",
|
||||
"refreshFailed": "ソース管理を更新できませんでした。",
|
||||
"stageFailed": "変更のステージングに失敗しました。",
|
||||
"updateBranchFailed": "リモートブランチを更新できませんでした。「PR を作成」を再試行してください。"
|
||||
},
|
||||
"hostedReviewRemotePrerequisite": {
|
||||
"forcePushFailed": "lease 付きの強制プッシュに失敗しました。",
|
||||
"publishFailed": "ブランチの公開に失敗しました。",
|
||||
"pushFailed": "コミットのプッシュに失敗しました。"
|
||||
},
|
||||
"hostedReviewService": {
|
||||
"createFailed": "PR の作成に失敗しました。",
|
||||
"pushBeforeCreateFailed": "プッシュに失敗しました。プッシュのエラーを解決してから、もう一度お試しください。"
|
||||
},
|
||||
"hubTab": {
|
||||
"changes": "変更点",
|
||||
"commits": "コミット",
|
||||
"pullRequest": "PR"
|
||||
},
|
||||
"loaders": {
|
||||
"connectingToDesktop": "デスクトップに接続中…",
|
||||
"loadFailed": "ソース管理を読み込めませんでした。",
|
||||
"updateDesktop": "モバイルでソース管理を使うには、デスクトップ版 Orca を更新してください。",
|
||||
"waitingForDesktop": "デスクトップへの接続を待機中…"
|
||||
},
|
||||
"modals": {
|
||||
"actionsTitle": "ソース管理",
|
||||
"currentBranch": "現在",
|
||||
"discardButton": "破棄",
|
||||
"discardConfirmMessage": "「{{path}}」への変更を破棄しますか?この操作は取り消せません。",
|
||||
"discardTitle": "変更を破棄",
|
||||
"openPrMessage": "ブラウザで開きますか?",
|
||||
"openPrWithWarning": "ブラウザで開きますか?\n\n{{warning}}",
|
||||
"prCreatedTitle": "PR を作成しました",
|
||||
"switchBranchTitle": "ブランチを切り替え"
|
||||
},
|
||||
"openers": {
|
||||
"openDiffFailed": "差分を開けませんでした。",
|
||||
"tabNotReady": "ファイルは開きましたが、タブの準備がまだできていません。再試行してください。",
|
||||
"waitingForDesktop": "デスクトップへの接続を待機中…"
|
||||
},
|
||||
"panel": {
|
||||
"loadFailedTitle": "読み込めません",
|
||||
"unavailableTitle": "ソース管理を利用できません"
|
||||
},
|
||||
"prChip": {
|
||||
"createPr": "PR を作成",
|
||||
"loading": "PR を読み込み中…",
|
||||
"loadingLabel": "PR を読み込み中",
|
||||
"openLabel": "PR #{{number}}、{{state}}、{{checks}}。PR を開く。",
|
||||
"openWithComments_one": "PR #{{number}}、{{state}}、{{checks}}、未解決のコメント {{count}} 件。PR を開く。",
|
||||
"openWithComments_other": "PR #{{number}}、{{state}}、{{checks}}、未解決のコメント {{count}} 件。PR を開く。",
|
||||
"unavailableLabel": "PR を表示できません:{{message}}"
|
||||
},
|
||||
"prCreate": {
|
||||
"authRequired": "{{reviewLabel}} を作成する前に認証してください。",
|
||||
"baseNotOnRemote": "{{reviewLabel}} を作成する前にベースブランチをプッシュしてください。",
|
||||
@@ -2605,8 +2846,19 @@
|
||||
"unsupportedMergeRequests": "このリポジトリでは MR の作成に対応していません。",
|
||||
"unsupportedPullRequests": "このリポジトリでは PR の作成に対応していません。"
|
||||
},
|
||||
"prLink": {
|
||||
"updatePullRequestFailed": "リンクされた PR の更新に失敗しました。",
|
||||
"updateReviewFailed": "リンクされたレビューの更新に失敗しました。"
|
||||
},
|
||||
"primaryAction": {
|
||||
"forcePushFromDesktop": "デスクトップからこの PR のブランチを強制プッシュ"
|
||||
"commit": "Commit",
|
||||
"forcePush": "フォースプッシュ",
|
||||
"forcePushFromDesktop": "デスクトップからこの PR のブランチを強制プッシュ",
|
||||
"publishBranch": "ブランチを公開",
|
||||
"pull": "プル",
|
||||
"push": "プッシュ",
|
||||
"stageAll": "ステージオール",
|
||||
"sync": "同期"
|
||||
},
|
||||
"remoteDropdown": {
|
||||
"branchAlreadyPublished": "ブランチは既に公開されています",
|
||||
@@ -2656,6 +2908,591 @@
|
||||
"tryFastForwardPull": "fast-forward プルを試行します。git がローカルコミットを拒否する場合があります",
|
||||
"tryRegularPush": "通常のプッシュを試行します。git が強制プッシュを要求する場合があります",
|
||||
"useForcePushToSync": "強制プッシュを使用してください — リモートにはローカルコミットの古いコピーしかありません"
|
||||
},
|
||||
"runners": {
|
||||
"actionFailed": "ソース管理の操作に失敗しました。"
|
||||
},
|
||||
"screenState": {
|
||||
"noBranch": "ブランチなし"
|
||||
},
|
||||
"state": {
|
||||
"noUpstream": "アップストリームなし",
|
||||
"syncStatus": "{{ahead}} コミット先行、{{behind}} コミット遅れ"
|
||||
},
|
||||
"useMobileCommitFailureRecovery": {
|
||||
"launchFailed": "Agent の起動に失敗しました。",
|
||||
"waitingForDesktop": "デスクトップへの接続を待機中…"
|
||||
},
|
||||
"useMobileCommitMessageGeneration": {
|
||||
"generateFailed": "コミットメッセージの生成に失敗しました。"
|
||||
},
|
||||
"useMobileCreatePrRunner": {
|
||||
"branchRequired": "PR を作成する前にブランチをチェックアウトしてください。"
|
||||
},
|
||||
"useMobileGitRequests": {
|
||||
"actionFailed": "ソース管理の操作に失敗しました。",
|
||||
"branchUnavailable": "ブランチの状態を確認できません。",
|
||||
"commitFailed": "コミットに失敗しました。",
|
||||
"waitingForDesktop": "デスクトップへの接続を待機中…"
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"composerSource": {
|
||||
"baseFailed": "ベースブランチの特定に失敗しました。",
|
||||
"forkPushWarning": "この PR は「メンテナーによる編集を許可」がオフのため、フォークへのプッシュが GitHub に拒否される場合があります。"
|
||||
},
|
||||
"detailCommentRenderers": {
|
||||
"commentPlaceholder": "コメントを追加",
|
||||
"comments_one": "{{count}} 件のコメント",
|
||||
"comments_other": "{{count}} 件のコメント",
|
||||
"reopenThread": "スレッドを再開",
|
||||
"reply": "返事",
|
||||
"resolveThread": "スレッドを解決",
|
||||
"resolvedCommentBy": "{{author}} の解決済みコメント",
|
||||
"resolvedThreadBy": "{{author}} の解決済みスレッド",
|
||||
"sendComment": "コメントを送信",
|
||||
"show": "表示"
|
||||
},
|
||||
"filterPickers": {
|
||||
"allTeams": "全チーム",
|
||||
"changeStatus": "ステータスを変更",
|
||||
"fieldHidden": "カードでは非表示",
|
||||
"fieldShown": "カードに表示",
|
||||
"fieldsSubtitle": "アイテムカードに表示するプロジェクトのフィールドを選択してください。",
|
||||
"fieldsTitle": "プロジェクトのフィールド",
|
||||
"gitlabFilter": "GitLab フィルター",
|
||||
"gitlabView": "GitLab ビュー",
|
||||
"jiraFilter": "Jira フィルター",
|
||||
"jiraSite": "Jira サイト",
|
||||
"linearFilter": "Linear フィルター",
|
||||
"linearIssue": "Linear Issue",
|
||||
"linearWorkspace": "Linear ワークスペース",
|
||||
"loadingStates": "ステータスを読み込み中…",
|
||||
"noFields": "このビューに表示できる追加フィールドはありません。",
|
||||
"noStates": "利用可能なステータスがありません。",
|
||||
"switchWorkspaceFailed": "ワークスペースの切り替えに失敗しました",
|
||||
"teamsSubtitle": "「タスク」に表示するチームを選択してください。",
|
||||
"teamsTitle": "Linear チーム",
|
||||
"teams_one": "{{count}} チーム",
|
||||
"teams_other": "{{count}} チーム"
|
||||
},
|
||||
"githubProjectList": {
|
||||
"browseProjects": "プロジェクトを参照",
|
||||
"chooseProject": "GitHub プロジェクトを選択",
|
||||
"emptyField": "空欄",
|
||||
"issueSubtitle": "Issue · {{repository}}{{number}}",
|
||||
"itemSubtitle": "プロジェクトアイテム · {{repository}}{{number}}",
|
||||
"items": "アイテム",
|
||||
"moreFields_one": "+{{count}} フィールド",
|
||||
"moreFields_other": "+{{count}} フィールド",
|
||||
"noItems": "プロジェクトのアイテムがありません。",
|
||||
"pullRequestSubtitle": "PR · {{repository}}{{number}}"
|
||||
},
|
||||
"githubProjectPickers": {
|
||||
"add": "追加",
|
||||
"addByUrlHint": "表示されないプロジェクトは URL を入力して追加してください。",
|
||||
"addPlaceholder": "URL または所有者/番号で追加",
|
||||
"adding": "追加中…",
|
||||
"browseAll": "すべて閲覧する",
|
||||
"browseLoading": "すべて閲覧する(読み込み中…)",
|
||||
"chooseView": "プロジェクトビューを選択",
|
||||
"loadFailed": "プロジェクトのロードに失敗しました",
|
||||
"noMatches": "一致するプロジェクトがありません。",
|
||||
"noMoreProjects": "これ以上プロジェクトはありません。",
|
||||
"noProjects": "読み込み済みのプロジェクトがありません。",
|
||||
"organizationsError": "組織: {{message}}",
|
||||
"organizationsLoadFailed": "一部の組織を読み込めませんでした({{count}} 件)。",
|
||||
"ownerLoadFailed": "{{owner}} のプロジェクトを読み込めませんでした。",
|
||||
"pin": "ピン",
|
||||
"pinned": "ピン留め済み",
|
||||
"recent": "最近の",
|
||||
"retryHint": "タップして再試行してください。",
|
||||
"searchProjects": "プロジェクトを検索する",
|
||||
"sort": "プロジェクトの並べ替え",
|
||||
"subtitle": "「タスク」ページで使うプロジェクトビューを選択してください。",
|
||||
"title": "GitHub Projects",
|
||||
"unsupportedLayout": "Orca はこの GitHub プロジェクトのレイアウトにまだ対応していません。",
|
||||
"view": "プロジェクトビュー"
|
||||
},
|
||||
"githubViewControls": {
|
||||
"fields": "フィールド: {{fields}}",
|
||||
"openView": "GitHub でビューを開く",
|
||||
"sort": "並べ替え: {{sort}}",
|
||||
"source": "ソース: {{source}}"
|
||||
},
|
||||
"itemActions": {
|
||||
"changeStatus": "ステータスを変更",
|
||||
"copyGitHubLink": "GitHub リンクをコピーする",
|
||||
"copyLinearLink": "Linear リンクをコピーする",
|
||||
"createWorkspace": "ワークスペースを作成",
|
||||
"creating": "作成中…",
|
||||
"mergeConflicts": "GitHub でマージの競合が報告されています。",
|
||||
"mergeMergeRequest": "MR をマージ",
|
||||
"mergePullRequest": "PR をマージ"
|
||||
},
|
||||
"itemDetailContent": {
|
||||
"addSubIssue": "サブ Issue を追加",
|
||||
"assignee": "担当者",
|
||||
"assignees": "担当者",
|
||||
"checks": "チェック",
|
||||
"description": "説明",
|
||||
"discussion": "ディスカッション",
|
||||
"noChecks": "チェックが見つかりません。",
|
||||
"noComments": "コメントはありません。",
|
||||
"noPipelineRuns": "この MR のパイプライン実行履歴はありません。",
|
||||
"noSubIssues": "サブ Issue はありません。",
|
||||
"none": "なし",
|
||||
"pipeline": "パイプライン",
|
||||
"pipelineJobs_one": "{{count}} 件のジョブ",
|
||||
"pipelineJobs_other": "{{count}} 件のジョブ",
|
||||
"project": "プロジェクト",
|
||||
"rerunAll": "すべて再実行",
|
||||
"rerunFailed": "失敗分を再実行",
|
||||
"status": "状態",
|
||||
"subIssueTitle": "サブ Issue のタイトル",
|
||||
"subIssues": "サブ Issue",
|
||||
"type": "種類"
|
||||
},
|
||||
"itemDetailDrawer": {
|
||||
"refreshDetails": "詳細を更新"
|
||||
},
|
||||
"itemFieldEditors": {
|
||||
"addLabels": "追加するラベル(カンマ区切り)",
|
||||
"addUsernames": "追加するユーザー名(カンマ区切り)",
|
||||
"assignees": "担当者",
|
||||
"labels": "ラベル",
|
||||
"loadingAssignees": "担当者を読み込み中…",
|
||||
"loadingLabels": "ラベルを読み込み中…",
|
||||
"noAssignableUsers": "このリポジトリで担当者に指定できるユーザーが見つかりませんでした。",
|
||||
"noLabels": "このリポジトリにはラベルがありません。",
|
||||
"none": "なし",
|
||||
"removeLabels": "削除するラベル(カンマ区切り)",
|
||||
"removeUsernames": "削除するユーザー名(カンマ区切り)",
|
||||
"saveTitle": "タイトルを保存",
|
||||
"title": "タイトル",
|
||||
"updateAssignees": "担当者を更新",
|
||||
"updateLabels": "ラベルを更新"
|
||||
},
|
||||
"itemReviewSections": {
|
||||
"binaryFile": "バイナリファイルです。",
|
||||
"changedFilesTitle": "変更済みファイル",
|
||||
"descriptionPlaceholder": "説明",
|
||||
"fileContentsUnavailable": "ファイルの内容を表示できません。",
|
||||
"hideFile": "非表示",
|
||||
"loadingReviewers": "レビュアーを読み込み中…",
|
||||
"markUnviewed": "未閲覧としてマークする",
|
||||
"markViewed": "閲覧済みとしてマークする",
|
||||
"noDescription": "説明はありません。",
|
||||
"noReviewerSuggestions": "レビュアーの候補が見つかりませんでした。",
|
||||
"noReviewersRequested": "レビュアーはリクエストされていません。",
|
||||
"requestReview": "レビューを依頼",
|
||||
"reviewersPlaceholder": "依頼するレビュアー",
|
||||
"reviewersTitle": "レビュアー",
|
||||
"saveDescription": "説明を保存",
|
||||
"viewFile": "表示"
|
||||
},
|
||||
"legacySurface": {
|
||||
"loadIssuesFailed": "{{source}} から Issue を読み込めませんでした。",
|
||||
"mergeAction": "マージ",
|
||||
"mergeMethodTitle": "マージ方法",
|
||||
"mergePullRequestTitle": "PR をマージ",
|
||||
"mergeRequestMergeMessage": "この MR のマージ方法を選択してください。",
|
||||
"mergeRequestTitle": "MR をマージ",
|
||||
"pullRequestMergeMessage": "この PR のマージ方法を選択してください。",
|
||||
"retryLoadingIssues": "{{source}} からの Issue の読み込みを再試行",
|
||||
"retrying": "再試行中…",
|
||||
"sourceFallback": "{{repo}} では優先する Issue ソースの upstream が利用できません。origin を使用します。",
|
||||
"subIssueDataUnavailable": "トークンではサブ Issue データを利用できません。",
|
||||
"updateItemTitle": "項目を更新"
|
||||
},
|
||||
"linearList": {
|
||||
"changeStatusFrom": "状態を「{{status}}」から変更"
|
||||
},
|
||||
"linearViewControls": {
|
||||
"displayButton": "表示",
|
||||
"groupLabel": "グループ化:{{group}}",
|
||||
"orderLabel": "並べ替え:{{order}}"
|
||||
},
|
||||
"listDisplayPickers": {
|
||||
"displayPropertiesTitle": "表示項目",
|
||||
"linearGroupTitle": "Linear の Issue をグループ化",
|
||||
"linearOrderTitle": "Linear の Issue を並べ替え",
|
||||
"linearViewTitle": "Linear の表示",
|
||||
"sortTasksTitle": "タスクを並べ替え"
|
||||
},
|
||||
"listSurface": {
|
||||
"connectLinearButton": "Linear に接続",
|
||||
"connectLinearMessage": "「タスク」から、担当する Linear の Issue を確認して作業を開始できます。",
|
||||
"connectLinearTitle": "Linear アカウントを接続する",
|
||||
"jiraStatusFailed": "Jira の状態の読み取りに失敗しました。",
|
||||
"updateDesktopMessage": "モバイルの「タスク」画面には、新しいバージョンのデスクトップランタイムが必要です。",
|
||||
"updateDesktopTitle": "Orca デスクトップを更新"
|
||||
},
|
||||
"options": {
|
||||
"all": "全て",
|
||||
"assignedToMe": "私に割り当てられた Issue",
|
||||
"assignee": "担当者",
|
||||
"board": "ボード",
|
||||
"boardDescription": "グループ別の列で表示",
|
||||
"closedState": "クローズ",
|
||||
"completedState": "完了",
|
||||
"createdState": "自分が作成",
|
||||
"githubAssignedIssuesDescription": "私に割り当てられたオープンな Issue",
|
||||
"githubDescription": "Issue と PR",
|
||||
"githubIssuesDescription": "GitHub Issue",
|
||||
"githubOpenIssuesDescription": "オープンな GitHub Issue",
|
||||
"githubProjectsDescription": "GitHub Projects のビュー",
|
||||
"githubPullRequestsDescription": "GitHub PR",
|
||||
"gitlabAllDescription": "GitLab の全ての状態",
|
||||
"gitlabClosedDescription": "クローズした Issue と MR",
|
||||
"gitlabDescription": "Issue と MR",
|
||||
"gitlabMergedDescription": "マージ済みの MR",
|
||||
"gitlabOpenDescription": "オープンな Issue と MR",
|
||||
"identifier": "識別子",
|
||||
"issues": "Issue",
|
||||
"jiraDescription": "担当する Issue と報告した Issue",
|
||||
"labels": "ラベル",
|
||||
"linearAllDescription": "接続済みワークスペース全体のオープンな Issue",
|
||||
"linearAssignedDescription": "自分が担当する Issue",
|
||||
"linearCompletedDescription": "最近完了した Issue",
|
||||
"linearCreatedDescription": "自分が作成した Issue",
|
||||
"linearDescription": "担当する Issue とチームの Issue",
|
||||
"list": "リスト",
|
||||
"listDescription": "Issue をコンパクトに一覧表示",
|
||||
"mergedState": "マージ済み",
|
||||
"mine": "私の",
|
||||
"myIssues": "自分の Issue",
|
||||
"myPullRequestsDescription": "私が作成した PR",
|
||||
"myTodos": "私の ToDo",
|
||||
"myTodosDescription": "未処理の GitLab ToDo",
|
||||
"needsReview": "レビュー待ち",
|
||||
"noGrouping": "グループ化なし",
|
||||
"openPullRequestsDescription": "オープンな PR",
|
||||
"openState": "オープン",
|
||||
"priority": "優先度",
|
||||
"projectMergeRequests": "プロジェクトの MR",
|
||||
"projectMergeRequestsDescription": "リポジトリ別の MR と Issue",
|
||||
"projects": "プロジェクト",
|
||||
"pullRequests": "PR",
|
||||
"repository": "リポジトリ",
|
||||
"repositorySortDescription": "リポジトリ別にグループ化し、アクティビティが新しい順に表示",
|
||||
"reviewRequestsDescription": "私に割り当てられたレビュー依頼",
|
||||
"status": "状態",
|
||||
"team": "チーム",
|
||||
"updated": "更新日時",
|
||||
"updatedSortDescription": "アクティビティが新しい順"
|
||||
},
|
||||
"pickerProjection": {
|
||||
"allRepos": "すべてのリポジトリ",
|
||||
"allSites": "すべてのサイト",
|
||||
"currentlyAscending": "現在は昇順・タップで降順に変更",
|
||||
"currentlyDescending": "現在は降順・タップで昇順に変更",
|
||||
"fieldAscending": "{{field}} 昇順",
|
||||
"fieldDescending": "{{field}} 降順",
|
||||
"fields": "フィールド",
|
||||
"repos_one": "{{count}} 件のリポジトリ",
|
||||
"repos_other": "{{count}} 件のリポジトリ",
|
||||
"selectTarget": "作成先を選択",
|
||||
"selectedFields": "{{selected}}/{{total}} フィールド",
|
||||
"sortAscending": "昇順に並べ替え",
|
||||
"sources_one": "{{count}} 件のソース",
|
||||
"sources_other": "{{count}} 件のソース",
|
||||
"unsupportedLayout": "モバイルでは未対応のレイアウト",
|
||||
"updatedSort": "更新日時",
|
||||
"usesFieldAscending": "{{field}} の昇順を使用",
|
||||
"usesFieldDescending": "{{field}} の降順を使用",
|
||||
"usesGitHubRankOrder": "GitHub のランク順を使用",
|
||||
"viewNumber": "ビュー #{{number}}",
|
||||
"viewOrder": "ビューの並び順"
|
||||
},
|
||||
"prFileDiff": {
|
||||
"commentOnLine": "{{line}} 行目にコメント",
|
||||
"commentPlaceholder": "レビューコメントを追加",
|
||||
"noTextChanges": "テキストの変更はありません。",
|
||||
"showingDiffLines": "差分の全 {{total}} 行中、先頭 {{limit}} 行を表示しています。"
|
||||
},
|
||||
"projectComments": {
|
||||
"comments_one": "{{count}} 件のコメント",
|
||||
"comments_other": "{{count}} 件のコメント",
|
||||
"discussion": "ディスカッション",
|
||||
"editComment": "コメントを編集",
|
||||
"noComments": "コメントはありません。",
|
||||
"reopenThread": "スレッドを再開",
|
||||
"reply": "返事",
|
||||
"resolveThread": "スレッドを解決",
|
||||
"resolvedCommentBy": "{{author}} のコメント(解決済み)",
|
||||
"resolvedThreadBy": "{{author}} のスレッド(解決済み)",
|
||||
"show": "表示"
|
||||
},
|
||||
"projectDetailDrawer": {
|
||||
"addRepositoryFromDesktop": "{{repository}} は Orca に追加されていません。デスクトップアプリからこのリポジトリを追加し、モバイルの「タスク」を更新してください。",
|
||||
"clearType": "種類をクリア",
|
||||
"closeItem": "項目をクローズ",
|
||||
"copyGitHubLink": "GitHub リンクをコピーする",
|
||||
"copyRepository": "リポジトリ名をコピー",
|
||||
"createWorkspace": "ワークスペースを作成",
|
||||
"draftIssue": "下書きの Issue",
|
||||
"issue": "Issue",
|
||||
"issueType": "Issue の種類",
|
||||
"loadingIssueTypes": "Issue の種類を読み込み中…",
|
||||
"mergePullRequest": "PR をマージ",
|
||||
"mergeRepositoryRequirement": "マージするには、このリポジトリを Orca に追加する必要があります。",
|
||||
"noIssueTypes": "このリポジトリには Issue の種類が設定されていません。",
|
||||
"noType": "種類なし",
|
||||
"openInGitHub": "GitHub で開く",
|
||||
"projectItem": "プロジェクト項目",
|
||||
"projectSubtitle": "GitHub プロジェクト · {{repository}}{{itemNumber}}",
|
||||
"pullRequest": "PR",
|
||||
"reopenItem": "項目を再オープン",
|
||||
"repositoryNotInOrca": "このリポジトリは Orca に登録されていません",
|
||||
"status": "状態",
|
||||
"type": "種類",
|
||||
"workspaceCreationRequirement": "ワークスペースは GitHub の Issue と PR からのみ作成できます。"
|
||||
},
|
||||
"projectFieldEditors": {
|
||||
"clearField": "フィールドをクリア",
|
||||
"completedIteration": "完了 · {{startDate}} · {{duration}} 日",
|
||||
"datePlaceholder": "YYYY-MM-DD",
|
||||
"invalidDate": "日付は YYYY-MM-DD 形式で入力してください。",
|
||||
"invalidNumber": "有効な数値を入力してください。",
|
||||
"noIterations": "利用可能なイテレーションはありません。",
|
||||
"numberPlaceholder": "数値",
|
||||
"projectFields": "プロジェクトのフィールド",
|
||||
"saveField": "フィールドを保存",
|
||||
"textPlaceholder": "テキスト",
|
||||
"upcomingIteration": "現在および今後の予定 · {{startDate}} · {{duration}} 日"
|
||||
},
|
||||
"projectMetadataEditors": {
|
||||
"assignees": "担当者",
|
||||
"description": "説明",
|
||||
"labels": "ラベル",
|
||||
"loadingAssignees": "担当者を読み込み中…",
|
||||
"loadingLabels": "ラベルを読み込み中…",
|
||||
"noAssignableUsers": "このリポジトリで割り当て可能なユーザーが見つかりません。",
|
||||
"noDescription": "説明はありません。",
|
||||
"noLabels": "このリポジトリにはラベルがありません。",
|
||||
"none": "なし",
|
||||
"saveDescription": "説明を保存",
|
||||
"saveTitle": "タイトルを保存",
|
||||
"title": "タイトル"
|
||||
},
|
||||
"projectReviewPanels": {
|
||||
"binaryFile": "バイナリファイルです。",
|
||||
"changedFiles": "変更済みファイル",
|
||||
"checks": "チェック",
|
||||
"fileUnavailable": "ファイルの内容を表示できません。",
|
||||
"hideFile": "非表示",
|
||||
"loadingReviewers": "レビュアーを読み込み中…",
|
||||
"markUnviewed": "未閲覧としてマークする",
|
||||
"markViewed": "閲覧済みとしてマークする",
|
||||
"noChecks": "チェックが見つかりません。",
|
||||
"noReviewers": "レビュアーはリクエストされていません。",
|
||||
"noSuggestions": "レビュアー候補が見つかりません。",
|
||||
"requestReview": "レビューを依頼",
|
||||
"requestReviewers": "レビューの依頼先",
|
||||
"rerunAll": "すべて再実行",
|
||||
"rerunFailed": "失敗分を再実行",
|
||||
"reviewers": "レビュアー",
|
||||
"viewFile": "表示"
|
||||
},
|
||||
"providerControls": {
|
||||
"myTodos": "自分の ToDo",
|
||||
"projectMergeRequests": "プロジェクトの MR",
|
||||
"sort": "並べ替え:{{sortLabel}}"
|
||||
},
|
||||
"providerItemList": {
|
||||
"intoBranch": "{{base}} へ",
|
||||
"nextPage": "次のページ",
|
||||
"page": "{{page}} ページ",
|
||||
"pageOfTotal": "{{page}} / {{total}} ページ",
|
||||
"previousPage": "前のページへ",
|
||||
"selectPage": "ページを選択、{{page}} ページ",
|
||||
"selectPageOfTotal": "ページを選択、全 {{total}} ページ中 {{page}} ページ"
|
||||
},
|
||||
"providerPickers": {
|
||||
"allRepositories": "すべてのリポジトリ",
|
||||
"githubView": "GitHub の表示",
|
||||
"issueSources": "GitHub Issue の取得元",
|
||||
"issueSourcesDescription": "リポジトリごとに、検索や作業の作成に使うソースを upstream または origin から選択してください。",
|
||||
"issues": "Issue",
|
||||
"noIssueSources": "ほかに利用できる Issue の取得元はありません。",
|
||||
"origin": "origin",
|
||||
"pageHint": "読み込み済みまたは利用可能な結果ページに移動します。",
|
||||
"pageLoaded": "読み込み済み",
|
||||
"pageNotLoaded": "以前の結果を読み込み",
|
||||
"pageNumber": "{{page}} ページ",
|
||||
"pages": "GitHub の結果ページ",
|
||||
"pullRequests": "PR",
|
||||
"queryingSource": "検索対象: {{source}}",
|
||||
"repoDescription": "検索対象のリポジトリを選択してください。",
|
||||
"repos": "リポジトリ",
|
||||
"taskSource": "タスクソース",
|
||||
"upstream": "upstream"
|
||||
},
|
||||
"providerViewProjection": {
|
||||
"all": "全て",
|
||||
"allSites": "すべてのサイト",
|
||||
"allTeams": "全チーム",
|
||||
"allWorkspaces": "すべてのワークスペース",
|
||||
"chooseProject": "プロジェクトを選択",
|
||||
"default": "デフォルト",
|
||||
"defaultSubtitle": "{{subtitle}} · デフォルト",
|
||||
"issues": "Issue",
|
||||
"list": "リスト",
|
||||
"noGrouping": "グループ化なし",
|
||||
"openState": "オープン",
|
||||
"priority": "優先度",
|
||||
"projects": "プロジェクト",
|
||||
"pullRequests": "PR",
|
||||
"teams_one": "{{count}} チーム",
|
||||
"teams_other": "{{count}} チーム",
|
||||
"workspace": "ワークスペース"
|
||||
},
|
||||
"reviewerLinear": {
|
||||
"issues": "Issue",
|
||||
"unassigned": "未割り当て"
|
||||
},
|
||||
"screenChrome": {
|
||||
"connectLinear": "Linear に接続",
|
||||
"newGitHubIssue": "GitHub の新規 Issue",
|
||||
"newLinearIssue": "新規 Linear Issue",
|
||||
"refreshGitHub": "GitHub の作業を更新する",
|
||||
"refreshGitLab": "GitLab 作業項目を更新する",
|
||||
"refreshJira": "Jira Issue を更新する",
|
||||
"refreshLinear": "Linear を更新",
|
||||
"title": "タスク"
|
||||
},
|
||||
"searchControl": {
|
||||
"jiraPlaceholder": "Jira JQL(例:project = ABC AND statusCategory != Done)",
|
||||
"projectPlaceholder": "プロジェクトビューを検索…",
|
||||
"providerPlaceholder": "{{provider}} のタスクを検索…"
|
||||
},
|
||||
"smartSourceModes": {
|
||||
"allStates": "全て",
|
||||
"branch": "ブランチ",
|
||||
"closedState": "クローズ",
|
||||
"mergedState": "マージ済み",
|
||||
"name": "名前",
|
||||
"openState": "オープン",
|
||||
"smart": "スマート"
|
||||
},
|
||||
"sparsePresetDraft": {
|
||||
"directoryRequired": "少なくとも 1 つのディレクトリを追加してください。",
|
||||
"repoRelativeDirectoriesRequired": "ルート、絶対パス、親セグメントではなく、リポジトリ相対ディレクトリを使用してください。"
|
||||
},
|
||||
"taskViewOptions": {
|
||||
"allSubtitle": "選択したサイト全体の未解決の Issue",
|
||||
"assignedSubtitle": "自分に割り当てられた未解決の Issue",
|
||||
"doneSubtitle": "最近解決された自分の Issue",
|
||||
"noGitHubTasks": "GitHub のタスクはありません。",
|
||||
"noGitLabTasks": "GitLab のタスクはありません。",
|
||||
"noJiraTasks": "Jira のタスクはありません。",
|
||||
"noLinearTasks": "Linear のタスクはありません。",
|
||||
"reportedSubtitle": "報告した未解決の Issue"
|
||||
},
|
||||
"tasksCreateDrawers": {
|
||||
"connect": "接続",
|
||||
"connectLinearWorkspace": "Linear ワークスペースに接続",
|
||||
"createIssue": "Issue を作成",
|
||||
"createWorkspaceIn": "ワークスペースの作成先リポジトリ",
|
||||
"description": "説明",
|
||||
"descriptionPlaceholder": "背景情報を追加",
|
||||
"fileIn": "{{slug}} に登録",
|
||||
"issueSource": "Issue ソース",
|
||||
"keySecurityHint": "キーはホスト OS のキーチェーンで暗号化され、ローカルに保存されます。",
|
||||
"linearConnectSubtitle": "ワークスペースの Issue を閲覧するには、個人用 API キーを貼り付けてください。",
|
||||
"linearSettingsLink": "Linear の設定 / セキュリティ / 新規 API キー",
|
||||
"linearTeam": "Linear チーム",
|
||||
"linearTeamSubtitle": "選択した Linear チームに Issue を作成します。",
|
||||
"newIssueTitle": "{{providerLabel}} の新規 Issue",
|
||||
"origin": "オリジン",
|
||||
"personalApiKey": "個人用APIキー",
|
||||
"repository": "リポジトリ",
|
||||
"repositorySubtitle": "選択したリポジトリに Issue を作成します。",
|
||||
"team": "チーム",
|
||||
"title": "タイトル",
|
||||
"titlePlaceholder": "タスクのタイトル",
|
||||
"upstream": "upstream"
|
||||
},
|
||||
"workspaceAgentSelection": {
|
||||
"blankTerminal": "ブランクターミナル"
|
||||
},
|
||||
"workspaceCreateDrawer": {
|
||||
"addRepository": "Linear の Issue からワークスペースを作成する前に、Git リポジトリを追加してください。",
|
||||
"advanced": "詳細設定",
|
||||
"agent": "Agent",
|
||||
"connect": "接続",
|
||||
"connectFirst": "先にリポジトリに接続",
|
||||
"connectRepository": "リポジトリに接続",
|
||||
"connecting": "接続中…",
|
||||
"createFrom": "{{branch}} から作成",
|
||||
"defaultBranch": "デフォルトブランチ",
|
||||
"detectingAgents": "Agent を検出中…",
|
||||
"optional": "[オプション]",
|
||||
"remoteRepository": "リモートリポジトリ",
|
||||
"repository": "リポジトリ",
|
||||
"repositoryNotFound": "リポジトリが見つかりません。",
|
||||
"selectRepository": "リポジトリを選択",
|
||||
"sshConnection": "SSH 接続",
|
||||
"startFrom": "作成元",
|
||||
"title": "ワークスペースを作成",
|
||||
"workspaceName": "ワークスペース名"
|
||||
},
|
||||
"workspaceCreateProjection": {
|
||||
"nameAlreadyExists": "「{{name}}」は既に存在します。",
|
||||
"nameRequired": "名前を入力してください。",
|
||||
"nameTooLong": "名前は80文字以内にしてください。",
|
||||
"openShell": "シェルを開く"
|
||||
},
|
||||
"workspaceOptionPickers": {
|
||||
"baseBranchSubtitle": "既存のブランチまたは参照を選択してください。",
|
||||
"baseBranchTitle": "作成元",
|
||||
"branchName": "ブランチ名: {{name}}",
|
||||
"defaultBranch": "デフォルトブランチ",
|
||||
"defaultBranchSubtitle": "このリポジトリに設定されたベースブランチを使用",
|
||||
"editPreset": "{{name}} を編集",
|
||||
"fullCheckout": "フルチェックアウト",
|
||||
"fullCheckoutSubtitle": "リポジトリ全体を使用",
|
||||
"newPreset": "新規プリセット",
|
||||
"noBranches": "一致するブランチはありません。",
|
||||
"searchBranches": "ブランチを検索",
|
||||
"sparseCheckoutTitle": "スパースチェックアウト"
|
||||
},
|
||||
"workspaceSshGate": {
|
||||
"authenticationFailed": "認証に失敗しました",
|
||||
"connected": "接続済み",
|
||||
"connecting": "接続中",
|
||||
"connectionFailed": "接続に失敗しました",
|
||||
"deployingRelay": "リレーをデプロイ中",
|
||||
"disconnected": "切断済み",
|
||||
"reconnectFailed": "再接続に失敗しました",
|
||||
"reconnecting": "再接続中"
|
||||
},
|
||||
"workspaceTrustDrawers": {
|
||||
"alwaysTrustAndRun": "常に信頼して実行",
|
||||
"creating": "作成中…",
|
||||
"directoriesLabel": "ディレクトリ",
|
||||
"directories_one": "{{count}} 個のディレクトリ",
|
||||
"directories_other": "{{count}} 個のディレクトリ",
|
||||
"dontRun": "実行しない",
|
||||
"editSparsePreset": "スパースプリセットを編集",
|
||||
"nameLabel": "名前",
|
||||
"namePlaceholder": "レンダラー UI",
|
||||
"newSetupScript": "新しいセットアップスクリプト",
|
||||
"newSparsePreset": "新しいスパースプリセット",
|
||||
"runHooks": "フックを実行する",
|
||||
"runSetupAndCreate": "セットアップを実行して作成",
|
||||
"runSetupTitle": "{{name}} のセットアップを実行しますか?",
|
||||
"setupChangedTitle": "{{name}} のセットアップスクリプトが変更されました",
|
||||
"setupScript": "セットアップスクリプト",
|
||||
"setupSubtitle": "{{name}} でこのワークスペースを作成する前に、セットアップの実行有無を選択してください。",
|
||||
"setupTitle": "セットアップスクリプトを実行しますか?",
|
||||
"skipSetupAndCreate": "セットアップをスキップして作成",
|
||||
"trustFailed": "セットアップスクリプトの信頼設定に失敗しました。",
|
||||
"trustSubtitle": "このリポジトリの orca.yaml は、ワークスペースの起動前にコンピュータ上で実行されます。このリポジトリを信頼できる場合のみ実行してください。"
|
||||
},
|
||||
"worktreeCreateRetry": {
|
||||
"createFailed": "ワークスペースの作成に失敗しました"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
+861
-24
@@ -13,7 +13,7 @@
|
||||
"sessionWindow": "5시간",
|
||||
"switchFailed": "계정을 전환하지 못했습니다.",
|
||||
"title": "계정",
|
||||
"useReset": "초기화권 사용",
|
||||
"useReset": "재설정권 사용",
|
||||
"weeklyWindow": "7일"
|
||||
}
|
||||
},
|
||||
@@ -1491,7 +1491,21 @@
|
||||
"workspace": "워크스페이스"
|
||||
}
|
||||
},
|
||||
"newWorkspace": {
|
||||
"hostPicker": {
|
||||
"title": "워크스페이스 생성 호스트"
|
||||
},
|
||||
"loadingDrawer": {
|
||||
"downloadProgress": "다운로드 중… {{progress}}",
|
||||
"downloading": "다운로드 중",
|
||||
"loading": "로드 중"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"desktopChannel": {
|
||||
"name": "데스크톱 알림",
|
||||
"silentName": "Orca 무음 알림"
|
||||
},
|
||||
"notificationDeliverySection": {
|
||||
"footer": "알림 유형은 페어링된 각 데스크톱의 알림 설정을 따릅니다. 이 앱을 7일 동안 사용하지 않으면 알림이 일시 중지됩니다. 다시 받으려면 앱을 열고 다시 연결하세요.",
|
||||
"onlyWhenAway": "데스크톱을 사용하지 않을 때만",
|
||||
@@ -2034,9 +2048,9 @@
|
||||
"switchToTerminalView": "터미널 보기로 전환"
|
||||
},
|
||||
"newTabAgentHostLaunch": {
|
||||
"notesNotSent": "에이전트가 시작되었지만 노트가 전송되지 않았습니다.",
|
||||
"notesSent": "노트 전송됨",
|
||||
"notesUnconfirmed": "에이전트가 시작되었지만 노트가 전송되었는지 확인하지 못했습니다.",
|
||||
"notesNotSent": "에이전트가 시작되었지만 메모가 전송되지 않았습니다.",
|
||||
"notesSent": "메모 전송됨",
|
||||
"notesUnconfirmed": "에이전트가 시작되었지만 메모가 전송되었는지 확인하지 못했습니다.",
|
||||
"promptUnconfirmed": "에이전트가 시작되었지만 프롬프트가 전송되었는지 확인하지 못했습니다."
|
||||
},
|
||||
"prActionsEngine": {
|
||||
@@ -2162,7 +2176,7 @@
|
||||
"draftsHint": "나가기 전에 휴대폰의 초안을 복사하거나 버리세요.",
|
||||
"file": "파일",
|
||||
"markdown": "Markdown",
|
||||
"markdownNote": "Markdown 메모",
|
||||
"markdownNote": "Markdown 노트",
|
||||
"newBrowser": "새 브라우저",
|
||||
"newTab": "새 탭",
|
||||
"notesCopied": "메모를 복사했습니다.",
|
||||
@@ -2254,12 +2268,12 @@
|
||||
"untitledNoteCreateFailed": "제목 없는 Markdown 노트를 만들 수 없습니다."
|
||||
},
|
||||
"useDiffComments": {
|
||||
"copyNotesFailed": "노트를 복사하지 못했습니다.",
|
||||
"deleteNoteFailed": "노트를 삭제하지 못했습니다.",
|
||||
"noteAdded": "노트 추가됨",
|
||||
"notesCopied": "노트 복사됨",
|
||||
"saveNoteFailed": "노트를 저장하지 못했습니다.",
|
||||
"saveNotesFailed": "리뷰 노트를 저장하지 못했습니다.",
|
||||
"copyNotesFailed": "메모를 복사하지 못했습니다.",
|
||||
"deleteNoteFailed": "메모를 삭제하지 못했습니다.",
|
||||
"noteAdded": "메모 추가됨",
|
||||
"notesCopied": "메모 복사됨",
|
||||
"saveNoteFailed": "메모를 저장하지 못했습니다.",
|
||||
"saveNotesFailed": "리뷰 메모를 저장하지 못했습니다.",
|
||||
"waitingForDesktop": "데스크톱 대기 중…"
|
||||
},
|
||||
"useDiffReviewCommentActions": {
|
||||
@@ -2287,14 +2301,14 @@
|
||||
"openFailed": "세션에서 열 수 없습니다."
|
||||
},
|
||||
"useDiffReviewSendActions": {
|
||||
"copyFailed": "리뷰 노트를 복사할 수 없습니다.",
|
||||
"copyFailed": "리뷰 메모를 복사할 수 없습니다.",
|
||||
"inputLocked": "터미널 입력이 잠겨 있습니다.",
|
||||
"loadSessionsFailed": "에이전트 세션을 로드할 수 없습니다.",
|
||||
"notesCopied": "리뷰 노트 복사됨",
|
||||
"notesSent": "리뷰 노트 전송됨",
|
||||
"notesSentWithWarning": "리뷰 노트를 전송했습니다. {{warning}}",
|
||||
"promptNotSent": "에이전트가 시작되었지만 노트가 전송되지 않았습니다. '노트 복사'로 복사한 후 붙여넣으세요.",
|
||||
"sendFailed": "노트를 전송하지 못했습니다.",
|
||||
"notesCopied": "리뷰 메모 복사됨",
|
||||
"notesSent": "리뷰 메모 전송됨",
|
||||
"notesSentWithWarning": "리뷰 메모를 전송했습니다. {{warning}}",
|
||||
"promptNotSent": "에이전트가 시작되었지만 메모가 전송되지 않았습니다. '메모 복사'로 복사한 후 붙여넣으세요.",
|
||||
"sendFailed": "메모를 전송하지 못했습니다.",
|
||||
"startingAgent": "에이전트 시작 중…",
|
||||
"waitingForDesktop": "데스크톱 연결 대기 중…"
|
||||
},
|
||||
@@ -2324,7 +2338,7 @@
|
||||
},
|
||||
"usePanelRouteActions": {
|
||||
"checkHostHint": "호스트 연결을 확인하세요.",
|
||||
"copyNotesHint": "대신 노트를 복사하세요.",
|
||||
"copyNotesHint": "대신 메모를 복사하세요.",
|
||||
"detectingAgents": "에이전트 감지 중",
|
||||
"newSessionHint": "새 에이전트 세션",
|
||||
"noEnabledAgents": "활성화된 에이전트 없음",
|
||||
@@ -2358,9 +2372,9 @@
|
||||
"forkBusy": "다른 터미널을 여는 중입니다. 잠시 기다린 후 {{agentName}} 채팅을 다시 시도하세요.",
|
||||
"forkUnavailable": "연결되어 있고 업데이트된 호스트에서 {{agentName}} 채팅을 열고 다시 시도하세요.",
|
||||
"inputLocked": "터미널 입력이 다른 클라이언트에 의해 잠겨 있습니다.",
|
||||
"notesSent": "노트 전송됨",
|
||||
"sendNotesError": "노트를 보내지 못했습니다.",
|
||||
"sendNotesFailed": "노트를 보내지 못했습니다.",
|
||||
"notesSent": "메모 전송됨",
|
||||
"sendNotesError": "메모를 보내지 못했습니다.",
|
||||
"sendNotesFailed": "메모를 보내지 못했습니다.",
|
||||
"terminalTitle": "터미널"
|
||||
},
|
||||
"useTerminalInput": {
|
||||
@@ -2520,11 +2534,67 @@
|
||||
}
|
||||
},
|
||||
"sourceControl": {
|
||||
"actionSheetRunners": {
|
||||
"noBaseBranch": "리베이스할 기본 브랜치가 없습니다.",
|
||||
"waitingForDesktop": "데스크톱 연결 대기 중…"
|
||||
},
|
||||
"actions": {
|
||||
"checkingReviewStatus": "리뷰 상태를 확인 중입니다.",
|
||||
"checkoutBeforePublish": "커밋을 게시하기 전에 브랜치를 체크아웃하세요.",
|
||||
"commitStagedChanges": "스테이징된 변경 사항을 커밋하세요.",
|
||||
"commits": "커밋",
|
||||
"committing": "커밋이 진행 중입니다.",
|
||||
"createPr": "PR 작성",
|
||||
"enterCommitMessage": "커밋하려면 커밋 메시지를 입력하세요.",
|
||||
"forcePushWithLease": "원격 브랜치를 업데이트하려면 lease로 강제 푸시하세요.",
|
||||
"forcePushing": "강제 푸시가 진행 중입니다.",
|
||||
"linkedReviewUnavailable": "연결된 리뷰 브랜치를 사용할 수 없습니다.",
|
||||
"publishToOrigin": "이 브랜치를 origin에 게시하세요.",
|
||||
"pullCommits_one": "커밋 {{count}}개를 풀하세요.",
|
||||
"pullCommits_other": "커밋 {{count}}개를 풀하세요.",
|
||||
"pushAndCreatePr": "푸시 및 PR 작성",
|
||||
"switchBranch": "브랜치 전환"
|
||||
"pushCommits_one": "커밋 {{count}}개를 푸시하세요.",
|
||||
"pushCommits_other": "커밋 {{count}}개를 푸시하세요.",
|
||||
"pushLinkedReview": "연결된 리뷰 브랜치에 업데이트를 푸시하세요.",
|
||||
"remoteOperationInProgress": "원격 작업이 진행 중입니다.",
|
||||
"resolveConflicts": "커밋하기 전에 충돌을 해결하세요.",
|
||||
"reviewAlreadyMerged": "커밋할 항목이 없습니다. 리뷰가 이미 병합되었습니다.",
|
||||
"stageAllChanges": "모든 변경 사항을 스테이지하세요.",
|
||||
"stageFileToCommit": "커밋하려면 파일을 하나 이상 스테이지하세요.",
|
||||
"switchBranch": "브랜치 전환",
|
||||
"syncCounts": "커밋 {{behind}}개를 풀하고 {{ahead}}개를 푸시하세요.",
|
||||
"upToDate": "커밋할 항목이 없습니다. 브랜치가 최신 상태입니다.",
|
||||
"waitForRemoteOperation": "원격 작업이 끝나면 다시 시도하세요."
|
||||
},
|
||||
"branchBaseRef": {
|
||||
"resolveFailed": "브랜치의 기준점을 확인할 수 없습니다."
|
||||
},
|
||||
"branchCard": {
|
||||
"branchCount": "브랜치 변경 {{count}}개",
|
||||
"changedCount": "변경 {{count}}개",
|
||||
"cherryPickState": "체리픽",
|
||||
"mergeState": "병합",
|
||||
"rebaseState": "리베이스",
|
||||
"stagedCount": "{{count}}개 스테이징됨"
|
||||
},
|
||||
"branchCompare": {
|
||||
"commits_one": "커밋 {{count}}개",
|
||||
"commits_other": "커밋 {{count}}개",
|
||||
"files_one": "파일 {{count}}개",
|
||||
"files_other": "파일 {{count}}개",
|
||||
"sectionTitle": "브랜치에 커밋됨",
|
||||
"summary": "{{files}} - {{baseRef}} 대비",
|
||||
"summaryWithCommits": "{{files}} - {{commits}} - {{baseRef}} 대비"
|
||||
},
|
||||
"branchCompareOutcome": {
|
||||
"baseBranchUnavailable": "비교할 기본 브랜치를 확인할 수 없습니다.",
|
||||
"loadFailed": "커밋된 변경 사항을 로드할 수 없습니다."
|
||||
},
|
||||
"branchDiffPreviewDrawer": {
|
||||
"closePreview": "커밋된 차이점 미리보기 닫기",
|
||||
"committedOnBranch": "브랜치에 커밋됨",
|
||||
"loadFailed": "차이점을 불러올 수 없음",
|
||||
"truncated": "모바일 미리보기용으로 차이점의 일부가 생략되었습니다."
|
||||
},
|
||||
"commitDropdown": {
|
||||
"checkOutBranchToPush": "커밋을 푸시하기 전에 브랜치를 체크아웃하세요",
|
||||
@@ -2549,8 +2619,49 @@
|
||||
"stageFile": "commit 할 파일을 하나 이상 스테이지하세요",
|
||||
"useCommitAndForcePush": "Commit 및 강제 푸시를 사용하세요 — 원격에는 로컬 커밋의 이전 사본만 있습니다"
|
||||
},
|
||||
"commitFailurePanel": {
|
||||
"fix": "수정",
|
||||
"fixWithAi": "AI로 commit 실패 수정",
|
||||
"hideDetails": "세부 정보 숨기기",
|
||||
"hideFailureDetails": "커밋 실패 세부 정보 숨기기",
|
||||
"showDetails": "세부 정보 표시",
|
||||
"showFailureDetails": "커밋 실패 세부 정보 표시",
|
||||
"summary": "커밋에 실패했습니다.",
|
||||
"title": "커밋 실패"
|
||||
},
|
||||
"commitMessageAi": {
|
||||
"generateFailed": "커밋 메시지를 생성하지 못했습니다."
|
||||
},
|
||||
"commitRunners": {
|
||||
"actionFailed": "소스 제어 작업에 실패했습니다.",
|
||||
"commitFailed": "커밋 실패"
|
||||
},
|
||||
"conflictAbort": {
|
||||
"abortMerge": "병합 중단",
|
||||
"abortOperation": "{{operation}} 중단",
|
||||
"abortRebase": "리베이스 중단",
|
||||
"aborting": "중단 중…"
|
||||
},
|
||||
"content": {
|
||||
"cancelGeneration": "커밋 메시지 생성 취소",
|
||||
"commitMessageDisabled": "커밋 메시지 입력이 비활성화되었습니다. 스테이징된 파일이 없습니다.",
|
||||
"commitMessagePlaceholder": "Commit 메시지",
|
||||
"emptyMessage": "워크트리에 변경 사항이 없습니다.",
|
||||
"emptyTitle": "로컬 변경 사항 없음",
|
||||
"generateMessage": "AI로 commit 메시지 생성",
|
||||
"noStagedFiles": "스테이징된 파일 없음",
|
||||
"openActions": "소스 제어 작업 열기",
|
||||
"reconnecting": "데스크톱에 다시 연결 중…",
|
||||
"regenerateHint": "다시 생성하려면 메시지를 지웁니다.",
|
||||
"stageAll": "모두 스테이지",
|
||||
"unstageAll": "모두 언스테이징"
|
||||
},
|
||||
"createPrAction": {
|
||||
"createReview": "{{titleLabel}} 만들기"
|
||||
"checkingStatus": "리뷰 상태 확인 중…",
|
||||
"createPullRequest": "PR 생성",
|
||||
"createReview": "{{titleLabel}} 만들기",
|
||||
"providerUnavailable": "이 제공업체에서는 리뷰를 생성할 수 없음",
|
||||
"statusUnavailable": "리뷰 상태를 사용할 수 없음"
|
||||
},
|
||||
"dropdownCounts": {
|
||||
"fastForwardCount_one": "커밋 {{count}}개 fast-forward",
|
||||
@@ -2572,6 +2683,64 @@
|
||||
"titleUnpublishedForcePushCount_one": "브랜치 커밋 {{count}}개를 lease로 강제 푸시하고 필요하면 업스트림을 설정합니다.",
|
||||
"titleUnpublishedForcePushCount_other": "브랜치 커밋 {{count}}개를 lease로 강제 푸시하고 필요하면 업스트림을 설정합니다."
|
||||
},
|
||||
"fileList": {
|
||||
"committedSection": "브랜치에 커밋됨"
|
||||
},
|
||||
"fileRows": {
|
||||
"addedByThem": "상대 쪽에서 추가됨",
|
||||
"addedByUs": "우리 쪽에서 추가됨",
|
||||
"bothAdded": "양쪽에서 추가됨",
|
||||
"bothDeleted": "양쪽에서 삭제됨",
|
||||
"bothModified": "양쪽에서 수정됨",
|
||||
"committedSection": "브랜치에 커밋됨",
|
||||
"committedUnavailable": "커밋된 변경 사항을 확인할 수 없습니다.",
|
||||
"deletedByThem": "상대 쪽에서 삭제됨",
|
||||
"deletedByUs": "우리 쪽에서 삭제됨",
|
||||
"discardFile": "{{path}} 변경사항 취소",
|
||||
"loadingCommitted": "커밋된 변경 사항 로드 중…",
|
||||
"openChangedFile": "변경된 파일 {{path}} 열기",
|
||||
"openCommittedChange": "{{path}}의 커밋된 변경 사항 열기",
|
||||
"renamedFrom": "이전 경로: {{path}}",
|
||||
"stageFile": "{{path}} 스테이지",
|
||||
"unresolvedConflict": "해결되지 않은 충돌",
|
||||
"unstageFile": "{{path}} 언스테이지"
|
||||
},
|
||||
"gitHistory": {
|
||||
"days_one": "{{count}}일",
|
||||
"days_other": "{{count}}일",
|
||||
"hours_one": "{{count}}시간",
|
||||
"hours_other": "{{count}}시간",
|
||||
"justNow": "방금 전",
|
||||
"loadFailed": "커밋 기록을 로드하지 못했습니다.",
|
||||
"minutes_one": "{{count}}분",
|
||||
"minutes_other": "{{count}}분",
|
||||
"months_one": "{{count}}개월",
|
||||
"months_other": "{{count}}개월",
|
||||
"noCommitMessage": "(커밋 메시지 없음)",
|
||||
"years_one": "{{count}}년",
|
||||
"years_other": "{{count}}년"
|
||||
},
|
||||
"gitHistoryList": {
|
||||
"loadFailed": "기록을 불러오지 못했습니다.",
|
||||
"loadFilesFailed": "커밋 파일을 불러올 수 없습니다.",
|
||||
"noCommits": "커밋이 없습니다.",
|
||||
"noFileChanges": "파일 변경 사항 없음",
|
||||
"retryFiles": "커밋 파일 다시 불러오기",
|
||||
"waitingForDesktop": "데스크톱 응답 대기 중…"
|
||||
},
|
||||
"gitStatus": {
|
||||
"changes": "변경 사항",
|
||||
"conflicts": "충돌",
|
||||
"stagedChanges": "스테이징된 변경 사항"
|
||||
},
|
||||
"header": {
|
||||
"backToSession": "세션으로 돌아가기",
|
||||
"close": "소스 제어 닫기",
|
||||
"openNumberedPrWeb": "웹에서 PR #{{number}} 열기",
|
||||
"openPrWeb": "웹에서 PR 열기",
|
||||
"refresh": "소스 제어 새로고침",
|
||||
"title": "소스 제어"
|
||||
},
|
||||
"hostedReview": {
|
||||
"mrCopy": {
|
||||
"reviewLabel": "MR",
|
||||
@@ -2584,9 +2753,81 @@
|
||||
"titleLabel": "PR"
|
||||
}
|
||||
},
|
||||
"hostedReviewCopy": {
|
||||
"committingChanges": "변경 사항 커밋 중…",
|
||||
"creatingReview": "리뷰 생성 중…",
|
||||
"forcePushing": "lease로 강제 푸시하는 중…",
|
||||
"generatingCommitMessage": "커밋 메시지 생성 중…",
|
||||
"publishingBranch": "브랜치를 게시하는 중…",
|
||||
"pushingCommits": "커밋 푸시 중…",
|
||||
"stagingChanges": "변경 사항 스테이징 중…",
|
||||
"updatingBranch": "브랜치를 업데이트하는 중…"
|
||||
},
|
||||
"hostedReviewCreate": {
|
||||
"pushSucceeded": "푸시는 성공했지만 {{shortLabel}} 생성에 실패했습니다: {{error}}"
|
||||
},
|
||||
"hostedReviewCreateIntent": {
|
||||
"branchChanged": "PR을 준비하는 동안 브랜치가 변경되었습니다.",
|
||||
"generateMessageFailed": "커밋 메시지를 생성하지 못했습니다. 소스 제어에서 메시지를 입력한 다음 다시 시도하세요.",
|
||||
"resolveConflicts": "PR을 생성하기 전에 충돌을 해결하세요.",
|
||||
"resolveOrStageChanges": "PR을 생성하기 전에 변경 사항을 정리하거나 스테이지하세요.",
|
||||
"reviewCommitMessage": "커밋 메시지를 검토한 다음 PR 생성을 다시 시도하세요."
|
||||
},
|
||||
"hostedReviewGitPreparation": {
|
||||
"commitFailed": "커밋 실패",
|
||||
"refreshFailed": "소스 제어를 새로고침할 수 없습니다.",
|
||||
"stageFailed": "변경 사항을 스테이지하지 못했습니다.",
|
||||
"updateBranchFailed": "원격 브랜치를 업데이트할 수 없습니다. PR 생성을 다시 시도하세요."
|
||||
},
|
||||
"hostedReviewRemotePrerequisite": {
|
||||
"forcePushFailed": "lease로 강제 푸시하지 못했습니다.",
|
||||
"publishFailed": "브랜치를 게시하지 못했습니다.",
|
||||
"pushFailed": "커밋을 푸시하지 못했습니다."
|
||||
},
|
||||
"hostedReviewService": {
|
||||
"createFailed": "PR을 생성하지 못했습니다.",
|
||||
"pushBeforeCreateFailed": "푸시에 실패했습니다. 푸시 오류를 해결한 후 다시 시도하세요."
|
||||
},
|
||||
"hubTab": {
|
||||
"changes": "변경 사항",
|
||||
"commits": "커밋",
|
||||
"pullRequest": "PR"
|
||||
},
|
||||
"loaders": {
|
||||
"connectingToDesktop": "데스크톱에 연결 중…",
|
||||
"loadFailed": "소스 제어를 로드할 수 없습니다.",
|
||||
"updateDesktop": "모바일에서 소스 제어를 사용하려면 Orca 데스크톱 앱을 업데이트하세요.",
|
||||
"waitingForDesktop": "데스크톱 연결 대기 중…"
|
||||
},
|
||||
"modals": {
|
||||
"actionsTitle": "소스 제어",
|
||||
"currentBranch": "현재",
|
||||
"discardButton": "버리기",
|
||||
"discardConfirmMessage": "\"{{path}}\"의 변경 사항을 버리시겠습니까? 이 작업은 되돌릴 수 없습니다.",
|
||||
"discardTitle": "변경사항 취소",
|
||||
"openPrMessage": "브라우저에서 여시겠습니까?",
|
||||
"openPrWithWarning": "브라우저에서 여시겠습니까?\n\n{{warning}}",
|
||||
"prCreatedTitle": "PR 생성 완료",
|
||||
"switchBranchTitle": "브랜치 전환"
|
||||
},
|
||||
"openers": {
|
||||
"openDiffFailed": "차이점을 열 수 없습니다.",
|
||||
"tabNotReady": "파일은 열렸지만 탭이 아직 준비되지 않았습니다. 다시 시도하세요.",
|
||||
"waitingForDesktop": "데스크톱 연결 대기 중…"
|
||||
},
|
||||
"panel": {
|
||||
"loadFailedTitle": "로드 실패",
|
||||
"unavailableTitle": "소스 제어 사용 불가"
|
||||
},
|
||||
"prChip": {
|
||||
"createPr": "PR 생성",
|
||||
"loading": "PR 로드 중…",
|
||||
"loadingLabel": "PR 로드 중",
|
||||
"openLabel": "PR #{{number}}, {{state}}, {{checks}}. PR 열기.",
|
||||
"openWithComments_one": "PR #{{number}}, {{state}}, {{checks}}, 해결되지 않은 댓글 {{count}}개. PR 열기.",
|
||||
"openWithComments_other": "PR #{{number}}, {{state}}, {{checks}}, 해결되지 않은 댓글 {{count}}개. PR 열기.",
|
||||
"unavailableLabel": "PR 확인 불가: {{message}}"
|
||||
},
|
||||
"prCreate": {
|
||||
"authRequired": "{{reviewLabel}} 생성 전에 인증하세요.",
|
||||
"baseNotOnRemote": "{{reviewLabel}}을(를) 생성하기 전에 기본 브랜치를 푸시하세요.",
|
||||
@@ -2605,8 +2846,19 @@
|
||||
"unsupportedMergeRequests": "이 저장소에서는 MR 생성을 지원하지 않습니다.",
|
||||
"unsupportedPullRequests": "이 저장소에서는 PR 생성을 지원하지 않습니다."
|
||||
},
|
||||
"prLink": {
|
||||
"updatePullRequestFailed": "연결된 PR을 업데이트하지 못했습니다.",
|
||||
"updateReviewFailed": "연결된 리뷰를 업데이트하지 못했습니다."
|
||||
},
|
||||
"primaryAction": {
|
||||
"forcePushFromDesktop": "데스크톱에서 이 PR의 브랜치를 강제 푸시하세요."
|
||||
"commit": "Commit",
|
||||
"forcePush": "강제 푸시",
|
||||
"forcePushFromDesktop": "데스크톱에서 이 PR의 브랜치를 강제 푸시하세요.",
|
||||
"publishBranch": "브랜치 게시",
|
||||
"pull": "풀",
|
||||
"push": "푸시",
|
||||
"stageAll": "모두 스테이지",
|
||||
"sync": "동기화"
|
||||
},
|
||||
"remoteDropdown": {
|
||||
"branchAlreadyPublished": "브랜치가 이미 게시되었습니다",
|
||||
@@ -2656,6 +2908,591 @@
|
||||
"tryFastForwardPull": "fast-forward 풀을 시도합니다. git에서 로컬 커밋을 거부할 수 있습니다",
|
||||
"tryRegularPush": "일반 푸시를 시도합니다. git에서 강제 푸시가 필요할 수 있습니다",
|
||||
"useForcePushToSync": "강제 푸시를 사용하세요 — 원격에는 로컬 커밋의 이전 사본만 있습니다"
|
||||
},
|
||||
"runners": {
|
||||
"actionFailed": "소스 제어 작업에 실패했습니다."
|
||||
},
|
||||
"screenState": {
|
||||
"noBranch": "브랜치 없음"
|
||||
},
|
||||
"state": {
|
||||
"noUpstream": "업스트림 없음",
|
||||
"syncStatus": "{{ahead}}개 앞섬, {{behind}}개 뒤처짐"
|
||||
},
|
||||
"useMobileCommitFailureRecovery": {
|
||||
"launchFailed": "에이전트를 실행하지 못했습니다.",
|
||||
"waitingForDesktop": "데스크톱 연결 대기 중…"
|
||||
},
|
||||
"useMobileCommitMessageGeneration": {
|
||||
"generateFailed": "커밋 메시지를 생성하지 못했습니다."
|
||||
},
|
||||
"useMobileCreatePrRunner": {
|
||||
"branchRequired": "PR을 생성하기 전에 브랜치를 체크아웃하세요."
|
||||
},
|
||||
"useMobileGitRequests": {
|
||||
"actionFailed": "소스 제어 작업에 실패했습니다.",
|
||||
"branchUnavailable": "브랜치 상태를 확인할 수 없습니다.",
|
||||
"commitFailed": "커밋 실패",
|
||||
"waitingForDesktop": "데스크톱 연결 대기 중…"
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"composerSource": {
|
||||
"baseFailed": "기본 브랜치를 확인하지 못했습니다.",
|
||||
"forkPushWarning": "이 PR에서 \"유지 관리자의 수정 허용\"이 꺼져 있어 GitHub에서 포크로의 푸시를 거부할 수 있습니다."
|
||||
},
|
||||
"detailCommentRenderers": {
|
||||
"commentPlaceholder": "댓글 추가",
|
||||
"comments_one": "댓글 {{count}}개",
|
||||
"comments_other": "댓글 {{count}}개",
|
||||
"reopenThread": "스레드 다시 열기",
|
||||
"reply": "회신",
|
||||
"resolveThread": "스레드 해결",
|
||||
"resolvedCommentBy": "{{author}}의 댓글 · 해결됨",
|
||||
"resolvedThreadBy": "{{author}}의 스레드 · 해결됨",
|
||||
"sendComment": "댓글 보내기",
|
||||
"show": "표시"
|
||||
},
|
||||
"filterPickers": {
|
||||
"allTeams": "모든 팀",
|
||||
"changeStatus": "상태 변경",
|
||||
"fieldHidden": "카드에서 숨김",
|
||||
"fieldShown": "카드에 표시됨",
|
||||
"fieldsSubtitle": "항목 카드에 표시할 프로젝트 필드를 선택하세요.",
|
||||
"fieldsTitle": "프로젝트 필드",
|
||||
"gitlabFilter": "GitLab 필터",
|
||||
"gitlabView": "GitLab 보기",
|
||||
"jiraFilter": "Jira 필터",
|
||||
"jiraSite": "Jira 사이트",
|
||||
"linearFilter": "Linear 필터",
|
||||
"linearIssue": "Linear 이슈",
|
||||
"linearWorkspace": "Linear 워크스페이스",
|
||||
"loadingStates": "상태 로드 중…",
|
||||
"noFields": "이 보기에는 표시할 추가 필드가 없습니다.",
|
||||
"noStates": "사용 가능한 상태가 없습니다.",
|
||||
"switchWorkspaceFailed": "워크스페이스를 전환하지 못했습니다.",
|
||||
"teamsSubtitle": "작업 화면에 표시할 팀을 선택하세요.",
|
||||
"teamsTitle": "Linear 팀",
|
||||
"teams_one": "팀 {{count}}개",
|
||||
"teams_other": "팀 {{count}}개"
|
||||
},
|
||||
"githubProjectList": {
|
||||
"browseProjects": "프로젝트 검색",
|
||||
"chooseProject": "GitHub 프로젝트를 선택하세요.",
|
||||
"emptyField": "비어 있음",
|
||||
"issueSubtitle": "이슈 · {{repository}}{{number}}",
|
||||
"itemSubtitle": "프로젝트 항목 · {{repository}}{{number}}",
|
||||
"items": "항목",
|
||||
"moreFields_one": "필드 +{{count}}개",
|
||||
"moreFields_other": "필드 +{{count}}개",
|
||||
"noItems": "프로젝트 항목이 없습니다.",
|
||||
"pullRequestSubtitle": "PR · {{repository}}{{number}}"
|
||||
},
|
||||
"githubProjectPickers": {
|
||||
"add": "추가",
|
||||
"addByUrlHint": "목록에 없는 프로젝트는 URL로 추가하세요.",
|
||||
"addPlaceholder": "URL 또는 소유자/번호로 추가",
|
||||
"adding": "추가 중…",
|
||||
"browseAll": "모두 찾아보기",
|
||||
"browseLoading": "모두 찾아보기 (로드 중…)",
|
||||
"chooseView": "프로젝트 보기 선택",
|
||||
"loadFailed": "프로젝트를 로드하지 못했습니다.",
|
||||
"noMatches": "일치하는 프로젝트가 없습니다.",
|
||||
"noMoreProjects": "더 이상 프로젝트가 없습니다.",
|
||||
"noProjects": "불러온 프로젝트 없음",
|
||||
"organizationsError": "조직: {{message}}",
|
||||
"organizationsLoadFailed": "일부 조직을 불러오지 못했습니다({{count}}개).",
|
||||
"ownerLoadFailed": "{{owner}}의 프로젝트를 불러올 수 없습니다.",
|
||||
"pin": "핀",
|
||||
"pinned": "고정됨",
|
||||
"recent": "최근",
|
||||
"retryHint": "탭하여 다시 시도하세요.",
|
||||
"searchProjects": "프로젝트 검색",
|
||||
"sort": "프로젝트 정렬",
|
||||
"subtitle": "작업 페이지에 표시할 프로젝트 보기를 선택하세요.",
|
||||
"title": "GitHub 프로젝트",
|
||||
"unsupportedLayout": "Orca는 아직 이 GitHub 프로젝트 레이아웃을 지원하지 않습니다.",
|
||||
"view": "프로젝트 보기"
|
||||
},
|
||||
"githubViewControls": {
|
||||
"fields": "필드: {{fields}}",
|
||||
"openView": "GitHub에서 보기 열기",
|
||||
"sort": "정렬: {{sort}}",
|
||||
"source": "출처: {{source}}"
|
||||
},
|
||||
"itemActions": {
|
||||
"changeStatus": "상태 변경",
|
||||
"copyGitHubLink": "GitHub 링크 복사",
|
||||
"copyLinearLink": "Linear 링크 복사",
|
||||
"createWorkspace": "워크스페이스 만들기",
|
||||
"creating": "만드는 중…",
|
||||
"mergeConflicts": "GitHub에서 병합 충돌이 보고되었습니다.",
|
||||
"mergeMergeRequest": "MR 병합",
|
||||
"mergePullRequest": "PR 병합"
|
||||
},
|
||||
"itemDetailContent": {
|
||||
"addSubIssue": "하위 이슈 추가",
|
||||
"assignee": "담당자",
|
||||
"assignees": "담당자",
|
||||
"checks": "체크",
|
||||
"description": "설명",
|
||||
"discussion": "토론",
|
||||
"noChecks": "체크를 찾을 수 없습니다.",
|
||||
"noComments": "댓글이 없습니다.",
|
||||
"noPipelineRuns": "이 MR에 실행된 파이프라인이 없습니다.",
|
||||
"noSubIssues": "하위 이슈가 없습니다.",
|
||||
"none": "없음",
|
||||
"pipeline": "파이프라인",
|
||||
"pipelineJobs_one": "작업 {{count}}개",
|
||||
"pipelineJobs_other": "작업 {{count}}개",
|
||||
"project": "프로젝트",
|
||||
"rerunAll": "모두 재실행",
|
||||
"rerunFailed": "실패한 체크 재실행",
|
||||
"status": "상태",
|
||||
"subIssueTitle": "하위 이슈 제목",
|
||||
"subIssues": "하위 이슈",
|
||||
"type": "유형"
|
||||
},
|
||||
"itemDetailDrawer": {
|
||||
"refreshDetails": "상세 정보 새로고침"
|
||||
},
|
||||
"itemFieldEditors": {
|
||||
"addLabels": "추가할 라벨(쉼표로 구분)",
|
||||
"addUsernames": "추가할 사용자 이름(쉼표로 구분)",
|
||||
"assignees": "담당자",
|
||||
"labels": "라벨",
|
||||
"loadingAssignees": "담당자 로드 중…",
|
||||
"loadingLabels": "라벨 로드 중…",
|
||||
"noAssignableUsers": "이 저장소에서 담당자로 지정할 수 있는 사용자가 없습니다.",
|
||||
"noLabels": "이 저장소에 라벨이 없습니다.",
|
||||
"none": "없음",
|
||||
"removeLabels": "제거할 라벨(쉼표로 구분)",
|
||||
"removeUsernames": "제거할 사용자 이름(쉼표로 구분)",
|
||||
"saveTitle": "제목 저장",
|
||||
"title": "제목",
|
||||
"updateAssignees": "담당자 업데이트",
|
||||
"updateLabels": "라벨 업데이트"
|
||||
},
|
||||
"itemReviewSections": {
|
||||
"binaryFile": "바이너리 파일입니다.",
|
||||
"changedFilesTitle": "변경된 파일",
|
||||
"descriptionPlaceholder": "설명",
|
||||
"fileContentsUnavailable": "파일 내용을 표시할 수 없습니다.",
|
||||
"hideFile": "숨기기",
|
||||
"loadingReviewers": "리뷰어 로드 중…",
|
||||
"markUnviewed": "보지 않은 것으로 표시",
|
||||
"markViewed": "본 것으로 표시",
|
||||
"noDescription": "설명이 없습니다.",
|
||||
"noReviewerSuggestions": "추천 리뷰어를 찾지 못했습니다.",
|
||||
"noReviewersRequested": "요청한 리뷰어가 없습니다.",
|
||||
"requestReview": "리뷰 요청",
|
||||
"reviewersPlaceholder": "리뷰를 요청할 리뷰어",
|
||||
"reviewersTitle": "리뷰어",
|
||||
"saveDescription": "설명 저장",
|
||||
"viewFile": "보기"
|
||||
},
|
||||
"legacySurface": {
|
||||
"loadIssuesFailed": "{{source}}에서 이슈를 로드하지 못했습니다.",
|
||||
"mergeAction": "병합",
|
||||
"mergeMethodTitle": "병합 방식",
|
||||
"mergePullRequestTitle": "PR 병합",
|
||||
"mergeRequestMergeMessage": "이 MR의 병합 방식을 선택하세요.",
|
||||
"mergeRequestTitle": "머지 리퀘스트",
|
||||
"pullRequestMergeMessage": "이 PR의 병합 방식을 선택하세요.",
|
||||
"retryLoadingIssues": "{{source}}에서 이슈 로드 다시 시도",
|
||||
"retrying": "다시 시도 중…",
|
||||
"sourceFallback": "{{repo}}에서 선택한 이슈 소스인 upstream을 사용할 수 없습니다. origin을 사용합니다.",
|
||||
"subIssueDataUnavailable": "현재 토큰으로는 하위 이슈 데이터를 조회할 수 없습니다.",
|
||||
"updateItemTitle": "항목 업데이트"
|
||||
},
|
||||
"linearList": {
|
||||
"changeStatusFrom": "상태 변경(현재: {{status}})"
|
||||
},
|
||||
"linearViewControls": {
|
||||
"displayButton": "표시",
|
||||
"groupLabel": "그룹화: {{group}}",
|
||||
"orderLabel": "정렬: {{order}}"
|
||||
},
|
||||
"listDisplayPickers": {
|
||||
"displayPropertiesTitle": "표시 속성",
|
||||
"linearGroupTitle": "Linear 이슈 그룹화",
|
||||
"linearOrderTitle": "Linear 이슈 정렬",
|
||||
"linearViewTitle": "Linear 보기",
|
||||
"sortTasksTitle": "작업 정렬"
|
||||
},
|
||||
"listSurface": {
|
||||
"connectLinearButton": "Linear 연결",
|
||||
"connectLinearMessage": "작업 화면에서 할당받은 Linear 이슈를 바로 살펴보고 작업을 시작하세요.",
|
||||
"connectLinearTitle": "Linear 계정 연결",
|
||||
"jiraStatusFailed": "Jira 상태를 읽지 못했습니다.",
|
||||
"updateDesktopMessage": "모바일 작업 화면을 사용하려면 더 최신 버전의 데스크톱 런타임이 필요합니다.",
|
||||
"updateDesktopTitle": "Orca 데스크톱 업데이트"
|
||||
},
|
||||
"options": {
|
||||
"all": "모두",
|
||||
"assignedToMe": "나에게 할당됨",
|
||||
"assignee": "담당자",
|
||||
"board": "보드",
|
||||
"boardDescription": "그룹별 열",
|
||||
"closedState": "닫힘",
|
||||
"completedState": "완료됨",
|
||||
"createdState": "내가 만든 이슈",
|
||||
"githubAssignedIssuesDescription": "나에게 할당된 열린 이슈",
|
||||
"githubDescription": "이슈 및 PR",
|
||||
"githubIssuesDescription": "GitHub 이슈",
|
||||
"githubOpenIssuesDescription": "열려 있는 GitHub 이슈",
|
||||
"githubProjectsDescription": "GitHub 프로젝트 보기",
|
||||
"githubPullRequestsDescription": "GitHub PR",
|
||||
"gitlabAllDescription": "모든 GitLab 상태",
|
||||
"gitlabClosedDescription": "닫힌 이슈 및 MR",
|
||||
"gitlabDescription": "이슈 및 MR",
|
||||
"gitlabMergedDescription": "병합된 MR",
|
||||
"gitlabOpenDescription": "열린 이슈 및 MR",
|
||||
"identifier": "식별자",
|
||||
"issues": "이슈",
|
||||
"jiraDescription": "할당된 이슈 및 보고한 이슈",
|
||||
"labels": "라벨",
|
||||
"linearAllDescription": "연결된 워크스페이스의 열린 이슈",
|
||||
"linearAssignedDescription": "할당받은 이슈",
|
||||
"linearCompletedDescription": "최근 완료된 이슈",
|
||||
"linearCreatedDescription": "직접 생성한 이슈",
|
||||
"linearDescription": "할당된 이슈 및 팀 이슈",
|
||||
"list": "목록",
|
||||
"listDescription": "이슈를 간결한 행으로 표시",
|
||||
"mergedState": "병합됨",
|
||||
"mine": "내 항목",
|
||||
"myIssues": "내 이슈",
|
||||
"myPullRequestsDescription": "내가 작성한 PR",
|
||||
"myTodos": "내 할 일",
|
||||
"myTodosDescription": "대기 중인 GitLab 할 일",
|
||||
"needsReview": "리뷰 필요",
|
||||
"noGrouping": "그룹화 없음",
|
||||
"openPullRequestsDescription": "열린 PR",
|
||||
"openState": "열림",
|
||||
"priority": "우선순위",
|
||||
"projectMergeRequests": "프로젝트 MR",
|
||||
"projectMergeRequestsDescription": "저장소별 MR 및 이슈",
|
||||
"projects": "프로젝트",
|
||||
"pullRequests": "PR",
|
||||
"repository": "리포지토리",
|
||||
"repositorySortDescription": "저장소별로 그룹화한 후 최근 활동순 정렬",
|
||||
"reviewRequestsDescription": "나에게 할당된 리뷰 요청",
|
||||
"status": "상태",
|
||||
"team": "팀",
|
||||
"updated": "업데이트됨",
|
||||
"updatedSortDescription": "최근 활동순"
|
||||
},
|
||||
"pickerProjection": {
|
||||
"allRepos": "모든 저장소",
|
||||
"allSites": "모든 사이트",
|
||||
"currentlyAscending": "현재 오름차순 · 탭하면 내림차순",
|
||||
"currentlyDescending": "현재 내림차순 · 탭하면 오름차순",
|
||||
"fieldAscending": "{{field}} 오름차순",
|
||||
"fieldDescending": "{{field}} 내림차순",
|
||||
"fields": "필드",
|
||||
"repos_one": "저장소 {{count}}개",
|
||||
"repos_other": "저장소 {{count}}개",
|
||||
"selectTarget": "대상 선택",
|
||||
"selectedFields": "필드 {{selected}}/{{total}}개",
|
||||
"sortAscending": "오름차순 정렬",
|
||||
"sources_one": "소스 {{count}}개",
|
||||
"sources_other": "소스 {{count}}개",
|
||||
"unsupportedLayout": "모바일에서 지원하지 않는 레이아웃",
|
||||
"updatedSort": "업데이트됨",
|
||||
"usesFieldAscending": "{{field}} 오름차순 사용",
|
||||
"usesFieldDescending": "{{field}} 내림차순 사용",
|
||||
"usesGitHubRankOrder": "GitHub 항목 순서 사용",
|
||||
"viewNumber": "보기 #{{number}}",
|
||||
"viewOrder": "보기 순서"
|
||||
},
|
||||
"prFileDiff": {
|
||||
"commentOnLine": "{{line}}번 줄에 댓글 추가",
|
||||
"commentPlaceholder": "리뷰 댓글 추가",
|
||||
"noTextChanges": "텍스트 변경 사항이 없습니다.",
|
||||
"showingDiffLines": "차이점 총 {{total}}줄 중 처음 {{limit}}줄을 표시합니다."
|
||||
},
|
||||
"projectComments": {
|
||||
"comments_one": "댓글 {{count}}개",
|
||||
"comments_other": "댓글 {{count}}개",
|
||||
"discussion": "토론",
|
||||
"editComment": "댓글 수정",
|
||||
"noComments": "댓글이 없습니다.",
|
||||
"reopenThread": "스레드 다시 열기",
|
||||
"reply": "회신",
|
||||
"resolveThread": "스레드 해결",
|
||||
"resolvedCommentBy": "{{author}}의 해결된 댓글",
|
||||
"resolvedThreadBy": "{{author}}의 해결된 스레드",
|
||||
"show": "표시"
|
||||
},
|
||||
"projectDetailDrawer": {
|
||||
"addRepositoryFromDesktop": "{{repository}}이(가) Orca에 추가되지 않았습니다. 데스크톱 앱에서 이 저장소를 추가한 후 모바일의 작업 화면을 새로고침하세요.",
|
||||
"clearType": "유형 해제",
|
||||
"closeItem": "항목 닫기",
|
||||
"copyGitHubLink": "GitHub 링크 복사",
|
||||
"copyRepository": "저장소 복사",
|
||||
"createWorkspace": "워크스페이스 생성",
|
||||
"draftIssue": "초안 이슈",
|
||||
"issue": "이슈",
|
||||
"issueType": "이슈 유형",
|
||||
"loadingIssueTypes": "이슈 유형 로드 중…",
|
||||
"mergePullRequest": "PR 병합",
|
||||
"mergeRepositoryRequirement": "병합하려면 이 저장소가 Orca에 추가되어 있어야 합니다.",
|
||||
"noIssueTypes": "이 저장소에 설정된 이슈 유형이 없습니다.",
|
||||
"noType": "유형 없음",
|
||||
"openInGitHub": "GitHub에서 열기",
|
||||
"projectItem": "프로젝트 항목",
|
||||
"projectSubtitle": "GitHub 프로젝트 · {{repository}}{{itemNumber}}",
|
||||
"pullRequest": "PR",
|
||||
"reopenItem": "항목 다시 열기",
|
||||
"repositoryNotInOrca": "Orca에 없는 저장소",
|
||||
"status": "상태",
|
||||
"type": "유형",
|
||||
"workspaceCreationRequirement": "워크스페이스는 GitHub 이슈와 PR에서만 생성할 수 있습니다."
|
||||
},
|
||||
"projectFieldEditors": {
|
||||
"clearField": "필드 비우기",
|
||||
"completedIteration": "완료 · {{startDate}} · {{duration}}일",
|
||||
"datePlaceholder": "YYYY-MM-DD",
|
||||
"invalidDate": "날짜를 YYYY-MM-DD 형식으로 입력하세요.",
|
||||
"invalidNumber": "올바른 숫자를 입력하세요.",
|
||||
"noIterations": "사용 가능한 반복 주기가 없습니다.",
|
||||
"numberPlaceholder": "숫자",
|
||||
"projectFields": "프로젝트 필드",
|
||||
"saveField": "필드 저장",
|
||||
"textPlaceholder": "텍스트",
|
||||
"upcomingIteration": "진행 중 및 예정 · {{startDate}} · {{duration}}일"
|
||||
},
|
||||
"projectMetadataEditors": {
|
||||
"assignees": "담당자",
|
||||
"description": "설명",
|
||||
"labels": "라벨",
|
||||
"loadingAssignees": "담당자 로드 중…",
|
||||
"loadingLabels": "라벨 로드 중…",
|
||||
"noAssignableUsers": "이 저장소에서 담당자로 지정할 수 있는 사용자가 없습니다.",
|
||||
"noDescription": "설명이 없습니다.",
|
||||
"noLabels": "이 저장소에 라벨이 없습니다.",
|
||||
"none": "없음",
|
||||
"saveDescription": "설명 저장",
|
||||
"saveTitle": "제목 저장",
|
||||
"title": "제목"
|
||||
},
|
||||
"projectReviewPanels": {
|
||||
"binaryFile": "바이너리 파일입니다.",
|
||||
"changedFiles": "변경된 파일",
|
||||
"checks": "체크",
|
||||
"fileUnavailable": "파일 내용을 사용할 수 없습니다.",
|
||||
"hideFile": "숨기기",
|
||||
"loadingReviewers": "리뷰어 로드 중…",
|
||||
"markUnviewed": "보지 않은 것으로 표시",
|
||||
"markViewed": "본 것으로 표시",
|
||||
"noChecks": "체크가 없습니다.",
|
||||
"noReviewers": "요청한 리뷰어가 없습니다.",
|
||||
"noSuggestions": "추천 리뷰어가 없습니다.",
|
||||
"requestReview": "리뷰 요청",
|
||||
"requestReviewers": "리뷰어 요청",
|
||||
"rerunAll": "모두 재실행",
|
||||
"rerunFailed": "실패한 체크 재실행",
|
||||
"reviewers": "리뷰어",
|
||||
"viewFile": "보기"
|
||||
},
|
||||
"providerControls": {
|
||||
"myTodos": "내 할 일",
|
||||
"projectMergeRequests": "프로젝트 MR",
|
||||
"sort": "정렬: {{sortLabel}}"
|
||||
},
|
||||
"providerItemList": {
|
||||
"intoBranch": "{{base}}(으)로",
|
||||
"nextPage": "다음 페이지",
|
||||
"page": "{{page}}페이지",
|
||||
"pageOfTotal": "{{page}} / {{total}}페이지",
|
||||
"previousPage": "이전 페이지",
|
||||
"selectPage": "페이지 선택, {{page}}페이지",
|
||||
"selectPageOfTotal": "페이지 선택, 전체 {{total}}페이지 중 {{page}}페이지"
|
||||
},
|
||||
"providerPickers": {
|
||||
"allRepositories": "모든 리포지토리",
|
||||
"githubView": "GitHub 보기",
|
||||
"issueSources": "GitHub 이슈 소스",
|
||||
"issueSourcesDescription": "각 리포지토리에서 이슈 조회와 작업 생성에 사용할 소스를 upstream과 origin 중에서 선택하세요.",
|
||||
"issues": "이슈",
|
||||
"noIssueSources": "사용할 수 있는 다른 이슈 소스가 없습니다.",
|
||||
"origin": "origin",
|
||||
"pageHint": "로드되었거나 로드 가능한 결과 페이지로 이동하세요.",
|
||||
"pageLoaded": "로드됨",
|
||||
"pageNotLoaded": "이전 결과를 로드합니다.",
|
||||
"pageNumber": "{{page}}페이지",
|
||||
"pages": "GitHub 페이지",
|
||||
"pullRequests": "PR",
|
||||
"queryingSource": "조회 대상: {{source}}",
|
||||
"repoDescription": "조회할 리포지토리를 선택하세요.",
|
||||
"repos": "리포지토리",
|
||||
"taskSource": "작업 소스",
|
||||
"upstream": "업스트림"
|
||||
},
|
||||
"providerViewProjection": {
|
||||
"all": "모두",
|
||||
"allSites": "모든 사이트",
|
||||
"allTeams": "모든 팀",
|
||||
"allWorkspaces": "모든 워크스페이스",
|
||||
"chooseProject": "프로젝트 선택",
|
||||
"default": "기본",
|
||||
"defaultSubtitle": "{{subtitle}} · 기본",
|
||||
"issues": "이슈",
|
||||
"list": "목록",
|
||||
"noGrouping": "그룹화 없음",
|
||||
"openState": "열림",
|
||||
"priority": "우선순위",
|
||||
"projects": "프로젝트",
|
||||
"pullRequests": "PR",
|
||||
"teams_one": "팀 {{count}}개",
|
||||
"teams_other": "팀 {{count}}개",
|
||||
"workspace": "워크스페이스"
|
||||
},
|
||||
"reviewerLinear": {
|
||||
"issues": "이슈",
|
||||
"unassigned": "할당되지 않음"
|
||||
},
|
||||
"screenChrome": {
|
||||
"connectLinear": "Linear 연결",
|
||||
"newGitHubIssue": "새 GitHub 이슈",
|
||||
"newLinearIssue": "새 Linear 이슈",
|
||||
"refreshGitHub": "GitHub 작업 새로 고침",
|
||||
"refreshGitLab": "GitLab 작업 항목 새로 고침",
|
||||
"refreshJira": "Jira 이슈 새로 고침",
|
||||
"refreshLinear": "Linear 새로고침",
|
||||
"title": "작업"
|
||||
},
|
||||
"searchControl": {
|
||||
"jiraPlaceholder": "Jira JQL, 예: project = ABC AND statusCategory != Done",
|
||||
"projectPlaceholder": "프로젝트 보기 검색…",
|
||||
"providerPlaceholder": "{{provider}} 작업 검색…"
|
||||
},
|
||||
"smartSourceModes": {
|
||||
"allStates": "모두",
|
||||
"branch": "브랜치",
|
||||
"closedState": "닫힘",
|
||||
"mergedState": "병합됨",
|
||||
"name": "이름",
|
||||
"openState": "열림",
|
||||
"smart": "스마트"
|
||||
},
|
||||
"sparsePresetDraft": {
|
||||
"directoryRequired": "하나 이상의 디렉터리를 추가합니다.",
|
||||
"repoRelativeDirectoriesRequired": "루트, 절대 경로, 상위 경로가 아니라 repo 기준 상대 디렉터리를 사용하세요."
|
||||
},
|
||||
"taskViewOptions": {
|
||||
"allSubtitle": "선택한 사이트의 미해결 이슈",
|
||||
"assignedSubtitle": "나에게 할당된 미해결 이슈",
|
||||
"doneSubtitle": "최근 해결된 내 이슈",
|
||||
"noGitHubTasks": "GitHub 작업 없음",
|
||||
"noGitLabTasks": "GitLab 작업 없음",
|
||||
"noJiraTasks": "Jira 작업 없음",
|
||||
"noLinearTasks": "Linear 작업 없음",
|
||||
"reportedSubtitle": "내가 보고한 미해결 이슈"
|
||||
},
|
||||
"tasksCreateDrawers": {
|
||||
"connect": "연결",
|
||||
"connectLinearWorkspace": "Linear 워크스페이스 연결",
|
||||
"createIssue": "이슈 생성",
|
||||
"createWorkspaceIn": "워크스페이스 생성 리포지토리",
|
||||
"description": "설명",
|
||||
"descriptionPlaceholder": "배경 설명 추가",
|
||||
"fileIn": "{{slug}}에 이슈 등록",
|
||||
"issueSource": "이슈 소스",
|
||||
"keySecurityHint": "키는 호스트 OS 키체인을 통해 암호화되어 로컬에 저장됩니다.",
|
||||
"linearConnectSubtitle": "해당 워크스페이스의 이슈를 보려면 개인 API 키를 붙여넣으세요.",
|
||||
"linearSettingsLink": "Linear 설정 / 보안 / 새 API 키",
|
||||
"linearTeam": "Linear 팀",
|
||||
"linearTeamSubtitle": "선택한 Linear 팀에 이슈를 생성하세요.",
|
||||
"newIssueTitle": "새 {{providerLabel}} 이슈",
|
||||
"origin": "origin",
|
||||
"personalApiKey": "개인 API 키",
|
||||
"repository": "리포지토리",
|
||||
"repositorySubtitle": "선택한 리포지토리에 이슈를 생성하세요.",
|
||||
"team": "팀",
|
||||
"title": "제목",
|
||||
"titlePlaceholder": "작업 제목",
|
||||
"upstream": "업스트림"
|
||||
},
|
||||
"workspaceAgentSelection": {
|
||||
"blankTerminal": "빈 터미널"
|
||||
},
|
||||
"workspaceCreateDrawer": {
|
||||
"addRepository": "Linear 워크스페이스를 생성하기 전에 Git 리포지토리를 추가하세요.",
|
||||
"advanced": "고급",
|
||||
"agent": "에이전트",
|
||||
"connect": "연결",
|
||||
"connectFirst": "먼저 리포지토리를 연결하세요",
|
||||
"connectRepository": "리포지토리 연결",
|
||||
"connecting": "연결 중…",
|
||||
"createFrom": "{{branch}} 기준으로 생성",
|
||||
"defaultBranch": "기본 브랜치",
|
||||
"detectingAgents": "에이전트 감지 중…",
|
||||
"optional": "[선택 사항]",
|
||||
"remoteRepository": "원격 리포지토리",
|
||||
"repository": "리포지토리",
|
||||
"repositoryNotFound": "리포지토리를 찾을 수 없습니다.",
|
||||
"selectRepository": "리포지토리 선택",
|
||||
"sshConnection": "SSH 연결",
|
||||
"startFrom": "시작 기준",
|
||||
"title": "워크스페이스 생성",
|
||||
"workspaceName": "워크스페이스 이름"
|
||||
},
|
||||
"workspaceCreateProjection": {
|
||||
"nameAlreadyExists": "\"{{name}}\"이(가) 이미 존재합니다.",
|
||||
"nameRequired": "이름을 입력하세요.",
|
||||
"nameTooLong": "이름은 80자 이하여야 합니다.",
|
||||
"openShell": "셸 열기"
|
||||
},
|
||||
"workspaceOptionPickers": {
|
||||
"baseBranchSubtitle": "기존 브랜치나 참조를 선택하세요.",
|
||||
"baseBranchTitle": "시작 기준",
|
||||
"branchName": "브랜치 이름: {{name}}",
|
||||
"defaultBranch": "기본 브랜치",
|
||||
"defaultBranchSubtitle": "이 저장소에 설정된 기본 브랜치 사용",
|
||||
"editPreset": "프리셋 편집: {{name}}",
|
||||
"fullCheckout": "전체 체크아웃",
|
||||
"fullCheckoutSubtitle": "저장소 전체 사용",
|
||||
"newPreset": "새로운 사전 설정",
|
||||
"noBranches": "일치하는 브랜치가 없습니다.",
|
||||
"searchBranches": "브랜치 검색",
|
||||
"sparseCheckoutTitle": "스파스 체크아웃"
|
||||
},
|
||||
"workspaceSshGate": {
|
||||
"authenticationFailed": "인증 실패",
|
||||
"connected": "연결됨",
|
||||
"connecting": "연결 중",
|
||||
"connectionFailed": "연결 실패",
|
||||
"deployingRelay": "릴레이 배포 중",
|
||||
"disconnected": "연결 끊김",
|
||||
"reconnectFailed": "다시 연결 실패",
|
||||
"reconnecting": "다시 연결 중"
|
||||
},
|
||||
"workspaceTrustDrawers": {
|
||||
"alwaysTrustAndRun": "항상 신뢰하고 실행",
|
||||
"creating": "만드는 중…",
|
||||
"directoriesLabel": "디렉터리",
|
||||
"directories_one": "디렉터리 {{count}}개",
|
||||
"directories_other": "디렉터리 {{count}}개",
|
||||
"dontRun": "실행 안 함",
|
||||
"editSparsePreset": "스파스 프리셋 편집",
|
||||
"nameLabel": "이름",
|
||||
"namePlaceholder": "렌더러 UI",
|
||||
"newSetupScript": "새 설정 스크립트",
|
||||
"newSparsePreset": "새 스파스 프리셋",
|
||||
"runHooks": "후크 실행",
|
||||
"runSetupAndCreate": "설정 실행 후 만들기",
|
||||
"runSetupTitle": "{{name}}의 설정 스크립트를 실행하시겠습니까?",
|
||||
"setupChangedTitle": "{{name}}의 설정 스크립트가 변경되었습니다",
|
||||
"setupScript": "설정 스크립트",
|
||||
"setupSubtitle": "{{name}}의 워크스페이스를 만들려면 먼저 설정 스크립트 실행 여부를 선택해야 합니다.",
|
||||
"setupTitle": "설정 스크립트를 실행하시겠습니까?",
|
||||
"skipSetupAndCreate": "설정 건너뛰고 만들기",
|
||||
"trustFailed": "설정 스크립트 신뢰 설정에 실패했습니다.",
|
||||
"trustSubtitle": "워크스페이스가 시작되기 전에 이 저장소의 orca.yaml이 컴퓨터에서 실행됩니다. 이 저장소를 신뢰하는 경우에만 실행하세요."
|
||||
},
|
||||
"worktreeCreateRetry": {
|
||||
"createFailed": "워크스페이스를 생성하지 못했습니다."
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
+873
-17
@@ -6,7 +6,7 @@
|
||||
"connectingTo": "Conectando a {{name}}…",
|
||||
"default": "Padrão do sistema",
|
||||
"hostNotFound": "Host não encontrado",
|
||||
"invalidSnapshot": "Dados de contas inválidos recebidos do host",
|
||||
"invalidSnapshot": "Snapshot de contas inválido recebido do host",
|
||||
"loadingAccounts": "Carregando contas…",
|
||||
"manageAccountsHint": "Adicione contas ou autentique-as novamente em Configurações → Contas no desktop.",
|
||||
"refreshAccounts": "Atualizar contas",
|
||||
@@ -383,8 +383,8 @@
|
||||
"stoppingState": "Parando…"
|
||||
},
|
||||
"streamFrame": {
|
||||
"streamEnded": "Transmissão da conversa encerrada",
|
||||
"streamFailed": "Falha na transmissão da conversa"
|
||||
"streamEnded": "Transmissão da transcrição encerrada",
|
||||
"streamFailed": "Falha na transmissão da transcrição"
|
||||
},
|
||||
"taskList": {
|
||||
"added": "Adicionada {{task}}",
|
||||
@@ -604,7 +604,7 @@
|
||||
"resetting": "Redefinindo…",
|
||||
"resettingLabel": "Redefinindo limites de taxa do Codex",
|
||||
"scopedHint": "Usa uma redefinição obtida para {{scopeLabel}}",
|
||||
"useReset": "Usar redefinição",
|
||||
"useReset": "Redefinir agora",
|
||||
"useResetLabel": "Usar redefinição de limite de taxa do Codex"
|
||||
},
|
||||
"customKeyModal": {
|
||||
@@ -1234,7 +1234,7 @@
|
||||
"loadFolderFailed": "Não foi possível carregar a pasta",
|
||||
"loading": "Carregando…",
|
||||
"openFolder": "Abrir pasta {{name}}",
|
||||
"previewFile": "Visualizar arquivo {{name}}",
|
||||
"previewFile": "Pré-visualizar arquivo {{name}}",
|
||||
"retryLoading": "Tentar carregar {{path}} novamente",
|
||||
"unavailable": "Indisponível no celular"
|
||||
},
|
||||
@@ -1261,16 +1261,16 @@
|
||||
"editorLabel": "Editor de {{title}}"
|
||||
},
|
||||
"filePreviewResponse": {
|
||||
"binaryUnavailable": "Visualização de arquivos binários indisponível",
|
||||
"binaryUnavailable": "Pré-visualização de arquivos binários indisponível",
|
||||
"bytes": "{{size}} B",
|
||||
"fileChanged": "O arquivo foi alterado no desktop. Recarregue a visualização antes de salvar.",
|
||||
"fileChanged": "O arquivo foi alterado no desktop. Recarregue a pré-visualização antes de salvar.",
|
||||
"fileNotFound": "Arquivo não encontrado",
|
||||
"fileTooLarge": "Arquivo muito grande para visualização no celular",
|
||||
"fileTooLarge": "Arquivo muito grande para pré-visualização no celular",
|
||||
"filesystemUnreachable": "Não foi possível acessar o sistema de arquivos do desktop",
|
||||
"kilobytes": "{{size}} KB",
|
||||
"loadFailed": "Não foi possível carregar a visualização",
|
||||
"loadFailed": "Não foi possível carregar a pré-visualização",
|
||||
"megabytes": "{{size}} MB",
|
||||
"reloadBeforeSaving": "Recarregue a visualização antes de salvar.",
|
||||
"reloadBeforeSaving": "Recarregue a pré-visualização antes de salvar.",
|
||||
"unknownSize": "tamanho desconhecido"
|
||||
},
|
||||
"filePreviewScreen": {
|
||||
@@ -1290,8 +1290,8 @@
|
||||
"waiting": "Aguardando o desktop…"
|
||||
},
|
||||
"filePreviewSourceText": {
|
||||
"previewLabel": "Visualização do arquivo",
|
||||
"truncatedNote": "Visualização truncada. Tamanho do arquivo: {{size}}."
|
||||
"previewLabel": "Pré-visualização do arquivo",
|
||||
"truncatedNote": "Pré-visualização truncada. Tamanho do arquivo: {{size}}."
|
||||
},
|
||||
"markdownPreviewImage": {
|
||||
"expandFallback": "Expandir imagem",
|
||||
@@ -1354,7 +1354,7 @@
|
||||
"tryAgain": "Tente novamente."
|
||||
},
|
||||
"tasksCard": {
|
||||
"noSources": "Nenhuma fonte de tarefas conectada",
|
||||
"noSources": "Nenhuma origem de tarefas conectada",
|
||||
"openProviderTasks": "Abrir tarefas do {{provider}}",
|
||||
"title": "Tarefas"
|
||||
}
|
||||
@@ -1532,7 +1532,21 @@
|
||||
"workspace": "Espaço de Trabalho"
|
||||
}
|
||||
},
|
||||
"newWorkspace": {
|
||||
"hostPicker": {
|
||||
"title": "Criar Espaço de Trabalho em"
|
||||
},
|
||||
"loadingDrawer": {
|
||||
"downloadProgress": "Baixando… {{progress}}",
|
||||
"downloading": "Baixando",
|
||||
"loading": "Carregando"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"desktopChannel": {
|
||||
"name": "Notificações do desktop",
|
||||
"silentName": "Notificações silenciosas do Orca"
|
||||
},
|
||||
"notificationDeliverySection": {
|
||||
"footer": "Os tipos de alerta seguem as configurações de notificação de cada desktop pareado. As notificações são pausadas após 7 dias sem usar este app; abra-o e reconecte-se para retomá-las.",
|
||||
"onlyWhenAway": "Só quando estiver longe do desktop",
|
||||
@@ -1853,7 +1867,7 @@
|
||||
"sendKey": "Enviar {{label}}",
|
||||
"switchToBufferedInput": "Mudar para entrada de comandos em buffer",
|
||||
"switchToDesktopMode": "Alternar para o modo desktop",
|
||||
"switchToLiveInput": "Mudar para entrada direta no terminal",
|
||||
"switchToLiveInput": "Mudar para entrada em tempo real no terminal",
|
||||
"switchToPhoneMode": "Mudar para o modo celular"
|
||||
},
|
||||
"activeContent": {
|
||||
@@ -2590,11 +2604,71 @@
|
||||
}
|
||||
},
|
||||
"sourceControl": {
|
||||
"actionSheetRunners": {
|
||||
"noBaseBranch": "Nenhuma branch base disponível para fazer rebase",
|
||||
"waitingForDesktop": "Aguardando o desktop…"
|
||||
},
|
||||
"actions": {
|
||||
"checkingReviewStatus": "Verificando status da revisão.",
|
||||
"checkoutBeforePublish": "Faça checkout de uma branch antes de publicar commits.",
|
||||
"commitStagedChanges": "Faça commit das alterações staged.",
|
||||
"commits": "Commits",
|
||||
"committing": "Commit em andamento.",
|
||||
"createPr": "Criar PR",
|
||||
"enterCommitMessage": "Digite uma mensagem de commit para fazer commit.",
|
||||
"forcePushWithLease": "Faça force push com lease para atualizar a branch remota.",
|
||||
"forcePushing": "Force push em andamento.",
|
||||
"linkedReviewUnavailable": "A branch da revisão vinculada está indisponível.",
|
||||
"publishToOrigin": "Publique esta branch no origin.",
|
||||
"pullCommits_many": "Faça pull de {{count}} commits.",
|
||||
"pullCommits_one": "Faça pull de {{count}} commit.",
|
||||
"pullCommits_other": "Faça pull de {{count}} commits.",
|
||||
"pushAndCreatePr": "Push e Criar PR",
|
||||
"switchBranch": "Trocar de branch"
|
||||
"pushCommits_many": "Faça push de {{count}} commits.",
|
||||
"pushCommits_one": "Faça push de {{count}} commit.",
|
||||
"pushCommits_other": "Faça push de {{count}} commits.",
|
||||
"pushLinkedReview": "Faça push das atualizações para a branch da revisão vinculada.",
|
||||
"remoteOperationInProgress": "Operação remota em andamento.",
|
||||
"resolveConflicts": "Resolva os conflitos antes de fazer commit.",
|
||||
"reviewAlreadyMerged": "Nada para fazer commit. A revisão já foi mergeada.",
|
||||
"stageAllChanges": "Adicione todas as alterações ao stage.",
|
||||
"stageFileToCommit": "Adicione pelo menos um arquivo ao stage para fazer commit.",
|
||||
"switchBranch": "Trocar de branch",
|
||||
"syncCounts": "Faça pull de {{behind}} e push de {{ahead}}.",
|
||||
"upToDate": "Nada para fazer commit. A branch está atualizada.",
|
||||
"waitForRemoteOperation": "Tente novamente quando a operação remota terminar."
|
||||
},
|
||||
"branchBaseRef": {
|
||||
"resolveFailed": "Não foi possível determinar a branch base"
|
||||
},
|
||||
"branchCard": {
|
||||
"branchCount": "{{count}} na branch",
|
||||
"changedCount": "Alterações: {{count}}",
|
||||
"cherryPickState": "cherry-pick",
|
||||
"mergeState": "merge",
|
||||
"rebaseState": "rebase",
|
||||
"stagedCount": "No stage: {{count}}"
|
||||
},
|
||||
"branchCompare": {
|
||||
"commits_many": "{{count}} commits",
|
||||
"commits_one": "{{count}} commit",
|
||||
"commits_other": "{{count}} commits",
|
||||
"files_many": "{{count}} arquivos",
|
||||
"files_one": "{{count}} arquivo",
|
||||
"files_other": "{{count}} arquivos",
|
||||
"sectionTitle": "Commitado na Branch",
|
||||
"summary": "{{files}} - em relação a {{baseRef}}",
|
||||
"summaryWithCommits": "{{files}} - {{commits}} - em relação a {{baseRef}}"
|
||||
},
|
||||
"branchCompareOutcome": {
|
||||
"baseBranchUnavailable": "Não foi possível determinar a branch base para comparação.",
|
||||
"loadFailed": "Não foi possível carregar as alterações commitadas"
|
||||
},
|
||||
"branchDiffPreviewDrawer": {
|
||||
"closePreview": "Fechar prévia do diff commitado",
|
||||
"committedOnBranch": "Commitado na branch",
|
||||
"loadFailed": "Não foi possível carregar o diff",
|
||||
"truncated": "Diff truncado para prévia no celular."
|
||||
},
|
||||
"commitDropdown": {
|
||||
"checkOutBranchToPush": "Faça checkout de uma branch antes de fazer push de commits",
|
||||
@@ -2619,8 +2693,49 @@
|
||||
"stageFile": "Coloque pelo menos um arquivo em stage para fazer commit",
|
||||
"useCommitAndForcePush": "Use Commit e Force Push — o remoto só tem cópias antigas de commits locais"
|
||||
},
|
||||
"commitFailurePanel": {
|
||||
"fix": "Corrigir",
|
||||
"fixWithAi": "Corrigir falha de commit com IA",
|
||||
"hideDetails": "Ocultar detalhes",
|
||||
"hideFailureDetails": "Ocultar detalhes da falha no commit",
|
||||
"showDetails": "Mostrar detalhes",
|
||||
"showFailureDetails": "Mostrar detalhes da falha no commit",
|
||||
"summary": "Falha no commit.",
|
||||
"title": "Falha no commit"
|
||||
},
|
||||
"commitMessageAi": {
|
||||
"generateFailed": "Falha ao gerar mensagem de commit"
|
||||
},
|
||||
"commitRunners": {
|
||||
"actionFailed": "Falha na ação de controle de versão",
|
||||
"commitFailed": "Falha no commit"
|
||||
},
|
||||
"conflictAbort": {
|
||||
"abortMerge": "Abortar merge",
|
||||
"abortOperation": "Abortar {{operation}}",
|
||||
"abortRebase": "Abortar rebase",
|
||||
"aborting": "Abortando…"
|
||||
},
|
||||
"content": {
|
||||
"cancelGeneration": "Cancelar geração da mensagem de commit",
|
||||
"commitMessageDisabled": "Mensagem de commit desativada. Nenhum arquivo no stage.",
|
||||
"commitMessagePlaceholder": "Mensagem de commit",
|
||||
"emptyMessage": "A árvore de trabalho está limpa.",
|
||||
"emptyTitle": "Nenhuma alteração local",
|
||||
"generateMessage": "Gerar mensagem de commit com IA",
|
||||
"noStagedFiles": "Nenhum arquivo no stage",
|
||||
"openActions": "Abrir ações de controle de versão",
|
||||
"reconnecting": "Reconectando ao desktop…",
|
||||
"regenerateHint": "Limpe a mensagem para gerar novamente.",
|
||||
"stageAll": "Colocar Tudo em Stage",
|
||||
"unstageAll": "Remover Tudo do Stage"
|
||||
},
|
||||
"createPrAction": {
|
||||
"createReview": "Criar {{titleLabel}}"
|
||||
"checkingStatus": "Verificando status de review…",
|
||||
"createPullRequest": "Criar Pull Request",
|
||||
"createReview": "Criar {{titleLabel}}",
|
||||
"providerUnavailable": "Criação de revisões indisponível para este provedor",
|
||||
"statusUnavailable": "Status de review indisponível"
|
||||
},
|
||||
"dropdownCounts": {
|
||||
"fastForwardCount_many": "Fazer fast-forward de {{count}} commits",
|
||||
@@ -2649,6 +2764,69 @@
|
||||
"titleUnpublishedForcePushCount_one": "Faça force push com lease de {{count}} commit da branch e defina um upstream se necessário.",
|
||||
"titleUnpublishedForcePushCount_other": "Faça force push com lease de {{count}} commits da branch e defina um upstream se necessário."
|
||||
},
|
||||
"fileList": {
|
||||
"committedSection": "Commitado na Branch"
|
||||
},
|
||||
"fileRows": {
|
||||
"addedByThem": "Adicionado por eles",
|
||||
"addedByUs": "Adicionado por nós",
|
||||
"bothAdded": "Adicionado por ambos",
|
||||
"bothDeleted": "Excluído por ambos",
|
||||
"bothModified": "Modificado por ambos",
|
||||
"committedSection": "Commitado na Branch",
|
||||
"committedUnavailable": "Alterações commitadas indisponíveis.",
|
||||
"deletedByThem": "Excluído por eles",
|
||||
"deletedByUs": "Excluído por nós",
|
||||
"discardFile": "Descartar {{path}}",
|
||||
"loadingCommitted": "Carregando alterações commitadas…",
|
||||
"openChangedFile": "Abrir arquivo alterado {{path}}",
|
||||
"openCommittedChange": "Abrir alteração commitada em {{path}}",
|
||||
"renamedFrom": "de {{path}}",
|
||||
"stageFile": "Adicionar {{path}} ao stage",
|
||||
"unresolvedConflict": "Conflito não resolvido",
|
||||
"unstageFile": "Remover {{path}} do stage"
|
||||
},
|
||||
"gitHistory": {
|
||||
"days_many": "{{count}}d",
|
||||
"days_one": "{{count}}d",
|
||||
"days_other": "{{count}}d",
|
||||
"hours_many": "{{count}}h",
|
||||
"hours_one": "{{count}}h",
|
||||
"hours_other": "{{count}}h",
|
||||
"justNow": "agora mesmo",
|
||||
"loadFailed": "Falha ao carregar o histórico de commits",
|
||||
"minutes_many": "{{count}}m",
|
||||
"minutes_one": "{{count}}m",
|
||||
"minutes_other": "{{count}}m",
|
||||
"months_many": "{{count}} meses",
|
||||
"months_one": "{{count}} mês",
|
||||
"months_other": "{{count}} meses",
|
||||
"noCommitMessage": "(sem mensagem de commit)",
|
||||
"years_many": "{{count}} anos",
|
||||
"years_one": "{{count}} ano",
|
||||
"years_other": "{{count}} anos"
|
||||
},
|
||||
"gitHistoryList": {
|
||||
"loadFailed": "Falha ao carregar o histórico",
|
||||
"loadFilesFailed": "Não foi possível carregar os arquivos do commit",
|
||||
"noCommits": "Nenhum commit.",
|
||||
"noFileChanges": "Nenhuma alteração em arquivos",
|
||||
"retryFiles": "Tentar carregar os arquivos do commit novamente",
|
||||
"waitingForDesktop": "Aguardando o desktop…"
|
||||
},
|
||||
"gitStatus": {
|
||||
"changes": "Alterações",
|
||||
"conflicts": "Conflitos",
|
||||
"stagedChanges": "Alterações no Stage"
|
||||
},
|
||||
"header": {
|
||||
"backToSession": "Voltar à sessão",
|
||||
"close": "Fechar controle de código-fonte",
|
||||
"openNumberedPrWeb": "Abrir pull request #{{number}} na web",
|
||||
"openPrWeb": "Abrir pull request na web",
|
||||
"refresh": "Atualizar controle de código-fonte",
|
||||
"title": "Controle de Código-Fonte"
|
||||
},
|
||||
"hostedReview": {
|
||||
"mrCopy": {
|
||||
"reviewLabel": "merge request",
|
||||
@@ -2661,9 +2839,82 @@
|
||||
"titleLabel": "Pull Request"
|
||||
}
|
||||
},
|
||||
"hostedReviewCopy": {
|
||||
"committingChanges": "Commitando alterações…",
|
||||
"creatingReview": "Criando revisão…",
|
||||
"forcePushing": "Fazendo force push com lease…",
|
||||
"generatingCommitMessage": "Gerando mensagem de commit…",
|
||||
"publishingBranch": "Publicando a branch…",
|
||||
"pushingCommits": "Enviando (push) commits…",
|
||||
"stagingChanges": "Adicionando alterações ao stage…",
|
||||
"updatingBranch": "Atualizando a branch…"
|
||||
},
|
||||
"hostedReviewCreate": {
|
||||
"pushSucceeded": "Push concluído, mas a criação do {{shortLabel}} falhou: {{error}}"
|
||||
},
|
||||
"hostedReviewCreateIntent": {
|
||||
"branchChanged": "A branch mudou durante a preparação do pull request.",
|
||||
"generateMessageFailed": "Não foi possível gerar uma mensagem de commit. Adicione uma no Controle de Código-Fonte e tente novamente.",
|
||||
"resolveConflicts": "Resolva os conflitos antes de criar um pull request.",
|
||||
"resolveOrStageChanges": "Resolva as pendências ou adicione as alterações ao stage antes de criar um pull request.",
|
||||
"reviewCommitMessage": "Revise a mensagem de commit e tente novamente Criar PR."
|
||||
},
|
||||
"hostedReviewGitPreparation": {
|
||||
"commitFailed": "Falha no commit",
|
||||
"refreshFailed": "Não foi possível atualizar o controle de versão",
|
||||
"stageFailed": "Falha ao adicionar alterações ao stage",
|
||||
"updateBranchFailed": "Não foi possível atualizar a branch remota. Tente novamente Criar PR."
|
||||
},
|
||||
"hostedReviewRemotePrerequisite": {
|
||||
"forcePushFailed": "Falha ao fazer force push com lease",
|
||||
"publishFailed": "Falha ao publicar a branch",
|
||||
"pushFailed": "Falha ao fazer push dos commits"
|
||||
},
|
||||
"hostedReviewService": {
|
||||
"createFailed": "Falha ao criar pull request",
|
||||
"pushBeforeCreateFailed": "O push falhou. Resolva o erro de push e tente novamente."
|
||||
},
|
||||
"hubTab": {
|
||||
"changes": "Alterações",
|
||||
"commits": "Commits",
|
||||
"pullRequest": "Pull Request"
|
||||
},
|
||||
"loaders": {
|
||||
"connectingToDesktop": "Conectando ao desktop…",
|
||||
"loadFailed": "Não foi possível carregar o controle de versão",
|
||||
"updateDesktop": "Atualize o Orca no desktop para usar o controle de versão no celular.",
|
||||
"waitingForDesktop": "Aguardando o desktop…"
|
||||
},
|
||||
"modals": {
|
||||
"actionsTitle": "Controle de Código-Fonte",
|
||||
"currentBranch": "atual",
|
||||
"discardButton": "Descartar",
|
||||
"discardConfirmMessage": "Descartar alterações em \"{{path}}\"? Esta ação não pode ser desfeita.",
|
||||
"discardTitle": "Descartar alteração?",
|
||||
"openPrMessage": "Abrir no seu navegador?",
|
||||
"openPrWithWarning": "Abrir no seu navegador?\n\n{{warning}}",
|
||||
"prCreatedTitle": "Pull Request Criado",
|
||||
"switchBranchTitle": "Trocar Branch"
|
||||
},
|
||||
"openers": {
|
||||
"openDiffFailed": "Não foi possível abrir o diff",
|
||||
"tabNotReady": "O arquivo foi aberto, mas a aba ainda não está pronta. Tente novamente.",
|
||||
"waitingForDesktop": "Aguardando o desktop…"
|
||||
},
|
||||
"panel": {
|
||||
"loadFailedTitle": "Não foi possível carregar",
|
||||
"unavailableTitle": "Controle de Código-Fonte Indisponível"
|
||||
},
|
||||
"prChip": {
|
||||
"createPr": "Criar pull request",
|
||||
"loading": "Carregando pull request…",
|
||||
"loadingLabel": "Carregando pull request",
|
||||
"openLabel": "Pull request #{{number}}, {{state}}, {{checks}}. Abrir pull request.",
|
||||
"openWithComments_many": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentários não resolvidos. Abrir pull request.",
|
||||
"openWithComments_one": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentário não resolvido. Abrir pull request.",
|
||||
"openWithComments_other": "Pull request #{{number}}, {{state}}, {{checks}}, {{count}} comentários não resolvidos. Abrir pull request.",
|
||||
"unavailableLabel": "Pull request indisponível: {{message}}"
|
||||
},
|
||||
"prCreate": {
|
||||
"authRequired": "Autentique-se antes de criar um {{reviewLabel}}.",
|
||||
"baseNotOnRemote": "Faça push da branch base antes de criar um {{reviewLabel}}.",
|
||||
@@ -2682,8 +2933,19 @@
|
||||
"unsupportedMergeRequests": "Não há suporte à criação de merge requests neste repositório.",
|
||||
"unsupportedPullRequests": "Não há suporte à criação de pull requests neste repositório."
|
||||
},
|
||||
"prLink": {
|
||||
"updatePullRequestFailed": "Falha ao atualizar o pull request vinculado",
|
||||
"updateReviewFailed": "Falha ao atualizar a revisão vinculada"
|
||||
},
|
||||
"primaryAction": {
|
||||
"forcePushFromDesktop": "Faça force push da branch deste pull request pelo desktop"
|
||||
"commit": "Commit",
|
||||
"forcePush": "Force Push",
|
||||
"forcePushFromDesktop": "Faça force push da branch deste pull request pelo desktop",
|
||||
"publishBranch": "Publicar Branch",
|
||||
"pull": "Pull",
|
||||
"push": "Push",
|
||||
"stageAll": "Colocar Tudo em Stage",
|
||||
"sync": "Sincronizar"
|
||||
},
|
||||
"remoteDropdown": {
|
||||
"branchAlreadyPublished": "A branch já está publicada",
|
||||
@@ -2733,6 +2995,600 @@
|
||||
"tryFastForwardPull": "Tente um pull com fast-forward; o git pode rejeitar commits locais",
|
||||
"tryRegularPush": "Tente um push normal; o git pode exigir force push",
|
||||
"useForcePushToSync": "Use Force Push — o remoto só tem cópias antigas de commits locais"
|
||||
},
|
||||
"runners": {
|
||||
"actionFailed": "Falha na ação de controle de versão"
|
||||
},
|
||||
"screenState": {
|
||||
"noBranch": "Sem branch"
|
||||
},
|
||||
"state": {
|
||||
"noUpstream": "Sem upstream",
|
||||
"syncStatus": "{{ahead}} à frente, {{behind}} atrás"
|
||||
},
|
||||
"useMobileCommitFailureRecovery": {
|
||||
"launchFailed": "Falha ao iniciar o agente",
|
||||
"waitingForDesktop": "Aguardando o desktop…"
|
||||
},
|
||||
"useMobileCommitMessageGeneration": {
|
||||
"generateFailed": "Falha ao gerar a mensagem de commit"
|
||||
},
|
||||
"useMobileCreatePrRunner": {
|
||||
"branchRequired": "Faça checkout de uma branch antes de criar um pull request."
|
||||
},
|
||||
"useMobileGitRequests": {
|
||||
"actionFailed": "Falha na ação de controle de versão",
|
||||
"branchUnavailable": "Status da branch indisponível",
|
||||
"commitFailed": "Falha no commit",
|
||||
"waitingForDesktop": "Aguardando o desktop…"
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"composerSource": {
|
||||
"baseFailed": "Falha ao determinar a branch base.",
|
||||
"forkPushWarning": "Este PR está com \"Permitir edições de mantenedores\" desativado; o GitHub pode rejeitar o push para o fork."
|
||||
},
|
||||
"detailCommentRenderers": {
|
||||
"commentPlaceholder": "Adicionar um comentário",
|
||||
"comments_many": "{{count}} comentários",
|
||||
"comments_one": "{{count}} comentário",
|
||||
"comments_other": "{{count}} comentários",
|
||||
"reopenThread": "Reabrir thread",
|
||||
"reply": "Responder",
|
||||
"resolveThread": "Resolver thread",
|
||||
"resolvedCommentBy": "Comentário de {{author}} resolvido",
|
||||
"resolvedThreadBy": "Thread de {{author}} resolvida",
|
||||
"sendComment": "Enviar comentário",
|
||||
"show": "Mostrar"
|
||||
},
|
||||
"filterPickers": {
|
||||
"allTeams": "Todas as equipes",
|
||||
"changeStatus": "Alterar status",
|
||||
"fieldHidden": "Oculto nos cartões",
|
||||
"fieldShown": "Exibido nos cartões",
|
||||
"fieldsSubtitle": "Selecione quais campos do projeto aparecem nos cartões dos itens.",
|
||||
"fieldsTitle": "Campos do Projeto",
|
||||
"gitlabFilter": "Filtro do GitLab",
|
||||
"gitlabView": "Visualização do GitLab",
|
||||
"jiraFilter": "Filtro do Jira",
|
||||
"jiraSite": "Site do Jira",
|
||||
"linearFilter": "Filtro do Linear",
|
||||
"linearIssue": "Issue do Linear",
|
||||
"linearWorkspace": "Espaço de trabalho do Linear",
|
||||
"loadingStates": "Carregando estados…",
|
||||
"noFields": "Esta visualização não tem campos extras para mostrar.",
|
||||
"noStates": "Nenhum estado disponível",
|
||||
"switchWorkspaceFailed": "Falha ao trocar de espaço de trabalho",
|
||||
"teamsSubtitle": "Selecione quais equipes aparecem em Tarefas.",
|
||||
"teamsTitle": "Equipes do Linear",
|
||||
"teams_many": "{{count}} equipes",
|
||||
"teams_one": "{{count}} equipe",
|
||||
"teams_other": "{{count}} equipes"
|
||||
},
|
||||
"githubProjectList": {
|
||||
"browseProjects": "Navegar pelos projetos",
|
||||
"chooseProject": "Selecione um projeto do GitHub",
|
||||
"emptyField": "Vazio",
|
||||
"issueSubtitle": "Issue · {{repository}}{{number}}",
|
||||
"itemSubtitle": "Item do projeto · {{repository}}{{number}}",
|
||||
"items": "Itens",
|
||||
"moreFields_many": "+{{count}} campos",
|
||||
"moreFields_one": "+{{count}} campo",
|
||||
"moreFields_other": "+{{count}} campos",
|
||||
"noItems": "Nenhum item no projeto",
|
||||
"pullRequestSubtitle": "Pull request · {{repository}}{{number}}"
|
||||
},
|
||||
"githubProjectPickers": {
|
||||
"add": "Adicionar",
|
||||
"addByUrlHint": "Use Adicionar por URL para acessar os projetos ausentes.",
|
||||
"addPlaceholder": "Adicionar por URL ou owner/número",
|
||||
"adding": "Adicionando…",
|
||||
"browseAll": "Navegar por todos",
|
||||
"browseLoading": "Navegar por todos (carregando…)",
|
||||
"chooseView": "Selecionar visualização do projeto",
|
||||
"loadFailed": "Falha ao carregar os projetos",
|
||||
"noMatches": "Nenhum projeto corresponde à busca.",
|
||||
"noMoreProjects": "Não há mais projetos.",
|
||||
"noProjects": "Nenhum projeto carregado",
|
||||
"organizationsError": "organizações: {{message}}",
|
||||
"organizationsLoadFailed": "Algumas organizações não foram carregadas ({{count}}).",
|
||||
"ownerLoadFailed": "Não foi possível carregar os projetos de {{owner}}.",
|
||||
"pin": "Fixar",
|
||||
"pinned": "Fixados",
|
||||
"recent": "Recentes",
|
||||
"retryHint": "Toque para tentar novamente.",
|
||||
"searchProjects": "Buscar projetos",
|
||||
"sort": "Ordenação do projeto",
|
||||
"subtitle": "Selecione uma visualização de projeto para a página Tarefas.",
|
||||
"title": "GitHub Projects",
|
||||
"unsupportedLayout": "O Orca ainda não oferece suporte a este layout de projeto do GitHub.",
|
||||
"view": "Visualização do projeto"
|
||||
},
|
||||
"githubViewControls": {
|
||||
"fields": "Campos: {{fields}}",
|
||||
"openView": "Abrir visualização no GitHub",
|
||||
"sort": "Ordenação: {{sort}}",
|
||||
"source": "Origem: {{source}}"
|
||||
},
|
||||
"itemActions": {
|
||||
"changeStatus": "Alterar status",
|
||||
"copyGitHubLink": "Copiar link do GitHub",
|
||||
"copyLinearLink": "Copiar link do Linear",
|
||||
"createWorkspace": "Criar espaço de trabalho",
|
||||
"creating": "Criando…",
|
||||
"mergeConflicts": "O GitHub informa conflitos de merge.",
|
||||
"mergeMergeRequest": "Fazer merge do merge request",
|
||||
"mergePullRequest": "Fazer merge do pull request"
|
||||
},
|
||||
"itemDetailContent": {
|
||||
"addSubIssue": "Adicionar sub-issue",
|
||||
"assignee": "Responsável",
|
||||
"assignees": "Responsáveis",
|
||||
"checks": "Verificações",
|
||||
"description": "Descrição",
|
||||
"discussion": "Discussão",
|
||||
"noChecks": "Nenhuma verificação encontrada.",
|
||||
"noComments": "Sem comentários.",
|
||||
"noPipelineRuns": "Nenhuma execução de pipeline para este MR.",
|
||||
"noSubIssues": "Nenhuma sub-issue.",
|
||||
"none": "Nenhum item",
|
||||
"pipeline": "Pipeline",
|
||||
"pipelineJobs_many": "{{count}} jobs",
|
||||
"pipelineJobs_one": "{{count}} job",
|
||||
"pipelineJobs_other": "{{count}} jobs",
|
||||
"project": "Projeto",
|
||||
"rerunAll": "Reexecutar todas",
|
||||
"rerunFailed": "Reexecutar as que falharam",
|
||||
"status": "Status",
|
||||
"subIssueTitle": "Título da sub-issue",
|
||||
"subIssues": "Sub-issues",
|
||||
"type": "Tipo"
|
||||
},
|
||||
"itemDetailDrawer": {
|
||||
"refreshDetails": "Atualizar detalhes"
|
||||
},
|
||||
"itemFieldEditors": {
|
||||
"addLabels": "Adicionar rótulos, separados por vírgula",
|
||||
"addUsernames": "Adicionar nomes de usuário, separados por vírgula",
|
||||
"assignees": "Responsáveis",
|
||||
"labels": "Rótulos",
|
||||
"loadingAssignees": "Carregando responsáveis…",
|
||||
"loadingLabels": "Carregando rótulos…",
|
||||
"noAssignableUsers": "Nenhum usuário disponível para atribuição neste repositório.",
|
||||
"noLabels": "Nenhum rótulo neste repositório.",
|
||||
"none": "Nenhum",
|
||||
"removeLabels": "Remover rótulos, separados por vírgula",
|
||||
"removeUsernames": "Remover nomes de usuário, separados por vírgula",
|
||||
"saveTitle": "Salvar título",
|
||||
"title": "Título",
|
||||
"updateAssignees": "Atualizar responsáveis",
|
||||
"updateLabels": "Atualizar rótulos"
|
||||
},
|
||||
"itemReviewSections": {
|
||||
"binaryFile": "Arquivo binário.",
|
||||
"changedFilesTitle": "Arquivos alterados",
|
||||
"descriptionPlaceholder": "Descrição",
|
||||
"fileContentsUnavailable": "Conteúdo do arquivo indisponível.",
|
||||
"hideFile": "Ocultar",
|
||||
"loadingReviewers": "Carregando revisores…",
|
||||
"markUnviewed": "Marcar como não visualizado",
|
||||
"markViewed": "Marcar como visualizado",
|
||||
"noDescription": "Sem descrição.",
|
||||
"noReviewerSuggestions": "Nenhuma sugestão de revisor encontrada.",
|
||||
"noReviewersRequested": "Nenhum revisor solicitado.",
|
||||
"requestReview": "Solicitar revisão",
|
||||
"reviewersPlaceholder": "Solicitar revisores",
|
||||
"reviewersTitle": "Revisores",
|
||||
"saveDescription": "Salvar descrição",
|
||||
"viewFile": "Ver"
|
||||
},
|
||||
"legacySurface": {
|
||||
"loadIssuesFailed": "Não foi possível carregar as issues de {{source}}.",
|
||||
"mergeAction": "Merge",
|
||||
"mergeMethodTitle": "Método de merge",
|
||||
"mergePullRequestTitle": "Fazer Merge do Pull Request",
|
||||
"mergeRequestMergeMessage": "Escolha como fazer merge deste merge request.",
|
||||
"mergeRequestTitle": "Merge Request",
|
||||
"pullRequestMergeMessage": "Escolha como fazer merge deste pull request.",
|
||||
"retryLoadingIssues": "Tentar carregar novamente as issues de {{source}}",
|
||||
"retrying": "Tentando novamente…",
|
||||
"sourceFallback": "A origem de issues preferida, upstream, está indisponível para {{repo}}. Usando origin.",
|
||||
"subIssueDataUnavailable": "Os dados de sub-issue não estão disponíveis para o seu token.",
|
||||
"updateItemTitle": "Atualizar Item"
|
||||
},
|
||||
"linearList": {
|
||||
"changeStatusFrom": "Alterar status de {{status}}"
|
||||
},
|
||||
"linearViewControls": {
|
||||
"displayButton": "Exibição",
|
||||
"groupLabel": "Agrupar por: {{group}}",
|
||||
"orderLabel": "Ordem: {{order}}"
|
||||
},
|
||||
"listDisplayPickers": {
|
||||
"displayPropertiesTitle": "Propriedades de exibição",
|
||||
"linearGroupTitle": "Agrupar issues do Linear",
|
||||
"linearOrderTitle": "Ordenar issues do Linear",
|
||||
"linearViewTitle": "Visualização do Linear",
|
||||
"sortTasksTitle": "Ordenar tarefas"
|
||||
},
|
||||
"listSurface": {
|
||||
"connectLinearButton": "Conectar Linear",
|
||||
"connectLinearMessage": "Veja as issues do Linear atribuídas a você e comece a trabalhar nelas diretamente em Tarefas.",
|
||||
"connectLinearTitle": "Conecte sua conta do Linear",
|
||||
"jiraStatusFailed": "Falha ao ler o status do Jira",
|
||||
"updateDesktopMessage": "Esta visualização de Tarefas no celular requer uma versão mais recente do Orca no desktop.",
|
||||
"updateDesktopTitle": "Atualize o Orca no desktop"
|
||||
},
|
||||
"options": {
|
||||
"all": "Todos",
|
||||
"assignedToMe": "Atribuído a mim",
|
||||
"assignee": "Responsável",
|
||||
"board": "Quadro",
|
||||
"boardDescription": "Colunas agrupadas",
|
||||
"closedState": "Fechados",
|
||||
"completedState": "Concluídas",
|
||||
"createdState": "Criadas",
|
||||
"githubAssignedIssuesDescription": "Issues abertas atribuídas a você",
|
||||
"githubDescription": "Issues e pull requests",
|
||||
"githubIssuesDescription": "Issues do GitHub",
|
||||
"githubOpenIssuesDescription": "Issues abertas do GitHub",
|
||||
"githubProjectsDescription": "Visualizações do GitHub Projects",
|
||||
"githubPullRequestsDescription": "Pull requests do GitHub",
|
||||
"gitlabAllDescription": "Qualquer estado do GitLab",
|
||||
"gitlabClosedDescription": "Issues e merge requests fechados",
|
||||
"gitlabDescription": "Issues e merge requests",
|
||||
"gitlabMergedDescription": "Merge requests mergeados",
|
||||
"gitlabOpenDescription": "Issues e merge requests em aberto",
|
||||
"identifier": "Identificador",
|
||||
"issues": "Issues",
|
||||
"jiraDescription": "Issues atribuídas e relatadas",
|
||||
"labels": "Rótulos",
|
||||
"linearAllDescription": "Issues abertas nos espaços de trabalho conectados",
|
||||
"linearAssignedDescription": "Issues atribuídas a você",
|
||||
"linearCompletedDescription": "Issues concluídas recentemente",
|
||||
"linearCreatedDescription": "Issues criadas por você",
|
||||
"linearDescription": "Issues atribuídas e da equipe",
|
||||
"list": "Lista",
|
||||
"listDescription": "Issues em linhas compactas",
|
||||
"mergedState": "Mergeados",
|
||||
"mine": "Meus",
|
||||
"myIssues": "Minhas issues",
|
||||
"myPullRequestsDescription": "Pull requests criados por você",
|
||||
"myTodos": "Minhas pendências",
|
||||
"myTodosDescription": "Pendências do GitLab",
|
||||
"needsReview": "Precisa de revisão",
|
||||
"noGrouping": "Sem agrupamento",
|
||||
"openPullRequestsDescription": "Pull requests abertos",
|
||||
"openState": "Em aberto",
|
||||
"priority": "Prioridade",
|
||||
"projectMergeRequests": "MRs do projeto",
|
||||
"projectMergeRequestsDescription": "Merge requests e issues por repositório",
|
||||
"projects": "Projetos",
|
||||
"pullRequests": "PRs",
|
||||
"repository": "Repositório",
|
||||
"repositorySortDescription": "Agrupar por repositório, depois pela atividade mais recente",
|
||||
"reviewRequestsDescription": "Solicitações de revisão atribuídas a você",
|
||||
"status": "Status",
|
||||
"team": "Equipe",
|
||||
"updated": "Atualizado",
|
||||
"updatedSortDescription": "Atividade mais recente primeiro"
|
||||
},
|
||||
"pickerProjection": {
|
||||
"allRepos": "Todos os repositórios",
|
||||
"allSites": "Todos os sites",
|
||||
"currentlyAscending": "Crescente · toque para inverter",
|
||||
"currentlyDescending": "Decrescente · toque para inverter",
|
||||
"fieldAscending": "{{field}} cresc.",
|
||||
"fieldDescending": "{{field}} decresc.",
|
||||
"fields": "Campos",
|
||||
"repos_many": "{{count}} repositórios",
|
||||
"repos_one": "{{count}} repositório",
|
||||
"repos_other": "{{count}} repositórios",
|
||||
"selectTarget": "Selecionar destino",
|
||||
"selectedFields": "{{selected}}/{{total}} campos",
|
||||
"sortAscending": "Ordenar em ordem crescente",
|
||||
"sources_many": "{{count}} origens",
|
||||
"sources_one": "{{count}} origem",
|
||||
"sources_other": "{{count}} origens",
|
||||
"unsupportedLayout": "Layout não compatível no celular",
|
||||
"updatedSort": "Atualizado",
|
||||
"usesFieldAscending": "Usa {{field}} em ordem crescente",
|
||||
"usesFieldDescending": "Usa {{field}} em ordem decrescente",
|
||||
"usesGitHubRankOrder": "Usa a ordem de classificação do GitHub",
|
||||
"viewNumber": "Visualização #{{number}}",
|
||||
"viewOrder": "Ordem da visualização"
|
||||
},
|
||||
"prFileDiff": {
|
||||
"commentOnLine": "Comentar na linha {{line}}",
|
||||
"commentPlaceholder": "Adicionar comentário de revisão",
|
||||
"noTextChanges": "Nenhuma alteração de texto encontrada.",
|
||||
"showingDiffLines": "Exibindo as primeiras {{limit}} de {{total}} linhas do diff."
|
||||
},
|
||||
"projectComments": {
|
||||
"comments_many": "{{count}} comentários",
|
||||
"comments_one": "{{count}} comentário",
|
||||
"comments_other": "{{count}} comentários",
|
||||
"discussion": "Discussão",
|
||||
"editComment": "Editar comentário",
|
||||
"noComments": "Nenhum comentário.",
|
||||
"reopenThread": "Reabrir thread",
|
||||
"reply": "Responder",
|
||||
"resolveThread": "Resolver thread",
|
||||
"resolvedCommentBy": "Comentário de {{author}} resolvido",
|
||||
"resolvedThreadBy": "Thread de {{author}} resolvida",
|
||||
"show": "Mostrar"
|
||||
},
|
||||
"projectDetailDrawer": {
|
||||
"addRepositoryFromDesktop": "{{repository}} não foi adicionado ao Orca. Adicione este repositório pelo app desktop e depois atualize Tarefas no celular.",
|
||||
"clearType": "Limpar tipo",
|
||||
"closeItem": "Fechar item",
|
||||
"copyGitHubLink": "Copiar link do GitHub",
|
||||
"copyRepository": "Copiar repositório",
|
||||
"createWorkspace": "Criar Espaço de Trabalho",
|
||||
"draftIssue": "Rascunho de issue",
|
||||
"issue": "Issue",
|
||||
"issueType": "Tipo de issue",
|
||||
"loadingIssueTypes": "Carregando tipos de issue…",
|
||||
"mergePullRequest": "Fazer merge do pull request",
|
||||
"mergeRepositoryRequirement": "Para fazer merge, este repositório precisa estar no Orca.",
|
||||
"noIssueTypes": "Nenhum tipo de issue configurado para este repositório.",
|
||||
"noType": "Sem tipo",
|
||||
"openInGitHub": "Abrir no GitHub",
|
||||
"projectItem": "Item do projeto",
|
||||
"projectSubtitle": "Projeto do GitHub · {{repository}}{{itemNumber}}",
|
||||
"pullRequest": "Pull request",
|
||||
"reopenItem": "Reabrir item",
|
||||
"repositoryNotInOrca": "Repositório não está no Orca",
|
||||
"status": "Status",
|
||||
"type": "Tipo",
|
||||
"workspaceCreationRequirement": "Espaços de trabalho só podem ser criados a partir de issues e pull requests do GitHub."
|
||||
},
|
||||
"projectFieldEditors": {
|
||||
"clearField": "Limpar campo",
|
||||
"completedIteration": "Concluída · {{startDate}} · {{duration}}d",
|
||||
"datePlaceholder": "YYYY-MM-DD",
|
||||
"invalidDate": "Digite uma data no formato YYYY-MM-DD.",
|
||||
"invalidNumber": "Digite um número válido.",
|
||||
"noIterations": "Nenhuma iteração disponível.",
|
||||
"numberPlaceholder": "Número",
|
||||
"projectFields": "Campos do projeto",
|
||||
"saveField": "Salvar campo",
|
||||
"textPlaceholder": "Texto",
|
||||
"upcomingIteration": "Atual e próximas · {{startDate}} · {{duration}}d"
|
||||
},
|
||||
"projectMetadataEditors": {
|
||||
"assignees": "Responsáveis",
|
||||
"description": "Descrição",
|
||||
"labels": "Rótulos",
|
||||
"loadingAssignees": "Carregando responsáveis…",
|
||||
"loadingLabels": "Carregando rótulos…",
|
||||
"noAssignableUsers": "Nenhum usuário disponível para atribuição neste repositório.",
|
||||
"noDescription": "Sem descrição.",
|
||||
"noLabels": "Nenhum rótulo neste repositório.",
|
||||
"none": "Nenhum",
|
||||
"saveDescription": "Salvar descrição",
|
||||
"saveTitle": "Salvar título",
|
||||
"title": "Título"
|
||||
},
|
||||
"projectReviewPanels": {
|
||||
"binaryFile": "Arquivo binário.",
|
||||
"changedFiles": "Arquivos alterados",
|
||||
"checks": "Verificações",
|
||||
"fileUnavailable": "Conteúdo do arquivo indisponível.",
|
||||
"hideFile": "Ocultar",
|
||||
"loadingReviewers": "Carregando revisores…",
|
||||
"markUnviewed": "Marcar como não visualizado",
|
||||
"markViewed": "Marcar como visualizado",
|
||||
"noChecks": "Nenhuma verificação encontrada.",
|
||||
"noReviewers": "Nenhum revisor solicitado.",
|
||||
"noSuggestions": "Nenhuma sugestão de revisor encontrada.",
|
||||
"requestReview": "Solicitar revisão",
|
||||
"requestReviewers": "Solicitar revisores",
|
||||
"rerunAll": "Reexecutar todas",
|
||||
"rerunFailed": "Reexecutar as que falharam",
|
||||
"reviewers": "Revisores",
|
||||
"viewFile": "Ver"
|
||||
},
|
||||
"providerControls": {
|
||||
"myTodos": "Minhas pendências",
|
||||
"projectMergeRequests": "MRs do projeto",
|
||||
"sort": "Ordenar por: {{sortLabel}}"
|
||||
},
|
||||
"providerItemList": {
|
||||
"intoBranch": "para {{base}}",
|
||||
"nextPage": "Próxima página",
|
||||
"page": "Página {{page}}",
|
||||
"pageOfTotal": "Página {{page}} de {{total}}",
|
||||
"previousPage": "Página anterior",
|
||||
"selectPage": "Selecionar página, página {{page}}",
|
||||
"selectPageOfTotal": "Selecionar página, página {{page}} de {{total}}"
|
||||
},
|
||||
"providerPickers": {
|
||||
"allRepositories": "Todos os repositórios",
|
||||
"githubView": "Visualização do GitHub",
|
||||
"issueSources": "Origens de issues do GitHub",
|
||||
"issueSourcesDescription": "Escolha, para cada repositório, se deseja buscar e criar issues em upstream ou origin.",
|
||||
"issues": "Issues",
|
||||
"noIssueSources": "Nenhuma origem alternativa de issues disponível.",
|
||||
"origin": "Origin",
|
||||
"pageHint": "Ir para uma página de resultados carregada ou disponível.",
|
||||
"pageLoaded": "Carregada",
|
||||
"pageNotLoaded": "Carrega resultados mais antigos",
|
||||
"pageNumber": "Página {{page}}",
|
||||
"pages": "Páginas do GitHub",
|
||||
"pullRequests": "Pull Requests",
|
||||
"queryingSource": "Consultando {{source}}",
|
||||
"repoDescription": "Escolha quais repositórios consultar.",
|
||||
"repos": "Repositórios",
|
||||
"taskSource": "Origem de tarefas",
|
||||
"upstream": "Upstream"
|
||||
},
|
||||
"providerViewProjection": {
|
||||
"all": "Todos",
|
||||
"allSites": "Todos os sites",
|
||||
"allTeams": "Todas as equipes",
|
||||
"allWorkspaces": "Todos os espaços de trabalho",
|
||||
"chooseProject": "Escolher projeto",
|
||||
"default": "Padrão",
|
||||
"defaultSubtitle": "{{subtitle}} · Padrão",
|
||||
"issues": "Issues",
|
||||
"list": "Lista",
|
||||
"noGrouping": "Sem agrupamento",
|
||||
"openState": "Em aberto",
|
||||
"priority": "Prioridade",
|
||||
"projects": "Projetos",
|
||||
"pullRequests": "PRs",
|
||||
"teams_many": "{{count}} equipes",
|
||||
"teams_one": "{{count}} equipe",
|
||||
"teams_other": "{{count}} equipes",
|
||||
"workspace": "Espaço de trabalho"
|
||||
},
|
||||
"reviewerLinear": {
|
||||
"issues": "Issues",
|
||||
"unassigned": "Não atribuído"
|
||||
},
|
||||
"screenChrome": {
|
||||
"connectLinear": "Conectar Linear",
|
||||
"newGitHubIssue": "Nova issue do GitHub",
|
||||
"newLinearIssue": "Nova issue do Linear",
|
||||
"refreshGitHub": "Atualizar trabalho do GitHub",
|
||||
"refreshGitLab": "Atualizar itens de trabalho do GitLab",
|
||||
"refreshJira": "Atualizar issues do Jira",
|
||||
"refreshLinear": "Atualizar Linear",
|
||||
"title": "Tarefas"
|
||||
},
|
||||
"searchControl": {
|
||||
"jiraPlaceholder": "JQL do Jira, ex.: project = ABC AND statusCategory != Done",
|
||||
"projectPlaceholder": "Buscar na visualização do projeto…",
|
||||
"providerPlaceholder": "Buscar tarefas do {{provider}}…"
|
||||
},
|
||||
"smartSourceModes": {
|
||||
"allStates": "Todos",
|
||||
"branch": "Branch",
|
||||
"closedState": "Fechado",
|
||||
"mergedState": "Mergeado",
|
||||
"name": "Nome",
|
||||
"openState": "Aberto",
|
||||
"smart": "Inteligente"
|
||||
},
|
||||
"sparsePresetDraft": {
|
||||
"directoryRequired": "Adicione ao menos um diretório.",
|
||||
"repoRelativeDirectoriesRequired": "Use diretórios relativos ao repositório, não caminhos raiz, absolutos ou segmentos pai."
|
||||
},
|
||||
"taskViewOptions": {
|
||||
"allSubtitle": "Issues não resolvidas nos sites selecionados",
|
||||
"assignedSubtitle": "Issues não resolvidas atribuídas a você",
|
||||
"doneSubtitle": "Suas issues resolvidas recentemente",
|
||||
"noGitHubTasks": "Nenhuma tarefa do GitHub",
|
||||
"noGitLabTasks": "Nenhuma tarefa do GitLab",
|
||||
"noJiraTasks": "Nenhuma tarefa do Jira",
|
||||
"noLinearTasks": "Nenhuma tarefa do Linear",
|
||||
"reportedSubtitle": "Issues não resolvidas que você relatou"
|
||||
},
|
||||
"tasksCreateDrawers": {
|
||||
"connect": "Conectar",
|
||||
"connectLinearWorkspace": "Conectar espaço de trabalho do Linear",
|
||||
"createIssue": "Criar Issue",
|
||||
"createWorkspaceIn": "Criar Espaço de Trabalho em",
|
||||
"description": "Descrição",
|
||||
"descriptionPlaceholder": "Adicionar contexto",
|
||||
"fileIn": "Criar em {{slug}}",
|
||||
"issueSource": "Origem da issue",
|
||||
"keySecurityHint": "Sua chave é criptografada pelo chaveiro do sistema operacional do host e armazenada localmente.",
|
||||
"linearConnectSubtitle": "Cole uma chave de API pessoal para consultar as issues desse espaço de trabalho.",
|
||||
"linearSettingsLink": "Configurações do Linear / Segurança / Nova chave de API",
|
||||
"linearTeam": "Equipe do Linear",
|
||||
"linearTeamSubtitle": "Crie uma issue na equipe selecionada do Linear.",
|
||||
"newIssueTitle": "Nova Issue do {{providerLabel}}",
|
||||
"origin": "Origin",
|
||||
"personalApiKey": "Chave de API pessoal",
|
||||
"repository": "Repositório",
|
||||
"repositorySubtitle": "Crie uma issue no repositório selecionado.",
|
||||
"team": "Equipe",
|
||||
"title": "Título",
|
||||
"titlePlaceholder": "Título da tarefa",
|
||||
"upstream": "Upstream"
|
||||
},
|
||||
"workspaceAgentSelection": {
|
||||
"blankTerminal": "Terminal em Branco"
|
||||
},
|
||||
"workspaceCreateDrawer": {
|
||||
"addRepository": "Adicione um repositório Git antes de criar um espaço de trabalho do Linear.",
|
||||
"advanced": "Avançado",
|
||||
"agent": "Agente",
|
||||
"connect": "Conectar",
|
||||
"connectFirst": "Conecte o repositório primeiro",
|
||||
"connectRepository": "Conectar Repositório",
|
||||
"connecting": "Conectando…",
|
||||
"createFrom": "Criar a partir de {{branch}}",
|
||||
"defaultBranch": "Branch padrão",
|
||||
"detectingAgents": "Detectando agentes…",
|
||||
"optional": "[Opcional]",
|
||||
"remoteRepository": "Repositório remoto",
|
||||
"repository": "Repositório",
|
||||
"repositoryNotFound": "Repositório não encontrado.",
|
||||
"selectRepository": "Selecione um repositório",
|
||||
"sshConnection": "Conexão SSH",
|
||||
"startFrom": "Iniciar a partir de",
|
||||
"title": "Criar Espaço de Trabalho",
|
||||
"workspaceName": "Nome do Espaço de Trabalho"
|
||||
},
|
||||
"workspaceCreateProjection": {
|
||||
"nameAlreadyExists": "\"{{name}}\" já existe.",
|
||||
"nameRequired": "O nome é obrigatório.",
|
||||
"nameTooLong": "O nome deve ter no máximo 80 caracteres.",
|
||||
"openShell": "Abrir uma shell"
|
||||
},
|
||||
"workspaceOptionPickers": {
|
||||
"baseBranchSubtitle": "Selecione uma branch ou referência existente.",
|
||||
"baseBranchTitle": "Iniciar a partir de",
|
||||
"branchName": "Nome da branch: {{name}}",
|
||||
"defaultBranch": "Branch padrão",
|
||||
"defaultBranchSubtitle": "Usar a branch base configurada neste repositório",
|
||||
"editPreset": "Editar {{name}}",
|
||||
"fullCheckout": "Checkout completo",
|
||||
"fullCheckoutSubtitle": "Usar o repositório inteiro",
|
||||
"newPreset": "Novo predefinido",
|
||||
"noBranches": "Nenhuma branch corresponde à busca.",
|
||||
"searchBranches": "Buscar branches",
|
||||
"sparseCheckoutTitle": "Checkout esparso"
|
||||
},
|
||||
"workspaceSshGate": {
|
||||
"authenticationFailed": "Falha na autenticação",
|
||||
"connected": "Conectado",
|
||||
"connecting": "Conectando",
|
||||
"connectionFailed": "Falha na conexão",
|
||||
"deployingRelay": "Implantando relay",
|
||||
"disconnected": "Desconectado",
|
||||
"reconnectFailed": "Falha na reconexão",
|
||||
"reconnecting": "Reconectando"
|
||||
},
|
||||
"workspaceTrustDrawers": {
|
||||
"alwaysTrustAndRun": "Sempre confiar e executar",
|
||||
"creating": "Criando…",
|
||||
"directoriesLabel": "Diretórios",
|
||||
"directories_many": "{{count}} diretórios",
|
||||
"directories_one": "{{count}} diretório",
|
||||
"directories_other": "{{count}} diretórios",
|
||||
"dontRun": "Não executar",
|
||||
"editSparsePreset": "Editar predefinição de checkout esparso",
|
||||
"nameLabel": "Nome",
|
||||
"namePlaceholder": "Interface do renderizador",
|
||||
"newSetupScript": "Novo script de configuração",
|
||||
"newSparsePreset": "Nova predefinição de checkout esparso",
|
||||
"runHooks": "Executar hooks",
|
||||
"runSetupAndCreate": "Executar configuração e criar",
|
||||
"runSetupTitle": "Executar a configuração de {{name}}?",
|
||||
"setupChangedTitle": "O script de configuração de {{name}} mudou",
|
||||
"setupScript": "Script de configuração",
|
||||
"setupSubtitle": "Escolha se deseja executar a configuração de {{name}} antes de criar este espaço de trabalho.",
|
||||
"setupTitle": "Executar script de configuração?",
|
||||
"skipSetupAndCreate": "Pular configuração e criar",
|
||||
"trustFailed": "Falha ao marcar o script de configuração como confiável.",
|
||||
"trustSubtitle": "O orca.yaml deste repositório é executado no seu computador antes de iniciar o espaço de trabalho. Execute-o apenas se você confiar neste repositório."
|
||||
},
|
||||
"worktreeCreateRetry": {
|
||||
"createFailed": "Falha ao criar espaço de trabalho"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
@@ -1530,12 +1530,12 @@
|
||||
"cardDisplay": "Отображение карточек",
|
||||
"cardLayout": "Вид карточек",
|
||||
"clearFilters": "Сбросить фильтры",
|
||||
"exceptDefaultBranch": "Кроме основной ветки",
|
||||
"exceptDefaultBranch": "Кроме ветки по умолчанию",
|
||||
"filters": "Фильтры",
|
||||
"groupBy": "Группировать по",
|
||||
"hideAutomationCreated": "Скрыть созданные автоматизацией",
|
||||
"hideCliCreated": "Скрыть созданные через CLI",
|
||||
"hideDefaultBranch": "Скрыть основную ветку",
|
||||
"hideDefaultBranch": "Скрыть ветку по умолчанию",
|
||||
"hideDetachedHead": "Скрыть с отсоединённым HEAD",
|
||||
"hideOtherClientWorkspaces": "Скрыть рабочие пространства других клиентов",
|
||||
"hideSleeping": "Скрыть спящие рабочие пространства",
|
||||
@@ -1569,7 +1569,21 @@
|
||||
"workspace": "Рабочее пространство"
|
||||
}
|
||||
},
|
||||
"newWorkspace": {
|
||||
"hostPicker": {
|
||||
"title": "Где создать рабочее пространство"
|
||||
},
|
||||
"loadingDrawer": {
|
||||
"downloadProgress": "Скачивание… {{progress}}",
|
||||
"downloading": "Скачивание",
|
||||
"loading": "Загрузка"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"desktopChannel": {
|
||||
"name": "Уведомления с компьютера",
|
||||
"silentName": "Беззвучные уведомления Orca"
|
||||
},
|
||||
"notificationDeliverySection": {
|
||||
"footer": "Типы уведомлений зависят от настроек уведомлений на каждом сопряжённом компьютере. Если не пользоваться приложением 7 дней, уведомления приостанавливаются. Чтобы возобновить их, откройте приложение и подключитесь снова.",
|
||||
"onlyWhenAway": "Только когда вы не за компьютером",
|
||||
@@ -1806,7 +1820,7 @@
|
||||
"noDetails": "Подробности недоступны."
|
||||
},
|
||||
"prCheckDetailContent": {
|
||||
"annotation": "Примечание",
|
||||
"annotation": "Аннотация",
|
||||
"failedJobs": "Неудачные задания",
|
||||
"jobs": "Задания",
|
||||
"unknown": "неизвестно"
|
||||
@@ -2339,7 +2353,7 @@
|
||||
},
|
||||
"terminalLiveInputStatus": {
|
||||
"listening": "Прослушивание",
|
||||
"liveInput": "Ввод в реальном времени",
|
||||
"liveInput": "Прямой ввод",
|
||||
"preparingMic": "Подготовка микрофона",
|
||||
"processing": "Обработка",
|
||||
"releaseMicHint": "Отпустите кнопку микрофона, чтобы остановить запись",
|
||||
@@ -2374,7 +2388,7 @@
|
||||
"browserCommandFailed": "Не удалось выполнить команду браузера",
|
||||
"browserCreateFailed": "Не удалось создать вкладку браузера",
|
||||
"browserUnavailable": "Страница браузера пока недоступна.",
|
||||
"browserUpdateRequired": "Для трансляции браузера на телефон обновите Orca на сервере",
|
||||
"browserUpdateRequired": "Для трансляции браузера на телефон обновите Orca на компьютере",
|
||||
"invalidUrl": "Введите корректный URL",
|
||||
"noteCreateFailed": "Не удалось создать заметку Markdown",
|
||||
"untitledNoteCreateFailed": "Не удалось создать заметку Markdown без названия"
|
||||
@@ -2468,7 +2482,7 @@
|
||||
"actionFailed": "Не удалось выполнить действие с комментарием"
|
||||
},
|
||||
"usePrTitleAction": {
|
||||
"disconnected": "Нет подключения к серверу.",
|
||||
"disconnected": "Нет подключения к компьютеру.",
|
||||
"updateFailed": "Не удалось обновить заголовок."
|
||||
},
|
||||
"useQuickCommands": {
|
||||
@@ -2656,11 +2670,75 @@
|
||||
}
|
||||
},
|
||||
"sourceControl": {
|
||||
"actionSheetRunners": {
|
||||
"noBaseBranch": "Нет базовой ветки для перебазирования",
|
||||
"waitingForDesktop": "Ожидание подключения к компьютеру…"
|
||||
},
|
||||
"actions": {
|
||||
"checkingReviewStatus": "Получение статуса PR/MR.",
|
||||
"checkoutBeforePublish": "Переключитесь на ветку перед публикацией коммитов.",
|
||||
"commitStagedChanges": "Создать коммит с изменениями в индексе.",
|
||||
"commits": "Коммиты",
|
||||
"committing": "Создаётся коммит.",
|
||||
"createPr": "Создать PR",
|
||||
"enterCommitMessage": "Введите сообщение, чтобы создать коммит.",
|
||||
"forcePushWithLease": "Обновить удалённую ветку принудительной отправкой с проверкой её состояния.",
|
||||
"forcePushing": "Выполняется принудительная отправка.",
|
||||
"linkedReviewUnavailable": "Ветка связанного PR/MR недоступна.",
|
||||
"publishToOrigin": "Опубликовать эту ветку в origin.",
|
||||
"pullCommits_few": "Получить и слить {{count}} коммита.",
|
||||
"pullCommits_many": "Получить и слить {{count}} коммитов.",
|
||||
"pullCommits_one": "Получить и слить {{count}} коммит.",
|
||||
"pullCommits_other": "Получить и слить {{count}} коммита.",
|
||||
"pushAndCreatePr": "Отправить и создать PR",
|
||||
"switchBranch": "Переключиться на ветку"
|
||||
"pushCommits_few": "Отправить {{count}} коммита.",
|
||||
"pushCommits_many": "Отправить {{count}} коммитов.",
|
||||
"pushCommits_one": "Отправить {{count}} коммит.",
|
||||
"pushCommits_other": "Отправить {{count}} коммита.",
|
||||
"pushLinkedReview": "Отправить изменения в ветку связанного PR/MR.",
|
||||
"remoteOperationInProgress": "Выполняется удалённая операция.",
|
||||
"resolveConflicts": "Разрешите конфликты перед созданием коммита.",
|
||||
"reviewAlreadyMerged": "Нет изменений для коммита. Изменения уже слиты.",
|
||||
"stageAllChanges": "Добавить все изменения в индекс.",
|
||||
"stageFileToCommit": "Добавьте хотя бы один файл в индекс, чтобы создать коммит.",
|
||||
"switchBranch": "Переключиться на ветку",
|
||||
"syncCounts": "Получить и слить: {{behind}}, отправить: {{ahead}}.",
|
||||
"upToDate": "Нет изменений для коммита. Ветка актуальна.",
|
||||
"waitForRemoteOperation": "Повторите попытку после завершения удалённой операции."
|
||||
},
|
||||
"branchBaseRef": {
|
||||
"resolveFailed": "Не удалось определить базовую ветку"
|
||||
},
|
||||
"branchCard": {
|
||||
"branchCount": "В ветке: {{count}}",
|
||||
"changedCount": "Изменено: {{count}}",
|
||||
"cherryPickState": "cherry-pick",
|
||||
"mergeState": "слияние",
|
||||
"rebaseState": "перебазирование",
|
||||
"stagedCount": "В индексе: {{count}}"
|
||||
},
|
||||
"branchCompare": {
|
||||
"commits_few": "{{count}} коммита",
|
||||
"commits_many": "{{count}} коммитов",
|
||||
"commits_one": "{{count}} коммит",
|
||||
"commits_other": "{{count}} коммита",
|
||||
"files_few": "{{count}} файла",
|
||||
"files_many": "{{count}} файлов",
|
||||
"files_one": "{{count}} файл",
|
||||
"files_other": "{{count}} файла",
|
||||
"sectionTitle": "Закоммичено в ветке",
|
||||
"summary": "{{files}} — по сравнению с {{baseRef}}",
|
||||
"summaryWithCommits": "{{files}} — {{commits}} — по сравнению с {{baseRef}}"
|
||||
},
|
||||
"branchCompareOutcome": {
|
||||
"baseBranchUnavailable": "Не удалось определить базовую ветку для сравнения.",
|
||||
"loadFailed": "Не удалось загрузить закоммиченные изменения"
|
||||
},
|
||||
"branchDiffPreviewDrawer": {
|
||||
"closePreview": "Закрыть предпросмотр закоммиченных изменений",
|
||||
"committedOnBranch": "Закоммичено в ветке",
|
||||
"loadFailed": "Не удалось загрузить различия",
|
||||
"truncated": "В мобильном предпросмотре показана часть различий."
|
||||
},
|
||||
"commitDropdown": {
|
||||
"checkOutBranchToPush": "Переключитесь на ветку перед отправкой коммитов",
|
||||
@@ -2685,8 +2763,49 @@
|
||||
"stageFile": "Добавьте в индекс хотя бы один файл для коммита",
|
||||
"useCommitAndForcePush": "Используйте «Закоммитить и принудительно отправить»: в удалённой ветке только старые версии локальных коммитов"
|
||||
},
|
||||
"commitFailurePanel": {
|
||||
"fix": "Исправить",
|
||||
"fixWithAi": "Исправить ошибку коммита с ИИ",
|
||||
"hideDetails": "Скрыть подробности",
|
||||
"hideFailureDetails": "Скрыть подробности ошибки коммита",
|
||||
"showDetails": "Показать подробности",
|
||||
"showFailureDetails": "Показать подробности ошибки коммита",
|
||||
"summary": "Не удалось создать коммит.",
|
||||
"title": "Не удалось создать коммит"
|
||||
},
|
||||
"commitMessageAi": {
|
||||
"generateFailed": "Не удалось сгенерировать сообщение коммита"
|
||||
},
|
||||
"commitRunners": {
|
||||
"actionFailed": "Не удалось выполнить операцию управления версиями",
|
||||
"commitFailed": "Не удалось создать коммит"
|
||||
},
|
||||
"conflictAbort": {
|
||||
"abortMerge": "Прервать слияние",
|
||||
"abortOperation": "Прервать {{operation}}",
|
||||
"abortRebase": "Прервать перебазирование",
|
||||
"aborting": "Прерывание…"
|
||||
},
|
||||
"content": {
|
||||
"cancelGeneration": "Отменить создание сообщения коммита",
|
||||
"commitMessageDisabled": "Ввод сообщения коммита недоступен. В индексе нет файлов.",
|
||||
"commitMessagePlaceholder": "Сообщение коммита",
|
||||
"emptyMessage": "В рабочем дереве нет изменений.",
|
||||
"emptyTitle": "Нет локальных изменений",
|
||||
"generateMessage": "Создать сообщение коммита с помощью ИИ",
|
||||
"noStagedFiles": "В индексе нет файлов",
|
||||
"openActions": "Открыть меню управления версиями",
|
||||
"reconnecting": "Переподключение к компьютеру…",
|
||||
"regenerateHint": "Очистите сообщение для повторного создания.",
|
||||
"stageAll": "Добавить всё в индекс",
|
||||
"unstageAll": "Убрать всё из индекса"
|
||||
},
|
||||
"createPrAction": {
|
||||
"createReview": "Создать {{titleLabel}}"
|
||||
"checkingStatus": "Получение статуса PR/MR…",
|
||||
"createPullRequest": "Создать пул-реквест",
|
||||
"createReview": "Создать {{titleLabel}}",
|
||||
"providerUnavailable": "Создание PR/MR недоступно для этого провайдера",
|
||||
"statusUnavailable": "Статус PR/MR недоступен"
|
||||
},
|
||||
"dropdownCounts": {
|
||||
"fastForwardCount_few": "Продвинуть ветку на {{count}} коммита",
|
||||
@@ -2722,6 +2841,74 @@
|
||||
"titleUnpublishedForcePushCount_one": "Принудительно отправьте {{count}} коммит этой ветки с проверкой состояния удалённой ветки и при необходимости настройте отслеживаемую удалённую ветку.",
|
||||
"titleUnpublishedForcePushCount_other": "Принудительно отправьте {{count}} коммита этой ветки с проверкой состояния удалённой ветки и при необходимости настройте отслеживаемую удалённую ветку."
|
||||
},
|
||||
"fileList": {
|
||||
"committedSection": "Закоммичено в ветке"
|
||||
},
|
||||
"fileRows": {
|
||||
"addedByThem": "Добавлен ими",
|
||||
"addedByUs": "Добавлен нами",
|
||||
"bothAdded": "Добавлен с обеих сторон",
|
||||
"bothDeleted": "Удалён с обеих сторон",
|
||||
"bothModified": "Изменён с обеих сторон",
|
||||
"committedSection": "Закоммичено в ветке",
|
||||
"committedUnavailable": "Закоммиченные изменения недоступны.",
|
||||
"deletedByThem": "Удалён ими",
|
||||
"deletedByUs": "Удалён нами",
|
||||
"discardFile": "Отменить изменения в «{{path}}»",
|
||||
"loadingCommitted": "Загрузка закоммиченных изменений…",
|
||||
"openChangedFile": "Открыть изменённый файл {{path}}",
|
||||
"openCommittedChange": "Открыть закоммиченные изменения в «{{path}}»",
|
||||
"renamedFrom": "из {{path}}",
|
||||
"stageFile": "Добавить {{path}} в индекс",
|
||||
"unresolvedConflict": "Неразрешённый конфликт",
|
||||
"unstageFile": "Убрать {{path}} из индекса"
|
||||
},
|
||||
"gitHistory": {
|
||||
"days_few": "{{count}} д",
|
||||
"days_many": "{{count}} д",
|
||||
"days_one": "{{count}} д",
|
||||
"days_other": "{{count}} д",
|
||||
"hours_few": "{{count}} ч",
|
||||
"hours_many": "{{count}} ч",
|
||||
"hours_one": "{{count}} ч",
|
||||
"hours_other": "{{count}} ч",
|
||||
"justNow": "только что",
|
||||
"loadFailed": "Не удалось загрузить историю коммитов",
|
||||
"minutes_few": "{{count}} мин",
|
||||
"minutes_many": "{{count}} мин",
|
||||
"minutes_one": "{{count}} мин",
|
||||
"minutes_other": "{{count}} мин",
|
||||
"months_few": "{{count}} мес.",
|
||||
"months_many": "{{count}} мес.",
|
||||
"months_one": "{{count}} мес.",
|
||||
"months_other": "{{count}} мес.",
|
||||
"noCommitMessage": "(без сообщения коммита)",
|
||||
"years_few": "{{count}} года",
|
||||
"years_many": "{{count}} лет",
|
||||
"years_one": "{{count}} год",
|
||||
"years_other": "{{count}} года"
|
||||
},
|
||||
"gitHistoryList": {
|
||||
"loadFailed": "Не удалось загрузить историю",
|
||||
"loadFilesFailed": "Не удалось загрузить файлы коммита",
|
||||
"noCommits": "Нет коммитов.",
|
||||
"noFileChanges": "Нет изменений в файлах",
|
||||
"retryFiles": "Повторить загрузку файлов коммита",
|
||||
"waitingForDesktop": "Ожидание ответа от компьютера…"
|
||||
},
|
||||
"gitStatus": {
|
||||
"changes": "Изменения",
|
||||
"conflicts": "Конфликты",
|
||||
"stagedChanges": "Изменения в индексе"
|
||||
},
|
||||
"header": {
|
||||
"backToSession": "Вернуться к сессии",
|
||||
"close": "Закрыть управление версиями",
|
||||
"openNumberedPrWeb": "Открыть пул-реквест #{{number}} в браузере",
|
||||
"openPrWeb": "Открыть пул-реквест в браузере",
|
||||
"refresh": "Обновить данные управления версиями",
|
||||
"title": "Управление версиями"
|
||||
},
|
||||
"hostedReview": {
|
||||
"mrCopy": {
|
||||
"reviewLabel": "запрос на слияние",
|
||||
@@ -2734,9 +2921,83 @@
|
||||
"titleLabel": "Пул-реквест"
|
||||
}
|
||||
},
|
||||
"hostedReviewCopy": {
|
||||
"committingChanges": "Создание коммита…",
|
||||
"creatingReview": "Создание запроса на проверку…",
|
||||
"forcePushing": "Принудительная отправка с проверкой удалённой ветки…",
|
||||
"generatingCommitMessage": "Создание сообщения коммита…",
|
||||
"publishingBranch": "Публикация ветки…",
|
||||
"pushingCommits": "Отправка коммитов…",
|
||||
"stagingChanges": "Добавление изменений в индекс…",
|
||||
"updatingBranch": "Обновление ветки…"
|
||||
},
|
||||
"hostedReviewCreate": {
|
||||
"pushSucceeded": "Отправка прошла успешно, но не удалось создать {{shortLabel}}: {{error}}"
|
||||
},
|
||||
"hostedReviewCreateIntent": {
|
||||
"branchChanged": "Ветка изменилась во время подготовки пул-реквеста.",
|
||||
"generateMessageFailed": "Не удалось сгенерировать сообщение коммита. Введите его в разделе «Управление версиями» и повторите попытку.",
|
||||
"resolveConflicts": "Разрешите конфликты перед созданием пул-реквеста.",
|
||||
"resolveOrStageChanges": "Разрешите конфликты или добавьте изменения в индекс перед созданием пул-реквеста.",
|
||||
"reviewCommitMessage": "Проверьте сообщение коммита и повторите «Создать PR»."
|
||||
},
|
||||
"hostedReviewGitPreparation": {
|
||||
"commitFailed": "Не удалось создать коммит",
|
||||
"refreshFailed": "Не удалось обновить данные управления версиями",
|
||||
"stageFailed": "Не удалось добавить изменения в индекс",
|
||||
"updateBranchFailed": "Не удалось обновить удалённую ветку. Повторите «Создать PR»."
|
||||
},
|
||||
"hostedReviewRemotePrerequisite": {
|
||||
"forcePushFailed": "Не удалось выполнить принудительную отправку с проверкой удалённой ветки",
|
||||
"publishFailed": "Не удалось опубликовать ветку",
|
||||
"pushFailed": "Не удалось отправить коммиты"
|
||||
},
|
||||
"hostedReviewService": {
|
||||
"createFailed": "Не удалось создать пул-реквест",
|
||||
"pushBeforeCreateFailed": "Не удалось отправить изменения. Устраните причину ошибки отправки, затем повторите попытку."
|
||||
},
|
||||
"hubTab": {
|
||||
"changes": "Изменения",
|
||||
"commits": "Коммиты",
|
||||
"pullRequest": "Пул-реквест"
|
||||
},
|
||||
"loaders": {
|
||||
"connectingToDesktop": "Подключение к компьютеру…",
|
||||
"loadFailed": "Не удалось загрузить данные управления версиями",
|
||||
"updateDesktop": "Обновите Orca на компьютере, чтобы использовать управление версиями на мобильном устройстве.",
|
||||
"waitingForDesktop": "Ожидание подключения к компьютеру…"
|
||||
},
|
||||
"modals": {
|
||||
"actionsTitle": "Управление версиями",
|
||||
"currentBranch": "текущая",
|
||||
"discardButton": "Отменить изменения",
|
||||
"discardConfirmMessage": "Отменить изменения в «{{path}}»? Это действие необратимо.",
|
||||
"discardTitle": "Отменить изменение",
|
||||
"openPrMessage": "Открыть в браузере?",
|
||||
"openPrWithWarning": "Открыть в браузере?\n\n{{warning}}",
|
||||
"prCreatedTitle": "Пул-реквест создан",
|
||||
"switchBranchTitle": "Переключиться на ветку"
|
||||
},
|
||||
"openers": {
|
||||
"openDiffFailed": "Не удалось открыть сравнение",
|
||||
"tabNotReady": "Файл открыт, но его вкладка ещё не готова. Повторите попытку.",
|
||||
"waitingForDesktop": "Ожидание подключения к компьютеру…"
|
||||
},
|
||||
"panel": {
|
||||
"loadFailedTitle": "Не удалось загрузить",
|
||||
"unavailableTitle": "Управление версиями недоступно"
|
||||
},
|
||||
"prChip": {
|
||||
"createPr": "Создать пул-реквест",
|
||||
"loading": "Загрузка пул-реквеста…",
|
||||
"loadingLabel": "Загрузка пул-реквеста",
|
||||
"openLabel": "Пул-реквест #{{number}}, {{state}}, {{checks}}. Открыть пул-реквест.",
|
||||
"openWithComments_few": "Пул-реквест #{{number}}, {{state}}, {{checks}}, {{count}} неразрешённых комментария. Открыть пул-реквест.",
|
||||
"openWithComments_many": "Пул-реквест #{{number}}, {{state}}, {{checks}}, {{count}} неразрешённых комментариев. Открыть пул-реквест.",
|
||||
"openWithComments_one": "Пул-реквест #{{number}}, {{state}}, {{checks}}, {{count}} неразрешённый комментарий. Открыть пул-реквест.",
|
||||
"openWithComments_other": "Пул-реквест #{{number}}, {{state}}, {{checks}}, {{count}} неразрешённого комментария. Открыть пул-реквест.",
|
||||
"unavailableLabel": "Пул-реквест недоступен: {{message}}"
|
||||
},
|
||||
"prCreate": {
|
||||
"authRequired": "Прежде чем создать {{reviewLabel}}, пройдите аутентификацию.",
|
||||
"baseNotOnRemote": "Прежде чем создать {{reviewLabel}}, отправьте базовую ветку.",
|
||||
@@ -2755,8 +3016,19 @@
|
||||
"unsupportedMergeRequests": "Создание запросов на слияние для этого репозитория не поддерживается.",
|
||||
"unsupportedPullRequests": "Создание пул-реквестов для этого репозитория не поддерживается."
|
||||
},
|
||||
"prLink": {
|
||||
"updatePullRequestFailed": "Не удалось обновить связь с пул-реквестом",
|
||||
"updateReviewFailed": "Не удалось обновить связь с запросом на проверку"
|
||||
},
|
||||
"primaryAction": {
|
||||
"forcePushFromDesktop": "Принудительно отправьте ветку этого пул-реквеста из настольного приложения"
|
||||
"commit": "Закоммитить",
|
||||
"forcePush": "Отправить принудительно",
|
||||
"forcePushFromDesktop": "Принудительно отправьте ветку этого пул-реквеста из настольного приложения",
|
||||
"publishBranch": "Опубликовать ветку",
|
||||
"pull": "Получить и слить",
|
||||
"push": "Отправить",
|
||||
"stageAll": "Добавить всё в индекс",
|
||||
"sync": "Синхронизировать"
|
||||
},
|
||||
"remoteDropdown": {
|
||||
"branchAlreadyPublished": "Ветка уже опубликована",
|
||||
@@ -2806,6 +3078,609 @@
|
||||
"tryFastForwardPull": "Попробовать получить изменения и слить перемоткой вперёд; git может отклонить операцию из-за локальных коммитов",
|
||||
"tryRegularPush": "Попробовать обычную отправку; git может потребовать принудительную отправку",
|
||||
"useForcePushToSync": "Используйте принудительную отправку: в удалённом репозитории есть только старые версии локальных коммитов"
|
||||
},
|
||||
"runners": {
|
||||
"actionFailed": "Не удалось выполнить операцию управления версиями"
|
||||
},
|
||||
"screenState": {
|
||||
"noBranch": "Нет ветки"
|
||||
},
|
||||
"state": {
|
||||
"noUpstream": "Нет отслеживаемой ветки",
|
||||
"syncStatus": "Опережает на {{ahead}}, отстаёт на {{behind}}"
|
||||
},
|
||||
"useMobileCommitFailureRecovery": {
|
||||
"launchFailed": "Не удалось запустить агента",
|
||||
"waitingForDesktop": "Ожидание подключения к компьютеру…"
|
||||
},
|
||||
"useMobileCommitMessageGeneration": {
|
||||
"generateFailed": "Не удалось сгенерировать сообщение коммита"
|
||||
},
|
||||
"useMobileCreatePrRunner": {
|
||||
"branchRequired": "Перед созданием пул-реквеста переключитесь на ветку."
|
||||
},
|
||||
"useMobileGitRequests": {
|
||||
"actionFailed": "Не удалось выполнить операцию управления версиями",
|
||||
"branchUnavailable": "Состояние ветки недоступно",
|
||||
"commitFailed": "Не удалось создать коммит",
|
||||
"waitingForDesktop": "Ожидание подключения к компьютеру…"
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"composerSource": {
|
||||
"baseFailed": "Не удалось определить базовую ветку.",
|
||||
"forkPushWarning": "В этом PR отключена настройка «Разрешить правки сопровождающим»; GitHub может отклонить отправку в форк."
|
||||
},
|
||||
"detailCommentRenderers": {
|
||||
"commentPlaceholder": "Добавить комментарий",
|
||||
"comments_few": "{{count}} комментария",
|
||||
"comments_many": "{{count}} комментариев",
|
||||
"comments_one": "{{count}} комментарий",
|
||||
"comments_other": "{{count}} комментария",
|
||||
"reopenThread": "Возобновить обсуждение",
|
||||
"reply": "Ответить",
|
||||
"resolveThread": "Закрыть обсуждение",
|
||||
"resolvedCommentBy": "Закрытый комментарий от {{author}}",
|
||||
"resolvedThreadBy": "Закрытое обсуждение от {{author}}",
|
||||
"sendComment": "Отправить комментарий",
|
||||
"show": "Показать"
|
||||
},
|
||||
"filterPickers": {
|
||||
"allTeams": "Все команды",
|
||||
"changeStatus": "Изменить статус",
|
||||
"fieldHidden": "Скрыто на карточках",
|
||||
"fieldShown": "Показано на карточках",
|
||||
"fieldsSubtitle": "Выберите, какие поля проекта показывать на карточках элементов.",
|
||||
"fieldsTitle": "Поля проекта",
|
||||
"gitlabFilter": "Фильтр GitLab",
|
||||
"gitlabView": "Представление GitLab",
|
||||
"jiraFilter": "Фильтр Jira",
|
||||
"jiraSite": "Сайт Jira",
|
||||
"linearFilter": "Фильтр Linear",
|
||||
"linearIssue": "Задача Linear",
|
||||
"linearWorkspace": "Рабочее пространство Linear",
|
||||
"loadingStates": "Загрузка статусов…",
|
||||
"noFields": "В этом представлении нет дополнительных полей.",
|
||||
"noStates": "Нет доступных статусов",
|
||||
"switchWorkspaceFailed": "Не удалось сменить рабочее пространство",
|
||||
"teamsSubtitle": "Выберите команды для отображения в разделе «Задачи».",
|
||||
"teamsTitle": "Команды Linear",
|
||||
"teams_few": "{{count}} команды",
|
||||
"teams_many": "{{count}} команд",
|
||||
"teams_one": "{{count}} команда",
|
||||
"teams_other": "{{count}} команды"
|
||||
},
|
||||
"githubProjectList": {
|
||||
"browseProjects": "Просмотреть проекты",
|
||||
"chooseProject": "Выберите проект GitHub",
|
||||
"emptyField": "Пусто",
|
||||
"issueSubtitle": "Задача · {{repository}}{{number}}",
|
||||
"itemSubtitle": "Элемент проекта · {{repository}}{{number}}",
|
||||
"items": "Элементы",
|
||||
"moreFields_few": "+{{count}} поля",
|
||||
"moreFields_many": "+{{count}} полей",
|
||||
"moreFields_one": "+{{count}} поле",
|
||||
"moreFields_other": "+{{count}} поля",
|
||||
"noItems": "В проекте нет элементов",
|
||||
"pullRequestSubtitle": "Пул-реквест · {{repository}}{{number}}"
|
||||
},
|
||||
"githubProjectPickers": {
|
||||
"add": "Добавить",
|
||||
"addByUrlHint": "Добавьте недостающие проекты по URL.",
|
||||
"addPlaceholder": "Добавить по URL или owner/number",
|
||||
"adding": "Добавление…",
|
||||
"browseAll": "Посмотреть все",
|
||||
"browseLoading": "Посмотреть все (загрузка…)",
|
||||
"chooseView": "Выберите представление проекта",
|
||||
"loadFailed": "Не удалось загрузить проекты",
|
||||
"noMatches": "Подходящих проектов не найдено.",
|
||||
"noMoreProjects": "Больше проектов нет.",
|
||||
"noProjects": "Нет загруженных проектов",
|
||||
"organizationsError": "организации: {{message}}",
|
||||
"organizationsLoadFailed": "Не удалось загрузить некоторые организации ({{count}}).",
|
||||
"ownerLoadFailed": "Не удалось загрузить проекты {{owner}}.",
|
||||
"pin": "Закрепить",
|
||||
"pinned": "Закреплено",
|
||||
"recent": "Недавние",
|
||||
"retryHint": "Нажмите, чтобы повторить.",
|
||||
"searchProjects": "Поиск проектов",
|
||||
"sort": "Сортировка проекта",
|
||||
"subtitle": "Выберите представление проекта для страницы «Задачи».",
|
||||
"title": "Проекты GitHub",
|
||||
"unsupportedLayout": "Orca пока не поддерживает этот макет проекта GitHub.",
|
||||
"view": "Представление проекта"
|
||||
},
|
||||
"githubViewControls": {
|
||||
"fields": "Поля: {{fields}}",
|
||||
"openView": "Открыть представление в GitHub",
|
||||
"sort": "Сортировка: {{sort}}",
|
||||
"source": "Источник: {{source}}"
|
||||
},
|
||||
"itemActions": {
|
||||
"changeStatus": "Изменить статус",
|
||||
"copyGitHubLink": "Скопировать ссылку на GitHub",
|
||||
"copyLinearLink": "Скопировать ссылку на Linear",
|
||||
"createWorkspace": "Создать рабочее пространство",
|
||||
"creating": "Создание…",
|
||||
"mergeConflicts": "GitHub сообщает о конфликтах слияния.",
|
||||
"mergeMergeRequest": "Слить запрос на слияние",
|
||||
"mergePullRequest": "Слить пул-реквест"
|
||||
},
|
||||
"itemDetailContent": {
|
||||
"addSubIssue": "Добавить подзадачу",
|
||||
"assignee": "Исполнитель",
|
||||
"assignees": "Исполнители",
|
||||
"checks": "Проверки",
|
||||
"description": "Описание",
|
||||
"discussion": "Обсуждение",
|
||||
"noChecks": "Проверки не найдены.",
|
||||
"noComments": "Комментариев нет.",
|
||||
"noPipelineRuns": "Для этого MR нет запусков конвейера.",
|
||||
"noSubIssues": "Нет подзадач.",
|
||||
"none": "Нет",
|
||||
"pipeline": "Конвейер",
|
||||
"pipelineJobs_few": "{{count}} задания",
|
||||
"pipelineJobs_many": "{{count}} заданий",
|
||||
"pipelineJobs_one": "{{count}} задание",
|
||||
"pipelineJobs_other": "{{count}} задания",
|
||||
"project": "Проект",
|
||||
"rerunAll": "Повторить все",
|
||||
"rerunFailed": "Повторить неуспешные",
|
||||
"status": "Статус",
|
||||
"subIssueTitle": "Название подзадачи",
|
||||
"subIssues": "Подзадачи",
|
||||
"type": "Тип"
|
||||
},
|
||||
"itemDetailDrawer": {
|
||||
"refreshDetails": "Обновить данные"
|
||||
},
|
||||
"itemFieldEditors": {
|
||||
"addLabels": "Метки для добавления (через запятую)",
|
||||
"addUsernames": "Логины для добавления (через запятую)",
|
||||
"assignees": "Исполнители",
|
||||
"labels": "Метки",
|
||||
"loadingAssignees": "Загрузка исполнителей…",
|
||||
"loadingLabels": "Загрузка меток…",
|
||||
"noAssignableUsers": "В этом репозитории не найдены пользователи, которых можно назначить исполнителями.",
|
||||
"noLabels": "В этом репозитории нет меток.",
|
||||
"none": "Нет",
|
||||
"removeLabels": "Метки для удаления (через запятую)",
|
||||
"removeUsernames": "Логины для удаления (через запятую)",
|
||||
"saveTitle": "Сохранить заголовок",
|
||||
"title": "Заголовок",
|
||||
"updateAssignees": "Обновить исполнителей",
|
||||
"updateLabels": "Обновить метки"
|
||||
},
|
||||
"itemReviewSections": {
|
||||
"binaryFile": "Двоичный файл.",
|
||||
"changedFilesTitle": "Изменённые файлы",
|
||||
"descriptionPlaceholder": "Описание",
|
||||
"fileContentsUnavailable": "Содержимое файла недоступно.",
|
||||
"hideFile": "Скрыть",
|
||||
"loadingReviewers": "Загрузка рецензентов…",
|
||||
"markUnviewed": "Отметить непросмотренным",
|
||||
"markViewed": "Отметить просмотренным",
|
||||
"noDescription": "Описания нет.",
|
||||
"noReviewerSuggestions": "Кандидаты в рецензенты не найдены.",
|
||||
"noReviewersRequested": "Проверка ещё ни у кого не запрошена.",
|
||||
"requestReview": "Запросить проверку",
|
||||
"reviewersPlaceholder": "Пригласить рецензентов",
|
||||
"reviewersTitle": "Рецензенты",
|
||||
"saveDescription": "Сохранить описание",
|
||||
"viewFile": "Просмотреть"
|
||||
},
|
||||
"legacySurface": {
|
||||
"loadIssuesFailed": "Не удалось загрузить задачи из {{source}}.",
|
||||
"mergeAction": "Слить",
|
||||
"mergeMethodTitle": "Способ слияния",
|
||||
"mergePullRequestTitle": "Слить пул-реквест",
|
||||
"mergeRequestMergeMessage": "Выберите способ слияния этого запроса на слияние.",
|
||||
"mergeRequestTitle": "Запрос на слияние",
|
||||
"pullRequestMergeMessage": "Выберите способ слияния этого пул-реквеста.",
|
||||
"retryLoadingIssues": "Повторить загрузку задач из {{source}}",
|
||||
"retrying": "Повторная попытка…",
|
||||
"sourceFallback": "Предпочтительный источник задач upstream недоступен для {{repo}}. Используется origin.",
|
||||
"subIssueDataUnavailable": "Ваш токен не даёт доступа к данным подзадач.",
|
||||
"updateItemTitle": "Обновить элемент"
|
||||
},
|
||||
"linearList": {
|
||||
"changeStatusFrom": "Изменить статус «{{status}}»"
|
||||
},
|
||||
"linearViewControls": {
|
||||
"displayButton": "Отображение",
|
||||
"groupLabel": "Группировка: {{group}}",
|
||||
"orderLabel": "Порядок: {{order}}"
|
||||
},
|
||||
"listDisplayPickers": {
|
||||
"displayPropertiesTitle": "Отображаемые поля",
|
||||
"linearGroupTitle": "Группировка задач Linear",
|
||||
"linearOrderTitle": "Сортировка задач Linear",
|
||||
"linearViewTitle": "Вид задач Linear",
|
||||
"sortTasksTitle": "Сортировка задач"
|
||||
},
|
||||
"listSurface": {
|
||||
"connectLinearButton": "Подключить Linear",
|
||||
"connectLinearMessage": "Просматривайте назначенные вам задачи Linear и начинайте работу над ними прямо в разделе «Задачи».",
|
||||
"connectLinearTitle": "Подключите учётную запись Linear",
|
||||
"jiraStatusFailed": "Не удалось получить статус Jira",
|
||||
"updateDesktopMessage": "Для раздела «Задачи» в мобильном приложении нужна более новая версия Orca на компьютере.",
|
||||
"updateDesktopTitle": "Обновите Orca на компьютере"
|
||||
},
|
||||
"options": {
|
||||
"all": "Все",
|
||||
"assignedToMe": "Назначенные мне",
|
||||
"assignee": "Исполнитель",
|
||||
"board": "Доска",
|
||||
"boardDescription": "Колонки по группам",
|
||||
"closedState": "Закрытые",
|
||||
"completedState": "Выполненные",
|
||||
"createdState": "Созданные",
|
||||
"githubAssignedIssuesDescription": "Открытые задачи, назначенные вам",
|
||||
"githubDescription": "Задачи и пул-реквесты",
|
||||
"githubIssuesDescription": "Задачи GitHub",
|
||||
"githubOpenIssuesDescription": "Открытые задачи GitHub",
|
||||
"githubProjectsDescription": "Представления GitHub Projects",
|
||||
"githubPullRequestsDescription": "Пул-реквесты GitHub",
|
||||
"gitlabAllDescription": "Любой статус GitLab",
|
||||
"gitlabClosedDescription": "Закрытые задачи и запросы на слияние",
|
||||
"gitlabDescription": "Задачи и запросы на слияние",
|
||||
"gitlabMergedDescription": "Слитые запросы на слияние",
|
||||
"gitlabOpenDescription": "Открытые задачи и запросы на слияние",
|
||||
"identifier": "Идентификатор",
|
||||
"issues": "Задачи",
|
||||
"jiraDescription": "Назначенные вам и созданные вами задачи",
|
||||
"labels": "Метки",
|
||||
"linearAllDescription": "Открытые задачи в подключённых рабочих пространствах",
|
||||
"linearAssignedDescription": "Задачи, назначенные вам",
|
||||
"linearCompletedDescription": "Недавно выполненные задачи",
|
||||
"linearCreatedDescription": "Задачи, созданные вами",
|
||||
"linearDescription": "Назначенные вам задачи и задачи команды",
|
||||
"list": "Список",
|
||||
"listDescription": "Компактный список задач",
|
||||
"mergedState": "Слитые",
|
||||
"mine": "Мои",
|
||||
"myIssues": "Мои задачи",
|
||||
"myPullRequestsDescription": "Созданные вами пул-реквесты",
|
||||
"myTodos": "Мои дела",
|
||||
"myTodosDescription": "Невыполненные дела GitLab",
|
||||
"needsReview": "Нужна проверка",
|
||||
"noGrouping": "Без группировки",
|
||||
"openPullRequestsDescription": "Открытые пул-реквесты",
|
||||
"openState": "Открытые",
|
||||
"priority": "Приоритет",
|
||||
"projectMergeRequests": "MR проекта",
|
||||
"projectMergeRequestsDescription": "Запросы на слияние и задачи по репозиториям",
|
||||
"projects": "Проекты",
|
||||
"pullRequests": "PR",
|
||||
"repository": "Репозиторий",
|
||||
"repositorySortDescription": "По репозиториям, внутри — сначала недавно обновлённые",
|
||||
"reviewRequestsDescription": "Запросы на проверку, назначенные вам",
|
||||
"status": "Статус",
|
||||
"team": "Команда",
|
||||
"updated": "Обновлено",
|
||||
"updatedSortDescription": "Сначала недавно обновлённые"
|
||||
},
|
||||
"pickerProjection": {
|
||||
"allRepos": "Все репозитории",
|
||||
"allSites": "Все сайты",
|
||||
"currentlyAscending": "По возрастанию · нажмите для сортировки по убыванию",
|
||||
"currentlyDescending": "По убыванию · нажмите для сортировки по возрастанию",
|
||||
"fieldAscending": "{{field}} по возрастанию",
|
||||
"fieldDescending": "{{field}} по убыванию",
|
||||
"fields": "Поля",
|
||||
"repos_few": "{{count}} репозитория",
|
||||
"repos_many": "{{count}} репозиториев",
|
||||
"repos_one": "{{count}} репозиторий",
|
||||
"repos_other": "{{count}} репозитория",
|
||||
"selectTarget": "Выбрать место создания",
|
||||
"selectedFields": "Поля: {{selected}}/{{total}}",
|
||||
"sortAscending": "Сортировать по возрастанию",
|
||||
"sources_few": "{{count}} источника",
|
||||
"sources_many": "{{count}} источников",
|
||||
"sources_one": "{{count}} источник",
|
||||
"sources_other": "{{count}} источника",
|
||||
"unsupportedLayout": "Макет не поддерживается на мобильных устройствах",
|
||||
"updatedSort": "Обновлено",
|
||||
"usesFieldAscending": "Сортировка: {{field}} по возрастанию",
|
||||
"usesFieldDescending": "Сортировка: {{field}} по убыванию",
|
||||
"usesGitHubRankOrder": "Порядок элементов из GitHub",
|
||||
"viewNumber": "Представление № {{number}}",
|
||||
"viewOrder": "Порядок представления"
|
||||
},
|
||||
"prFileDiff": {
|
||||
"commentOnLine": "Комментировать строку {{line}}",
|
||||
"commentPlaceholder": "Добавьте комментарий к строке",
|
||||
"noTextChanges": "Текстовых изменений не найдено.",
|
||||
"showingDiffLines": "Показаны строки сравнения с 1 по {{limit}} из {{total}}."
|
||||
},
|
||||
"projectComments": {
|
||||
"comments_few": "{{count}} комментария",
|
||||
"comments_many": "{{count}} комментариев",
|
||||
"comments_one": "{{count}} комментарий",
|
||||
"comments_other": "{{count}} комментария",
|
||||
"discussion": "Обсуждение",
|
||||
"editComment": "Редактировать комментарий",
|
||||
"noComments": "Комментариев нет.",
|
||||
"reopenThread": "Открыть обсуждение заново",
|
||||
"reply": "Ответить",
|
||||
"resolveThread": "Закрыть обсуждение",
|
||||
"resolvedCommentBy": "Закрытый комментарий от {{author}}",
|
||||
"resolvedThreadBy": "Закрытое обсуждение от {{author}}",
|
||||
"show": "Показать"
|
||||
},
|
||||
"projectDetailDrawer": {
|
||||
"addRepositoryFromDesktop": "Репозиторий {{repository}} не добавлен в Orca. Добавьте его в настольном приложении, затем обновите раздел «Задачи» в мобильном приложении.",
|
||||
"clearType": "Сбросить тип",
|
||||
"closeItem": "Закрыть элемент",
|
||||
"copyGitHubLink": "Скопировать ссылку на GitHub",
|
||||
"copyRepository": "Скопировать имя репозитория",
|
||||
"createWorkspace": "Создать рабочее пространство",
|
||||
"draftIssue": "Черновик задачи",
|
||||
"issue": "Задача",
|
||||
"issueType": "Тип задачи",
|
||||
"loadingIssueTypes": "Загрузка типов задач…",
|
||||
"mergePullRequest": "Слить пул-реквест",
|
||||
"mergeRepositoryRequirement": "Для слияния добавьте этот репозиторий в Orca.",
|
||||
"noIssueTypes": "Для этого репозитория не настроены типы задач.",
|
||||
"noType": "Без типа",
|
||||
"openInGitHub": "Открыть на GitHub",
|
||||
"projectItem": "Элемент проекта",
|
||||
"projectSubtitle": "Проект GitHub · {{repository}}{{itemNumber}}",
|
||||
"pullRequest": "Пул-реквест",
|
||||
"reopenItem": "Открыть элемент заново",
|
||||
"repositoryNotInOrca": "Репозиторий не добавлен в Orca",
|
||||
"status": "Статус",
|
||||
"type": "Тип",
|
||||
"workspaceCreationRequirement": "Рабочие пространства можно создавать только на основе задач и пул-реквестов GitHub."
|
||||
},
|
||||
"projectFieldEditors": {
|
||||
"clearField": "Очистить поле",
|
||||
"completedIteration": "Завершена · {{startDate}} · {{duration}} дн.",
|
||||
"datePlaceholder": "YYYY-MM-DD",
|
||||
"invalidDate": "Введите дату в формате YYYY-MM-DD.",
|
||||
"invalidNumber": "Введите корректное число.",
|
||||
"noIterations": "Нет доступных итераций.",
|
||||
"numberPlaceholder": "Число",
|
||||
"projectFields": "Поля проекта",
|
||||
"saveField": "Сохранить поле",
|
||||
"textPlaceholder": "Текст",
|
||||
"upcomingIteration": "Текущая или предстоящая · {{startDate}} · {{duration}} дн."
|
||||
},
|
||||
"projectMetadataEditors": {
|
||||
"assignees": "Исполнители",
|
||||
"description": "Описание",
|
||||
"labels": "Метки",
|
||||
"loadingAssignees": "Загрузка исполнителей…",
|
||||
"loadingLabels": "Загрузка меток…",
|
||||
"noAssignableUsers": "Для этого репозитория не найдены пользователи, которых можно назначить исполнителями.",
|
||||
"noDescription": "Описания нет.",
|
||||
"noLabels": "В этом репозитории нет меток.",
|
||||
"none": "Нет",
|
||||
"saveDescription": "Сохранить описание",
|
||||
"saveTitle": "Сохранить заголовок",
|
||||
"title": "Заголовок"
|
||||
},
|
||||
"projectReviewPanels": {
|
||||
"binaryFile": "Двоичный файл.",
|
||||
"changedFiles": "Изменённые файлы",
|
||||
"checks": "Проверки",
|
||||
"fileUnavailable": "Содержимое файла недоступно.",
|
||||
"hideFile": "Скрыть",
|
||||
"loadingReviewers": "Загрузка рецензентов…",
|
||||
"markUnviewed": "Отметить непросмотренным",
|
||||
"markViewed": "Отметить просмотренным",
|
||||
"noChecks": "Проверки не найдены.",
|
||||
"noReviewers": "Проверка ещё ни у кого не запрошена.",
|
||||
"noSuggestions": "Подходящих рецензентов нет.",
|
||||
"requestReview": "Запросить проверку",
|
||||
"requestReviewers": "Укажите рецензентов",
|
||||
"rerunAll": "Перезапустить все",
|
||||
"rerunFailed": "Перезапустить неудачные",
|
||||
"reviewers": "Рецензенты",
|
||||
"viewFile": "Просмотреть"
|
||||
},
|
||||
"providerControls": {
|
||||
"myTodos": "Мои дела",
|
||||
"projectMergeRequests": "MR проекта",
|
||||
"sort": "Сортировка: {{sortLabel}}"
|
||||
},
|
||||
"providerItemList": {
|
||||
"intoBranch": "в {{base}}",
|
||||
"nextPage": "Следующая страница",
|
||||
"page": "Страница {{page}}",
|
||||
"pageOfTotal": "Страница {{page}} из {{total}}",
|
||||
"previousPage": "Предыдущая страница",
|
||||
"selectPage": "Выбрать страницу, страница {{page}}",
|
||||
"selectPageOfTotal": "Выбрать страницу, страница {{page}} из {{total}}"
|
||||
},
|
||||
"providerPickers": {
|
||||
"allRepositories": "Все репозитории",
|
||||
"githubView": "Режим GitHub",
|
||||
"issueSources": "Источники задач GitHub",
|
||||
"issueSourcesDescription": "Выберите для каждого репозитория, где искать и создавать задачи: upstream или origin.",
|
||||
"issues": "Задачи",
|
||||
"noIssueSources": "Другие источники задач недоступны.",
|
||||
"origin": "Исходный репозиторий",
|
||||
"pageHint": "Перейдите на загруженную или доступную страницу результатов.",
|
||||
"pageLoaded": "Загружена",
|
||||
"pageNotLoaded": "Загрузит более ранние результаты",
|
||||
"pageNumber": "Страница {{page}}",
|
||||
"pages": "Страницы GitHub",
|
||||
"pullRequests": "Пул-реквесты",
|
||||
"queryingSource": "Запрос к {{source}}",
|
||||
"repoDescription": "Выберите репозитории для поиска.",
|
||||
"repos": "Репозитории",
|
||||
"taskSource": "Источник задач",
|
||||
"upstream": "Вышестоящий репозиторий"
|
||||
},
|
||||
"providerViewProjection": {
|
||||
"all": "Все",
|
||||
"allSites": "Все сайты",
|
||||
"allTeams": "Все команды",
|
||||
"allWorkspaces": "Все рабочие пространства",
|
||||
"chooseProject": "Выбрать проект",
|
||||
"default": "По умолчанию",
|
||||
"defaultSubtitle": "{{subtitle}} · По умолчанию",
|
||||
"issues": "Задачи",
|
||||
"list": "Список",
|
||||
"noGrouping": "Без группировки",
|
||||
"openState": "Открытые",
|
||||
"priority": "Приоритет",
|
||||
"projects": "Проекты",
|
||||
"pullRequests": "PR",
|
||||
"teams_few": "{{count}} команды",
|
||||
"teams_many": "{{count}} команд",
|
||||
"teams_one": "{{count}} команда",
|
||||
"teams_other": "{{count}} команды",
|
||||
"workspace": "Рабочее пространство"
|
||||
},
|
||||
"reviewerLinear": {
|
||||
"issues": "Задачи",
|
||||
"unassigned": "Не назначено"
|
||||
},
|
||||
"screenChrome": {
|
||||
"connectLinear": "Подключить Linear",
|
||||
"newGitHubIssue": "Новая задача GitHub",
|
||||
"newLinearIssue": "Новая задача Linear",
|
||||
"refreshGitHub": "Обновить задачи GitHub",
|
||||
"refreshGitLab": "Обновить задачи GitLab",
|
||||
"refreshJira": "Обновить задачи Jira",
|
||||
"refreshLinear": "Обновить Linear",
|
||||
"title": "Задачи"
|
||||
},
|
||||
"searchControl": {
|
||||
"jiraPlaceholder": "Jira JQL, например project = ABC AND statusCategory != Done",
|
||||
"projectPlaceholder": "Поиск в проекте…",
|
||||
"providerPlaceholder": "Поиск задач {{provider}}…"
|
||||
},
|
||||
"smartSourceModes": {
|
||||
"allStates": "Все",
|
||||
"branch": "Ветка",
|
||||
"closedState": "Закрытые",
|
||||
"mergedState": "Слитые",
|
||||
"name": "Название",
|
||||
"openState": "Открытые",
|
||||
"smart": "Умный ввод"
|
||||
},
|
||||
"sparsePresetDraft": {
|
||||
"directoryRequired": "Добавьте хотя бы один каталог.",
|
||||
"repoRelativeDirectoriesRequired": "Укажите каталоги относительно репозитория. Корень, абсолютные пути и переходы к родительскому каталогу недопустимы."
|
||||
},
|
||||
"taskViewOptions": {
|
||||
"allSubtitle": "Нерешённые задачи на выбранных сайтах",
|
||||
"assignedSubtitle": "Нерешённые задачи, назначенные вам",
|
||||
"doneSubtitle": "Ваши недавно решённые задачи",
|
||||
"noGitHubTasks": "Нет задач в GitHub",
|
||||
"noGitLabTasks": "Нет задач в GitLab",
|
||||
"noJiraTasks": "Нет задач в Jira",
|
||||
"noLinearTasks": "Нет задач в Linear",
|
||||
"reportedSubtitle": "Нерешённые задачи, созданные вами"
|
||||
},
|
||||
"tasksCreateDrawers": {
|
||||
"connect": "Подключить",
|
||||
"connectLinearWorkspace": "Подключить рабочее пространство Linear",
|
||||
"createIssue": "Создать задачу",
|
||||
"createWorkspaceIn": "Где создать рабочее пространство",
|
||||
"description": "Описание",
|
||||
"descriptionPlaceholder": "Добавьте подробности",
|
||||
"fileIn": "Создать в {{slug}}",
|
||||
"issueSource": "Источник задач",
|
||||
"keySecurityHint": "Ваш ключ шифруется с помощью хранилища ключей ОС сервера и хранится локально.",
|
||||
"linearConnectSubtitle": "Вставьте личный API-ключ, чтобы просматривать задачи из этого рабочего пространства.",
|
||||
"linearSettingsLink": "Настройки Linear / Безопасность / Новый API-ключ",
|
||||
"linearTeam": "Команда Linear",
|
||||
"linearTeamSubtitle": "Создайте задачу в выбранной команде Linear.",
|
||||
"newIssueTitle": "Новая задача в {{providerLabel}}",
|
||||
"origin": "Исходный репозиторий",
|
||||
"personalApiKey": "Личный API-ключ",
|
||||
"repository": "Репозиторий",
|
||||
"repositorySubtitle": "Создайте задачу в выбранном репозитории.",
|
||||
"team": "Команда",
|
||||
"title": "Заголовок",
|
||||
"titlePlaceholder": "Заголовок задачи",
|
||||
"upstream": "Вышестоящий репозиторий"
|
||||
},
|
||||
"workspaceAgentSelection": {
|
||||
"blankTerminal": "Пустой терминал"
|
||||
},
|
||||
"workspaceCreateDrawer": {
|
||||
"addRepository": "Добавьте репозиторий Git, прежде чем создавать рабочее пространство для задачи Linear.",
|
||||
"advanced": "Дополнительно",
|
||||
"agent": "Агент",
|
||||
"connect": "Подключиться",
|
||||
"connectFirst": "Сначала подключите репозиторий",
|
||||
"connectRepository": "Подключить репозиторий",
|
||||
"connecting": "Подключение…",
|
||||
"createFrom": "Создать на основе {{branch}}",
|
||||
"defaultBranch": "Ветка по умолчанию",
|
||||
"detectingAgents": "Поиск агентов…",
|
||||
"optional": "[Необязательно]",
|
||||
"remoteRepository": "Удалённый репозиторий",
|
||||
"repository": "Репозиторий",
|
||||
"repositoryNotFound": "Репозиторий не найден.",
|
||||
"selectRepository": "Выберите репозиторий",
|
||||
"sshConnection": "SSH-подключение",
|
||||
"startFrom": "Начать с",
|
||||
"title": "Создать рабочее пространство",
|
||||
"workspaceName": "Название рабочего пространства"
|
||||
},
|
||||
"workspaceCreateProjection": {
|
||||
"nameAlreadyExists": "«{{name}}» уже существует.",
|
||||
"nameRequired": "Укажите название.",
|
||||
"nameTooLong": "Название должно быть не длиннее 80 символов.",
|
||||
"openShell": "Открыть командную оболочку"
|
||||
},
|
||||
"workspaceOptionPickers": {
|
||||
"baseBranchSubtitle": "Выберите существующую ветку или ссылку Git.",
|
||||
"baseBranchTitle": "Начать с",
|
||||
"branchName": "Имя ветки: {{name}}",
|
||||
"defaultBranch": "Ветка по умолчанию",
|
||||
"defaultBranchSubtitle": "Использовать заданную базовую ветку репозитория",
|
||||
"editPreset": "Изменить {{name}}",
|
||||
"fullCheckout": "Полная выгрузка",
|
||||
"fullCheckoutSubtitle": "Использовать весь репозиторий",
|
||||
"newPreset": "Новый набор настроек",
|
||||
"noBranches": "Подходящих веток нет.",
|
||||
"searchBranches": "Поиск веток",
|
||||
"sparseCheckoutTitle": "Выборочная выгрузка"
|
||||
},
|
||||
"workspaceSshGate": {
|
||||
"authenticationFailed": "Ошибка аутентификации",
|
||||
"connected": "Подключён",
|
||||
"connecting": "Подключение",
|
||||
"connectionFailed": "Не удалось подключиться",
|
||||
"deployingRelay": "Развёртывание ретранслятора",
|
||||
"disconnected": "Отключён",
|
||||
"reconnectFailed": "Не удалось подключиться повторно",
|
||||
"reconnecting": "Повторное подключение"
|
||||
},
|
||||
"workspaceTrustDrawers": {
|
||||
"alwaysTrustAndRun": "Всегда доверять и запускать",
|
||||
"creating": "Создание…",
|
||||
"directoriesLabel": "Каталоги",
|
||||
"directories_few": "{{count}} каталога",
|
||||
"directories_many": "{{count}} каталогов",
|
||||
"directories_one": "{{count}} каталог",
|
||||
"directories_other": "{{count}} каталога",
|
||||
"dontRun": "Не выполнять",
|
||||
"editSparsePreset": "Изменить набор выборочной выгрузки",
|
||||
"nameLabel": "Название",
|
||||
"namePlaceholder": "Интерфейс рендерера",
|
||||
"newSetupScript": "Новый скрипт настройки",
|
||||
"newSparsePreset": "Новый набор выборочной выгрузки",
|
||||
"runHooks": "Выполнить хуки",
|
||||
"runSetupAndCreate": "Выполнить настройку и создать",
|
||||
"runSetupTitle": "Запустить настройку из {{name}}?",
|
||||
"setupChangedTitle": "Скрипт настройки {{name}} изменился",
|
||||
"setupScript": "Скрипт настройки",
|
||||
"setupSubtitle": "Перед созданием рабочего пространства для {{name}} выберите, запускать ли скрипт настройки.",
|
||||
"setupTitle": "Запустить скрипт настройки?",
|
||||
"skipSetupAndCreate": "Пропустить настройку и создать",
|
||||
"trustFailed": "Не удалось добавить скрипт настройки в доверенные.",
|
||||
"trustSubtitle": "Скрипт из orca.yaml этого репозитория выполняется на вашем компьютере перед запуском рабочего пространства. Запускайте его, только если доверяете этому репозиторию."
|
||||
},
|
||||
"worktreeCreateRetry": {
|
||||
"createFailed": "Не удалось создать рабочее пространство"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
+871
-34
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+853
-16
@@ -13,7 +13,7 @@
|
||||
"sessionWindow": "5小时",
|
||||
"switchFailed": "无法切换账户",
|
||||
"title": "账户",
|
||||
"useReset": "使用重置机会",
|
||||
"useReset": "使用重置额度",
|
||||
"weeklyWindow": "7天"
|
||||
}
|
||||
},
|
||||
@@ -168,7 +168,7 @@
|
||||
},
|
||||
"chat": {
|
||||
"ask": {
|
||||
"answerPlaceholder": "输入你的回答",
|
||||
"answerPlaceholder": "输入您的回答",
|
||||
"next": "下一步",
|
||||
"other": "其他…",
|
||||
"skip": "跳过",
|
||||
@@ -281,7 +281,7 @@
|
||||
"stoppedManually": "已手动停止"
|
||||
},
|
||||
"orcaStop": {
|
||||
"canContinue": "你可以在此对话中继续。",
|
||||
"canContinue": "您可以在此对话中继续。",
|
||||
"crash": "此回复进行期间,{{machine}} 上的 Orca 意外停止。",
|
||||
"quit": "此回复进行期间,{{machine}} 上的 Orca 已关闭。",
|
||||
"remote": "此回复进行期间,{{machine}} 上的 Orca 已停止。",
|
||||
@@ -834,7 +834,7 @@
|
||||
"loadFailed": "发生错误。",
|
||||
"loading": "正在加载 PR…",
|
||||
"notPermitted": "无权访问:您的 GitHub 账户尚未连接。",
|
||||
"retryLoading": "重新加载 PR"
|
||||
"retryLoading": "重试加载 PR"
|
||||
},
|
||||
"protocolBlockScreen": {
|
||||
"backToHosts": "返回主机列表",
|
||||
@@ -1491,7 +1491,21 @@
|
||||
"workspace": "工作区"
|
||||
}
|
||||
},
|
||||
"newWorkspace": {
|
||||
"hostPicker": {
|
||||
"title": "选择创建工作区的主机"
|
||||
},
|
||||
"loadingDrawer": {
|
||||
"downloadProgress": "正在下载… {{progress}}",
|
||||
"downloading": "正在下载",
|
||||
"loading": "加载中"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"desktopChannel": {
|
||||
"name": "桌面通知",
|
||||
"silentName": "Orca 静默通知"
|
||||
},
|
||||
"notificationDeliverySection": {
|
||||
"footer": "提醒类型遵循各个已配对桌面的通知设置。连续 7 天未使用此应用后,通知将暂停;打开应用并重新连接即可恢复。",
|
||||
"onlyWhenAway": "仅在离开桌面时",
|
||||
@@ -1545,7 +1559,7 @@
|
||||
"openOnWeb": "在网页上打开 {{name}}",
|
||||
"passed": "{{count}} 项通过",
|
||||
"pending": "待处理",
|
||||
"pendingCount": "{{count}} 项待完成",
|
||||
"pendingCount": "{{count}} 项待处理",
|
||||
"queued": "已加入队列",
|
||||
"rerunFailing": "重新运行失败的检查",
|
||||
"skipped": "已跳过",
|
||||
@@ -1948,14 +1962,14 @@
|
||||
"unstaged": "未暂存"
|
||||
},
|
||||
"fileReader": {
|
||||
"copyReviewNotes": "复制评论注释",
|
||||
"copyReviewNotes": "复制评审备注",
|
||||
"imageLabel": "{{title}} 图片",
|
||||
"noReviewNotes": "暂无评论注释",
|
||||
"noReviewNotes": "暂无评审备注",
|
||||
"previewLabel": "{{title}} 预览",
|
||||
"reviewNotes_one": "{{count}} 条评论注释",
|
||||
"reviewNotes_other": "{{count}} 条评论注释",
|
||||
"reviewNotes_one": "{{count}} 条评审备注",
|
||||
"reviewNotes_other": "{{count}} 条评审备注",
|
||||
"send": "发送",
|
||||
"sendReviewNotes": "将评论注释发送给 AI"
|
||||
"sendReviewNotes": "将评审备注发送给 AI"
|
||||
},
|
||||
"floatingWorkspace": {
|
||||
"title": "浮动工作区"
|
||||
@@ -2169,7 +2183,7 @@
|
||||
"notesHint": "选择接收当前注释的智能体会话。",
|
||||
"removeShortcutMessage": "移除此自定义快捷键?",
|
||||
"renameTerminal": "重命名终端",
|
||||
"sendReviewNotes": "发送评论注释",
|
||||
"sendReviewNotes": "发送评审备注",
|
||||
"shortcut": "快捷键",
|
||||
"terminal": "终端",
|
||||
"terminalName": "终端名称",
|
||||
@@ -2293,7 +2307,7 @@
|
||||
"notesCopied": "评审笔记已复制",
|
||||
"notesSent": "评审笔记已发送",
|
||||
"notesSentWithWarning": "评审笔记已发送。{{warning}}",
|
||||
"promptNotSent": "智能体已启动,但笔记未发送。请使用“复制笔记”复制后粘贴。",
|
||||
"promptNotSent": "智能体已启动,但笔记未发送。请使用“复制备注”复制后粘贴。",
|
||||
"sendFailed": "发送笔记失败",
|
||||
"startingAgent": "正在启动智能体…",
|
||||
"waitingForDesktop": "等待桌面连接…"
|
||||
@@ -2344,7 +2358,7 @@
|
||||
"updateFailed": "更新标题失败。"
|
||||
},
|
||||
"useQuickCommands": {
|
||||
"loadFailed": "加载快速命令失败",
|
||||
"loadFailed": "加载快捷命令失败",
|
||||
"saveFailed": "保存快速命令失败"
|
||||
},
|
||||
"useSessionTerminalSendActions": {
|
||||
@@ -2520,11 +2534,67 @@
|
||||
}
|
||||
},
|
||||
"sourceControl": {
|
||||
"actionSheetRunners": {
|
||||
"noBaseBranch": "没有可作为变基目标的基础分支",
|
||||
"waitingForDesktop": "正在等待桌面…"
|
||||
},
|
||||
"actions": {
|
||||
"checkingReviewStatus": "正在检查评审状态。",
|
||||
"checkoutBeforePublish": "请先检出分支再发布提交。",
|
||||
"commitStagedChanges": "提交已暂存的更改。",
|
||||
"commits": "提交",
|
||||
"committing": "正在提交。",
|
||||
"createPr": "创建PR",
|
||||
"enterCommitMessage": "请输入提交信息后再提交。",
|
||||
"forcePushWithLease": "使用 lease 强制推送以更新远程分支。",
|
||||
"forcePushing": "正在强制推送。",
|
||||
"linkedReviewUnavailable": "关联的评审分支不可用。",
|
||||
"publishToOrigin": "将此分支发布到 origin。",
|
||||
"pullCommits_one": "拉取 {{count}} 个提交。",
|
||||
"pullCommits_other": "拉取 {{count}} 个提交。",
|
||||
"pushAndCreatePr": "推送并创建 PR",
|
||||
"switchBranch": "切换分支"
|
||||
"pushCommits_one": "推送 {{count}} 个提交。",
|
||||
"pushCommits_other": "推送 {{count}} 个提交。",
|
||||
"pushLinkedReview": "将更新推送到关联的评审分支。",
|
||||
"remoteOperationInProgress": "正在执行远程操作。",
|
||||
"resolveConflicts": "请先解决冲突再提交。",
|
||||
"reviewAlreadyMerged": "没有可提交的内容。评审已合并。",
|
||||
"stageAllChanges": "暂存全部更改。",
|
||||
"stageFileToCommit": "请至少暂存一个文件后再提交。",
|
||||
"switchBranch": "切换分支",
|
||||
"syncCounts": "拉取 {{behind}} 个提交,推送 {{ahead}} 个提交。",
|
||||
"upToDate": "没有可提交的内容。分支已是最新状态。",
|
||||
"waitForRemoteOperation": "请在远程操作完成后重试。"
|
||||
},
|
||||
"branchBaseRef": {
|
||||
"resolveFailed": "无法解析基础分支"
|
||||
},
|
||||
"branchCard": {
|
||||
"branchCount": "已提交 {{count}} 个文件",
|
||||
"changedCount": "已更改 {{count}} 个文件",
|
||||
"cherryPickState": "cherry-pick",
|
||||
"mergeState": "合并",
|
||||
"rebaseState": "变基",
|
||||
"stagedCount": "已暂存 {{count}} 个文件"
|
||||
},
|
||||
"branchCompare": {
|
||||
"commits_one": "{{count}} 次提交",
|
||||
"commits_other": "{{count}} 次提交",
|
||||
"files_one": "{{count}} 个文件",
|
||||
"files_other": "{{count}} 个文件",
|
||||
"sectionTitle": "已提交的更改",
|
||||
"summary": "{{files}} - 与 {{baseRef}} 比较",
|
||||
"summaryWithCommits": "{{files}} - {{commits}} - 与 {{baseRef}} 比较"
|
||||
},
|
||||
"branchCompareOutcome": {
|
||||
"baseBranchUnavailable": "无法解析用于比较的基础分支。",
|
||||
"loadFailed": "无法加载已提交的更改"
|
||||
},
|
||||
"branchDiffPreviewDrawer": {
|
||||
"closePreview": "关闭已提交更改的差异预览",
|
||||
"committedOnBranch": "已提交到分支",
|
||||
"loadFailed": "无法加载差异",
|
||||
"truncated": "移动端预览中的差异已截断。"
|
||||
},
|
||||
"commitDropdown": {
|
||||
"checkOutBranchToPush": "请先检出分支再推送提交",
|
||||
@@ -2549,8 +2619,49 @@
|
||||
"stageFile": "暂存至少一个要提交的文件",
|
||||
"useCommitAndForcePush": "使用提交并强制推送 — 远程只有本地提交的旧副本"
|
||||
},
|
||||
"commitFailurePanel": {
|
||||
"fix": "修复",
|
||||
"fixWithAi": "使用 AI 修复提交失败",
|
||||
"hideDetails": "隐藏详情",
|
||||
"hideFailureDetails": "隐藏提交失败详情",
|
||||
"showDetails": "显示详情",
|
||||
"showFailureDetails": "显示提交失败详情",
|
||||
"summary": "提交失败。",
|
||||
"title": "提交失败"
|
||||
},
|
||||
"commitMessageAi": {
|
||||
"generateFailed": "生成提交信息失败"
|
||||
},
|
||||
"commitRunners": {
|
||||
"actionFailed": "源代码控制操作失败",
|
||||
"commitFailed": "提交失败"
|
||||
},
|
||||
"conflictAbort": {
|
||||
"abortMerge": "中止合并",
|
||||
"abortOperation": "中止 {{operation}}",
|
||||
"abortRebase": "中止变基",
|
||||
"aborting": "正在中止…"
|
||||
},
|
||||
"content": {
|
||||
"cancelGeneration": "取消生成提交信息",
|
||||
"commitMessageDisabled": "提交信息输入已禁用。没有已暂存的文件。",
|
||||
"commitMessagePlaceholder": "提交信息",
|
||||
"emptyMessage": "工作树无更改。",
|
||||
"emptyTitle": "无本地更改",
|
||||
"generateMessage": "使用 AI 生成提交信息",
|
||||
"noStagedFiles": "没有已暂存的文件",
|
||||
"openActions": "打开源代码控制操作菜单",
|
||||
"reconnecting": "正在重新连接桌面…",
|
||||
"regenerateHint": "清除消息以重新生成。",
|
||||
"stageAll": "暂存全部",
|
||||
"unstageAll": "取消全部暂存"
|
||||
},
|
||||
"createPrAction": {
|
||||
"createReview": "创建 {{titleLabel}}"
|
||||
"checkingStatus": "正在检查评审状态…",
|
||||
"createPullRequest": "创建PR",
|
||||
"createReview": "创建 {{titleLabel}}",
|
||||
"providerUnavailable": "此提供商无法创建评审",
|
||||
"statusUnavailable": "评审状态不可用"
|
||||
},
|
||||
"dropdownCounts": {
|
||||
"fastForwardCount_one": "快进 {{count}} 个提交",
|
||||
@@ -2572,6 +2683,64 @@
|
||||
"titleUnpublishedForcePushCount_one": "使用 lease 强制推送 {{count}} 个分支提交,并在需要时设置上游。",
|
||||
"titleUnpublishedForcePushCount_other": "使用 lease 强制推送 {{count}} 个分支提交,并在需要时设置上游。"
|
||||
},
|
||||
"fileList": {
|
||||
"committedSection": "已提交的更改"
|
||||
},
|
||||
"fileRows": {
|
||||
"addedByThem": "对方已添加",
|
||||
"addedByUs": "我方已添加",
|
||||
"bothAdded": "双方均已添加",
|
||||
"bothDeleted": "双方均已删除",
|
||||
"bothModified": "双方均已修改",
|
||||
"committedSection": "已提交的更改",
|
||||
"committedUnavailable": "已提交的更改不可用。",
|
||||
"deletedByThem": "对方已删除",
|
||||
"deletedByUs": "我方已删除",
|
||||
"discardFile": "放弃 {{path}} 的更改",
|
||||
"loadingCommitted": "正在加载已提交的更改…",
|
||||
"openChangedFile": "打开已更改的文件 {{path}}",
|
||||
"openCommittedChange": "打开 {{path}} 中已提交的更改",
|
||||
"renamedFrom": "原路径 {{path}}",
|
||||
"stageFile": "暂存 {{path}}",
|
||||
"unresolvedConflict": "未解决的冲突",
|
||||
"unstageFile": "取消暂存 {{path}}"
|
||||
},
|
||||
"gitHistory": {
|
||||
"days_one": "{{count}} 天",
|
||||
"days_other": "{{count}} 天",
|
||||
"hours_one": "{{count}} 小时",
|
||||
"hours_other": "{{count}} 小时",
|
||||
"justNow": "刚刚",
|
||||
"loadFailed": "加载提交历史失败",
|
||||
"minutes_one": "{{count}} 分钟",
|
||||
"minutes_other": "{{count}} 分钟",
|
||||
"months_one": "{{count}} 个月",
|
||||
"months_other": "{{count}} 个月",
|
||||
"noCommitMessage": "(无提交信息)",
|
||||
"years_one": "{{count}} 年",
|
||||
"years_other": "{{count}} 年"
|
||||
},
|
||||
"gitHistoryList": {
|
||||
"loadFailed": "加载历史记录失败",
|
||||
"loadFilesFailed": "无法加载提交文件",
|
||||
"noCommits": "暂无提交。",
|
||||
"noFileChanges": "无文件更改",
|
||||
"retryFiles": "重试加载提交文件",
|
||||
"waitingForDesktop": "正在等待桌面…"
|
||||
},
|
||||
"gitStatus": {
|
||||
"changes": "更改",
|
||||
"conflicts": "冲突",
|
||||
"stagedChanges": "已暂存的更改"
|
||||
},
|
||||
"header": {
|
||||
"backToSession": "返回会话",
|
||||
"close": "关闭源代码控制",
|
||||
"openNumberedPrWeb": "在网页上打开 PR #{{number}}",
|
||||
"openPrWeb": "在网页上打开 PR",
|
||||
"refresh": "刷新源代码控制",
|
||||
"title": "源代码控制"
|
||||
},
|
||||
"hostedReview": {
|
||||
"mrCopy": {
|
||||
"reviewLabel": "合并请求",
|
||||
@@ -2584,9 +2753,81 @@
|
||||
"titleLabel": "PR"
|
||||
}
|
||||
},
|
||||
"hostedReviewCopy": {
|
||||
"committingChanges": "正在提交更改…",
|
||||
"creatingReview": "正在创建评审…",
|
||||
"forcePushing": "正在使用 lease 强制推送…",
|
||||
"generatingCommitMessage": "正在生成提交信息…",
|
||||
"publishingBranch": "正在发布分支…",
|
||||
"pushingCommits": "正在推送提交…",
|
||||
"stagingChanges": "正在暂存更改…",
|
||||
"updatingBranch": "正在更新分支…"
|
||||
},
|
||||
"hostedReviewCreate": {
|
||||
"pushSucceeded": "推送成功,但创建 {{shortLabel}} 失败:{{error}}"
|
||||
},
|
||||
"hostedReviewCreateIntent": {
|
||||
"branchChanged": "准备创建 PR 时分支发生了变化。",
|
||||
"generateMessageFailed": "无法生成提交信息。请在“源代码控制”中填写后重试。",
|
||||
"resolveConflicts": "请先解决冲突,再创建 PR。",
|
||||
"resolveOrStageChanges": "请先处理或暂存更改,再创建 PR。",
|
||||
"reviewCommitMessage": "请先检查提交信息,然后重试创建 PR。"
|
||||
},
|
||||
"hostedReviewGitPreparation": {
|
||||
"commitFailed": "提交失败",
|
||||
"refreshFailed": "无法刷新源代码控制",
|
||||
"stageFailed": "暂存更改失败",
|
||||
"updateBranchFailed": "无法更新远程分支。请重试创建 PR。"
|
||||
},
|
||||
"hostedReviewRemotePrerequisite": {
|
||||
"forcePushFailed": "使用 lease 强制推送失败",
|
||||
"publishFailed": "发布分支失败",
|
||||
"pushFailed": "推送提交失败"
|
||||
},
|
||||
"hostedReviewService": {
|
||||
"createFailed": "创建 PR 失败",
|
||||
"pushBeforeCreateFailed": "推送失败。请解决推送错误后重试。"
|
||||
},
|
||||
"hubTab": {
|
||||
"changes": "更改",
|
||||
"commits": "提交",
|
||||
"pullRequest": "PR"
|
||||
},
|
||||
"loaders": {
|
||||
"connectingToDesktop": "正在连接桌面…",
|
||||
"loadFailed": "无法加载源代码控制",
|
||||
"updateDesktop": "请更新 Orca 桌面端,以在手机上使用源代码控制。",
|
||||
"waitingForDesktop": "正在等待桌面…"
|
||||
},
|
||||
"modals": {
|
||||
"actionsTitle": "源代码控制",
|
||||
"currentBranch": "当前",
|
||||
"discardButton": "放弃",
|
||||
"discardConfirmMessage": "放弃对“{{path}}”的更改?此操作无法撤销。",
|
||||
"discardTitle": "放弃更改",
|
||||
"openPrMessage": "在浏览器中打开?",
|
||||
"openPrWithWarning": "在浏览器中打开?\n\n{{warning}}",
|
||||
"prCreatedTitle": "PR 已创建",
|
||||
"switchBranchTitle": "切换分支"
|
||||
},
|
||||
"openers": {
|
||||
"openDiffFailed": "无法打开差异",
|
||||
"tabNotReady": "文件已打开,但标签页尚未就绪。请重试。",
|
||||
"waitingForDesktop": "正在等待桌面…"
|
||||
},
|
||||
"panel": {
|
||||
"loadFailedTitle": "无法加载",
|
||||
"unavailableTitle": "源代码控制不可用"
|
||||
},
|
||||
"prChip": {
|
||||
"createPr": "创建 PR",
|
||||
"loading": "正在加载 PR…",
|
||||
"loadingLabel": "正在加载 PR",
|
||||
"openLabel": "PR #{{number}},{{state}},{{checks}}。打开 PR。",
|
||||
"openWithComments_one": "PR #{{number}},{{state}},{{checks}},{{count}} 条未解决的评论。打开 PR。",
|
||||
"openWithComments_other": "PR #{{number}},{{state}},{{checks}},{{count}} 条未解决的评论。打开 PR。",
|
||||
"unavailableLabel": "PR 不可用:{{message}}"
|
||||
},
|
||||
"prCreate": {
|
||||
"authRequired": "请在创建 {{reviewLabel}} 之前完成身份验证。",
|
||||
"baseNotOnRemote": "请先推送基础分支,再创建 {{reviewLabel}}。",
|
||||
@@ -2605,8 +2846,19 @@
|
||||
"unsupportedMergeRequests": "此仓库不支持创建合并请求。",
|
||||
"unsupportedPullRequests": "此仓库不支持创建 PR。"
|
||||
},
|
||||
"prLink": {
|
||||
"updatePullRequestFailed": "更新关联的 PR 失败",
|
||||
"updateReviewFailed": "更新关联的评审失败"
|
||||
},
|
||||
"primaryAction": {
|
||||
"forcePushFromDesktop": "从桌面强制推送此 PR 的分支"
|
||||
"commit": "提交",
|
||||
"forcePush": "强制推送",
|
||||
"forcePushFromDesktop": "从桌面强制推送此 PR 的分支",
|
||||
"publishBranch": "发布分支",
|
||||
"pull": "拉",
|
||||
"push": "推",
|
||||
"stageAll": "暂存全部",
|
||||
"sync": "同步"
|
||||
},
|
||||
"remoteDropdown": {
|
||||
"branchAlreadyPublished": "分支已发布",
|
||||
@@ -2656,6 +2908,591 @@
|
||||
"tryFastForwardPull": "尝试快进拉取;git 可能会拒绝本地提交",
|
||||
"tryRegularPush": "尝试常规推送;git 可能要求强制推送",
|
||||
"useForcePushToSync": "请使用强制推送——远程只有本地提交的旧副本"
|
||||
},
|
||||
"runners": {
|
||||
"actionFailed": "源代码控制操作失败"
|
||||
},
|
||||
"screenState": {
|
||||
"noBranch": "无分支"
|
||||
},
|
||||
"state": {
|
||||
"noUpstream": "无上游分支",
|
||||
"syncStatus": "领先 {{ahead}},落后 {{behind}}"
|
||||
},
|
||||
"useMobileCommitFailureRecovery": {
|
||||
"launchFailed": "启动智能体失败",
|
||||
"waitingForDesktop": "正在等待桌面…"
|
||||
},
|
||||
"useMobileCommitMessageGeneration": {
|
||||
"generateFailed": "生成提交信息失败"
|
||||
},
|
||||
"useMobileCreatePrRunner": {
|
||||
"branchRequired": "创建 PR 前,请先检出分支。"
|
||||
},
|
||||
"useMobileGitRequests": {
|
||||
"actionFailed": "源代码控制操作失败",
|
||||
"branchUnavailable": "无法获取分支状态",
|
||||
"commitFailed": "提交失败",
|
||||
"waitingForDesktop": "正在等待桌面…"
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"composerSource": {
|
||||
"baseFailed": "无法解析基础分支。",
|
||||
"forkPushWarning": "此 PR 未开启“允许维护者编辑”;向 fork 仓库推送可能会被 GitHub 拒绝。"
|
||||
},
|
||||
"detailCommentRenderers": {
|
||||
"commentPlaceholder": "添加评论",
|
||||
"comments_one": "{{count}} 条评论",
|
||||
"comments_other": "{{count}} 条评论",
|
||||
"reopenThread": "重新打开讨论串",
|
||||
"reply": "回复",
|
||||
"resolveThread": "解决讨论串",
|
||||
"resolvedCommentBy": "{{author}} 的评论(已解决)",
|
||||
"resolvedThreadBy": "{{author}} 的讨论串(已解决)",
|
||||
"sendComment": "发送评论",
|
||||
"show": "显示"
|
||||
},
|
||||
"filterPickers": {
|
||||
"allTeams": "所有团队",
|
||||
"changeStatus": "更改状态",
|
||||
"fieldHidden": "不在卡片上显示",
|
||||
"fieldShown": "在卡片上显示",
|
||||
"fieldsSubtitle": "选择要在条目卡片上显示的项目字段。",
|
||||
"fieldsTitle": "项目字段",
|
||||
"gitlabFilter": "GitLab 筛选",
|
||||
"gitlabView": "GitLab 视图",
|
||||
"jiraFilter": "Jira 筛选",
|
||||
"jiraSite": "Jira 站点",
|
||||
"linearFilter": "Linear 筛选",
|
||||
"linearIssue": "Linear 议题",
|
||||
"linearWorkspace": "Linear 工作区",
|
||||
"loadingStates": "正在加载状态…",
|
||||
"noFields": "此视图没有可显示的额外字段。",
|
||||
"noStates": "无可用状态",
|
||||
"switchWorkspaceFailed": "切换工作区失败",
|
||||
"teamsSubtitle": "选择要在“任务”中显示的团队。",
|
||||
"teamsTitle": "Linear 团队",
|
||||
"teams_one": "{{count}} 个团队",
|
||||
"teams_other": "{{count}} 个团队"
|
||||
},
|
||||
"githubProjectList": {
|
||||
"browseProjects": "浏览项目",
|
||||
"chooseProject": "选择 GitHub 项目",
|
||||
"emptyField": "空的",
|
||||
"issueSubtitle": "议题 · {{repository}}{{number}}",
|
||||
"itemSubtitle": "项目条目 · {{repository}}{{number}}",
|
||||
"items": "条目",
|
||||
"moreFields_one": "+{{count}} 个字段",
|
||||
"moreFields_other": "+{{count}} 个字段",
|
||||
"noItems": "没有项目条目",
|
||||
"pullRequestSubtitle": "PR · {{repository}}{{number}}"
|
||||
},
|
||||
"githubProjectPickers": {
|
||||
"add": "添加",
|
||||
"addByUrlHint": "使用“通过 URL 添加”来访问未列出的项目。",
|
||||
"addPlaceholder": "通过 URL 或 owner/number 添加",
|
||||
"adding": "添加中…",
|
||||
"browseAll": "浏览全部",
|
||||
"browseLoading": "浏览全部(加载中…)",
|
||||
"chooseView": "选择项目视图",
|
||||
"loadFailed": "无法加载项目",
|
||||
"noMatches": "没有匹配的项目。",
|
||||
"noMoreProjects": "没有更多项目。",
|
||||
"noProjects": "尚未加载任何项目",
|
||||
"organizationsError": "组织:{{message}}",
|
||||
"organizationsLoadFailed": "{{count}} 个组织未能加载。",
|
||||
"ownerLoadFailed": "无法加载 {{owner}} 的项目。",
|
||||
"pin": "固定",
|
||||
"pinned": "已固定",
|
||||
"recent": "最近的",
|
||||
"retryHint": "点按重试。",
|
||||
"searchProjects": "搜索项目",
|
||||
"sort": "项目排序",
|
||||
"subtitle": "为“任务”页面选择项目视图。",
|
||||
"title": "GitHub 项目",
|
||||
"unsupportedLayout": "Orca 暂不支持此 GitHub 项目布局。",
|
||||
"view": "项目视图"
|
||||
},
|
||||
"githubViewControls": {
|
||||
"fields": "字段:{{fields}}",
|
||||
"openView": "在 GitHub 中打开视图",
|
||||
"sort": "排序:{{sort}}",
|
||||
"source": "来源:{{source}}"
|
||||
},
|
||||
"itemActions": {
|
||||
"changeStatus": "更改状态",
|
||||
"copyGitHubLink": "复制 GitHub 链接",
|
||||
"copyLinearLink": "复制 Linear 链接",
|
||||
"createWorkspace": "创建工作区",
|
||||
"creating": "创建中…",
|
||||
"mergeConflicts": "GitHub 报告存在合并冲突。",
|
||||
"mergeMergeRequest": "合并合并请求",
|
||||
"mergePullRequest": "合并 PR"
|
||||
},
|
||||
"itemDetailContent": {
|
||||
"addSubIssue": "添加子议题",
|
||||
"assignee": "负责人",
|
||||
"assignees": "负责人",
|
||||
"checks": "检查项",
|
||||
"description": "描述",
|
||||
"discussion": "讨论",
|
||||
"noChecks": "未找到检查项。",
|
||||
"noComments": "暂无评论。",
|
||||
"noPipelineRuns": "此 MR 没有运行任何管道。",
|
||||
"noSubIssues": "没有子议题。",
|
||||
"none": "没有任何",
|
||||
"pipeline": "管道",
|
||||
"pipelineJobs_one": "{{count}} 个作业",
|
||||
"pipelineJobs_other": "{{count}} 个作业",
|
||||
"project": "项目",
|
||||
"rerunAll": "重新运行全部",
|
||||
"rerunFailed": "重新运行失败项",
|
||||
"status": "状态",
|
||||
"subIssueTitle": "子议题标题",
|
||||
"subIssues": "子议题",
|
||||
"type": "类型"
|
||||
},
|
||||
"itemDetailDrawer": {
|
||||
"refreshDetails": "刷新详情"
|
||||
},
|
||||
"itemFieldEditors": {
|
||||
"addLabels": "添加标签,以英文逗号分隔",
|
||||
"addUsernames": "添加用户名,以英文逗号分隔",
|
||||
"assignees": "负责人",
|
||||
"labels": "标签",
|
||||
"loadingAssignees": "正在加载负责人…",
|
||||
"loadingLabels": "正在加载标签…",
|
||||
"noAssignableUsers": "未找到此仓库中可指派的用户。",
|
||||
"noLabels": "此仓库没有标签。",
|
||||
"none": "没有任何",
|
||||
"removeLabels": "移除标签,以英文逗号分隔",
|
||||
"removeUsernames": "移除用户名,以英文逗号分隔",
|
||||
"saveTitle": "保存标题",
|
||||
"title": "标题",
|
||||
"updateAssignees": "更新负责人",
|
||||
"updateLabels": "更新标签"
|
||||
},
|
||||
"itemReviewSections": {
|
||||
"binaryFile": "二进制文件。",
|
||||
"changedFilesTitle": "已更改文件",
|
||||
"descriptionPlaceholder": "描述",
|
||||
"fileContentsUnavailable": "文件内容不可用。",
|
||||
"hideFile": "隐藏",
|
||||
"loadingReviewers": "正在加载评审人…",
|
||||
"markUnviewed": "标记未查看",
|
||||
"markViewed": "标记已查看",
|
||||
"noDescription": "没有描述。",
|
||||
"noReviewerSuggestions": "未找到推荐的评审人。",
|
||||
"noReviewersRequested": "未请求评审人",
|
||||
"requestReview": "请求评审",
|
||||
"reviewersPlaceholder": "邀请评审人",
|
||||
"reviewersTitle": "评审人",
|
||||
"saveDescription": "保存描述",
|
||||
"viewFile": "查看"
|
||||
},
|
||||
"legacySurface": {
|
||||
"loadIssuesFailed": "无法从 {{source}} 加载议题。",
|
||||
"mergeAction": "合并",
|
||||
"mergeMethodTitle": "合并方式",
|
||||
"mergePullRequestTitle": "合并 PR",
|
||||
"mergeRequestMergeMessage": "请选择此合并请求的合并方式。",
|
||||
"mergeRequestTitle": "合并请求",
|
||||
"pullRequestMergeMessage": "请选择此 PR 的合并方式。",
|
||||
"retryLoadingIssues": "重试从 {{source}} 加载议题",
|
||||
"retrying": "正在重试…",
|
||||
"sourceFallback": "{{repo}} 的首选议题来源 upstream 不可用,已改用 origin。",
|
||||
"subIssueDataUnavailable": "您的token无法获取子议题数据。",
|
||||
"updateItemTitle": "更新条目"
|
||||
},
|
||||
"linearList": {
|
||||
"changeStatusFrom": "更改状态,当前为 {{status}}"
|
||||
},
|
||||
"linearViewControls": {
|
||||
"displayButton": "显示",
|
||||
"groupLabel": "分组:{{group}}",
|
||||
"orderLabel": "排序:{{order}}"
|
||||
},
|
||||
"listDisplayPickers": {
|
||||
"displayPropertiesTitle": "显示属性",
|
||||
"linearGroupTitle": "Linear 议题分组",
|
||||
"linearOrderTitle": "Linear 议题排序",
|
||||
"linearViewTitle": "Linear 视图",
|
||||
"sortTasksTitle": "任务排序"
|
||||
},
|
||||
"listSurface": {
|
||||
"connectLinearButton": "连接 Linear",
|
||||
"connectLinearMessage": "直接在“任务”中浏览并开始处理分配给您的 Linear 议题。",
|
||||
"connectLinearTitle": "连接您的 Linear 账户",
|
||||
"jiraStatusFailed": "读取 Jira 状态失败",
|
||||
"updateDesktopMessage": "此移动端“任务”视图需要更高版本的桌面端运行时。",
|
||||
"updateDesktopTitle": "更新 Orca 桌面端"
|
||||
},
|
||||
"options": {
|
||||
"all": "全部",
|
||||
"assignedToMe": "分配给我",
|
||||
"assignee": "负责人",
|
||||
"board": "看板",
|
||||
"boardDescription": "按组分列显示",
|
||||
"closedState": "已关闭",
|
||||
"completedState": "已完成",
|
||||
"createdState": "我创建的",
|
||||
"githubAssignedIssuesDescription": "分配给您的开放议题",
|
||||
"githubDescription": "议题和 PR",
|
||||
"githubIssuesDescription": "GitHub 议题",
|
||||
"githubOpenIssuesDescription": "开放的 GitHub 议题",
|
||||
"githubProjectsDescription": "GitHub 项目视图",
|
||||
"githubPullRequestsDescription": "GitHub PR",
|
||||
"gitlabAllDescription": "所有 GitLab 状态",
|
||||
"gitlabClosedDescription": "已关闭的议题和合并请求",
|
||||
"gitlabDescription": "议题和合并请求",
|
||||
"gitlabMergedDescription": "已合并的合并请求",
|
||||
"gitlabOpenDescription": "开放的议题和合并请求",
|
||||
"identifier": "标识符",
|
||||
"issues": "议题",
|
||||
"jiraDescription": "分配给您及由您报告的议题",
|
||||
"labels": "标签",
|
||||
"linearAllDescription": "所有已连接工作区中的开放议题",
|
||||
"linearAssignedDescription": "分配给您的议题",
|
||||
"linearCompletedDescription": "最近完成的议题",
|
||||
"linearCreatedDescription": "您创建的议题",
|
||||
"linearDescription": "分配给您的议题和团队议题",
|
||||
"list": "列表",
|
||||
"listDescription": "以紧凑行显示议题",
|
||||
"mergedState": "已合并",
|
||||
"mine": "我的",
|
||||
"myIssues": "我的议题",
|
||||
"myPullRequestsDescription": "您创建的 PR",
|
||||
"myTodos": "我的待办事项",
|
||||
"myTodosDescription": "待处理的 GitLab 待办事项",
|
||||
"needsReview": "待评审",
|
||||
"noGrouping": "没有分组",
|
||||
"openPullRequestsDescription": "开放的 PR",
|
||||
"openState": "开放",
|
||||
"priority": "优先级",
|
||||
"projectMergeRequests": "项目 MR",
|
||||
"projectMergeRequestsDescription": "按仓库查看合并请求和议题",
|
||||
"projects": "项目",
|
||||
"pullRequests": "PR",
|
||||
"repository": "仓库",
|
||||
"repositorySortDescription": "按仓库分组,组内最新活动优先",
|
||||
"reviewRequestsDescription": "分配给您的评审请求",
|
||||
"status": "状态",
|
||||
"team": "团队",
|
||||
"updated": "已更新",
|
||||
"updatedSortDescription": "最新活动优先"
|
||||
},
|
||||
"pickerProjection": {
|
||||
"allRepos": "所有仓库",
|
||||
"allSites": "所有站点",
|
||||
"currentlyAscending": "当前升序 · 点按切换为降序",
|
||||
"currentlyDescending": "当前降序 · 点按切换为升序",
|
||||
"fieldAscending": "{{field}} 升序",
|
||||
"fieldDescending": "{{field}} 降序",
|
||||
"fields": "字段",
|
||||
"repos_one": "{{count}} 个仓库",
|
||||
"repos_other": "{{count}} 个仓库",
|
||||
"selectTarget": "选择目标",
|
||||
"selectedFields": "{{selected}}/{{total}} 个字段",
|
||||
"sortAscending": "升序排列",
|
||||
"sources_one": "{{count}} 个来源",
|
||||
"sources_other": "{{count}} 个来源",
|
||||
"unsupportedLayout": "移动端不支持此布局",
|
||||
"updatedSort": "已更新",
|
||||
"usesFieldAscending": "按 {{field}} 升序排列",
|
||||
"usesFieldDescending": "按 {{field}} 降序排列",
|
||||
"usesGitHubRankOrder": "采用 GitHub 排列顺序",
|
||||
"viewNumber": "视图 #{{number}}",
|
||||
"viewOrder": "视图顺序"
|
||||
},
|
||||
"prFileDiff": {
|
||||
"commentOnLine": "在第 {{line}} 行添加评论",
|
||||
"commentPlaceholder": "添加评审评论",
|
||||
"noTextChanges": "未发现文本更改。",
|
||||
"showingDiffLines": "显示前 {{limit}} 行差异,共 {{total}} 行。"
|
||||
},
|
||||
"projectComments": {
|
||||
"comments_one": "{{count}} 条评论",
|
||||
"comments_other": "{{count}} 条评论",
|
||||
"discussion": "讨论",
|
||||
"editComment": "编辑评论",
|
||||
"noComments": "暂无评论。",
|
||||
"reopenThread": "重新打开讨论串",
|
||||
"reply": "回复",
|
||||
"resolveThread": "解决讨论串",
|
||||
"resolvedCommentBy": "{{author}} 的评论(已解决)",
|
||||
"resolvedThreadBy": "{{author}} 发起的讨论串(已解决)",
|
||||
"show": "显示"
|
||||
},
|
||||
"projectDetailDrawer": {
|
||||
"addRepositoryFromDesktop": "{{repository}} 尚未添加到 Orca。请在桌面应用中添加此仓库,然后刷新移动端的“任务”。",
|
||||
"clearType": "清除类型",
|
||||
"closeItem": "关闭条目",
|
||||
"copyGitHubLink": "复制 GitHub 链接",
|
||||
"copyRepository": "复制仓库名",
|
||||
"createWorkspace": "创建工作区",
|
||||
"draftIssue": "草稿议题",
|
||||
"issue": "议题",
|
||||
"issueType": "议题类型",
|
||||
"loadingIssueTypes": "正在加载议题类型…",
|
||||
"mergePullRequest": "合并 PR",
|
||||
"mergeRepositoryRequirement": "合并前需在 Orca 中添加此仓库。",
|
||||
"noIssueTypes": "此仓库未配置议题类型。",
|
||||
"noType": "无类型",
|
||||
"openInGitHub": "在 GitHub 中打开",
|
||||
"projectItem": "项目条目",
|
||||
"projectSubtitle": "GitHub 项目 · {{repository}}{{itemNumber}}",
|
||||
"pullRequest": "PR",
|
||||
"reopenItem": "重新打开条目",
|
||||
"repositoryNotInOrca": "仓库不在 Orca 中",
|
||||
"status": "状态",
|
||||
"type": "类型",
|
||||
"workspaceCreationRequirement": "只能从 GitHub 议题和 PR 创建工作区。"
|
||||
},
|
||||
"projectFieldEditors": {
|
||||
"clearField": "清空字段",
|
||||
"completedIteration": "已完成 · {{startDate}} · {{duration}} 天",
|
||||
"datePlaceholder": "YYYY-MM-DD",
|
||||
"invalidDate": "请按 YYYY-MM-DD 格式输入日期。",
|
||||
"invalidNumber": "请输入有效数字。",
|
||||
"noIterations": "暂无可用迭代。",
|
||||
"numberPlaceholder": "数字",
|
||||
"projectFields": "项目字段",
|
||||
"saveField": "保存字段",
|
||||
"textPlaceholder": "文本",
|
||||
"upcomingIteration": "当前及即将开始 · {{startDate}} · {{duration}} 天"
|
||||
},
|
||||
"projectMetadataEditors": {
|
||||
"assignees": "负责人",
|
||||
"description": "描述",
|
||||
"labels": "标签",
|
||||
"loadingAssignees": "正在加载负责人…",
|
||||
"loadingLabels": "正在加载标签…",
|
||||
"noAssignableUsers": "未找到此仓库中可设为负责人的用户。",
|
||||
"noDescription": "没有描述。",
|
||||
"noLabels": "此仓库中没有标签。",
|
||||
"none": "无",
|
||||
"saveDescription": "保存描述",
|
||||
"saveTitle": "保存标题",
|
||||
"title": "标题"
|
||||
},
|
||||
"projectReviewPanels": {
|
||||
"binaryFile": "二进制文件。",
|
||||
"changedFiles": "已更改文件",
|
||||
"checks": "检查项",
|
||||
"fileUnavailable": "文件内容不可用。",
|
||||
"hideFile": "隐藏",
|
||||
"loadingReviewers": "正在加载评审人…",
|
||||
"markUnviewed": "标记未查看",
|
||||
"markViewed": "标记已查看",
|
||||
"noChecks": "未找到检查项。",
|
||||
"noReviewers": "未请求评审人",
|
||||
"noSuggestions": "未找到推荐的评审人。",
|
||||
"requestReview": "请求评审",
|
||||
"requestReviewers": "邀请评审人",
|
||||
"rerunAll": "全部重新运行",
|
||||
"rerunFailed": "重新运行失败项",
|
||||
"reviewers": "评审人",
|
||||
"viewFile": "查看"
|
||||
},
|
||||
"providerControls": {
|
||||
"myTodos": "我的待办",
|
||||
"projectMergeRequests": "项目 MR",
|
||||
"sort": "排序:{{sortLabel}}"
|
||||
},
|
||||
"providerItemList": {
|
||||
"intoBranch": "合并到 {{base}}",
|
||||
"nextPage": "前往下一页",
|
||||
"page": "第 {{page}} 页",
|
||||
"pageOfTotal": "第 {{page}} 页,共 {{total}} 页",
|
||||
"previousPage": "前往上一页",
|
||||
"selectPage": "选择页码,当前第 {{page}} 页",
|
||||
"selectPageOfTotal": "选择页码,当前第 {{page}} 页,共 {{total}} 页"
|
||||
},
|
||||
"providerPickers": {
|
||||
"allRepositories": "所有仓库",
|
||||
"githubView": "GitHub 视图",
|
||||
"issueSources": "GitHub 议题来源",
|
||||
"issueSourcesDescription": "选择每个仓库从 upstream 还是 origin 查询和创建工作项。",
|
||||
"issues": "议题",
|
||||
"noIssueSources": "没有其他可用的议题来源。",
|
||||
"origin": "origin",
|
||||
"pageHint": "跳转到已加载或可用的结果页。",
|
||||
"pageLoaded": "已加载",
|
||||
"pageNotLoaded": "加载更早的结果",
|
||||
"pageNumber": "第 {{page}} 页",
|
||||
"pages": "GitHub 结果页",
|
||||
"pullRequests": "PR",
|
||||
"queryingSource": "正在查询 {{source}}",
|
||||
"repoDescription": "选择要查询的仓库。",
|
||||
"repos": "仓库",
|
||||
"taskSource": "任务来源",
|
||||
"upstream": "上游"
|
||||
},
|
||||
"providerViewProjection": {
|
||||
"all": "全部",
|
||||
"allSites": "所有站点",
|
||||
"allTeams": "所有团队",
|
||||
"allWorkspaces": "所有工作区",
|
||||
"chooseProject": "选择项目",
|
||||
"default": "默认",
|
||||
"defaultSubtitle": "{{subtitle}} · 默认",
|
||||
"issues": "议题",
|
||||
"list": "列表",
|
||||
"noGrouping": "没有分组",
|
||||
"openState": "开放",
|
||||
"priority": "优先级",
|
||||
"projects": "项目",
|
||||
"pullRequests": "PR",
|
||||
"teams_one": "{{count}} 个团队",
|
||||
"teams_other": "{{count}} 个团队",
|
||||
"workspace": "工作区"
|
||||
},
|
||||
"reviewerLinear": {
|
||||
"issues": "议题",
|
||||
"unassigned": "未分配"
|
||||
},
|
||||
"screenChrome": {
|
||||
"connectLinear": "连接 Linear",
|
||||
"newGitHubIssue": "新的 GitHub 议题",
|
||||
"newLinearIssue": "新建 Linear 议题",
|
||||
"refreshGitHub": "刷新 GitHub 工作",
|
||||
"refreshGitLab": "刷新 GitLab 工作项",
|
||||
"refreshJira": "刷新 Jira 议题",
|
||||
"refreshLinear": "刷新 Linear",
|
||||
"title": "任务"
|
||||
},
|
||||
"searchControl": {
|
||||
"jiraPlaceholder": "Jira JQL,例如 project = ABC AND statusCategory != Done",
|
||||
"projectPlaceholder": "搜索项目视图…",
|
||||
"providerPlaceholder": "搜索 {{provider}} 任务…"
|
||||
},
|
||||
"smartSourceModes": {
|
||||
"allStates": "全部",
|
||||
"branch": "分支",
|
||||
"closedState": "已关闭",
|
||||
"mergedState": "已合并",
|
||||
"name": "名称",
|
||||
"openState": "开放",
|
||||
"smart": "智能"
|
||||
},
|
||||
"sparsePresetDraft": {
|
||||
"directoryRequired": "添加至少一个目录。",
|
||||
"repoRelativeDirectoriesRequired": "使用仓库相对目录,而不是根目录、绝对路径或父段。"
|
||||
},
|
||||
"taskViewOptions": {
|
||||
"allSubtitle": "所选站点中未解决的议题",
|
||||
"assignedSubtitle": "分配给您的未解决议题",
|
||||
"doneSubtitle": "分配给您且最近已解决的议题",
|
||||
"noGitHubTasks": "暂无 GitHub 任务",
|
||||
"noGitLabTasks": "暂无 GitLab 任务",
|
||||
"noJiraTasks": "暂无 Jira 任务",
|
||||
"noLinearTasks": "暂无 Linear 任务",
|
||||
"reportedSubtitle": "您报告的未解决议题"
|
||||
},
|
||||
"tasksCreateDrawers": {
|
||||
"connect": "连接",
|
||||
"connectLinearWorkspace": "连接 Linear 工作区",
|
||||
"createIssue": "创建议题",
|
||||
"createWorkspaceIn": "选择创建工作区的仓库",
|
||||
"description": "描述",
|
||||
"descriptionPlaceholder": "补充背景信息",
|
||||
"fileIn": "在 {{slug}} 中创建议题",
|
||||
"issueSource": "议题来源",
|
||||
"keySecurityHint": "密钥通过主机操作系统的钥匙串加密,并存储在本地。",
|
||||
"linearConnectSubtitle": "粘贴个人 API 密钥,即可浏览该工作区的议题。",
|
||||
"linearSettingsLink": "Linear 设置 / 安全 / 新建 API 密钥",
|
||||
"linearTeam": "Linear 团队",
|
||||
"linearTeamSubtitle": "在所选 Linear 团队中创建议题。",
|
||||
"newIssueTitle": "新建 {{providerLabel}} 议题",
|
||||
"origin": "origin",
|
||||
"personalApiKey": "个人API密钥",
|
||||
"repository": "仓库",
|
||||
"repositorySubtitle": "在所选仓库中创建议题。",
|
||||
"team": "团队",
|
||||
"title": "标题",
|
||||
"titlePlaceholder": "任务标题",
|
||||
"upstream": "上游"
|
||||
},
|
||||
"workspaceAgentSelection": {
|
||||
"blankTerminal": "空白终端"
|
||||
},
|
||||
"workspaceCreateDrawer": {
|
||||
"addRepository": "创建 Linear 工作区前,请先添加 Git 仓库。",
|
||||
"advanced": "高级",
|
||||
"agent": "智能体",
|
||||
"connect": "连接",
|
||||
"connectFirst": "请先连接仓库",
|
||||
"connectRepository": "连接仓库",
|
||||
"connecting": "连接中…",
|
||||
"createFrom": "基于 {{branch}} 创建",
|
||||
"defaultBranch": "默认分支",
|
||||
"detectingAgents": "正在检测智能体…",
|
||||
"optional": "[可选]",
|
||||
"remoteRepository": "远程仓库",
|
||||
"repository": "仓库",
|
||||
"repositoryNotFound": "未找到仓库。",
|
||||
"selectRepository": "选择仓库",
|
||||
"sshConnection": "SSH 连接",
|
||||
"startFrom": "创建起点",
|
||||
"title": "创建工作区",
|
||||
"workspaceName": "工作区名称"
|
||||
},
|
||||
"workspaceCreateProjection": {
|
||||
"nameAlreadyExists": "“{{name}}”已存在。",
|
||||
"nameRequired": "请输入名称。",
|
||||
"nameTooLong": "名称不能超过80个字符。",
|
||||
"openShell": "打开 shell"
|
||||
},
|
||||
"workspaceOptionPickers": {
|
||||
"baseBranchSubtitle": "选择现有分支或引用。",
|
||||
"baseBranchTitle": "创建起点",
|
||||
"branchName": "分支名称:{{name}}",
|
||||
"defaultBranch": "默认分支",
|
||||
"defaultBranchSubtitle": "使用此仓库配置的基础分支",
|
||||
"editPreset": "编辑 {{name}}",
|
||||
"fullCheckout": "完整检出",
|
||||
"fullCheckoutSubtitle": "使用整个仓库",
|
||||
"newPreset": "新预设",
|
||||
"noBranches": "没有匹配的分支。",
|
||||
"searchBranches": "搜索分支",
|
||||
"sparseCheckoutTitle": "稀疏检出"
|
||||
},
|
||||
"workspaceSshGate": {
|
||||
"authenticationFailed": "身份验证失败",
|
||||
"connected": "已连接",
|
||||
"connecting": "连接中",
|
||||
"connectionFailed": "连接失败",
|
||||
"deployingRelay": "正在部署中继",
|
||||
"disconnected": "已断开连接",
|
||||
"reconnectFailed": "重新连接失败",
|
||||
"reconnecting": "重新连接中"
|
||||
},
|
||||
"workspaceTrustDrawers": {
|
||||
"alwaysTrustAndRun": "始终信任并运行",
|
||||
"creating": "创建中…",
|
||||
"directoriesLabel": "目录",
|
||||
"directories_one": "{{count}} 个目录",
|
||||
"directories_other": "{{count}} 个目录",
|
||||
"dontRun": "不运行",
|
||||
"editSparsePreset": "编辑稀疏检出预设",
|
||||
"nameLabel": "名称",
|
||||
"namePlaceholder": "渲染器界面",
|
||||
"newSetupScript": "新设置脚本",
|
||||
"newSparsePreset": "新建稀疏检出预设",
|
||||
"runHooks": "运行钩子",
|
||||
"runSetupAndCreate": "运行设置脚本并创建",
|
||||
"runSetupTitle": "运行 {{name}} 的设置脚本?",
|
||||
"setupChangedTitle": "{{name}} 的设置脚本已更改",
|
||||
"setupScript": "设置脚本",
|
||||
"setupSubtitle": "创建此工作区前,请选择是否运行 {{name}} 的设置脚本。",
|
||||
"setupTitle": "运行设置脚本?",
|
||||
"skipSetupAndCreate": "跳过设置脚本并创建",
|
||||
"trustFailed": "无法将设置脚本设为可信。",
|
||||
"trustSubtitle": "工作区启动前,此仓库的 orca.yaml 会在您的电脑上运行。请仅在信任此仓库时运行。"
|
||||
},
|
||||
"worktreeCreateRetry": {
|
||||
"createFailed": "创建工作区失败"
|
||||
}
|
||||
},
|
||||
"terminal": {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useRouter } from 'expo-router'
|
||||
import { PickerModal } from '../components/PickerModal'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { hostPickerOptions } from '../components/use-connected-host-picker'
|
||||
import { selectConnectableHostProfiles } from '../transport/host-catalog-selection'
|
||||
import { loadHostCatalog } from '../transport/host-store'
|
||||
@@ -14,6 +15,7 @@ export function NewWorkspaceHostPicker({
|
||||
hostIds: readonly string[]
|
||||
onPick: (hostId: string) => void
|
||||
}) {
|
||||
const t = useMobileTranslation()
|
||||
const router = useRouter()
|
||||
const hosts = useOfferedHosts(hostIds)
|
||||
const [open, setOpen] = useState(true)
|
||||
@@ -27,7 +29,7 @@ export function NewWorkspaceHostPicker({
|
||||
}, [nothingToPick, router])
|
||||
return (
|
||||
<PickerModal
|
||||
title="Create Workspace On"
|
||||
title={t('newWorkspace.hostPicker.title', 'Create Workspace On')}
|
||||
visible={hosts !== null && !nothingToPick && open}
|
||||
options={hostPickerOptions(hosts ?? [])}
|
||||
selected=""
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from 'react-native'
|
||||
import { BOTTOM_DRAWER_SHOW_DURATION_MS } from '../components/bottom-drawer-constants'
|
||||
import { bottomDrawerStyles } from '../components/bottom-drawer-styles'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { useResponsiveLayout } from '../layout/responsive-layout'
|
||||
import { useWindowSafeAreaInsets } from '../layout/side-safe-area'
|
||||
import {
|
||||
@@ -36,6 +37,7 @@ export function NewWorkspaceLoadingDrawer({
|
||||
download: ShellOverlayDownload | null
|
||||
onCancel: () => void
|
||||
}) {
|
||||
const t = useMobileTranslation()
|
||||
useMobileColorScheme()
|
||||
const insets = useWindowSafeAreaInsets()
|
||||
const { isWideLayout, modalMaxWidth } = useResponsiveLayout()
|
||||
@@ -85,7 +87,7 @@ export function NewWorkspaceLoadingDrawer({
|
||||
<Pressable
|
||||
style={bottomDrawerStyles.backdropPressable}
|
||||
onPress={onCancel}
|
||||
accessibilityLabel="Cancel"
|
||||
accessibilityLabel={t('common.cancel', 'Cancel')}
|
||||
/>
|
||||
</Animated.View>
|
||||
<View
|
||||
@@ -113,7 +115,10 @@ export function NewWorkspaceLoadingDrawer({
|
||||
</View>
|
||||
<View style={styles.body}>
|
||||
{download === null ? (
|
||||
<ActivityIndicator color={colors.textSecondary} accessibilityLabel="Loading" />
|
||||
<ActivityIndicator
|
||||
color={colors.textSecondary}
|
||||
accessibilityLabel={t('newWorkspace.loadingDrawer.loading', 'Loading')}
|
||||
/>
|
||||
) : (
|
||||
<DownloadProgress download={download} />
|
||||
)}
|
||||
@@ -125,6 +130,7 @@ export function NewWorkspaceLoadingDrawer({
|
||||
}
|
||||
|
||||
function DownloadProgress({ download }: { download: ShellOverlayDownload }) {
|
||||
const t = useMobileTranslation()
|
||||
useMobileColorScheme()
|
||||
return (
|
||||
<>
|
||||
@@ -132,10 +138,12 @@ function DownloadProgress({ download }: { download: ShellOverlayDownload }) {
|
||||
feed={download.feed}
|
||||
receivedBytes={download.receivedBytes}
|
||||
totalBytes={download.totalBytes}
|
||||
accessibilityLabel="Downloading"
|
||||
accessibilityLabel={t('newWorkspace.loadingDrawer.downloading', 'Downloading')}
|
||||
/>
|
||||
<Text style={styles.caption}>
|
||||
Downloading… {downloadedMegabytesCaption(download.receivedBytes, download.totalBytes)}
|
||||
{t('newWorkspace.loadingDrawer.downloadProgress', 'Downloading… {{progress}}', {
|
||||
progress: downloadedMegabytesCaption(download.receivedBytes, download.totalBytes)
|
||||
})}
|
||||
</Text>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
import * as Notifications from 'expo-notifications'
|
||||
import { Platform } from 'react-native'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
// Create the shared FCM channel before socket subscription: a background push can arrive first, and Android drops notifications for missing channels.
|
||||
export const DESKTOP_NOTIFICATION_CHANNEL_ID = 'orca-desktop'
|
||||
|
||||
// Android updates existing channels; other platforms do nothing.
|
||||
// Android updates existing channels, so calling again after a language change renames them; other platforms do nothing.
|
||||
export async function ensureDesktopNotificationChannel(): Promise<void> {
|
||||
if (Platform.OS !== 'android') {
|
||||
return
|
||||
}
|
||||
await Notifications.setNotificationChannelAsync(`${DESKTOP_NOTIFICATION_CHANNEL_ID}-silent`, {
|
||||
name: 'Orca silent notifications',
|
||||
name: translate('notifications.desktopChannel.silentName', 'Orca silent notifications'),
|
||||
importance: Notifications.AndroidImportance.HIGH,
|
||||
sound: null,
|
||||
enableVibrate: false
|
||||
})
|
||||
await Notifications.setNotificationChannelAsync(DESKTOP_NOTIFICATION_CHANNEL_ID, {
|
||||
name: 'Desktop Notifications',
|
||||
name: translate('notifications.desktopChannel.name', 'Desktop Notifications'),
|
||||
importance: Notifications.AndroidImportance.HIGH,
|
||||
vibrationPattern: [0, 250],
|
||||
lightColor: '#6366f1'
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ActivityIndicator, Pressable, Text, View } from 'react-native'
|
||||
import { X } from 'lucide-react-native'
|
||||
import { colors } from '../theme/mobile-theme'
|
||||
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { BottomDrawer } from '../components/BottomDrawer'
|
||||
import { MobileSyntaxSegments } from '../components/MobileSyntaxSegments'
|
||||
import { mobileDiffLineNumber, mobileDiffLinePrefix } from './mobile-diff-format'
|
||||
@@ -15,6 +16,7 @@ type Props = {
|
||||
|
||||
export function MobileBranchDiffPreviewDrawer({ branchDiffPreview, onClose }: Props) {
|
||||
useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
if (!branchDiffPreview) {
|
||||
return null
|
||||
}
|
||||
@@ -34,14 +36,17 @@ export function MobileBranchDiffPreviewDrawer({ branchDiffPreview, onClose }: Pr
|
||||
<Text style={styles.diffDrawerMeta} numberOfLines={1}>
|
||||
{branchDiffPreview.kind === 'ready'
|
||||
? `${branchDiffPreview.summary.baseRef}..HEAD`
|
||||
: 'Committed on branch'}
|
||||
: t('sourceControl.branchDiffPreviewDrawer.committedOnBranch', 'Committed on branch')}
|
||||
</Text>
|
||||
</View>
|
||||
<Pressable
|
||||
style={({ pressed }) => [styles.diffCloseButton, pressed && styles.iconButtonPressed]}
|
||||
onPress={onClose}
|
||||
hitSlop={8}
|
||||
accessibilityLabel="Close committed diff preview"
|
||||
accessibilityLabel={t(
|
||||
'sourceControl.branchDiffPreviewDrawer.closePreview',
|
||||
'Close committed diff preview'
|
||||
)}
|
||||
>
|
||||
<X size={18} color={colors.textSecondary} strokeWidth={2.1} />
|
||||
</Pressable>
|
||||
@@ -52,13 +57,20 @@ export function MobileBranchDiffPreviewDrawer({ branchDiffPreview, onClose }: Pr
|
||||
</View>
|
||||
) : branchDiffPreview.kind === 'error' ? (
|
||||
<View style={styles.diffState}>
|
||||
<Text style={styles.stateTitle}>Unable to Load Diff</Text>
|
||||
<Text style={styles.stateTitle}>
|
||||
{t('sourceControl.branchDiffPreviewDrawer.loadFailed', 'Unable to Load Diff')}
|
||||
</Text>
|
||||
<Text style={styles.stateText}>{branchDiffPreview.message}</Text>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.diffLines}>
|
||||
{branchDiffPreview.truncated ? (
|
||||
<Text style={styles.diffTruncatedText}>Diff truncated for mobile preview.</Text>
|
||||
<Text style={styles.diffTruncatedText}>
|
||||
{t(
|
||||
'sourceControl.branchDiffPreviewDrawer.truncated',
|
||||
'Diff truncated for mobile preview.'
|
||||
)}
|
||||
</Text>
|
||||
) : null}
|
||||
{branchDiffPreview.lines.map((line, index) => (
|
||||
<View
|
||||
|
||||
@@ -3,6 +3,7 @@ import { ActivityIndicator, Pressable, Text, View } from 'react-native'
|
||||
import { ChevronDown, ChevronRight, Sparkles } from 'lucide-react-native'
|
||||
import { colors } from '../theme/mobile-theme'
|
||||
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { AgentLaunchNotice } from '../components/AgentLaunchNotice'
|
||||
import type { MobileCommitFailureRecovery } from './mobile-commit-failure-recovery'
|
||||
import type { MobileCommitFailureRecoveryAction } from './use-mobile-commit-failure-recovery'
|
||||
@@ -15,6 +16,7 @@ type Props = {
|
||||
|
||||
export function MobileCommitFailurePanel({ failure, action }: Props) {
|
||||
useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
const [expanded, setExpanded] = useState(false)
|
||||
const Chevron = expanded ? ChevronDown : ChevronRight
|
||||
const detailsText = failure.error.trim()
|
||||
@@ -23,9 +25,11 @@ export function MobileCommitFailurePanel({ failure, action }: Props) {
|
||||
<View style={styles.commitFailurePanel}>
|
||||
<View style={styles.commitFailureHeader}>
|
||||
<View style={styles.commitFailureTextBlock}>
|
||||
<Text style={styles.commitFailureTitle}>Commit failed</Text>
|
||||
<Text style={styles.commitFailureTitle}>
|
||||
{t('sourceControl.commitFailurePanel.title', 'Commit failed')}
|
||||
</Text>
|
||||
<Text style={styles.commitFailureSummary} numberOfLines={2}>
|
||||
{action.summary ?? 'Commit failed.'}
|
||||
{action.summary ?? t('sourceControl.commitFailurePanel.summary', 'Commit failed.')}
|
||||
</Text>
|
||||
</View>
|
||||
<Pressable
|
||||
@@ -38,14 +42,19 @@ export function MobileCommitFailurePanel({ failure, action }: Props) {
|
||||
onPress={() => void action.launch()}
|
||||
disabled={action.launching || action.availability !== 'available'}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Fix commit failure with AI"
|
||||
accessibilityLabel={t(
|
||||
'sourceControl.commitFailurePanel.fixWithAi',
|
||||
'Fix commit failure with AI'
|
||||
)}
|
||||
>
|
||||
{action.launching ? (
|
||||
<ActivityIndicator color={colors.bgBase} />
|
||||
) : (
|
||||
<Sparkles size={14} color={colors.bgBase} strokeWidth={2.2} />
|
||||
)}
|
||||
<Text style={styles.commitFailureFixButtonText}>Fix</Text>
|
||||
<Text style={styles.commitFailureFixButtonText}>
|
||||
{t('sourceControl.commitFailurePanel.fix', 'Fix')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
{action.hasDetails && detailsText ? (
|
||||
@@ -58,12 +67,22 @@ export function MobileCommitFailurePanel({ failure, action }: Props) {
|
||||
onPress={() => setExpanded((current) => !current)}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={
|
||||
expanded ? 'Hide commit failure details' : 'Show commit failure details'
|
||||
expanded
|
||||
? t(
|
||||
'sourceControl.commitFailurePanel.hideFailureDetails',
|
||||
'Hide commit failure details'
|
||||
)
|
||||
: t(
|
||||
'sourceControl.commitFailurePanel.showFailureDetails',
|
||||
'Show commit failure details'
|
||||
)
|
||||
}
|
||||
>
|
||||
<Chevron size={14} color={colors.textSecondary} strokeWidth={2.2} />
|
||||
<Text style={styles.commitFailureDetailsButtonText}>
|
||||
{expanded ? 'Hide details' : 'Show details'}
|
||||
{expanded
|
||||
? t('sourceControl.commitFailurePanel.hideDetails', 'Hide details')
|
||||
: t('sourceControl.commitFailurePanel.showDetails', 'Show details')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
{expanded ? <Text style={styles.commitFailureDetailsText}>{detailsText}</Text> : null}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { memo, useCallback, useEffect, useState } from 'react'
|
||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { ActivityIndicator, FlatList, Pressable, Text, View } from 'react-native'
|
||||
import { ChevronDown, ChevronRight } from 'lucide-react-native'
|
||||
import { colors, radii, spacing, typography } from '../theme/mobile-theme'
|
||||
import { themedStyleSheet } from '../theme/themed-styles'
|
||||
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import type { ConnectionState } from '../transport/types'
|
||||
import type { RpcClient } from '../transport/rpc-client'
|
||||
import { useForceReconnect } from '../transport/host-client-hooks'
|
||||
@@ -16,6 +18,7 @@ import {
|
||||
type MobileCommitRow
|
||||
} from './mobile-git-history'
|
||||
import { resolveMobileHistoryScreenView } from './mobile-history-screen-state'
|
||||
import type { MobileGitHistoryResult } from './git-history-reply-schema'
|
||||
|
||||
type CommitFilesState = {
|
||||
files?: MobileGitChangedFile[]
|
||||
@@ -42,8 +45,14 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({
|
||||
refreshNonce = 0
|
||||
}: Props) {
|
||||
const colorScheme = useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
const forceReconnect = useForceReconnect()
|
||||
const [rows, setRows] = useState<MobileCommitRow[] | null>(null)
|
||||
// Keep the fetched page, not formatted rows, so relative times follow a language switch.
|
||||
const [rows, setRows] = useState<{ result: MobileGitHistoryResult; nowMs: number } | null>(null)
|
||||
const commitRows = useMemo(
|
||||
() => (rows ? mapMobileCommitRows(rows.result, rows.nowMs) : null),
|
||||
[rows, t]
|
||||
)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [reloadNonce, setReloadNonce] = useState(0)
|
||||
const [expanded, setExpanded] = useState<string | null>(null)
|
||||
@@ -70,11 +79,15 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({
|
||||
try {
|
||||
const result = await fetchMobileGitHistory(client, worktreeId)
|
||||
if (active) {
|
||||
setRows(mapMobileCommitRows(result, Date.now()))
|
||||
setRows({ result, nowMs: Date.now() })
|
||||
}
|
||||
} catch (err) {
|
||||
if (active) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to load history')
|
||||
setError(
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate('sourceControl.gitHistoryList.loadFailed', 'Failed to load history')
|
||||
)
|
||||
}
|
||||
}
|
||||
})()
|
||||
@@ -124,7 +137,13 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({
|
||||
...prev,
|
||||
[commitId]: {
|
||||
files: prev[commitId]?.files,
|
||||
error: err instanceof Error ? err.message : 'Unable to load commit files'
|
||||
error:
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate(
|
||||
'sourceControl.gitHistoryList.loadFilesFailed',
|
||||
'Unable to load commit files'
|
||||
)
|
||||
}
|
||||
}))
|
||||
}
|
||||
@@ -169,7 +188,10 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({
|
||||
{connected || retryAction ? (
|
||||
<Pressable
|
||||
style={styles.retryButton}
|
||||
accessibilityLabel="Retry commit files"
|
||||
accessibilityLabel={t(
|
||||
'sourceControl.gitHistoryList.retryFiles',
|
||||
'Retry commit files'
|
||||
)}
|
||||
onPress={() => {
|
||||
if (connState !== 'connected') {
|
||||
retryAction?.()
|
||||
@@ -178,7 +200,7 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text style={styles.retryText}>Retry</Text>
|
||||
<Text style={styles.retryText}>{t('common.retry', 'Retry')}</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
</View>
|
||||
@@ -187,12 +209,16 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({
|
||||
connected ? (
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
) : (
|
||||
<Text style={styles.empty}>Waiting for desktop...</Text>
|
||||
<Text style={styles.empty}>
|
||||
{t('sourceControl.gitHistoryList.waitingForDesktop', 'Waiting for desktop...')}
|
||||
</Text>
|
||||
)
|
||||
) : null}
|
||||
{files !== undefined ? (
|
||||
files.length === 0 ? (
|
||||
<Text style={styles.empty}>No file changes</Text>
|
||||
<Text style={styles.empty}>
|
||||
{t('sourceControl.gitHistoryList.noFileChanges', 'No file changes')}
|
||||
</Text>
|
||||
) : (
|
||||
files.map((file) => (
|
||||
<View key={file.path} style={styles.fileRow}>
|
||||
@@ -212,20 +238,26 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({
|
||||
</View>
|
||||
)
|
||||
},
|
||||
[colorScheme, connected, connState, expanded, filesById, retryAction, toggleCommit]
|
||||
[colorScheme, connected, connState, expanded, filesById, retryAction, toggleCommit, t]
|
||||
)
|
||||
|
||||
const view = resolveMobileHistoryScreenView({ connected, rows, error })
|
||||
const view = resolveMobileHistoryScreenView({ connected, rows: commitRows, error })
|
||||
|
||||
if (view.kind === 'error' || view.kind === 'waiting') {
|
||||
return (
|
||||
<View style={styles.state}>
|
||||
<Text style={styles.stateText}>
|
||||
{view.kind === 'waiting' ? 'Waiting for desktop...' : view.message}
|
||||
{view.kind === 'waiting'
|
||||
? t('sourceControl.gitHistoryList.waitingForDesktop', 'Waiting for desktop...')
|
||||
: view.message}
|
||||
</Text>
|
||||
{retry ? (
|
||||
<Pressable style={styles.retryButton} onPress={retry} accessibilityLabel="Retry">
|
||||
<Text style={styles.retryText}>Retry</Text>
|
||||
<Pressable
|
||||
style={styles.retryButton}
|
||||
onPress={retry}
|
||||
accessibilityLabel={t('common.retry', 'Retry')}
|
||||
>
|
||||
<Text style={styles.retryText}>{t('common.retry', 'Retry')}</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
</View>
|
||||
@@ -241,7 +273,9 @@ export const MobileGitHistoryList = memo(function MobileGitHistoryList({
|
||||
if (view.kind === 'empty') {
|
||||
return (
|
||||
<View style={styles.state}>
|
||||
<Text style={styles.stateText}>No commits.</Text>
|
||||
<Text style={styles.stateText}>
|
||||
{t('sourceControl.gitHistoryList.noCommits', 'No commits.')}
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Pressable, Text, View } from 'react-native'
|
||||
import { GitBranch } from 'lucide-react-native'
|
||||
import { colors } from '../theme/mobile-theme'
|
||||
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { styles } from './mobile-source-control-styles'
|
||||
import { MobileSourceControlPrChip } from './MobileSourceControlPrChip'
|
||||
import type { MobilePrChipSummary } from './mobile-pr-chip-summary'
|
||||
@@ -35,7 +36,16 @@ export function MobileSourceControlBranchCard({
|
||||
onOpenPr
|
||||
}: Props) {
|
||||
useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
const showConflict = conflictOperation !== null && conflictOperation !== 'unknown'
|
||||
const conflictLabel =
|
||||
conflictOperation === 'merge'
|
||||
? t('sourceControl.branchCard.mergeState', 'merge')
|
||||
: conflictOperation === 'rebase'
|
||||
? t('sourceControl.branchCard.rebaseState', 'rebase')
|
||||
: conflictOperation === 'cherry-pick'
|
||||
? t('sourceControl.branchCard.cherryPickState', 'cherry-pick')
|
||||
: conflictOperation
|
||||
return (
|
||||
<View style={styles.summaryCard}>
|
||||
<View style={styles.summaryHeader}>
|
||||
@@ -48,14 +58,26 @@ export function MobileSourceControlBranchCard({
|
||||
{syncLabel ? <Text style={styles.syncText}>{syncLabel}</Text> : null}
|
||||
</View>
|
||||
<View style={styles.countRow}>
|
||||
<Text style={styles.countText}>{unstagedCount} changed</Text>
|
||||
<Text style={styles.countText}>{stagedCount} staged</Text>
|
||||
{branchCount > 0 ? <Text style={styles.countText}>{branchCount} on branch</Text> : null}
|
||||
<Text style={styles.countText}>
|
||||
{t('sourceControl.branchCard.changedCount', '{{count}} changed', {
|
||||
count: unstagedCount
|
||||
})}
|
||||
</Text>
|
||||
<Text style={styles.countText}>
|
||||
{t('sourceControl.branchCard.stagedCount', '{{count}} staged', { count: stagedCount })}
|
||||
</Text>
|
||||
{branchCount > 0 ? (
|
||||
<Text style={styles.countText}>
|
||||
{t('sourceControl.branchCard.branchCount', '{{count}} on branch', {
|
||||
count: branchCount
|
||||
})}
|
||||
</Text>
|
||||
) : null}
|
||||
</View>
|
||||
{/* Keep Abort on its own row so long counts cannot overflow the card. */}
|
||||
{showConflict ? (
|
||||
<View style={styles.conflictRow}>
|
||||
<Text style={styles.conflictText}>{conflictOperation}</Text>
|
||||
<Text style={styles.conflictText}>{conflictLabel}</Text>
|
||||
{conflictOperation === 'merge' || conflictOperation === 'rebase' ? (
|
||||
<Pressable
|
||||
style={({ pressed }) => [
|
||||
|
||||
@@ -3,6 +3,7 @@ import { ActivityIndicator, Pressable, Text, TextInput, View } from 'react-nativ
|
||||
import { Minus, MoreHorizontal, Plus, Sparkles } from 'lucide-react-native'
|
||||
import { colors, spacing } from '../theme/mobile-theme'
|
||||
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { MobileSourceControlCreatePrEntry } from './MobileSourceControlCreatePrEntry'
|
||||
import { MobileCommitFailurePanel } from './MobileCommitFailurePanel'
|
||||
import { KEYBOARD_COMMIT_BAR_CLEARANCE } from './mobile-source-control-screen-state'
|
||||
@@ -20,6 +21,7 @@ type Props = {
|
||||
|
||||
export function MobileSourceControlContent({ state, primaryAction }: Props) {
|
||||
useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
const {
|
||||
insets,
|
||||
connState,
|
||||
@@ -102,7 +104,9 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) {
|
||||
// Retained rows look actionable offline; show reconnect state beside them.
|
||||
<View style={styles.reconnectBanner}>
|
||||
<ActivityIndicator size="small" color={colors.statusAmber} />
|
||||
<Text style={styles.reconnectBannerText}>Reconnecting to desktop...</Text>
|
||||
<Text style={styles.reconnectBannerText}>
|
||||
{t('sourceControl.content.reconnecting', 'Reconnecting to desktop...')}
|
||||
</Text>
|
||||
</View>
|
||||
) : null}
|
||||
<View style={hubStyles.changesControls}>
|
||||
@@ -134,7 +138,9 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) {
|
||||
) : (
|
||||
<Plus size={15} color={colors.textPrimary} strokeWidth={2.2} />
|
||||
)}
|
||||
<Text style={styles.bulkButtonText}>Stage All</Text>
|
||||
<Text style={styles.bulkButtonText}>
|
||||
{t('sourceControl.content.stageAll', 'Stage All')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={({ pressed }) => [
|
||||
@@ -150,7 +156,9 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) {
|
||||
) : (
|
||||
<Minus size={15} color={colors.textPrimary} strokeWidth={2.2} />
|
||||
)}
|
||||
<Text style={styles.bulkButtonText}>Unstage All</Text>
|
||||
<Text style={styles.bulkButtonText}>
|
||||
{t('sourceControl.content.unstageAll', 'Unstage All')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={({ pressed }) => [
|
||||
@@ -161,7 +169,10 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) {
|
||||
onPress={() => setShowActionSheet(true)}
|
||||
disabled={ioBusy}
|
||||
hitSlop={8}
|
||||
accessibilityLabel="Open source control actions"
|
||||
accessibilityLabel={t(
|
||||
'sourceControl.content.openActions',
|
||||
'Open source control actions'
|
||||
)}
|
||||
>
|
||||
<MoreHorizontal size={18} color={colors.textPrimary} strokeWidth={2.1} />
|
||||
</Pressable>
|
||||
@@ -170,8 +181,12 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) {
|
||||
|
||||
{!hasVisibleChanges ? (
|
||||
<View style={styles.state}>
|
||||
<Text style={styles.stateTitle}>No local changes</Text>
|
||||
<Text style={styles.stateText}>Working tree is clean.</Text>
|
||||
<Text style={styles.stateTitle}>
|
||||
{t('sourceControl.content.emptyTitle', 'No local changes')}
|
||||
</Text>
|
||||
<Text style={styles.stateText}>
|
||||
{t('sourceControl.content.emptyMessage', 'Working tree is clean.')}
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
fileList
|
||||
@@ -192,16 +207,21 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) {
|
||||
style={[styles.commitInput, styles.commitInputDisabled]}
|
||||
accessibilityRole="text"
|
||||
accessibilityState={{ disabled: true }}
|
||||
accessibilityLabel="Commit message disabled. No staged files."
|
||||
accessibilityLabel={t(
|
||||
'sourceControl.content.commitMessageDisabled',
|
||||
'Commit message disabled. No staged files.'
|
||||
)}
|
||||
>
|
||||
<Text style={styles.commitInputDisabledText}>No staged files</Text>
|
||||
<Text style={styles.commitInputDisabledText}>
|
||||
{t('sourceControl.content.noStagedFiles', 'No staged files')}
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
<TextInput
|
||||
style={styles.commitInput}
|
||||
value={commitMessage}
|
||||
onChangeText={setCommitMessage}
|
||||
placeholder="Commit message"
|
||||
placeholder={t('sourceControl.content.commitMessagePlaceholder', 'Commit message')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
editable={busyAction === null && openingPath === null && openingBranchPath === null}
|
||||
returnKeyType="done"
|
||||
@@ -219,15 +239,17 @@ export function MobileSourceControlContent({ state, primaryAction }: Props) {
|
||||
disabled={generateDisabled}
|
||||
accessibilityState={{ disabled: generateDisabled }}
|
||||
accessibilityHint={
|
||||
generateBlockedByMessage ? 'Clear the message to regenerate.' : undefined
|
||||
generateBlockedByMessage
|
||||
? t('sourceControl.content.regenerateHint', 'Clear the message to regenerate.')
|
||||
: undefined
|
||||
}
|
||||
onPress={() =>
|
||||
generatingMessage ? cancelGenerateCommitMessage() : void generateCommitMessage()
|
||||
}
|
||||
accessibilityLabel={
|
||||
generatingMessage
|
||||
? 'Cancel commit message generation'
|
||||
: 'Generate commit message with AI'
|
||||
? t('sourceControl.content.cancelGeneration', 'Cancel commit message generation')
|
||||
: t('sourceControl.content.generateMessage', 'Generate commit message with AI')
|
||||
}
|
||||
>
|
||||
{generatingMessage ? (
|
||||
|
||||
@@ -10,6 +10,7 @@ import type {
|
||||
} from './mobile-source-control-screen-state'
|
||||
import type { MobileSourceControlState } from './use-mobile-source-control-state'
|
||||
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { styles } from './mobile-source-control-styles'
|
||||
import { hubStyles } from './mobile-source-control-hub-styles'
|
||||
|
||||
@@ -39,6 +40,7 @@ export type FileListState = Pick<
|
||||
|
||||
export function MobileSourceControlFileList({ state }: { state: FileListState }) {
|
||||
const colorScheme = useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
const sections: FileSection[] = state.sections.map((section) => ({
|
||||
...section,
|
||||
key: section.id
|
||||
@@ -46,7 +48,7 @@ export function MobileSourceControlFileList({ state }: { state: FileListState })
|
||||
if (state.shouldShowBranchCompareSection) {
|
||||
sections.push({
|
||||
key: 'committed',
|
||||
title: 'Committed on Branch',
|
||||
title: t('sourceControl.fileList.committedSection', 'Committed on Branch'),
|
||||
data:
|
||||
state.branchCompareState.kind === 'ready' &&
|
||||
state.branchCompareResult?.summary.status === 'ready'
|
||||
@@ -54,7 +56,7 @@ export function MobileSourceControlFileList({ state }: { state: FileListState })
|
||||
: []
|
||||
})
|
||||
}
|
||||
const renderFileRow = makeRenderFileRow(state)
|
||||
const renderFileRow = makeRenderFileRow(state, t)
|
||||
return (
|
||||
<SectionList<FileEntry, FileSection>
|
||||
style={hubStyles.tabBody}
|
||||
|
||||
@@ -2,8 +2,10 @@ import { ActivityIndicator, Pressable, Text, View } from 'react-native'
|
||||
import { ChevronRight, FileText, Minus, Plus, Trash2 } from 'lucide-react-native'
|
||||
import { colors } from '../theme/mobile-theme'
|
||||
import { STATUS_LABELS } from '../../../src/shared/git-status-labels'
|
||||
import { CONFLICT_KIND_LABELS } from '../../../src/shared/source-control-conflict-prompts'
|
||||
import type { GitConflictKind } from '../../../src/shared/git-status-types'
|
||||
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
|
||||
import type { Translate } from '../i18n/mobile-i18n'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { formatMobileBranchEntryMeta } from './mobile-branch-entry-format'
|
||||
import {
|
||||
statusColor,
|
||||
@@ -23,10 +25,31 @@ type RowState = Pick<
|
||||
| 'setDiscardTarget'
|
||||
>
|
||||
|
||||
export function makeRenderFileRow(state: RowState) {
|
||||
function conflictKindLabel(kind: GitConflictKind | undefined, t: Translate): string {
|
||||
switch (kind) {
|
||||
case 'both_modified':
|
||||
return t('sourceControl.fileRows.bothModified', 'Both modified')
|
||||
case 'both_added':
|
||||
return t('sourceControl.fileRows.bothAdded', 'Both added')
|
||||
case 'deleted_by_us':
|
||||
return t('sourceControl.fileRows.deletedByUs', 'Deleted by us')
|
||||
case 'deleted_by_them':
|
||||
return t('sourceControl.fileRows.deletedByThem', 'Deleted by them')
|
||||
case 'added_by_us':
|
||||
return t('sourceControl.fileRows.addedByUs', 'Added by us')
|
||||
case 'added_by_them':
|
||||
return t('sourceControl.fileRows.addedByThem', 'Added by them')
|
||||
case 'both_deleted':
|
||||
return t('sourceControl.fileRows.bothDeleted', 'Both deleted')
|
||||
default:
|
||||
return t('sourceControl.fileRows.unresolvedConflict', 'Unresolved conflict')
|
||||
}
|
||||
}
|
||||
|
||||
export function makeRenderFileRow(state: RowState, t: Translate) {
|
||||
const { busyAction, openingPath, openingBranchPath, openFile, runGitAction, setDiscardTarget } =
|
||||
state
|
||||
return function FileRow({ item }: { item: MobileGitStatusEntryView }) {
|
||||
return function renderFileRow({ item }: { item: MobileGitStatusEntryView }) {
|
||||
const rowBusy =
|
||||
busyAction === item.stageActionId ||
|
||||
busyAction === item.unstageActionId ||
|
||||
@@ -45,7 +68,13 @@ export function makeRenderFileRow(state: RowState) {
|
||||
]}
|
||||
onPress={() => void openFile(item)}
|
||||
disabled={rowDisabled}
|
||||
accessibilityLabel={`Open changed file ${item.path}`}
|
||||
accessibilityLabel={t(
|
||||
'sourceControl.fileRows.openChangedFile',
|
||||
'Open changed file {{path}}',
|
||||
{
|
||||
path: item.path
|
||||
}
|
||||
)}
|
||||
>
|
||||
<View style={styles.statusBadge}>
|
||||
<Text style={[styles.statusBadgeText, { color: statusColor(item.status) }]}>
|
||||
@@ -66,11 +95,11 @@ export function makeRenderFileRow(state: RowState) {
|
||||
</Text>
|
||||
{item.oldPath ? (
|
||||
<Text style={styles.fileMeta} numberOfLines={1}>
|
||||
from {item.oldPath}
|
||||
{t('sourceControl.fileRows.renamedFrom', 'from {{path}}', { path: item.oldPath })}
|
||||
</Text>
|
||||
) : item.conflictStatus === 'unresolved' ? (
|
||||
<Text style={styles.fileMeta} numberOfLines={1}>
|
||||
{item.conflictKind ? CONFLICT_KIND_LABELS[item.conflictKind] : 'Unresolved conflict'}
|
||||
{conflictKindLabel(item.conflictKind, t)}
|
||||
</Text>
|
||||
) : null}
|
||||
</View>
|
||||
@@ -88,7 +117,9 @@ export function makeRenderFileRow(state: RowState) {
|
||||
void runGitAction(item.unstageActionId, 'git.unstage', { filePath: item.path })
|
||||
}
|
||||
hitSlop={8}
|
||||
accessibilityLabel={`Unstage ${item.path}`}
|
||||
accessibilityLabel={t('sourceControl.fileRows.unstageFile', 'Unstage {{path}}', {
|
||||
path: item.path
|
||||
})}
|
||||
>
|
||||
<Minus size={16} color={colors.textSecondary} strokeWidth={2.2} />
|
||||
</Pressable>
|
||||
@@ -106,7 +137,9 @@ export function makeRenderFileRow(state: RowState) {
|
||||
void runGitAction(item.stageActionId, 'git.stage', { filePath: item.path })
|
||||
}
|
||||
hitSlop={8}
|
||||
accessibilityLabel={`Stage ${item.path}`}
|
||||
accessibilityLabel={t('sourceControl.fileRows.stageFile', 'Stage {{path}}', {
|
||||
path: item.path
|
||||
})}
|
||||
>
|
||||
<Plus size={16} color={colors.textSecondary} strokeWidth={2.2} />
|
||||
</Pressable>
|
||||
@@ -121,7 +154,9 @@ export function makeRenderFileRow(state: RowState) {
|
||||
disabled={ioBusy}
|
||||
onPress={() => setDiscardTarget(item)}
|
||||
hitSlop={8}
|
||||
accessibilityLabel={`Discard ${item.path}`}
|
||||
accessibilityLabel={t('sourceControl.fileRows.discardFile', 'Discard {{path}}', {
|
||||
path: item.path
|
||||
})}
|
||||
>
|
||||
<Trash2 size={16} color={colors.statusRed} strokeWidth={2.1} />
|
||||
</Pressable>
|
||||
@@ -151,6 +186,7 @@ type BranchState = Pick<
|
||||
|
||||
export function BranchCompareHeader({ state }: { state: BranchState }) {
|
||||
useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
const {
|
||||
shouldShowBranchCompareSection,
|
||||
branchCompareSummaryText,
|
||||
@@ -166,7 +202,9 @@ export function BranchCompareHeader({ state }: { state: BranchState }) {
|
||||
<View style={styles.branchCompareBlock}>
|
||||
<View style={styles.sectionHeader}>
|
||||
<View style={styles.branchSectionTitleBlock}>
|
||||
<Text style={styles.sectionTitle}>Committed on Branch</Text>
|
||||
<Text style={styles.sectionTitle}>
|
||||
{t('sourceControl.fileRows.committedSection', 'Committed on Branch')}
|
||||
</Text>
|
||||
{branchCompareSummaryText ? (
|
||||
<Text style={styles.branchSectionSubtitle} numberOfLines={1}>
|
||||
{branchCompareSummaryText}
|
||||
@@ -178,7 +216,9 @@ export function BranchCompareHeader({ state }: { state: BranchState }) {
|
||||
{branchCompareState.kind === 'loading' ? (
|
||||
<View style={styles.branchStateRow}>
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
<Text style={styles.branchStateText}>Loading committed changes...</Text>
|
||||
<Text style={styles.branchStateText}>
|
||||
{t('sourceControl.fileRows.loadingCommitted', 'Loading committed changes...')}
|
||||
</Text>
|
||||
</View>
|
||||
) : branchCompareState.kind === 'error' ? (
|
||||
<View style={styles.branchStateRow}>
|
||||
@@ -187,7 +227,8 @@ export function BranchCompareHeader({ state }: { state: BranchState }) {
|
||||
) : branchCompareResult && branchCompareResult.summary.status !== 'ready' ? (
|
||||
<View style={styles.branchStateRow}>
|
||||
<Text style={styles.branchStateText}>
|
||||
{branchCompareResult.summary.errorMessage ?? 'Committed changes unavailable.'}
|
||||
{branchCompareResult.summary.errorMessage ??
|
||||
t('sourceControl.fileRows.committedUnavailable', 'Committed changes unavailable.')}
|
||||
</Text>
|
||||
</View>
|
||||
) : null}
|
||||
@@ -203,6 +244,7 @@ export function BranchFileRow({
|
||||
state: BranchState
|
||||
}) {
|
||||
useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
const { busyAction, openBranchDiff, openingBranchPath, openingPath } = state
|
||||
const rowBusy = openingBranchPath === entry.path
|
||||
const rowDisabled =
|
||||
@@ -218,7 +260,13 @@ export function BranchFileRow({
|
||||
]}
|
||||
onPress={() => void openBranchDiff(entry)}
|
||||
disabled={rowDisabled}
|
||||
accessibilityLabel={`Open committed change ${entry.path}`}
|
||||
accessibilityLabel={t(
|
||||
'sourceControl.fileRows.openCommittedChange',
|
||||
'Open committed change {{path}}',
|
||||
{
|
||||
path: entry.path
|
||||
}
|
||||
)}
|
||||
>
|
||||
<View style={styles.statusBadge}>
|
||||
<Text style={[styles.statusBadgeText, { color: statusColor(entry.status) }]}>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Pressable, Text, View } from 'react-native'
|
||||
import { ChevronLeft, ExternalLink, RefreshCw, X } from 'lucide-react-native'
|
||||
import { colors } from '../theme/mobile-theme'
|
||||
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { styles } from './mobile-source-control-styles'
|
||||
|
||||
type Props = {
|
||||
@@ -28,6 +29,7 @@ export function MobileSourceControlHeader({
|
||||
prNumber = null
|
||||
}: Props) {
|
||||
useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
return (
|
||||
<View style={styles.topBar}>
|
||||
{/* Dock dismissal and route Back have distinct semantics. */}
|
||||
@@ -37,7 +39,7 @@ export function MobileSourceControlHeader({
|
||||
onPress={onClose}
|
||||
hitSlop={8}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Close source control"
|
||||
accessibilityLabel={t('sourceControl.header.close', 'Close source control')}
|
||||
>
|
||||
<X size={22} color={colors.textSecondary} strokeWidth={2.2} />
|
||||
</Pressable>
|
||||
@@ -47,14 +49,14 @@ export function MobileSourceControlHeader({
|
||||
onPress={onBack}
|
||||
hitSlop={8}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Back to session"
|
||||
accessibilityLabel={t('sourceControl.header.backToSession', 'Back to session')}
|
||||
>
|
||||
<ChevronLeft size={22} color={colors.textSecondary} strokeWidth={2.2} />
|
||||
</Pressable>
|
||||
)}
|
||||
<View style={styles.titleBlock}>
|
||||
<Text style={styles.title} numberOfLines={1}>
|
||||
Source Control
|
||||
{t('sourceControl.header.title', 'Source Control')}
|
||||
</Text>
|
||||
<Text style={styles.meta} numberOfLines={1}>
|
||||
{worktreeLabel}
|
||||
@@ -68,8 +70,14 @@ export function MobileSourceControlHeader({
|
||||
accessibilityRole="link"
|
||||
accessibilityLabel={
|
||||
prNumber != null
|
||||
? `Open pull request #${prNumber} on the web`
|
||||
: 'Open pull request on the web'
|
||||
? t(
|
||||
'sourceControl.header.openNumberedPrWeb',
|
||||
'Open pull request #{{number}} on the web',
|
||||
{
|
||||
number: prNumber
|
||||
}
|
||||
)
|
||||
: t('sourceControl.header.openPrWeb', 'Open pull request on the web')
|
||||
}
|
||||
>
|
||||
<ExternalLink size={18} color={colors.textSecondary} strokeWidth={2.1} />
|
||||
@@ -85,7 +93,7 @@ export function MobileSourceControlHeader({
|
||||
disabled={ioBusy}
|
||||
hitSlop={8}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Refresh source control"
|
||||
accessibilityLabel={t('sourceControl.header.refresh', 'Refresh source control')}
|
||||
>
|
||||
<RefreshCw size={18} color={colors.textSecondary} strokeWidth={2.1} />
|
||||
</Pressable>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ActionSheetModal, type ActionSheetAction } from '../components/ActionSh
|
||||
import { ConfirmModal } from '../components/ConfirmModal'
|
||||
import { PickerModal } from '../components/PickerModal'
|
||||
import { openMobilePrUrl } from '../components/mobile-pr-url'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { MobileBranchDiffPreviewDrawer } from './MobileBranchDiffPreviewDrawer'
|
||||
import type { MobileSourceControlState } from './use-mobile-source-control-state'
|
||||
|
||||
@@ -11,6 +12,7 @@ type Props = {
|
||||
}
|
||||
|
||||
export function MobileSourceControlModals({ state, actionSheetActions }: Props) {
|
||||
const t = useMobileTranslation()
|
||||
const {
|
||||
branchDiffPreview,
|
||||
setBranchDiffPreview,
|
||||
@@ -39,7 +41,7 @@ export function MobileSourceControlModals({ state, actionSheetActions }: Props)
|
||||
|
||||
<ActionSheetModal
|
||||
visible={showActionSheet}
|
||||
title="Source Control"
|
||||
title={t('sourceControl.modals.actionsTitle', 'Source Control')}
|
||||
message={branchLabel}
|
||||
actions={actionSheetActions}
|
||||
onClose={() => setShowActionSheet(false)}
|
||||
@@ -47,13 +49,17 @@ export function MobileSourceControlModals({ state, actionSheetActions }: Props)
|
||||
|
||||
<ConfirmModal
|
||||
visible={discardTarget !== null}
|
||||
title="Discard Change"
|
||||
title={t('sourceControl.modals.discardTitle', 'Discard Change')}
|
||||
message={
|
||||
discardTarget
|
||||
? `Discard changes to "${discardTarget.path}"? This cannot be undone.`
|
||||
? t(
|
||||
'sourceControl.modals.discardConfirmMessage',
|
||||
'Discard changes to "{{path}}"? This cannot be undone.',
|
||||
{ path: discardTarget.path }
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
confirmLabel="Discard"
|
||||
confirmLabel={t('sourceControl.modals.discardButton', 'Discard')}
|
||||
destructive
|
||||
onConfirm={() => {
|
||||
if (discardTarget) {
|
||||
@@ -68,11 +74,14 @@ export function MobileSourceControlModals({ state, actionSheetActions }: Props)
|
||||
|
||||
<PickerModal
|
||||
visible={showBranchPicker}
|
||||
title="Switch Branch"
|
||||
title={t('sourceControl.modals.switchBranchTitle', 'Switch Branch')}
|
||||
options={(localBranches?.branches ?? []).map((b) => ({
|
||||
value: b,
|
||||
label: b,
|
||||
subtitle: b === localBranches?.current ? 'current' : undefined
|
||||
subtitle:
|
||||
b === localBranches?.current
|
||||
? t('sourceControl.modals.currentBranch', 'current')
|
||||
: undefined
|
||||
}))}
|
||||
selected={localBranches?.current ?? ''}
|
||||
onSelect={(branch) => {
|
||||
@@ -87,13 +96,19 @@ export function MobileSourceControlModals({ state, actionSheetActions }: Props)
|
||||
|
||||
<ConfirmModal
|
||||
visible={createdPrUrl !== null}
|
||||
title="Pull Request Created"
|
||||
title={t('sourceControl.modals.prCreatedTitle', 'Pull Request Created')}
|
||||
message={
|
||||
createdPrWarning
|
||||
? `Open it in your browser?\n\n${createdPrWarning}`
|
||||
: 'Open it in your browser?'
|
||||
? t(
|
||||
'sourceControl.modals.openPrWithWarning',
|
||||
'Open it in your browser?\n\n{{warning}}',
|
||||
{
|
||||
warning: createdPrWarning
|
||||
}
|
||||
)
|
||||
: t('sourceControl.modals.openPrMessage', 'Open it in your browser?')
|
||||
}
|
||||
confirmLabel="Open"
|
||||
confirmLabel={t('common.open', 'Open')}
|
||||
onConfirm={() => {
|
||||
if (createdPrUrl) {
|
||||
openMobilePrUrl(createdPrUrl)
|
||||
|
||||
@@ -264,12 +264,14 @@ export function MobileSourceControlPanel({
|
||||
) : screenState.kind === 'error' || screenState.kind === 'unavailable' ? (
|
||||
<View style={styles.state}>
|
||||
<Text style={styles.stateTitle}>
|
||||
{screenState.kind === 'unavailable' ? 'Source Control Unavailable' : 'Unable to Load'}
|
||||
{screenState.kind === 'unavailable'
|
||||
? t('sourceControl.panel.unavailableTitle', 'Source Control Unavailable')
|
||||
: t('sourceControl.panel.loadFailedTitle', 'Unable to Load')}
|
||||
</Text>
|
||||
<Text style={styles.stateText}>{screenState.message}</Text>
|
||||
{screenState.kind === 'error' && statusRetry ? (
|
||||
<Pressable style={styles.retryButton} onPress={statusRetry}>
|
||||
<Text style={styles.retryText}>Retry</Text>
|
||||
<Text style={styles.retryText}>{t('common.retry', 'Retry')}</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
} from 'lucide-react-native'
|
||||
import { colors } from '../theme/mobile-theme'
|
||||
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
|
||||
import type { Translate } from '../i18n/mobile-i18n'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { statusColor } from '../components/pr-sidebar/pr-sidebar-status-color'
|
||||
import { hubStyles } from './mobile-source-control-hub-styles'
|
||||
import type { MobilePrChipRollup, MobilePrChipSummary } from './mobile-pr-chip-summary'
|
||||
@@ -21,12 +23,13 @@ type Props = {
|
||||
|
||||
export function MobileSourceControlPrChip({ summary, onPress }: Props) {
|
||||
useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
return (
|
||||
<Pressable
|
||||
style={({ pressed }) => [hubStyles.chip, pressed && hubStyles.chipPressed]}
|
||||
onPress={onPress}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={chipAccessibilityLabel(summary)}
|
||||
accessibilityLabel={chipAccessibilityLabel(summary, t)}
|
||||
>
|
||||
<View style={hubStyles.chipIcon}>
|
||||
<GitPullRequest size={15} color={colors.textSecondary} strokeWidth={2.1} />
|
||||
@@ -35,12 +38,14 @@ export function MobileSourceControlPrChip({ summary, onPress }: Props) {
|
||||
<>
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
<Text style={hubStyles.chipMutedText} numberOfLines={1}>
|
||||
Loading pull request…
|
||||
{t('sourceControl.prChip.loading', 'Loading pull request…')}
|
||||
</Text>
|
||||
</>
|
||||
) : summary.kind === 'none' ? (
|
||||
<>
|
||||
<Text style={hubStyles.chipCreateText}>Create pull request</Text>
|
||||
<Text style={hubStyles.chipCreateText}>
|
||||
{t('sourceControl.prChip.createPr', 'Create pull request')}
|
||||
</Text>
|
||||
<View style={hubStyles.chipSpacer} />
|
||||
<ChevronRight size={16} color={colors.textMuted} strokeWidth={2.1} />
|
||||
</>
|
||||
@@ -102,20 +107,41 @@ function RollupIcon({ kind, color }: { kind: MobilePrChipRollup['kind']; color:
|
||||
}
|
||||
}
|
||||
|
||||
function chipAccessibilityLabel(summary: MobilePrChipSummary): string {
|
||||
function chipAccessibilityLabel(summary: MobilePrChipSummary, t: Translate): string {
|
||||
switch (summary.kind) {
|
||||
case 'loading':
|
||||
return 'Loading pull request'
|
||||
return t('sourceControl.prChip.loadingLabel', 'Loading pull request')
|
||||
case 'none':
|
||||
return 'Create pull request'
|
||||
return t('sourceControl.prChip.createPr', 'Create pull request')
|
||||
case 'unavailable':
|
||||
return `Pull request unavailable: ${summary.message}`
|
||||
return t('sourceControl.prChip.unavailableLabel', 'Pull request unavailable: {{message}}', {
|
||||
message: summary.message
|
||||
})
|
||||
case 'ready': {
|
||||
const comments =
|
||||
summary.commentCount != null && summary.commentCount > 0
|
||||
? `, ${summary.commentCount} unresolved comments`
|
||||
: ''
|
||||
return `Pull request #${summary.number}, ${summary.stateLabel}, ${summary.rollup.text}${comments}. Open pull request.`
|
||||
const count = summary.commentCount
|
||||
const details = {
|
||||
number: summary.number,
|
||||
state: summary.stateLabel,
|
||||
checks: summary.rollup.text
|
||||
}
|
||||
if (count != null && count > 0) {
|
||||
return count === 1
|
||||
? t(
|
||||
'sourceControl.prChip.openWithComments_one',
|
||||
'Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request.',
|
||||
{ ...details, count }
|
||||
)
|
||||
: t(
|
||||
'sourceControl.prChip.openWithComments_other',
|
||||
'Pull request #{{number}}, {{state}}, {{checks}}, {{count}} unresolved comments. Open pull request.',
|
||||
{ ...details, count }
|
||||
)
|
||||
}
|
||||
return t(
|
||||
'sourceControl.prChip.openLabel',
|
||||
'Pull request #{{number}}, {{state}}, {{checks}}. Open pull request.',
|
||||
details
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { MobileHostedReviewCreateIntentProgress } from './mobile-hosted-review-create-intent'
|
||||
|
||||
// Use the desktop provider vocabulary: GitLab says Merge Request.
|
||||
export type HostedReviewCopy = {
|
||||
@@ -26,3 +27,29 @@ function mrCopy(): HostedReviewCopy {
|
||||
export function hostedReviewCopy(provider: string | undefined): HostedReviewCopy {
|
||||
return provider === 'gitlab' ? mrCopy() : prCopy()
|
||||
}
|
||||
|
||||
export function mobileHostedReviewCreateIntentProgressMessage(
|
||||
progress: MobileHostedReviewCreateIntentProgress
|
||||
): string {
|
||||
switch (progress) {
|
||||
case 'fast_forwarding':
|
||||
return translate('sourceControl.hostedReviewCopy.updatingBranch', 'Updating branch...')
|
||||
case 'staging':
|
||||
return translate('sourceControl.hostedReviewCopy.stagingChanges', 'Staging changes...')
|
||||
case 'generating_commit_message':
|
||||
return translate(
|
||||
'sourceControl.hostedReviewCopy.generatingCommitMessage',
|
||||
'Generating commit message...'
|
||||
)
|
||||
case 'committing':
|
||||
return translate('sourceControl.hostedReviewCopy.committingChanges', 'Committing changes...')
|
||||
case 'publishing':
|
||||
return translate('sourceControl.hostedReviewCopy.publishingBranch', 'Publishing branch...')
|
||||
case 'pushing':
|
||||
return translate('sourceControl.hostedReviewCopy.pushingCommits', 'Pushing commits...')
|
||||
case 'force_pushing':
|
||||
return translate('sourceControl.hostedReviewCopy.forcePushing', 'Force pushing with lease...')
|
||||
case 'creating_review':
|
||||
return translate('sourceControl.hostedReviewCopy.creatingReview', 'Creating review...')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { refusedRpcMessageOrFallback } from '../transport/rpc-refusal-message'
|
||||
import { getRepoIdFromWorktreeId } from '../../../src/shared/worktree/id'
|
||||
import { isMobileGitUnavailableReply } from './mobile-git-status'
|
||||
@@ -87,6 +88,11 @@ async function readDefaultBaseRef(
|
||||
try {
|
||||
return repoDefaultBaseRefRead.interpret(defaultReply)
|
||||
} catch (error) {
|
||||
throw new Error(refusedRpcMessageOrFallback(error, 'Unable to resolve branch base'))
|
||||
throw new Error(
|
||||
refusedRpcMessageOrFallback(
|
||||
error,
|
||||
translate('sourceControl.branchBaseRef.resolveFailed', 'Unable to resolve branch base')
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { RpcOperationSender } from '../transport/rpc-operation-sender'
|
||||
import type { RequestCurrency } from '../transport/generation-scoped-request-owner'
|
||||
import { refusedRpcMessageOrFallback } from '../transport/rpc-refusal-message'
|
||||
@@ -51,7 +52,13 @@ async function readCompare(
|
||||
baseRef: string | null
|
||||
): Promise<BranchCompareOutcome> {
|
||||
if (!baseRef) {
|
||||
return { kind: 'failed', message: 'Unable to resolve the base branch for comparison.' }
|
||||
return {
|
||||
kind: 'failed',
|
||||
message: translate(
|
||||
'sourceControl.branchCompareOutcome.baseBranchUnavailable',
|
||||
'Unable to resolve the base branch for comparison.'
|
||||
)
|
||||
}
|
||||
}
|
||||
try {
|
||||
const reply = await gitBranchCompareRead.request(client, {
|
||||
@@ -67,7 +74,13 @@ async function readCompare(
|
||||
} catch (error) {
|
||||
return {
|
||||
kind: 'failed',
|
||||
message: refusedRpcMessageOrFallback(error, 'Unable to load committed changes')
|
||||
message: refusedRpcMessageOrFallback(
|
||||
error,
|
||||
translate(
|
||||
'sourceControl.branchCompareOutcome.loadFailed',
|
||||
'Unable to load committed changes'
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -78,7 +91,13 @@ async function readCompare(
|
||||
function failedCompare(err: unknown): BranchCompareOutcome {
|
||||
return {
|
||||
kind: 'failed',
|
||||
message: err instanceof Error ? err.message : 'Unable to load committed changes'
|
||||
message:
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate(
|
||||
'sourceControl.branchCompareOutcome.loadFailed',
|
||||
'Unable to load committed changes'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { compareFileNames } from '../../../src/shared/file-name-sort'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type {
|
||||
MobileGitBranchChangeEntry,
|
||||
MobileGitBranchCompareReply,
|
||||
@@ -11,7 +12,7 @@ export type MobileGitBranchCompareResult = MobileGitBranchCompareReply
|
||||
export type MobileBranchCompareSection<
|
||||
TEntry extends MobileGitBranchChangeEntry = MobileGitBranchChangeEntry
|
||||
> = {
|
||||
title: 'Committed on Branch'
|
||||
title: string
|
||||
data: TEntry[]
|
||||
}
|
||||
|
||||
@@ -24,7 +25,7 @@ export function buildMobileBranchCompareSection<TEntry extends MobileGitBranchCh
|
||||
const data = [...entries]
|
||||
data.sort((a, b) => compareFileNames(a.path, b.path))
|
||||
return {
|
||||
title: 'Committed on Branch',
|
||||
title: translate('sourceControl.branchCompare.sectionTitle', 'Committed on Branch'),
|
||||
data
|
||||
}
|
||||
}
|
||||
@@ -35,12 +36,30 @@ export function formatMobileBranchCompareSummary(
|
||||
if (summary.status !== 'ready') {
|
||||
return summary.errorMessage ?? null
|
||||
}
|
||||
const parts = [`${summary.changedFiles} ${summary.changedFiles === 1 ? 'file' : 'files'}`]
|
||||
if (summary.commitsAhead !== undefined) {
|
||||
parts.push(`${summary.commitsAhead} ${summary.commitsAhead === 1 ? 'commit' : 'commits'}`)
|
||||
const files = branchCompareFiles(summary.changedFiles)
|
||||
if (summary.commitsAhead === undefined) {
|
||||
return translate('sourceControl.branchCompare.summary', '{{files}} - vs {{baseRef}}', {
|
||||
files,
|
||||
baseRef: summary.baseRef
|
||||
})
|
||||
}
|
||||
parts.push(`vs ${summary.baseRef}`)
|
||||
return parts.join(' - ')
|
||||
return translate(
|
||||
'sourceControl.branchCompare.summaryWithCommits',
|
||||
'{{files}} - {{commits}} - vs {{baseRef}}',
|
||||
{ files, commits: branchCompareCommits(summary.commitsAhead), baseRef: summary.baseRef }
|
||||
)
|
||||
}
|
||||
|
||||
function branchCompareFiles(count: number): string {
|
||||
return count === 1
|
||||
? translate('sourceControl.branchCompare.files_one', '{{count}} file', { count })
|
||||
: translate('sourceControl.branchCompare.files_other', '{{count}} files', { count })
|
||||
}
|
||||
|
||||
function branchCompareCommits(count: number): string {
|
||||
return count === 1
|
||||
? translate('sourceControl.branchCompare.commits_one', '{{count}} commit', { count })
|
||||
: translate('sourceControl.branchCompare.commits_other', '{{count}} commits', { count })
|
||||
}
|
||||
|
||||
export function canOpenMobileBranchCompareDiff(summary: MobileGitBranchCompareSummary): boolean {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { refusedRpcMessageOrFallback } from '../transport/rpc-refusal-message'
|
||||
import {
|
||||
gitCancelGenerateCommitMessageRun,
|
||||
@@ -21,7 +22,13 @@ export async function requestMobileCommitMessage(
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: refusedRpcMessageOrFallback(error, 'Failed to generate commit message')
|
||||
error: refusedRpcMessageOrFallback(
|
||||
error,
|
||||
translate(
|
||||
'sourceControl.commitMessageAi.generateFailed',
|
||||
'Failed to generate commit message'
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ const BUSY_ACTIONS = new Set(['create-pr', 'push-create-pr'])
|
||||
function hiddenAction(onPress: () => void): MobileCreatePrAction {
|
||||
return {
|
||||
visible: false,
|
||||
label: 'Create Pull Request',
|
||||
label: translate('sourceControl.createPrAction.createPullRequest', 'Create Pull Request'),
|
||||
disabled: true,
|
||||
loading: false,
|
||||
pushFirst: false,
|
||||
@@ -62,7 +62,10 @@ export function buildMobileCreatePrAction({
|
||||
if (eligibilityState.kind === 'error') {
|
||||
return {
|
||||
visible: true,
|
||||
label: 'Review status unavailable',
|
||||
label: translate(
|
||||
'sourceControl.createPrAction.statusUnavailable',
|
||||
'Review status unavailable'
|
||||
),
|
||||
disabled: true,
|
||||
loading: false,
|
||||
pushFirst: false,
|
||||
@@ -73,7 +76,7 @@ export function buildMobileCreatePrAction({
|
||||
if (!eligibility) {
|
||||
return {
|
||||
visible: true,
|
||||
label: 'Checking review status…',
|
||||
label: translate('sourceControl.createPrAction.checkingStatus', 'Checking review status…'),
|
||||
disabled: true,
|
||||
loading: true,
|
||||
pushFirst: false,
|
||||
@@ -84,7 +87,10 @@ export function buildMobileCreatePrAction({
|
||||
if (!supportsHostedReviewCreation(eligibility.provider)) {
|
||||
return {
|
||||
visible: true,
|
||||
label: 'Review creation unavailable for this provider',
|
||||
label: translate(
|
||||
'sourceControl.createPrAction.providerUnavailable',
|
||||
'Review creation unavailable for this provider'
|
||||
),
|
||||
disabled: true,
|
||||
loading: false,
|
||||
pushFirst: false,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { MobileGitHistoryItem, MobileGitHistoryResult } from './git-history-reply-schema'
|
||||
import { refusedRpcMessageOrFallback } from '../transport/rpc-refusal-message'
|
||||
import { gitHistoryRead } from './mobile-git-read-operations'
|
||||
@@ -19,32 +20,48 @@ export function formatCommitTime(timestampMs: number | null | undefined, nowMs:
|
||||
}
|
||||
const delta = nowMs - timestampMs
|
||||
if (delta < 60_000) {
|
||||
return 'just now'
|
||||
return translate('sourceControl.gitHistory.justNow', 'just now')
|
||||
}
|
||||
const minutes = Math.floor(delta / 60_000)
|
||||
if (minutes < 60) {
|
||||
return `${minutes}m`
|
||||
const count = minutes
|
||||
return count === 1
|
||||
? translate('sourceControl.gitHistory.minutes_one', '{{count}}m', { count })
|
||||
: translate('sourceControl.gitHistory.minutes_other', '{{count}}m', { count })
|
||||
}
|
||||
const hours = Math.floor(minutes / 60)
|
||||
if (hours < 24) {
|
||||
return `${hours}h`
|
||||
const count = hours
|
||||
return count === 1
|
||||
? translate('sourceControl.gitHistory.hours_one', '{{count}}h', { count })
|
||||
: translate('sourceControl.gitHistory.hours_other', '{{count}}h', { count })
|
||||
}
|
||||
const days = Math.floor(hours / 24)
|
||||
if (days < 30) {
|
||||
return `${days}d`
|
||||
const count = days
|
||||
return count === 1
|
||||
? translate('sourceControl.gitHistory.days_one', '{{count}}d', { count })
|
||||
: translate('sourceControl.gitHistory.days_other', '{{count}}d', { count })
|
||||
}
|
||||
const months = Math.floor(days / 30)
|
||||
if (months < 12) {
|
||||
return `${months}mo`
|
||||
const count = months
|
||||
return count === 1
|
||||
? translate('sourceControl.gitHistory.months_one', '{{count}}mo', { count })
|
||||
: translate('sourceControl.gitHistory.months_other', '{{count}}mo', { count })
|
||||
}
|
||||
return `${Math.floor(months / 12)}y`
|
||||
const count = Math.floor(months / 12)
|
||||
return count === 1
|
||||
? translate('sourceControl.gitHistory.years_one', '{{count}}y', { count })
|
||||
: translate('sourceControl.gitHistory.years_other', '{{count}}y', { count })
|
||||
}
|
||||
|
||||
export function toMobileCommitRow(item: MobileGitHistoryItem, nowMs: number): MobileCommitRow {
|
||||
return {
|
||||
id: item.id,
|
||||
shortId: item.displayId ?? item.id.slice(0, 7),
|
||||
subject: item.subject || '(no commit message)',
|
||||
subject:
|
||||
item.subject || translate('sourceControl.gitHistory.noCommitMessage', '(no commit message)'),
|
||||
author: item.author ?? '',
|
||||
parentId: item.parentIds[0] ?? null,
|
||||
relativeTime: formatCommitTime(item.timestamp, nowMs)
|
||||
@@ -68,6 +85,11 @@ export async function fetchMobileGitHistory(
|
||||
try {
|
||||
return gitHistoryRead.interpret(reply)
|
||||
} catch (error) {
|
||||
throw new Error(refusedRpcMessageOrFallback(error, 'Failed to load commit history'))
|
||||
throw new Error(
|
||||
refusedRpcMessageOrFallback(
|
||||
error,
|
||||
translate('sourceControl.gitHistory.loadFailed', 'Failed to load commit history')
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { GitFileStatus, GitStagingArea } from '../../../src/shared/git-status-types'
|
||||
import {
|
||||
buildSourceControlDisplaySections,
|
||||
@@ -43,10 +44,12 @@ export type MobileSourceControlSection<TEntry extends MobileGitStatusEntry = Mob
|
||||
data: TEntry[]
|
||||
}
|
||||
|
||||
const SECTION_TITLES: Record<SourceControlDisplaySectionId, string> = {
|
||||
conflicts: 'Conflicts',
|
||||
unstaged: 'Changes',
|
||||
staged: 'Staged Changes'
|
||||
function sectionTitles(): Record<SourceControlDisplaySectionId, string> {
|
||||
return {
|
||||
conflicts: translate('sourceControl.gitStatus.conflicts', 'Conflicts'),
|
||||
unstaged: translate('sourceControl.gitStatus.changes', 'Changes'),
|
||||
staged: translate('sourceControl.gitStatus.stagedChanges', 'Staged Changes')
|
||||
}
|
||||
}
|
||||
|
||||
// Desktop's sections: conflicts pinned on top, then the user's group order, sorted like desktop.
|
||||
@@ -54,13 +57,14 @@ export function buildMobileSourceControlSections<TEntry extends MobileGitStatusE
|
||||
entries: readonly TEntry[],
|
||||
groupOrder: SourceControlGroupOrder
|
||||
): MobileSourceControlSection<TEntry>[] {
|
||||
const titles = sectionTitles()
|
||||
return buildSourceControlDisplaySections(
|
||||
groupSourceControlEntries(entries.filter(hasKnownArea)),
|
||||
resolveSourceControlGroupOrder(groupOrder)
|
||||
).map((section) => ({
|
||||
id: section.id,
|
||||
area: section.area,
|
||||
title: SECTION_TITLES[section.id],
|
||||
title: titles[section.id],
|
||||
data: section.items
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { requestMobileCommitMessage } from './mobile-commit-message-ai'
|
||||
import { getStageablePaths, type MobileGitStatusResult } from './mobile-git-status'
|
||||
import { getMobilePrEligibilityReadiness } from './mobile-open-pr-prefill'
|
||||
@@ -13,6 +14,8 @@ import {
|
||||
import { applyMobileHostedReviewRemotePrerequisite } from './mobile-hosted-review-remote-prerequisite'
|
||||
import type { RpcOperationSender } from '../transport/rpc-operation-sender'
|
||||
|
||||
export { mobileHostedReviewCreateIntentProgressMessage } from './hosted-review-copy'
|
||||
|
||||
export type MobileHostedReviewCreateIntentProgress =
|
||||
| 'fast_forwarding'
|
||||
| 'staging'
|
||||
@@ -50,29 +53,6 @@ type PrepareInput = {
|
||||
onProgress?: (progress: MobileHostedReviewCreateIntentProgress) => void
|
||||
}
|
||||
|
||||
export function mobileHostedReviewCreateIntentProgressMessage(
|
||||
progress: MobileHostedReviewCreateIntentProgress
|
||||
): string {
|
||||
switch (progress) {
|
||||
case 'fast_forwarding':
|
||||
return 'Updating branch...'
|
||||
case 'staging':
|
||||
return 'Staging changes...'
|
||||
case 'generating_commit_message':
|
||||
return 'Generating commit message...'
|
||||
case 'committing':
|
||||
return 'Committing changes...'
|
||||
case 'publishing':
|
||||
return 'Publishing branch...'
|
||||
case 'pushing':
|
||||
return 'Pushing commits...'
|
||||
case 'force_pushing':
|
||||
return 'Force pushing with lease...'
|
||||
case 'creating_review':
|
||||
return 'Creating review...'
|
||||
}
|
||||
}
|
||||
|
||||
function hasUnresolvedConflicts(status: MobileGitStatusResult | null): boolean {
|
||||
return status?.entries.some((entry) => entry.conflictStatus === 'unresolved') === true
|
||||
}
|
||||
@@ -106,7 +86,10 @@ async function ensureLocalChangesCommitted(
|
||||
if (hasUnresolvedConflicts(currentStatus)) {
|
||||
return {
|
||||
ok: false,
|
||||
error: 'Resolve conflicts before creating a pull request.',
|
||||
error: translate(
|
||||
'sourceControl.hostedReviewCreateIntent.resolveConflicts',
|
||||
'Resolve conflicts before creating a pull request.'
|
||||
),
|
||||
committed: false,
|
||||
status: currentStatus
|
||||
}
|
||||
@@ -132,7 +115,10 @@ async function ensureLocalChangesCommitted(
|
||||
if (!mobileHostedReviewBranchStillMatches(input.branch, currentStatus)) {
|
||||
return {
|
||||
ok: false,
|
||||
error: 'Branch changed while preparing the pull request.',
|
||||
error: translate(
|
||||
'sourceControl.hostedReviewCreateIntent.branchChanged',
|
||||
'Branch changed while preparing the pull request.'
|
||||
),
|
||||
committed: false,
|
||||
status: currentStatus
|
||||
}
|
||||
@@ -143,7 +129,10 @@ async function ensureLocalChangesCommitted(
|
||||
if (!hasStagedChanges) {
|
||||
return {
|
||||
ok: false,
|
||||
error: 'Resolve or stage changes before creating a pull request.',
|
||||
error: translate(
|
||||
'sourceControl.hostedReviewCreateIntent.resolveOrStageChanges',
|
||||
'Resolve or stage changes before creating a pull request.'
|
||||
),
|
||||
committed: false,
|
||||
status: currentStatus
|
||||
}
|
||||
@@ -156,7 +145,10 @@ async function ensureLocalChangesCommitted(
|
||||
if (!generated.success) {
|
||||
return {
|
||||
ok: false,
|
||||
error: 'Could not generate a commit message. Add one in Source Control, then retry.',
|
||||
error: translate(
|
||||
'sourceControl.hostedReviewCreateIntent.generateMessageFailed',
|
||||
'Could not generate a commit message. Add one in Source Control, then retry.'
|
||||
),
|
||||
committed: false,
|
||||
status: currentStatus
|
||||
}
|
||||
@@ -164,7 +156,10 @@ async function ensureLocalChangesCommitted(
|
||||
if (input.readCommitMessage?.().trim()) {
|
||||
return {
|
||||
ok: false,
|
||||
error: 'Review the commit message, then retry Create PR.',
|
||||
error: translate(
|
||||
'sourceControl.hostedReviewCreateIntent.reviewCommitMessage',
|
||||
'Review the commit message, then retry Create PR.'
|
||||
),
|
||||
committed: false,
|
||||
status: currentStatus
|
||||
}
|
||||
@@ -202,7 +197,10 @@ async function ensureLocalChangesCommitted(
|
||||
if (!mobileHostedReviewBranchStillMatches(input.branch, currentStatus)) {
|
||||
return {
|
||||
ok: false,
|
||||
error: 'Branch changed while preparing the pull request.',
|
||||
error: translate(
|
||||
'sourceControl.hostedReviewCreateIntent.branchChanged',
|
||||
'Branch changed while preparing the pull request.'
|
||||
),
|
||||
committed: true,
|
||||
status: currentStatus
|
||||
}
|
||||
@@ -221,7 +219,10 @@ export async function prepareMobileHostedReviewCreateIntent(
|
||||
return {
|
||||
ok: false,
|
||||
error: initialStatus.ok
|
||||
? 'Branch changed while preparing the pull request.'
|
||||
? translate(
|
||||
'sourceControl.hostedReviewCreateIntent.branchChanged',
|
||||
'Branch changed while preparing the pull request.'
|
||||
)
|
||||
: initialStatus.error,
|
||||
status: currentStatus
|
||||
}
|
||||
@@ -242,7 +243,10 @@ export async function prepareMobileHostedReviewCreateIntent(
|
||||
if (!mobileHostedReviewBranchStillMatches(input.branch, currentStatus)) {
|
||||
return {
|
||||
ok: false,
|
||||
error: 'Branch changed while preparing the pull request.',
|
||||
error: translate(
|
||||
'sourceControl.hostedReviewCreateIntent.branchChanged',
|
||||
'Branch changed while preparing the pull request.'
|
||||
),
|
||||
status: currentStatus
|
||||
}
|
||||
}
|
||||
@@ -285,7 +289,10 @@ export async function prepareMobileHostedReviewCreateIntent(
|
||||
if (!mobileHostedReviewBranchStillMatches(input.branch, currentStatus)) {
|
||||
return {
|
||||
ok: false,
|
||||
error: 'Branch changed while preparing the pull request.',
|
||||
error: translate(
|
||||
'sourceControl.hostedReviewCreateIntent.branchChanged',
|
||||
'Branch changed while preparing the pull request.'
|
||||
),
|
||||
committed: committed.committed,
|
||||
status: currentStatus
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { RpcSendParams } from '../transport/rpc-params-contract'
|
||||
import {
|
||||
hostReplyErrorTextOrFallback,
|
||||
@@ -30,7 +31,13 @@ export async function readMobileHostedReviewGitStatus(
|
||||
} catch (error) {
|
||||
return {
|
||||
ok: false,
|
||||
error: refusedRpcMessageOrFallback(error, 'Unable to refresh source control')
|
||||
error: refusedRpcMessageOrFallback(
|
||||
error,
|
||||
translate(
|
||||
'sourceControl.hostedReviewGitPreparation.refreshFailed',
|
||||
'Unable to refresh source control'
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,7 +89,10 @@ export function fastForwardMobileHostedReviewBranch(
|
||||
return settleMobileHostedReviewMutation(
|
||||
() => gitFastForwardRun.request(client, { worktree: `id:${worktreeId}` }),
|
||||
(reply) => gitFastForwardRun.interpret(reply),
|
||||
'Could not update the remote branch. Retry Create PR.'
|
||||
translate(
|
||||
'sourceControl.hostedReviewGitPreparation.updateBranchFailed',
|
||||
'Could not update the remote branch. Retry Create PR.'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -94,7 +104,7 @@ export function stageMobileHostedReviewPaths(
|
||||
return settleMobileHostedReviewMutation(
|
||||
() => gitBulkStageRun.request(client, { worktree: `id:${worktreeId}`, filePaths }),
|
||||
(reply) => gitBulkStageRun.interpret(reply),
|
||||
'Failed to stage changes'
|
||||
translate('sourceControl.hostedReviewGitPreparation.stageFailed', 'Failed to stage changes')
|
||||
)
|
||||
}
|
||||
|
||||
@@ -107,16 +117,34 @@ export async function commitMobileHostedReviewStagedChanges(
|
||||
try {
|
||||
reply = await gitCommitRun.request(client, { worktree: `id:${worktreeId}`, message })
|
||||
} catch (error) {
|
||||
return { ok: false, error: error instanceof Error ? error.message : 'Commit failed' }
|
||||
return {
|
||||
ok: false,
|
||||
error:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: translate('sourceControl.hostedReviewGitPreparation.commitFailed', 'Commit failed')
|
||||
}
|
||||
}
|
||||
let outcome: ReturnType<typeof gitCommitRun.interpret>
|
||||
try {
|
||||
outcome = gitCommitRun.interpret(reply)
|
||||
} catch (error) {
|
||||
return { ok: false, error: refusedRpcMessageOrFallback(error, 'Commit failed') }
|
||||
return {
|
||||
ok: false,
|
||||
error: refusedRpcMessageOrFallback(
|
||||
error,
|
||||
translate('sourceControl.hostedReviewGitPreparation.commitFailed', 'Commit failed')
|
||||
)
|
||||
}
|
||||
}
|
||||
// Acceptance can still carry an in-band commit failure.
|
||||
return outcome.success === true
|
||||
? { ok: true }
|
||||
: { ok: false, error: hostReplyErrorTextOrFallback(outcome.error, 'Commit failed') }
|
||||
: {
|
||||
ok: false,
|
||||
error: hostReplyErrorTextOrFallback(
|
||||
outcome.error,
|
||||
translate('sourceControl.hostedReviewGitPreparation.commitFailed', 'Commit failed')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { resolveCreatePrIntentRemoteStep } from '../../../src/shared/source-control-create-review-intent'
|
||||
import type { MobileGitStatusResult } from './mobile-git-status'
|
||||
import type { MobileHostedReviewCreateIntentProgress } from './mobile-hosted-review-create-intent'
|
||||
@@ -50,19 +51,32 @@ export async function applyMobileHostedReviewRemotePrerequisite(
|
||||
result = await pushMobileHostedReviewBranch(
|
||||
client,
|
||||
{ worktree, publish: true },
|
||||
'Failed to publish branch'
|
||||
translate(
|
||||
'sourceControl.hostedReviewRemotePrerequisite.publishFailed',
|
||||
'Failed to publish branch'
|
||||
)
|
||||
)
|
||||
break
|
||||
case 'push':
|
||||
input.onProgress?.('pushing')
|
||||
result = await pushMobileHostedReviewBranch(client, { worktree }, 'Failed to push commits')
|
||||
result = await pushMobileHostedReviewBranch(
|
||||
client,
|
||||
{ worktree },
|
||||
translate(
|
||||
'sourceControl.hostedReviewRemotePrerequisite.pushFailed',
|
||||
'Failed to push commits'
|
||||
)
|
||||
)
|
||||
break
|
||||
case 'force_push':
|
||||
input.onProgress?.('force_pushing')
|
||||
result = await pushMobileHostedReviewBranch(
|
||||
client,
|
||||
{ worktree, forceWithLease: true },
|
||||
'Failed to force push with lease'
|
||||
translate(
|
||||
'sourceControl.hostedReviewRemotePrerequisite.forcePushFailed',
|
||||
'Failed to force push with lease'
|
||||
)
|
||||
)
|
||||
break
|
||||
case 'fast_forward':
|
||||
|
||||
@@ -162,19 +162,17 @@ export type MobileHostedReviewCreateOutcome =
|
||||
| { ok: true; url: string; number?: number; existing?: boolean; linkError?: string }
|
||||
| { ok: false; error: string }
|
||||
|
||||
const PUSH_BEFORE_CREATE_ERROR = 'Push failed. Resolve the push error, then try again.'
|
||||
|
||||
// The form intentionally uses one actionable fallback for all push failures.
|
||||
async function pushMobileBranchBeforeCreate(
|
||||
client: RpcOperationSender,
|
||||
worktreeId: string
|
||||
): Promise<{ ok: true } | { ok: false; error: string }> {
|
||||
const pushed = await pushMobileHostedReviewBranch(
|
||||
client,
|
||||
{ worktree: `id:${worktreeId}` },
|
||||
PUSH_BEFORE_CREATE_ERROR
|
||||
const error = translate(
|
||||
'sourceControl.hostedReviewService.pushBeforeCreateFailed',
|
||||
'Push failed. Resolve the push error, then try again.'
|
||||
)
|
||||
return pushed.ok ? { ok: true } : { ok: false, error: PUSH_BEFORE_CREATE_ERROR }
|
||||
const pushed = await pushMobileHostedReviewBranch(client, { worktree: `id:${worktreeId}` }, error)
|
||||
return pushed.ok ? { ok: true } : { ok: false, error }
|
||||
}
|
||||
|
||||
function formatMobileHostedReviewCreateError(
|
||||
@@ -244,7 +242,13 @@ export async function createMobileHostedReview(
|
||||
} catch (error) {
|
||||
return {
|
||||
ok: false,
|
||||
error: refusedRpcMessageOrFallback(error, 'Failed to create pull request')
|
||||
error: refusedRpcMessageOrFallback(
|
||||
error,
|
||||
translate(
|
||||
'sourceControl.hostedReviewService.createFailed',
|
||||
'Failed to create pull request'
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
if (result.ok) {
|
||||
@@ -271,13 +275,19 @@ export async function createMobileHostedReview(
|
||||
ok: false,
|
||||
error:
|
||||
formatMobileHostedReviewCreateError(result, pushed, input.provider) ||
|
||||
'Failed to create pull request'
|
||||
translate('sourceControl.hostedReviewService.createFailed', 'Failed to create pull request')
|
||||
}
|
||||
} catch (err) {
|
||||
// Inline creation must display transport errors instead of leaking rejected promises.
|
||||
return {
|
||||
ok: false,
|
||||
error: err instanceof Error ? err.message : 'Failed to create pull request'
|
||||
error:
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate(
|
||||
'sourceControl.hostedReviewService.createFailed',
|
||||
'Failed to create pull request'
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { RpcSendParams } from '../transport/rpc-params-contract'
|
||||
import { CLEARED_HOSTED_REVIEW_SELECTION_UPDATES } from '../../../src/shared/worktree/hosted-review-links'
|
||||
import { refusedRpcMessageOrFallback } from '../transport/rpc-refusal-message'
|
||||
@@ -79,7 +80,10 @@ export function linkMobilePr(
|
||||
return setWorktreeReviewLink(
|
||||
client,
|
||||
buildWorktreeSetLinkParams(worktreeId, prNumber),
|
||||
'Failed to update linked pull request'
|
||||
translate(
|
||||
'sourceControl.prLink.updatePullRequestFailed',
|
||||
'Failed to update linked pull request'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -95,7 +99,11 @@ export async function linkMobileHostedReview(
|
||||
return { ok: true }
|
||||
}
|
||||
// Link refresh failure is nonfatal: the review already exists, so keep its URL.
|
||||
return setWorktreeReviewLink(client, params, 'Failed to update linked review')
|
||||
return setWorktreeReviewLink(
|
||||
client,
|
||||
params,
|
||||
translate('sourceControl.prLink.updateReviewFailed', 'Failed to update linked review')
|
||||
)
|
||||
}
|
||||
|
||||
// Like desktop, suppress the unlinked PR so branch discovery does not bring it straight back.
|
||||
@@ -107,7 +115,10 @@ export function unlinkMobilePr(
|
||||
return setWorktreeReviewLink(
|
||||
client,
|
||||
{ ...buildWorktreeSetLinkParams(worktreeId, null), suppressedGitHubPR: prNumber },
|
||||
'Failed to update linked pull request'
|
||||
translate(
|
||||
'sourceControl.prLink.updatePullRequestFailed',
|
||||
'Failed to update linked pull request'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -131,7 +142,10 @@ export async function clearMobileWorktreeReviewLink(
|
||||
await setWorktreeReviewLink(
|
||||
client,
|
||||
{ worktree: `id:${worktreeId}`, ...CLEARED_HOSTED_REVIEW_SELECTION_UPDATES },
|
||||
'Failed to update linked pull request'
|
||||
translate(
|
||||
'sourceControl.prLink.updatePullRequestFailed',
|
||||
'Failed to update linked pull request'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { translate, type Translate } from '../i18n/mobile-i18n'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { Translate } from '../i18n/mobile-i18n'
|
||||
import { mobileCommitDropdownCopy } from './mobile-commit-dropdown-copy'
|
||||
import { mobileRemoteDropdownCopy } from './mobile-remote-dropdown-copy'
|
||||
import type { GitConflictOperation } from '../../../src/shared/git-status-types'
|
||||
@@ -6,6 +7,7 @@ import { deriveDropdownActionContext } from '../../../src/shared/source-control-
|
||||
import { buildCommitDropdownItems } from '../../../src/shared/source-control-dropdown-commit-items'
|
||||
import type { DropdownItem } from '../../../src/shared/source-control-dropdown-item-types'
|
||||
import { buildRemoteDropdownItems } from '../../../src/shared/source-control-dropdown-remote-items'
|
||||
import type { SourceControlCommitAreaPrimaryActionDecision } from '../../../src/shared/source-control-primary-action-decision'
|
||||
import type { SourceControlPrimaryActionDecisionInputs } from '../../../src/shared/source-control-primary-action-decision-types'
|
||||
|
||||
// String identifiers keep native lucide imports out of this module.
|
||||
@@ -155,3 +157,100 @@ export function buildMobileSourceControlActions(
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export function getMobilePrimaryActionHint(
|
||||
decision: SourceControlCommitAreaPrimaryActionDecision
|
||||
): string {
|
||||
switch (decision.titleIntent) {
|
||||
case 'commit_in_progress':
|
||||
return translate('sourceControl.actions.committing', 'Commit in progress.')
|
||||
case 'force_push_in_progress':
|
||||
return translate('sourceControl.actions.forcePushing', 'Force push in progress.')
|
||||
case 'action_in_progress':
|
||||
case 'remote_operation_in_progress':
|
||||
return translate(
|
||||
'sourceControl.actions.remoteOperationInProgress',
|
||||
'Remote operation in progress.'
|
||||
)
|
||||
case 'remote_operation_blocks_commit':
|
||||
return translate(
|
||||
'sourceControl.actions.waitForRemoteOperation',
|
||||
'Try again once the remote operation finishes.'
|
||||
)
|
||||
case 'resolve_conflicts_before_commit':
|
||||
return translate(
|
||||
'sourceControl.actions.resolveConflicts',
|
||||
'Resolve conflicts before committing.'
|
||||
)
|
||||
case 'commit_staged_changes':
|
||||
return translate('sourceControl.actions.commitStagedChanges', 'Commit staged changes.')
|
||||
case 'enter_commit_message':
|
||||
return translate(
|
||||
'sourceControl.actions.enterCommitMessage',
|
||||
'Enter a commit message to commit.'
|
||||
)
|
||||
case 'stage_all_changes':
|
||||
return translate('sourceControl.actions.stageAllChanges', 'Stage all changes.')
|
||||
case 'stage_file_to_commit':
|
||||
return translate(
|
||||
'sourceControl.actions.stageFileToCommit',
|
||||
'Stage at least one file to commit.'
|
||||
)
|
||||
case 'checkout_branch_before_publish':
|
||||
return translate(
|
||||
'sourceControl.actions.checkoutBeforePublish',
|
||||
'Check out a branch before publishing commits.'
|
||||
)
|
||||
case 'checking_review_status':
|
||||
return translate('sourceControl.actions.checkingReviewStatus', 'Checking review status.')
|
||||
case 'review_already_merged':
|
||||
return translate(
|
||||
'sourceControl.actions.reviewAlreadyMerged',
|
||||
'Nothing to commit. The review is already merged.'
|
||||
)
|
||||
case 'publish_branch':
|
||||
return translate('sourceControl.actions.publishToOrigin', 'Publish this branch to origin.')
|
||||
case 'push_linked_review':
|
||||
return translate(
|
||||
'sourceControl.actions.pushLinkedReview',
|
||||
'Push updates to the linked review branch.'
|
||||
)
|
||||
case 'linked_review_target_unavailable':
|
||||
return translate(
|
||||
'sourceControl.actions.linkedReviewUnavailable',
|
||||
'The linked review branch is unavailable.'
|
||||
)
|
||||
case 'force_push_with_lease':
|
||||
return translate(
|
||||
'sourceControl.actions.forcePushWithLease',
|
||||
'Force push with lease to update the remote branch.'
|
||||
)
|
||||
case 'sync_counts':
|
||||
return translate('sourceControl.actions.syncCounts', 'Pull {{behind}}, push {{ahead}}.', {
|
||||
behind: decision.behind ?? 0,
|
||||
ahead: decision.ahead ?? 0
|
||||
})
|
||||
case 'pull_count': {
|
||||
const count = decision.count ?? 0
|
||||
return count === 1
|
||||
? translate('sourceControl.actions.pullCommits_one', 'Pull {{count}} commit.', {
|
||||
count
|
||||
})
|
||||
: translate('sourceControl.actions.pullCommits_other', 'Pull {{count}} commits.', {
|
||||
count
|
||||
})
|
||||
}
|
||||
case 'push_count': {
|
||||
const count = decision.count ?? 0
|
||||
return count === 1
|
||||
? translate('sourceControl.actions.pushCommits_one', 'Push {{count}} commit.', {
|
||||
count
|
||||
})
|
||||
: translate('sourceControl.actions.pushCommits_other', 'Push {{count}} commits.', {
|
||||
count
|
||||
})
|
||||
}
|
||||
case 'nothing_to_commit_up_to_date':
|
||||
return translate('sourceControl.actions.upToDate', 'Nothing to commit. Branch is up to date.')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
export function isMobileConflictAborting(
|
||||
busyAction: string | null,
|
||||
conflictOperation: string | null
|
||||
@@ -9,5 +11,17 @@ export function isMobileConflictAborting(
|
||||
}
|
||||
|
||||
export function mobileConflictAbortLabel(conflictOperation: string, aborting: boolean): string {
|
||||
return aborting ? 'Aborting…' : `Abort ${conflictOperation}`
|
||||
if (aborting) {
|
||||
return translate('sourceControl.conflictAbort.aborting', 'Aborting…')
|
||||
}
|
||||
switch (conflictOperation) {
|
||||
case 'merge':
|
||||
return translate('sourceControl.conflictAbort.abortMerge', 'Abort merge')
|
||||
case 'rebase':
|
||||
return translate('sourceControl.conflictAbort.abortRebase', 'Abort rebase')
|
||||
default:
|
||||
return translate('sourceControl.conflictAbort.abortOperation', 'Abort {{operation}}', {
|
||||
operation: conflictOperation
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
export type SourceControlHubTab = 'changes' | 'pr' | 'history'
|
||||
|
||||
export const SOURCE_CONTROL_HUB_TABS: readonly SourceControlHubTab[] = [
|
||||
@@ -7,9 +9,15 @@ export const SOURCE_CONTROL_HUB_TABS: readonly SourceControlHubTab[] = [
|
||||
] as const
|
||||
|
||||
export const SOURCE_CONTROL_HUB_TAB_LABELS: Record<SourceControlHubTab, string> = {
|
||||
changes: 'Changes',
|
||||
pr: 'Pull Request',
|
||||
history: 'Commits'
|
||||
get changes() {
|
||||
return translate('sourceControl.hubTab.changes', 'Changes')
|
||||
},
|
||||
get pr() {
|
||||
return translate('sourceControl.hubTab.pullRequest', 'Pull Request')
|
||||
},
|
||||
get history() {
|
||||
return translate('sourceControl.hubTab.commits', 'Commits')
|
||||
}
|
||||
}
|
||||
|
||||
export function parseSourceControlHubTab(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { getMobilePrimaryActionHint } from './mobile-source-control-actions'
|
||||
import { getMobileForcePushBlockedReason } from './mobile-source-control-review-copy'
|
||||
import type { SourceControlPrimaryActionDecisionInputs } from '../../../src/shared/source-control-primary-action-decision-types'
|
||||
import {
|
||||
@@ -197,67 +199,21 @@ export function getMobileBranchCommitsAhead(
|
||||
|
||||
function getMobilePrimaryActionLabel(decision: MobileSourceControlPrimaryActionDecision): string {
|
||||
if (decision.requiresForceWithLease) {
|
||||
return 'Force Push'
|
||||
return translate('sourceControl.primaryAction.forcePush', 'Force Push')
|
||||
}
|
||||
switch (decision.kind) {
|
||||
case 'commit':
|
||||
return 'Commit'
|
||||
return translate('sourceControl.primaryAction.commit', 'Commit')
|
||||
case 'stage':
|
||||
return 'Stage All'
|
||||
return translate('sourceControl.primaryAction.stageAll', 'Stage All')
|
||||
case 'push':
|
||||
return 'Push'
|
||||
return translate('sourceControl.primaryAction.push', 'Push')
|
||||
case 'pull':
|
||||
return 'Pull'
|
||||
return translate('sourceControl.primaryAction.pull', 'Pull')
|
||||
case 'sync':
|
||||
return 'Sync'
|
||||
return translate('sourceControl.primaryAction.sync', 'Sync')
|
||||
case 'publish':
|
||||
return 'Publish Branch'
|
||||
}
|
||||
}
|
||||
|
||||
function getMobilePrimaryActionHint(decision: MobileSourceControlPrimaryActionDecision): string {
|
||||
switch (decision.titleIntent) {
|
||||
case 'commit_in_progress':
|
||||
return 'Commit in progress.'
|
||||
case 'force_push_in_progress':
|
||||
return 'Force push in progress.'
|
||||
case 'action_in_progress':
|
||||
case 'remote_operation_in_progress':
|
||||
return 'Remote operation in progress.'
|
||||
case 'remote_operation_blocks_commit':
|
||||
return 'Try again once the remote operation finishes.'
|
||||
case 'resolve_conflicts_before_commit':
|
||||
return 'Resolve conflicts before committing.'
|
||||
case 'commit_staged_changes':
|
||||
return 'Commit staged changes.'
|
||||
case 'enter_commit_message':
|
||||
return 'Enter a commit message to commit.'
|
||||
case 'stage_all_changes':
|
||||
return 'Stage all changes.'
|
||||
case 'stage_file_to_commit':
|
||||
return 'Stage at least one file to commit.'
|
||||
case 'checkout_branch_before_publish':
|
||||
return 'Check out a branch before publishing commits.'
|
||||
case 'checking_review_status':
|
||||
return 'Checking review status.'
|
||||
case 'review_already_merged':
|
||||
return 'Nothing to commit. The review is already merged.'
|
||||
case 'publish_branch':
|
||||
return 'Publish this branch to origin.'
|
||||
case 'push_linked_review':
|
||||
return 'Push updates to the linked review branch.'
|
||||
case 'linked_review_target_unavailable':
|
||||
return 'The linked review branch is unavailable.'
|
||||
case 'force_push_with_lease':
|
||||
return 'Force push with lease to update the remote branch.'
|
||||
case 'sync_counts':
|
||||
return `Pull ${decision.behind ?? 0}, push ${decision.ahead ?? 0}.`
|
||||
case 'pull_count':
|
||||
return `Pull ${decision.count ?? 0} commit${decision.count === 1 ? '' : 's'}.`
|
||||
case 'push_count':
|
||||
return `Push ${decision.count ?? 0} commit${decision.count === 1 ? '' : 's'}.`
|
||||
case 'nothing_to_commit_up_to_date':
|
||||
return 'Nothing to commit. Branch is up to date.'
|
||||
return translate('sourceControl.primaryAction.publishBranch', 'Publish Branch')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
ArrowDown,
|
||||
ArrowDownUp,
|
||||
@@ -130,7 +131,7 @@ export function formatBranchLabel(branch: string | undefined, head: string | und
|
||||
if (branch?.startsWith('refs/heads/')) {
|
||||
return branch.slice('refs/heads/'.length)
|
||||
}
|
||||
return branch || head?.slice(0, 7) || 'No branch'
|
||||
return branch || head?.slice(0, 7) || translate('sourceControl.screenState.noBranch', 'No branch')
|
||||
}
|
||||
|
||||
export function statusColor(status: MobileGitFileStatus): string {
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { useMemo } from 'react'
|
||||
import type { SourceControlGroupOrder } from '../../../src/shared/ui-chrome-types'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { buildMobileSourceControlSections, type MobileGitStatusEntry } from './mobile-git-status'
|
||||
|
||||
export function useMobileSourceControlSections<TEntry extends MobileGitStatusEntry>(
|
||||
entries: readonly TEntry[],
|
||||
groupOrder: SourceControlGroupOrder
|
||||
) {
|
||||
return useMemo(() => buildMobileSourceControlSections(entries, groupOrder), [entries, groupOrder])
|
||||
// Section titles are translated inside the builder.
|
||||
const t = useMobileTranslation()
|
||||
return useMemo(
|
||||
() => buildMobileSourceControlSections(entries, groupOrder),
|
||||
[entries, groupOrder, t]
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import type { ConnectionState } from '../transport/types'
|
||||
import type { RpcClient } from '../transport/rpc-client'
|
||||
import { triggerError, triggerSuccess } from '../platform/haptics'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { useHostProtocolGates } from '../components/host-protocol-gates-context'
|
||||
import { launchAgentWithPrompt, promptedLaunchNotice } from '../session/pr-ai-triage-launch'
|
||||
import { resolveMobileAgentLaunchAvailability } from '../session/mobile-agent-launch-availability'
|
||||
@@ -79,7 +80,12 @@ export function useMobileCommitFailureRecovery({
|
||||
return false
|
||||
}
|
||||
if (!client || connState !== 'connected') {
|
||||
setLaunchError('Waiting for desktop...')
|
||||
setLaunchError(
|
||||
translate(
|
||||
'sourceControl.useMobileCommitFailureRecovery.waitingForDesktop',
|
||||
'Waiting for desktop...'
|
||||
)
|
||||
)
|
||||
triggerError()
|
||||
return false
|
||||
}
|
||||
@@ -113,7 +119,14 @@ export function useMobileCommitFailureRecovery({
|
||||
return notice.succeeded
|
||||
} catch (err) {
|
||||
triggerError()
|
||||
setLaunchError(err instanceof Error ? err.message : 'Failed to launch agent')
|
||||
setLaunchError(
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate(
|
||||
'sourceControl.useMobileCommitFailureRecovery.launchFailed',
|
||||
'Failed to launch agent'
|
||||
)
|
||||
)
|
||||
return false
|
||||
} finally {
|
||||
inFlightRef.current = false
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from 'react'
|
||||
import type { RpcClient } from '../transport/rpc-client'
|
||||
import { triggerError, triggerSuccess } from '../platform/haptics'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { cancelMobileCommitMessage, requestMobileCommitMessage } from './mobile-commit-message-ai'
|
||||
|
||||
type Params = {
|
||||
@@ -70,7 +71,14 @@ export function useMobileCommitMessageGeneration(params: Params) {
|
||||
// Catch transport drops because callers void this handler; retain error feedback.
|
||||
if (mountedRef.current && run === runRef.current) {
|
||||
triggerError()
|
||||
setActionError(err instanceof Error ? err.message : 'Failed to generate commit message')
|
||||
setActionError(
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate(
|
||||
'sourceControl.useMobileCommitMessageGeneration.generateFailed',
|
||||
'Failed to generate commit message'
|
||||
)
|
||||
)
|
||||
}
|
||||
} finally {
|
||||
if (activeRunRef.current === run) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useCallback, useEffect, useRef, type MutableRefObject } from 'react'
|
||||
import type { RpcClient } from '../transport/rpc-client'
|
||||
import { triggerError } from '../platform/haptics'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { MobileGitStatusResult } from './mobile-git-status'
|
||||
import type { LoadStatusOptions } from './mobile-source-control-screen-state'
|
||||
import {
|
||||
@@ -68,7 +69,12 @@ export function useMobileCreatePrRunner({
|
||||
const branch = status?.branch
|
||||
if (!client || !branch) {
|
||||
triggerError()
|
||||
setActionError('Check out a branch before creating a pull request.')
|
||||
setActionError(
|
||||
translate(
|
||||
'sourceControl.useMobileCreatePrRunner.branchRequired',
|
||||
'Check out a branch before creating a pull request.'
|
||||
)
|
||||
)
|
||||
return
|
||||
}
|
||||
const created: { current: MobileHostedReviewCreateIntentRunOutcome | null } = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useCallback } from 'react'
|
||||
import type { ConnectionState, RpcSuccess } from '../transport/types'
|
||||
import type { RpcClient } from '../transport/rpc-client'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
isMobileGitUnavailable,
|
||||
type MobileGitStatusResult,
|
||||
@@ -18,16 +19,25 @@ export function useMobileGitRequests({ client, connState, worktreeId }: Params)
|
||||
const sendGitRequest = useCallback(
|
||||
async <T>(method: string, params?: Record<string, unknown>): Promise<T> => {
|
||||
if (!client || connState !== 'connected') {
|
||||
throw new Error('Waiting for desktop...')
|
||||
throw new Error(
|
||||
translate(
|
||||
'sourceControl.useMobileGitRequests.waitingForDesktop',
|
||||
'Waiting for desktop...'
|
||||
)
|
||||
)
|
||||
}
|
||||
const response = await client.sendRequest(method, {
|
||||
worktree: `id:${worktreeId}`,
|
||||
...params
|
||||
})
|
||||
if (!response.ok) {
|
||||
const error = new Error(
|
||||
response.error?.message || 'Source control action failed'
|
||||
) as GitRequestError
|
||||
const error: GitRequestError = new Error(
|
||||
response.error?.message ||
|
||||
translate(
|
||||
'sourceControl.useMobileGitRequests.actionFailed',
|
||||
'Source control action failed'
|
||||
)
|
||||
)
|
||||
error.code = response.error?.code
|
||||
throw error
|
||||
}
|
||||
@@ -40,7 +50,10 @@ export function useMobileGitRequests({ client, connState, worktreeId }: Params)
|
||||
async (message: string): Promise<GitCommitResult> => {
|
||||
const result = await sendGitRequest<GitCommitResult>('git.commit', { message })
|
||||
if (!result || result.success !== true) {
|
||||
throw new Error(result?.error || 'Commit failed')
|
||||
throw new Error(
|
||||
result?.error ||
|
||||
translate('sourceControl.useMobileGitRequests.commitFailed', 'Commit failed')
|
||||
)
|
||||
}
|
||||
return result
|
||||
},
|
||||
@@ -58,7 +71,12 @@ export function useMobileGitRequests({ client, connState, worktreeId }: Params)
|
||||
}
|
||||
const status = await sendGitRequest<MobileGitStatusResult>('git.status')
|
||||
if (!status.upstreamStatus) {
|
||||
throw new Error('Branch status unavailable')
|
||||
throw new Error(
|
||||
translate(
|
||||
'sourceControl.useMobileGitRequests.branchUnavailable',
|
||||
'Branch status unavailable'
|
||||
)
|
||||
)
|
||||
}
|
||||
return status.upstreamStatus
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback } from 'react'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { RpcClient } from '../transport/rpc-client'
|
||||
|
||||
type GitStep = { method: string; params?: Record<string, unknown> }
|
||||
@@ -66,10 +67,20 @@ export function useMobileSourceControlActionSheetRunners(params: Params) {
|
||||
async (baseRef: string | null) => {
|
||||
await runGitWorkflow('rebase', async () => {
|
||||
if (!client) {
|
||||
throw new Error('Waiting for desktop...')
|
||||
throw new Error(
|
||||
translate(
|
||||
'sourceControl.actionSheetRunners.waitingForDesktop',
|
||||
'Waiting for desktop...'
|
||||
)
|
||||
)
|
||||
}
|
||||
if (!baseRef) {
|
||||
throw new Error('No base branch to rebase onto')
|
||||
throw new Error(
|
||||
translate(
|
||||
'sourceControl.actionSheetRunners.noBaseBranch',
|
||||
'No base branch to rebase onto'
|
||||
)
|
||||
)
|
||||
}
|
||||
await sendGitRequest<unknown>('git.rebaseFromBase', { baseRef })
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback, type MutableRefObject } from 'react'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { triggerError, triggerSuccess } from '../platform/haptics'
|
||||
import type { LoadStatusOptions } from './mobile-source-control-screen-state'
|
||||
import type {
|
||||
@@ -69,7 +70,10 @@ export function useMobileSourceControlCommitRunners(params: Params) {
|
||||
await sendCommitRequest(message)
|
||||
} catch (err) {
|
||||
recordCommitFailure({
|
||||
error: err instanceof Error ? err.message : 'Commit failed',
|
||||
error:
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate('sourceControl.commitRunners.commitFailed', 'Commit failed'),
|
||||
commitMessage: message,
|
||||
stagedEntries
|
||||
})
|
||||
@@ -110,7 +114,10 @@ export function useMobileSourceControlCommitRunners(params: Params) {
|
||||
return false
|
||||
}
|
||||
triggerError()
|
||||
const errorMessage = err instanceof Error ? err.message : 'Source control action failed'
|
||||
const errorMessage =
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate('sourceControl.commitRunners.actionFailed', 'Source control action failed')
|
||||
if (!didCommit) {
|
||||
recordCommitFailure({ error: errorMessage, commitMessage: message, stagedEntries })
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useRef, useState, type MutableRefObject } from 'react'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { MobileSourceControlSettings } from '../transport/settings-read-operations'
|
||||
import { useMobileSourceControlSettings } from './mobile-source-control-settings'
|
||||
import { useFocusEffect } from 'expo-router'
|
||||
@@ -168,7 +169,12 @@ export function useMobileSourceControlLoaders(params: Params): MobileSourceContr
|
||||
setScreenState({
|
||||
kind: 'error',
|
||||
message:
|
||||
connState === 'connected' ? 'Connecting to desktop...' : 'Waiting for desktop...'
|
||||
connState === 'connected'
|
||||
? translate(
|
||||
'sourceControl.loaders.connectingToDesktop',
|
||||
'Connecting to desktop...'
|
||||
)
|
||||
: translate('sourceControl.loaders.waitingForDesktop', 'Waiting for desktop...')
|
||||
})
|
||||
}
|
||||
return false
|
||||
@@ -204,7 +210,10 @@ export function useMobileSourceControlLoaders(params: Params): MobileSourceContr
|
||||
if (isMobileGitUnavailableReply(reply)) {
|
||||
setScreenState({
|
||||
kind: 'unavailable',
|
||||
message: 'Update Orca desktop to use Source Control on mobile.'
|
||||
message: translate(
|
||||
'sourceControl.loaders.updateDesktop',
|
||||
'Update Orca desktop to use Source Control on mobile.'
|
||||
)
|
||||
})
|
||||
return false
|
||||
}
|
||||
@@ -218,13 +227,19 @@ export function useMobileSourceControlLoaders(params: Params): MobileSourceContr
|
||||
}
|
||||
continue
|
||||
}
|
||||
throw new Error(refusal.message || 'Unable to load source control')
|
||||
throw new Error(
|
||||
refusal.message ||
|
||||
translate('sourceControl.loaders.loadFailed', 'Unable to load source control')
|
||||
)
|
||||
}
|
||||
} catch (err) {
|
||||
if (!isCurrentLoad()) {
|
||||
return false
|
||||
}
|
||||
const message = err instanceof Error ? err.message : 'Unable to load source control'
|
||||
const message =
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate('sourceControl.loaders.loadFailed', 'Unable to load source control')
|
||||
setScreenState((prev) => {
|
||||
// Mutations can succeed while refresh races an abort; retain the last good screen through transient read failure.
|
||||
if (options?.preserveReadyOnFailure && prev.kind === 'ready') {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useRef, useState, type MutableRefObject } from 'react'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { useWorkspaceRouteHandoff } from '../navigation/workspace-route-handoff'
|
||||
import type { RpcClient } from '../transport/rpc-client'
|
||||
import { isRendererUnavailableReply } from '../transport/renderer-unavailable-reply'
|
||||
@@ -87,7 +88,9 @@ export function useMobileSourceControlOpeners(params: Params) {
|
||||
if (!mountedRef.current) {
|
||||
return
|
||||
}
|
||||
setActionError('Waiting for desktop...')
|
||||
setActionError(
|
||||
translate('sourceControl.openers.waitingForDesktop', 'Waiting for desktop...')
|
||||
)
|
||||
return
|
||||
}
|
||||
openingPathRef.current = entry.path
|
||||
@@ -127,7 +130,12 @@ export function useMobileSourceControlOpeners(params: Params) {
|
||||
sourceFileDiffOpenRun.interpret(diffReply)
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(refusedRpcMessageOrFallback(error, 'Unable to open diff'))
|
||||
throw new Error(
|
||||
refusedRpcMessageOrFallback(
|
||||
error,
|
||||
translate('sourceControl.openers.openDiffFailed', 'Unable to open diff')
|
||||
)
|
||||
)
|
||||
}
|
||||
if (!mountedRef.current) {
|
||||
return
|
||||
@@ -145,7 +153,12 @@ export function useMobileSourceControlOpeners(params: Params) {
|
||||
return
|
||||
}
|
||||
if (revealResult === 'timeout') {
|
||||
throw new Error("The file opened, but its tab isn't ready yet. Try again.")
|
||||
throw new Error(
|
||||
translate(
|
||||
'sourceControl.openers.tabNotReady',
|
||||
"The file opened, but its tab isn't ready yet. Try again."
|
||||
)
|
||||
)
|
||||
}
|
||||
triggerSelection()
|
||||
// Embedded panels dismiss their dock; route panels pop back to the activated diff, with Back as the unwired-dock fallback.
|
||||
@@ -159,7 +172,11 @@ export function useMobileSourceControlOpeners(params: Params) {
|
||||
return
|
||||
}
|
||||
triggerError()
|
||||
setActionError(err instanceof Error ? err.message : 'Unable to open diff')
|
||||
setActionError(
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate('sourceControl.openers.openDiffFailed', 'Unable to open diff')
|
||||
)
|
||||
} finally {
|
||||
if (openingPathRef.current === entry.path) {
|
||||
openingPathRef.current = null
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback, type Dispatch, type MutableRefObject, type SetStateAction } from 'react'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { RouteHandoff } from '../navigation/route-handoff'
|
||||
import type { RpcClient } from '../transport/rpc-client'
|
||||
import { triggerError, triggerSuccess } from '../platform/haptics'
|
||||
@@ -110,7 +111,8 @@ export function useMobileSourceControlRunners(params: Params) {
|
||||
return false
|
||||
}
|
||||
triggerError()
|
||||
setActionError(err instanceof Error ? err.message : 'Source control action failed')
|
||||
const text = translate('sourceControl.runners.actionFailed', 'Source control action failed')
|
||||
setActionError(err instanceof Error ? err.message : text)
|
||||
return false
|
||||
} finally {
|
||||
if (busyActionRef.current === actionId) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useMemo, useRef, useState } from 'react'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||
import { useForceReconnect } from '../transport/host-client-hooks'
|
||||
import { useWorkspaceClient } from '../transport/use-workspace-client'
|
||||
@@ -46,6 +47,7 @@ export type MobileSourceControlStateParams = {
|
||||
}
|
||||
|
||||
export function useMobileSourceControlState(params: MobileSourceControlStateParams) {
|
||||
const t = useMobileTranslation()
|
||||
const {
|
||||
hostId,
|
||||
worktreeId,
|
||||
@@ -123,7 +125,7 @@ export function useMobileSourceControlState(params: MobileSourceControlStatePara
|
||||
const branchCompareResult = branchCompareState.kind === 'ready' ? branchCompareState.result : null
|
||||
const branchCompareSection = useMemo(
|
||||
() => buildMobileBranchCompareSection(branchCompareResult?.entries ?? []),
|
||||
[branchCompareResult]
|
||||
[branchCompareResult, t]
|
||||
)
|
||||
const branchCompareSummaryText = branchCompareResult
|
||||
? formatMobileBranchCompareSummary(branchCompareResult.summary)
|
||||
@@ -162,9 +164,9 @@ export function useMobileSourceControlState(params: MobileSourceControlStatePara
|
||||
const upstreamKnown = upstream !== undefined
|
||||
const syncLabel =
|
||||
upstream && upstream.hasUpstream
|
||||
? `${upstream.ahead} ahead, ${upstream.behind} behind`
|
||||
? t('sourceControl.state.syncStatus', '{{ahead}} ahead, {{behind}} behind', upstream)
|
||||
: upstream && !upstream.hasUpstream
|
||||
? 'No upstream'
|
||||
? t('sourceControl.state.noUpstream', 'No upstream')
|
||||
: null
|
||||
|
||||
const { sendGitRequest, sendCommitRequest, runGitSyncSteps } = useMobileGitRequests({
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import {
|
||||
SafeAreaView,
|
||||
View,
|
||||
@@ -82,6 +83,7 @@ import { renderMobileTasksItemDetailDrawer } from './mobile-tasks-item-detail-dr
|
||||
|
||||
export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentationModel }) {
|
||||
const colorScheme = useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
const {
|
||||
error,
|
||||
githubMode,
|
||||
@@ -126,8 +128,11 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
style={styles.sourceNoticeBanner}
|
||||
>
|
||||
<Text style={styles.sourceNoticeText}>
|
||||
Preferred issue source upstream is unavailable for {fallback.repoLabel}. Using
|
||||
origin.
|
||||
{t(
|
||||
'tasks.legacySurface.sourceFallback',
|
||||
'Preferred issue source upstream is unavailable for {{repo}}. Using origin.',
|
||||
{ repo: fallback.repoLabel }
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
))
|
||||
@@ -136,6 +141,11 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
{!error && provider === 'github' && githubMode === 'items'
|
||||
? githubSourceErrors.map((sourceError) => {
|
||||
const isRetrying = retryingGithubSourceRepoPaths.has(sourceError.repoPath)
|
||||
const sourceErrorParts = t(
|
||||
'tasks.legacySurface.loadIssuesFailed',
|
||||
"Couldn't load issues from {{source}}.",
|
||||
{ source: '\uFFFC' }
|
||||
).split('\uFFFC')
|
||||
return (
|
||||
<View
|
||||
key={`github-source-error:${sourceError.repoId}:${sourceError.source.owner}/${sourceError.source.repo}`}
|
||||
@@ -143,11 +153,11 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
>
|
||||
<View style={styles.sourceErrorCopy}>
|
||||
<Text style={styles.sourceErrorText}>
|
||||
Couldn't load issues from{' '}
|
||||
{sourceErrorParts[0]}
|
||||
<Text style={styles.sourceErrorSlug}>
|
||||
{sourceError.source.owner}/{sourceError.source.repo}
|
||||
</Text>
|
||||
.
|
||||
{sourceErrorParts.slice(1).join('')}
|
||||
</Text>
|
||||
<Text style={styles.sourceErrorMessage} numberOfLines={2}>
|
||||
{sourceError.message}
|
||||
@@ -155,13 +165,19 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
</View>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`Retry loading issues from ${sourceError.source.owner}/${sourceError.source.repo}`}
|
||||
accessibilityLabel={t(
|
||||
'tasks.legacySurface.retryLoadingIssues',
|
||||
'Retry loading issues from {{source}}',
|
||||
{ source: `${sourceError.source.owner}/${sourceError.source.repo}` }
|
||||
)}
|
||||
style={styles.sourceErrorRetry}
|
||||
disabled={loading || isRetrying}
|
||||
onPress={() => void retryGitHubIssueSourceFetch(sourceError.repoPath)}
|
||||
>
|
||||
<Text style={styles.sourceErrorRetryText}>
|
||||
{isRetrying ? 'Retrying...' : 'Retry'}
|
||||
{isRetrying
|
||||
? t('tasks.legacySurface.retrying', 'Retrying...')
|
||||
: t('common.retry', 'Retry')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
@@ -176,7 +192,10 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
<View style={styles.projectDataNotice}>
|
||||
<AlertTriangle size={15} color={colors.statusAmber} />
|
||||
<Text style={styles.projectDataNoticeText}>
|
||||
Sub-issue data is unavailable for your token.
|
||||
{t(
|
||||
'tasks.legacySurface.subIssueDataUnavailable',
|
||||
'Sub-issue data is unavailable for your token.'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
) : null}
|
||||
@@ -261,8 +280,11 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
|
||||
<ActionSheetModal
|
||||
visible={taskUiReady && mergeMethodProjectRow != null}
|
||||
title="Merge method"
|
||||
message="Choose how this pull request should be merged."
|
||||
title={t('tasks.legacySurface.mergeMethodTitle', 'Merge method')}
|
||||
message={t(
|
||||
'tasks.legacySurface.pullRequestMergeMessage',
|
||||
'Choose how this pull request should be merged.'
|
||||
)}
|
||||
actions={
|
||||
mergeMethodProjectRow
|
||||
? (['squash', 'merge', 'rebase'] as const).map((method) => ({
|
||||
@@ -278,11 +300,17 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
/>
|
||||
<ActionSheetModal
|
||||
visible={taskUiReady && mergeMethodTaskItem != null}
|
||||
title="Merge method"
|
||||
title={t('tasks.legacySurface.mergeMethodTitle', 'Merge method')}
|
||||
message={
|
||||
mergeMethodTaskItem?.provider === 'gitlab'
|
||||
? 'Choose how this merge request should be merged.'
|
||||
: 'Choose how this pull request should be merged.'
|
||||
? t(
|
||||
'tasks.legacySurface.mergeRequestMergeMessage',
|
||||
'Choose how this merge request should be merged.'
|
||||
)
|
||||
: t(
|
||||
'tasks.legacySurface.pullRequestMergeMessage',
|
||||
'Choose how this pull request should be merged.'
|
||||
)
|
||||
}
|
||||
actions={
|
||||
mergeMethodTaskItem
|
||||
@@ -292,7 +320,7 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
).map((method) => ({
|
||||
label:
|
||||
mergeMethodTaskItem.provider === 'gitlab' && method === 'merge'
|
||||
? 'Merge'
|
||||
? t('tasks.legacySurface.mergeAction', 'Merge')
|
||||
: getHostedReviewMergeMethodLabel(method),
|
||||
icon: GitBranch,
|
||||
onPress: () => {
|
||||
@@ -307,7 +335,9 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
<ConfirmModal
|
||||
visible={taskUiReady && pendingHostedMerge != null}
|
||||
title={
|
||||
pendingHostedMerge?.item.provider === 'gitlab' ? 'Merge Request' : 'Merge Pull Request'
|
||||
pendingHostedMerge?.item.provider === 'gitlab'
|
||||
? t('tasks.legacySurface.mergeRequestTitle', 'Merge Request')
|
||||
: t('tasks.legacySurface.mergePullRequestTitle', 'Merge Pull Request')
|
||||
}
|
||||
message={
|
||||
pendingHostedMerge ? getHostedMergeConfirmMessage(pendingHostedMerge) : undefined
|
||||
@@ -315,7 +345,7 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
confirmLabel={
|
||||
pendingHostedMerge
|
||||
? getHostedReviewMergeMethodLabel(pendingHostedMerge.method)
|
||||
: 'Merge'
|
||||
: t('tasks.legacySurface.mergeAction', 'Merge')
|
||||
}
|
||||
onConfirm={() => {
|
||||
if (!taskUiReady || !pendingHostedMerge) {
|
||||
@@ -327,7 +357,7 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
/>
|
||||
<ConfirmModal
|
||||
visible={taskUiReady && pendingProjectGitHubMerge != null}
|
||||
title="Merge Pull Request"
|
||||
title={t('tasks.legacySurface.mergePullRequestTitle', 'Merge Pull Request')}
|
||||
message={
|
||||
pendingProjectGitHubMerge
|
||||
? getProjectGitHubMergeConfirmMessage(pendingProjectGitHubMerge)
|
||||
@@ -336,7 +366,7 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
confirmLabel={
|
||||
pendingProjectGitHubMerge
|
||||
? getHostedReviewMergeMethodLabel(pendingProjectGitHubMerge.method)
|
||||
: 'Merge'
|
||||
: t('tasks.legacySurface.mergeAction', 'Merge')
|
||||
}
|
||||
onConfirm={() => {
|
||||
if (!taskUiReady || !pendingProjectGitHubMerge) {
|
||||
@@ -354,7 +384,7 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
title={
|
||||
pendingHostedStateChange
|
||||
? getHostedStateConfirmTitle(pendingHostedStateChange)
|
||||
: 'Update Item'
|
||||
: t('tasks.legacySurface.updateItemTitle', 'Update Item')
|
||||
}
|
||||
message={
|
||||
pendingHostedStateChange
|
||||
@@ -364,7 +394,7 @@ export function MobileTasksLegacySurface({ model }: { model: ConnectionPresentat
|
||||
confirmLabel={
|
||||
pendingHostedStateChange
|
||||
? getHostedStateConfirmLabel(pendingHostedStateChange)
|
||||
: 'Confirm'
|
||||
: t('common.confirm', 'Confirm')
|
||||
}
|
||||
destructive={pendingHostedStateChange?.nextState === 'closed'}
|
||||
onConfirm={() => {
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
import { MAX_RENDERED_PR_DIFF_LINES } from './mobile-tasks-options'
|
||||
import type { GitHubPRFileContents } from './mobile-tasks-provider-detail-types'
|
||||
import { styles } from './mobile-tasks-legacy-styles'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
|
||||
export function formatDiffLineNumber(value: number | undefined): string {
|
||||
return value === undefined ? ' ' : value.toString().padStart(4, ' ')
|
||||
@@ -47,6 +48,7 @@ export function GitHubPrFileDiff({
|
||||
onSubmitComment: (line: number) => void
|
||||
}): ReactNode {
|
||||
useMobileColorScheme()
|
||||
const t = useMobileTranslation()
|
||||
const diffPreview = useMemo(
|
||||
() =>
|
||||
buildGitHubPrFileDiffPreview(
|
||||
@@ -64,14 +66,25 @@ export function GitHubPrFileDiff({
|
||||
const hiddenDiffLineCount = Math.max(0, diffPreview.totalLineCount - visibleDiffLines.length)
|
||||
|
||||
if (diffPreview.totalLineCount === 0) {
|
||||
return <Text style={styles.detailMuted}>No text changes found.</Text>
|
||||
return (
|
||||
<Text style={styles.detailMuted}>
|
||||
{t('tasks.prFileDiff.noTextChanges', 'No text changes found.')}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.fileDiff}>
|
||||
{hiddenDiffLineCount > 0 ? (
|
||||
<Text style={styles.detailMuted}>
|
||||
Showing first {MAX_RENDERED_PR_DIFF_LINES} of {diffPreview.totalLineCount} diff lines.
|
||||
{t(
|
||||
'tasks.prFileDiff.showingDiffLines',
|
||||
'Showing first {{limit}} of {{total}} diff lines.',
|
||||
{
|
||||
limit: MAX_RENDERED_PR_DIFF_LINES,
|
||||
total: diffPreview.totalLineCount
|
||||
}
|
||||
)}
|
||||
</Text>
|
||||
) : null}
|
||||
{visibleDiffLines.map((line) => {
|
||||
@@ -115,7 +128,7 @@ export function GitHubPrFileDiff({
|
||||
style={[styles.input, styles.replyInput]}
|
||||
value={commentDrafts[draftKey] ?? ''}
|
||||
onChangeText={(next) => onCommentDraftChange(draftKey, next)}
|
||||
placeholder="Add review comment"
|
||||
placeholder={t('tasks.prFileDiff.commentPlaceholder', 'Add review comment')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
multiline
|
||||
textAlignVertical="top"
|
||||
@@ -125,7 +138,11 @@ export function GitHubPrFileDiff({
|
||||
disabled={disabled || !(commentDrafts[draftKey] ?? '').trim()}
|
||||
onPress={() => onSubmitComment(commentLine)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Comment on line {commentLine}</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{t('tasks.prFileDiff.commentOnLine', 'Comment on line {{line}}', {
|
||||
line: commentLine
|
||||
})}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { useCallback, useState } from 'react'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
|
||||
export function getBaseResolveError(error: unknown): string {
|
||||
return error instanceof Error
|
||||
? error.message
|
||||
: translate('tasks.composerSource.baseFailed', 'Failed to resolve base branch.')
|
||||
}
|
||||
|
||||
export function useForkPushWarning() {
|
||||
const t = useMobileTranslation()
|
||||
const [hasWarning, setHasWarning] = useState(false)
|
||||
const setForkPushWarning = useCallback((warning: string | null) => {
|
||||
setHasWarning(warning !== null)
|
||||
}, [])
|
||||
|
||||
return [
|
||||
hasWarning
|
||||
? t(
|
||||
'tasks.composerSource.forkPushWarning',
|
||||
'This PR has "Allow edits from maintainers" off; pushing to the fork may be rejected by GitHub.'
|
||||
)
|
||||
: null,
|
||||
setForkPushWarning
|
||||
] as const
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { MrStateFilter, SmartNameMode } from './mobile-composer-source-types'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
// Lucide has no brand icons; provider modes use TaskProviderLogo SVGs.
|
||||
export type SmartModeIcon =
|
||||
@@ -12,13 +13,31 @@ export type SmartModeOption = {
|
||||
}
|
||||
|
||||
export const SMART_MODE_OPTIONS: readonly SmartModeOption[] = [
|
||||
{ id: 'smart', label: 'Smart', icon: { type: 'lucide', name: 'sparkles' } },
|
||||
{
|
||||
id: 'smart',
|
||||
get label() {
|
||||
return translate('tasks.smartSourceModes.smart', 'Smart')
|
||||
},
|
||||
icon: { type: 'lucide', name: 'sparkles' }
|
||||
},
|
||||
{ id: 'github', label: 'GitHub', icon: { type: 'provider', provider: 'github' } },
|
||||
{ id: 'linear', label: 'Linear', icon: { type: 'provider', provider: 'linear' } },
|
||||
{ id: 'jira', label: 'Jira', icon: { type: 'provider', provider: 'jira' } },
|
||||
{ id: 'gitlab', label: 'GitLab', icon: { type: 'provider', provider: 'gitlab' } },
|
||||
{ id: 'branches', label: 'Branch', icon: { type: 'lucide', name: 'git-branch' } },
|
||||
{ id: 'text', label: 'Name', icon: { type: 'lucide', name: 'case-sensitive' } }
|
||||
{
|
||||
id: 'branches',
|
||||
get label() {
|
||||
return translate('tasks.smartSourceModes.branch', 'Branch')
|
||||
},
|
||||
icon: { type: 'lucide', name: 'git-branch' }
|
||||
},
|
||||
{
|
||||
id: 'text',
|
||||
get label() {
|
||||
return translate('tasks.smartSourceModes.name', 'Name')
|
||||
},
|
||||
icon: { type: 'lucide', name: 'case-sensitive' }
|
||||
}
|
||||
]
|
||||
|
||||
export type SmartModeAvailabilityInput = {
|
||||
@@ -75,10 +94,30 @@ export function normalizeSmartMode(
|
||||
export type MrStateFilterOption = { id: MrStateFilter; label: string }
|
||||
|
||||
export const MR_STATE_FILTER_OPTIONS: readonly MrStateFilterOption[] = [
|
||||
{ id: 'opened', label: 'Open' },
|
||||
{ id: 'merged', label: 'Merged' },
|
||||
{ id: 'closed', label: 'Closed' },
|
||||
{ id: 'all', label: 'All' }
|
||||
{
|
||||
id: 'opened',
|
||||
get label() {
|
||||
return translate('tasks.smartSourceModes.openState', 'Open')
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'merged',
|
||||
get label() {
|
||||
return translate('tasks.smartSourceModes.mergedState', 'Merged')
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'closed',
|
||||
get label() {
|
||||
return translate('tasks.smartSourceModes.closedState', 'Closed')
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'all',
|
||||
get label() {
|
||||
return translate('tasks.smartSourceModes.allStates', 'All')
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
export const DEFAULT_MR_STATE_FILTER: MrStateFilter = 'opened'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { JiraIssueFilter } from '../../../src/shared/jira/jira-types'
|
||||
import type { TaskProvider } from '../../../src/shared/task-providers'
|
||||
import type { PickerOption } from '../components/PickerModal'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { JIRA_FILTER_LABELS } from './mobile-jira-issue-filters'
|
||||
|
||||
export const PROVIDER_LABELS: Record<TaskProvider, string> = {
|
||||
@@ -11,27 +12,61 @@ export const PROVIDER_LABELS: Record<TaskProvider, string> = {
|
||||
}
|
||||
|
||||
export const PROVIDER_EMPTY_LABELS: Record<TaskProvider, string> = {
|
||||
github: 'No GitHub tasks',
|
||||
gitlab: 'No GitLab tasks',
|
||||
linear: 'No Linear tasks',
|
||||
jira: 'No Jira tasks'
|
||||
get github() {
|
||||
return translate('tasks.taskViewOptions.noGitHubTasks', 'No GitHub tasks')
|
||||
},
|
||||
get gitlab() {
|
||||
return translate('tasks.taskViewOptions.noGitLabTasks', 'No GitLab tasks')
|
||||
},
|
||||
get linear() {
|
||||
return translate('tasks.taskViewOptions.noLinearTasks', 'No Linear tasks')
|
||||
},
|
||||
get jira() {
|
||||
return translate('tasks.taskViewOptions.noJiraTasks', 'No Jira tasks')
|
||||
}
|
||||
}
|
||||
|
||||
export const JIRA_FILTER_OPTIONS: PickerOption<JiraIssueFilter>[] = [
|
||||
{
|
||||
value: 'assigned',
|
||||
label: JIRA_FILTER_LABELS.assigned,
|
||||
subtitle: 'Unresolved issues assigned to you'
|
||||
get label() {
|
||||
return JIRA_FILTER_LABELS.assigned
|
||||
},
|
||||
get subtitle() {
|
||||
return translate(
|
||||
'tasks.taskViewOptions.assignedSubtitle',
|
||||
'Unresolved issues assigned to you'
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 'reported',
|
||||
label: JIRA_FILTER_LABELS.reported,
|
||||
subtitle: 'Unresolved issues you reported'
|
||||
get label() {
|
||||
return JIRA_FILTER_LABELS.reported
|
||||
},
|
||||
get subtitle() {
|
||||
return translate('tasks.taskViewOptions.reportedSubtitle', 'Unresolved issues you reported')
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 'all',
|
||||
label: JIRA_FILTER_LABELS.all,
|
||||
subtitle: 'Unresolved issues across the selected sites'
|
||||
get label() {
|
||||
return JIRA_FILTER_LABELS.all
|
||||
},
|
||||
get subtitle() {
|
||||
return translate(
|
||||
'tasks.taskViewOptions.allSubtitle',
|
||||
'Unresolved issues across the selected sites'
|
||||
)
|
||||
}
|
||||
},
|
||||
{ value: 'done', label: JIRA_FILTER_LABELS.done, subtitle: 'Your recently resolved issues' }
|
||||
{
|
||||
value: 'done',
|
||||
get label() {
|
||||
return JIRA_FILTER_LABELS.done
|
||||
},
|
||||
get subtitle() {
|
||||
return translate('tasks.taskViewOptions.doneSubtitle', 'Your recently resolved issues')
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
BottomDrawer,
|
||||
View,
|
||||
@@ -56,18 +57,30 @@ export function renderMobileTasksCreateDrawer(model: ConnectionPresentationModel
|
||||
<View style={styles.sheetHeader}>
|
||||
<View style={styles.sheetTitleRow}>
|
||||
<TaskProviderLogo provider={provider} size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.sheetTitle}>New {providerLabel} Issue</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate('tasks.tasksCreateDrawers.newIssueTitle', 'New {{providerLabel}} Issue', {
|
||||
providerLabel
|
||||
})}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
{provider === 'github' || provider === 'gitlab'
|
||||
? 'Create an issue in the selected repository.'
|
||||
: 'Create an issue in the selected Linear team.'}
|
||||
? translate(
|
||||
'tasks.tasksCreateDrawers.repositorySubtitle',
|
||||
'Create an issue in the selected repository.'
|
||||
)
|
||||
: translate(
|
||||
'tasks.tasksCreateDrawers.linearTeamSubtitle',
|
||||
'Create an issue in the selected Linear team.'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.createForm}>
|
||||
<Text style={styles.fieldLabel}>
|
||||
{provider === 'github' || provider === 'gitlab' ? 'Repository' : 'Team'}
|
||||
{provider === 'github' || provider === 'gitlab'
|
||||
? translate('tasks.tasksCreateDrawers.repository', 'Repository')
|
||||
: translate('tasks.tasksCreateDrawers.team', 'Team')}
|
||||
</Text>
|
||||
<Pressable
|
||||
style={styles.targetButton}
|
||||
@@ -103,12 +116,16 @@ export function renderMobileTasksCreateDrawer(model: ConnectionPresentationModel
|
||||
selectedCreateRepo &&
|
||||
hasGitHubIssueSourceChoice(selectedCreateGitHubSources) ? (
|
||||
<View style={styles.issueSourceBox}>
|
||||
<Text style={styles.fieldLabel}>Issue source</Text>
|
||||
<Text style={styles.fieldLabel}>
|
||||
{translate('tasks.tasksCreateDrawers.issueSource', 'Issue source')}
|
||||
</Text>
|
||||
<Text style={styles.issueSourceHint} numberOfLines={2}>
|
||||
File in{' '}
|
||||
{selectedCreateIssuePreference === 'origin'
|
||||
? issueSourceSlug(selectedCreateGitHubSources?.prs)
|
||||
: issueSourceSlug(selectedCreateGitHubSources?.upstreamCandidate)}
|
||||
{translate('tasks.tasksCreateDrawers.fileIn', 'File in {{slug}}', {
|
||||
slug:
|
||||
selectedCreateIssuePreference === 'origin'
|
||||
? issueSourceSlug(selectedCreateGitHubSources?.prs)
|
||||
: issueSourceSlug(selectedCreateGitHubSources?.upstreamCandidate)
|
||||
})}
|
||||
</Text>
|
||||
<View style={styles.issueSourceSegment}>
|
||||
{(['upstream', 'origin'] as const).map((preference) => {
|
||||
@@ -135,7 +152,9 @@ export function renderMobileTasksCreateDrawer(model: ConnectionPresentationModel
|
||||
selected && styles.issueSourceSegmentTextActive
|
||||
]}
|
||||
>
|
||||
{preference === 'upstream' ? 'Upstream' : 'Origin'}
|
||||
{preference === 'upstream'
|
||||
? translate('tasks.tasksCreateDrawers.upstream', 'Upstream')
|
||||
: translate('tasks.tasksCreateDrawers.origin', 'Origin')}
|
||||
</Text>
|
||||
<Text style={styles.issueSourceSlug} numberOfLines={1}>
|
||||
{slug}
|
||||
@@ -147,23 +166,27 @@ export function renderMobileTasksCreateDrawer(model: ConnectionPresentationModel
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
<Text style={styles.fieldLabel}>Title</Text>
|
||||
<Text style={styles.fieldLabel}>
|
||||
{translate('tasks.tasksCreateDrawers.title', 'Title')}
|
||||
</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
value={createTitle}
|
||||
onChangeText={setCreateTitle}
|
||||
placeholder="Task title"
|
||||
placeholder={translate('tasks.tasksCreateDrawers.titlePlaceholder', 'Task title')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
autoCapitalize="sentences"
|
||||
returnKeyType="next"
|
||||
/>
|
||||
|
||||
<Text style={styles.fieldLabel}>Description</Text>
|
||||
<Text style={styles.fieldLabel}>
|
||||
{translate('tasks.tasksCreateDrawers.description', 'Description')}
|
||||
</Text>
|
||||
<TextInput
|
||||
style={[styles.input, styles.bodyInput]}
|
||||
value={createBody}
|
||||
onChangeText={setCreateBody}
|
||||
placeholder="Add context"
|
||||
placeholder={translate('tasks.tasksCreateDrawers.descriptionPlaceholder', 'Add context')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
multiline
|
||||
textAlignVertical="top"
|
||||
@@ -180,7 +203,9 @@ export function renderMobileTasksCreateDrawer(model: ConnectionPresentationModel
|
||||
{creatingTask ? (
|
||||
<ActivityIndicator size="small" color={colors.bgBase} />
|
||||
) : (
|
||||
<Text style={styles.createButtonText}>Create Issue</Text>
|
||||
<Text style={styles.createButtonText}>
|
||||
{translate('tasks.tasksCreateDrawers.createIssue', 'Create Issue')}
|
||||
</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
</View>
|
||||
@@ -203,7 +228,11 @@ export function renderMobileTasksCreateTargetPicker(model: ConnectionPresentatio
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showCreateTask && showCreateTargetPicker}
|
||||
title={provider === 'linear' ? 'Linear Team' : 'Repository'}
|
||||
title={
|
||||
provider === 'linear'
|
||||
? translate('tasks.tasksCreateDrawers.linearTeam', 'Linear Team')
|
||||
: translate('tasks.tasksCreateDrawers.repository', 'Repository')
|
||||
}
|
||||
options={createTargetOptions}
|
||||
selected={
|
||||
provider === 'github' || provider === 'gitlab'
|
||||
@@ -247,14 +276,24 @@ export function renderMobileTasksLinearConnectDrawer(model: ConnectionPresentati
|
||||
<View style={styles.sheetHeader}>
|
||||
<View style={styles.sheetTitleRow}>
|
||||
<TaskProviderLogo provider="linear" size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.sheetTitle}>Connect Linear workspace</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate(
|
||||
'tasks.tasksCreateDrawers.connectLinearWorkspace',
|
||||
'Connect Linear workspace'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
Paste a Personal API key to browse issues from that workspace.
|
||||
{translate(
|
||||
'tasks.tasksCreateDrawers.linearConnectSubtitle',
|
||||
'Paste a Personal API key to browse issues from that workspace.'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.createForm}>
|
||||
<Text style={styles.fieldLabel}>Personal API key</Text>
|
||||
<Text style={styles.fieldLabel}>
|
||||
{translate('tasks.tasksCreateDrawers.personalApiKey', 'Personal API key')}
|
||||
</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
value={linearApiKeyDraft}
|
||||
@@ -281,12 +320,20 @@ export function renderMobileTasksLinearConnectDrawer(model: ConnectionPresentati
|
||||
onPress={() => void Linking.openURL('https://linear.app/settings/account/security')}
|
||||
>
|
||||
<ExternalLink size={13} color={colors.textSecondary} />
|
||||
<Text style={styles.inlineTextLinkText}>Linear Settings / Security / New API key</Text>
|
||||
<Text style={styles.inlineTextLinkText}>
|
||||
{translate(
|
||||
'tasks.tasksCreateDrawers.linearSettingsLink',
|
||||
'Linear Settings / Security / New API key'
|
||||
)}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<View style={styles.securityHintRow}>
|
||||
<Lock size={13} color={colors.textMuted} />
|
||||
<Text style={styles.securityHintText}>
|
||||
Your key is encrypted via the host OS keychain and stored locally.
|
||||
{translate(
|
||||
'tasks.tasksCreateDrawers.keySecurityHint',
|
||||
'Your key is encrypted via the host OS keychain and stored locally.'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
<Pressable
|
||||
@@ -301,7 +348,9 @@ export function renderMobileTasksLinearConnectDrawer(model: ConnectionPresentati
|
||||
{linearConnectState === 'connecting' ? (
|
||||
<ActivityIndicator size="small" color={colors.bgBase} />
|
||||
) : (
|
||||
<Text style={styles.createButtonText}>Connect</Text>
|
||||
<Text style={styles.createButtonText}>
|
||||
{translate('tasks.tasksCreateDrawers.connect', 'Connect')}
|
||||
</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
</View>
|
||||
@@ -321,7 +370,7 @@ export function renderMobileTasksWorkspaceCreateTargetPicker(model: ConnectionPr
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && workspaceRepoPickerItem != null}
|
||||
title="Create Workspace In"
|
||||
title={translate('tasks.tasksCreateDrawers.createWorkspaceIn', 'Create Workspace In')}
|
||||
options={workspaceRepoOptions}
|
||||
selected={workspaceRepos[0]?.id ?? ''}
|
||||
onSelect={(repoId) => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
BottomDrawer,
|
||||
View,
|
||||
@@ -34,12 +35,21 @@ export function renderMobileTasksGitHubProjectFieldsPicker(model: ConnectionPres
|
||||
onClose={() => setShowGitHubProjectFieldsPicker(false)}
|
||||
>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>Project Fields</Text>
|
||||
<Text style={styles.sheetSubtitle}>Choose which Project fields appear on item cards.</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate('tasks.filterPickers.fieldsTitle', 'Project Fields')}
|
||||
</Text>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
{translate(
|
||||
'tasks.filterPickers.fieldsSubtitle',
|
||||
'Choose which Project fields appear on item cards.'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.repoPickerGroup}>
|
||||
{githubProjectAvailableSummaryFields.length === 0 ? (
|
||||
<Text style={styles.repoPickerSubtitle}>This view has no extra fields to show.</Text>
|
||||
<Text style={styles.repoPickerSubtitle}>
|
||||
{translate('tasks.filterPickers.noFields', 'This view has no extra fields to show.')}
|
||||
</Text>
|
||||
) : (
|
||||
githubProjectAvailableSummaryFields.map((field, index) => {
|
||||
const visible = !githubProjectHiddenFieldIds.has(field.id)
|
||||
@@ -55,7 +65,9 @@ export function renderMobileTasksGitHubProjectFieldsPicker(model: ConnectionPres
|
||||
{field.name}
|
||||
</Text>
|
||||
<Text style={styles.repoPickerSubtitle} numberOfLines={1}>
|
||||
{visible ? 'Shown on cards' : 'Hidden from cards'}
|
||||
{visible
|
||||
? translate('tasks.filterPickers.fieldShown', 'Shown on cards')
|
||||
: translate('tasks.filterPickers.fieldHidden', 'Hidden from cards')}
|
||||
</Text>
|
||||
</View>
|
||||
{visible ? <Check size={15} color={colors.textPrimary} /> : null}
|
||||
@@ -82,7 +94,7 @@ export function renderMobileTasksGitLabViewPicker(model: ConnectionPresentationM
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showGitLabViewPicker}
|
||||
title="GitLab View"
|
||||
title={translate('tasks.filterPickers.gitlabView', 'GitLab View')}
|
||||
options={GITLAB_VIEW_OPTIONS}
|
||||
selected={gitlabView}
|
||||
onSelect={(view) => {
|
||||
@@ -99,21 +111,14 @@ export function renderMobileTasksGitLabViewPicker(model: ConnectionPresentationM
|
||||
}
|
||||
|
||||
export function renderMobileTasksGitLabFilterPicker(model: ConnectionPresentationModel) {
|
||||
const {
|
||||
gitlabFilter,
|
||||
setGitlabFilter,
|
||||
setShowGitLabFilterPicker,
|
||||
showGitLabFilterPicker,
|
||||
taskUiReady
|
||||
} = model
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showGitLabFilterPicker}
|
||||
title="GitLab Filter"
|
||||
visible={model.taskUiReady && model.showGitLabFilterPicker}
|
||||
title={translate('tasks.filterPickers.gitlabFilter', 'GitLab Filter')}
|
||||
options={GITLAB_FILTER_OPTIONS}
|
||||
selected={gitlabFilter}
|
||||
onSelect={setGitlabFilter}
|
||||
onClose={() => setShowGitLabFilterPicker(false)}
|
||||
selected={model.gitlabFilter}
|
||||
onSelect={model.setGitlabFilter}
|
||||
onClose={() => model.setShowGitLabFilterPicker(false)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -132,7 +137,7 @@ export function renderMobileTasksLinearFilterPicker(model: ConnectionPresentatio
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showLinearFilterPicker}
|
||||
title="Linear Filter"
|
||||
title={translate('tasks.filterPickers.linearFilter', 'Linear Filter')}
|
||||
options={LINEAR_FILTER_OPTIONS}
|
||||
selected={linearFilter}
|
||||
onSelect={(filter) => {
|
||||
@@ -162,7 +167,7 @@ export function renderMobileTasksLinearWorkspacePicker(model: ConnectionPresenta
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showLinearWorkspacePicker}
|
||||
title="Linear Workspace"
|
||||
title={translate('tasks.filterPickers.linearWorkspace', 'Linear Workspace')}
|
||||
options={linearWorkspaceOptions}
|
||||
selected={selectedLinearWorkspaceId ?? ''}
|
||||
onSelect={(workspaceId) => {
|
||||
@@ -173,7 +178,14 @@ export function renderMobileTasksLinearWorkspacePicker(model: ConnectionPresenta
|
||||
.request(client, { workspaceId })
|
||||
.then(() => loadLinearContext())
|
||||
.catch((err) => {
|
||||
setError(err instanceof Error ? err.message : 'Failed to switch workspace')
|
||||
setError(
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate(
|
||||
'tasks.filterPickers.switchWorkspaceFailed',
|
||||
'Failed to switch workspace'
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
}}
|
||||
@@ -192,14 +204,19 @@ export function renderMobileTasksLinearTeamPicker(model: ConnectionPresentationM
|
||||
showLinearTeamPicker,
|
||||
taskUiReady
|
||||
} = model
|
||||
const count = linearTeams.length
|
||||
return (
|
||||
<BottomDrawer
|
||||
visible={taskUiReady && showLinearTeamPicker}
|
||||
onClose={() => setShowLinearTeamPicker(false)}
|
||||
>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>Linear Teams</Text>
|
||||
<Text style={styles.sheetSubtitle}>Choose which teams appear in Tasks.</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate('tasks.filterPickers.teamsTitle', 'Linear Teams')}
|
||||
</Text>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
{translate('tasks.filterPickers.teamsSubtitle', 'Choose which teams appear in Tasks.')}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.repoPickerGroup}>
|
||||
<Pressable
|
||||
@@ -211,8 +228,14 @@ export function renderMobileTasksLinearTeamPicker(model: ConnectionPresentationM
|
||||
}}
|
||||
>
|
||||
<View style={styles.repoPickerTextWrap}>
|
||||
<Text style={styles.repoPickerTitle}>All teams</Text>
|
||||
<Text style={styles.repoPickerSubtitle}>{linearTeams.length} teams</Text>
|
||||
<Text style={styles.repoPickerTitle}>
|
||||
{translate('tasks.filterPickers.allTeams', 'All teams')}
|
||||
</Text>
|
||||
<Text style={styles.repoPickerSubtitle}>
|
||||
{count === 1
|
||||
? translate('tasks.filterPickers.teams_one', '{{count}} team', { count })
|
||||
: translate('tasks.filterPickers.teams_other', '{{count}} teams', { count })}
|
||||
</Text>
|
||||
</View>
|
||||
{selectedLinearTeamIds.size === linearTeams.length ? (
|
||||
<Check size={15} color={colors.textPrimary} />
|
||||
@@ -275,19 +298,26 @@ export function renderMobileTasksLinearStatusPicker(model: ConnectionPresentatio
|
||||
zIndex={TASK_SECONDARY_DRAWER_Z_INDEX}
|
||||
>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>Change Status</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate('tasks.filterPickers.changeStatus', 'Change Status')}
|
||||
</Text>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
{linearStatusPickerItem?.source.identifier ?? 'Linear issue'}
|
||||
{linearStatusPickerItem?.source.identifier ??
|
||||
translate('tasks.filterPickers.linearIssue', 'Linear issue')}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.repoPickerGroup}>
|
||||
{linearStatesLoading ? (
|
||||
<View style={styles.detailLoadingInline}>
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
<Text style={styles.detailMuted}>Loading states...</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.filterPickers.loadingStates', 'Loading states...')}
|
||||
</Text>
|
||||
</View>
|
||||
) : linearStates.length === 0 ? (
|
||||
<Text style={styles.emptyInlineText}>No states available</Text>
|
||||
<Text style={styles.emptyInlineText}>
|
||||
{translate('tasks.filterPickers.noStates', 'No states available')}
|
||||
</Text>
|
||||
) : (
|
||||
linearStates.map((state, index) => {
|
||||
const selected =
|
||||
@@ -347,7 +377,7 @@ export function renderMobileTasksJiraFilterPicker(model: ConnectionPresentationM
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showJiraFilterPicker}
|
||||
title="Jira Filter"
|
||||
title={translate('tasks.filterPickers.jiraFilter', 'Jira Filter')}
|
||||
options={JIRA_FILTER_OPTIONS}
|
||||
selected={jiraFilter}
|
||||
onSelect={(filter) => {
|
||||
@@ -362,26 +392,17 @@ export function renderMobileTasksJiraFilterPicker(model: ConnectionPresentationM
|
||||
}
|
||||
|
||||
export function renderMobileTasksJiraSitePicker(model: ConnectionPresentationModel) {
|
||||
const {
|
||||
jiraConnection,
|
||||
jiraSiteOptions,
|
||||
setItems,
|
||||
setJiraConnection,
|
||||
setShowJiraSitePicker,
|
||||
showJiraSitePicker,
|
||||
taskUiReady
|
||||
} = model
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showJiraSitePicker}
|
||||
title="Jira Site"
|
||||
options={jiraSiteOptions}
|
||||
selected={jiraConnection.selection ?? ''}
|
||||
visible={model.taskUiReady && model.showJiraSitePicker}
|
||||
title={translate('tasks.filterPickers.jiraSite', 'Jira Site')}
|
||||
options={model.jiraSiteOptions}
|
||||
selected={model.jiraConnection.selection ?? ''}
|
||||
onSelect={(siteId) => {
|
||||
setJiraConnection((current) => ({ ...current, selection: siteId }))
|
||||
setItems([])
|
||||
model.setJiraConnection((current) => ({ ...current, selection: siteId }))
|
||||
model.setItems([])
|
||||
}}
|
||||
onClose={() => setShowJiraSitePicker(false)}
|
||||
onClose={() => model.setShowJiraSitePicker(false)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
View,
|
||||
ActivityIndicator,
|
||||
@@ -20,6 +21,41 @@ import {
|
||||
projectFieldDisplayLabel,
|
||||
projectRowStatusLabel
|
||||
} from './mobile-tasks-legacy-foundation'
|
||||
import type { GitHubProjectField, GitHubProjectRow } from './mobile-tasks-view-state-types'
|
||||
|
||||
function isProjectFieldEmpty(row: GitHubProjectRow, field: GitHubProjectField): boolean {
|
||||
switch (field.dataType) {
|
||||
case 'ASSIGNEES':
|
||||
return row.content.assignees.map((user) => user.login).join(', ') === ''
|
||||
case 'LABELS':
|
||||
return row.content.labels.map((label) => label.name).join(', ') === ''
|
||||
case 'REPOSITORY':
|
||||
return row.content.repository == null
|
||||
case 'PARENT_ISSUE':
|
||||
return !row.content.parentIssue
|
||||
case 'ISSUE_TYPE':
|
||||
return row.content.issueType?.name == null
|
||||
case 'TITLE':
|
||||
return false
|
||||
}
|
||||
const value = row.fieldValuesByFieldId?.[field.id]
|
||||
if (!value) {
|
||||
return true
|
||||
}
|
||||
switch (value.kind) {
|
||||
case 'text':
|
||||
return !value.text
|
||||
case 'labels':
|
||||
return value.labels.map((label) => label.name).join(', ') === ''
|
||||
case 'users':
|
||||
return value.users.map((user) => user.login).join(', ') === ''
|
||||
case 'date':
|
||||
case 'iteration':
|
||||
case 'number':
|
||||
case 'single-select':
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function renderMobileTasksGitHubProjectList(
|
||||
model: ConnectionPresentationModel,
|
||||
@@ -42,13 +78,16 @@ export function renderMobileTasksGitHubProjectList(
|
||||
taskUiReady,
|
||||
visibleGitHubProjectRows
|
||||
} = model
|
||||
const count = githubProjectSummaryFields.length - 4
|
||||
return githubProjectLoading ? (
|
||||
<View style={styles.centered}>
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
</View>
|
||||
) : !activeGitHubProject ? (
|
||||
<View style={styles.centered}>
|
||||
<Text style={styles.emptyText}>Choose a GitHub project</Text>
|
||||
<Text style={styles.emptyText}>
|
||||
{translate('tasks.githubProjectList.chooseProject', 'Choose a GitHub project')}
|
||||
</Text>
|
||||
<Pressable
|
||||
style={[styles.targetButton, styles.centerActionButton]}
|
||||
disabled={!taskUiReady}
|
||||
@@ -59,7 +98,9 @@ export function renderMobileTasksGitHubProjectList(
|
||||
setShowGitHubProjectPicker(true)
|
||||
}}
|
||||
>
|
||||
<Text style={styles.targetButtonText}>Browse projects</Text>
|
||||
<Text style={styles.targetButtonText}>
|
||||
{translate('tasks.githubProjectList.browseProjects', 'Browse projects')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
) : githubProjectError ? (
|
||||
@@ -72,7 +113,9 @@ export function renderMobileTasksGitHubProjectList(
|
||||
</View>
|
||||
) : !githubProjectTable || visibleGitHubProjectRows.length === 0 ? (
|
||||
<View style={styles.centered}>
|
||||
<Text style={styles.emptyText}>No project items</Text>
|
||||
<Text style={styles.emptyText}>
|
||||
{translate('tasks.githubProjectList.noItems', 'No project items')}
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
<FlatList
|
||||
@@ -106,7 +149,7 @@ export function renderMobileTasksGitHubProjectList(
|
||||
style={entry.collapsed ? styles.projectGroupChevronCollapsed : undefined}
|
||||
/>
|
||||
<Text style={styles.projectGroupTitle} numberOfLines={1}>
|
||||
{entry.group.label || 'Items'}
|
||||
{entry.group.label || translate('tasks.githubProjectList.items', 'Items')}
|
||||
</Text>
|
||||
<Text style={styles.projectGroupMeta}>{projectGroupMeta(entry.group)}</Text>
|
||||
</Pressable>
|
||||
@@ -143,19 +186,40 @@ export function renderMobileTasksGitHubProjectList(
|
||||
/>
|
||||
<Text style={styles.subtitle} numberOfLines={1}>
|
||||
{row.itemType === 'PULL_REQUEST'
|
||||
? 'Pull request'
|
||||
? translate(
|
||||
'tasks.githubProjectList.pullRequestSubtitle',
|
||||
'Pull request · {{repository}}{{number}}',
|
||||
{
|
||||
repository: row.content.repository ?? githubProjectTable.project.title,
|
||||
number: row.content.number ? ` #${row.content.number}` : ''
|
||||
}
|
||||
)
|
||||
: row.itemType === 'ISSUE'
|
||||
? 'Issue'
|
||||
: 'Project item'}{' '}
|
||||
· {row.content.repository ?? githubProjectTable.project.title}
|
||||
{row.content.number ? ` #${row.content.number}` : ''}
|
||||
? translate(
|
||||
'tasks.githubProjectList.issueSubtitle',
|
||||
'Issue · {{repository}}{{number}}',
|
||||
{
|
||||
repository: row.content.repository ?? githubProjectTable.project.title,
|
||||
number: row.content.number ? ` #${row.content.number}` : ''
|
||||
}
|
||||
)
|
||||
: translate(
|
||||
'tasks.githubProjectList.itemSubtitle',
|
||||
'Project item · {{repository}}{{number}}',
|
||||
{
|
||||
repository: row.content.repository ?? githubProjectTable.project.title,
|
||||
number: row.content.number ? ` #${row.content.number}` : ''
|
||||
}
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
{githubProjectSummaryFields.length > 0 ? (
|
||||
<View style={styles.projectFieldPillRow}>
|
||||
{githubProjectSummaryFields.slice(0, 4).map((field) => {
|
||||
const value = projectFieldDisplayLabel(row, field)
|
||||
const isEmpty = value === 'Empty'
|
||||
const isEmpty = isProjectFieldEmpty(row, field)
|
||||
const value = isEmpty
|
||||
? translate('tasks.githubProjectList.emptyField', 'Empty')
|
||||
: projectFieldDisplayLabel(row, field)
|
||||
return (
|
||||
<View key={field.id} style={styles.projectFieldPill}>
|
||||
<Text style={styles.projectFieldPillText} numberOfLines={1}>
|
||||
@@ -170,7 +234,17 @@ export function renderMobileTasksGitHubProjectList(
|
||||
{githubProjectSummaryFields.length > 4 ? (
|
||||
<View style={styles.projectFieldPill}>
|
||||
<Text style={styles.projectFieldPillText}>
|
||||
+{githubProjectSummaryFields.length - 4} fields
|
||||
{count === 1
|
||||
? translate(
|
||||
'tasks.githubProjectList.moreFields_one',
|
||||
'+{{count}} field',
|
||||
{ count }
|
||||
)
|
||||
: translate(
|
||||
'tasks.githubProjectList.moreFields_other',
|
||||
'+{{count}} fields',
|
||||
{ count }
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
BottomDrawer,
|
||||
View,
|
||||
@@ -42,14 +43,22 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati
|
||||
showGitHubProjectPicker,
|
||||
taskUiReady
|
||||
} = model
|
||||
const count = githubProjectPartialFailures.length
|
||||
return (
|
||||
<BottomDrawer
|
||||
visible={taskUiReady && showGitHubProjectPicker}
|
||||
onClose={() => setShowGitHubProjectPicker(false)}
|
||||
>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>GitHub Projects</Text>
|
||||
<Text style={styles.sheetSubtitle}>Choose a project view for the Tasks page.</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate('tasks.githubProjectPickers.title', 'GitHub Projects')}
|
||||
</Text>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
{translate(
|
||||
'tasks.githubProjectPickers.subtitle',
|
||||
'Choose a project view for the Tasks page.'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.projectPickerControls}>
|
||||
@@ -57,7 +66,7 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati
|
||||
style={styles.input}
|
||||
value={githubProjectPickerSearch}
|
||||
onChangeText={setGithubProjectPickerSearch}
|
||||
placeholder="Search projects"
|
||||
placeholder={translate('tasks.githubProjectPickers.searchProjects', 'Search projects')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
@@ -71,7 +80,10 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati
|
||||
setGithubProjectPasteError('')
|
||||
}}
|
||||
onSubmitEditing={() => void resolveGitHubProjectFromInput()}
|
||||
placeholder="Add by URL or owner/number"
|
||||
placeholder={translate(
|
||||
'tasks.githubProjectPickers.addPlaceholder',
|
||||
'Add by URL or owner/number'
|
||||
)}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
@@ -82,7 +94,9 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati
|
||||
onPress={() => void resolveGitHubProjectFromInput()}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{githubProjectPasteBusy ? 'Adding...' : 'Add'}
|
||||
{githubProjectPasteBusy
|
||||
? translate('tasks.githubProjectPickers.adding', 'Adding...')
|
||||
: translate('tasks.githubProjectPickers.add', 'Add')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
@@ -100,15 +114,35 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati
|
||||
<Text style={styles.projectWarningTitle}>
|
||||
{githubProjectPartialFailures.length === 1 &&
|
||||
githubProjectPartialFailures[0]!.owner !== '*'
|
||||
? `Couldn't load projects from ${githubProjectPartialFailures[0]!.owner}.`
|
||||
: `Some organizations didn't load (${githubProjectPartialFailures.length}).`}
|
||||
? translate(
|
||||
'tasks.githubProjectPickers.ownerLoadFailed',
|
||||
"Couldn't load projects from {{owner}}.",
|
||||
{
|
||||
owner: githubProjectPartialFailures[0]!.owner
|
||||
}
|
||||
)
|
||||
: translate(
|
||||
'tasks.githubProjectPickers.organizationsLoadFailed',
|
||||
"Some organizations didn't load ({{count}}).",
|
||||
{ count }
|
||||
)}
|
||||
</Text>
|
||||
<Text style={styles.projectWarningText}>
|
||||
{translate(
|
||||
'tasks.githubProjectPickers.addByUrlHint',
|
||||
'Use Add by URL to reach missing projects.'
|
||||
)}
|
||||
</Text>
|
||||
<Text style={styles.projectWarningText}>Use Add by URL to reach missing projects.</Text>
|
||||
<Text style={styles.projectWarningText} numberOfLines={2}>
|
||||
{githubProjectPartialFailures
|
||||
.map(
|
||||
(failure) =>
|
||||
`${failure.owner === '*' ? 'orgs' : failure.owner}: ${failure.message}`
|
||||
.map(({ owner, message }) =>
|
||||
owner === '*'
|
||||
? translate(
|
||||
'tasks.githubProjectPickers.organizationsError',
|
||||
'orgs: {{message}}',
|
||||
{ message }
|
||||
)
|
||||
: `${owner}: ${message}`
|
||||
)
|
||||
.join(' · ')}
|
||||
</Text>
|
||||
@@ -129,21 +163,29 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati
|
||||
onPress={() =>
|
||||
void loadGitHubProjects().catch((err) => {
|
||||
setGithubProjectError(
|
||||
err instanceof Error ? err.message : 'Failed to load projects'
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate('tasks.githubProjectPickers.loadFailed', 'Failed to load projects')
|
||||
)
|
||||
})
|
||||
}
|
||||
>
|
||||
<View style={styles.repoPickerTextWrap}>
|
||||
<Text style={styles.repoPickerTitle}>No projects loaded</Text>
|
||||
<Text style={styles.repoPickerSubtitle}>Tap to retry.</Text>
|
||||
<Text style={styles.repoPickerTitle}>
|
||||
{translate('tasks.githubProjectPickers.noProjects', 'No projects loaded')}
|
||||
</Text>
|
||||
<Text style={styles.repoPickerSubtitle}>
|
||||
{translate('tasks.githubProjectPickers.retryHint', 'Tap to retry.')}
|
||||
</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
) : (
|
||||
<>
|
||||
{pinnedGitHubProjects.length > 0 ? (
|
||||
<>
|
||||
<Text style={styles.linearStatesTitle}>Pinned</Text>
|
||||
<Text style={styles.linearStatesTitle}>
|
||||
{translate('tasks.githubProjectPickers.pinned', 'Pinned')}
|
||||
</Text>
|
||||
{pinnedGitHubProjects.map((project, index) => {
|
||||
const key = githubProjectKey(project)
|
||||
const selected =
|
||||
@@ -178,7 +220,9 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati
|
||||
})
|
||||
}}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Remove</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('common.remove', 'Remove')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
{selected ? <Check size={15} color={colors.textPrimary} /> : null}
|
||||
</Pressable>
|
||||
@@ -190,7 +234,9 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati
|
||||
|
||||
{recentGitHubProjects.length > 0 ? (
|
||||
<>
|
||||
<Text style={styles.linearStatesTitle}>Recent</Text>
|
||||
<Text style={styles.linearStatesTitle}>
|
||||
{translate('tasks.githubProjectPickers.recent', 'Recent')}
|
||||
</Text>
|
||||
{recentGitHubProjects.map((project, index) => {
|
||||
const key = githubProjectKey(project)
|
||||
const selected =
|
||||
@@ -231,7 +277,9 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati
|
||||
})
|
||||
}}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Pin</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.githubProjectPickers.pin', 'Pin')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
{selected ? <Check size={15} color={colors.textPrimary} /> : null}
|
||||
@@ -243,11 +291,15 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati
|
||||
) : null}
|
||||
|
||||
<Text style={styles.linearStatesTitle}>
|
||||
{githubProjectLoading ? 'Browse all (loading...)' : 'Browse all'}
|
||||
{githubProjectLoading
|
||||
? translate('tasks.githubProjectPickers.browseLoading', 'Browse all (loading...)')
|
||||
: translate('tasks.githubProjectPickers.browseAll', 'Browse all')}
|
||||
</Text>
|
||||
{browseGitHubProjects.length === 0 ? (
|
||||
<Text style={styles.emptyInlineText}>
|
||||
{githubProjectPickerSearch.trim() ? 'No matching projects.' : 'No more projects.'}
|
||||
{githubProjectPickerSearch.trim()
|
||||
? translate('tasks.githubProjectPickers.noMatches', 'No matching projects.')
|
||||
: translate('tasks.githubProjectPickers.noMoreProjects', 'No more projects.')}
|
||||
</Text>
|
||||
) : (
|
||||
browseGitHubProjects.map((project, index) => {
|
||||
@@ -286,46 +338,43 @@ export function renderMobileTasksGitHubProjectPicker(model: ConnectionPresentati
|
||||
}
|
||||
|
||||
export function renderMobileTasksGitHubProjectViewPicker(model: ConnectionPresentationModel) {
|
||||
const {
|
||||
activeGitHubProject,
|
||||
activeGitHubProjectKey,
|
||||
activeGitHubProjectViewId,
|
||||
commitGitHubProjectView,
|
||||
githubProjectViewOptions,
|
||||
githubProjectViews,
|
||||
pendingGitHubProjectViewSelection,
|
||||
setGithubProjectError,
|
||||
setPendingGitHubProjectViewSelection,
|
||||
setShowGitHubProjectViewPicker,
|
||||
showGitHubProjectViewPicker,
|
||||
taskUiReady
|
||||
} = model
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showGitHubProjectViewPicker}
|
||||
title={pendingGitHubProjectViewSelection ? 'Choose Project View' : 'Project View'}
|
||||
options={githubProjectViewOptions}
|
||||
selected={pendingGitHubProjectViewSelection ? '' : (activeGitHubProjectViewId ?? '')}
|
||||
visible={model.taskUiReady && model.showGitHubProjectViewPicker}
|
||||
title={
|
||||
model.pendingGitHubProjectViewSelection
|
||||
? translate('tasks.githubProjectPickers.chooseView', 'Choose Project View')
|
||||
: translate('tasks.githubProjectPickers.view', 'Project View')
|
||||
}
|
||||
options={model.githubProjectViewOptions}
|
||||
selected={
|
||||
model.pendingGitHubProjectViewSelection ? '' : (model.activeGitHubProjectViewId ?? '')
|
||||
}
|
||||
onSelect={(viewId) => {
|
||||
const view = githubProjectViews.find((candidate) => candidate.id === viewId)
|
||||
const view = model.githubProjectViews.find((candidate) => candidate.id === viewId)
|
||||
if (view && view.layout !== 'TABLE_LAYOUT') {
|
||||
setGithubProjectError("Orca doesn't support this GitHub Project layout yet.")
|
||||
model.setGithubProjectError(
|
||||
translate(
|
||||
'tasks.githubProjectPickers.unsupportedLayout',
|
||||
"Orca doesn't support this GitHub Project layout yet."
|
||||
)
|
||||
)
|
||||
return
|
||||
}
|
||||
if (pendingGitHubProjectViewSelection) {
|
||||
commitGitHubProjectView(pendingGitHubProjectViewSelection, viewId)
|
||||
setPendingGitHubProjectViewSelection(null)
|
||||
if (model.pendingGitHubProjectViewSelection) {
|
||||
model.commitGitHubProjectView(model.pendingGitHubProjectViewSelection, viewId)
|
||||
model.setPendingGitHubProjectViewSelection(null)
|
||||
return
|
||||
}
|
||||
if (!activeGitHubProject || !activeGitHubProjectKey) {
|
||||
if (!model.activeGitHubProject || !model.activeGitHubProjectKey) {
|
||||
return
|
||||
}
|
||||
commitGitHubProjectView(activeGitHubProject, viewId)
|
||||
model.commitGitHubProjectView(model.activeGitHubProject, viewId)
|
||||
}}
|
||||
onClose={() => {
|
||||
setShowGitHubProjectViewPicker(false)
|
||||
if (pendingGitHubProjectViewSelection) {
|
||||
setPendingGitHubProjectViewSelection(null)
|
||||
model.setShowGitHubProjectViewPicker(false)
|
||||
if (model.pendingGitHubProjectViewSelection) {
|
||||
model.setPendingGitHubProjectViewSelection(null)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
@@ -333,26 +382,18 @@ export function renderMobileTasksGitHubProjectViewPicker(model: ConnectionPresen
|
||||
}
|
||||
|
||||
export function renderMobileTasksGitHubProjectSortPicker(model: ConnectionPresentationModel) {
|
||||
const {
|
||||
githubProjectSortOptions,
|
||||
githubProjectSortOverride,
|
||||
setGithubProjectSortOverride,
|
||||
setShowGitHubProjectSortPicker,
|
||||
showGitHubProjectSortPicker,
|
||||
taskUiReady
|
||||
} = model
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showGitHubProjectSortPicker}
|
||||
title="Project Sort"
|
||||
options={githubProjectSortOptions}
|
||||
selected={githubProjectSortOverride?.fieldId ?? PROJECT_VIEW_DEFAULT_SORT}
|
||||
visible={model.taskUiReady && model.showGitHubProjectSortPicker}
|
||||
title={translate('tasks.githubProjectPickers.sort', 'Project Sort')}
|
||||
options={model.githubProjectSortOptions}
|
||||
selected={model.githubProjectSortOverride?.fieldId ?? PROJECT_VIEW_DEFAULT_SORT}
|
||||
onSelect={(fieldId) => {
|
||||
if (fieldId === PROJECT_VIEW_DEFAULT_SORT) {
|
||||
setGithubProjectSortOverride(null)
|
||||
model.setGithubProjectSortOverride(null)
|
||||
return
|
||||
}
|
||||
setGithubProjectSortOverride((current) => {
|
||||
model.setGithubProjectSortOverride((current) => {
|
||||
if (!current || current.fieldId !== fieldId) {
|
||||
return { fieldId, direction: 'ASC' }
|
||||
}
|
||||
@@ -362,7 +403,7 @@ export function renderMobileTasksGitHubProjectSortPicker(model: ConnectionPresen
|
||||
return null
|
||||
})
|
||||
}}
|
||||
onClose={() => setShowGitHubProjectSortPicker(false)}
|
||||
onClose={() => model.setShowGitHubProjectSortPicker(false)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { Pressable, Text, View, Linking, ExternalLink, colors } from './mobile-tasks-dependencies'
|
||||
import { styles } from './mobile-tasks-legacy-styles'
|
||||
|
||||
@@ -67,7 +68,11 @@ export function renderMobileTasksGitHubViewControls(model: ConnectionPresentatio
|
||||
setShowGitHubIssueSourcePicker(true)
|
||||
}}
|
||||
>
|
||||
<Text style={styles.segmentSecondaryText}>Source: {githubIssueSourceLabel}</Text>
|
||||
<Text style={styles.segmentSecondaryText}>
|
||||
{translate('tasks.githubViewControls.source', 'Source: {{source}}', {
|
||||
source: githubIssueSourceLabel
|
||||
})}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
</>
|
||||
@@ -110,7 +115,11 @@ export function renderMobileTasksGitHubViewControls(model: ConnectionPresentatio
|
||||
setShowGitHubProjectSortPicker(true)
|
||||
}}
|
||||
>
|
||||
<Text style={styles.segmentSecondaryText}>Sort: {githubProjectSortLabel}</Text>
|
||||
<Text style={styles.segmentSecondaryText}>
|
||||
{translate('tasks.githubViewControls.sort', 'Sort: {{sort}}', {
|
||||
sort: githubProjectSortLabel
|
||||
})}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
{githubProjectAvailableSummaryFields.length > 0 ? (
|
||||
@@ -124,7 +133,11 @@ export function renderMobileTasksGitHubViewControls(model: ConnectionPresentatio
|
||||
setShowGitHubProjectFieldsPicker(true)
|
||||
}}
|
||||
>
|
||||
<Text style={styles.segmentSecondaryText}>Fields: {githubProjectFieldsLabel}</Text>
|
||||
<Text style={styles.segmentSecondaryText}>
|
||||
{translate('tasks.githubViewControls.fields', 'Fields: {{fields}}', {
|
||||
fields: githubProjectFieldsLabel
|
||||
})}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
{githubProjectTable ? (
|
||||
@@ -135,7 +148,10 @@ export function renderMobileTasksGitHubViewControls(model: ConnectionPresentatio
|
||||
{selectedGitHubProjectViewUrl ? (
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Open view in GitHub"
|
||||
accessibilityLabel={translate(
|
||||
'tasks.githubViewControls.openView',
|
||||
'Open view in GitHub'
|
||||
)}
|
||||
style={styles.segmentIconButton}
|
||||
disabled={!taskUiReady}
|
||||
onPress={() => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
View,
|
||||
Pressable,
|
||||
@@ -59,7 +60,9 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel)
|
||||
>
|
||||
<Plus size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>
|
||||
{creatingKey === actionItem.key ? 'Creating...' : 'Create Workspace'}
|
||||
{creatingKey === actionItem.key
|
||||
? translate('tasks.itemActions.creating', 'Creating...')
|
||||
: translate('tasks.itemActions.createWorkspace', 'Create Workspace')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
|
||||
@@ -83,7 +86,9 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel)
|
||||
>
|
||||
<Copy size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>
|
||||
{copiedLinkKey === `linear-url:${actionItem.key}` ? 'Copied' : 'Copy Linear link'}
|
||||
{copiedLinkKey === `linear-url:${actionItem.key}`
|
||||
? translate('common.copied', 'Copied')
|
||||
: translate('tasks.itemActions.copyLinearLink', 'Copy Linear link')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
@@ -98,7 +103,9 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel)
|
||||
>
|
||||
<Copy size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>
|
||||
{copiedLinkKey === `task:${actionItem.key}` ? 'Copied' : 'Copy GitHub link'}
|
||||
{copiedLinkKey === `task:${actionItem.key}`
|
||||
? translate('common.copied', 'Copied')
|
||||
: translate('tasks.itemActions.copyGitHubLink', 'Copy GitHub link')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
@@ -142,10 +149,14 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel)
|
||||
}
|
||||
>
|
||||
<GitBranch size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>Merge pull request</Text>
|
||||
<Text style={styles.actionText}>
|
||||
{translate('tasks.itemActions.mergePullRequest', 'Merge pull request')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
{isGitHubPrMergeBlocked(actionItem) ? (
|
||||
<Text style={styles.emptyInlineText}>GitHub reports merge conflicts.</Text>
|
||||
<Text style={styles.emptyInlineText}>
|
||||
{translate('tasks.itemActions.mergeConflicts', 'GitHub reports merge conflicts.')}
|
||||
</Text>
|
||||
) : null}
|
||||
</>
|
||||
) : null}
|
||||
@@ -190,7 +201,9 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel)
|
||||
}
|
||||
>
|
||||
<GitBranch size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>Merge merge request</Text>
|
||||
<Text style={styles.actionText}>
|
||||
{translate('tasks.itemActions.mergeMergeRequest', 'Merge merge request')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
) : null}
|
||||
@@ -206,7 +219,9 @@ export function renderMobileTasksItemActions(model: ConnectionPresentationModel)
|
||||
}}
|
||||
>
|
||||
<GitBranch size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>Change status</Text>
|
||||
<Text style={styles.actionText}>
|
||||
{translate('tasks.itemActions.changeStatus', 'Change status')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { isBrokenCheck } from '../../../src/shared/pr-checks-fix-prompt'
|
||||
import {
|
||||
View,
|
||||
@@ -27,6 +28,12 @@ import {
|
||||
import { renderMobileTasksItemFieldEditors } from './mobile-tasks-item-field-editors'
|
||||
import { JiraDetailMeta } from '../components/JiraDetailMeta'
|
||||
|
||||
function pipelineJobsSummary(count: number): string {
|
||||
return count === 1
|
||||
? translate('tasks.itemDetailContent.pipelineJobs_one', '{{count}} jobs', { count })
|
||||
: translate('tasks.itemDetailContent.pipelineJobs_other', '{{count}} jobs', { count })
|
||||
}
|
||||
|
||||
export function renderMobileTasksItemDetailContent(model: ConnectionPresentationModel) {
|
||||
const {
|
||||
actionItem,
|
||||
@@ -63,22 +70,30 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation
|
||||
<>
|
||||
<View style={styles.detailMetaGrid}>
|
||||
<View style={styles.detailMetaItem}>
|
||||
<Text style={styles.detailMetaLabel}>Type</Text>
|
||||
<Text style={styles.detailMetaLabel}>
|
||||
{translate('tasks.itemDetailContent.type', 'Type')}
|
||||
</Text>
|
||||
<Text style={styles.detailMetaValue}>{taskKindLabel(actionItem)}</Text>
|
||||
</View>
|
||||
<View style={styles.detailMetaItem}>
|
||||
<Text style={styles.detailMetaLabel}>Status</Text>
|
||||
<Text style={styles.detailMetaLabel}>
|
||||
{translate('tasks.itemDetailContent.status', 'Status')}
|
||||
</Text>
|
||||
<Text style={styles.detailMetaValue}>{actionItem.status}</Text>
|
||||
</View>
|
||||
{detailPayload.provider === 'linear' && detailPayload.assignee ? (
|
||||
<View style={styles.detailMetaItem}>
|
||||
<Text style={styles.detailMetaLabel}>Assignee</Text>
|
||||
<Text style={styles.detailMetaLabel}>
|
||||
{translate('tasks.itemDetailContent.assignee', 'Assignee')}
|
||||
</Text>
|
||||
<Text style={styles.detailMetaValue}>{detailPayload.assignee}</Text>
|
||||
</View>
|
||||
) : null}
|
||||
{detailPayload.provider === 'linear' && detailPayload.project ? (
|
||||
<View style={styles.detailMetaItem}>
|
||||
<Text style={styles.detailMetaLabel}>Project</Text>
|
||||
<Text style={styles.detailMetaLabel}>
|
||||
{translate('tasks.itemDetailContent.project', 'Project')}
|
||||
</Text>
|
||||
<Text style={styles.detailMetaValue}>{detailPayload.project.name}</Text>
|
||||
</View>
|
||||
) : null}
|
||||
@@ -92,7 +107,9 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation
|
||||
{(detailPayload.provider === 'github' || detailPayload.provider === 'gitlab') &&
|
||||
detailPayload.assignees.length > 0 ? (
|
||||
<View style={styles.detailMetaItem}>
|
||||
<Text style={styles.detailMetaLabel}>Assignees</Text>
|
||||
<Text style={styles.detailMetaLabel}>
|
||||
{translate('tasks.itemDetailContent.assignees', 'Assignees')}
|
||||
</Text>
|
||||
<Text style={styles.detailMetaValue}>{detailPayload.assignees.join(', ')}</Text>
|
||||
</View>
|
||||
) : null}
|
||||
@@ -109,7 +126,9 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation
|
||||
) : null}
|
||||
|
||||
<View style={styles.detailSection}>
|
||||
<Text style={styles.detailSectionTitle}>Description</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.itemDetailContent.description', 'Description')}
|
||||
</Text>
|
||||
{renderMobileTasksItemBodyEditor(model)}
|
||||
</View>
|
||||
|
||||
@@ -123,33 +142,41 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation
|
||||
actionItem.source.type === 'pr' ? (
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Checks</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.itemDetailContent.checks', 'Checks')}
|
||||
</Text>
|
||||
<View style={styles.inlineActionRow}>
|
||||
<Pressable
|
||||
style={styles.inlineSaveButtonCompact}
|
||||
disabled={mutatingStatus}
|
||||
onPress={() => void refreshGitHubChecks(actionItem)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Refresh</Text>
|
||||
<Text style={styles.inlineSaveText}>{translate('common.refresh', 'Refresh')}</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={styles.inlineSaveButtonCompact}
|
||||
disabled={mutatingStatus || !detailPayload.checks.some(isBrokenCheck)}
|
||||
onPress={() => void rerunGitHubChecks(actionItem, true)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Rerun failed</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.itemDetailContent.rerunFailed', 'Rerun failed')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={styles.inlineSaveButtonCompact}
|
||||
disabled={mutatingStatus || detailPayload.checks.length === 0}
|
||||
onPress={() => void rerunGitHubChecks(actionItem, false)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Rerun all</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.itemDetailContent.rerunAll', 'Rerun all')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
{detailPayload.checks.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No checks found.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.itemDetailContent.noChecks', 'No checks found.')}
|
||||
</Text>
|
||||
) : (
|
||||
detailPayload.checks.map((check) => (
|
||||
<Pressable
|
||||
@@ -180,15 +207,19 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation
|
||||
actionItem.source.type === 'mr' ? (
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Pipeline</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.itemDetailContent.pipeline', 'Pipeline')}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{detailPayload.pipelineJobs.length
|
||||
? `${detailPayload.pipelineJobs.length} jobs`
|
||||
: 'None'}
|
||||
? pipelineJobsSummary(detailPayload.pipelineJobs.length)
|
||||
: translate('tasks.itemDetailContent.none', 'None')}
|
||||
</Text>
|
||||
</View>
|
||||
{detailPayload.pipelineJobs.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No pipeline runs for this MR.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.itemDetailContent.noPipelineRuns', 'No pipeline runs for this MR.')}
|
||||
</Text>
|
||||
) : (
|
||||
detailPayload.pipelineJobs.map((job) => {
|
||||
const duration = formatDurationSeconds(job.duration)
|
||||
@@ -228,11 +259,17 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation
|
||||
actionItem.provider === 'linear' ? (
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Sub-issues</Text>
|
||||
<Text style={styles.detailSectionMeta}>{detailPayload.children.length || 'None'}</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.itemDetailContent.subIssues', 'Sub-issues')}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{detailPayload.children.length || translate('tasks.itemDetailContent.none', 'None')}
|
||||
</Text>
|
||||
</View>
|
||||
{detailPayload.children.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No sub-issues.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.itemDetailContent.noSubIssues', 'No sub-issues.')}
|
||||
</Text>
|
||||
) : (
|
||||
detailPayload.children.map((child) => (
|
||||
<Pressable
|
||||
@@ -244,7 +281,7 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation
|
||||
<Text style={styles.detailLine}>
|
||||
{child.identifier} · {child.title}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>Open</Text>
|
||||
<Text style={styles.detailSectionMeta}>{translate('common.open', 'Open')}</Text>
|
||||
</Pressable>
|
||||
))
|
||||
)}
|
||||
@@ -252,7 +289,7 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation
|
||||
style={[styles.input, styles.stackedInput]}
|
||||
value={linearSubIssueTitle}
|
||||
onChangeText={setLinearSubIssueTitle}
|
||||
placeholder="Sub-issue title"
|
||||
placeholder={translate('tasks.itemDetailContent.subIssueTitle', 'Sub-issue title')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
/>
|
||||
<Pressable
|
||||
@@ -260,20 +297,26 @@ export function renderMobileTasksItemDetailContent(model: ConnectionPresentation
|
||||
disabled={mutatingStatus || linearSubIssueTitle.trim().length === 0}
|
||||
onPress={() => void createLinearSubIssue(actionItem)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Add sub-issue</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.itemDetailContent.addSubIssue', 'Add sub-issue')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Discussion</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.itemDetailContent.discussion', 'Discussion')}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{discussionSummary(detailPayload.comments.length)}
|
||||
</Text>
|
||||
</View>
|
||||
{detailPayload.comments.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No comments.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.itemDetailContent.noComments', 'No comments.')}
|
||||
</Text>
|
||||
) : (
|
||||
detailCommentGroups.map(renderDetailCommentGroup)
|
||||
)}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
BottomDrawer,
|
||||
View,
|
||||
@@ -32,7 +33,10 @@ export function renderMobileTasksItemDetailDrawer(model: ConnectionPresentationM
|
||||
<Pressable
|
||||
style={styles.iconButton}
|
||||
disabled={detailLoading}
|
||||
accessibilityLabel="Refresh details"
|
||||
accessibilityLabel={translate(
|
||||
'tasks.itemDetailDrawer.refreshDetails',
|
||||
'Refresh details'
|
||||
)}
|
||||
onPress={() => setDetailRefreshSeq((current) => current + 1)}
|
||||
>
|
||||
<RefreshCw
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
SHOW_MOBILE_DETAIL_METADATA_EDITORS,
|
||||
splitCommaList
|
||||
@@ -51,12 +52,14 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM
|
||||
detailPayload.provider === 'gitlab')) ? (
|
||||
<>
|
||||
<View style={styles.detailSection}>
|
||||
<Text style={styles.detailSectionTitle}>Title</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.itemFieldEditors.title', 'Title')}
|
||||
</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
value={itemTitleDraft}
|
||||
onChangeText={setItemTitleDraft}
|
||||
placeholder="Title"
|
||||
placeholder={translate('tasks.itemFieldEditors.title', 'Title')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
/>
|
||||
<Pressable
|
||||
@@ -86,25 +89,35 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Save title</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.itemFieldEditors.saveTitle', 'Save title')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Labels</Text>
|
||||
<Text style={styles.detailSectionMeta}>{detailPayload.labels.length || 'None'}</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.itemFieldEditors.labels', 'Labels')}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{detailPayload.labels.length || translate('tasks.itemFieldEditors.none', 'None')}
|
||||
</Text>
|
||||
</View>
|
||||
{actionItem.provider === 'github' ? (
|
||||
itemLabelsLoading ? (
|
||||
<View style={styles.detailLoadingInline}>
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
<Text style={styles.detailMuted}>Loading labels...</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.itemFieldEditors.loadingLabels', 'Loading labels...')}
|
||||
</Text>
|
||||
</View>
|
||||
) : itemLabelsError ? (
|
||||
<Text style={styles.detailError}>{itemLabelsError}</Text>
|
||||
) : itemAvailableLabels.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No labels in this repository.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.itemFieldEditors.noLabels', 'No labels in this repository.')}
|
||||
</Text>
|
||||
) : (
|
||||
<View style={styles.chipRow}>
|
||||
{[...new Set([...itemAvailableLabels, ...detailPayload.labels])].map((label) => {
|
||||
@@ -136,7 +149,10 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM
|
||||
style={styles.input}
|
||||
value={itemAddLabelsDraft}
|
||||
onChangeText={setItemAddLabelsDraft}
|
||||
placeholder="Add labels, comma separated"
|
||||
placeholder={translate(
|
||||
'tasks.itemFieldEditors.addLabels',
|
||||
'Add labels, comma separated'
|
||||
)}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
@@ -144,7 +160,10 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM
|
||||
style={[styles.input, styles.stackedInput]}
|
||||
value={itemRemoveLabelsDraft}
|
||||
onChangeText={setItemRemoveLabelsDraft}
|
||||
placeholder="Remove labels, comma separated"
|
||||
placeholder={translate(
|
||||
'tasks.itemFieldEditors.removeLabels',
|
||||
'Remove labels, comma separated'
|
||||
)}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
@@ -162,7 +181,9 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM
|
||||
})
|
||||
}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Update labels</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.itemFieldEditors.updateLabels', 'Update labels')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
)}
|
||||
@@ -170,19 +191,30 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM
|
||||
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Assignees</Text>
|
||||
<Text style={styles.detailSectionMeta}>{detailPayload.assignees.length || 'None'}</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.itemFieldEditors.assignees', 'Assignees')}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{detailPayload.assignees.length || translate('tasks.itemFieldEditors.none', 'None')}
|
||||
</Text>
|
||||
</View>
|
||||
{actionItem.provider === 'github' ? (
|
||||
itemAssignableUsersLoading ? (
|
||||
<View style={styles.detailLoadingInline}>
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
<Text style={styles.detailMuted}>Loading assignees...</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.itemFieldEditors.loadingAssignees', 'Loading assignees...')}
|
||||
</Text>
|
||||
</View>
|
||||
) : itemAssignableUsersError ? (
|
||||
<Text style={styles.detailError}>{itemAssignableUsersError}</Text>
|
||||
) : itemAssignableUsers.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No assignable users found for this repository.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate(
|
||||
'tasks.itemFieldEditors.noAssignableUsers',
|
||||
'No assignable users found for this repository.'
|
||||
)}
|
||||
</Text>
|
||||
) : (
|
||||
<View style={styles.chipRow}>
|
||||
{[
|
||||
@@ -227,7 +259,10 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM
|
||||
style={styles.input}
|
||||
value={itemAddAssigneesDraft}
|
||||
onChangeText={setItemAddAssigneesDraft}
|
||||
placeholder="Add usernames, comma separated"
|
||||
placeholder={translate(
|
||||
'tasks.itemFieldEditors.addUsernames',
|
||||
'Add usernames, comma separated'
|
||||
)}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
@@ -235,7 +270,10 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM
|
||||
style={[styles.input, styles.stackedInput]}
|
||||
value={itemRemoveAssigneesDraft}
|
||||
onChangeText={setItemRemoveAssigneesDraft}
|
||||
placeholder="Remove usernames, comma separated"
|
||||
placeholder={translate(
|
||||
'tasks.itemFieldEditors.removeUsernames',
|
||||
'Remove usernames, comma separated'
|
||||
)}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
@@ -253,7 +291,9 @@ export function renderMobileTasksItemFieldEditors(model: ConnectionPresentationM
|
||||
})
|
||||
}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Update assignees</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.itemFieldEditors.updateAssignees', 'Update assignees')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
SHOW_MOBILE_DETAIL_METADATA_EDITORS,
|
||||
SHOW_MOBILE_DETAIL_REVIEW_PANELS,
|
||||
@@ -46,7 +47,7 @@ export function renderMobileTasksItemBodyEditor(model: ConnectionPresentationMod
|
||||
style={[styles.input, styles.bodyInput]}
|
||||
value={itemBodyDraft}
|
||||
onChangeText={setItemBodyDraft}
|
||||
placeholder="Description"
|
||||
placeholder={translate('tasks.itemReviewSections.descriptionPlaceholder', 'Description')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
multiline
|
||||
textAlignVertical="top"
|
||||
@@ -77,12 +78,20 @@ export function renderMobileTasksItemBodyEditor(model: ConnectionPresentationMod
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Save description</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.itemReviewSections.saveDescription', 'Save description')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<MobileMarkdown content={itemBodyDraft} fallback="No description." />
|
||||
<MobileMarkdown
|
||||
content={itemBodyDraft}
|
||||
fallback={translate('tasks.itemReviewSections.noDescription', 'No description.')}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<MobileMarkdown content={detailPayloadBody(detailPayload)} fallback="No description." />
|
||||
<MobileMarkdown
|
||||
content={detailPayloadBody(detailPayload)}
|
||||
fallback={translate('tasks.itemReviewSections.noDescription', 'No description.')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -107,14 +116,18 @@ export function renderMobileTasksItemReviewPanel(model: ConnectionPresentationMo
|
||||
actionItem.source.type === 'pr' ? (
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Reviewers</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.itemReviewSections.reviewersTitle', 'Reviewers')}
|
||||
</Text>
|
||||
{detailPayload.provider === 'github' ? (
|
||||
<Text style={styles.detailSectionMeta}>{getGitHubReviewSummary(detailPayload)}</Text>
|
||||
) : null}
|
||||
</View>
|
||||
{detailPayload.provider === 'github' ? (
|
||||
getGitHubReviewerRows(detailPayload).length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No reviewers requested.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.itemReviewSections.noReviewersRequested', 'No reviewers requested.')}
|
||||
</Text>
|
||||
) : (
|
||||
getGitHubReviewerRows(detailPayload).map((reviewer) => (
|
||||
<View key={reviewer.login} style={styles.reviewerRow}>
|
||||
@@ -141,12 +154,19 @@ export function renderMobileTasksItemReviewPanel(model: ConnectionPresentationMo
|
||||
{itemAssignableUsersLoading ? (
|
||||
<View style={styles.detailLoadingInline}>
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
<Text style={styles.detailMuted}>Loading reviewers...</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.itemReviewSections.loadingReviewers', 'Loading reviewers...')}
|
||||
</Text>
|
||||
</View>
|
||||
) : itemAssignableUsersError ? (
|
||||
<Text style={styles.detailError}>{itemAssignableUsersError}</Text>
|
||||
) : itemReviewerCandidates.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No reviewer suggestions found.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate(
|
||||
'tasks.itemReviewSections.noReviewerSuggestions',
|
||||
'No reviewer suggestions found.'
|
||||
)}
|
||||
</Text>
|
||||
) : (
|
||||
<View style={styles.chipRow}>
|
||||
{itemReviewerCandidates.map((user) => {
|
||||
@@ -171,7 +191,10 @@ export function renderMobileTasksItemReviewPanel(model: ConnectionPresentationMo
|
||||
style={styles.input}
|
||||
value={itemReviewersDraft}
|
||||
onChangeText={setItemReviewersDraft}
|
||||
placeholder="Request reviewers"
|
||||
placeholder={translate(
|
||||
'tasks.itemReviewSections.reviewersPlaceholder',
|
||||
'Request reviewers'
|
||||
)}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
@@ -180,7 +203,9 @@ export function renderMobileTasksItemReviewPanel(model: ConnectionPresentationMo
|
||||
disabled={mutatingStatus || splitReviewerList(itemReviewersDraft).length === 0}
|
||||
onPress={() => void requestGitHubReviewers(actionItem)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Request review</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.itemReviewSections.requestReview', 'Request review')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
) : null
|
||||
@@ -207,7 +232,9 @@ export function renderMobileTasksItemFiles(model: ConnectionPresentationModel) {
|
||||
detailPayload.provider === 'github' &&
|
||||
detailPayload.files.length > 0 ? (
|
||||
<View style={styles.detailSection}>
|
||||
<Text style={styles.detailSectionTitle}>Changed files</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.itemReviewSections.changedFilesTitle', 'Changed files')}
|
||||
</Text>
|
||||
{detailPayload.files.map((file) =>
|
||||
actionItem.provider === 'github' && actionItem.source.type === 'pr' ? (
|
||||
<View key={file.path} style={styles.fileCard}>
|
||||
@@ -223,7 +250,9 @@ export function renderMobileTasksItemFiles(model: ConnectionPresentationModel) {
|
||||
: ''}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{expandedPrFilePath === file.path ? 'Hide' : 'View'}
|
||||
{expandedPrFilePath === file.path
|
||||
? translate('tasks.itemReviewSections.hideFile', 'Hide')
|
||||
: translate('tasks.itemReviewSections.viewFile', 'View')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
@@ -232,7 +261,9 @@ export function renderMobileTasksItemFiles(model: ConnectionPresentationModel) {
|
||||
onPress={() => void toggleGitHubFileViewed(actionItem, file)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{file.viewerViewedState === 'VIEWED' ? 'Mark unviewed' : 'Mark viewed'}
|
||||
{file.viewerViewedState === 'VIEWED'
|
||||
? translate('tasks.itemReviewSections.markUnviewed', 'Mark unviewed')
|
||||
: translate('tasks.itemReviewSections.markViewed', 'Mark viewed')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
{expandedPrFilePath === file.path ? (
|
||||
@@ -241,7 +272,9 @@ export function renderMobileTasksItemFiles(model: ConnectionPresentationModel) {
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
) : prFileContents[file.path]?.originalIsBinary ||
|
||||
prFileContents[file.path]?.modifiedIsBinary ? (
|
||||
<Text style={styles.detailMuted}>Binary file.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.itemReviewSections.binaryFile', 'Binary file.')}
|
||||
</Text>
|
||||
) : prFileContents[file.path] ? (
|
||||
<GitHubPrFileDiff
|
||||
filePath={file.path}
|
||||
@@ -259,7 +292,12 @@ export function renderMobileTasksItemFiles(model: ConnectionPresentationModel) {
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Text style={styles.detailMuted}>File contents unavailable.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate(
|
||||
'tasks.itemReviewSections.fileContentsUnavailable',
|
||||
'File contents unavailable.'
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
View,
|
||||
ActivityIndicator,
|
||||
@@ -86,7 +87,13 @@ export function renderMobileTasksLinearList(
|
||||
style={[styles.statusPillSelf, styles.linearStatePill]}
|
||||
disabled={mutatingStatus}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`Change status from ${issue.state.name}`}
|
||||
accessibilityLabel={translate(
|
||||
'tasks.linearList.changeStatusFrom',
|
||||
'Change status from {{status}}',
|
||||
{
|
||||
status: issue.state.name
|
||||
}
|
||||
)}
|
||||
onPress={(event) => {
|
||||
event.stopPropagation()
|
||||
triggerMediumImpact()
|
||||
@@ -175,7 +182,13 @@ export function renderMobileTasksLinearList(
|
||||
style={[styles.statusPill, styles.linearStatePill]}
|
||||
disabled={mutatingStatus}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`Change status from ${issue.state.name}`}
|
||||
accessibilityLabel={translate(
|
||||
'tasks.linearList.changeStatusFrom',
|
||||
'Change status from {{status}}',
|
||||
{
|
||||
status: issue.state.name
|
||||
}
|
||||
)}
|
||||
onPress={(event) => {
|
||||
event.stopPropagation()
|
||||
triggerMediumImpact()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { Pressable, Text } from './mobile-tasks-dependencies'
|
||||
import { styles } from './mobile-tasks-legacy-styles'
|
||||
|
||||
@@ -86,7 +87,11 @@ export function renderMobileTasksLinearViewControls(model: ConnectionPresentatio
|
||||
setShowLinearGroupPicker(true)
|
||||
}}
|
||||
>
|
||||
<Text style={styles.segmentSecondaryText}>Group: {linearGroupLabel}</Text>
|
||||
<Text style={styles.segmentSecondaryText}>
|
||||
{translate('tasks.linearViewControls.groupLabel', 'Group: {{group}}', {
|
||||
group: linearGroupLabel
|
||||
})}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={styles.segmentButton}
|
||||
@@ -98,7 +103,11 @@ export function renderMobileTasksLinearViewControls(model: ConnectionPresentatio
|
||||
setShowLinearOrderPicker(true)
|
||||
}}
|
||||
>
|
||||
<Text style={styles.segmentSecondaryText}>Order: {linearOrderLabel}</Text>
|
||||
<Text style={styles.segmentSecondaryText}>
|
||||
{translate('tasks.linearViewControls.orderLabel', 'Order: {{order}}', {
|
||||
order: linearOrderLabel
|
||||
})}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={styles.segmentButton}
|
||||
@@ -110,7 +119,9 @@ export function renderMobileTasksLinearViewControls(model: ConnectionPresentatio
|
||||
setShowLinearDisplayPicker(true)
|
||||
}}
|
||||
>
|
||||
<Text style={styles.segmentSecondaryText}>Display</Text>
|
||||
<Text style={styles.segmentSecondaryText}>
|
||||
{translate('tasks.linearViewControls.displayButton', 'Display')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
BottomDrawer,
|
||||
View,
|
||||
@@ -28,7 +29,7 @@ export function renderMobileTasksLinearViewPicker(model: ConnectionPresentationM
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showLinearViewPicker}
|
||||
title="Linear View"
|
||||
title={translate('tasks.listDisplayPickers.linearViewTitle', 'Linear View')}
|
||||
options={LINEAR_VIEW_OPTIONS}
|
||||
selected={linearViewMode}
|
||||
onSelect={setLinearViewMode}
|
||||
@@ -48,7 +49,7 @@ export function renderMobileTasksLinearGroupPicker(model: ConnectionPresentation
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showLinearGroupPicker}
|
||||
title="Group Linear Issues"
|
||||
title={translate('tasks.listDisplayPickers.linearGroupTitle', 'Group Linear Issues')}
|
||||
options={LINEAR_GROUP_OPTIONS}
|
||||
selected={linearGroupBy}
|
||||
onSelect={setLinearGroupBy}
|
||||
@@ -68,7 +69,7 @@ export function renderMobileTasksLinearOrderPicker(model: ConnectionPresentation
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showLinearOrderPicker}
|
||||
title="Order Linear Issues"
|
||||
title={translate('tasks.listDisplayPickers.linearOrderTitle', 'Order Linear Issues')}
|
||||
options={LINEAR_ORDER_OPTIONS}
|
||||
selected={linearOrderBy}
|
||||
onSelect={setLinearOrderBy}
|
||||
@@ -92,7 +93,9 @@ export function renderMobileTasksLinearDisplayPicker(model: ConnectionPresentati
|
||||
onClose={() => setShowLinearDisplayPicker(false)}
|
||||
>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>Display Properties</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate('tasks.listDisplayPickers.displayPropertiesTitle', 'Display Properties')}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.repoPickerGroup}>
|
||||
{LINEAR_DISPLAY_OPTIONS.map((property, index) => {
|
||||
@@ -135,7 +138,7 @@ export function renderMobileTasksSortPicker(model: ConnectionPresentationModel)
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showSortPicker}
|
||||
title="Sort Tasks"
|
||||
title={translate('tasks.listDisplayPickers.sortTasksTitle', 'Sort Tasks')}
|
||||
options={SORT_OPTIONS}
|
||||
selected={taskSort}
|
||||
onSelect={setTaskSort}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
@@ -36,9 +37,14 @@ export function renderMobileTasksListSurface(
|
||||
return !tasksSupported ? (
|
||||
tasksUnsupported ? (
|
||||
<View style={styles.centered}>
|
||||
<Text style={styles.emptyText}>Update Orca desktop</Text>
|
||||
<Text style={styles.emptyText}>
|
||||
{translate('tasks.listSurface.updateDesktopTitle', 'Update Orca desktop')}
|
||||
</Text>
|
||||
<Text style={styles.centeredHint}>
|
||||
This mobile Tasks view needs a newer desktop runtime.
|
||||
{translate(
|
||||
'tasks.listSurface.updateDesktopMessage',
|
||||
'This mobile Tasks view needs a newer desktop runtime.'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
@@ -53,16 +59,25 @@ export function renderMobileTasksListSurface(
|
||||
disabled={!taskUiReady}
|
||||
onCheckAgain={() => {
|
||||
void refreshJiraConnection().catch((err: unknown) => {
|
||||
setError(err instanceof Error ? err.message : 'Failed to read Jira status')
|
||||
setError(
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate('tasks.listSurface.jiraStatusFailed', 'Failed to read Jira status')
|
||||
)
|
||||
})
|
||||
}}
|
||||
/>
|
||||
) : provider === 'linear' && !linearConnected ? (
|
||||
<View style={styles.centered}>
|
||||
<TaskProviderLogo provider="linear" size={32} color={colors.textSecondary} />
|
||||
<Text style={styles.emptyText}>Connect your Linear account</Text>
|
||||
<Text style={styles.emptyText}>
|
||||
{translate('tasks.listSurface.connectLinearTitle', 'Connect your Linear account')}
|
||||
</Text>
|
||||
<Text style={styles.centeredHint}>
|
||||
Browse and start work on your assigned Linear issues directly from Tasks.
|
||||
{translate(
|
||||
'tasks.listSurface.connectLinearMessage',
|
||||
'Browse and start work on your assigned Linear issues directly from Tasks.'
|
||||
)}
|
||||
</Text>
|
||||
<Pressable
|
||||
style={[styles.targetButton, styles.centerActionButton]}
|
||||
@@ -77,7 +92,9 @@ export function renderMobileTasksListSurface(
|
||||
setShowLinearConnect(true)
|
||||
}}
|
||||
>
|
||||
<Text style={styles.targetButtonText}>Connect Linear</Text>
|
||||
<Text style={styles.targetButtonText}>
|
||||
{translate('tasks.listSurface.connectLinearButton', 'Connect Linear')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
) : provider === 'github' && githubMode === 'project' ? (
|
||||
|
||||
@@ -23,12 +23,30 @@ import type {
|
||||
} from './mobile-tasks-view-state-types'
|
||||
import type { ActionableTaskItem } from './mobile-tasks-project-workspace-types'
|
||||
import type { LinearIssue } from './mobile-tasks-provider-detail-types'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
export const PROVIDER_OPTIONS: PickerOption<TaskProvider>[] = [
|
||||
type TaskOptionCopy<T extends string> = Omit<PickerOption<T>, 'label' | 'subtitle'> & {
|
||||
label: string | (() => string)
|
||||
subtitle?: () => string
|
||||
}
|
||||
|
||||
function localizedTaskOptions<T extends string>(options: TaskOptionCopy<T>[]): PickerOption<T>[] {
|
||||
return options.map(({ label, subtitle, ...option }) => ({
|
||||
...option,
|
||||
get label() {
|
||||
return typeof label === 'string' ? label : label()
|
||||
},
|
||||
get subtitle() {
|
||||
return subtitle?.()
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
export const PROVIDER_OPTIONS = localizedTaskOptions<TaskProvider>([
|
||||
{
|
||||
value: 'github',
|
||||
label: 'GitHub',
|
||||
subtitle: 'Issues and pull requests',
|
||||
subtitle: () => translate('tasks.options.githubDescription', 'Issues and pull requests'),
|
||||
renderIcon: (selected) => (
|
||||
<TaskProviderLogo
|
||||
provider="github"
|
||||
@@ -40,7 +58,7 @@ export const PROVIDER_OPTIONS: PickerOption<TaskProvider>[] = [
|
||||
{
|
||||
value: 'gitlab',
|
||||
label: 'GitLab',
|
||||
subtitle: 'Issues and merge requests',
|
||||
subtitle: () => translate('tasks.options.gitlabDescription', 'Issues and merge requests'),
|
||||
renderIcon: (selected) => (
|
||||
<TaskProviderLogo
|
||||
provider="gitlab"
|
||||
@@ -52,7 +70,7 @@ export const PROVIDER_OPTIONS: PickerOption<TaskProvider>[] = [
|
||||
{
|
||||
value: 'linear',
|
||||
label: 'Linear',
|
||||
subtitle: 'Assigned and team issues',
|
||||
subtitle: () => translate('tasks.options.linearDescription', 'Assigned and team issues'),
|
||||
renderIcon: (selected) => (
|
||||
<TaskProviderLogo
|
||||
provider="linear"
|
||||
@@ -64,7 +82,7 @@ export const PROVIDER_OPTIONS: PickerOption<TaskProvider>[] = [
|
||||
{
|
||||
value: 'jira',
|
||||
label: 'Jira',
|
||||
subtitle: 'Assigned and reported issues',
|
||||
subtitle: () => translate('tasks.options.jiraDescription', 'Assigned and reported issues'),
|
||||
renderIcon: (selected) => (
|
||||
<TaskProviderLogo
|
||||
provider="jira"
|
||||
@@ -73,26 +91,70 @@ export const PROVIDER_OPTIONS: PickerOption<TaskProvider>[] = [
|
||||
/>
|
||||
)
|
||||
}
|
||||
]
|
||||
])
|
||||
|
||||
export const GITLAB_FILTER_OPTIONS: PickerOption<GitLabFilter>[] = [
|
||||
{ value: 'opened', label: 'Open', subtitle: 'Open issues and merge requests' },
|
||||
{ value: 'merged', label: 'Merged', subtitle: 'Merged merge requests' },
|
||||
{ value: 'closed', label: 'Closed', subtitle: 'Closed issues and merge requests' },
|
||||
{ value: 'all', label: 'All', subtitle: 'Any GitLab state' }
|
||||
]
|
||||
export const GITLAB_FILTER_OPTIONS = localizedTaskOptions<GitLabFilter>([
|
||||
{
|
||||
value: 'opened',
|
||||
label: () => translate('tasks.options.openState', 'Open'),
|
||||
subtitle: () =>
|
||||
translate('tasks.options.gitlabOpenDescription', 'Open issues and merge requests')
|
||||
},
|
||||
{
|
||||
value: 'merged',
|
||||
label: () => translate('tasks.options.mergedState', 'Merged'),
|
||||
subtitle: () => translate('tasks.options.gitlabMergedDescription', 'Merged merge requests')
|
||||
},
|
||||
{
|
||||
value: 'closed',
|
||||
label: () => translate('tasks.options.closedState', 'Closed'),
|
||||
subtitle: () =>
|
||||
translate('tasks.options.gitlabClosedDescription', 'Closed issues and merge requests')
|
||||
},
|
||||
{
|
||||
value: 'all',
|
||||
label: () => translate('tasks.options.all', 'All'),
|
||||
subtitle: () => translate('tasks.options.gitlabAllDescription', 'Any GitLab state')
|
||||
}
|
||||
])
|
||||
|
||||
export const LINEAR_FILTER_OPTIONS: PickerOption<LinearFilter>[] = [
|
||||
{ value: 'all', label: 'All', subtitle: 'Open issues across connected workspaces' },
|
||||
{ value: 'assigned', label: 'My Issues', subtitle: 'Issues assigned to you' },
|
||||
{ value: 'created', label: 'Created', subtitle: 'Issues created by you' },
|
||||
{ value: 'completed', label: 'Completed', subtitle: 'Recently completed issues' }
|
||||
]
|
||||
export const LINEAR_FILTER_OPTIONS = localizedTaskOptions<LinearFilter>([
|
||||
{
|
||||
value: 'all',
|
||||
label: () => translate('tasks.options.all', 'All'),
|
||||
subtitle: () =>
|
||||
translate('tasks.options.linearAllDescription', 'Open issues across connected workspaces')
|
||||
},
|
||||
{
|
||||
value: 'assigned',
|
||||
label: () => translate('tasks.options.myIssues', 'My Issues'),
|
||||
subtitle: () => translate('tasks.options.linearAssignedDescription', 'Issues assigned to you')
|
||||
},
|
||||
{
|
||||
value: 'created',
|
||||
label: () => translate('tasks.options.createdState', 'Created'),
|
||||
subtitle: () => translate('tasks.options.linearCreatedDescription', 'Issues created by you')
|
||||
},
|
||||
{
|
||||
value: 'completed',
|
||||
label: () => translate('tasks.options.completedState', 'Completed'),
|
||||
subtitle: () =>
|
||||
translate('tasks.options.linearCompletedDescription', 'Recently completed issues')
|
||||
}
|
||||
])
|
||||
|
||||
export const LINEAR_VIEW_OPTIONS: PickerOption<LinearViewMode>[] = [
|
||||
{ value: 'list', label: 'List', subtitle: 'Compact issue rows' },
|
||||
{ value: 'board', label: 'Board', subtitle: 'Grouped columns' }
|
||||
]
|
||||
export const LINEAR_VIEW_OPTIONS = localizedTaskOptions<LinearViewMode>([
|
||||
{
|
||||
value: 'list',
|
||||
label: () => translate('tasks.options.list', 'List'),
|
||||
subtitle: () => translate('tasks.options.listDescription', 'Compact issue rows')
|
||||
},
|
||||
{
|
||||
value: 'board',
|
||||
label: () => translate('tasks.options.board', 'Board'),
|
||||
subtitle: () => translate('tasks.options.boardDescription', 'Grouped columns')
|
||||
}
|
||||
])
|
||||
|
||||
export function taskWorkspaceFallback(item: ActionableTaskItem): string {
|
||||
if (item.provider === 'github' || item.provider === 'gitlab') {
|
||||
@@ -120,28 +182,28 @@ export const COMMENT_REACTION_EMOJI: Record<string, string> = {
|
||||
eyes: 'eyes'
|
||||
}
|
||||
|
||||
export const LINEAR_GROUP_OPTIONS: PickerOption<LinearGroupBy>[] = [
|
||||
{ value: 'none', label: 'No grouping' },
|
||||
{ value: 'status', label: 'Status' },
|
||||
{ value: 'assignee', label: 'Assignee' },
|
||||
{ value: 'priority', label: 'Priority' },
|
||||
{ value: 'team', label: 'Team' }
|
||||
]
|
||||
export const LINEAR_GROUP_OPTIONS = localizedTaskOptions<LinearGroupBy>([
|
||||
{ value: 'none', label: () => translate('tasks.options.noGrouping', 'No grouping') },
|
||||
{ value: 'status', label: () => translate('tasks.options.status', 'Status') },
|
||||
{ value: 'assignee', label: () => translate('tasks.options.assignee', 'Assignee') },
|
||||
{ value: 'priority', label: () => translate('tasks.options.priority', 'Priority') },
|
||||
{ value: 'team', label: () => translate('tasks.options.team', 'Team') }
|
||||
])
|
||||
|
||||
export const LINEAR_ORDER_OPTIONS: PickerOption<LinearOrderBy>[] = [
|
||||
{ value: 'priority', label: 'Priority' },
|
||||
{ value: 'updated', label: 'Updated' },
|
||||
{ value: 'identifier', label: 'Identifier' }
|
||||
]
|
||||
export const LINEAR_ORDER_OPTIONS = localizedTaskOptions<LinearOrderBy>([
|
||||
{ value: 'priority', label: () => translate('tasks.options.priority', 'Priority') },
|
||||
{ value: 'updated', label: () => translate('tasks.options.updated', 'Updated') },
|
||||
{ value: 'identifier', label: () => translate('tasks.options.identifier', 'Identifier') }
|
||||
])
|
||||
|
||||
export const LINEAR_DISPLAY_OPTIONS: PickerOption<LinearDisplayProperty>[] = [
|
||||
{ value: 'state', label: 'Status' },
|
||||
{ value: 'priority', label: 'Priority' },
|
||||
{ value: 'assignee', label: 'Assignee' },
|
||||
{ value: 'team', label: 'Team' },
|
||||
{ value: 'labels', label: 'Labels' },
|
||||
{ value: 'updated', label: 'Updated' }
|
||||
]
|
||||
export const LINEAR_DISPLAY_OPTIONS = localizedTaskOptions<LinearDisplayProperty>([
|
||||
{ value: 'state', label: () => translate('tasks.options.status', 'Status') },
|
||||
{ value: 'priority', label: () => translate('tasks.options.priority', 'Priority') },
|
||||
{ value: 'assignee', label: () => translate('tasks.options.assignee', 'Assignee') },
|
||||
{ value: 'team', label: () => translate('tasks.options.team', 'Team') },
|
||||
{ value: 'labels', label: () => translate('tasks.options.labels', 'Labels') },
|
||||
{ value: 'updated', label: () => translate('tasks.options.updated', 'Updated') }
|
||||
])
|
||||
|
||||
export const DEFAULT_LINEAR_DISPLAY_PROPERTIES: LinearDisplayProperty[] = [
|
||||
'state',
|
||||
@@ -152,36 +214,91 @@ export const DEFAULT_LINEAR_DISPLAY_PROPERTIES: LinearDisplayProperty[] = [
|
||||
'updated'
|
||||
]
|
||||
|
||||
export const GITHUB_KIND_OPTIONS: PickerOption<GitHubMode>[] = [
|
||||
{ value: 'issues', label: 'Issues', subtitle: 'GitHub issues' },
|
||||
{ value: 'prs', label: 'PRs', subtitle: 'GitHub pull requests' },
|
||||
{ value: 'project', label: 'Projects', subtitle: 'GitHub Projects views' }
|
||||
]
|
||||
export const GITHUB_KIND_OPTIONS = localizedTaskOptions<GitHubMode>([
|
||||
{
|
||||
value: 'issues',
|
||||
label: () => translate('tasks.options.issues', 'Issues'),
|
||||
subtitle: () => translate('tasks.options.githubIssuesDescription', 'GitHub issues')
|
||||
},
|
||||
{
|
||||
value: 'prs',
|
||||
label: () => translate('tasks.options.pullRequests', 'PRs'),
|
||||
subtitle: () => translate('tasks.options.githubPullRequestsDescription', 'GitHub pull requests')
|
||||
},
|
||||
{
|
||||
value: 'project',
|
||||
label: () => translate('tasks.options.projects', 'Projects'),
|
||||
subtitle: () => translate('tasks.options.githubProjectsDescription', 'GitHub Projects views')
|
||||
}
|
||||
])
|
||||
|
||||
export const ISSUE_PRESETS: PickerOption<GitHubPreset>[] = [
|
||||
{ value: 'issues', label: 'Open', subtitle: 'Open GitHub issues' },
|
||||
{ value: 'my-issues', label: 'Assigned to me', subtitle: 'Open issues assigned to you' }
|
||||
]
|
||||
export const ISSUE_PRESETS = localizedTaskOptions<GitHubPreset>([
|
||||
{
|
||||
value: 'issues',
|
||||
label: () => translate('tasks.options.openState', 'Open'),
|
||||
subtitle: () => translate('tasks.options.githubOpenIssuesDescription', 'Open GitHub issues')
|
||||
},
|
||||
{
|
||||
value: 'my-issues',
|
||||
label: () => translate('tasks.options.assignedToMe', 'Assigned to me'),
|
||||
subtitle: () =>
|
||||
translate('tasks.options.githubAssignedIssuesDescription', 'Open issues assigned to you')
|
||||
}
|
||||
])
|
||||
|
||||
export const PR_PRESETS: PickerOption<GitHubPreset>[] = [
|
||||
{ value: 'prs', label: 'Open', subtitle: 'Open pull requests' },
|
||||
{ value: 'my-prs', label: 'Mine', subtitle: 'Pull requests authored by you' },
|
||||
{ value: 'review', label: 'Needs review', subtitle: 'Review requests assigned to you' }
|
||||
]
|
||||
export const PR_PRESETS = localizedTaskOptions<GitHubPreset>([
|
||||
{
|
||||
value: 'prs',
|
||||
label: () => translate('tasks.options.openState', 'Open'),
|
||||
subtitle: () => translate('tasks.options.openPullRequestsDescription', 'Open pull requests')
|
||||
},
|
||||
{
|
||||
value: 'my-prs',
|
||||
label: () => translate('tasks.options.mine', 'Mine'),
|
||||
subtitle: () =>
|
||||
translate('tasks.options.myPullRequestsDescription', 'Pull requests authored by you')
|
||||
},
|
||||
{
|
||||
value: 'review',
|
||||
label: () => translate('tasks.options.needsReview', 'Needs review'),
|
||||
subtitle: () =>
|
||||
translate('tasks.options.reviewRequestsDescription', 'Review requests assigned to you')
|
||||
}
|
||||
])
|
||||
|
||||
export const GITLAB_VIEW_OPTIONS: PickerOption<GitLabView>[] = [
|
||||
{ value: 'project', label: 'Project MRs', subtitle: 'Merge requests and issues by repository' },
|
||||
{ value: 'todos', label: 'My Todos', subtitle: 'Pending GitLab todos' }
|
||||
]
|
||||
export const GITLAB_VIEW_OPTIONS = localizedTaskOptions<GitLabView>([
|
||||
{
|
||||
value: 'project',
|
||||
label: () => translate('tasks.options.projectMergeRequests', 'Project MRs'),
|
||||
subtitle: () =>
|
||||
translate(
|
||||
'tasks.options.projectMergeRequestsDescription',
|
||||
'Merge requests and issues by repository'
|
||||
)
|
||||
},
|
||||
{
|
||||
value: 'todos',
|
||||
label: () => translate('tasks.options.myTodos', 'My Todos'),
|
||||
subtitle: () => translate('tasks.options.myTodosDescription', 'Pending GitLab todos')
|
||||
}
|
||||
])
|
||||
|
||||
export const SORT_OPTIONS: PickerOption<TaskSort>[] = [
|
||||
{ value: 'updated', label: 'Updated', subtitle: 'Newest activity first' },
|
||||
export const SORT_OPTIONS = localizedTaskOptions<TaskSort>([
|
||||
{
|
||||
value: 'updated',
|
||||
label: () => translate('tasks.options.updated', 'Updated'),
|
||||
subtitle: () => translate('tasks.options.updatedSortDescription', 'Newest activity first')
|
||||
},
|
||||
{
|
||||
value: 'repository',
|
||||
label: 'Repository',
|
||||
subtitle: 'Group by repository, then newest activity'
|
||||
label: () => translate('tasks.options.repository', 'Repository'),
|
||||
subtitle: () =>
|
||||
translate(
|
||||
'tasks.options.repositorySortDescription',
|
||||
'Group by repository, then newest activity'
|
||||
)
|
||||
}
|
||||
]
|
||||
])
|
||||
|
||||
export type ProjectSortOverride = { fieldId: string; direction: GitHubProjectSortDirection }
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
@@ -24,6 +25,12 @@ import {
|
||||
projectRowType
|
||||
} from './mobile-tasks-legacy-foundation'
|
||||
|
||||
function resolvedCommentCountLabel(count: number): string {
|
||||
return count === 1
|
||||
? translate('tasks.projectComments.comments_one', '{{count}} comment', { count })
|
||||
: translate('tasks.projectComments.comments_other', '{{count}} comments', { count })
|
||||
}
|
||||
|
||||
export function renderMobileTasksProjectComments(model: ConnectionPresentationModel) {
|
||||
const {
|
||||
addProjectRowComment,
|
||||
@@ -53,13 +60,17 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo
|
||||
return projectRowDetail?.provider === 'github' ? (
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Discussion</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectComments.discussion', 'Discussion')}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{discussionSummary(projectRowDetail.comments.length)}
|
||||
</Text>
|
||||
</View>
|
||||
{projectRowDetail.comments.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No comments.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.projectComments.noComments', 'No comments.')}
|
||||
</Text>
|
||||
) : (
|
||||
projectDetailCommentGroups.map((group) => {
|
||||
const groupId = detailCommentGroupId(group)
|
||||
@@ -81,11 +92,26 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo
|
||||
}
|
||||
>
|
||||
<Text style={styles.resolvedCommentTitle} numberOfLines={1}>
|
||||
Resolved {group.kind === 'thread' ? 'thread' : 'comment'} by{' ' as string}
|
||||
{commentAuthor(root)}
|
||||
{group.kind === 'thread'
|
||||
? translate(
|
||||
'tasks.projectComments.resolvedThreadBy',
|
||||
'Resolved thread by {{author}}',
|
||||
{
|
||||
author: commentAuthor(root)
|
||||
}
|
||||
)
|
||||
: translate(
|
||||
'tasks.projectComments.resolvedCommentBy',
|
||||
'Resolved comment by {{author}}',
|
||||
{
|
||||
author: commentAuthor(root)
|
||||
}
|
||||
)}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{count > 1 ? `${count} comments` : 'Show'}
|
||||
{count > 1
|
||||
? resolvedCommentCountLabel(count)
|
||||
: translate('tasks.projectComments.show', 'Show')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
)
|
||||
@@ -120,7 +146,7 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo
|
||||
style={[styles.input, styles.commentInput]}
|
||||
value={projectEditingCommentDraft}
|
||||
onChangeText={setProjectEditingCommentDraft}
|
||||
placeholder="Edit comment"
|
||||
placeholder={translate('tasks.projectComments.editComment', 'Edit comment')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
multiline
|
||||
textAlignVertical="top"
|
||||
@@ -131,7 +157,9 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo
|
||||
disabled={projectMutating || projectEditingCommentDraft.trim().length === 0}
|
||||
onPress={() => void updateProjectRowComment(projectRowItem, comment)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Save</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('common.save', 'Save')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={styles.inlineSaveButtonCompact}
|
||||
@@ -141,7 +169,9 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo
|
||||
setProjectEditingCommentDraft('')
|
||||
}}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Cancel</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('common.cancel', 'Cancel')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</>
|
||||
@@ -160,7 +190,12 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo
|
||||
}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{comment.isResolved ? 'Reopen thread' : 'Resolve thread'}
|
||||
{comment.isResolved
|
||||
? translate('tasks.projectComments.reopenThread', 'Reopen thread')
|
||||
: translate(
|
||||
'tasks.projectComments.resolveThread',
|
||||
'Resolve thread'
|
||||
)}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
@@ -173,7 +208,7 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo
|
||||
[commentId]: next
|
||||
}))
|
||||
}
|
||||
placeholder="Reply"
|
||||
placeholder={translate('tasks.projectComments.reply', 'Reply')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
multiline
|
||||
textAlignVertical="top"
|
||||
@@ -183,7 +218,9 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo
|
||||
disabled={projectMutating || !(itemReplyDrafts[commentId] ?? '').trim()}
|
||||
onPress={() => void replyToProjectGitHubComment(projectRowItem, comment)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Reply</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.projectComments.reply', 'Reply')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={styles.inlineSaveButtonCompact}
|
||||
@@ -193,14 +230,18 @@ export function renderMobileTasksProjectComments(model: ConnectionPresentationMo
|
||||
setProjectEditingCommentDraft(comment.body)
|
||||
}}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Edit</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('common.edit', 'Edit')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={styles.inlineSaveButtonCompact}
|
||||
disabled={projectMutating}
|
||||
onPress={() => void deleteProjectRowComment(projectRowItem, comment)}
|
||||
>
|
||||
<Text style={styles.inlineDeleteText}>Delete</Text>
|
||||
<Text style={styles.inlineDeleteText}>
|
||||
{translate('common.delete', 'Delete')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
BottomDrawer,
|
||||
View,
|
||||
@@ -52,10 +53,15 @@ export function renderMobileTasksProjectMissingRepoDrawer(model: ConnectionPrese
|
||||
{projectRepoNotInOrca ? (
|
||||
<View>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>Repository not in Orca</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate('tasks.projectDetailDrawer.repositoryNotInOrca', 'Repository not in Orca')}
|
||||
</Text>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
{projectRepoNotInOrca.owner}/{projectRepoNotInOrca.repo} is not added to Orca. Add
|
||||
this repository from the desktop app, then refresh mobile Tasks.
|
||||
{translate(
|
||||
'tasks.projectDetailDrawer.addRepositoryFromDesktop',
|
||||
'{{repository}} is not added to Orca. Add this repository from the desktop app, then refresh mobile Tasks.',
|
||||
{ repository: `${projectRepoNotInOrca.owner}/${projectRepoNotInOrca.repo}` }
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
@@ -70,7 +76,9 @@ export function renderMobileTasksProjectMissingRepoDrawer(model: ConnectionPrese
|
||||
}}
|
||||
>
|
||||
<ExternalLink size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>Open in GitHub</Text>
|
||||
<Text style={styles.actionText}>
|
||||
{translate('tasks.projectDetailDrawer.openInGitHub', 'Open in GitHub')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
{projectRepoNotInOrca.url ? <View style={styles.actionSeparator} /> : null}
|
||||
@@ -87,8 +95,8 @@ export function renderMobileTasksProjectMissingRepoDrawer(model: ConnectionPrese
|
||||
<Text style={styles.actionText}>
|
||||
{copiedLinkKey ===
|
||||
`project-repo:${projectRepoNotInOrca.owner}/${projectRepoNotInOrca.repo}`
|
||||
? 'Copied'
|
||||
: 'Copy repository'}
|
||||
? translate('common.copied', 'Copied')
|
||||
: translate('tasks.projectDetailDrawer.copyRepository', 'Copy repository')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
@@ -118,6 +126,7 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati
|
||||
projectRowHandoff,
|
||||
taskUiReady
|
||||
} = model
|
||||
const projectNumber = projectRowItem?.content.number
|
||||
return (
|
||||
<BottomDrawer
|
||||
visible={taskUiReady && projectRowItem != null}
|
||||
@@ -133,27 +142,37 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
GitHub Project · {projectRowItem.content.repository ?? activeProjectLabel}
|
||||
{projectRowItem.content.number ? ` #${projectRowItem.content.number}` : ''}
|
||||
{translate(
|
||||
'tasks.projectDetailDrawer.projectSubtitle',
|
||||
'GitHub Project · {{repository}}{{itemNumber}}',
|
||||
{
|
||||
repository: projectRowItem.content.repository ?? activeProjectLabel,
|
||||
itemNumber: projectNumber ? ` #${projectNumber}` : ''
|
||||
}
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.detailGroup}>
|
||||
<View style={styles.detailMetaGrid}>
|
||||
<View style={styles.detailMetaItem}>
|
||||
<Text style={styles.detailMetaLabel}>Type</Text>
|
||||
<Text style={styles.detailMetaLabel}>
|
||||
{translate('tasks.projectDetailDrawer.type', 'Type')}
|
||||
</Text>
|
||||
<Text style={styles.detailMetaValue}>
|
||||
{projectRowItem.itemType === 'PULL_REQUEST'
|
||||
? 'Pull request'
|
||||
? translate('tasks.projectDetailDrawer.pullRequest', 'Pull request')
|
||||
: projectRowItem.itemType === 'ISSUE'
|
||||
? 'Issue'
|
||||
? translate('tasks.projectDetailDrawer.issue', 'Issue')
|
||||
: projectRowItem.itemType === 'DRAFT_ISSUE'
|
||||
? 'Draft issue'
|
||||
: 'Project item'}
|
||||
? translate('tasks.projectDetailDrawer.draftIssue', 'Draft issue')
|
||||
: translate('tasks.projectDetailDrawer.projectItem', 'Project item')}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.detailMetaItem}>
|
||||
<Text style={styles.detailMetaLabel}>Status</Text>
|
||||
<Text style={styles.detailMetaLabel}>
|
||||
{translate('tasks.projectDetailDrawer.status', 'Status')}
|
||||
</Text>
|
||||
<Text style={styles.detailMetaValue}>{projectRowStatusLabel(projectRowItem)}</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -178,21 +197,32 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati
|
||||
{SHOW_MOBILE_PROJECT_METADATA_EDITORS && projectRowItem.itemType === 'ISSUE' ? (
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Issue type</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectDetailDrawer.issueType', 'Issue type')}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{projectRowItem.content.issueType?.name ?? 'No type'}
|
||||
{projectRowItem.content.issueType?.name ??
|
||||
translate('tasks.projectDetailDrawer.noType', 'No type')}
|
||||
</Text>
|
||||
</View>
|
||||
{projectIssueTypesLoading ? (
|
||||
<View style={styles.detailLoadingInline}>
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
<Text style={styles.detailMuted}>Loading issue types...</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate(
|
||||
'tasks.projectDetailDrawer.loadingIssueTypes',
|
||||
'Loading issue types...'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
) : projectIssueTypesError ? (
|
||||
<Text style={styles.detailError}>{projectIssueTypesError}</Text>
|
||||
) : projectIssueTypes.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>
|
||||
No issue types configured for this repository.
|
||||
{translate(
|
||||
'tasks.projectDetailDrawer.noIssueTypes',
|
||||
'No issue types configured for this repository.'
|
||||
)}
|
||||
</Text>
|
||||
) : (
|
||||
<View style={styles.chipRow}>
|
||||
@@ -226,7 +256,9 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati
|
||||
disabled={projectMutating}
|
||||
onPress={() => void mutateProjectRowIssueType(projectRowItem, null)}
|
||||
>
|
||||
<Text style={styles.detailChipText}>Clear type</Text>
|
||||
<Text style={styles.detailChipText}>
|
||||
{translate('tasks.projectDetailDrawer.clearType', 'Clear type')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
</View>
|
||||
@@ -251,11 +283,16 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati
|
||||
}
|
||||
>
|
||||
<Plus size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>Create Workspace</Text>
|
||||
<Text style={styles.actionText}>
|
||||
{translate('tasks.projectDetailDrawer.createWorkspace', 'Create Workspace')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : (
|
||||
<Text style={styles.emptyInlineText}>
|
||||
Workspaces can only be created from GitHub issues and pull requests.
|
||||
{translate(
|
||||
'tasks.projectDetailDrawer.workspaceCreationRequirement',
|
||||
'Workspaces can only be created from GitHub issues and pull requests.'
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
@@ -273,7 +310,9 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati
|
||||
}}
|
||||
>
|
||||
<ExternalLink size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>Open in GitHub</Text>
|
||||
<Text style={styles.actionText}>
|
||||
{translate('tasks.projectDetailDrawer.openInGitHub', 'Open in GitHub')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<View style={styles.actionSeparator} />
|
||||
<Pressable
|
||||
@@ -290,8 +329,8 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati
|
||||
<Copy size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>
|
||||
{copiedLinkKey === `github-project:${projectRowItem.id}`
|
||||
? 'Copied'
|
||||
: 'Copy GitHub link'}
|
||||
? translate('common.copied', 'Copied')
|
||||
: translate('tasks.projectDetailDrawer.copyGitHubLink', 'Copy GitHub link')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
@@ -327,7 +366,9 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati
|
||||
<X size={16} color={colors.textPrimary} />
|
||||
)}
|
||||
<Text style={styles.actionText}>
|
||||
{projectRowItem.content.state === 'CLOSED' ? 'Reopen item' : 'Close item'}
|
||||
{projectRowItem.content.state === 'CLOSED'
|
||||
? translate('tasks.projectDetailDrawer.reopenItem', 'Reopen item')
|
||||
: translate('tasks.projectDetailDrawer.closeItem', 'Close item')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
@@ -343,11 +384,16 @@ export function renderMobileTasksProjectDetailDrawer(model: ConnectionPresentati
|
||||
onPress={() => setMergeMethodProjectRow(projectRowItem)}
|
||||
>
|
||||
<GitBranch size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>Merge pull request</Text>
|
||||
<Text style={styles.actionText}>
|
||||
{translate('tasks.projectDetailDrawer.mergePullRequest', 'Merge pull request')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
{!projectRowHostedRepo ? (
|
||||
<Text style={styles.emptyInlineText}>
|
||||
Merge requires this repository in Orca.
|
||||
{translate(
|
||||
'tasks.projectDetailDrawer.mergeRepositoryRequirement',
|
||||
'Merge requires this repository in Orca.'
|
||||
)}
|
||||
</Text>
|
||||
) : null}
|
||||
</>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
SHOW_MOBILE_PROJECT_METADATA_EDITORS,
|
||||
editableProjectFields,
|
||||
@@ -23,15 +24,25 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati
|
||||
return SHOW_MOBILE_PROJECT_METADATA_EDITORS &&
|
||||
editableProjectFields(githubProjectTable).length > 0 ? (
|
||||
<View style={styles.detailSection}>
|
||||
<Text style={styles.detailSectionTitle}>Project fields</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectFieldEditors.projectFields', 'Project fields')}
|
||||
</Text>
|
||||
{editableProjectFields(githubProjectTable).map((field) => {
|
||||
const currentLabel = projectFieldValueLabel(projectRowItem, field)
|
||||
const currentValue = projectRowItem.fieldValuesByFieldId?.[field.id]
|
||||
const isEmpty =
|
||||
!currentValue ||
|
||||
(currentValue.kind === 'text' && !currentValue.text) ||
|
||||
(currentValue.kind === 'labels' && currentValue.labels.length === 0) ||
|
||||
(currentValue.kind === 'users' && currentValue.users.length === 0)
|
||||
const draftValue = projectFieldDrafts[field.id] ?? ''
|
||||
const saveTextField = (): void => {
|
||||
if (field.dataType === 'NUMBER') {
|
||||
const number = Number(draftValue)
|
||||
if (!Number.isFinite(number)) {
|
||||
setProjectRowDetailError('Enter a valid number.')
|
||||
setProjectRowDetailError(
|
||||
translate('tasks.projectFieldEditors.invalidNumber', 'Enter a valid number.')
|
||||
)
|
||||
return
|
||||
}
|
||||
void mutateProjectRowField(projectRowItem, field, {
|
||||
@@ -43,7 +54,9 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati
|
||||
if (field.dataType === 'DATE') {
|
||||
const date = draftValue.trim()
|
||||
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
||||
setProjectRowDetailError('Enter a date as YYYY-MM-DD.')
|
||||
setProjectRowDetailError(
|
||||
translate('tasks.projectFieldEditors.invalidDate', 'Enter a date as YYYY-MM-DD.')
|
||||
)
|
||||
return
|
||||
}
|
||||
void mutateProjectRowField(projectRowItem, field, { kind: 'date', date })
|
||||
@@ -92,7 +105,12 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati
|
||||
) : field.dataType === 'ITERATION' && field.kind === 'iteration' ? (
|
||||
<View style={styles.projectIterationList}>
|
||||
{field.iterations.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No iterations available.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate(
|
||||
'tasks.projectFieldEditors.noIterations',
|
||||
'No iterations available.'
|
||||
)}
|
||||
</Text>
|
||||
) : (
|
||||
field.iterations.map((iteration) => {
|
||||
const fieldValue = projectRowItem.fieldValuesByFieldId?.[field.id]
|
||||
@@ -114,8 +132,23 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati
|
||||
<View style={styles.projectIterationCopy}>
|
||||
<Text style={styles.actionText}>{iteration.title}</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{iteration.completed ? 'Completed' : 'Current & upcoming'} ·{' '}
|
||||
{iteration.startDate} · {iteration.duration}d
|
||||
{iteration.completed
|
||||
? translate(
|
||||
'tasks.projectFieldEditors.completedIteration',
|
||||
'Completed · {{startDate}} · {{duration}}d',
|
||||
{
|
||||
startDate: iteration.startDate,
|
||||
duration: iteration.duration
|
||||
}
|
||||
)
|
||||
: translate(
|
||||
'tasks.projectFieldEditors.upcomingIteration',
|
||||
'Current & upcoming · {{startDate}} · {{duration}}d',
|
||||
{
|
||||
startDate: iteration.startDate,
|
||||
duration: iteration.duration
|
||||
}
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
{selected ? <Check size={14} color={colors.textSecondary} /> : null}
|
||||
@@ -137,10 +170,10 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati
|
||||
}
|
||||
placeholder={
|
||||
field.dataType === 'DATE'
|
||||
? 'YYYY-MM-DD'
|
||||
? translate('tasks.projectFieldEditors.datePlaceholder', 'YYYY-MM-DD')
|
||||
: field.dataType === 'NUMBER'
|
||||
? 'Number'
|
||||
: 'Text'
|
||||
? translate('tasks.projectFieldEditors.numberPlaceholder', 'Number')
|
||||
: translate('tasks.projectFieldEditors.textPlaceholder', 'Text')
|
||||
}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
keyboardType={field.dataType === 'NUMBER' ? 'numeric' : 'default'}
|
||||
@@ -151,16 +184,20 @@ export function renderMobileTasksProjectFieldEditors(model: ConnectionPresentati
|
||||
disabled={projectMutating}
|
||||
onPress={saveTextField}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Save field</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.projectFieldEditors.saveField', 'Save field')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
)}
|
||||
<Pressable
|
||||
style={styles.inlineSaveButton}
|
||||
disabled={projectMutating || currentLabel === 'Empty'}
|
||||
disabled={projectMutating || isEmpty}
|
||||
onPress={() => void mutateProjectRowField(projectRowItem, field, null)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Clear field</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.projectFieldEditors.clearField', 'Clear field')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
SHOW_MOBILE_PROJECT_METADATA_EDITORS,
|
||||
projectRowType
|
||||
@@ -31,23 +32,29 @@ export function renderMobileTasksProjectLabelsEditor(model: ConnectionPresentati
|
||||
return SHOW_MOBILE_PROJECT_METADATA_EDITORS && projectRowType(projectRowItem) ? (
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Labels</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectMetadataEditors.labels', 'Labels')}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{(projectRowDetail?.provider === 'github'
|
||||
? projectRowDetail.labels
|
||||
: projectRowItem.content.labels.map((label) => label.name)
|
||||
).length || 'None'}
|
||||
).length || translate('tasks.projectMetadataEditors.none', 'None')}
|
||||
</Text>
|
||||
</View>
|
||||
{projectLabelsLoading ? (
|
||||
<View style={styles.detailLoadingInline}>
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
<Text style={styles.detailMuted}>Loading labels...</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.projectMetadataEditors.loadingLabels', 'Loading labels...')}
|
||||
</Text>
|
||||
</View>
|
||||
) : projectLabelsError ? (
|
||||
<Text style={styles.detailError}>{projectLabelsError}</Text>
|
||||
) : projectAvailableLabels.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No labels in this repository.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.projectMetadataEditors.noLabels', 'No labels in this repository.')}
|
||||
</Text>
|
||||
) : (
|
||||
<View style={styles.chipRow}>
|
||||
{[
|
||||
@@ -104,23 +111,32 @@ export function renderMobileTasksProjectAssigneesEditor(model: ConnectionPresent
|
||||
return SHOW_MOBILE_PROJECT_METADATA_EDITORS && projectRowType(projectRowItem) ? (
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Assignees</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectMetadataEditors.assignees', 'Assignees')}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{(projectRowDetail?.provider === 'github'
|
||||
? projectRowDetail.assignees
|
||||
: projectRowItem.content.assignees.map((assignee) => assignee.login)
|
||||
).length || 'None'}
|
||||
).length || translate('tasks.projectMetadataEditors.none', 'None')}
|
||||
</Text>
|
||||
</View>
|
||||
{projectAssignableUsersLoading ? (
|
||||
<View style={styles.detailLoadingInline}>
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
<Text style={styles.detailMuted}>Loading assignees...</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.projectMetadataEditors.loadingAssignees', 'Loading assignees...')}
|
||||
</Text>
|
||||
</View>
|
||||
) : projectAssignableUsersError ? (
|
||||
<Text style={styles.detailError}>{projectAssignableUsersError}</Text>
|
||||
) : projectAssignableUsers.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No assignable users found for this repository.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate(
|
||||
'tasks.projectMetadataEditors.noAssignableUsers',
|
||||
'No assignable users found for this repository.'
|
||||
)}
|
||||
</Text>
|
||||
) : (
|
||||
<View style={styles.chipRow}>
|
||||
{[
|
||||
@@ -185,12 +201,14 @@ export function renderMobileTasksProjectIssueMetadata(model: ConnectionPresentat
|
||||
return SHOW_MOBILE_PROJECT_METADATA_EDITORS && projectRowType(projectRowItem) ? (
|
||||
<>
|
||||
<View style={styles.detailSection}>
|
||||
<Text style={styles.detailSectionTitle}>Title</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectMetadataEditors.title', 'Title')}
|
||||
</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
value={projectTitleDraft}
|
||||
onChangeText={setProjectTitleDraft}
|
||||
placeholder="Title"
|
||||
placeholder={translate('tasks.projectMetadataEditors.title', 'Title')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
/>
|
||||
<Pressable
|
||||
@@ -202,16 +220,20 @@ export function renderMobileTasksProjectIssueMetadata(model: ConnectionPresentat
|
||||
})
|
||||
}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Save title</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.projectMetadataEditors.saveTitle', 'Save title')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
<View style={styles.detailSection}>
|
||||
<Text style={styles.detailSectionTitle}>Description</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectMetadataEditors.description', 'Description')}
|
||||
</Text>
|
||||
<TextInput
|
||||
style={[styles.input, styles.bodyInput]}
|
||||
value={projectBodyDraft}
|
||||
onChangeText={setProjectBodyDraft}
|
||||
placeholder="Description"
|
||||
placeholder={translate('tasks.projectMetadataEditors.description', 'Description')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
multiline
|
||||
textAlignVertical="top"
|
||||
@@ -231,20 +253,32 @@ export function renderMobileTasksProjectIssueMetadata(model: ConnectionPresentat
|
||||
})
|
||||
}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Save description</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.projectMetadataEditors.saveDescription', 'Save description')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<MobileMarkdown content={projectBodyDraft} fallback="No description." />
|
||||
<MobileMarkdown
|
||||
content={projectBodyDraft}
|
||||
fallback={translate('tasks.projectMetadataEditors.noDescription', 'No description.')}
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<View style={styles.detailSection}>
|
||||
<Text style={styles.detailSectionTitle}>Title</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectMetadataEditors.title', 'Title')}
|
||||
</Text>
|
||||
<Text style={styles.detailLine}>{projectRowItem.content.title}</Text>
|
||||
</View>
|
||||
<View style={styles.detailSection}>
|
||||
<Text style={styles.detailSectionTitle}>Description</Text>
|
||||
<MobileMarkdown content={projectBodyDraft} fallback="No description." />
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectMetadataEditors.description', 'Description')}
|
||||
</Text>
|
||||
<MobileMarkdown
|
||||
content={projectBodyDraft}
|
||||
fallback={translate('tasks.projectMetadataEditors.noDescription', 'No description.')}
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import { isBrokenCheck } from '../../../src/shared/pr-checks-fix-prompt'
|
||||
import {
|
||||
SHOW_MOBILE_PROJECT_REVIEW_PANELS,
|
||||
@@ -55,11 +56,15 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati
|
||||
<>
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Reviewers</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectReviewPanels.reviewers', 'Reviewers')}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>{getGitHubReviewSummary(projectRowDetail)}</Text>
|
||||
</View>
|
||||
{getGitHubReviewerRows(projectRowDetail).length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No reviewers requested.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.projectReviewPanels.noReviewers', 'No reviewers requested.')}
|
||||
</Text>
|
||||
) : (
|
||||
getGitHubReviewerRows(projectRowDetail).map((reviewer) => (
|
||||
<View key={reviewer.login} style={styles.reviewerRow}>
|
||||
@@ -85,12 +90,16 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati
|
||||
{projectAssignableUsersLoading ? (
|
||||
<View style={styles.detailLoadingInline}>
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
<Text style={styles.detailMuted}>Loading reviewers...</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.projectReviewPanels.loadingReviewers', 'Loading reviewers...')}
|
||||
</Text>
|
||||
</View>
|
||||
) : projectAssignableUsersError ? (
|
||||
<Text style={styles.detailError}>{projectAssignableUsersError}</Text>
|
||||
) : projectReviewerCandidates.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No reviewer suggestions found.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.projectReviewPanels.noSuggestions', 'No reviewer suggestions found.')}
|
||||
</Text>
|
||||
) : (
|
||||
<View style={styles.chipRow}>
|
||||
{projectReviewerCandidates.map((user) => {
|
||||
@@ -115,7 +124,7 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati
|
||||
style={styles.input}
|
||||
value={projectReviewersDraft}
|
||||
onChangeText={setProjectReviewersDraft}
|
||||
placeholder="Request reviewers"
|
||||
placeholder={translate('tasks.projectReviewPanels.requestReviewers', 'Request reviewers')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
@@ -124,40 +133,50 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati
|
||||
disabled={projectMutating || splitReviewerList(projectReviewersDraft).length === 0}
|
||||
onPress={() => void requestProjectGitHubReviewers(projectRowItem)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Request review</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.projectReviewPanels.requestReview', 'Request review')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
|
||||
{projectRowType(projectRowItem) === 'pr' ? (
|
||||
<View style={styles.detailSection}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>Checks</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectReviewPanels.checks', 'Checks')}
|
||||
</Text>
|
||||
<View style={styles.inlineActionRow}>
|
||||
<Pressable
|
||||
style={styles.inlineSaveButtonCompact}
|
||||
disabled={projectMutating}
|
||||
onPress={() => void refreshProjectGitHubChecks(projectRowItem)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Refresh</Text>
|
||||
<Text style={styles.inlineSaveText}>{translate('common.refresh', 'Refresh')}</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={styles.inlineSaveButtonCompact}
|
||||
disabled={projectMutating || !projectRowDetail.checks.some(isBrokenCheck)}
|
||||
onPress={() => void rerunProjectGitHubChecks(projectRowItem, true)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Rerun failed</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.projectReviewPanels.rerunFailed', 'Rerun failed')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={styles.inlineSaveButtonCompact}
|
||||
disabled={projectMutating || projectRowDetail.checks.length === 0}
|
||||
onPress={() => void rerunProjectGitHubChecks(projectRowItem, false)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Rerun all</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.projectReviewPanels.rerunAll', 'Rerun all')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
{projectRowDetail.checks.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No checks found.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.projectReviewPanels.noChecks', 'No checks found.')}
|
||||
</Text>
|
||||
) : (
|
||||
projectRowDetail.checks.map((check) => (
|
||||
<Pressable
|
||||
@@ -182,7 +201,9 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati
|
||||
|
||||
{projectRowDetail.files.length > 0 ? (
|
||||
<View style={styles.detailSection}>
|
||||
<Text style={styles.detailSectionTitle}>Changed files</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.projectReviewPanels.changedFiles', 'Changed files')}
|
||||
</Text>
|
||||
{projectRowDetail.files.map((file) => (
|
||||
<View key={file.path} style={styles.fileCard}>
|
||||
<Pressable
|
||||
@@ -197,7 +218,9 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati
|
||||
: ''}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{expandedPrFilePath === file.path ? 'Hide' : 'View'}
|
||||
{expandedPrFilePath === file.path
|
||||
? translate('tasks.projectReviewPanels.hideFile', 'Hide')
|
||||
: translate('tasks.projectReviewPanels.viewFile', 'View')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
@@ -206,7 +229,9 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati
|
||||
onPress={() => void toggleProjectGitHubFileViewed(projectRowItem, file)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{file.viewerViewedState === 'VIEWED' ? 'Mark unviewed' : 'Mark viewed'}
|
||||
{file.viewerViewedState === 'VIEWED'
|
||||
? translate('tasks.projectReviewPanels.markUnviewed', 'Mark unviewed')
|
||||
: translate('tasks.projectReviewPanels.markViewed', 'Mark viewed')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
{expandedPrFilePath === file.path ? (
|
||||
@@ -215,7 +240,9 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati
|
||||
<ActivityIndicator size="small" color={colors.textSecondary} />
|
||||
) : prFileContents[file.path]?.originalIsBinary ||
|
||||
prFileContents[file.path]?.modifiedIsBinary ? (
|
||||
<Text style={styles.detailMuted}>Binary file.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.projectReviewPanels.binaryFile', 'Binary file.')}
|
||||
</Text>
|
||||
) : prFileContents[file.path] ? (
|
||||
<GitHubPrFileDiff
|
||||
filePath={file.path}
|
||||
@@ -233,7 +260,12 @@ export function renderMobileTasksProjectReviewPanels(model: ConnectionPresentati
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Text style={styles.detailMuted}>File contents unavailable.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate(
|
||||
'tasks.projectReviewPanels.fileUnavailable',
|
||||
'File contents unavailable.'
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
ScrollView,
|
||||
Pressable,
|
||||
@@ -92,7 +93,9 @@ export function renderMobileTasksProviderControls(model: ConnectionPresentationM
|
||||
}}
|
||||
>
|
||||
<Text style={styles.segmentSecondaryText}>
|
||||
{gitlabView === 'project' ? 'Project MRs' : 'My Todos'}
|
||||
{gitlabView === 'project'
|
||||
? translate('tasks.providerControls.projectMergeRequests', 'Project MRs')
|
||||
: translate('tasks.providerControls.myTodos', 'My Todos')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
{gitlabView === 'project' && (
|
||||
@@ -128,7 +131,9 @@ export function renderMobileTasksProviderControls(model: ConnectionPresentationM
|
||||
}}
|
||||
>
|
||||
<GitBranch size={14} color={colors.textSecondary} />
|
||||
<Text style={styles.segmentSecondaryText}>Sort: {sortLabel}</Text>
|
||||
<Text style={styles.segmentSecondaryText}>
|
||||
{translate('tasks.providerControls.sort', 'Sort: {{sortLabel}}', { sortLabel })}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
</ScrollView>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-presentation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
View,
|
||||
ActivityIndicator,
|
||||
@@ -83,7 +84,7 @@ export function renderMobileTasksProviderItemList(
|
||||
<View style={styles.paginationFooter}>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Previous page"
|
||||
accessibilityLabel={translate('tasks.providerItemList.previousPage', 'Previous page')}
|
||||
accessibilityState={{
|
||||
disabled: githubCurrentPage === 0 || githubPaginationLoading
|
||||
}}
|
||||
@@ -101,8 +102,14 @@ export function renderMobileTasksProviderItemList(
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={
|
||||
githubCountedTotalPages === null
|
||||
? `Select page, Page ${githubCurrentPage + 1}`
|
||||
: `Select page, Page ${githubCurrentPage + 1} of ${githubTotalPages}`
|
||||
? translate('tasks.providerItemList.selectPage', 'Select page, Page {{page}}', {
|
||||
page: githubCurrentPage + 1
|
||||
})
|
||||
: translate(
|
||||
'tasks.providerItemList.selectPageOfTotal',
|
||||
'Select page, Page {{page}} of {{total}}',
|
||||
{ page: githubCurrentPage + 1, total: githubTotalPages }
|
||||
)
|
||||
}
|
||||
accessibilityState={{ disabled: githubPaginationLoading }}
|
||||
style={styles.paginationLabelButton}
|
||||
@@ -116,13 +123,18 @@ export function renderMobileTasksProviderItemList(
|
||||
>
|
||||
<Text style={styles.paginationLabel}>
|
||||
{githubCountedTotalPages === null
|
||||
? `Page ${githubCurrentPage + 1}`
|
||||
: `Page ${githubCurrentPage + 1} of ${githubTotalPages}`}
|
||||
? translate('tasks.providerItemList.page', 'Page {{page}}', {
|
||||
page: githubCurrentPage + 1
|
||||
})
|
||||
: translate('tasks.providerItemList.pageOfTotal', 'Page {{page}} of {{total}}', {
|
||||
page: githubCurrentPage + 1,
|
||||
total: githubTotalPages
|
||||
})}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Next page"
|
||||
accessibilityLabel={translate('tasks.providerItemList.nextPage', 'Next page')}
|
||||
accessibilityState={{
|
||||
disabled:
|
||||
(!githubCanLoadUncountedNextPage && githubCurrentPage >= githubTotalPages - 1) ||
|
||||
@@ -205,7 +217,9 @@ export function renderMobileTasksProviderItemList(
|
||||
{branchSummary.head}
|
||||
</Text>
|
||||
<Text style={styles.branchMetaBase} numberOfLines={1}>
|
||||
into {branchSummary.base}
|
||||
{translate('tasks.providerItemList.intoBranch', 'into {{base}}', {
|
||||
base: branchSummary.base
|
||||
})}
|
||||
</Text>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
} from './mobile-tasks-legacy-foundation'
|
||||
import { styles } from './mobile-tasks-legacy-styles'
|
||||
import { normalizeJiraFilter } from './mobile-jira-issue-filters'
|
||||
import { translate as t } from '../i18n/mobile-i18n'
|
||||
|
||||
export function renderMobileTasksProviderPicker(model: ConnectionPresentationModel) {
|
||||
const {
|
||||
@@ -47,7 +48,7 @@ export function renderMobileTasksProviderPicker(model: ConnectionPresentationMod
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showProviderPicker}
|
||||
title="Task Source"
|
||||
title={t('tasks.providerPickers.taskSource', 'Task Source')}
|
||||
options={providerOptions}
|
||||
selected={provider}
|
||||
onSelect={(next) => {
|
||||
@@ -111,8 +112,10 @@ export function renderMobileTasksRepoPicker(model: ConnectionPresentationModel)
|
||||
return (
|
||||
<BottomDrawer visible={taskUiReady && showRepoPicker} onClose={() => setShowRepoPicker(false)}>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>Repositories</Text>
|
||||
<Text style={styles.sheetSubtitle}>Choose which repositories to query.</Text>
|
||||
<Text style={styles.sheetTitle}>{t('tasks.providerPickers.repos', 'Repositories')}</Text>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
{t('tasks.providerPickers.repoDescription', 'Choose which repositories to query.')}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.repoPickerGroup}>
|
||||
@@ -125,7 +128,9 @@ export function renderMobileTasksRepoPicker(model: ConnectionPresentationModel)
|
||||
}}
|
||||
>
|
||||
<View style={styles.repoPickerTextWrap}>
|
||||
<Text style={styles.repoPickerTitle}>All repositories</Text>
|
||||
<Text style={styles.repoPickerTitle}>
|
||||
{t('tasks.providerPickers.allRepositories', 'All repositories')}
|
||||
</Text>
|
||||
<Text style={styles.repoPickerSubtitle}>{repositoryCount(hostedRepos.length)}</Text>
|
||||
</View>
|
||||
{effectiveRepoIds.size === 0 ? <Check size={15} color={colors.textPrimary} /> : null}
|
||||
@@ -172,16 +177,23 @@ export function renderMobileTasksGitHubIssueSourcePicker(model: ConnectionPresen
|
||||
onClose={() => setShowGitHubIssueSourcePicker(false)}
|
||||
>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>GitHub Issue Sources</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{t('tasks.providerPickers.issueSources', 'GitHub Issue Sources')}
|
||||
</Text>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
Choose whether each repository queries and creates work from upstream or origin.
|
||||
{t(
|
||||
'tasks.providerPickers.issueSourcesDescription',
|
||||
'Choose whether each repository queries and creates work from upstream or origin.'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.repoPickerGroup}>
|
||||
{githubIssueSourceRows.length === 0 ? (
|
||||
<View style={styles.drawerLoadingRow}>
|
||||
<Text style={styles.detailMuted}>No alternate issue sources available.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{t('tasks.providerPickers.noIssueSources', 'No alternate issue sources available.')}
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
githubIssueSourceRows.map(({ repo, sources }, index) => {
|
||||
@@ -198,10 +210,11 @@ export function renderMobileTasksGitHubIssueSourcePicker(model: ConnectionPresen
|
||||
{repo.displayName}
|
||||
</Text>
|
||||
<Text style={styles.issueSourceHint} numberOfLines={2}>
|
||||
Querying{' '}
|
||||
{issueSourceSlug(
|
||||
selectedPreference === 'origin' ? sources.prs : sources.upstreamCandidate
|
||||
)}
|
||||
{t('tasks.providerPickers.queryingSource', 'Querying {{source}}', {
|
||||
source: issueSourceSlug(
|
||||
selectedPreference === 'origin' ? sources.prs : sources.upstreamCandidate
|
||||
)
|
||||
})}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.issueSourceSegment}>
|
||||
@@ -227,7 +240,9 @@ export function renderMobileTasksGitHubIssueSourcePicker(model: ConnectionPresen
|
||||
selected && styles.issueSourceSegmentTextActive
|
||||
]}
|
||||
>
|
||||
{preference === 'upstream' ? 'Upstream' : 'Origin'}
|
||||
{preference === 'upstream'
|
||||
? t('tasks.providerPickers.upstream', 'Upstream')
|
||||
: t('tasks.providerPickers.origin', 'Origin')}
|
||||
</Text>
|
||||
<Text style={styles.issueSourceSlug} numberOfLines={1}>
|
||||
{slug}
|
||||
@@ -264,7 +279,7 @@ export function renderMobileTasksGitHubViewPicker(model: ConnectionPresentationM
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showGitHubKindPicker}
|
||||
title="GitHub View"
|
||||
title={t('tasks.providerPickers.githubView', 'GitHub View')}
|
||||
options={GITHUB_KIND_OPTIONS}
|
||||
selected={githubMode === 'project' ? 'project' : githubKind}
|
||||
onSelect={(kind) => {
|
||||
@@ -311,7 +326,11 @@ export function renderMobileTasksGitHubPresetPicker(model: ConnectionPresentatio
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && showGitHubPresetPicker}
|
||||
title={githubKind === 'prs' ? 'Pull Requests' : 'Issues'}
|
||||
title={
|
||||
githubKind === 'prs'
|
||||
? t('tasks.providerPickers.pullRequests', 'Pull Requests')
|
||||
: t('tasks.providerPickers.issues', 'Issues')
|
||||
}
|
||||
options={githubPresetPickerOptions}
|
||||
selected={githubPreset}
|
||||
onSelect={(preset) => {
|
||||
@@ -349,8 +368,10 @@ export function renderMobileTasksPagePicker(model: ConnectionPresentationModel)
|
||||
onClose={() => setShowGitHubPagePicker(false)}
|
||||
>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>GitHub Pages</Text>
|
||||
<Text style={styles.sheetSubtitle}>Jump to a loaded or available result page.</Text>
|
||||
<Text style={styles.sheetTitle}>{t('tasks.providerPickers.pages', 'GitHub Pages')}</Text>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
{t('tasks.providerPickers.pageHint', 'Jump to a loaded or available result page.')}
|
||||
</Text>
|
||||
</View>
|
||||
<ScrollView style={styles.pagePickerList}>
|
||||
{githubPagePickerPages.map((index) => {
|
||||
@@ -367,9 +388,15 @@ export function renderMobileTasksPagePicker(model: ConnectionPresentationModel)
|
||||
}}
|
||||
>
|
||||
<View style={styles.pickerRowContent}>
|
||||
<Text style={styles.pickerRowLabel}>Page {index + 1}</Text>
|
||||
<Text style={styles.pickerRowLabel}>
|
||||
{t('tasks.providerPickers.pageNumber', 'Page {{page}}', {
|
||||
page: index + 1
|
||||
})}
|
||||
</Text>
|
||||
<Text style={styles.pickerRowSubtitle}>
|
||||
{loaded ? 'Loaded' : 'Loads older results'}
|
||||
{loaded
|
||||
? t('tasks.providerPickers.pageLoaded', 'Loaded')
|
||||
: t('tasks.providerPickers.pageNotLoaded', 'Loads older results')}
|
||||
</Text>
|
||||
</View>
|
||||
{selected ? <Check size={16} color={colors.textPrimary} /> : null}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { type GitHubOwnerRepo, colors } from './mobile-tasks-dependencies'
|
||||
import { getLinearPriorityLabel, getLinearPriorityRank } from './mobile-tasks-hosted-review'
|
||||
import { formatUpdatedAt, taskTime } from './mobile-tasks-item-mapping'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import type { LinearIssueSection } from './mobile-tasks-options'
|
||||
import type {
|
||||
LinearDisplayProperty,
|
||||
@@ -80,7 +81,7 @@ export function hasGitHubIssueSourceChoice(sources: GitHubRepoSources | undefine
|
||||
}
|
||||
|
||||
export function issueSourceSlug(source: GitHubOwnerRepo | null | undefined): string {
|
||||
return source ? `${source.owner}/${source.repo}` : 'Unknown'
|
||||
return source ? `${source.owner}/${source.repo}` : translate('common.unknown', 'Unknown')
|
||||
}
|
||||
|
||||
export function sortLinearIssues(
|
||||
@@ -117,21 +118,33 @@ export function getLinearIssueGroup(
|
||||
if (groupBy === 'assignee') {
|
||||
return {
|
||||
key: `assignee:${issue.assignee?.id ?? issue.assignee?.displayName ?? 'unassigned'}`,
|
||||
label: issue.assignee?.displayName ?? 'Unassigned',
|
||||
get label() {
|
||||
return (
|
||||
issue.assignee?.displayName ?? translate('tasks.reviewerLinear.unassigned', 'Unassigned')
|
||||
)
|
||||
},
|
||||
color: colors.accentBlue
|
||||
}
|
||||
}
|
||||
if (groupBy === 'priority') {
|
||||
return {
|
||||
key: `priority:${issue.priority}`,
|
||||
label: getLinearPriorityLabel(issue.priority),
|
||||
get label() {
|
||||
return getLinearPriorityLabel(issue.priority)
|
||||
},
|
||||
color: issue.priority === 1 ? colors.statusRed : colors.accentBlue
|
||||
}
|
||||
}
|
||||
if (groupBy === 'team') {
|
||||
return { key: `team:${issue.team.id}`, label: issue.team.name, color: issue.state.color }
|
||||
}
|
||||
return { key: 'all', label: 'Issues', color: colors.accentBlue }
|
||||
return {
|
||||
key: 'all',
|
||||
get label() {
|
||||
return translate('tasks.reviewerLinear.issues', 'Issues')
|
||||
},
|
||||
color: colors.accentBlue
|
||||
}
|
||||
}
|
||||
|
||||
export function groupLinearIssues(
|
||||
@@ -154,7 +167,16 @@ function groupOrderedLinearIssues(
|
||||
groupBy: LinearGroupBy
|
||||
): LinearIssueSection[] {
|
||||
if (groupBy === 'none') {
|
||||
return [{ key: 'all', label: 'Issues', color: colors.accentBlue, issues: sorted }]
|
||||
return [
|
||||
{
|
||||
key: 'all',
|
||||
get label() {
|
||||
return translate('tasks.reviewerLinear.issues', 'Issues')
|
||||
},
|
||||
color: colors.accentBlue,
|
||||
issues: sorted
|
||||
}
|
||||
]
|
||||
}
|
||||
const sections = new Map<
|
||||
string,
|
||||
@@ -166,7 +188,13 @@ function groupOrderedLinearIssues(
|
||||
if (section) {
|
||||
section.issues.push(issue)
|
||||
} else {
|
||||
sections.set(group.key, { ...group, issues: [issue] })
|
||||
sections.set(group.key, {
|
||||
...group,
|
||||
get label() {
|
||||
return group.label
|
||||
},
|
||||
issues: [issue]
|
||||
})
|
||||
}
|
||||
}
|
||||
return [...sections.values()]
|
||||
|
||||
@@ -13,13 +13,16 @@ import { MobileTasksHostSubtitle } from './mobile-tasks-host-subtitle'
|
||||
import { styles } from './mobile-tasks-legacy-styles'
|
||||
import { renderMobileTasksProviderControls } from './mobile-tasks-provider-controls'
|
||||
import { renderMobileTasksSearchControl } from './mobile-tasks-search-control'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
const REFRESH_LABELS = {
|
||||
github: 'Refresh GitHub work',
|
||||
gitlab: 'Refresh GitLab work items',
|
||||
linear: 'Refresh Linear',
|
||||
jira: 'Refresh Jira issues'
|
||||
} as const
|
||||
function refreshLabels() {
|
||||
return {
|
||||
github: translate('tasks.screenChrome.refreshGitHub', 'Refresh GitHub work'),
|
||||
gitlab: translate('tasks.screenChrome.refreshGitLab', 'Refresh GitLab work items'),
|
||||
linear: translate('tasks.screenChrome.refreshLinear', 'Refresh Linear'),
|
||||
jira: translate('tasks.screenChrome.refreshJira', 'Refresh Jira issues')
|
||||
}
|
||||
}
|
||||
|
||||
export function renderMobileTasksChrome(model: ConnectionPresentationModel) {
|
||||
const { setTaskCopyFeedbackRootRef } = model
|
||||
@@ -65,14 +68,14 @@ export function renderMobileTasksStatusBar(model: ConnectionPresentationModel) {
|
||||
onPress={() => router.back()}
|
||||
hitSlop={8}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Back"
|
||||
accessibilityLabel={translate('common.back', 'Back')}
|
||||
>
|
||||
<ChevronLeft size={22} color={colors.textPrimary} />
|
||||
</Pressable>
|
||||
<View style={styles.titleWrap}>
|
||||
<View style={styles.titleLine}>
|
||||
<StatusDot state={connState} verdict={headerVerdict} />
|
||||
<Text style={styles.title}>Tasks</Text>
|
||||
<Text style={styles.title}>{translate('tasks.screenChrome.title', 'Tasks')}</Text>
|
||||
</View>
|
||||
<MobileTasksHostSubtitle hostId={hostId} />
|
||||
</View>
|
||||
@@ -81,7 +84,7 @@ export function renderMobileTasksStatusBar(model: ConnectionPresentationModel) {
|
||||
disabled={!taskUiReady || loading || refreshing || githubProjectLoading}
|
||||
hitSlop={8}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={REFRESH_LABELS[provider]}
|
||||
accessibilityLabel={refreshLabels()[provider]}
|
||||
onPress={() => {
|
||||
if (!taskUiReady) {
|
||||
return
|
||||
@@ -103,10 +106,10 @@ export function renderMobileTasksStatusBar(model: ConnectionPresentationModel) {
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={
|
||||
provider === 'github'
|
||||
? 'New GitHub issue'
|
||||
? translate('tasks.screenChrome.newGitHubIssue', 'New GitHub issue')
|
||||
: linearConnected
|
||||
? 'New Linear issue'
|
||||
: 'Connect Linear'
|
||||
? translate('tasks.screenChrome.newLinearIssue', 'New Linear issue')
|
||||
: translate('tasks.screenChrome.connectLinear', 'Connect Linear')
|
||||
}
|
||||
onPress={() => {
|
||||
if (!taskUiReady) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { ConnectionPresentationModel } from './use-mobile-tasks-connection-
|
||||
import { View, MobileSearchField } from './mobile-tasks-dependencies'
|
||||
import { styles } from './mobile-tasks-legacy-styles'
|
||||
import { getTaskPresetQuery, scopeGitHubTaskSearch } from './mobile-tasks-legacy-foundation'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
export function renderMobileTasksSearchControl(model: ConnectionPresentationModel) {
|
||||
const {
|
||||
@@ -33,11 +34,20 @@ export function renderMobileTasksSearchControl(model: ConnectionPresentationMode
|
||||
onChangeText={isGithubProjectSearch ? setGithubProjectSearch : setQuery}
|
||||
placeholder={
|
||||
isGithubProjectSearch
|
||||
? 'Search project view...'
|
||||
? translate('tasks.searchControl.projectPlaceholder', 'Search project view...')
|
||||
: provider === 'jira'
|
||||
? // Jira accepts raw JQL, matching desktop.
|
||||
'Jira JQL, e.g. project = ABC AND statusCategory != Done'
|
||||
: `Search ${providerLabel} tasks...`
|
||||
translate(
|
||||
'tasks.searchControl.jiraPlaceholder',
|
||||
'Jira JQL, e.g. project = ABC AND statusCategory != Done'
|
||||
)
|
||||
: translate(
|
||||
'tasks.searchControl.providerPlaceholder',
|
||||
'Search {{provider}} tasks...',
|
||||
{
|
||||
provider: providerLabel
|
||||
}
|
||||
)
|
||||
}
|
||||
// Preset text is not an override; Project’s explicit empty filter must not leave Clear visible forever.
|
||||
showClear={
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
workspaceAgentIconId
|
||||
} from './mobile-tasks-legacy-foundation'
|
||||
import { styles } from './mobile-tasks-legacy-styles'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresentationModel) {
|
||||
const {
|
||||
@@ -60,7 +61,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
{workspaceCreateDraft ? (
|
||||
<View>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>Create Workspace</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate('tasks.workspaceCreateDrawer.title', 'Create Workspace')}
|
||||
</Text>
|
||||
<Text style={styles.sheetSubtitle} numberOfLines={2}>
|
||||
{workspaceCreateDraft.item.title}
|
||||
</Text>
|
||||
@@ -68,7 +71,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
|
||||
<View style={styles.workspaceCreateForm}>
|
||||
<View style={styles.workspaceCreateField}>
|
||||
<Text style={styles.workspaceCreateLabel}>Repository</Text>
|
||||
<Text style={styles.workspaceCreateLabel}>
|
||||
{translate('tasks.workspaceCreateDrawer.repository', 'Repository')}
|
||||
</Text>
|
||||
<Pressable
|
||||
style={styles.fieldButton}
|
||||
disabled={!workspaceCreateCanPickRepo}
|
||||
@@ -91,7 +96,11 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
]}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{workspaceCreateTargetRepo?.displayName ?? 'Select a repository'}
|
||||
{workspaceCreateTargetRepo?.displayName ??
|
||||
translate(
|
||||
'tasks.workspaceCreateDrawer.selectRepository',
|
||||
'Select a repository'
|
||||
)}
|
||||
</Text>
|
||||
{workspaceCreateCanPickRepo ? (
|
||||
<ChevronDown size={14} color={colors.textMuted} />
|
||||
@@ -101,7 +110,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
|
||||
{workspaceCreateTargetConnectionId ? (
|
||||
<View style={styles.workspaceCreateField}>
|
||||
<Text style={styles.workspaceCreateLabel}>SSH Connection</Text>
|
||||
<Text style={styles.workspaceCreateLabel}>
|
||||
{translate('tasks.workspaceCreateDrawer.sshConnection', 'SSH Connection')}
|
||||
</Text>
|
||||
<View style={styles.sshConnectCard}>
|
||||
<View style={styles.sshStatusRow}>
|
||||
<View
|
||||
@@ -116,7 +127,11 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
/>
|
||||
<View style={styles.sshStatusCopy}>
|
||||
<Text style={styles.sshStatusTitle} numberOfLines={1}>
|
||||
{workspaceCreateTargetRepo?.displayName ?? 'Remote repository'}
|
||||
{workspaceCreateTargetRepo?.displayName ??
|
||||
translate(
|
||||
'tasks.workspaceCreateDrawer.remoteRepository',
|
||||
'Remote repository'
|
||||
)}
|
||||
</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{workspaceSshStatusLabel(workspaceCreateSshStatus)}
|
||||
@@ -134,7 +149,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
onPress={() => void connectWorkspaceSshRepo()}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{workspaceCreateSshConnectInProgress ? 'Connecting...' : 'Connect'}
|
||||
{workspaceCreateSshConnectInProgress
|
||||
? translate('tasks.workspaceCreateDrawer.connecting', 'Connecting...')
|
||||
: translate('tasks.workspaceCreateDrawer.connect', 'Connect')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
)}
|
||||
@@ -148,7 +165,10 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
|
||||
<View style={styles.workspaceCreateField}>
|
||||
<Text style={styles.workspaceCreateLabel}>
|
||||
Workspace Name <Text style={styles.workspaceCreateLabelHint}>[Optional]</Text>
|
||||
{translate('tasks.workspaceCreateDrawer.workspaceName', 'Workspace Name')}{' '}
|
||||
<Text style={styles.workspaceCreateLabelHint}>
|
||||
{translate('tasks.workspaceCreateDrawer.optional', '[Optional]')}
|
||||
</Text>
|
||||
</Text>
|
||||
<MobileWorkspaceNameInput
|
||||
style={styles.input}
|
||||
@@ -160,7 +180,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
</View>
|
||||
|
||||
<View style={styles.workspaceCreateField}>
|
||||
<Text style={styles.workspaceCreateLabel}>Agent</Text>
|
||||
<Text style={styles.workspaceCreateLabel}>
|
||||
{translate('tasks.workspaceCreateDrawer.agent', 'Agent')}
|
||||
</Text>
|
||||
<Pressable
|
||||
style={[
|
||||
styles.fieldButton,
|
||||
@@ -172,9 +194,15 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
<MobileAgentIcon agentId={workspaceAgentIconId(resolvedWorkspaceAgent)} size={16} />
|
||||
<Text style={styles.fieldButtonText} numberOfLines={1}>
|
||||
{workspaceCreateRequiresSshConnection
|
||||
? 'Connect repository first'
|
||||
? translate(
|
||||
'tasks.workspaceCreateDrawer.connectFirst',
|
||||
'Connect repository first'
|
||||
)
|
||||
: workspaceAgentDetectionPending
|
||||
? 'Detecting agents...'
|
||||
? translate(
|
||||
'tasks.workspaceCreateDrawer.detectingAgents',
|
||||
'Detecting agents...'
|
||||
)
|
||||
: workspaceAgentLabel(resolvedWorkspaceAgent)}
|
||||
</Text>
|
||||
<ChevronDown size={14} color={colors.textMuted} />
|
||||
@@ -185,7 +213,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
style={styles.workspaceAdvancedToggle}
|
||||
onPress={() => setShowWorkspaceAdvanced((current) => !current)}
|
||||
>
|
||||
<Text style={styles.workspaceAdvancedText}>Advanced</Text>
|
||||
<Text style={styles.workspaceAdvancedText}>
|
||||
{translate('tasks.workspaceCreateDrawer.advanced', 'Advanced')}
|
||||
</Text>
|
||||
{showWorkspaceAdvanced ? (
|
||||
<ChevronUp size={14} color={colors.textSecondary} />
|
||||
) : (
|
||||
@@ -195,7 +225,9 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
|
||||
{showWorkspaceAdvanced ? (
|
||||
<View style={styles.workspaceCreateField}>
|
||||
<Text style={styles.workspaceCreateLabel}>Start from</Text>
|
||||
<Text style={styles.workspaceCreateLabel}>
|
||||
{translate('tasks.workspaceCreateDrawer.startFrom', 'Start from')}
|
||||
</Text>
|
||||
<Pressable
|
||||
style={styles.fieldButton}
|
||||
onPress={() => {
|
||||
@@ -205,13 +237,16 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
>
|
||||
<GitBranch size={14} color={colors.textMuted} />
|
||||
<Text style={styles.fieldButtonText} numberOfLines={1}>
|
||||
{workspaceBaseBranch?.refName ?? 'Default branch'}
|
||||
{workspaceBaseBranch?.refName ??
|
||||
translate('tasks.workspaceCreateDrawer.defaultBranch', 'Default branch')}
|
||||
</Text>
|
||||
<ChevronDown size={14} color={colors.textMuted} />
|
||||
</Pressable>
|
||||
{workspaceBaseBranch ? (
|
||||
<Text style={styles.detailMuted} numberOfLines={1}>
|
||||
Create from {workspaceBaseBranch.refName}
|
||||
{translate('tasks.workspaceCreateDrawer.createFrom', 'Create from {{branch}}', {
|
||||
branch: workspaceBaseBranch.refName
|
||||
})}
|
||||
</Text>
|
||||
) : null}
|
||||
</View>
|
||||
@@ -221,8 +256,14 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
{workspaceCreateTargetRepo ? null : (
|
||||
<Text style={styles.detailError}>
|
||||
{workspaceCreateDraft.item.provider === 'linear'
|
||||
? 'Add a Git repository before creating a Linear workspace.'
|
||||
: 'Repository not found.'}
|
||||
? translate(
|
||||
'tasks.workspaceCreateDrawer.addRepository',
|
||||
'Add a Git repository before creating a Linear workspace.'
|
||||
)
|
||||
: translate(
|
||||
'tasks.workspaceCreateDrawer.repositoryNotFound',
|
||||
'Repository not found.'
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
@@ -265,10 +306,16 @@ export function renderMobileTasksWorkspaceCreateDrawer(model: ConnectionPresenta
|
||||
) : (
|
||||
<Text style={styles.createButtonText}>
|
||||
{workspaceAgentDetectionPending
|
||||
? 'Detecting agents...'
|
||||
? translate(
|
||||
'tasks.workspaceCreateDrawer.detectingAgents',
|
||||
'Detecting agents...'
|
||||
)
|
||||
: workspaceCreateRequiresSshConnection
|
||||
? 'Connect Repository'
|
||||
: 'Create Workspace'}
|
||||
? translate(
|
||||
'tasks.workspaceCreateDrawer.connectRepository',
|
||||
'Connect Repository'
|
||||
)
|
||||
: translate('tasks.workspaceCreateDrawer.title', 'Create Workspace')}
|
||||
</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
@@ -292,7 +339,7 @@ export function renderMobileTasksWorkspaceCreateRepoPicker(model: ConnectionPres
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && workspaceCreateDraft != null && showWorkspaceCreateRepoPicker}
|
||||
title="Repository"
|
||||
title={translate('tasks.workspaceCreateDrawer.repository', 'Repository')}
|
||||
options={workspaceRepoOptions}
|
||||
selected={workspaceCreateTargetRepo?.id ?? ''}
|
||||
onSelect={(repoId) => {
|
||||
@@ -321,7 +368,7 @@ export function renderMobileTasksWorkspaceAgentPicker(model: ConnectionPresentat
|
||||
return (
|
||||
<PickerModal
|
||||
visible={taskUiReady && workspaceCreateDraft != null && showWorkspaceAgentPicker}
|
||||
title="Agent"
|
||||
title={translate('tasks.workspaceCreateDrawer.agent', 'Agent')}
|
||||
options={workspaceAgentOptions}
|
||||
selected={resolvedWorkspaceAgent}
|
||||
onSelect={(agent) => {
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from './mobile-tasks-dependencies'
|
||||
import { TASK_SECONDARY_DRAWER_Z_INDEX } from './mobile-tasks-legacy-foundation'
|
||||
import { styles } from './mobile-tasks-legacy-styles'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
export function renderMobileTasksWorkspaceBaseBranchPicker(model: ConnectionPresentationModel) {
|
||||
const {
|
||||
@@ -36,15 +37,25 @@ export function renderMobileTasksWorkspaceBaseBranchPicker(model: ConnectionPres
|
||||
>
|
||||
<View>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>Start From</Text>
|
||||
<Text style={styles.sheetSubtitle}>Pick an existing branch or ref.</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate('tasks.workspaceOptionPickers.baseBranchTitle', 'Start From')}
|
||||
</Text>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
{translate(
|
||||
'tasks.workspaceOptionPickers.baseBranchSubtitle',
|
||||
'Pick an existing branch or ref.'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.detailGroup}>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
value={workspaceBaseBranchQuery}
|
||||
onChangeText={setWorkspaceBaseBranchQuery}
|
||||
placeholder="Search branches"
|
||||
placeholder={translate(
|
||||
'tasks.workspaceOptionPickers.searchBranches',
|
||||
'Search branches'
|
||||
)}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
@@ -59,8 +70,15 @@ export function renderMobileTasksWorkspaceBaseBranchPicker(model: ConnectionPres
|
||||
{workspaceBaseBranch === null ? <Check size={16} color={colors.textPrimary} /> : null}
|
||||
</View>
|
||||
<View style={styles.pickerContent}>
|
||||
<Text style={styles.pickerLabel}>Default branch</Text>
|
||||
<Text style={styles.pickerSubtitle}>Use this repository's configured base</Text>
|
||||
<Text style={styles.pickerLabel}>
|
||||
{translate('tasks.workspaceOptionPickers.defaultBranch', 'Default branch')}
|
||||
</Text>
|
||||
<Text style={styles.pickerSubtitle}>
|
||||
{translate(
|
||||
'tasks.workspaceOptionPickers.defaultBranchSubtitle',
|
||||
"Use this repository's configured base"
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
{workspaceBaseBranchLoading ? (
|
||||
@@ -70,7 +88,9 @@ export function renderMobileTasksWorkspaceBaseBranchPicker(model: ConnectionPres
|
||||
) : workspaceBaseBranchError ? (
|
||||
<Text style={styles.detailError}>{workspaceBaseBranchError}</Text>
|
||||
) : workspaceBaseBranchQuery.trim() && workspaceBaseBranchResults.length === 0 ? (
|
||||
<Text style={styles.detailMuted}>No branches match.</Text>
|
||||
<Text style={styles.detailMuted}>
|
||||
{translate('tasks.workspaceOptionPickers.noBranches', 'No branches match.')}
|
||||
</Text>
|
||||
) : null}
|
||||
{workspaceBaseBranchResults.map((branch) => (
|
||||
<View key={`${branch.refName}:${branch.localBranchName}`}>
|
||||
@@ -92,7 +112,13 @@ export function renderMobileTasksWorkspaceBaseBranchPicker(model: ConnectionPres
|
||||
</Text>
|
||||
{branch.localBranchName !== branch.refName ? (
|
||||
<Text style={styles.pickerSubtitle} numberOfLines={1}>
|
||||
Branch name: {branch.localBranchName}
|
||||
{translate(
|
||||
'tasks.workspaceOptionPickers.branchName',
|
||||
'Branch name: {{name}}',
|
||||
{
|
||||
name: branch.localBranchName
|
||||
}
|
||||
)}
|
||||
</Text>
|
||||
) : null}
|
||||
</View>
|
||||
@@ -127,7 +153,9 @@ export function renderMobileTasksWorkspaceSparsePicker(model: ConnectionPresenta
|
||||
>
|
||||
<View>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>Sparse Checkout</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate('tasks.workspaceOptionPickers.sparseCheckoutTitle', 'Sparse Checkout')}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.detailGroup}>
|
||||
<Pressable
|
||||
@@ -143,8 +171,15 @@ export function renderMobileTasksWorkspaceSparsePicker(model: ConnectionPresenta
|
||||
) : null}
|
||||
</View>
|
||||
<View style={styles.pickerContent}>
|
||||
<Text style={styles.pickerLabel}>Full checkout</Text>
|
||||
<Text style={styles.pickerSubtitle}>Use the whole repository</Text>
|
||||
<Text style={styles.pickerLabel}>
|
||||
{translate('tasks.workspaceOptionPickers.fullCheckout', 'Full checkout')}
|
||||
</Text>
|
||||
<Text style={styles.pickerSubtitle}>
|
||||
{translate(
|
||||
'tasks.workspaceOptionPickers.fullCheckoutSubtitle',
|
||||
'Use the whole repository'
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
{workspaceSparsePresets.map((preset) => (
|
||||
@@ -175,7 +210,13 @@ export function renderMobileTasksWorkspaceSparsePicker(model: ConnectionPresenta
|
||||
<Pressable
|
||||
style={styles.iconActionButton}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`Edit ${preset.name}`}
|
||||
accessibilityLabel={translate(
|
||||
'tasks.workspaceOptionPickers.editPreset',
|
||||
'Edit {{name}}',
|
||||
{
|
||||
name: preset.name
|
||||
}
|
||||
)}
|
||||
onPress={() => startEditWorkspaceSparsePreset(preset)}
|
||||
>
|
||||
<Pencil size={15} color={colors.textMuted} />
|
||||
@@ -194,7 +235,9 @@ export function renderMobileTasksWorkspaceSparsePicker(model: ConnectionPresenta
|
||||
disabled={!workspaceSparsePresetsLoaded || workspaceSparsePresetsLoading}
|
||||
onPress={startNewWorkspaceSparsePreset}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>New preset</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{translate('tasks.workspaceOptionPickers.newPreset', 'New preset')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</BottomDrawer>
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from './mobile-tasks-dependencies'
|
||||
import { TASK_SECONDARY_DRAWER_Z_INDEX, setupSourceLabel } from './mobile-tasks-legacy-foundation'
|
||||
import { styles } from './mobile-tasks-legacy-styles'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
export function renderMobileTasksWorkspaceSparseDrawer(model: ConnectionPresentationModel) {
|
||||
const {
|
||||
@@ -25,6 +26,7 @@ export function renderMobileTasksWorkspaceSparseDrawer(model: ConnectionPresenta
|
||||
workspaceSparseDraftParsed,
|
||||
workspaceSparseSaving
|
||||
} = model
|
||||
const count = workspaceSparseDraftParsed?.directories.length ?? 0
|
||||
return (
|
||||
<BottomDrawer
|
||||
visible={taskUiReady && workspaceCreateDraft != null && workspaceSparseDraft != null}
|
||||
@@ -39,17 +41,24 @@ export function renderMobileTasksWorkspaceSparseDrawer(model: ConnectionPresenta
|
||||
<View>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{workspaceSparseDraft.mode === 'new' ? 'New Sparse Preset' : 'Edit Sparse Preset'}
|
||||
{workspaceSparseDraft.mode === 'new'
|
||||
? translate('tasks.workspaceTrustDrawers.newSparsePreset', 'New Sparse Preset')
|
||||
: translate('tasks.workspaceTrustDrawers.editSparsePreset', 'Edit Sparse Preset')}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.detailGroup}>
|
||||
<View style={styles.detailSection}>
|
||||
<Text style={styles.detailSectionTitle}>Name</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.workspaceTrustDrawers.nameLabel', 'Name')}
|
||||
</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
value={workspaceSparseDraft.name}
|
||||
onChangeText={(name) => setWorkspaceSparseDraft({ ...workspaceSparseDraft, name })}
|
||||
placeholder="Renderer UI"
|
||||
placeholder={translate(
|
||||
'tasks.workspaceTrustDrawers.namePlaceholder',
|
||||
'Renderer UI'
|
||||
)}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
@@ -57,7 +66,9 @@ export function renderMobileTasksWorkspaceSparseDrawer(model: ConnectionPresenta
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.detailSection}>
|
||||
<Text style={styles.detailSectionTitle}>Directories</Text>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{translate('tasks.workspaceTrustDrawers.directoriesLabel', 'Directories')}
|
||||
</Text>
|
||||
<TextInput
|
||||
style={[styles.input, styles.bodyInput, styles.monoInput]}
|
||||
value={workspaceSparseDraft.directoriesText}
|
||||
@@ -74,9 +85,17 @@ export function renderMobileTasksWorkspaceSparseDrawer(model: ConnectionPresenta
|
||||
</View>
|
||||
<Text style={workspaceSparseDraftError ? styles.detailError : styles.detailMuted}>
|
||||
{workspaceSparseDraftError ??
|
||||
(workspaceSparseDraftParsed?.directories.length === 1
|
||||
? '1 directory'
|
||||
: `${workspaceSparseDraftParsed?.directories.length ?? 0} directories`)}
|
||||
(count === 1
|
||||
? translate(
|
||||
'tasks.workspaceTrustDrawers.directories_one',
|
||||
'{{count}} directory',
|
||||
{ count }
|
||||
)
|
||||
: translate(
|
||||
'tasks.workspaceTrustDrawers.directories_other',
|
||||
'{{count}} directories',
|
||||
{ count }
|
||||
))}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.drawerActionRow}>
|
||||
@@ -85,7 +104,7 @@ export function renderMobileTasksWorkspaceSparseDrawer(model: ConnectionPresenta
|
||||
disabled={workspaceSparseSaving}
|
||||
onPress={() => setWorkspaceSparseDraft(null)}
|
||||
>
|
||||
<Text style={styles.secondaryActionText}>Cancel</Text>
|
||||
<Text style={styles.secondaryActionText}>{translate('common.cancel', 'Cancel')}</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={[
|
||||
@@ -98,7 +117,7 @@ export function renderMobileTasksWorkspaceSparseDrawer(model: ConnectionPresenta
|
||||
{workspaceSparseSaving ? (
|
||||
<ActivityIndicator size="small" color={colors.bgBase} />
|
||||
) : null}
|
||||
<Text style={styles.primaryActionText}>Save</Text>
|
||||
<Text style={styles.primaryActionText}>{translate('common.save', 'Save')}</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
@@ -118,9 +137,17 @@ export function renderMobileTasksSetupTrustDrawer(model: ConnectionPresentationM
|
||||
{setupPrompt ? (
|
||||
<View>
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>Run Setup Script?</Text>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{translate('tasks.workspaceTrustDrawers.setupTitle', 'Run Setup Script?')}
|
||||
</Text>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
{setupPrompt.repoName} requires a setup choice before creating this workspace.
|
||||
{translate(
|
||||
'tasks.workspaceTrustDrawers.setupSubtitle',
|
||||
'{{name}} requires a setup choice before creating this workspace.',
|
||||
{
|
||||
name: setupPrompt.repoName
|
||||
}
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
@@ -151,7 +178,12 @@ export function renderMobileTasksSetupTrustDrawer(model: ConnectionPresentationM
|
||||
>
|
||||
<Check size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>
|
||||
{creatingKey === setupPrompt.item.key ? 'Creating...' : 'Run setup and create'}
|
||||
{creatingKey === setupPrompt.item.key
|
||||
? translate('tasks.workspaceTrustDrawers.creating', 'Creating...')
|
||||
: translate(
|
||||
'tasks.workspaceTrustDrawers.runSetupAndCreate',
|
||||
'Run setup and create'
|
||||
)}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<View style={styles.actionSeparator} />
|
||||
@@ -173,7 +205,12 @@ export function renderMobileTasksSetupTrustDrawer(model: ConnectionPresentationM
|
||||
}
|
||||
>
|
||||
<X size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>Skip setup and create</Text>
|
||||
<Text style={styles.actionText}>
|
||||
{translate(
|
||||
'tasks.workspaceTrustDrawers.skipSetupAndCreate',
|
||||
'Skip setup and create'
|
||||
)}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
@@ -203,19 +240,31 @@ export function renderMobileTasksOrcaYamlTrustDrawer(model: ConnectionPresentati
|
||||
<View style={styles.sheetHeader}>
|
||||
<Text style={styles.sheetTitle}>
|
||||
{orcaYamlTrustPrompt.previouslyApproved
|
||||
? `${orcaYamlTrustPrompt.repoName}'s setup script changed`
|
||||
: `Run setup from ${orcaYamlTrustPrompt.repoName}?`}
|
||||
? translate(
|
||||
'tasks.workspaceTrustDrawers.setupChangedTitle',
|
||||
"{{name}}'s setup script changed",
|
||||
{ name: orcaYamlTrustPrompt.repoName }
|
||||
)
|
||||
: translate(
|
||||
'tasks.workspaceTrustDrawers.runSetupTitle',
|
||||
'Run setup from {{name}}?',
|
||||
{ name: orcaYamlTrustPrompt.repoName }
|
||||
)}
|
||||
</Text>
|
||||
<Text style={styles.sheetSubtitle}>
|
||||
This repository's orca.yaml runs on your machine before the workspace starts. Only run
|
||||
it if you trust this repository.
|
||||
{translate(
|
||||
'tasks.workspaceTrustDrawers.trustSubtitle',
|
||||
"This repository's orca.yaml runs on your machine before the workspace starts. Only run it if you trust this repository."
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.setupPromptBox}>
|
||||
<View style={styles.detailSectionHeader}>
|
||||
<Text style={styles.detailSectionTitle}>
|
||||
{orcaYamlTrustPrompt.previouslyApproved ? 'New setup script' : 'Setup script'}
|
||||
{orcaYamlTrustPrompt.previouslyApproved
|
||||
? translate('tasks.workspaceTrustDrawers.newSetupScript', 'New setup script')
|
||||
: translate('tasks.workspaceTrustDrawers.setupScript', 'Setup script')}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.setupPromptCommand}>{orcaYamlTrustPrompt.scriptContent}</Text>
|
||||
@@ -247,13 +296,22 @@ export function renderMobileTasksOrcaYamlTrustDrawer(model: ConnectionPresentati
|
||||
orcaYamlTrustPrompt.contentHash
|
||||
)
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to trust setup script.')
|
||||
setError(
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate(
|
||||
'tasks.workspaceTrustDrawers.trustFailed',
|
||||
'Failed to trust setup script.'
|
||||
)
|
||||
)
|
||||
}
|
||||
})()
|
||||
}
|
||||
>
|
||||
<Check size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>Run hooks</Text>
|
||||
<Text style={styles.actionText}>
|
||||
{translate('tasks.workspaceTrustDrawers.runHooks', 'Run hooks')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<View style={styles.actionSeparator} />
|
||||
<Pressable
|
||||
@@ -281,13 +339,22 @@ export function renderMobileTasksOrcaYamlTrustDrawer(model: ConnectionPresentati
|
||||
orcaYamlTrustPrompt.contentHash
|
||||
)
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to trust setup script.')
|
||||
setError(
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: translate(
|
||||
'tasks.workspaceTrustDrawers.trustFailed',
|
||||
'Failed to trust setup script.'
|
||||
)
|
||||
)
|
||||
}
|
||||
})()
|
||||
}
|
||||
>
|
||||
<Check size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>Always trust and run</Text>
|
||||
<Text style={styles.actionText}>
|
||||
{translate('tasks.workspaceTrustDrawers.alwaysTrustAndRun', 'Always trust and run')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
<View style={styles.actionSeparator} />
|
||||
<Pressable
|
||||
@@ -310,7 +377,9 @@ export function renderMobileTasksOrcaYamlTrustDrawer(model: ConnectionPresentati
|
||||
}}
|
||||
>
|
||||
<X size={16} color={colors.textPrimary} />
|
||||
<Text style={styles.actionText}>Don't run</Text>
|
||||
<Text style={styles.actionText}>
|
||||
{translate('tasks.workspaceTrustDrawers.dontRun', "Don't run")}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
const WINDOWS_DRIVE_PATH_PATTERN = /^[A-Za-z]:/
|
||||
|
||||
export type SparsePresetDirectoryParseResult = {
|
||||
@@ -40,7 +42,10 @@ export function parseSparsePresetDirectories(value: string): SparsePresetDirecto
|
||||
if (rawEntries.some(isAbsoluteSparseDirectoryPath)) {
|
||||
return {
|
||||
directories: [],
|
||||
error: 'Use repo-relative directories, not root, absolute paths, or parent segments.'
|
||||
error: translate(
|
||||
'tasks.sparsePresetDraft.repoRelativeDirectoriesRequired',
|
||||
'Use repo-relative directories, not root, absolute paths, or parent segments.'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,14 +54,17 @@ export function parseSparsePresetDirectories(value: string): SparsePresetDirecto
|
||||
if (directories.length === 0) {
|
||||
return {
|
||||
directories,
|
||||
error: 'Add at least one directory.'
|
||||
error: translate('tasks.sparsePresetDraft.directoryRequired', 'Add at least one directory.')
|
||||
}
|
||||
}
|
||||
|
||||
if (directories.some((entry) => entry === '.' || entry.split('/').includes('..'))) {
|
||||
return {
|
||||
directories: [],
|
||||
error: 'Use repo-relative directories, not root, absolute paths, or parent segments.'
|
||||
error: translate(
|
||||
'tasks.sparsePresetDraft.repoRelativeDirectoriesRequired',
|
||||
'Use repo-relative directories, not root, absolute paths, or parent segments.'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import type {
|
||||
SmartNameSelection
|
||||
} from './mobile-composer-source-types'
|
||||
import { useMobileComposerName } from './use-mobile-composer-name'
|
||||
import { getBaseResolveError, useForkPushWarning } from './composer-source-copy'
|
||||
|
||||
export type UseMobileComposerSourceArgs = {
|
||||
client: RpcClient | null
|
||||
@@ -45,7 +46,7 @@ export function useMobileComposerSource(args: UseMobileComposerSourceArgs) {
|
||||
const [base, setBase] = useState<ComposerBaseState>({})
|
||||
const [reuseEligibleBranch, setReuseEligibleBranch] = useState<string | null>(null)
|
||||
const [reuseSelectedBranch, setReuseSelectedBranch] = useState(false)
|
||||
const [forkPushWarning, setForkPushWarning] = useState<string | null>(null)
|
||||
const [forkPushWarning, setForkPushWarning] = useForkPushWarning()
|
||||
const [resolvingBase, setResolvingBase] = useState(false)
|
||||
const [branchCreateIntent, setBranchCreateIntent] = useState(false)
|
||||
|
||||
@@ -78,11 +79,10 @@ export function useMobileComposerSource(args: UseMobileComposerSourceArgs) {
|
||||
setForkPushWarning(getForkPushWarning(result))
|
||||
})
|
||||
.catch((error: unknown) => {
|
||||
if (resolveTokenRef.current !== token) {
|
||||
return
|
||||
if (resolveTokenRef.current === token) {
|
||||
setBase({})
|
||||
onError?.(getBaseResolveError(error))
|
||||
}
|
||||
setBase({})
|
||||
onError?.(error instanceof Error ? error.message : 'Failed to resolve base branch.')
|
||||
})
|
||||
.finally(() => {
|
||||
if (resolveTokenRef.current === token) {
|
||||
|
||||
@@ -23,8 +23,10 @@ import {
|
||||
renderCommentReactions
|
||||
} from './mobile-tasks-legacy-foundation'
|
||||
import { styles } from './mobile-tasks-legacy-styles'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
|
||||
export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsModel) {
|
||||
const t = useMobileTranslation()
|
||||
const {
|
||||
actionItem,
|
||||
detailPayload,
|
||||
@@ -49,7 +51,7 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod
|
||||
style={[styles.input, styles.commentInput, styles.commentComposerInput]}
|
||||
value={args.value}
|
||||
onChangeText={args.onChangeText}
|
||||
placeholder="Add a comment"
|
||||
placeholder={t('tasks.detailCommentRenderers.commentPlaceholder', 'Add a comment')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
editable={!args.disabled}
|
||||
multiline
|
||||
@@ -59,7 +61,7 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod
|
||||
{hasText ? (
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Send comment"
|
||||
accessibilityLabel={t('tasks.detailCommentRenderers.sendComment', 'Send comment')}
|
||||
style={({ pressed }) => [
|
||||
styles.commentComposerSend,
|
||||
pressed && !args.disabled && styles.commentComposerSendPressed,
|
||||
@@ -111,7 +113,9 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod
|
||||
onPress={() => void toggleGitHubReviewThread(actionItem, comment)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{comment.isResolved ? 'Reopen thread' : 'Resolve thread'}
|
||||
{comment.isResolved
|
||||
? t('tasks.detailCommentRenderers.reopenThread', 'Reopen thread')
|
||||
: t('tasks.detailCommentRenderers.resolveThread', 'Resolve thread')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
) : null}
|
||||
@@ -124,7 +128,7 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod
|
||||
[String(comment.id)]: next
|
||||
}))
|
||||
}
|
||||
placeholder="Reply"
|
||||
placeholder={t('tasks.detailCommentRenderers.reply', 'Reply')}
|
||||
placeholderTextColor={colors.textMuted}
|
||||
multiline
|
||||
textAlignVertical="top"
|
||||
@@ -134,7 +138,9 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod
|
||||
disabled={mutatingStatus || !(itemReplyDrafts[String(comment.id)] ?? '').trim()}
|
||||
onPress={() => void replyToGitHubComment(actionItem, comment)}
|
||||
>
|
||||
<Text style={styles.inlineSaveText}>Reply</Text>
|
||||
<Text style={styles.inlineSaveText}>
|
||||
{t('tasks.detailCommentRenderers.reply', 'Reply')}
|
||||
</Text>
|
||||
</Pressable>
|
||||
</>
|
||||
) : null}
|
||||
@@ -151,6 +157,10 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod
|
||||
isResolvedDetailCommentGroup(group) && !expandedResolvedCommentGroups.has(id)
|
||||
|
||||
if (isCollapsedResolved) {
|
||||
const countLabel =
|
||||
count === 1
|
||||
? t('tasks.detailCommentRenderers.comments_one', '{{count}} comment', { count })
|
||||
: t('tasks.detailCommentRenderers.comments_other', '{{count}} comments', { count })
|
||||
return (
|
||||
<Pressable
|
||||
key={id}
|
||||
@@ -164,9 +174,25 @@ export function useMobileTasksDetailCommentRenderers(model: TaskCreateActionsMod
|
||||
}
|
||||
>
|
||||
<Text style={styles.resolvedCommentTitle} numberOfLines={1}>
|
||||
Resolved {group.kind === 'thread' ? 'thread' : 'comment'} by {commentAuthor(root)}
|
||||
{group.kind === 'thread'
|
||||
? t(
|
||||
'tasks.detailCommentRenderers.resolvedThreadBy',
|
||||
'Resolved thread by {{author}}',
|
||||
{
|
||||
author: commentAuthor(root)
|
||||
}
|
||||
)
|
||||
: t(
|
||||
'tasks.detailCommentRenderers.resolvedCommentBy',
|
||||
'Resolved comment by {{author}}',
|
||||
{
|
||||
author: commentAuthor(root)
|
||||
}
|
||||
)}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>
|
||||
{count > 1 ? countLabel : t('tasks.detailCommentRenderers.show', 'Show')}
|
||||
</Text>
|
||||
<Text style={styles.detailSectionMeta}>{count > 1 ? `${count} comments` : 'Show'}</Text>
|
||||
</Pressable>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { DetailCommentRenderersModel } from './use-mobile-tasks-detail-comm
|
||||
import { type PickerOption, View, useMemo, useMobileColorScheme } from './mobile-tasks-dependencies'
|
||||
import {
|
||||
type GitHubRepoSources,
|
||||
type LinearTeam,
|
||||
PROJECT_VIEW_DEFAULT_SORT,
|
||||
PROVIDER_OPTIONS,
|
||||
type RepoSummary,
|
||||
@@ -18,8 +17,23 @@ import {
|
||||
import { styles } from './mobile-tasks-legacy-styles'
|
||||
import { PROVIDER_LABELS } from './mobile-task-view-options'
|
||||
import { jiraSiteLabel } from './jira-mobile-connection'
|
||||
import type { Translate } from '../i18n/mobile-i18n'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
|
||||
function sourceCountLabel(count: number, t: Translate): string {
|
||||
return count === 1
|
||||
? t('tasks.pickerProjection.sources_one', '{{count}} source', { count })
|
||||
: t('tasks.pickerProjection.sources_other', '{{count}} sources', { count })
|
||||
}
|
||||
|
||||
function repoCountLabel(count: number, t: Translate): string {
|
||||
return count === 1
|
||||
? t('tasks.pickerProjection.repos_one', '{{count}} repo', { count })
|
||||
: t('tasks.pickerProjection.repos_other', '{{count}} repos', { count })
|
||||
}
|
||||
|
||||
export function useMobileTasksPickerProjection(model: DetailCommentRenderersModel) {
|
||||
const t = useMobileTranslation()
|
||||
const colorScheme = useMobileColorScheme()
|
||||
const {
|
||||
createRepoId,
|
||||
@@ -60,38 +74,39 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode
|
||||
label: team.name,
|
||||
subtitle: team.workspaceName
|
||||
})),
|
||||
[hostedRepos, linearTeams, provider, repoHostLabels]
|
||||
[hostedRepos, linearTeams, provider, repoHostLabels, t]
|
||||
)
|
||||
const selectedCreateTarget =
|
||||
const selectedCreateRepo =
|
||||
provider === 'github' || provider === 'gitlab'
|
||||
? (hostedRepos.find((repo) => repo.id === createRepoId) ?? hostedRepos[0] ?? null)
|
||||
: (linearTeams.find((team) => team.id === createTeamId) ?? linearTeams[0] ?? null)
|
||||
const selectedCreateTargetLabel =
|
||||
: null
|
||||
const selectedCreateTeam =
|
||||
provider === 'github' || provider === 'gitlab'
|
||||
? ((selectedCreateTarget as RepoSummary | null)?.displayName ?? 'Select target')
|
||||
: ((selectedCreateTarget as LinearTeam | null)?.name ?? 'Select target')
|
||||
? null
|
||||
: (linearTeams.find((team) => team.id === createTeamId) ?? linearTeams[0] ?? null)
|
||||
const selectedCreateTarget = selectedCreateRepo ?? selectedCreateTeam
|
||||
const selectedCreateTargetLabel =
|
||||
selectedCreateRepo?.displayName ??
|
||||
selectedCreateTeam?.name ??
|
||||
t('tasks.pickerProjection.selectTarget', 'Select target')
|
||||
const providerLabel = PROVIDER_LABELS[provider]
|
||||
const showHeaderCreateTask =
|
||||
provider === 'linear' || (provider === 'github' && githubMode === 'items')
|
||||
const jiraSiteOptions = useMemo<PickerOption<string>[]>(
|
||||
() => [
|
||||
{ value: 'all', label: 'All sites' },
|
||||
{ value: 'all', label: t('tasks.pickerProjection.allSites', 'All sites') },
|
||||
...jiraConnection.sites.map((site) => ({
|
||||
value: site.id,
|
||||
label: jiraSiteLabel(site),
|
||||
subtitle: site.siteUrl
|
||||
}))
|
||||
],
|
||||
[jiraConnection.sites]
|
||||
[jiraConnection.sites, t]
|
||||
)
|
||||
const providerOptions = useMemo(
|
||||
() => PROVIDER_OPTIONS.filter((option) => visibleProviders.includes(option.value)),
|
||||
[visibleProviders]
|
||||
[t, visibleProviders]
|
||||
)
|
||||
const selectedCreateRepo =
|
||||
provider === 'github' || provider === 'gitlab'
|
||||
? (selectedCreateTarget as RepoSummary | null)
|
||||
: null
|
||||
const selectedCreateGitHubSources =
|
||||
provider === 'github' && selectedCreateRepo
|
||||
? githubRepoSources[selectedCreateRepo.id]
|
||||
@@ -117,13 +132,13 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode
|
||||
? githubIssueSourceRows[0]!.sources.prs
|
||||
: githubIssueSourceRows[0]!.sources.upstreamCandidate
|
||||
)
|
||||
: `${githubIssueSourceRows.length} sources`
|
||||
: sourceCountLabel(githubIssueSourceRows.length, t)
|
||||
const repoPickerLabel =
|
||||
effectiveRepoIds.size === 0 || selectedHostedRepos.length === hostedRepos.length
|
||||
? 'All repos'
|
||||
? t('tasks.pickerProjection.allRepos', 'All repos')
|
||||
: selectedHostedRepos.length === 1
|
||||
? selectedHostedRepos[0]!.displayName
|
||||
: `${selectedHostedRepos.length} repos`
|
||||
: repoCountLabel(selectedHostedRepos.length, t)
|
||||
const repoPickerSelectedRepo =
|
||||
effectiveRepoIds.size > 0 && selectedHostedRepos.length === 1 ? selectedHostedRepos[0]! : null
|
||||
const workspaceRepoOptions = useMemo<PickerOption<string>[]>(
|
||||
@@ -136,7 +151,7 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode
|
||||
<View style={[styles.pickerRepoDot, { backgroundColor: getRepoBadgeColor(repo) }]} />
|
||||
)
|
||||
})),
|
||||
[repoHostLabels, workspaceRepos]
|
||||
[repoHostLabels, t, workspaceRepos]
|
||||
)
|
||||
const sortedItems = useMemo(
|
||||
() => sortMobileTaskItems(items, taskSort, reposById),
|
||||
@@ -162,8 +177,10 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode
|
||||
entries.push({ type: 'item', key: item.key, item })
|
||||
}
|
||||
return entries
|
||||
}, [colorScheme, reposById, sortedItems, taskSort])
|
||||
const sortLabel = SORT_OPTIONS.find((option) => option.value === taskSort)?.label ?? 'Updated'
|
||||
}, [colorScheme, reposById, sortedItems, t, taskSort])
|
||||
const sortLabel =
|
||||
SORT_OPTIONS.find((option) => option.value === taskSort)?.label ??
|
||||
t('tasks.pickerProjection.updatedSort', 'Updated')
|
||||
const githubProjectFields = githubProjectTable?.selectedView.fields ?? []
|
||||
const githubProjectViewSort = githubProjectTable?.selectedView.sortByFields?.[0] ?? null
|
||||
const githubProjectSortField = githubProjectSortOverride
|
||||
@@ -172,35 +189,53 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode
|
||||
const githubProjectSortDirection =
|
||||
githubProjectSortOverride?.direction ?? githubProjectViewSort?.direction ?? null
|
||||
const githubProjectSortLabel = githubProjectSortField
|
||||
? `${githubProjectSortField.name} ${githubProjectSortDirection === 'DESC' ? 'desc' : 'asc'}`
|
||||
: 'View order'
|
||||
? githubProjectSortDirection === 'DESC'
|
||||
? t('tasks.pickerProjection.fieldDescending', '{{field}} desc', {
|
||||
field: githubProjectSortField.name
|
||||
})
|
||||
: t('tasks.pickerProjection.fieldAscending', '{{field}} asc', {
|
||||
field: githubProjectSortField.name
|
||||
})
|
||||
: t('tasks.pickerProjection.viewOrder', 'View order')
|
||||
const githubProjectFieldsLabel =
|
||||
githubProjectAvailableSummaryFields.length > 0
|
||||
? `${githubProjectSummaryFields.length}/${githubProjectAvailableSummaryFields.length} fields`
|
||||
: 'Fields'
|
||||
? t('tasks.pickerProjection.selectedFields', '{{selected}}/{{total}} fields', {
|
||||
selected: githubProjectSummaryFields.length,
|
||||
total: githubProjectAvailableSummaryFields.length
|
||||
})
|
||||
: t('tasks.pickerProjection.fields', 'Fields')
|
||||
const githubProjectSortOptions = useMemo<PickerOption<string>[]>(
|
||||
() => [
|
||||
{
|
||||
value: PROJECT_VIEW_DEFAULT_SORT,
|
||||
label: 'View order',
|
||||
label: t('tasks.pickerProjection.viewOrder', 'View order'),
|
||||
subtitle: githubProjectViewSort
|
||||
? `Uses ${githubProjectViewSort.field.name} ${githubProjectViewSort.direction.toLowerCase()}`
|
||||
: 'Uses GitHub rank order'
|
||||
? githubProjectViewSort.direction === 'DESC'
|
||||
? t('tasks.pickerProjection.usesFieldDescending', 'Uses {{field}} desc', {
|
||||
field: githubProjectViewSort.field.name
|
||||
})
|
||||
: t('tasks.pickerProjection.usesFieldAscending', 'Uses {{field}} asc', {
|
||||
field: githubProjectViewSort.field.name
|
||||
})
|
||||
: t('tasks.pickerProjection.usesGitHubRankOrder', 'Uses GitHub rank order')
|
||||
},
|
||||
...githubProjectFields.map((field) => {
|
||||
const active = githubProjectSortOverride?.fieldId === field.id
|
||||
const nextDirection =
|
||||
!active || githubProjectSortOverride.direction === 'DESC' ? 'ascending' : 'descending'
|
||||
return {
|
||||
value: field.id,
|
||||
label: field.name,
|
||||
subtitle: active
|
||||
? `Currently ${githubProjectSortOverride.direction.toLowerCase()} · tap for ${nextDirection}`
|
||||
: 'Sort ascending'
|
||||
? githubProjectSortOverride.direction === 'DESC'
|
||||
? t(
|
||||
'tasks.pickerProjection.currentlyDescending',
|
||||
'Currently desc · tap for ascending'
|
||||
)
|
||||
: t('tasks.pickerProjection.currentlyAscending', 'Currently asc · tap for descending')
|
||||
: t('tasks.pickerProjection.sortAscending', 'Sort ascending')
|
||||
}
|
||||
})
|
||||
],
|
||||
[githubProjectFields, githubProjectSortOverride, githubProjectViewSort]
|
||||
[githubProjectFields, githubProjectSortOverride, githubProjectViewSort, t]
|
||||
)
|
||||
const githubProjectViewOptions = useMemo<PickerOption<string>[]>(
|
||||
() =>
|
||||
@@ -208,10 +243,12 @@ export function useMobileTasksPickerProjection(model: DetailCommentRenderersMode
|
||||
value: view.id,
|
||||
label: view.name,
|
||||
subtitle:
|
||||
view.layout === 'TABLE_LAYOUT' ? `View #${view.number}` : 'Unsupported layout on mobile',
|
||||
view.layout === 'TABLE_LAYOUT'
|
||||
? t('tasks.pickerProjection.viewNumber', 'View #{{number}}', { number: view.number })
|
||||
: t('tasks.pickerProjection.unsupportedLayout', 'Unsupported layout on mobile'),
|
||||
disabled: view.layout !== 'TABLE_LAYOUT'
|
||||
})),
|
||||
[githubProjectViews]
|
||||
[githubProjectViews, t]
|
||||
)
|
||||
return Object.assign(model, {
|
||||
createTargetOptions,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { PickerProjectionModel } from './use-mobile-tasks-picker-projection'
|
||||
import { JIRA_FILTER_LABELS } from './mobile-jira-issue-filters'
|
||||
import { jiraSiteLabel } from './jira-mobile-connection'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import {
|
||||
type PickerOption,
|
||||
githubProjectKey,
|
||||
@@ -23,6 +24,7 @@ import {
|
||||
} from './mobile-tasks-legacy-foundation'
|
||||
|
||||
export function useMobileTasksProviderViewProjection(model: PickerProjectionModel) {
|
||||
const t = useMobileTranslation()
|
||||
const colorScheme = useMobileColorScheme()
|
||||
const {
|
||||
activeGitHubProject,
|
||||
@@ -60,53 +62,70 @@ export function useMobileTasksProviderViewProjection(model: PickerProjectionMode
|
||||
() =>
|
||||
githubPresetOptions.map((option) =>
|
||||
option.value === defaultGitHubPreset
|
||||
? { ...option, subtitle: option.subtitle ? `${option.subtitle} · Default` : 'Default' }
|
||||
? {
|
||||
...option,
|
||||
subtitle: option.subtitle
|
||||
? t('tasks.providerViewProjection.defaultSubtitle', '{{subtitle}} · Default', {
|
||||
subtitle: option.subtitle
|
||||
})
|
||||
: t('tasks.providerViewProjection.default', 'Default')
|
||||
}
|
||||
: option
|
||||
),
|
||||
[defaultGitHubPreset, githubPresetOptions]
|
||||
[defaultGitHubPreset, githubPresetOptions, t]
|
||||
)
|
||||
const githubPresetLabel =
|
||||
githubPresetOptions.find((preset) => preset.value === githubPreset)?.label ?? 'Open'
|
||||
githubPresetOptions.find((preset) => preset.value === githubPreset)?.label ??
|
||||
t('tasks.providerViewProjection.openState', 'Open')
|
||||
const gitlabFilterLabel =
|
||||
GITLAB_FILTER_OPTIONS.find((filter) => filter.value === gitlabFilter)?.label ?? 'Open'
|
||||
GITLAB_FILTER_OPTIONS.find((filter) => filter.value === gitlabFilter)?.label ??
|
||||
t('tasks.providerViewProjection.openState', 'Open')
|
||||
const jiraFilterLabel = JIRA_FILTER_LABELS[jiraFilter]
|
||||
const jiraSelectedSite =
|
||||
jiraConnection.selection && jiraConnection.selection !== 'all'
|
||||
? (jiraConnection.sites.find((site) => site.id === jiraConnection.selection) ?? null)
|
||||
: null
|
||||
const jiraSiteChipLabel = jiraSelectedSite ? jiraSiteLabel(jiraSelectedSite) : 'All sites'
|
||||
const jiraSiteChipLabel = jiraSelectedSite
|
||||
? jiraSiteLabel(jiraSelectedSite)
|
||||
: t('tasks.providerViewProjection.allSites', 'All sites')
|
||||
const linearFilterLabel =
|
||||
LINEAR_FILTER_OPTIONS.find((filter) => filter.value === linearFilter)?.label ?? 'All'
|
||||
LINEAR_FILTER_OPTIONS.find((filter) => filter.value === linearFilter)?.label ??
|
||||
t('tasks.providerViewProjection.all', 'All')
|
||||
const linearViewLabel =
|
||||
LINEAR_VIEW_OPTIONS.find((option) => option.value === linearViewMode)?.label ?? 'List'
|
||||
LINEAR_VIEW_OPTIONS.find((option) => option.value === linearViewMode)?.label ??
|
||||
t('tasks.providerViewProjection.list', 'List')
|
||||
const linearGroupLabel =
|
||||
LINEAR_GROUP_OPTIONS.find((option) => option.value === linearGroupBy)?.label ?? 'No grouping'
|
||||
LINEAR_GROUP_OPTIONS.find((option) => option.value === linearGroupBy)?.label ??
|
||||
t('tasks.providerViewProjection.noGrouping', 'No grouping')
|
||||
const linearOrderLabel =
|
||||
LINEAR_ORDER_OPTIONS.find((option) => option.value === linearOrderBy)?.label ?? 'Priority'
|
||||
LINEAR_ORDER_OPTIONS.find((option) => option.value === linearOrderBy)?.label ??
|
||||
t('tasks.providerViewProjection.priority', 'Priority')
|
||||
const linearWorkspaceLabel =
|
||||
selectedLinearWorkspaceId === 'all'
|
||||
? 'All workspaces'
|
||||
? t('tasks.providerViewProjection.allWorkspaces', 'All workspaces')
|
||||
: (linearWorkspaces.find((workspace) => workspace.id === selectedLinearWorkspaceId)
|
||||
?.organizationName ??
|
||||
linearWorkspaces.find((workspace) => workspace.id === selectedLinearWorkspaceId)
|
||||
?.displayName ??
|
||||
'Workspace')
|
||||
t('tasks.providerViewProjection.workspace', 'Workspace'))
|
||||
const linearWorkspaceOptions = useMemo<PickerOption<string>[]>(
|
||||
() => [
|
||||
{ value: 'all', label: 'All workspaces' },
|
||||
{ value: 'all', label: t('tasks.providerViewProjection.allWorkspaces', 'All workspaces') },
|
||||
...linearWorkspaces.map((workspace) => ({
|
||||
value: workspace.id,
|
||||
label: workspace.organizationName ?? workspace.displayName ?? workspace.id
|
||||
}))
|
||||
],
|
||||
[linearWorkspaces]
|
||||
[linearWorkspaces, t]
|
||||
)
|
||||
const count = selectedLinearTeamIds.size
|
||||
const linearTeamLabel =
|
||||
selectedLinearTeamIds.size === 0 || selectedLinearTeamIds.size === linearTeams.length
|
||||
? 'All teams'
|
||||
: selectedLinearTeamIds.size === 1
|
||||
? (linearTeams.find((team) => selectedLinearTeamIds.has(team.id))?.name ?? '1 team')
|
||||
: `${selectedLinearTeamIds.size} teams`
|
||||
count === 0 || count === linearTeams.length
|
||||
? t('tasks.providerViewProjection.allTeams', 'All teams')
|
||||
: count === 1
|
||||
? (linearTeams.find((team) => selectedLinearTeamIds.has(team.id))?.name ??
|
||||
t('tasks.providerViewProjection.teams_one', '{{count}} team', { count }))
|
||||
: t('tasks.providerViewProjection.teams_other', '{{count}} teams', { count })
|
||||
const effectiveLinearDisplayProperties = useMemo(() => {
|
||||
const next = new Set(linearDisplayProperties)
|
||||
if (linearGroupBy === 'status') {
|
||||
@@ -147,7 +166,7 @@ export function useMobileTasksProviderViewProjection(model: PickerProjectionMode
|
||||
)
|
||||
const linearIssueSections = useMemo(
|
||||
() => groupSortedLinearIssues(linearIssuesForView, linearGroupBy),
|
||||
[colorScheme, linearGroupBy, linearIssuesForView]
|
||||
[colorScheme, linearGroupBy, linearIssuesForView, t]
|
||||
)
|
||||
// Preserve FlatList data identity across unrelated renders.
|
||||
const linearListEntries = useMemo<LinearListEntry[]>(
|
||||
@@ -168,15 +187,19 @@ export function useMobileTasksProviderViewProjection(model: PickerProjectionMode
|
||||
linearGroupBy === 'none'
|
||||
? groupSortedLinearIssues(linearIssuesForView, 'status')
|
||||
: linearIssueSections,
|
||||
[linearGroupBy, linearIssueSections, linearIssuesForView]
|
||||
[linearGroupBy, linearIssueSections, linearIssuesForView, t]
|
||||
)
|
||||
const githubModeLabel =
|
||||
githubMode === 'project' ? 'Projects' : githubKind === 'prs' ? 'PRs' : 'Issues'
|
||||
githubMode === 'project'
|
||||
? t('tasks.providerViewProjection.projects', 'Projects')
|
||||
: githubKind === 'prs'
|
||||
? t('tasks.providerViewProjection.pullRequests', 'PRs')
|
||||
: t('tasks.providerViewProjection.issues', 'Issues')
|
||||
const activeProjectLabel = githubProjectTable
|
||||
? githubProjectTable.project.title
|
||||
: activeGitHubProject
|
||||
? `${activeGitHubProject.owner} #${activeGitHubProject.number}`
|
||||
: 'Choose project'
|
||||
: t('tasks.providerViewProjection.chooseProject', 'Choose project')
|
||||
const selectedGitHubProjectViewUrl = githubProjectTable
|
||||
? `${githubProjectTable.project.url}/views/${githubProjectTable.selectedView.number}`
|
||||
: null
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ProjectMetadataLoadingModel } from './use-mobile-tasks-project-metadata-loading'
|
||||
import { useMobileTranslation } from '../i18n/use-mobile-translation'
|
||||
import {
|
||||
type BaseRefSearchResult,
|
||||
MOBILE_TUI_AGENT_AUTO_PICK_ORDER,
|
||||
@@ -23,6 +24,7 @@ import {
|
||||
} from './mobile-tasks-legacy-foundation'
|
||||
|
||||
export function useMobileTasksWorkspaceCreateProjection(model: ProjectMetadataLoadingModel) {
|
||||
const t = useMobileTranslation()
|
||||
const {
|
||||
repos,
|
||||
runtimeTaskSettings,
|
||||
@@ -109,7 +111,7 @@ export function useMobileTasksWorkspaceCreateProjection(model: ProjectMetadataLo
|
||||
workspaceSparseDraft
|
||||
? parseSparsePresetDirectories(workspaceSparseDraft.directoriesText)
|
||||
: null,
|
||||
[workspaceSparseDraft]
|
||||
[t, workspaceSparseDraft]
|
||||
)
|
||||
const workspaceSparseDraftName = workspaceSparseDraft?.name.trim() ?? ''
|
||||
const workspaceSparseDraftNameCollision =
|
||||
@@ -122,11 +124,13 @@ export function useMobileTasksWorkspaceCreateProjection(model: ProjectMetadataLo
|
||||
: null
|
||||
const workspaceSparseDraftError =
|
||||
workspaceSparseDraft && workspaceSparseDraftName.length === 0
|
||||
? 'Name is required.'
|
||||
? t('tasks.workspaceCreateProjection.nameRequired', 'Name is required.')
|
||||
: workspaceSparseDraftName.length > 80
|
||||
? 'Name must be 80 characters or fewer.'
|
||||
? t('tasks.workspaceCreateProjection.nameTooLong', 'Name must be 80 characters or fewer.')
|
||||
: workspaceSparseDraftNameCollision
|
||||
? `"${workspaceSparseDraftNameCollision.name}" already exists.`
|
||||
? t('tasks.workspaceCreateProjection.nameAlreadyExists', '"{{name}}" already exists.', {
|
||||
name: workspaceSparseDraftNameCollision.name
|
||||
})
|
||||
: (workspaceSparseDraftParsed?.error ?? null)
|
||||
const canSaveWorkspaceSparseDraft =
|
||||
workspaceSparseDraft !== null &&
|
||||
@@ -166,11 +170,11 @@ export function useMobileTasksWorkspaceCreateProjection(model: ProjectMetadataLo
|
||||
{
|
||||
value: 'blank' as const,
|
||||
label: workspaceAgentLabel('blank'),
|
||||
subtitle: 'Open a shell',
|
||||
subtitle: t('tasks.workspaceCreateProjection.openShell', 'Open a shell'),
|
||||
renderIcon: () => <MobileAgentIcon agentId="__blank__" size={18} />
|
||||
}
|
||||
]
|
||||
}, [runtimeTaskSettings.disabledTuiAgents, workspaceAgent, workspaceDetectedAgentIds])
|
||||
}, [runtimeTaskSettings.disabledTuiAgents, t, workspaceAgent, workspaceDetectedAgentIds])
|
||||
const openWorkspaceCreate = useCallback((item: ActionableTaskItem, repoIdOverride?: string) => {
|
||||
const suggestedName = taskWorkspaceSuggestedName(item)
|
||||
setWorkspaceCreateDraft({ item, ...(repoIdOverride ? { repoIdOverride } : {}) })
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { TuiAgent } from '../../../src/shared/tui-agent'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
import {
|
||||
filterEnabledMobileTuiAgents,
|
||||
isMobileTuiAgent,
|
||||
@@ -27,7 +28,9 @@ type ResolveWorkspaceAgentSelectionArgs = WorkspaceAgentSelectionState & {
|
||||
}
|
||||
|
||||
export function workspaceAgentLabel(agent: WorkspaceAgentChoice): string {
|
||||
return agent === 'blank' ? 'Blank Terminal' : MOBILE_TUI_AGENT_LABELS[agent]
|
||||
return agent === 'blank'
|
||||
? translate('tasks.workspaceAgentSelection.blankTerminal', 'Blank Terminal')
|
||||
: MOBILE_TUI_AGENT_LABELS[agent]
|
||||
}
|
||||
|
||||
export function normalizeWorkspaceAgent(value: unknown): WorkspaceAgentChoice | null {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { SshConnectionState, SshConnectionStatus } from '../../../src/shared/ssh-types'
|
||||
import { ORCAD_RECLAIM_STALE_LOCK_FLAG } from '../../../src/shared/orcad-stale-lock-reclaim'
|
||||
import { translate } from '../i18n/mobile-i18n'
|
||||
|
||||
// Keep unread SSH fields optional so an omitted member cannot drop auth-failed state into connected fallback.
|
||||
export type WorkspaceSshRecord = Omit<
|
||||
@@ -25,27 +26,27 @@ function isWorkspaceSshConnectInProgress(status: SshConnectionStatus | null): bo
|
||||
|
||||
export function workspaceSshStatusLabel(status: SshConnectionStatus | null): string {
|
||||
if (status === 'connected') {
|
||||
return 'Connected'
|
||||
return translate('tasks.workspaceSshGate.connected', 'Connected')
|
||||
}
|
||||
if (status === 'connecting') {
|
||||
return 'Connecting'
|
||||
return translate('tasks.workspaceSshGate.connecting', 'Connecting')
|
||||
}
|
||||
if (status === 'deploying-relay') {
|
||||
return 'Deploying relay'
|
||||
return translate('tasks.workspaceSshGate.deployingRelay', 'Deploying relay')
|
||||
}
|
||||
if (status === 'reconnecting') {
|
||||
return 'Reconnecting'
|
||||
return translate('tasks.workspaceSshGate.reconnecting', 'Reconnecting')
|
||||
}
|
||||
if (status === 'auth-failed') {
|
||||
return 'Authentication failed'
|
||||
return translate('tasks.workspaceSshGate.authenticationFailed', 'Authentication failed')
|
||||
}
|
||||
if (status === 'reconnection-failed') {
|
||||
return 'Reconnect failed'
|
||||
return translate('tasks.workspaceSshGate.reconnectFailed', 'Reconnect failed')
|
||||
}
|
||||
if (status === 'error') {
|
||||
return 'Connection failed'
|
||||
return translate('tasks.workspaceSshGate.connectionFailed', 'Connection failed')
|
||||
}
|
||||
return 'Disconnected'
|
||||
return translate('tasks.workspaceSshGate.disconnected', 'Disconnected')
|
||||
}
|
||||
|
||||
export function deriveWorkspaceSshGate(args: {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user