mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
feat(ui): tighten workboard card operations
(cherry picked from commit 7cbdebc4ed)
# Conflicts:
# ui/src/styles/workboard.css
# ui/src/ui/views/workboard.ts
This commit is contained in:
16
ui/src/i18n/.i18n/ar.meta.json
generated
16
ui/src/i18n/.i18n/ar.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:31.090Z",
|
||||
"generatedAt": "2026-06-01T07:19:23.359Z",
|
||||
"locale": "ar",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/de.meta.json
generated
16
ui/src/i18n/.i18n/de.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:30.623Z",
|
||||
"generatedAt": "2026-06-01T07:19:21.786Z",
|
||||
"locale": "de",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/es.meta.json
generated
16
ui/src/i18n/.i18n/es.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:30.724Z",
|
||||
"generatedAt": "2026-06-01T07:19:22.097Z",
|
||||
"locale": "es",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/fa.meta.json
generated
16
ui/src/i18n/.i18n/fa.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:31.893Z",
|
||||
"generatedAt": "2026-06-01T07:19:26.307Z",
|
||||
"locale": "fa",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/fr.meta.json
generated
16
ui/src/i18n/.i18n/fr.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:31.001Z",
|
||||
"generatedAt": "2026-06-01T07:19:23.053Z",
|
||||
"locale": "fr",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/id.meta.json
generated
16
ui/src/i18n/.i18n/id.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:31.448Z",
|
||||
"generatedAt": "2026-06-01T07:19:24.706Z",
|
||||
"locale": "id",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/it.meta.json
generated
16
ui/src/i18n/.i18n/it.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:31.183Z",
|
||||
"generatedAt": "2026-06-01T07:19:23.725Z",
|
||||
"locale": "it",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/ja-JP.meta.json
generated
16
ui/src/i18n/.i18n/ja-JP.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:30.818Z",
|
||||
"generatedAt": "2026-06-01T07:19:22.425Z",
|
||||
"locale": "ja-JP",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/ko.meta.json
generated
16
ui/src/i18n/.i18n/ko.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:30.911Z",
|
||||
"generatedAt": "2026-06-01T07:19:22.739Z",
|
||||
"locale": "ko",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/nl.meta.json
generated
16
ui/src/i18n/.i18n/nl.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:31.801Z",
|
||||
"generatedAt": "2026-06-01T07:19:25.987Z",
|
||||
"locale": "nl",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/pl.meta.json
generated
16
ui/src/i18n/.i18n/pl.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:31.535Z",
|
||||
"generatedAt": "2026-06-01T07:19:25.027Z",
|
||||
"locale": "pl",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/pt-BR.meta.json
generated
16
ui/src/i18n/.i18n/pt-BR.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:30.531Z",
|
||||
"generatedAt": "2026-06-01T07:19:21.475Z",
|
||||
"locale": "pt-BR",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/th.meta.json
generated
16
ui/src/i18n/.i18n/th.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:31.623Z",
|
||||
"generatedAt": "2026-06-01T07:19:25.336Z",
|
||||
"locale": "th",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/tr.meta.json
generated
16
ui/src/i18n/.i18n/tr.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:31.272Z",
|
||||
"generatedAt": "2026-06-01T07:19:24.054Z",
|
||||
"locale": "tr",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/uk.meta.json
generated
16
ui/src/i18n/.i18n/uk.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:31.362Z",
|
||||
"generatedAt": "2026-06-01T07:19:24.380Z",
|
||||
"locale": "uk",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/vi.meta.json
generated
16
ui/src/i18n/.i18n/vi.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:31.711Z",
|
||||
"generatedAt": "2026-06-01T07:19:25.659Z",
|
||||
"locale": "vi",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/zh-CN.meta.json
generated
16
ui/src/i18n/.i18n/zh-CN.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:30.090Z",
|
||||
"generatedAt": "2026-06-01T07:19:20.827Z",
|
||||
"locale": "zh-CN",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
16
ui/src/i18n/.i18n/zh-TW.meta.json
generated
16
ui/src/i18n/.i18n/zh-TW.meta.json
generated
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"fallbackKeys": [
|
||||
"workboard.dependencies",
|
||||
"workboard.dependenciesBlocked",
|
||||
"workboard.dependenciesBlockedTitle",
|
||||
"workboard.dependenciesReady",
|
||||
"workboard.dependenciesReadyTitle",
|
||||
"workboard.dependencyMissing",
|
||||
"workboard.dependencyStatusMissing",
|
||||
"workboard.detailAddNote",
|
||||
"workboard.detailAutomation",
|
||||
"workboard.detailAutomationBoard",
|
||||
@@ -19,14 +26,15 @@
|
||||
"workboard.detailUpdatedValue",
|
||||
"workboard.detailWorkerLogs",
|
||||
"workboard.detailWorkerProtocol",
|
||||
"workboard.unknownStatus",
|
||||
"workboard.viewDetails"
|
||||
],
|
||||
"generatedAt": "2026-06-01T02:32:30.440Z",
|
||||
"generatedAt": "2026-06-01T07:19:21.160Z",
|
||||
"locale": "zh-TW",
|
||||
"model": "claude-opus-4-8",
|
||||
"provider": "anthropic",
|
||||
"sourceHash": "59589c3b29f7126995ed4763e88b763702a7c20b1791b4e16c62b394bca02d45",
|
||||
"totalKeys": 1304,
|
||||
"translatedKeys": 1284,
|
||||
"sourceHash": "0639815f4b249fd84b5149556602c9e5da1136d73a747f26a1c12981a4319ebb",
|
||||
"totalKeys": 1330,
|
||||
"translatedKeys": 1302,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
27
ui/src/i18n/locales/ar.ts
generated
27
ui/src/i18n/locales/ar.ts
generated
@@ -506,6 +506,8 @@ export const ar: TranslationMap = {
|
||||
newCard: "بطاقة جديدة",
|
||||
newCardHelp: "أضف العمل إلى قائمة الانتظار لجلسة وكيل.",
|
||||
archiveCard: "أرشفة البطاقة",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "حذف البطاقة",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -530,10 +532,35 @@ export const ar: TranslationMap = {
|
||||
openSession: "فتح الجلسة",
|
||||
openLinkedSession: "فتح الجلسة المرتبطة",
|
||||
defaultAgent: "الوكيل الافتراضي",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "تشغيل {engine}",
|
||||
openEngine: "فتح {engine}",
|
||||
runDefaultAgent: "تشغيل الوكيل الافتراضي",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "بدء",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "منبّه الموزّع",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/de.ts
generated
27
ui/src/i18n/locales/de.ts
generated
@@ -511,6 +511,8 @@ export const de: TranslationMap = {
|
||||
newCard: "Neue Karte",
|
||||
newCardHelp: "Arbeit für eine Agentensitzung in die Warteschlange einreihen.",
|
||||
archiveCard: "Karte archivieren",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Karte löschen",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -535,10 +537,35 @@ export const de: TranslationMap = {
|
||||
openSession: "Sitzung öffnen",
|
||||
openLinkedSession: "Verknüpfte Sitzung öffnen",
|
||||
defaultAgent: "Standard-Agent",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "{engine} ausführen",
|
||||
openEngine: "{engine} öffnen",
|
||||
runDefaultAgent: "Standard-Agent ausführen",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Starten",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Dispatcher anstoßen",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
@@ -505,6 +505,8 @@ export const en: TranslationMap = {
|
||||
newCard: "New card",
|
||||
newCardHelp: "Queue work for an agent session.",
|
||||
archiveCard: "Archive card",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Delete card",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -529,10 +531,35 @@ export const en: TranslationMap = {
|
||||
openSession: "Open session",
|
||||
openLinkedSession: "Open linked session",
|
||||
defaultAgent: "Default agent",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "Run {engine}",
|
||||
openEngine: "Open {engine}",
|
||||
runDefaultAgent: "Run default agent",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Start",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Dispatch ready work",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/es.ts
generated
27
ui/src/i18n/locales/es.ts
generated
@@ -508,6 +508,8 @@ export const es: TranslationMap = {
|
||||
newCard: "Nueva tarjeta",
|
||||
newCardHelp: "Pon trabajo en cola para una sesión de agente.",
|
||||
archiveCard: "Archivar tarjeta",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Eliminar tarjeta",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -532,10 +534,35 @@ export const es: TranslationMap = {
|
||||
openSession: "Abrir sesión",
|
||||
openLinkedSession: "Abrir sesión vinculada",
|
||||
defaultAgent: "Agente predeterminado",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "Ejecutar {engine}",
|
||||
openEngine: "Abrir {engine}",
|
||||
runDefaultAgent: "Ejecutar agente predeterminado",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Iniciar",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Avisar al despachador",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/fa.ts
generated
27
ui/src/i18n/locales/fa.ts
generated
@@ -508,6 +508,8 @@ export const fa: TranslationMap = {
|
||||
newCard: "کارت جدید",
|
||||
newCardHelp: "کار را برای یک نشست عامل در صف قرار دهید.",
|
||||
archiveCard: "بایگانی کارت",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "حذف کارت",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -532,10 +534,35 @@ export const fa: TranslationMap = {
|
||||
openSession: "باز کردن نشست",
|
||||
openLinkedSession: "باز کردن نشست پیوندشده",
|
||||
defaultAgent: "عامل پیشفرض",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "اجرای {engine}",
|
||||
openEngine: "باز کردن {engine}",
|
||||
runDefaultAgent: "اجرای عامل پیشفرض",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "شروع",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "تلنگر به توزیعکننده",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/fr.ts
generated
27
ui/src/i18n/locales/fr.ts
generated
@@ -510,6 +510,8 @@ export const fr: TranslationMap = {
|
||||
newCard: "Nouvelle carte",
|
||||
newCardHelp: "Mettez du travail en file d’attente pour une session d’agent.",
|
||||
archiveCard: "Archiver la carte",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Supprimer la carte",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -534,10 +536,35 @@ export const fr: TranslationMap = {
|
||||
openSession: "Ouvrir la session",
|
||||
openLinkedSession: "Ouvrir la session liée",
|
||||
defaultAgent: "Agent par défaut",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "Exécuter {engine}",
|
||||
openEngine: "Ouvrir {engine}",
|
||||
runDefaultAgent: "Exécuter l’agent par défaut",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Démarrer",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Relancer le répartiteur",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/id.ts
generated
27
ui/src/i18n/locales/id.ts
generated
@@ -507,6 +507,8 @@ export const id: TranslationMap = {
|
||||
newCard: "Kartu baru",
|
||||
newCardHelp: "Antrekan pekerjaan untuk sesi agen.",
|
||||
archiveCard: "Arsipkan kartu",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Hapus kartu",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -531,10 +533,35 @@ export const id: TranslationMap = {
|
||||
openSession: "Buka sesi",
|
||||
openLinkedSession: "Buka sesi tertaut",
|
||||
defaultAgent: "Agen default",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "Jalankan {engine}",
|
||||
openEngine: "Buka {engine}",
|
||||
runDefaultAgent: "Jalankan agen default",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Mulai",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Dorong dispatcher",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/it.ts
generated
27
ui/src/i18n/locales/it.ts
generated
@@ -509,6 +509,8 @@ export const it: TranslationMap = {
|
||||
newCard: "Nuova scheda",
|
||||
newCardHelp: "Metti in coda il lavoro per una sessione dell'agente.",
|
||||
archiveCard: "Archivia scheda",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Elimina scheda",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -533,10 +535,35 @@ export const it: TranslationMap = {
|
||||
openSession: "Apri sessione",
|
||||
openLinkedSession: "Apri sessione collegata",
|
||||
defaultAgent: "Agente predefinito",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "Esegui {engine}",
|
||||
openEngine: "Apri {engine}",
|
||||
runDefaultAgent: "Esegui agente predefinito",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Avvia",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Sollecita dispatcher",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/ja-JP.ts
generated
27
ui/src/i18n/locales/ja-JP.ts
generated
@@ -510,6 +510,8 @@ export const ja_JP: TranslationMap = {
|
||||
newCard: "新規カード",
|
||||
newCardHelp: "エージェントセッションの作業をキューに追加します。",
|
||||
archiveCard: "カードをアーカイブ",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "カードを削除",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -534,10 +536,35 @@ export const ja_JP: TranslationMap = {
|
||||
openSession: "セッションを開く",
|
||||
openLinkedSession: "リンクされたセッションを開く",
|
||||
defaultAgent: "デフォルトエージェント",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "{engine} を実行",
|
||||
openEngine: "{engine} を開く",
|
||||
runDefaultAgent: "デフォルトエージェントを実行",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "開始",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "ディスパッチャーを促す",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/ko.ts
generated
27
ui/src/i18n/locales/ko.ts
generated
@@ -506,6 +506,8 @@ export const ko: TranslationMap = {
|
||||
newCard: "새 카드",
|
||||
newCardHelp: "에이전트 세션을 위한 작업을 대기열에 추가합니다.",
|
||||
archiveCard: "카드 보관",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "카드 삭제",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -530,10 +532,35 @@ export const ko: TranslationMap = {
|
||||
openSession: "세션 열기",
|
||||
openLinkedSession: "연결된 세션 열기",
|
||||
defaultAgent: "기본 에이전트",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "{engine} 실행",
|
||||
openEngine: "{engine} 열기",
|
||||
runDefaultAgent: "기본 에이전트 실행",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "시작",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "디스패처 넛지",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/nl.ts
generated
27
ui/src/i18n/locales/nl.ts
generated
@@ -509,6 +509,8 @@ export const nl: TranslationMap = {
|
||||
newCard: "Nieuwe kaart",
|
||||
newCardHelp: "Zet werk in de wachtrij voor een agentsessie.",
|
||||
archiveCard: "Kaart archiveren",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Kaart verwijderen",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -533,10 +535,35 @@ export const nl: TranslationMap = {
|
||||
openSession: "Sessie openen",
|
||||
openLinkedSession: "Gekoppelde sessie openen",
|
||||
defaultAgent: "Standaardagent",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "{engine} uitvoeren",
|
||||
openEngine: "{engine} openen",
|
||||
runDefaultAgent: "Standaardagent uitvoeren",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Starten",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Dispatcher een zetje geven",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/pl.ts
generated
27
ui/src/i18n/locales/pl.ts
generated
@@ -508,6 +508,8 @@ export const pl: TranslationMap = {
|
||||
newCard: "Nowa karta",
|
||||
newCardHelp: "Dodaj zadanie do kolejki dla sesji agenta.",
|
||||
archiveCard: "Archiwizuj kartę",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Usuń kartę",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -532,10 +534,35 @@ export const pl: TranslationMap = {
|
||||
openSession: "Otwórz sesję",
|
||||
openLinkedSession: "Otwórz powiązaną sesję",
|
||||
defaultAgent: "Domyślny agent",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "Uruchom {engine}",
|
||||
openEngine: "Otwórz {engine}",
|
||||
runDefaultAgent: "Uruchom domyślnego agenta",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Rozpocznij",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Daj znać dyspozytorowi",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/pt-BR.ts
generated
27
ui/src/i18n/locales/pt-BR.ts
generated
@@ -507,6 +507,8 @@ export const pt_BR: TranslationMap = {
|
||||
newCard: "Novo cartão",
|
||||
newCardHelp: "Enfileire trabalho para uma sessão de agente.",
|
||||
archiveCard: "Arquivar cartão",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Excluir cartão",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -531,10 +533,35 @@ export const pt_BR: TranslationMap = {
|
||||
openSession: "Abrir sessão",
|
||||
openLinkedSession: "Abrir sessão vinculada",
|
||||
defaultAgent: "Agente padrão",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "Executar {engine}",
|
||||
openEngine: "Abrir {engine}",
|
||||
runDefaultAgent: "Executar agente padrão",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Iniciar",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Acionar despachante",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/th.ts
generated
27
ui/src/i18n/locales/th.ts
generated
@@ -505,6 +505,8 @@ export const th: TranslationMap = {
|
||||
newCard: "การ์ดใหม่",
|
||||
newCardHelp: "จัดคิวงานสำหรับเซสชันของเอเจนต์",
|
||||
archiveCard: "เก็บถาวรการ์ด",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "ลบการ์ด",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -529,10 +531,35 @@ export const th: TranslationMap = {
|
||||
openSession: "เปิดเซสชัน",
|
||||
openLinkedSession: "เปิดเซสชันที่ลิงก์ไว้",
|
||||
defaultAgent: "เอเจนต์เริ่มต้น",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "เรียกใช้ {engine}",
|
||||
openEngine: "เปิด {engine}",
|
||||
runDefaultAgent: "เรียกใช้เอเจนต์เริ่มต้น",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "เริ่ม",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "กระตุ้น dispatcher",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/tr.ts
generated
27
ui/src/i18n/locales/tr.ts
generated
@@ -510,6 +510,8 @@ export const tr: TranslationMap = {
|
||||
newCard: "Yeni kart",
|
||||
newCardHelp: "Bir ajan oturumu için işi kuyruğa alın.",
|
||||
archiveCard: "Kartı arşivle",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Kartı sil",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -534,10 +536,35 @@ export const tr: TranslationMap = {
|
||||
openSession: "Oturumu aç",
|
||||
openLinkedSession: "Bağlantılı oturumu aç",
|
||||
defaultAgent: "Varsayılan ajan",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "{engine} çalıştır",
|
||||
openEngine: "{engine} aç",
|
||||
runDefaultAgent: "Varsayılan ajanı çalıştır",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Başlat",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Dağıtıcıyı dürt",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/uk.ts
generated
27
ui/src/i18n/locales/uk.ts
generated
@@ -509,6 +509,8 @@ export const uk: TranslationMap = {
|
||||
newCard: "Нова картка",
|
||||
newCardHelp: "Поставте роботу в чергу для сесії агента.",
|
||||
archiveCard: "Архівувати картку",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Видалити картку",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -533,10 +535,35 @@ export const uk: TranslationMap = {
|
||||
openSession: "Відкрити сесію",
|
||||
openLinkedSession: "Відкрити пов’язану сесію",
|
||||
defaultAgent: "Агент за замовчуванням",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "Запустити {engine}",
|
||||
openEngine: "Відкрити {engine}",
|
||||
runDefaultAgent: "Запустити агента за замовчуванням",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Почати",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Підштовхнути диспетчер",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/vi.ts
generated
27
ui/src/i18n/locales/vi.ts
generated
@@ -508,6 +508,8 @@ export const vi: TranslationMap = {
|
||||
newCard: "Thẻ mới",
|
||||
newCardHelp: "Đưa công việc vào hàng đợi cho một phiên agent.",
|
||||
archiveCard: "Lưu trữ thẻ",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "Xóa thẻ",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -532,10 +534,35 @@ export const vi: TranslationMap = {
|
||||
openSession: "Mở phiên",
|
||||
openLinkedSession: "Mở phiên được liên kết",
|
||||
defaultAgent: "Agent mặc định",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "Chạy {engine}",
|
||||
openEngine: "Mở {engine}",
|
||||
runDefaultAgent: "Chạy agent mặc định",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "Bắt đầu",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "Nhắc dispatcher",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/zh-CN.ts
generated
27
ui/src/i18n/locales/zh-CN.ts
generated
@@ -504,6 +504,8 @@ export const zh_CN: TranslationMap = {
|
||||
newCard: "新建卡片",
|
||||
newCardHelp: "为代理会话排队工作。",
|
||||
archiveCard: "归档卡片",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "删除卡片",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -528,10 +530,35 @@ export const zh_CN: TranslationMap = {
|
||||
openSession: "打开会话",
|
||||
openLinkedSession: "打开关联会话",
|
||||
defaultAgent: "默认代理",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "运行 {engine}",
|
||||
openEngine: "打开 {engine}",
|
||||
runDefaultAgent: "运行默认代理",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "开始",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "提醒调度器",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
27
ui/src/i18n/locales/zh-TW.ts
generated
27
ui/src/i18n/locales/zh-TW.ts
generated
@@ -504,6 +504,8 @@ export const zh_TW: TranslationMap = {
|
||||
newCard: "新增卡片",
|
||||
newCardHelp: "為代理程式工作階段排入工作。",
|
||||
archiveCard: "封存卡片",
|
||||
unarchiveCard: "Restore from archive",
|
||||
archived: "Archived",
|
||||
deleteCard: "刪除卡片",
|
||||
viewDetails: "View details",
|
||||
detailTitle: "Card details",
|
||||
@@ -528,10 +530,35 @@ export const zh_TW: TranslationMap = {
|
||||
openSession: "開啟工作階段",
|
||||
openLinkedSession: "開啟連結的工作階段",
|
||||
defaultAgent: "預設代理程式",
|
||||
allAgents: "All agents",
|
||||
agentFilter: "Filter by agent",
|
||||
agentLinked: "Linked to {agent}",
|
||||
agentDefaultLinked: "Using default agent {agent}",
|
||||
engineOpenAI: "OpenAI",
|
||||
engineClaude: "Claude",
|
||||
engineDisabledRuntime:
|
||||
"{agent} uses the {runtime} ACP runtime. Use default start for that session.",
|
||||
runEngine: "執行 {engine}",
|
||||
openEngine: "開啟 {engine}",
|
||||
runDefaultAgent: "執行預設代理程式",
|
||||
run: "Run",
|
||||
open: "Open",
|
||||
start: "開始",
|
||||
dependencies: "Dependencies",
|
||||
dependenciesReady: "{count} ready",
|
||||
dependenciesReadyTitle: "{count} dependencies are done.",
|
||||
dependenciesBlocked: "{count} blocked",
|
||||
dependenciesBlockedTitle: "Waiting on dependencies: {parents}.",
|
||||
dependencyMissing: "{parent} (missing)",
|
||||
dependencyStatusMissing: "Missing",
|
||||
unknownStatus: "Unknown",
|
||||
showArchived: "Show archived cards",
|
||||
hideArchived: "Hide archived cards",
|
||||
showArchivedShort: "Archived",
|
||||
hideArchivedShort: "Hide archived",
|
||||
layout: "Card layout",
|
||||
layoutCompact: "Compact cards",
|
||||
layoutComfortable: "Comfortable cards",
|
||||
dispatch: "提醒分派器",
|
||||
dispatchSummary:
|
||||
"Dispatch complete: started {started}, promoted {promoted}, blocked {blocked}, reclaimed {reclaimed}, orchestrated {orchestrated}, failures {failures}.",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.workboard {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
gap: 12px;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
--workboard-control-height: 34px;
|
||||
@@ -14,15 +14,15 @@
|
||||
.workboard-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.workboard-toolbar {
|
||||
padding: 8px;
|
||||
border: 1px solid color-mix(in srgb, var(--border) 86%, transparent);
|
||||
padding: 9px;
|
||||
border: 1px solid color-mix(in srgb, var(--border-strong) 56%, transparent);
|
||||
border-radius: 8px;
|
||||
background: color-mix(in srgb, var(--panel) 84%, transparent);
|
||||
background: color-mix(in srgb, var(--panel-strong) 64%, var(--panel) 36%);
|
||||
}
|
||||
|
||||
.workboard-toolbar__filters,
|
||||
@@ -31,8 +31,11 @@
|
||||
.workboard-template-strip,
|
||||
.workboard-card__actions,
|
||||
.workboard-card__badges,
|
||||
.workboard-card__chips,
|
||||
.workboard-card__meta,
|
||||
.workboard-card__quick-actions,
|
||||
.workboard-card__top,
|
||||
.workboard-layout-toggle,
|
||||
.workboard-labels {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -45,6 +48,14 @@
|
||||
min-width: 260px;
|
||||
}
|
||||
|
||||
.workboard-layout-toggle {
|
||||
gap: 4px;
|
||||
padding: 2px;
|
||||
border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
|
||||
border-radius: var(--workboard-control-radius);
|
||||
background: color-mix(in srgb, var(--bg-elevated) 42%, transparent);
|
||||
}
|
||||
|
||||
.workboard .input {
|
||||
min-height: var(--workboard-control-height);
|
||||
border: 1px solid var(--workboard-control-border);
|
||||
@@ -101,8 +112,8 @@
|
||||
}
|
||||
|
||||
.workboard-toolbar__filters .input[type="search"] {
|
||||
width: min(360px, 100%);
|
||||
min-width: min(260px, 100%);
|
||||
width: min(420px, 100%);
|
||||
min-width: min(280px, 100%);
|
||||
}
|
||||
|
||||
.workboard-modal {
|
||||
@@ -224,28 +235,52 @@
|
||||
border-radius: var(--workboard-control-radius);
|
||||
}
|
||||
|
||||
.workboard .btn.active {
|
||||
border-color: color-mix(in srgb, var(--accent) 44%, var(--border-strong));
|
||||
background: color-mix(in srgb, var(--accent) 14%, var(--bg-elevated));
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.workboard-board {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: minmax(220px, 1fr);
|
||||
grid-auto-columns: minmax(292px, 1fr);
|
||||
grid-template-columns: none;
|
||||
gap: 12px;
|
||||
gap: 10px;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
padding-bottom: 8px;
|
||||
scroll-snap-type: x proximity;
|
||||
}
|
||||
|
||||
.workboard-board--compact {
|
||||
grid-auto-columns: minmax(262px, 1fr);
|
||||
}
|
||||
|
||||
.workboard-board--compact .workboard-column {
|
||||
min-width: 262px;
|
||||
}
|
||||
|
||||
.workboard-board--comfortable {
|
||||
grid-auto-columns: minmax(312px, 1fr);
|
||||
}
|
||||
|
||||
.workboard-board--comfortable .workboard-column {
|
||||
min-width: 312px;
|
||||
}
|
||||
|
||||
.workboard-column {
|
||||
min-height: 0;
|
||||
background: color-mix(in srgb, var(--panel) 78%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
|
||||
background: color-mix(in srgb, var(--panel-strong) 34%, var(--panel) 66%);
|
||||
border: 1px solid color-mix(in srgb, var(--border-strong) 52%, transparent);
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 220px;
|
||||
min-width: 292px;
|
||||
overflow: hidden;
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
.workboard-column--drop {
|
||||
@@ -257,20 +292,44 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 12px;
|
||||
padding: 10px 11px 9px;
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
|
||||
box-shadow: inset 0 2px 0 color-mix(in srgb, var(--accent) 30%, transparent);
|
||||
}
|
||||
|
||||
.workboard-column--ready .workboard-column__header,
|
||||
.workboard-column--scheduled .workboard-column__header {
|
||||
box-shadow: inset 0 2px 0 color-mix(in srgb, var(--warn) 38%, transparent);
|
||||
}
|
||||
|
||||
.workboard-column--running .workboard-column__header,
|
||||
.workboard-column--review .workboard-column__header {
|
||||
box-shadow: inset 0 2px 0 color-mix(in srgb, var(--accent-2) 38%, transparent);
|
||||
}
|
||||
|
||||
.workboard-column--blocked .workboard-column__header {
|
||||
box-shadow: inset 0 2px 0 color-mix(in srgb, var(--danger) 40%, transparent);
|
||||
}
|
||||
|
||||
.workboard-column--done .workboard-column__header {
|
||||
box-shadow: inset 0 2px 0 color-mix(in srgb, var(--ok) 40%, transparent);
|
||||
}
|
||||
|
||||
.workboard-column__header h2 {
|
||||
margin: 0;
|
||||
font-size: 0.82rem;
|
||||
color: color-mix(in srgb, var(--text) 72%, var(--muted));
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.workboard-column__header span {
|
||||
color: var(--muted);
|
||||
font-size: 0.82rem;
|
||||
min-width: 24px;
|
||||
border-radius: 999px;
|
||||
padding: 2px 7px;
|
||||
background: color-mix(in srgb, var(--bg-elevated) 72%, transparent);
|
||||
color: var(--text);
|
||||
font-size: 0.76rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.workboard-column__cards {
|
||||
@@ -284,17 +343,30 @@
|
||||
}
|
||||
|
||||
.workboard-card {
|
||||
border: 1px solid var(--border);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1px solid color-mix(in srgb, var(--border-strong) 58%, transparent);
|
||||
border-radius: 8px;
|
||||
background: var(--bg);
|
||||
padding: 11px;
|
||||
background: color-mix(in srgb, var(--bg-elevated) 72%, var(--bg) 28%);
|
||||
padding: 12px;
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
box-shadow: 0 1px 0 color-mix(in srgb, var(--border) 60%, transparent);
|
||||
gap: 9px;
|
||||
box-shadow:
|
||||
0 1px 0 color-mix(in srgb, white 3%, transparent) inset,
|
||||
0 8px 22px color-mix(in srgb, #000 18%, transparent);
|
||||
transition:
|
||||
border-color var(--duration-fast) var(--ease-out),
|
||||
background var(--duration-fast) var(--ease-out),
|
||||
box-shadow var(--duration-fast) var(--ease-out);
|
||||
box-shadow var(--duration-fast) var(--ease-out),
|
||||
transform var(--duration-fast) var(--ease-out);
|
||||
}
|
||||
|
||||
.workboard-card::before {
|
||||
position: absolute;
|
||||
inset: 0 auto 0 0;
|
||||
width: 3px;
|
||||
background: color-mix(in srgb, var(--muted) 44%, transparent);
|
||||
content: "";
|
||||
}
|
||||
|
||||
.workboard-card--openable {
|
||||
@@ -302,8 +374,12 @@
|
||||
}
|
||||
|
||||
.workboard-card--openable:hover {
|
||||
border-color: color-mix(in srgb, var(--accent) 34%, var(--border-strong));
|
||||
background: color-mix(in srgb, var(--bg-elevated) 54%, var(--bg) 46%);
|
||||
border-color: color-mix(in srgb, var(--accent) 36%, var(--border-strong));
|
||||
background: color-mix(in srgb, var(--bg-elevated) 84%, var(--bg) 16%);
|
||||
box-shadow:
|
||||
0 1px 0 color-mix(in srgb, white 4%, transparent) inset,
|
||||
0 12px 28px color-mix(in srgb, #000 24%, transparent);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.workboard-card--openable:focus-visible {
|
||||
@@ -316,19 +392,28 @@
|
||||
opacity: 0.62;
|
||||
}
|
||||
|
||||
.workboard-card--archived {
|
||||
opacity: 0.72;
|
||||
}
|
||||
|
||||
.workboard-card h3 {
|
||||
margin: 0;
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.3;
|
||||
color: var(--text-strong);
|
||||
font-size: 0.96rem;
|
||||
line-height: 1.25;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.workboard-card p {
|
||||
margin: 0;
|
||||
color: var(--muted);
|
||||
font-size: 0.86rem;
|
||||
line-height: 1.4;
|
||||
color: color-mix(in srgb, var(--muted) 88%, var(--text) 12%);
|
||||
font-size: 0.82rem;
|
||||
line-height: 1.42;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 4;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -340,14 +425,67 @@
|
||||
font-size: 0.76rem;
|
||||
}
|
||||
|
||||
.workboard-card__chips {
|
||||
min-width: 0;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.workboard-card__quick-actions {
|
||||
flex: 0 0 auto;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.workboard-card__actions {
|
||||
justify-content: flex-end;
|
||||
min-height: 28px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.workboard-card__badges {
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.workboard-dependencies {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.workboard-dependency {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
min-width: 0;
|
||||
min-height: 21px;
|
||||
border-radius: 6px;
|
||||
padding: 3px 8px;
|
||||
font-size: 0.74rem;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.workboard-dependency svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
flex: 0 0 auto;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 2.25;
|
||||
}
|
||||
|
||||
.workboard-dependency--blocked {
|
||||
border: 1px solid color-mix(in srgb, var(--warn) 34%, transparent);
|
||||
background: color-mix(in srgb, var(--warn) 10%, var(--bg-hover));
|
||||
color: color-mix(in srgb, var(--warn) 76%, var(--text));
|
||||
}
|
||||
|
||||
.workboard-dependency--ready {
|
||||
border: 1px solid color-mix(in srgb, var(--ok) 24%, transparent);
|
||||
background: color-mix(in srgb, var(--ok) 12%, transparent);
|
||||
color: color-mix(in srgb, var(--ok) 82%, var(--text));
|
||||
}
|
||||
|
||||
.workboard-card__execution-controls {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(72px, 1fr));
|
||||
@@ -369,6 +507,15 @@
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.workboard-card__quick-actions .workboard-card__icon,
|
||||
.workboard-card__quick-actions .workboard-card__start--icon {
|
||||
width: 26px;
|
||||
min-width: 26px;
|
||||
height: 26px;
|
||||
min-height: 26px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.workboard-card__delete:hover {
|
||||
border-color: color-mix(in srgb, var(--danger) 34%, var(--border));
|
||||
background: color-mix(in srgb, var(--danger) 14%, transparent);
|
||||
@@ -377,13 +524,18 @@
|
||||
|
||||
.workboard-card__start {
|
||||
min-height: 28px;
|
||||
padding: 4px 9px;
|
||||
gap: 6px;
|
||||
padding: 4px 8px;
|
||||
border-radius: 6px;
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.workboard-card__start--icon {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.workboard-card__start--manual {
|
||||
color: var(--muted);
|
||||
}
|
||||
@@ -410,6 +562,8 @@
|
||||
|
||||
.workboard-card__priority,
|
||||
.workboard-card__badges span,
|
||||
.workboard-agent-chip,
|
||||
.workboard-card__archived,
|
||||
.workboard-live,
|
||||
.workboard-lifecycle,
|
||||
.workboard-labels span {
|
||||
@@ -418,15 +572,92 @@
|
||||
min-height: 20px;
|
||||
border-radius: 999px;
|
||||
padding: 2px 7px;
|
||||
background: color-mix(in srgb, var(--border) 60%, transparent);
|
||||
color: var(--muted);
|
||||
background: color-mix(in srgb, var(--bg-hover) 72%, transparent);
|
||||
color: color-mix(in srgb, var(--muted) 82%, var(--text) 18%);
|
||||
font-size: 0.72rem;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.workboard-card__badges svg {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
margin-right: 4px;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.workboard-card__badge--warning {
|
||||
background: color-mix(in srgb, var(--warn) 17%, transparent) !important;
|
||||
color: color-mix(in srgb, var(--warn) 86%, var(--text)) !important;
|
||||
}
|
||||
|
||||
.workboard-agent-chip {
|
||||
max-width: 108px;
|
||||
overflow: hidden;
|
||||
background: color-mix(in srgb, var(--accent-2) 12%, var(--bg-hover));
|
||||
color: color-mix(in srgb, var(--accent-2) 62%, var(--text));
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.workboard-card__archived {
|
||||
background: color-mix(in srgb, var(--muted) 14%, transparent);
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.workboard-engine-mark {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 42px;
|
||||
height: 18px;
|
||||
border-radius: 5px;
|
||||
padding: 0 5px;
|
||||
font-size: 0.62rem;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.workboard-engine-mark--codex {
|
||||
background: color-mix(in srgb, var(--ok) 18%, var(--bg-hover));
|
||||
color: color-mix(in srgb, var(--ok) 72%, var(--text));
|
||||
}
|
||||
|
||||
.workboard-engine-mark--claude {
|
||||
background: color-mix(in srgb, var(--warn) 20%, var(--bg-hover));
|
||||
color: color-mix(in srgb, var(--warn) 76%, var(--text));
|
||||
}
|
||||
|
||||
.workboard-board--compact .workboard-column__cards {
|
||||
gap: 8px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.workboard-board--compact .workboard-card {
|
||||
gap: 6px;
|
||||
padding: 9px;
|
||||
}
|
||||
|
||||
.workboard-board--compact .workboard-card h3 {
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.22;
|
||||
}
|
||||
|
||||
.workboard-board--compact .workboard-card p {
|
||||
-webkit-line-clamp: 2;
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.workboard-board--compact .workboard-labels,
|
||||
.workboard-board--compact .workboard-card__badges {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.workboard-events {
|
||||
display: grid;
|
||||
display: none;
|
||||
gap: 4px;
|
||||
margin: 0;
|
||||
padding: 7px 0 0;
|
||||
@@ -468,11 +699,20 @@
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.priority-high::before,
|
||||
.priority-urgent::before {
|
||||
background: color-mix(in srgb, var(--danger) 76%, var(--accent));
|
||||
}
|
||||
|
||||
.priority-low .workboard-card__priority {
|
||||
background: color-mix(in srgb, var(--ok) 16%, transparent);
|
||||
color: var(--ok);
|
||||
}
|
||||
|
||||
.priority-low::before {
|
||||
background: color-mix(in srgb, var(--ok) 70%, transparent);
|
||||
}
|
||||
|
||||
.workboard-live {
|
||||
background: color-mix(in srgb, var(--accent) 18%, transparent);
|
||||
color: var(--accent);
|
||||
@@ -619,6 +859,45 @@
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.workboard-detail__dependencies li {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
.workboard-detail__dependencies li.is-blocked {
|
||||
border: 1px solid color-mix(in srgb, var(--warn) 26%, transparent);
|
||||
background: color-mix(in srgb, var(--warn) 10%, var(--bg) 90%);
|
||||
}
|
||||
|
||||
.workboard-detail__dependencies svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: var(--warn);
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 2;
|
||||
}
|
||||
|
||||
.workboard-detail__dependency-spacer {
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
.workboard-detail__dependencies span {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.workboard-detail__dependencies span:last-child {
|
||||
color: var(--muted);
|
||||
font-size: 0.76rem;
|
||||
}
|
||||
|
||||
.workboard textarea.input.workboard-detail__note {
|
||||
width: 100%;
|
||||
min-height: 84px;
|
||||
@@ -664,7 +943,7 @@
|
||||
}
|
||||
|
||||
.workboard-board {
|
||||
grid-auto-columns: minmax(260px, 82vw);
|
||||
grid-auto-columns: minmax(282px, 84vw);
|
||||
}
|
||||
|
||||
.workboard-detail-drawer {
|
||||
@@ -682,3 +961,26 @@
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.workboard-card__actions {
|
||||
opacity: 0.34;
|
||||
transition: opacity var(--duration-fast) var(--ease-out);
|
||||
}
|
||||
|
||||
.workboard-card:hover .workboard-card__actions,
|
||||
.workboard-card:focus-within .workboard-card__actions {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.workboard-card,
|
||||
.workboard-card__actions {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.workboard-card--openable:hover {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
createWorkboardCard,
|
||||
deleteWorkboardCard,
|
||||
getWorkboardLifecycle,
|
||||
getWorkboardDependencyState,
|
||||
getWorkboardState,
|
||||
loadWorkboard,
|
||||
moveWorkboardCard,
|
||||
@@ -139,6 +140,36 @@ describe("workboard controller", () => {
|
||||
expect(getWorkboardState(host).cards[0]).toMatchObject({ taskId: "task-1" });
|
||||
});
|
||||
|
||||
it("summarizes parent dependency readiness from loaded cards", () => {
|
||||
const parentDone = { ...sampleCard, id: "parent-done", title: "Done parent", status: "done" };
|
||||
const parentTodo = { ...sampleCard, id: "parent-todo", title: "Todo parent", status: "todo" };
|
||||
const child = {
|
||||
...sampleCard,
|
||||
id: "child-1",
|
||||
metadata: {
|
||||
links: [
|
||||
{ id: "link-1", type: "parent", targetCardId: parentDone.id, createdAt: 1 },
|
||||
{ id: "link-2", type: "parent", targetCardId: parentTodo.id, createdAt: 1 },
|
||||
{ id: "link-3", type: "parent", targetCardId: "missing-parent", createdAt: 1 },
|
||||
],
|
||||
},
|
||||
} satisfies WorkboardCard;
|
||||
|
||||
const dependencies = getWorkboardDependencyState(child, [parentDone, parentTodo, child]);
|
||||
|
||||
expect(
|
||||
dependencies.parents.map((parent) => [parent.title, parent.done, parent.missing]),
|
||||
).toEqual([
|
||||
["Done parent", true, false],
|
||||
["Todo parent", false, false],
|
||||
["missing-parent", false, true],
|
||||
]);
|
||||
expect(dependencies.blockedParents.map((parent) => parent.id)).toEqual([
|
||||
parentTodo.id,
|
||||
"missing-parent",
|
||||
]);
|
||||
});
|
||||
|
||||
it("links unassigned default-agent tasks with canonicalized session keys", async () => {
|
||||
const host = {};
|
||||
const linked = {
|
||||
@@ -717,7 +748,7 @@ describe("workboard controller", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("lets the gateway preflight decide starts when local parent state is stale", async () => {
|
||||
it("lets the gateway decide starts when cached parent dependencies are stale", async () => {
|
||||
const host = {};
|
||||
const parent = { ...sampleCard, id: "parent-1", title: "Parent", status: "running" };
|
||||
const child: WorkboardCard = {
|
||||
@@ -728,13 +759,18 @@ describe("workboard controller", () => {
|
||||
links: [{ id: "link-1", type: "parent", targetCardId: parent.id, createdAt: 1 }],
|
||||
},
|
||||
};
|
||||
const running = { ...child, status: "running", sessionKey: "agent:main:dashboard:child" };
|
||||
const running = {
|
||||
...child,
|
||||
status: "running",
|
||||
sessionKey: "subagent:workboard-default-child-1",
|
||||
runId: "run-1",
|
||||
} satisfies WorkboardCard;
|
||||
const client = createClient((method) => {
|
||||
if (method === "workboard.cards.list") {
|
||||
return { cards: [parent, child], statuses: ["todo", "running", "done"] };
|
||||
}
|
||||
if (method === "agent") {
|
||||
return { sessionKey: "agent:main:dashboard:child", runId: "run-child" };
|
||||
return { sessionKey: "subagent:workboard-default-child-1", runId: "run-1" };
|
||||
}
|
||||
if (method === "tasks.list") {
|
||||
return { tasks: [] };
|
||||
@@ -750,12 +786,17 @@ describe("workboard controller", () => {
|
||||
card: child,
|
||||
});
|
||||
|
||||
expect(sessionKey).toBe("agent:main:dashboard:child");
|
||||
expect(sessionKey).toBe("subagent:workboard-default-child-1");
|
||||
expect(client.request).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
"workboard.cards.update",
|
||||
expect.objectContaining({ id: child.id, patch: { status: "running" } }),
|
||||
);
|
||||
expect(client.request).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
"agent",
|
||||
expect.objectContaining({ sessionKey: "subagent:workboard-default-child-1" }),
|
||||
);
|
||||
});
|
||||
|
||||
it("does not create a session when the gateway rejects start preflight", async () => {
|
||||
|
||||
@@ -316,6 +316,19 @@ export type WorkboardTaskSummary = {
|
||||
error?: string;
|
||||
};
|
||||
|
||||
export type WorkboardDependencyParent = {
|
||||
id: string;
|
||||
title: string;
|
||||
status?: WorkboardStatus;
|
||||
done: boolean;
|
||||
missing: boolean;
|
||||
};
|
||||
|
||||
export type WorkboardDependencyState = {
|
||||
parents: WorkboardDependencyParent[];
|
||||
blockedParents: WorkboardDependencyParent[];
|
||||
};
|
||||
|
||||
export type WorkboardDispatchSummary = {
|
||||
started: number;
|
||||
failures: number;
|
||||
@@ -336,6 +349,9 @@ export type WorkboardUiState = {
|
||||
lastDispatchSummary: WorkboardDispatchSummary | null;
|
||||
query: string;
|
||||
priorityFilter: "all" | WorkboardPriority;
|
||||
agentFilter: string;
|
||||
showArchived: boolean;
|
||||
layout: "comfortable" | "compact";
|
||||
draftOpen: boolean;
|
||||
editingCardId: string | null;
|
||||
draftTitle: string;
|
||||
@@ -380,6 +396,9 @@ function createDefaultState(): WorkboardUiState {
|
||||
lastDispatchSummary: null,
|
||||
query: "",
|
||||
priorityFilter: "all",
|
||||
agentFilter: "all",
|
||||
showArchived: false,
|
||||
layout: "compact",
|
||||
draftOpen: false,
|
||||
editingCardId: null,
|
||||
draftTitle: "",
|
||||
@@ -1128,6 +1147,38 @@ function replaceCard(state: WorkboardUiState, card: WorkboardCard) {
|
||||
state.cards = next.toSorted((left, right) => left.position - right.position);
|
||||
}
|
||||
|
||||
function parentDependencyIds(card: WorkboardCard): string[] {
|
||||
const ids: string[] = [];
|
||||
for (const link of card.metadata?.links ?? []) {
|
||||
const id = link.type === "parent" ? link.targetCardId?.trim() : "";
|
||||
if (id && !ids.includes(id)) {
|
||||
ids.push(id);
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
export function getWorkboardDependencyState(
|
||||
card: WorkboardCard,
|
||||
cards: readonly WorkboardCard[],
|
||||
): WorkboardDependencyState {
|
||||
const cardsById = new Map(cards.map((entry) => [entry.id, entry]));
|
||||
const parents = parentDependencyIds(card).map((id) => {
|
||||
const parent = cardsById.get(id);
|
||||
return {
|
||||
id,
|
||||
title: parent?.title ?? id,
|
||||
status: parent?.status,
|
||||
done: parent?.status === "done",
|
||||
missing: !parent,
|
||||
};
|
||||
});
|
||||
return {
|
||||
parents,
|
||||
blockedParents: parents.filter((parent) => !parent.done),
|
||||
};
|
||||
}
|
||||
|
||||
function removeCardAndReferences(cards: readonly WorkboardCard[], cardId: string): WorkboardCard[] {
|
||||
const nextCards: WorkboardCard[] = [];
|
||||
for (const card of cards) {
|
||||
@@ -1775,6 +1826,7 @@ export async function archiveWorkboardCard(params: {
|
||||
host: WorkboardHost;
|
||||
client: GatewayBrowserClient | null;
|
||||
cardId: string;
|
||||
archived?: boolean;
|
||||
requestUpdate?: () => void;
|
||||
}) {
|
||||
const state = getWorkboardState(params.host);
|
||||
@@ -1787,7 +1839,7 @@ export async function archiveWorkboardCard(params: {
|
||||
try {
|
||||
const payload = await params.client.request("workboard.cards.archive", {
|
||||
id: params.cardId,
|
||||
archived: true,
|
||||
archived: params.archived ?? true,
|
||||
});
|
||||
replaceCard(state, normalizeCardPayload(payload));
|
||||
} catch (error) {
|
||||
|
||||
@@ -128,6 +128,43 @@ export const icons = {
|
||||
`,
|
||||
check: html` <svg viewBox="0 0 24 24"><path d="M20 6 9 17l-5-5" /></svg> `,
|
||||
play: html` <svg viewBox="0 0 24 24"><polygon points="6 3 20 12 6 21 6 3" /></svg> `,
|
||||
archive: html`
|
||||
<svg viewBox="0 0 24 24">
|
||||
<rect width="20" height="5" x="2" y="3" rx="1" />
|
||||
<path d="M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8" />
|
||||
<path d="M10 12h4" />
|
||||
</svg>
|
||||
`,
|
||||
archiveRestore: html`
|
||||
<svg viewBox="0 0 24 24">
|
||||
<rect width="20" height="5" x="2" y="3" rx="1" />
|
||||
<path d="M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8" />
|
||||
<path d="m9 15 3-3 3 3" />
|
||||
<path d="M12 12v6" />
|
||||
</svg>
|
||||
`,
|
||||
alertTriangle: html`
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="m21.73 18-8-14a2 2 0 0 0-3.46 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" />
|
||||
<path d="M12 9v4" />
|
||||
<path d="M12 17h.01" />
|
||||
</svg>
|
||||
`,
|
||||
layoutComfortable: html`
|
||||
<svg viewBox="0 0 24 24">
|
||||
<rect width="7" height="7" x="3" y="3" rx="1" />
|
||||
<rect width="7" height="7" x="14" y="3" rx="1" />
|
||||
<rect width="7" height="7" x="3" y="14" rx="1" />
|
||||
<rect width="7" height="7" x="14" y="14" rx="1" />
|
||||
</svg>
|
||||
`,
|
||||
layoutCompact: html`
|
||||
<svg viewBox="0 0 24 24">
|
||||
<rect width="18" height="3" x="3" y="5" rx="1" />
|
||||
<rect width="18" height="3" x="3" y="11" rx="1" />
|
||||
<rect width="18" height="3" x="3" y="17" rx="1" />
|
||||
</svg>
|
||||
`,
|
||||
arrowDown: html`
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M12 5v14" />
|
||||
|
||||
@@ -206,7 +206,7 @@ describe("renderWorkboard", () => {
|
||||
const startButtons = [
|
||||
...container.querySelectorAll<HTMLButtonElement>(".workboard-card__start"),
|
||||
];
|
||||
expect(startButtons.map((button) => button.textContent?.trim())).toEqual(["Start"]);
|
||||
expect(startButtons.map((button) => button.textContent?.trim())).toEqual([""]);
|
||||
expect(startButtons.map((button) => button.title)).toEqual(["Run default agent"]);
|
||||
expect(container.querySelector(".workboard-card")?.getAttribute("role")).toBe("button");
|
||||
|
||||
@@ -229,15 +229,91 @@ describe("renderWorkboard", () => {
|
||||
const detailStartButtons = [
|
||||
...container.querySelectorAll<HTMLButtonElement>(".workboard-detail .workboard-card__start"),
|
||||
];
|
||||
expect(detailStartButtons.map((button) => button.textContent?.trim())).toEqual([
|
||||
expect(detailStartButtons.map((button) => button.textContent?.replace(/\s+/g, ""))).toEqual([
|
||||
"Start",
|
||||
"codex",
|
||||
"claude",
|
||||
"codex",
|
||||
"claude",
|
||||
"OpenAIRun",
|
||||
"ClaudeRun",
|
||||
"OpenAIOpen",
|
||||
"ClaudeOpen",
|
||||
]);
|
||||
});
|
||||
|
||||
it("shows unfinished parent dependencies without blocking stale local starts", () => {
|
||||
const host = {};
|
||||
const state = getWorkboardState(host);
|
||||
state.loaded = true;
|
||||
state.cards = [
|
||||
{
|
||||
id: "parent-1",
|
||||
title: "Finish art pass",
|
||||
status: "todo",
|
||||
priority: "normal",
|
||||
labels: [],
|
||||
position: 1000,
|
||||
createdAt: 1,
|
||||
updatedAt: 1,
|
||||
},
|
||||
{
|
||||
id: "child-1",
|
||||
title: "Ship game shell",
|
||||
status: "todo",
|
||||
priority: "normal",
|
||||
labels: [],
|
||||
position: 2000,
|
||||
createdAt: 1,
|
||||
updatedAt: 1,
|
||||
metadata: {
|
||||
links: [{ id: "link-1", type: "parent", targetCardId: "parent-1", createdAt: 1 }],
|
||||
},
|
||||
},
|
||||
];
|
||||
const container = document.createElement("div");
|
||||
const props = {
|
||||
host,
|
||||
client: null,
|
||||
connected: true,
|
||||
pluginEnabled: true,
|
||||
agentsList: null,
|
||||
sessions: [],
|
||||
onOpenSession: () => undefined,
|
||||
onRequestUpdate: () => undefined,
|
||||
} satisfies WorkboardRenderProps;
|
||||
|
||||
render(renderWorkboard(props), container);
|
||||
|
||||
const childCard = [...container.querySelectorAll<HTMLElement>(".workboard-card")].find((card) =>
|
||||
card.textContent?.includes("Ship game shell"),
|
||||
);
|
||||
const start = childCard?.querySelector<HTMLButtonElement>(".workboard-card__start");
|
||||
expect(childCard?.textContent).toContain("1 blocked");
|
||||
expect(start?.disabled).toBe(false);
|
||||
expect(start?.title).toBe("Run default agent");
|
||||
|
||||
childCard
|
||||
?.querySelector<HTMLButtonElement>('button[title="View details"]')
|
||||
?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
||||
render(renderWorkboard(props), container);
|
||||
|
||||
const detail = container.querySelector(".workboard-detail");
|
||||
expect(detail?.textContent).toContain("Dependencies");
|
||||
expect(detail?.textContent).toContain("Finish art pass");
|
||||
expect(detail?.textContent).toContain("Todo");
|
||||
const detailRunButtons = [
|
||||
...container.querySelectorAll<HTMLButtonElement>(
|
||||
".workboard-detail .workboard-card__start--autonomous",
|
||||
),
|
||||
];
|
||||
const detailOpenButtons = [
|
||||
...container.querySelectorAll<HTMLButtonElement>(
|
||||
".workboard-detail .workboard-card__start--manual",
|
||||
),
|
||||
];
|
||||
expect(detailRunButtons.length).toBeGreaterThan(0);
|
||||
expect(detailRunButtons.every((button) => button.disabled)).toBe(false);
|
||||
expect(detailOpenButtons.length).toBeGreaterThan(0);
|
||||
expect(detailOpenButtons.every((button) => button.disabled)).toBe(false);
|
||||
});
|
||||
|
||||
it("hides autonomous model override actions for non-admin operators", () => {
|
||||
const host = {};
|
||||
const state = getWorkboardState(host);
|
||||
@@ -273,7 +349,7 @@ describe("renderWorkboard", () => {
|
||||
const startButtons = [
|
||||
...container.querySelectorAll<HTMLButtonElement>(".workboard-card__start"),
|
||||
];
|
||||
expect(startButtons.map((button) => button.textContent?.trim())).toEqual(["Start"]);
|
||||
expect(startButtons.map((button) => button.textContent?.trim())).toEqual([""]);
|
||||
expect(startButtons.map((button) => button.title)).toEqual(["Run default agent"]);
|
||||
|
||||
container
|
||||
@@ -295,10 +371,10 @@ describe("renderWorkboard", () => {
|
||||
const detailStartButtons = [
|
||||
...container.querySelectorAll<HTMLButtonElement>(".workboard-detail .workboard-card__start"),
|
||||
];
|
||||
expect(detailStartButtons.map((button) => button.textContent?.trim())).toEqual([
|
||||
expect(detailStartButtons.map((button) => button.textContent?.replace(/\s+/g, ""))).toEqual([
|
||||
"Start",
|
||||
"codex",
|
||||
"claude",
|
||||
"OpenAIOpen",
|
||||
"ClaudeOpen",
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -751,6 +827,26 @@ describe("renderWorkboard", () => {
|
||||
expect(container.textContent).toContain("stale");
|
||||
expect(container.textContent).not.toContain("Archived task");
|
||||
|
||||
container
|
||||
.querySelector<HTMLButtonElement>('button[title="Show archived cards"]')
|
||||
?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
||||
render(
|
||||
renderWorkboard({
|
||||
host,
|
||||
client: null,
|
||||
connected: true,
|
||||
pluginEnabled: true,
|
||||
agentsList: null,
|
||||
sessions: [],
|
||||
onOpenSession: () => undefined,
|
||||
}),
|
||||
container,
|
||||
);
|
||||
expect(container.textContent).toContain("Archived task");
|
||||
expect(
|
||||
container.querySelector<HTMLButtonElement>('button[title="Hide archived cards"]'),
|
||||
).not.toBeNull();
|
||||
|
||||
container
|
||||
.querySelector<HTMLButtonElement>('button[title="View details"]')
|
||||
?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
||||
@@ -787,6 +883,136 @@ describe("renderWorkboard", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("filters cards by linked agent", () => {
|
||||
const host = {};
|
||||
const state = getWorkboardState(host);
|
||||
state.loaded = true;
|
||||
state.cards = [
|
||||
{
|
||||
id: "card-1",
|
||||
title: "Main work",
|
||||
status: "todo",
|
||||
priority: "normal",
|
||||
labels: [],
|
||||
agentId: "main",
|
||||
position: 1000,
|
||||
createdAt: 1,
|
||||
updatedAt: 1,
|
||||
},
|
||||
{
|
||||
id: "card-2",
|
||||
title: "Ops work",
|
||||
status: "todo",
|
||||
priority: "normal",
|
||||
labels: [],
|
||||
agentId: "ops",
|
||||
position: 2000,
|
||||
createdAt: 1,
|
||||
updatedAt: 1,
|
||||
},
|
||||
];
|
||||
const container = document.createElement("div");
|
||||
|
||||
render(
|
||||
renderWorkboard({
|
||||
host,
|
||||
client: null,
|
||||
connected: true,
|
||||
pluginEnabled: true,
|
||||
agentsList: {
|
||||
defaultId: "main",
|
||||
mainKey: "agent:main:main",
|
||||
scope: "test",
|
||||
agents: [
|
||||
{ id: "main", name: "Main" },
|
||||
{ id: "ops", name: "Ops" },
|
||||
],
|
||||
},
|
||||
sessions: [],
|
||||
onOpenSession: () => undefined,
|
||||
}),
|
||||
container,
|
||||
);
|
||||
|
||||
const agentFilter = [...container.querySelectorAll<HTMLSelectElement>("select")].find(
|
||||
(select) => select.title === "Filter by agent",
|
||||
);
|
||||
agentFilter!.value = "ops";
|
||||
agentFilter!.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
render(
|
||||
renderWorkboard({
|
||||
host,
|
||||
client: null,
|
||||
connected: true,
|
||||
pluginEnabled: true,
|
||||
agentsList: {
|
||||
defaultId: "main",
|
||||
mainKey: "agent:main:main",
|
||||
scope: "test",
|
||||
agents: [
|
||||
{ id: "main", name: "Main" },
|
||||
{ id: "ops", name: "Ops" },
|
||||
],
|
||||
},
|
||||
sessions: [],
|
||||
onOpenSession: () => undefined,
|
||||
}),
|
||||
container,
|
||||
);
|
||||
|
||||
expect(container.textContent).not.toContain("Main work");
|
||||
expect(container.textContent).toContain("Ops work");
|
||||
expect(container.textContent).toContain("Ops");
|
||||
});
|
||||
|
||||
it("preflights model-specific starts for ACP runtime agents", () => {
|
||||
const host = {};
|
||||
const state = getWorkboardState(host);
|
||||
state.loaded = true;
|
||||
state.detailCardId = "card-1";
|
||||
state.cards = [
|
||||
{
|
||||
id: "card-1",
|
||||
title: "ACP-backed work",
|
||||
status: "todo",
|
||||
priority: "normal",
|
||||
labels: [],
|
||||
agentId: "main",
|
||||
position: 1000,
|
||||
createdAt: 1,
|
||||
updatedAt: 1,
|
||||
},
|
||||
];
|
||||
const container = document.createElement("div");
|
||||
|
||||
render(
|
||||
renderWorkboard({
|
||||
host,
|
||||
client: null,
|
||||
connected: true,
|
||||
pluginEnabled: true,
|
||||
agentsList: {
|
||||
defaultId: "main",
|
||||
mainKey: "agent:main:main",
|
||||
scope: "test",
|
||||
agents: [{ id: "main", name: "Main", agentRuntime: { id: "codex", source: "agent" } }],
|
||||
},
|
||||
sessions: [],
|
||||
onOpenSession: () => undefined,
|
||||
}),
|
||||
container,
|
||||
);
|
||||
|
||||
const engineButtons = [
|
||||
...container.querySelectorAll<HTMLButtonElement>(
|
||||
".workboard-detail .workboard-card__start:not(.workboard-card__start--default)",
|
||||
),
|
||||
];
|
||||
expect(engineButtons).toHaveLength(4);
|
||||
expect(engineButtons.every((button) => button.disabled)).toBe(true);
|
||||
expect(engineButtons[0]?.title).toContain("uses the codex ACP runtime");
|
||||
});
|
||||
|
||||
it("does not render details for archived selected cards", () => {
|
||||
const host = {};
|
||||
const state = getWorkboardState(host);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { html, nothing } from "lit";
|
||||
import { html, nothing, type TemplateResult } from "lit";
|
||||
import { t } from "../../i18n/index.ts";
|
||||
import {
|
||||
addWorkboardCardComment,
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
deleteWorkboardCard,
|
||||
dispatchWorkboard,
|
||||
findWorkboardSession,
|
||||
getWorkboardDependencyState,
|
||||
getWorkboardLifecycle,
|
||||
getWorkboardState,
|
||||
loadWorkboard,
|
||||
@@ -15,6 +16,7 @@ import {
|
||||
stopWorkboardCard,
|
||||
syncWorkboardLifecycle,
|
||||
WORKBOARD_PRIORITIES,
|
||||
type WorkboardDependencyState,
|
||||
type WorkboardExecutionEngine,
|
||||
type WorkboardExecutionMode,
|
||||
type WorkboardCard,
|
||||
@@ -31,6 +33,8 @@ import type { GatewayBrowserClient } from "../gateway.ts";
|
||||
import { icons } from "../icons.ts";
|
||||
import type { AgentsListResult, GatewaySessionRow } from "../types.ts";
|
||||
|
||||
type WorkboardAgentRow = AgentsListResult["agents"][number];
|
||||
|
||||
type WorkboardProps = {
|
||||
host: object;
|
||||
client: GatewayBrowserClient | null;
|
||||
@@ -187,30 +191,59 @@ function renderEvents(card: WorkboardCard) {
|
||||
|
||||
function renderCompactBadges(card: WorkboardCard, task?: WorkboardTaskSummary) {
|
||||
const metadata = card.metadata;
|
||||
const badges = [
|
||||
metadata?.templateId ? t(`workboard.template.${metadata.templateId}`) : null,
|
||||
(task ?? card.taskId) ? t("workboard.badgeTaskLinked") : null,
|
||||
metadata?.failureCount
|
||||
? t("workboard.badgeFailures", { count: String(metadata.failureCount) })
|
||||
: null,
|
||||
metadata?.comments?.length
|
||||
? t("workboard.badgeComments", { count: String(metadata.comments.length) })
|
||||
: null,
|
||||
metadata?.proof?.length
|
||||
? t("workboard.badgeProof", { count: String(metadata.proof.length) })
|
||||
: null,
|
||||
metadata?.claim ? t("workboard.badgeClaimed", { owner: metadata.claim.ownerId }) : null,
|
||||
metadata?.diagnostics?.length
|
||||
? t("workboard.badgeDiagnostics", { count: String(metadata.diagnostics.length) })
|
||||
: null,
|
||||
metadata?.stale ? t("workboard.badgeStale") : null,
|
||||
].filter((badge): badge is string => Boolean(badge));
|
||||
const badges: TemplateResult[] = [];
|
||||
if (metadata?.templateId) {
|
||||
badges.push(html`<span>${t(`workboard.template.${metadata.templateId}`)}</span>`);
|
||||
}
|
||||
if (task ?? card.taskId) {
|
||||
badges.push(html`<span>${t("workboard.badgeTaskLinked")}</span>`);
|
||||
}
|
||||
if (metadata?.failureCount) {
|
||||
badges.push(html`
|
||||
<span class="workboard-card__badge--warning">
|
||||
${icons.alertTriangle}${t("workboard.badgeFailures", {
|
||||
count: String(metadata.failureCount),
|
||||
})}
|
||||
</span>
|
||||
`);
|
||||
}
|
||||
if (metadata?.comments?.length) {
|
||||
badges.push(
|
||||
html`<span
|
||||
>${t("workboard.badgeComments", { count: String(metadata.comments.length) })}</span
|
||||
>`,
|
||||
);
|
||||
}
|
||||
if (metadata?.proof?.length) {
|
||||
badges.push(
|
||||
html`<span>${t("workboard.badgeProof", { count: String(metadata.proof.length) })}</span>`,
|
||||
);
|
||||
}
|
||||
if (metadata?.claim) {
|
||||
badges.push(
|
||||
html`<span>${t("workboard.badgeClaimed", { owner: metadata.claim.ownerId })}</span>`,
|
||||
);
|
||||
}
|
||||
if (metadata?.diagnostics?.length) {
|
||||
badges.push(
|
||||
html`<span class="workboard-card__badge--warning">
|
||||
${icons.alertTriangle}${t("workboard.badgeDiagnostics", {
|
||||
count: String(metadata.diagnostics.length),
|
||||
})}
|
||||
</span>`,
|
||||
);
|
||||
}
|
||||
if (metadata?.stale) {
|
||||
badges.push(
|
||||
html`<span class="workboard-card__badge--warning"
|
||||
>${icons.alertTriangle}${t("workboard.badgeStale")}</span
|
||||
>`,
|
||||
);
|
||||
}
|
||||
if (badges.length === 0) {
|
||||
return nothing;
|
||||
}
|
||||
return html`
|
||||
<div class="workboard-card__badges">${badges.map((badge) => html`<span>${badge}</span>`)}</div>
|
||||
`;
|
||||
return html` <div class="workboard-card__badges">${badges}</div> `;
|
||||
}
|
||||
|
||||
function matchesFilter(
|
||||
@@ -299,6 +332,112 @@ function isCardActionTarget(event: Event): boolean {
|
||||
: false;
|
||||
}
|
||||
|
||||
function agentDisplayName(agent: WorkboardAgentRow | undefined, fallback: string): string {
|
||||
return agent?.name ?? agent?.identity?.name ?? agent?.id ?? fallback;
|
||||
}
|
||||
|
||||
function cardAgentId(card: WorkboardCard, agentsList: AgentsListResult | null): string {
|
||||
return card.agentId?.trim() || agentsList?.defaultId || "";
|
||||
}
|
||||
|
||||
function findCardAgent(
|
||||
card: WorkboardCard,
|
||||
agentsList: AgentsListResult | null,
|
||||
): WorkboardAgentRow | undefined {
|
||||
const id = cardAgentId(card, agentsList);
|
||||
return id ? agentsList?.agents.find((agent) => agent.id === id) : undefined;
|
||||
}
|
||||
|
||||
function cardAgentLabel(card: WorkboardCard, agentsList: AgentsListResult | null): string {
|
||||
const fallback = card.agentId?.trim() || t("workboard.defaultAgent");
|
||||
return agentDisplayName(findCardAgent(card, agentsList), fallback);
|
||||
}
|
||||
|
||||
function matchesAgentFilter(
|
||||
card: WorkboardCard,
|
||||
agentsList: AgentsListResult | null,
|
||||
filter: WorkboardUiState["agentFilter"],
|
||||
): boolean {
|
||||
if (filter === "all") {
|
||||
return true;
|
||||
}
|
||||
const explicitAgentId = card.agentId?.trim();
|
||||
if (filter === "default") {
|
||||
return !explicitAgentId;
|
||||
}
|
||||
return explicitAgentId === filter || (!explicitAgentId && agentsList?.defaultId === filter);
|
||||
}
|
||||
|
||||
function buildAgentFilterOptions(
|
||||
cards: readonly WorkboardCard[],
|
||||
agentsList: AgentsListResult | null,
|
||||
) {
|
||||
const seen = new Set<string>();
|
||||
const options: Array<{ id: WorkboardUiState["agentFilter"]; label: string }> = [
|
||||
{ id: "all", label: t("workboard.allAgents") },
|
||||
{ id: "default", label: t("workboard.defaultAgent") },
|
||||
];
|
||||
for (const agent of agentsList?.agents ?? []) {
|
||||
if (seen.has(agent.id)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(agent.id);
|
||||
options.push({ id: agent.id, label: agentDisplayName(agent, agent.id) });
|
||||
}
|
||||
for (const card of cards) {
|
||||
const id = card.agentId?.trim();
|
||||
if (!id || seen.has(id)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(id);
|
||||
options.push({ id, label: id });
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
function engineDisplayName(engine: WorkboardExecutionEngine): string {
|
||||
return engine === "codex" ? t("workboard.engineOpenAI") : t("workboard.engineClaude");
|
||||
}
|
||||
|
||||
function engineBlockedByRuntime(
|
||||
props: WorkboardProps,
|
||||
card: WorkboardCard,
|
||||
engine: WorkboardExecutionEngine | null,
|
||||
): string | null {
|
||||
if (!engine) {
|
||||
return null;
|
||||
}
|
||||
const agent = findCardAgent(card, props.agentsList);
|
||||
const runtime = agent?.agentRuntime?.id?.trim();
|
||||
if (!runtime) {
|
||||
return null;
|
||||
}
|
||||
const normalized = runtime.toLowerCase();
|
||||
if (normalized === "openclaw" || normalized === "pi") {
|
||||
return null;
|
||||
}
|
||||
return t("workboard.engineDisabledRuntime", {
|
||||
agent: agentDisplayName(agent, card.agentId ?? t("workboard.defaultAgent")),
|
||||
runtime,
|
||||
});
|
||||
}
|
||||
|
||||
function renderAgentChip(props: WorkboardProps, card: WorkboardCard) {
|
||||
const label = cardAgentLabel(card, props.agentsList);
|
||||
const title = card.agentId
|
||||
? t("workboard.agentLinked", { agent: label })
|
||||
: t("workboard.agentDefaultLinked", { agent: label });
|
||||
return html`<span class="workboard-agent-chip" title=${title}>${label}</span>`;
|
||||
}
|
||||
|
||||
function renderEngineMark(engine: WorkboardExecutionEngine) {
|
||||
return html`
|
||||
<span class="workboard-engine-mark workboard-engine-mark--${engine}" aria-hidden="true">
|
||||
${engine === "codex" ? "OpenAI" : "Claude"}
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
|
||||
function openCardDetails(state: WorkboardUiState, card: WorkboardCard) {
|
||||
state.detailCardId = card.id;
|
||||
state.detailCommentBody = "";
|
||||
@@ -699,6 +838,82 @@ function cardCanStart(
|
||||
return !activeTask && (!linkedSessionKey || !session);
|
||||
}
|
||||
|
||||
function formatDependencyParent(parent: WorkboardDependencyState["parents"][number]): string {
|
||||
if (parent.missing) {
|
||||
return t("workboard.dependencyMissing", { parent: parent.title });
|
||||
}
|
||||
const status = parent.status ? formatStatusLabel(parent.status) : t("workboard.unknownStatus");
|
||||
return `${parent.title} (${status})`;
|
||||
}
|
||||
|
||||
function formatDependencyBlockerTitle(dependencies: WorkboardDependencyState): string | null {
|
||||
if (dependencies.blockedParents.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return t("workboard.dependenciesBlockedTitle", {
|
||||
parents: dependencies.blockedParents.map(formatDependencyParent).join(", "),
|
||||
});
|
||||
}
|
||||
|
||||
function renderDependencyBadges(dependencies: WorkboardDependencyState) {
|
||||
if (dependencies.parents.length === 0) {
|
||||
return nothing;
|
||||
}
|
||||
const blocked = dependencies.blockedParents.length;
|
||||
const title =
|
||||
formatDependencyBlockerTitle(dependencies) ??
|
||||
t("workboard.dependenciesReadyTitle", {
|
||||
count: String(dependencies.parents.length),
|
||||
});
|
||||
return html`
|
||||
<div class="workboard-dependencies" title=${title}>
|
||||
${blocked > 0
|
||||
? html`
|
||||
<span class="workboard-dependency workboard-dependency--blocked">
|
||||
${icons.alertTriangle}${t("workboard.dependenciesBlocked", {
|
||||
count: String(blocked),
|
||||
})}
|
||||
</span>
|
||||
`
|
||||
: html`
|
||||
<span class="workboard-dependency workboard-dependency--ready">
|
||||
${t("workboard.dependenciesReady", { count: String(dependencies.parents.length) })}
|
||||
</span>
|
||||
`}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderDependencyDetailList(dependencies: WorkboardDependencyState) {
|
||||
if (dependencies.parents.length === 0) {
|
||||
return nothing;
|
||||
}
|
||||
return html`
|
||||
<section class="workboard-detail__section">
|
||||
<h3>${t("workboard.dependencies")}</h3>
|
||||
<ul class="workboard-detail__list workboard-detail__dependencies">
|
||||
${dependencies.parents.map(
|
||||
(parent) => html`
|
||||
<li class=${parent.done ? "is-done" : "is-blocked"}>
|
||||
${parent.done
|
||||
? html`<span class="workboard-detail__dependency-spacer"></span>`
|
||||
: icons.alertTriangle}
|
||||
<span>${parent.title}</span>
|
||||
<span>
|
||||
${parent.missing
|
||||
? t("workboard.dependencyStatusMissing")
|
||||
: parent.status
|
||||
? formatStatusLabel(parent.status)
|
||||
: t("workboard.unknownStatus")}
|
||||
</span>
|
||||
</li>
|
||||
`,
|
||||
)}
|
||||
</ul>
|
||||
</section>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderLifecycle(
|
||||
card: WorkboardCard,
|
||||
sessions: readonly GatewaySessionRow[],
|
||||
@@ -733,21 +948,29 @@ function renderStartExecutionButton(
|
||||
card: WorkboardCard,
|
||||
engine: WorkboardExecutionEngine | null,
|
||||
mode: WorkboardExecutionMode,
|
||||
options: { iconOnly?: boolean } = {},
|
||||
) {
|
||||
const state = getWorkboardState(props.host);
|
||||
const busy = state.busyCardId === card.id;
|
||||
const title = engine
|
||||
? mode === "autonomous"
|
||||
? t("workboard.runEngine", { engine })
|
||||
: t("workboard.openEngine", { engine })
|
||||
: t("workboard.runDefaultAgent");
|
||||
const runtimeBlock = engineBlockedByRuntime(props, card, engine);
|
||||
const disabled =
|
||||
busy || !props.connected || Boolean(runtimeBlock) || Boolean(card.metadata?.archivedAt);
|
||||
const title = runtimeBlock
|
||||
? runtimeBlock
|
||||
: engine
|
||||
? mode === "autonomous"
|
||||
? t("workboard.runEngine", { engine: engineDisplayName(engine) })
|
||||
: t("workboard.openEngine", { engine: engineDisplayName(engine) })
|
||||
: t("workboard.runDefaultAgent");
|
||||
return html`
|
||||
<button
|
||||
class="btn btn--xs workboard-card__start workboard-card__start--${mode} ${engine
|
||||
? ""
|
||||
: "workboard-card__start--default"}"
|
||||
class="btn btn--xs workboard-card__start workboard-card__start--${mode} ${options.iconOnly
|
||||
? "workboard-card__start--icon"
|
||||
: ""} ${engine ? "" : "workboard-card__start--default"}"
|
||||
type="button"
|
||||
title=${title}
|
||||
?disabled=${busy || !props.connected}
|
||||
aria-label=${title}
|
||||
?disabled=${disabled}
|
||||
@click=${async () => {
|
||||
const key = await startWorkboardCard({
|
||||
host: props.host,
|
||||
@@ -762,7 +985,15 @@ function renderStartExecutionButton(
|
||||
}
|
||||
}}
|
||||
>
|
||||
${mode === "autonomous" ? icons.play : icons.penLine} ${engine ?? t("workboard.start")}
|
||||
${engine
|
||||
? html`${renderEngineMark(engine)}${options.iconOnly
|
||||
? nothing
|
||||
: html`<span
|
||||
>${mode === "autonomous" ? t("workboard.run") : t("workboard.open")}</span
|
||||
>`}`
|
||||
: html`${mode === "autonomous" ? icons.play : icons.penLine}${options.iconOnly
|
||||
? nothing
|
||||
: html`<span>${t("workboard.start")}</span>`}`}
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
@@ -825,7 +1056,7 @@ function renderCardDetailsPanel(props: WorkboardProps) {
|
||||
const card = state.detailCardId
|
||||
? (state.cards.find((entry) => entry.id === state.detailCardId) ?? null)
|
||||
: null;
|
||||
if (!card || card.metadata?.archivedAt) {
|
||||
if (!card || (card.metadata?.archivedAt && !state.showArchived)) {
|
||||
return nothing;
|
||||
}
|
||||
const task = state.tasksByCardId.get(card.id);
|
||||
@@ -847,6 +1078,7 @@ function renderCardDetailsPanel(props: WorkboardProps) {
|
||||
const events = (card.events ?? []).slice(-6).toReversed();
|
||||
const busy = state.busyCardId === card.id;
|
||||
const showStartControls = writable && cardCanStart(state, props.sessions, card);
|
||||
const dependencies = getWorkboardDependencyState(card, state.cards);
|
||||
return html`
|
||||
<aside class="workboard-detail-drawer" aria-label=${t("workboard.detailTitle")}>
|
||||
<div class="workboard-detail">
|
||||
@@ -901,6 +1133,7 @@ function renderCardDetailsPanel(props: WorkboardProps) {
|
||||
</section>
|
||||
`
|
||||
: nothing}
|
||||
${renderDependencyDetailList(dependencies)}
|
||||
${renderDetailList(t("workboard.fieldLabels"), card.labels)}
|
||||
${renderDetailList(
|
||||
t("workboard.badgeAttempts", { count: String(attempts.length) }),
|
||||
@@ -1089,11 +1322,13 @@ function renderCard(props: WorkboardProps, card: WorkboardCard) {
|
||||
const linkedSessionKey = card.sessionKey ?? card.execution?.sessionKey;
|
||||
const writable = canMutate(props);
|
||||
const showStartControls = writable && cardCanStart(state, props.sessions, card);
|
||||
const archived = Boolean(card.metadata?.archivedAt);
|
||||
const dependencies = getWorkboardDependencyState(card, state.cards);
|
||||
return html`
|
||||
<article
|
||||
class="workboard-card priority-${card.priority} ${busy
|
||||
? "workboard-card--busy"
|
||||
: ""} workboard-card--openable"
|
||||
: ""} ${archived ? "workboard-card--archived" : ""} workboard-card--openable"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title=${t("workboard.viewDetails")}
|
||||
@@ -1128,13 +1363,61 @@ function renderCard(props: WorkboardProps, card: WorkboardCard) {
|
||||
}}
|
||||
>
|
||||
<div class="workboard-card__top">
|
||||
<span class="workboard-card__priority">${card.priority}</span>
|
||||
${live ? html`<span class="workboard-live">${t("workboard.live")}</span>` : nothing}
|
||||
${syncing ? html`<span class="workboard-live">${t("common.saving")}</span>` : nothing}
|
||||
<div class="workboard-card__chips">
|
||||
<span class="workboard-card__priority">${card.priority}</span>
|
||||
${renderAgentChip(props, card)}
|
||||
${archived
|
||||
? html`<span class="workboard-card__archived">${t("workboard.archived")}</span>`
|
||||
: nothing}
|
||||
${live ? html`<span class="workboard-live">${t("workboard.live")}</span>` : nothing}
|
||||
${syncing ? html`<span class="workboard-live">${t("common.saving")}</span>` : nothing}
|
||||
</div>
|
||||
<div class="workboard-card__quick-actions">
|
||||
${showStartControls
|
||||
? renderStartExecutionButton(props, card, null, "autonomous", { iconOnly: true })
|
||||
: nothing}
|
||||
${writable && !archived
|
||||
? html`
|
||||
<button
|
||||
class="btn btn--icon workboard-card__icon"
|
||||
type="button"
|
||||
title=${t("workboard.editCard")}
|
||||
aria-label=${t("workboard.editCard")}
|
||||
@click=${() => {
|
||||
openEditModal(state, card);
|
||||
props.onRequestUpdate?.();
|
||||
}}
|
||||
>
|
||||
${icons.edit}
|
||||
</button>
|
||||
`
|
||||
: nothing}
|
||||
${writable
|
||||
? html`
|
||||
<button
|
||||
class="btn btn--icon workboard-card__icon"
|
||||
type="button"
|
||||
title=${archived ? t("workboard.unarchiveCard") : t("workboard.archiveCard")}
|
||||
aria-label=${archived ? t("workboard.unarchiveCard") : t("workboard.archiveCard")}
|
||||
?disabled=${busy}
|
||||
@click=${() =>
|
||||
archiveWorkboardCard({
|
||||
host: props.host,
|
||||
client: props.client,
|
||||
cardId: card.id,
|
||||
archived: !archived,
|
||||
requestUpdate: props.onRequestUpdate,
|
||||
})}
|
||||
>
|
||||
${archived ? icons.archiveRestore : icons.archive}
|
||||
</button>
|
||||
`
|
||||
: nothing}
|
||||
</div>
|
||||
</div>
|
||||
<h3>${card.title}</h3>
|
||||
${card.notes ? html`<p>${card.notes}</p>` : nothing}
|
||||
${renderLifecycle(card, props.sessions, task)}
|
||||
${renderLifecycle(card, props.sessions, task)} ${renderDependencyBadges(dependencies)}
|
||||
${card.labels.length
|
||||
? html`<div class="workboard-labels">
|
||||
${card.labels.map((label) => html`<span>${label}</span>`)}
|
||||
@@ -1142,9 +1425,7 @@ function renderCard(props: WorkboardProps, card: WorkboardCard) {
|
||||
: nothing}
|
||||
${renderCompactBadges(card, task)}
|
||||
<div class="workboard-card__meta">
|
||||
${card.agentId
|
||||
? html`<span>${card.agentId}</span>`
|
||||
: html`<span>${t("workboard.defaultAgent")}</span>`}
|
||||
<span>${linkedSessionKey ?? t("workboard.noLinkedSession")}</span>
|
||||
<span>${formatTime(card.updatedAt)}</span>
|
||||
</div>
|
||||
${renderEvents(card)}
|
||||
@@ -1159,20 +1440,6 @@ function renderCard(props: WorkboardProps, card: WorkboardCard) {
|
||||
>
|
||||
${icons.panelRightOpen}
|
||||
</button>
|
||||
${writable
|
||||
? html`
|
||||
<button
|
||||
class="btn btn--icon workboard-card__icon"
|
||||
title=${t("workboard.editCard")}
|
||||
@click=${() => {
|
||||
openEditModal(state, card);
|
||||
props.onRequestUpdate?.();
|
||||
}}
|
||||
>
|
||||
${icons.edit}
|
||||
</button>
|
||||
`
|
||||
: nothing}
|
||||
${linkedSessionKey
|
||||
? html`
|
||||
<button
|
||||
@@ -1220,26 +1487,13 @@ function renderCard(props: WorkboardProps, card: WorkboardCard) {
|
||||
</button>
|
||||
`
|
||||
: nothing}
|
||||
${showStartControls ? renderStartExecutionButton(props, card, null, "autonomous") : nothing}
|
||||
${writable
|
||||
? html`
|
||||
<button
|
||||
class="btn btn--icon workboard-card__icon"
|
||||
title=${t("workboard.archiveCard")}
|
||||
?disabled=${busy}
|
||||
@click=${() =>
|
||||
archiveWorkboardCard({
|
||||
host: props.host,
|
||||
client: props.client,
|
||||
cardId: card.id,
|
||||
requestUpdate: props.onRequestUpdate,
|
||||
})}
|
||||
>
|
||||
${icons.check}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn--icon workboard-card__icon workboard-card__delete"
|
||||
type="button"
|
||||
title=${t("workboard.deleteCard")}
|
||||
aria-label=${t("workboard.deleteCard")}
|
||||
?disabled=${busy}
|
||||
@click=${() =>
|
||||
deleteWorkboardCard({
|
||||
@@ -1263,7 +1517,9 @@ function renderColumn(props: WorkboardProps, status: WorkboardStatus, cards: Wor
|
||||
const writable = canMutate(props);
|
||||
return html`
|
||||
<section
|
||||
class="workboard-column ${state.draggedCardId ? "workboard-column--drop" : ""}"
|
||||
class="workboard-column workboard-column--${status} ${state.draggedCardId
|
||||
? "workboard-column--drop"
|
||||
: ""}"
|
||||
@dragover=${(event: DragEvent) => {
|
||||
if (writable && state.draggedCardId) {
|
||||
event.preventDefault();
|
||||
@@ -1330,9 +1586,11 @@ export function renderWorkboard(props: WorkboardProps) {
|
||||
}
|
||||
|
||||
const filtered = state.cards
|
||||
.filter((card) => !card.metadata?.archivedAt)
|
||||
.filter((card) => state.showArchived || !card.metadata?.archivedAt)
|
||||
.filter((card) => matchesAgentFilter(card, props.agentsList, state.agentFilter))
|
||||
.filter((card) => matchesFilter(card, { query: state.query, priority: state.priorityFilter }));
|
||||
const writable = canMutate(props);
|
||||
const agentOptions = buildAgentFilterOptions(state.cards, props.agentsList);
|
||||
const byStatus = new Map<WorkboardStatus, WorkboardCard[]>();
|
||||
for (const status of state.statuses) {
|
||||
byStatus.set(status, []);
|
||||
@@ -1348,6 +1606,7 @@ export function renderWorkboard(props: WorkboardProps) {
|
||||
<input
|
||||
class="input"
|
||||
type="search"
|
||||
title=${t("workboard.searchPlaceholder")}
|
||||
placeholder=${t("workboard.searchPlaceholder")}
|
||||
.value=${state.query}
|
||||
@input=${(event: InputEvent) => {
|
||||
@@ -1357,6 +1616,7 @@ export function renderWorkboard(props: WorkboardProps) {
|
||||
/>
|
||||
<select
|
||||
class="input"
|
||||
title=${t("workboard.allPriorities")}
|
||||
.value=${state.priorityFilter}
|
||||
@change=${(event: Event) => {
|
||||
state.priorityFilter = (event.currentTarget as HTMLSelectElement)
|
||||
@@ -1369,10 +1629,66 @@ export function renderWorkboard(props: WorkboardProps) {
|
||||
(priority) => html`<option value=${priority}>${priority}</option>`,
|
||||
)}
|
||||
</select>
|
||||
<select
|
||||
class="input"
|
||||
title=${t("workboard.agentFilter")}
|
||||
.value=${state.agentFilter}
|
||||
@change=${(event: Event) => {
|
||||
state.agentFilter = (event.currentTarget as HTMLSelectElement).value;
|
||||
props.onRequestUpdate?.();
|
||||
}}
|
||||
>
|
||||
${agentOptions.map((agent) => html`<option value=${agent.id}>${agent.label}</option>`)}
|
||||
</select>
|
||||
<button
|
||||
class="btn workboard-archive-toggle ${state.showArchived ? "active" : ""}"
|
||||
type="button"
|
||||
title=${state.showArchived ? t("workboard.hideArchived") : t("workboard.showArchived")}
|
||||
aria-pressed=${state.showArchived}
|
||||
@click=${() => {
|
||||
state.showArchived = !state.showArchived;
|
||||
props.onRequestUpdate?.();
|
||||
}}
|
||||
>
|
||||
${state.showArchived ? icons.eye : icons.eyeOff}
|
||||
${state.showArchived
|
||||
? t("workboard.hideArchivedShort")
|
||||
: t("workboard.showArchivedShort")}
|
||||
</button>
|
||||
<div class="workboard-layout-toggle" role="group" aria-label=${t("workboard.layout")}>
|
||||
<button
|
||||
class="btn btn--icon ${state.layout === "compact" ? "active" : ""}"
|
||||
type="button"
|
||||
title=${t("workboard.layoutCompact")}
|
||||
aria-label=${t("workboard.layoutCompact")}
|
||||
aria-pressed=${state.layout === "compact"}
|
||||
@click=${() => {
|
||||
state.layout = "compact";
|
||||
props.onRequestUpdate?.();
|
||||
}}
|
||||
>
|
||||
${icons.layoutCompact}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn--icon ${state.layout === "comfortable" ? "active" : ""}"
|
||||
type="button"
|
||||
title=${t("workboard.layoutComfortable")}
|
||||
aria-label=${t("workboard.layoutComfortable")}
|
||||
aria-pressed=${state.layout === "comfortable"}
|
||||
@click=${() => {
|
||||
state.layout = "comfortable";
|
||||
props.onRequestUpdate?.();
|
||||
}}
|
||||
>
|
||||
${icons.layoutComfortable}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="workboard-toolbar__actions">
|
||||
<button
|
||||
class="btn"
|
||||
type="button"
|
||||
title=${t("common.refresh")}
|
||||
?disabled=${state.loading}
|
||||
@click=${() =>
|
||||
loadWorkboard({
|
||||
@@ -1388,6 +1704,8 @@ export function renderWorkboard(props: WorkboardProps) {
|
||||
? html`
|
||||
<button
|
||||
class="btn"
|
||||
type="button"
|
||||
title=${t("workboard.dispatch")}
|
||||
?disabled=${state.loading}
|
||||
@click=${() =>
|
||||
dispatchWorkboard({
|
||||
@@ -1404,6 +1722,8 @@ export function renderWorkboard(props: WorkboardProps) {
|
||||
? html`
|
||||
<button
|
||||
class="btn primary"
|
||||
type="button"
|
||||
title=${t("workboard.newCard")}
|
||||
@click=${() => {
|
||||
openCreateModal(state);
|
||||
props.onRequestUpdate?.();
|
||||
@@ -1417,7 +1737,7 @@ export function renderWorkboard(props: WorkboardProps) {
|
||||
</div>
|
||||
${state.error ? html`<div class="callout danger">${state.error}</div>` : nothing}
|
||||
${renderDispatchSummary(state)} ${renderCardModal(props)} ${renderCardDetailsPanel(props)}
|
||||
<div class="workboard-board">
|
||||
<div class="workboard-board workboard-board--${state.layout}">
|
||||
${state.statuses.map((status) => renderColumn(props, status, byStatus.get(status) ?? []))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user