@cat-factory/app 0.274.0 → 0.276.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +158 -4
- package/app/components/board/LaneViewControl.vue +87 -0
- package/app/components/board/nodes/BlockNode.vue +31 -11
- package/app/components/board/nodes/FrameSwimlanes.vue +139 -0
- package/app/components/board/nodes/InitiativeCard.vue +9 -28
- package/app/components/board/nodes/LaneGroup.vue +93 -0
- package/app/components/board/nodes/LaneTask.vue +66 -0
- package/app/components/board/nodes/TaskCard.vue +16 -2
- package/app/components/board/nodes/TaskLane.vue +82 -0
- package/app/components/layout/BoardToolbar.vue +4 -0
- package/app/components/layout/CommandBar.vue +8 -1
- package/app/components/layout/RolePrompt.vue +75 -0
- package/app/components/layout/SideBar.vue +22 -13
- package/app/components/layout/UiRoleSwitcher.vue +73 -0
- package/app/components/panels/InspectorPanel.vue +15 -2
- package/app/components/panels/inspector/TaskStructure.vue +70 -3
- package/app/components/settings/WorkspaceSettingsPanel.vue +59 -0
- package/app/composables/useBlockDrag.ts +47 -17
- package/app/composables/useBlockQueries.ts +27 -24
- package/app/composables/useFrameLanes.ts +177 -0
- package/app/composables/useNavContributions.ts +3 -0
- package/app/composables/useTaskExpansion.ts +1 -1
- package/app/docs/consumer-extensions.md +20 -6
- package/app/modular/external-tools.spec.ts +0 -45
- package/app/modular/external-tools.ts +12 -23
- package/app/modular/nav-contributions.spec.ts +176 -17
- package/app/modular/nav-contributions.ts +106 -23
- package/app/modular/nav-gates.ts +11 -2
- package/app/modular/registry.spec.ts +1 -0
- package/app/modular/tutorial-tours.spec.ts +5 -3
- package/app/modular/tutorial-tours.ts +53 -8
- package/app/pages/index.vue +36 -7
- package/app/stores/board/placement.ts +7 -0
- package/app/stores/board.spec.ts +119 -14
- package/app/stores/laneView.spec.ts +61 -0
- package/app/stores/laneView.ts +85 -0
- package/app/stores/launchPrompt.ts +63 -0
- package/app/stores/taskExpansion.spec.ts +1 -1
- package/app/stores/taskExpansion.ts +1 -1
- package/app/stores/tutorial.ts +4 -4
- package/app/stores/uiMode.spec.ts +11 -0
- package/app/stores/uiMode.ts +14 -2
- package/app/stores/uiRole.spec.ts +185 -0
- package/app/stores/uiRole.ts +86 -0
- package/app/stores/workspaceSettings.ts +4 -0
- package/app/utils/framePlacement.ts +9 -4
- package/app/utils/laneGeometry.spec.ts +69 -0
- package/app/utils/laneGeometry.ts +104 -0
- package/app/utils/laneSort.spec.ts +236 -0
- package/app/utils/laneSort.ts +306 -0
- package/app/utils/swimlanes.spec.ts +259 -0
- package/app/utils/swimlanes.ts +355 -0
- package/app/utils/uiMode.spec.ts +12 -0
- package/app/utils/uiMode.ts +24 -6
- package/app/utils/uiRole.ts +123 -0
- package/i18n/locales/de.json +104 -3
- package/i18n/locales/en.json +110 -3
- package/i18n/locales/es.json +104 -3
- package/i18n/locales/fr.json +104 -3
- package/i18n/locales/he.json +104 -3
- package/i18n/locales/it.json +104 -3
- package/i18n/locales/ja.json +104 -3
- package/i18n/locales/pl.json +104 -3
- package/i18n/locales/tr.json +104 -3
- package/i18n/locales/uk.json +104 -3
- package/package.json +2 -2
- package/app/components/board/nodes/DraggableTask.vue +0 -58
- package/app/components/board/nodes/ModuleFrame.vue +0 -73
- package/app/stores/tutorial.prompt.ts +0 -59
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ROLE the person at the keyboard is here to do: `engineer`, `product-manager` or
|
|
3
|
+
* `designer`. Pure resolution logic, kept out of the store so it is testable without Pinia.
|
|
4
|
+
*
|
|
5
|
+
* This is the third narrowing axis in the SPA and it answers a different question from the
|
|
6
|
+
* other two. The interface MODE (`utils/uiMode.ts`) asks how much of the product to show;
|
|
7
|
+
* the AGENT TIER asks how deep into the agent catalog one surface reaches; the role asks
|
|
8
|
+
* WHICH JOB the surfaces are for. Engineer and product-manager do the same job here (plan
|
|
9
|
+
* work, run it, review and merge it), so they resolve to the same surface today and are kept
|
|
10
|
+
* as separate members because the copy people pick themselves by is the thing that makes the
|
|
11
|
+
* question answerable, and because the two diverge the moment one of them gets a surface the
|
|
12
|
+
* other does not.
|
|
13
|
+
*
|
|
14
|
+
* It is NOT authorization. Workspace RBAC (ADR 0025) decides what a request may do, is
|
|
15
|
+
* enforced server-side, and cannot be widened from a browser; this decides what the SPA
|
|
16
|
+
* OFFERS, and every role resolves to a surface the caller's permissions still gate. A role
|
|
17
|
+
* that hid a permitted destination would be a lie about the product, which is why the way
|
|
18
|
+
* back out of a narrowed role is reachable from inside it (see `UiRoleSwitcher`).
|
|
19
|
+
*/
|
|
20
|
+
export const UI_ROLES = ['engineer', 'product-manager', 'designer'] as const
|
|
21
|
+
|
|
22
|
+
export type UiRole = (typeof UI_ROLES)[number]
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The role a browser gets before the person picks one.
|
|
26
|
+
*
|
|
27
|
+
* The FULL surface, deliberately: an unanswered question must never take capability away.
|
|
28
|
+
* The first-run prompt is offered once per session until it is answered (see `stores/uiRole.ts`),
|
|
29
|
+
* and closing it leaves the whole product in place rather than guessing a narrower persona.
|
|
30
|
+
*/
|
|
31
|
+
export const DEFAULT_UI_ROLE: UiRole = 'engineer'
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* How much of the SPA a role is offered.
|
|
35
|
+
*
|
|
36
|
+
* - `full`: every destination the caller's permissions and the interface tier allow.
|
|
37
|
+
* - `intake`: the services already on the board, the tasks in flight on them, and the routes
|
|
38
|
+
* that bring new work IN (a new task, a task from a tracker ticket, a task from a design).
|
|
39
|
+
* None of the platform configuration behind them: an intake role never sets up a repo, a
|
|
40
|
+
* model, a pipeline or an integration, so carrying those destinations costs the surface more
|
|
41
|
+
* than the capability is worth there.
|
|
42
|
+
*
|
|
43
|
+
* A SURFACE rather than a per-role list of ids, because the narrowing is a property of the
|
|
44
|
+
* WORK, not of the persona's name: a second delivery-only persona reuses `intake` instead of
|
|
45
|
+
* copying its allow-list, and nothing has to be re-decided per role. The mapping is an
|
|
46
|
+
* exhaustive Record, so a new role fails the build until it picks a side.
|
|
47
|
+
*/
|
|
48
|
+
export type RoleSurface = 'full' | 'intake'
|
|
49
|
+
|
|
50
|
+
export const ROLE_SURFACES: Record<UiRole, RoleSurface> = {
|
|
51
|
+
engineer: 'full',
|
|
52
|
+
'product-manager': 'full',
|
|
53
|
+
designer: 'intake',
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* How each role is PRESENTED: its name, the one line that says what picking it gives you, and
|
|
58
|
+
* its glyph. One table rather than a copy in the switcher and another in the first-run prompt,
|
|
59
|
+
* because the two surfaces must not be able to describe the same role differently. The prompt
|
|
60
|
+
* is where the choice is explained and the switcher is where it is recognised later.
|
|
61
|
+
*
|
|
62
|
+
* i18n keys rather than strings (no display copy in code), and an exhaustive Record, so a new
|
|
63
|
+
* role fails the build until it has both. The keys themselves are invisible to typed messages
|
|
64
|
+
* and to `i18n:check`, since neither sees a key reached through a table lookup rather than
|
|
65
|
+
* written literally at the call site, which is what `uiRole.spec.ts` asserts against the base
|
|
66
|
+
* catalog instead.
|
|
67
|
+
*/
|
|
68
|
+
export interface RolePresentation {
|
|
69
|
+
labelKey: string
|
|
70
|
+
hintKey: string
|
|
71
|
+
icon: string
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const ROLE_PRESENTATION: Record<UiRole, RolePresentation> = {
|
|
75
|
+
engineer: {
|
|
76
|
+
labelKey: 'uiRole.roles.engineer',
|
|
77
|
+
hintKey: 'uiRole.hints.engineer',
|
|
78
|
+
icon: 'i-lucide-code-xml',
|
|
79
|
+
},
|
|
80
|
+
'product-manager': {
|
|
81
|
+
labelKey: 'uiRole.roles.productManager',
|
|
82
|
+
hintKey: 'uiRole.hints.productManager',
|
|
83
|
+
icon: 'i-lucide-clipboard-list',
|
|
84
|
+
},
|
|
85
|
+
designer: {
|
|
86
|
+
labelKey: 'uiRole.roles.designer',
|
|
87
|
+
hintKey: 'uiRole.hints.designer',
|
|
88
|
+
icon: 'i-lucide-frame',
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Coerce an untrusted value (a restored localStorage blob, possibly written by an older
|
|
94
|
+
* build or hand-edited) to a known role. Anything unrecognised resolves to `null`, i.e.
|
|
95
|
+
* "nobody has picked one", so {@link resolveUiRole} falls back to the default and the
|
|
96
|
+
* first-run prompt asks again. Never throws: a stale persisted value must not fail the boot.
|
|
97
|
+
*/
|
|
98
|
+
export function parseUiRole(raw: unknown): UiRole | null {
|
|
99
|
+
if (typeof raw !== 'string') return null
|
|
100
|
+
const value = raw.trim().toLowerCase()
|
|
101
|
+
return (UI_ROLES as readonly string[]).includes(value) ? (value as UiRole) : null
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Apply the precedence: the person's own stored choice → {@link DEFAULT_UI_ROLE}. */
|
|
105
|
+
export function resolveUiRole(stored: UiRole | null): UiRole {
|
|
106
|
+
return stored ?? DEFAULT_UI_ROLE
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Which surface a role is offered. */
|
|
110
|
+
export function roleSurface(role: UiRole): RoleSurface {
|
|
111
|
+
return ROLE_SURFACES[role]
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Whether the role sees the whole product.
|
|
116
|
+
*
|
|
117
|
+
* Stated POSITIVELY, and read that way everywhere (the `fullSurface` nav gate, the
|
|
118
|
+
* `intake` contribution flag it admits): a narrowing expressed as "not hidden" inverts once
|
|
119
|
+
* per reader and the reader that gets it backwards shows a designer the operator dashboard.
|
|
120
|
+
*/
|
|
121
|
+
export function isFullSurfaceRole(role: UiRole): boolean {
|
|
122
|
+
return roleSurface(role) === 'full'
|
|
123
|
+
}
|
package/i18n/locales/de.json
CHANGED
|
@@ -1163,6 +1163,15 @@
|
|
|
1163
1163
|
"advisory": "Hinweis (erfassen, nie anhalten)",
|
|
1164
1164
|
"off": "Aus (Prüfung überspringen)"
|
|
1165
1165
|
}
|
|
1166
|
+
},
|
|
1167
|
+
"doneLane": {
|
|
1168
|
+
"heading": "Spalte „Fertig“",
|
|
1169
|
+
"body": "Wie viel abgeschlossene Arbeit die Spalte „Fertig“ jedes Service-Rahmens sichtbar hält. Beide Grenzen verbergen nur Karten: eine ausgeblendete Aufgabe bleibt auf dem Board, bleibt durchsuchbar und bleibt in der Gesamtzahl der Spalte.",
|
|
1170
|
+
"maxItems": "Angezeigte Karten",
|
|
1171
|
+
"zeroHint": "Abgeschlossene Aufgaben werden gezählt, aber nie aufgeführt.",
|
|
1172
|
+
"ageToggle": "Außerdem länger abgeschlossene Aufgaben verbergen",
|
|
1173
|
+
"days": "Aufbewahren (Tage)",
|
|
1174
|
+
"hidesOnlyHint": "Es wird nichts gelöscht. Aufgaben ohne erfasstes Abschlussdatum werden nie wegen ihres Alters verborgen."
|
|
1166
1175
|
}
|
|
1167
1176
|
},
|
|
1168
1177
|
"localModelEndpoints": {
|
|
@@ -1791,11 +1800,12 @@
|
|
|
1791
1800
|
"title": "Struktur",
|
|
1792
1801
|
"hint": "Wo diese Aufgabe in ihrem Service liegt und welchen Coding-Standards ihre Agents folgen.",
|
|
1793
1802
|
"module": "Modul",
|
|
1794
|
-
"modulePlaceholder": "
|
|
1795
|
-
"moduleHint": "Das Service-Modul, zu dem diese Aufgabe gehört
|
|
1803
|
+
"modulePlaceholder": "Modul wählen oder eingeben",
|
|
1804
|
+
"moduleHint": "Das Service-Modul, zu dem diese Aufgabe gehört; das Board gruppiert die Spalten danach. Ein noch nicht vorhandenes Modul wird bei der Umsetzung der Aufgabe erstellt.",
|
|
1796
1805
|
"bestPractices": "Best Practices",
|
|
1797
1806
|
"bestPracticesEmpty": "Keine. Agents folgen ihren Standardvorgaben.",
|
|
1798
|
-
"bestPracticesHint": "Best-Practice-Fragmente, die zusätzlich zu den Standards auf Service-Ebene in die Prompts der Agents dieser Aufgabe eingearbeitet werden."
|
|
1807
|
+
"bestPracticesHint": "Best-Practice-Fragmente, die zusätzlich zu den Standards auf Service-Ebene in die Prompts der Agents dieser Aufgabe eingearbeitet werden.",
|
|
1808
|
+
"moduleNone": "Kein Modul"
|
|
1799
1809
|
},
|
|
1800
1810
|
"runSettings": {
|
|
1801
1811
|
"title": "Lauf-Einstellungen",
|
|
@@ -2667,6 +2677,7 @@
|
|
|
2667
2677
|
"shortcuts": "Tastenkürzel",
|
|
2668
2678
|
"bugHunt": "Fehlerjagd",
|
|
2669
2679
|
"toggleUiMode": "Oberflächenmodus wechseln",
|
|
2680
|
+
"chooseRole": "Rolle wechseln",
|
|
2670
2681
|
"foundationalServices": "Basisdienste",
|
|
2671
2682
|
"notificationSettings": "Benachrichtigungs-Routing verwalten"
|
|
2672
2683
|
},
|
|
@@ -2691,6 +2702,7 @@
|
|
|
2691
2702
|
"shortcuts": "keyboard shortcuts keys hotkeys cheatsheet help",
|
|
2692
2703
|
"bugHunt": "fehler bug jagd triage backlog tracker nicht zugewiesen",
|
|
2693
2704
|
"toggleUiMode": "oberfläche modus einfach erweitert anzeigen ausblenden",
|
|
2705
|
+
"chooseRole": "rolle entwickler produktmanager designer persona einfachere ansicht",
|
|
2694
2706
|
"tutorial": "tutorial tour einführung hilfe onboarding lernen grundlagen",
|
|
2695
2707
|
"foundationalServices": "gemeinsame Fähigkeit Plattform Dienst API Vertrag OpenAPI Katalog",
|
|
2696
2708
|
"notificationSettings": "benachrichtigungen e-mail routing kanäle posteingang"
|
|
@@ -3259,6 +3271,71 @@
|
|
|
3259
3271
|
"label": "Epic",
|
|
3260
3272
|
"activeCount": "{count} aktiv",
|
|
3261
3273
|
"noTasksYet": "Noch keine Aufgaben"
|
|
3274
|
+
},
|
|
3275
|
+
"lanes": {
|
|
3276
|
+
"viewTitle": "Anordnen",
|
|
3277
|
+
"resetView": "Auf Standard zurücksetzen",
|
|
3278
|
+
"notStarted": {
|
|
3279
|
+
"label": "Nicht begonnen",
|
|
3280
|
+
"empty": "Nichts wartet auf Bearbeitung."
|
|
3281
|
+
},
|
|
3282
|
+
"inProgress": {
|
|
3283
|
+
"label": "In Arbeit",
|
|
3284
|
+
"empty": "Keine laufenden Durchläufe."
|
|
3285
|
+
},
|
|
3286
|
+
"needsYou": {
|
|
3287
|
+
"label": "Wartet auf dich",
|
|
3288
|
+
"empty": "Nichts wartet auf dich."
|
|
3289
|
+
},
|
|
3290
|
+
"done": {
|
|
3291
|
+
"label": "Fertig",
|
|
3292
|
+
"empty": "Noch nichts abgeschlossen.",
|
|
3293
|
+
"hiddenByCap": "+{count} nicht angezeigt",
|
|
3294
|
+
"hiddenByAge": "+{count} außerhalb des Aufbewahrungszeitraums",
|
|
3295
|
+
"undated": "{count} ohne erfasstes Datum",
|
|
3296
|
+
"allWithheld": "Abgeschlossene Aufgaben werden hier gezählt, aber laut Board-Einstellungen nicht aufgeführt."
|
|
3297
|
+
},
|
|
3298
|
+
"reason": {
|
|
3299
|
+
"unstarted": "Startbereit",
|
|
3300
|
+
"dependencies": "Wartet auf eine Abhängigkeit",
|
|
3301
|
+
"running": "Läuft",
|
|
3302
|
+
"backgroundReview": "Prüfung im Hintergrund",
|
|
3303
|
+
"decision": "Entscheidung erforderlich",
|
|
3304
|
+
"approval": "Freigabe erforderlich",
|
|
3305
|
+
"failed": "Durchlauf fehlgeschlagen",
|
|
3306
|
+
"budgetPaused": "Vom Ausgabenbudget angehalten",
|
|
3307
|
+
"prAwaitingMerge": "Pull Request wartet auf Merge",
|
|
3308
|
+
"parked": "Wartet auf einen Menschen",
|
|
3309
|
+
"unclassified": "Unbekannter Status",
|
|
3310
|
+
"merged": "Zusammengeführt"
|
|
3311
|
+
},
|
|
3312
|
+
"sort": {
|
|
3313
|
+
"heading": "Sortieren nach",
|
|
3314
|
+
"smart": "Pro Spalte empfohlen",
|
|
3315
|
+
"title": "Titel (A–Z)",
|
|
3316
|
+
"oldest_activity": "Stillste zuerst",
|
|
3317
|
+
"newest_activity": "Zuletzt aktiv",
|
|
3318
|
+
"longest_wait": "Am längsten wartend",
|
|
3319
|
+
"severity_desc": "Schweregrad (höchster zuerst)",
|
|
3320
|
+
"impact_desc": "Geschätzte Wirkung (höchste zuerst)",
|
|
3321
|
+
"task_type": "Aufgabentyp"
|
|
3322
|
+
},
|
|
3323
|
+
"group": {
|
|
3324
|
+
"heading": "Gruppieren nach",
|
|
3325
|
+
"none": "Keine Gruppierung",
|
|
3326
|
+
"module": "Modul",
|
|
3327
|
+
"task_type": "Aufgabentyp",
|
|
3328
|
+
"initiative": "Initiative",
|
|
3329
|
+
"epic": "Epic",
|
|
3330
|
+
"blocking_reason": "Was benötigt wird",
|
|
3331
|
+
"catchAll": {
|
|
3332
|
+
"module": "Kein Modul",
|
|
3333
|
+
"task_type": "Kein Typ",
|
|
3334
|
+
"initiative": "Nicht in einer Initiative",
|
|
3335
|
+
"epic": "Nicht in einem Epic",
|
|
3336
|
+
"blocking_reason": "Nicht klassifiziert"
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3262
3339
|
}
|
|
3263
3340
|
},
|
|
3264
3341
|
"contextAttachments": {
|
|
@@ -5665,6 +5742,25 @@
|
|
|
5665
5742
|
"switchTo": "Zu „{mode}“ wechseln",
|
|
5666
5743
|
"pinned": "Von dieser Installation festgelegt"
|
|
5667
5744
|
},
|
|
5745
|
+
"uiRole": {
|
|
5746
|
+
"switcher": "Deine Rolle",
|
|
5747
|
+
"roles": {
|
|
5748
|
+
"engineer": "Entwickler",
|
|
5749
|
+
"productManager": "Produktmanager",
|
|
5750
|
+
"designer": "Designer"
|
|
5751
|
+
},
|
|
5752
|
+
"hints": {
|
|
5753
|
+
"engineer": "Alles: Arbeit planen, ausführen, prüfen und mergen sowie die Plattform dahinter einrichten.",
|
|
5754
|
+
"productManager": "Dieselben Flächen wie beim Entwickler: Arbeit planen, ausführen und bis zum Merge begleiten.",
|
|
5755
|
+
"designer": "Ein einfacheres Board: die Services, die schon darauf sind, die laufende Arbeit und neue Aufgaben aus einem Design oder Issue."
|
|
5756
|
+
},
|
|
5757
|
+
"prompt": {
|
|
5758
|
+
"title": "Woran arbeitest du?",
|
|
5759
|
+
"intro": "Wähle das Passendste, dann startet die App mit den Flächen, die diese Aufgabe braucht. Das ändert nur, was du SIEHST, nie was du darfst.",
|
|
5760
|
+
"change": "Du kannst das jederzeit oben in der Seitenleiste ändern.",
|
|
5761
|
+
"later": "Jetzt nicht"
|
|
5762
|
+
}
|
|
5763
|
+
},
|
|
5668
5764
|
"common": {
|
|
5669
5765
|
"loading": "Wird geladen…",
|
|
5670
5766
|
"save": "Speichern",
|
|
@@ -7453,6 +7549,7 @@
|
|
|
7453
7549
|
"failedRun": "Ein fehlgeschlagener Lauf",
|
|
7454
7550
|
"infrastructure": "Ein mit diesem Workspace verbundenes Ausführungs-Backend",
|
|
7455
7551
|
"advancedTier": "Der erweiterte Oberflächenmodus",
|
|
7552
|
+
"fullSurface": "Die Rolle „Entwickler“ oder „Produktmanager“",
|
|
7456
7553
|
"designSource": "Eine verbundene Design-Quelle"
|
|
7457
7554
|
},
|
|
7458
7555
|
"overlay": {
|
|
@@ -7494,6 +7591,10 @@
|
|
|
7494
7591
|
"title": "Board-Steuerung",
|
|
7495
7592
|
"body": "Mit diesen Steuerelementen zoomst du hinein und heraus oder bringst das ganze Board ins Bild."
|
|
7496
7593
|
},
|
|
7594
|
+
"role": {
|
|
7595
|
+
"title": "Deine Rolle",
|
|
7596
|
+
"body": "Das Board richtet sich nach deiner Aufgabe: Entwickler und Produktmanager sehen alle Flächen, Designer eine einfachere, die Arbeit hereinholt und verfolgt. Du kannst das hier jederzeit ändern."
|
|
7597
|
+
},
|
|
7497
7598
|
"interfaceTier": {
|
|
7498
7599
|
"title": "Einfach und erweitert",
|
|
7499
7600
|
"body": "Die Oberfläche startet im einfachen Modus, der die alltäglichen Arbeitsflächen zeigt. Wechsle hier auf erweitert, wenn du zusätzlich die Flächen für Experimente, Bootstrap und Betrieb brauchst."
|
package/i18n/locales/en.json
CHANGED
|
@@ -38,6 +38,31 @@
|
|
|
38
38
|
},
|
|
39
39
|
"pinned": "Set by this deployment"
|
|
40
40
|
},
|
|
41
|
+
"uiRole": {
|
|
42
|
+
"switcher": "Your role",
|
|
43
|
+
"@switcher": {
|
|
44
|
+
"description": "Label above the picker that chooses which job the person does (Engineer, Product manager, Designer). It tunes which surfaces the app shows; it is NOT a permission or a job title in an org chart."
|
|
45
|
+
},
|
|
46
|
+
"roles": {
|
|
47
|
+
"engineer": "Engineer",
|
|
48
|
+
"productManager": "Product manager",
|
|
49
|
+
"designer": "Designer",
|
|
50
|
+
"@designer": {
|
|
51
|
+
"description": "A product/UX designer: the person who makes the designs the work is built from. Not a 'designer' in any other sense."
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"hints": {
|
|
55
|
+
"engineer": "Everything: plan work, run it, review and merge it, and set up the platform it runs on.",
|
|
56
|
+
"productManager": "The same surfaces as an engineer: plan work, run it, and follow it through to a merge.",
|
|
57
|
+
"designer": "A simpler board: the services already on it, the work in flight, and new tasks from a design or a ticket."
|
|
58
|
+
},
|
|
59
|
+
"prompt": {
|
|
60
|
+
"title": "What do you work on?",
|
|
61
|
+
"intro": "Pick the closest match and the app opens on the surfaces that job needs. This changes what you SEE, never what you are allowed to do.",
|
|
62
|
+
"change": "You can change this at any time from the top of the sidebar.",
|
|
63
|
+
"later": "Not now"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
41
66
|
"common": {
|
|
42
67
|
"loading": "Loading…",
|
|
43
68
|
"save": "Save",
|
|
@@ -544,6 +569,71 @@
|
|
|
544
569
|
"label": "Epic",
|
|
545
570
|
"activeCount": "{count} active",
|
|
546
571
|
"noTasksYet": "No tasks yet"
|
|
572
|
+
},
|
|
573
|
+
"lanes": {
|
|
574
|
+
"viewTitle": "Arrange",
|
|
575
|
+
"resetView": "Reset to defaults",
|
|
576
|
+
"notStarted": {
|
|
577
|
+
"label": "Not started",
|
|
578
|
+
"empty": "Nothing waiting to be picked up."
|
|
579
|
+
},
|
|
580
|
+
"inProgress": {
|
|
581
|
+
"label": "In progress",
|
|
582
|
+
"empty": "No runs in flight."
|
|
583
|
+
},
|
|
584
|
+
"needsYou": {
|
|
585
|
+
"label": "Needs you",
|
|
586
|
+
"empty": "Nothing is waiting on you."
|
|
587
|
+
},
|
|
588
|
+
"done": {
|
|
589
|
+
"label": "Done",
|
|
590
|
+
"empty": "Nothing finished yet.",
|
|
591
|
+
"hiddenByCap": "+{count} not shown",
|
|
592
|
+
"hiddenByAge": "+{count} beyond the retention window",
|
|
593
|
+
"undated": "{count} with no recorded date",
|
|
594
|
+
"allWithheld": "Finished tasks are counted here but not listed, per this board settings."
|
|
595
|
+
},
|
|
596
|
+
"reason": {
|
|
597
|
+
"unstarted": "Ready to start",
|
|
598
|
+
"dependencies": "Waiting on a dependency",
|
|
599
|
+
"running": "Running",
|
|
600
|
+
"backgroundReview": "Reviewing in the background",
|
|
601
|
+
"decision": "Decision needed",
|
|
602
|
+
"approval": "Approval needed",
|
|
603
|
+
"failed": "Run failed",
|
|
604
|
+
"budgetPaused": "Paused by the spend budget",
|
|
605
|
+
"prAwaitingMerge": "Pull request awaiting merge",
|
|
606
|
+
"parked": "Waiting on a human",
|
|
607
|
+
"unclassified": "Unrecognised status",
|
|
608
|
+
"merged": "Merged"
|
|
609
|
+
},
|
|
610
|
+
"sort": {
|
|
611
|
+
"heading": "Sort by",
|
|
612
|
+
"smart": "Recommended per lane",
|
|
613
|
+
"title": "Title (A–Z)",
|
|
614
|
+
"oldest_activity": "Quietest first",
|
|
615
|
+
"newest_activity": "Most recently active",
|
|
616
|
+
"longest_wait": "Longest waiting",
|
|
617
|
+
"severity_desc": "Severity (highest first)",
|
|
618
|
+
"impact_desc": "Estimated impact (highest first)",
|
|
619
|
+
"task_type": "Task type"
|
|
620
|
+
},
|
|
621
|
+
"group": {
|
|
622
|
+
"heading": "Group by",
|
|
623
|
+
"none": "No grouping",
|
|
624
|
+
"module": "Module",
|
|
625
|
+
"task_type": "Task type",
|
|
626
|
+
"initiative": "Initiative",
|
|
627
|
+
"epic": "Epic",
|
|
628
|
+
"blocking_reason": "What it needs",
|
|
629
|
+
"catchAll": {
|
|
630
|
+
"module": "No module",
|
|
631
|
+
"task_type": "No type",
|
|
632
|
+
"initiative": "Not in an initiative",
|
|
633
|
+
"epic": "Not in an epic",
|
|
634
|
+
"blocking_reason": "Unclassified"
|
|
635
|
+
}
|
|
636
|
+
}
|
|
547
637
|
}
|
|
548
638
|
},
|
|
549
639
|
"contextAttachments": {
|
|
@@ -1211,11 +1301,12 @@
|
|
|
1211
1301
|
"title": "Structure",
|
|
1212
1302
|
"hint": "Where this task lives in its service and which coding standards its agents follow.",
|
|
1213
1303
|
"module": "Module",
|
|
1214
|
-
"modulePlaceholder": "
|
|
1215
|
-
"moduleHint": "The service module this task belongs to
|
|
1304
|
+
"modulePlaceholder": "Pick or type a module",
|
|
1305
|
+
"moduleHint": "The service module this task belongs to; the board groups lanes by it. A module that doesn't exist yet is created when the task is implemented.",
|
|
1216
1306
|
"bestPractices": "Best practices",
|
|
1217
1307
|
"bestPracticesEmpty": "None. Agents follow their default guidance.",
|
|
1218
|
-
"bestPracticesHint": "Best-practice fragments folded into the prompts of this task's agents, on top of the service-level standards."
|
|
1308
|
+
"bestPracticesHint": "Best-practice fragments folded into the prompts of this task's agents, on top of the service-level standards.",
|
|
1309
|
+
"moduleNone": "No module"
|
|
1219
1310
|
},
|
|
1220
1311
|
"runSettings": {
|
|
1221
1312
|
"title": "Run settings",
|
|
@@ -2512,6 +2603,7 @@
|
|
|
2512
2603
|
"shortcuts": "Keyboard shortcuts",
|
|
2513
2604
|
"bugHunt": "Bug hunt",
|
|
2514
2605
|
"toggleUiMode": "Switch interface mode",
|
|
2606
|
+
"chooseRole": "Change your role",
|
|
2515
2607
|
"foundationalServices": "Foundational services",
|
|
2516
2608
|
"notificationSettings": "Manage notification routing"
|
|
2517
2609
|
},
|
|
@@ -2536,6 +2628,7 @@
|
|
|
2536
2628
|
"shortcuts": "keyboard shortcuts keys hotkeys cheatsheet help",
|
|
2537
2629
|
"bugHunt": "bug hunt triage backlog issue tracker unassigned",
|
|
2538
2630
|
"toggleUiMode": "interface mode basic advanced simple expert show hide",
|
|
2631
|
+
"chooseRole": "role engineer product manager designer persona simpler view",
|
|
2539
2632
|
"tutorial": "tutorial onboarding tour guide help learn basics",
|
|
2540
2633
|
"foundationalServices": "shared capability platform service api contract openapi catalog",
|
|
2541
2634
|
"notificationSettings": "notifications email routing channels inbox"
|
|
@@ -3925,6 +4018,15 @@
|
|
|
3925
4018
|
"advisory": "Advisory (record, never park)",
|
|
3926
4019
|
"off": "Off (skip the check)"
|
|
3927
4020
|
}
|
|
4021
|
+
},
|
|
4022
|
+
"doneLane": {
|
|
4023
|
+
"heading": "Done lane",
|
|
4024
|
+
"body": "How much finished work each service frame's Done lane keeps in view. Both caps hide cards only: an aged-out task stays on the board, stays searchable, and stays in the lane's total.",
|
|
4025
|
+
"maxItems": "Cards shown",
|
|
4026
|
+
"zeroHint": "Finished tasks will be counted but never listed.",
|
|
4027
|
+
"ageToggle": "Also hide tasks completed long ago",
|
|
4028
|
+
"days": "Keep for (days)",
|
|
4029
|
+
"hidesOnlyHint": "Nothing is deleted. Tasks with no recorded completion date are never hidden by age."
|
|
3928
4030
|
}
|
|
3929
4031
|
},
|
|
3930
4032
|
"localModelEndpoints": {
|
|
@@ -7727,6 +7829,7 @@
|
|
|
7727
7829
|
"failedRun": "A run that failed",
|
|
7728
7830
|
"infrastructure": "An execution backend connected to this workspace",
|
|
7729
7831
|
"advancedTier": "The advanced interface mode",
|
|
7832
|
+
"fullSurface": "The Engineer or Product manager role",
|
|
7730
7833
|
"designSource": "A connected design source"
|
|
7731
7834
|
},
|
|
7732
7835
|
"overlay": {
|
|
@@ -7774,6 +7877,10 @@
|
|
|
7774
7877
|
"title": "Board controls",
|
|
7775
7878
|
"body": "Zoom in and out or fit the whole board into view with these controls."
|
|
7776
7879
|
},
|
|
7880
|
+
"role": {
|
|
7881
|
+
"title": "Your role",
|
|
7882
|
+
"body": "The board is tuned to the job you do. Engineers and product managers get every surface; designers get a simpler one that brings work in and follows it. Change it here whenever you like."
|
|
7883
|
+
},
|
|
7777
7884
|
"interfaceTier": {
|
|
7778
7885
|
"title": "Basic and advanced",
|
|
7779
7886
|
"body": "The interface starts in basic mode, which shows the everyday delivery surfaces. Switch to advanced here when you also want the experimentation, bootstrap and operator surfaces."
|
package/i18n/locales/es.json
CHANGED
|
@@ -32,6 +32,25 @@
|
|
|
32
32
|
"switchTo": "Cambiar a {mode}",
|
|
33
33
|
"pinned": "Definido por este despliegue"
|
|
34
34
|
},
|
|
35
|
+
"uiRole": {
|
|
36
|
+
"switcher": "Tu rol",
|
|
37
|
+
"roles": {
|
|
38
|
+
"engineer": "Ingeniero",
|
|
39
|
+
"productManager": "Gestor de producto",
|
|
40
|
+
"designer": "Diseñador"
|
|
41
|
+
},
|
|
42
|
+
"hints": {
|
|
43
|
+
"engineer": "Todo: planificar el trabajo, ejecutarlo, revisarlo y fusionarlo, y configurar la plataforma que lo ejecuta.",
|
|
44
|
+
"productManager": "Las mismas superficies que un ingeniero: planificar el trabajo, ejecutarlo y seguirlo hasta la fusión.",
|
|
45
|
+
"designer": "Un tablero más sencillo: los servicios que ya están en él, el trabajo en curso y tareas nuevas desde un diseño o una incidencia."
|
|
46
|
+
},
|
|
47
|
+
"prompt": {
|
|
48
|
+
"title": "¿En qué trabajas?",
|
|
49
|
+
"intro": "Elige la opción más parecida y la app se abrirá en las superficies que necesita ese trabajo. Esto cambia lo que VES, nunca lo que puedes hacer.",
|
|
50
|
+
"change": "Puedes cambiarlo cuando quieras desde la parte superior de la barra lateral.",
|
|
51
|
+
"later": "Ahora no"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
35
54
|
"common": {
|
|
36
55
|
"loading": "Cargando…",
|
|
37
56
|
"save": "Guardar",
|
|
@@ -490,6 +509,71 @@
|
|
|
490
509
|
"label": "Épica",
|
|
491
510
|
"activeCount": "{count} activas",
|
|
492
511
|
"noTasksYet": "Aún no hay tareas"
|
|
512
|
+
},
|
|
513
|
+
"lanes": {
|
|
514
|
+
"viewTitle": "Organizar",
|
|
515
|
+
"resetView": "Restablecer los valores predeterminados",
|
|
516
|
+
"notStarted": {
|
|
517
|
+
"label": "Sin empezar",
|
|
518
|
+
"empty": "Nada esperando a que se tome."
|
|
519
|
+
},
|
|
520
|
+
"inProgress": {
|
|
521
|
+
"label": "En curso",
|
|
522
|
+
"empty": "No hay ejecuciones en marcha."
|
|
523
|
+
},
|
|
524
|
+
"needsYou": {
|
|
525
|
+
"label": "Te necesita",
|
|
526
|
+
"empty": "Nada espera por ti."
|
|
527
|
+
},
|
|
528
|
+
"done": {
|
|
529
|
+
"label": "Terminado",
|
|
530
|
+
"empty": "Aún no hay nada terminado.",
|
|
531
|
+
"hiddenByCap": "+{count} sin mostrar",
|
|
532
|
+
"hiddenByAge": "+{count} fuera del periodo de conservación",
|
|
533
|
+
"undated": "{count} sin fecha registrada",
|
|
534
|
+
"allWithheld": "Las tareas terminadas se cuentan aquí, pero no se listan, según los ajustes de este tablero."
|
|
535
|
+
},
|
|
536
|
+
"reason": {
|
|
537
|
+
"unstarted": "Lista para empezar",
|
|
538
|
+
"dependencies": "Esperando una dependencia",
|
|
539
|
+
"running": "En ejecución",
|
|
540
|
+
"backgroundReview": "Revisando en segundo plano",
|
|
541
|
+
"decision": "Se necesita una decisión",
|
|
542
|
+
"approval": "Se necesita aprobación",
|
|
543
|
+
"failed": "La ejecución falló",
|
|
544
|
+
"budgetPaused": "Pausada por el presupuesto de gasto",
|
|
545
|
+
"prAwaitingMerge": "Pull request pendiente de fusión",
|
|
546
|
+
"parked": "Esperando a una persona",
|
|
547
|
+
"unclassified": "Estado no reconocido",
|
|
548
|
+
"merged": "Fusionada"
|
|
549
|
+
},
|
|
550
|
+
"sort": {
|
|
551
|
+
"heading": "Ordenar por",
|
|
552
|
+
"smart": "Recomendado por columna",
|
|
553
|
+
"title": "Título (A–Z)",
|
|
554
|
+
"oldest_activity": "Las más silenciosas primero",
|
|
555
|
+
"newest_activity": "Actividad más reciente",
|
|
556
|
+
"longest_wait": "Las que esperan más tiempo",
|
|
557
|
+
"severity_desc": "Gravedad (mayor primero)",
|
|
558
|
+
"impact_desc": "Impacto estimado (mayor primero)",
|
|
559
|
+
"task_type": "Tipo de tarea"
|
|
560
|
+
},
|
|
561
|
+
"group": {
|
|
562
|
+
"heading": "Agrupar por",
|
|
563
|
+
"none": "Sin agrupar",
|
|
564
|
+
"module": "Módulo",
|
|
565
|
+
"task_type": "Tipo de tarea",
|
|
566
|
+
"initiative": "Iniciativa",
|
|
567
|
+
"epic": "Épica",
|
|
568
|
+
"blocking_reason": "Qué necesita",
|
|
569
|
+
"catchAll": {
|
|
570
|
+
"module": "Sin módulo",
|
|
571
|
+
"task_type": "Sin tipo",
|
|
572
|
+
"initiative": "Fuera de una iniciativa",
|
|
573
|
+
"epic": "Fuera de una épica",
|
|
574
|
+
"blocking_reason": "Sin clasificar"
|
|
575
|
+
}
|
|
576
|
+
}
|
|
493
577
|
}
|
|
494
578
|
},
|
|
495
579
|
"contextAttachments": {
|
|
@@ -1124,11 +1208,12 @@
|
|
|
1124
1208
|
"title": "Estructura",
|
|
1125
1209
|
"hint": "Dónde vive esta tarea dentro de su servicio y qué estándares de código siguen sus agentes.",
|
|
1126
1210
|
"module": "Módulo",
|
|
1127
|
-
"modulePlaceholder": "
|
|
1128
|
-
"moduleHint": "El módulo del servicio al que pertenece esta tarea
|
|
1211
|
+
"modulePlaceholder": "Elige o escribe un módulo",
|
|
1212
|
+
"moduleHint": "El módulo del servicio al que pertenece esta tarea; el tablero agrupa las columnas por él. Un módulo que aún no existe se crea cuando se implementa la tarea.",
|
|
1129
1213
|
"bestPractices": "Buenas prácticas",
|
|
1130
1214
|
"bestPracticesEmpty": "Ninguna. Los agentes siguen su guía predeterminada.",
|
|
1131
|
-
"bestPracticesHint": "Fragmentos de buenas prácticas incorporados a los prompts de los agentes de esta tarea, además de los estándares a nivel de servicio."
|
|
1215
|
+
"bestPracticesHint": "Fragmentos de buenas prácticas incorporados a los prompts de los agentes de esta tarea, además de los estándares a nivel de servicio.",
|
|
1216
|
+
"moduleNone": "Sin módulo"
|
|
1132
1217
|
},
|
|
1133
1218
|
"runSettings": {
|
|
1134
1219
|
"title": "Ajustes de ejecución",
|
|
@@ -2387,6 +2472,7 @@
|
|
|
2387
2472
|
"shortcuts": "Atajos de teclado",
|
|
2388
2473
|
"bugHunt": "Caza de errores",
|
|
2389
2474
|
"toggleUiMode": "Cambiar el modo de interfaz",
|
|
2475
|
+
"chooseRole": "Cambiar tu rol",
|
|
2390
2476
|
"foundationalServices": "Servicios fundamentales",
|
|
2391
2477
|
"notificationSettings": "Gestionar el enrutamiento de notificaciones"
|
|
2392
2478
|
},
|
|
@@ -2411,6 +2497,7 @@
|
|
|
2411
2497
|
"shortcuts": "atajos teclado teclas ayuda",
|
|
2412
2498
|
"bugHunt": "error bug caza triaje backlog incidencias sin asignar",
|
|
2413
2499
|
"toggleUiMode": "interfaz modo básico avanzado mostrar ocultar",
|
|
2500
|
+
"chooseRole": "rol ingeniero gestor de producto diseñador perfil vista sencilla",
|
|
2414
2501
|
"tutorial": "tutorial recorrido guía ayuda aprender introducción",
|
|
2415
2502
|
"foundationalServices": "capacidad compartida plataforma servicio api contrato openapi catálogo",
|
|
2416
2503
|
"notificationSettings": "notificaciones correo enrutamiento canales bandeja"
|
|
@@ -3643,6 +3730,15 @@
|
|
|
3643
3730
|
"advisory": "Aviso (registrar, nunca detener)",
|
|
3644
3731
|
"off": "Desactivado (omitir la comprobación)"
|
|
3645
3732
|
}
|
|
3733
|
+
},
|
|
3734
|
+
"doneLane": {
|
|
3735
|
+
"heading": "Columna «Terminado»",
|
|
3736
|
+
"body": "Cuánto trabajo terminado mantiene a la vista la columna «Terminado» de cada servicio. Ambos límites solo ocultan tarjetas: una tarea oculta sigue en el tablero, sigue siendo buscable y sigue contando en el total de la columna.",
|
|
3737
|
+
"maxItems": "Tarjetas mostradas",
|
|
3738
|
+
"zeroHint": "Las tareas terminadas se contarán, pero nunca se listarán.",
|
|
3739
|
+
"ageToggle": "Ocultar también las tareas terminadas hace tiempo",
|
|
3740
|
+
"days": "Conservar (días)",
|
|
3741
|
+
"hidesOnlyHint": "No se elimina nada. Las tareas sin fecha de finalización registrada nunca se ocultan por antigüedad."
|
|
3646
3742
|
}
|
|
3647
3743
|
},
|
|
3648
3744
|
"localModelEndpoints": {
|
|
@@ -7453,6 +7549,7 @@
|
|
|
7453
7549
|
"failedRun": "Una ejecución que ha fallado",
|
|
7454
7550
|
"infrastructure": "Un backend de ejecución conectado a este espacio de trabajo",
|
|
7455
7551
|
"advancedTier": "El modo de interfaz avanzado",
|
|
7552
|
+
"fullSurface": "El rol de Ingeniero o Gestor de producto",
|
|
7456
7553
|
"designSource": "Una fuente de diseño conectada"
|
|
7457
7554
|
},
|
|
7458
7555
|
"overlay": {
|
|
@@ -7494,6 +7591,10 @@
|
|
|
7494
7591
|
"title": "Controles del tablero",
|
|
7495
7592
|
"body": "Con estos controles acercas, alejas o ajustas todo el tablero a la vista."
|
|
7496
7593
|
},
|
|
7594
|
+
"role": {
|
|
7595
|
+
"title": "Tu rol",
|
|
7596
|
+
"body": "El tablero se adapta al trabajo que haces: los ingenieros y los gestores de producto ven todas las superficies; los diseñadores, una más sencilla que trae trabajo nuevo y lo sigue. Puedes cambiarlo aquí cuando quieras."
|
|
7597
|
+
},
|
|
7497
7598
|
"interfaceTier": {
|
|
7498
7599
|
"title": "Básico y avanzado",
|
|
7499
7600
|
"body": "La interfaz arranca en modo básico, que muestra las superficies del trabajo diario. Cambia aquí a avanzado cuando también quieras las de experimentación, arranque de repositorios y operación."
|