refactor(web): extract ShellPage sidebar JSX into components
ShellPage's JSX carried the whole sidebar inline, including two near-copies of the group header and of the main header's sidebar toggles, which made the render hard to follow and easy to change in one place only. Move-only: the sidebar header, group header (one component for the conversation and project variants), the team and project roster rows, the archived section, the user menu and the sidebar toggle buttons now live in pages/shell. DOM, classNames, test ids, aria attributes, handlers and messages are unchanged; the catalogs only update their file references, and the desktop source checks for the header toggles now read the file they moved to. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u
This commit is contained in:
parent
a0060b8df7
commit
3c678519a6
@ -63,6 +63,7 @@ describe("window chrome", () => {
|
|||||||
it("keeps conversation header controls clickable", () => {
|
it("keeps conversation header controls clickable", () => {
|
||||||
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), "../pages");
|
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), "../pages");
|
||||||
const shell = readFileSync(path.join(root, "Shell.tsx"), "utf8");
|
const shell = readFileSync(path.join(root, "Shell.tsx"), "utf8");
|
||||||
|
const toggles = readFileSync(path.join(root, "shell/sidebar-toggle-buttons.tsx"), "utf8");
|
||||||
expect(shell).toContain(
|
expect(shell).toContain(
|
||||||
'className="app-drag flex items-center justify-between border-b border-sidebar-border',
|
'className="app-drag flex items-center justify-between border-b border-sidebar-border',
|
||||||
);
|
);
|
||||||
@ -70,14 +71,16 @@ describe("window chrome", () => {
|
|||||||
expect(shell).toContain('className="app-no-drag flex min-w-0 items-center gap-3"');
|
expect(shell).toContain('className="app-no-drag flex min-w-0 items-center gap-3"');
|
||||||
// Ensure header sidebar toggle controls stay clickable (not part of drag region)
|
// Ensure header sidebar toggle controls stay clickable (not part of drag region)
|
||||||
expect(
|
expect(
|
||||||
shell.match(/app-no-drag .* size-control-lg .* place-items-center/g)?.length ?? 0,
|
toggles.match(/app-no-drag .* size-control-lg .* place-items-center/g)?.length ?? 0,
|
||||||
).toBeGreaterThanOrEqual(2);
|
).toBeGreaterThanOrEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("moves window chrome into the conversation header when the bots sidebar is collapsed", () => {
|
it("moves window chrome into the conversation header when the bots sidebar is collapsed", () => {
|
||||||
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), "../pages");
|
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), "../pages");
|
||||||
const shell = readFileSync(path.join(root, "Shell.tsx"), "utf8");
|
const shell = readFileSync(path.join(root, "Shell.tsx"), "utf8");
|
||||||
expect(shell).toContain("{botsSidebarCollapsed && desktopBridge() ? <WindowChrome /> : null}");
|
const toggles = readFileSync(path.join(root, "shell/sidebar-toggle-buttons.tsx"), "utf8");
|
||||||
|
expect(shell).toContain("collapsed={botsSidebarCollapsed}");
|
||||||
|
expect(toggles).toContain("{collapsed && desktopBridge() ? <WindowChrome /> : null}");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ msgstr ""
|
|||||||
"Plural-Forms: \n"
|
"Plural-Forms: \n"
|
||||||
"X-Generator: @lingui/cli\n"
|
"X-Generator: @lingui/cli\n"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid " (unread)"
|
msgid " (unread)"
|
||||||
msgstr " (ungelesen)"
|
msgstr " (ungelesen)"
|
||||||
|
|
||||||
@ -126,17 +126,17 @@ msgid "{0}, {label}"
|
|||||||
msgstr "{0}, {label}"
|
msgstr "{0}, {label}"
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, 1:1 conversation"
|
msgid "{0}, 1:1 conversation"
|
||||||
msgstr "{0}, 1:1-Unterhaltung"
|
msgstr "{0}, 1:1-Unterhaltung"
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, group conversation"
|
msgid "{0}, group conversation"
|
||||||
msgstr "{0}, Gruppenunterhaltung"
|
msgstr "{0}, Gruppenunterhaltung"
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, main conversation"
|
msgid "{0}, main conversation"
|
||||||
msgstr "{0}, Hauptunterhaltung"
|
msgstr "{0}, Hauptunterhaltung"
|
||||||
|
|
||||||
@ -339,6 +339,7 @@ msgstr "Aktionsbestätigungen"
|
|||||||
#. placeholder {0}: sectionMenu.section.name
|
#. placeholder {0}: sectionMenu.section.name
|
||||||
#: src/pages/BotContextMenu.tsx
|
#: src/pages/BotContextMenu.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Actions for {0}"
|
msgid "Actions for {0}"
|
||||||
msgstr "Aktionen für {0}"
|
msgstr "Aktionen für {0}"
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ msgstr "Aktiv"
|
|||||||
msgid "Active model"
|
msgid "Active model"
|
||||||
msgstr "Aktives Modell"
|
msgstr "Aktives Modell"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Activity"
|
msgid "Activity"
|
||||||
msgstr "Aktivität"
|
msgstr "Aktivität"
|
||||||
|
|
||||||
@ -647,7 +648,7 @@ msgstr "Archivieren"
|
|||||||
msgid "archived"
|
msgid "archived"
|
||||||
msgstr "archiviert"
|
msgstr "archiviert"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Archived"
|
msgid "Archived"
|
||||||
msgstr "Archiviert"
|
msgstr "Archiviert"
|
||||||
|
|
||||||
@ -1159,7 +1160,7 @@ msgid "Coder"
|
|||||||
msgstr "Coder"
|
msgstr "Coder"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Collapse {0}"
|
msgid "Collapse {0}"
|
||||||
msgstr "{0} einklappen"
|
msgstr "{0} einklappen"
|
||||||
|
|
||||||
@ -1743,9 +1744,9 @@ msgstr "Avatare konnten nicht aktualisiert werden"
|
|||||||
msgid "Couldn't update messaging settings"
|
msgid "Couldn't update messaging settings"
|
||||||
msgstr "Messaging-Einstellungen konnten nicht aktualisiert werden"
|
msgstr "Messaging-Einstellungen konnten nicht aktualisiert werden"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
|
||||||
#: src/pages/shell/bot-panel.tsx
|
#: src/pages/shell/bot-panel.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr "Erstellen"
|
msgstr "Erstellen"
|
||||||
|
|
||||||
@ -1902,14 +1903,14 @@ msgstr "Standardbereich"
|
|||||||
#: src/pages/KnowledgeSection.tsx
|
#: src/pages/KnowledgeSection.tsx
|
||||||
#: src/pages/McpServersOverlay.tsx
|
#: src/pages/McpServersOverlay.tsx
|
||||||
#: src/pages/RoutineEditor.tsx
|
#: src/pages/RoutineEditor.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Löschen"
|
msgstr "Löschen"
|
||||||
|
|
||||||
#. placeholder {0}: bot.name
|
#. placeholder {0}: bot.name
|
||||||
#. placeholder {0}: group.name
|
#. placeholder {0}: group.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Delete {0}"
|
msgid "Delete {0}"
|
||||||
msgstr "{0} löschen"
|
msgstr "{0} löschen"
|
||||||
|
|
||||||
@ -2218,7 +2219,7 @@ msgid "Expand"
|
|||||||
msgstr "Erweitern"
|
msgstr "Erweitern"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Expand {0}"
|
msgid "Expand {0}"
|
||||||
msgstr "{0} ausklappen"
|
msgstr "{0} ausklappen"
|
||||||
|
|
||||||
@ -2791,7 +2792,7 @@ msgstr "Lokales Docker"
|
|||||||
msgid "Local Server Settings"
|
msgid "Local Server Settings"
|
||||||
msgstr "Einstellungen des lokalen Servers"
|
msgstr "Einstellungen des lokalen Servers"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "Abmelden"
|
msgstr "Abmelden"
|
||||||
|
|
||||||
@ -2974,7 +2975,7 @@ msgstr "Minimal"
|
|||||||
msgid "Minimize"
|
msgid "Minimize"
|
||||||
msgstr "Minimieren"
|
msgstr "Minimieren"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Minimize bots"
|
msgid "Minimize bots"
|
||||||
msgstr "Bots minimieren"
|
msgstr "Bots minimieren"
|
||||||
|
|
||||||
@ -3396,7 +3397,7 @@ msgid "Open"
|
|||||||
msgstr "Öffnen"
|
msgstr "Öffnen"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Open {0}"
|
msgid "Open {0}"
|
||||||
msgstr "{0} öffnen"
|
msgstr "{0} öffnen"
|
||||||
|
|
||||||
@ -3416,7 +3417,7 @@ msgstr "Im Browser öffnen"
|
|||||||
msgid "Open in full window"
|
msgid "Open in full window"
|
||||||
msgstr "In vollständigem Fenster öffnen"
|
msgstr "In vollständigem Fenster öffnen"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Open navigation"
|
msgid "Open navigation"
|
||||||
msgstr "Navigation öffnen"
|
msgstr "Navigation öffnen"
|
||||||
|
|
||||||
@ -3931,7 +3932,7 @@ msgstr "Wird zurückgesetzt…"
|
|||||||
msgid "Restart to update"
|
msgid "Restart to update"
|
||||||
msgstr "Zum Aktualisieren neu starten"
|
msgstr "Zum Aktualisieren neu starten"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Restore"
|
msgid "Restore"
|
||||||
msgstr "Wiederherstellen"
|
msgstr "Wiederherstellen"
|
||||||
|
|
||||||
@ -4136,7 +4137,7 @@ msgid "Searching…"
|
|||||||
msgstr "Suche…"
|
msgstr "Suche…"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Select {0}"
|
msgid "Select {0}"
|
||||||
msgstr "{0} auswählen"
|
msgstr "{0} auswählen"
|
||||||
|
|
||||||
@ -4202,6 +4203,7 @@ msgstr "Stimme einrichten"
|
|||||||
#: src/pages/MessagingSettingsOverlay.tsx
|
#: src/pages/MessagingSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Einstellungen"
|
msgstr "Einstellungen"
|
||||||
|
|
||||||
@ -4253,6 +4255,7 @@ msgid "Show all {0}"
|
|||||||
msgstr "Alle {0} anzeigen"
|
msgstr "Alle {0} anzeigen"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Show bots"
|
msgid "Show bots"
|
||||||
msgstr "Bots anzeigen"
|
msgstr "Bots anzeigen"
|
||||||
|
|
||||||
@ -4832,7 +4835,7 @@ msgstr "Hochladen"
|
|||||||
|
|
||||||
#: src/pages/AccountSettingsOverlay.tsx
|
#: src/pages/AccountSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Usage"
|
msgid "Usage"
|
||||||
msgstr "Nutzung"
|
msgstr "Nutzung"
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ msgstr ""
|
|||||||
"Plural-Forms: \n"
|
"Plural-Forms: \n"
|
||||||
"X-Generator: @lingui/cli\n"
|
"X-Generator: @lingui/cli\n"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid " (unread)"
|
msgid " (unread)"
|
||||||
msgstr " (unread)"
|
msgstr " (unread)"
|
||||||
|
|
||||||
@ -126,17 +126,17 @@ msgid "{0}, {label}"
|
|||||||
msgstr "{0}, {label}"
|
msgstr "{0}, {label}"
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, 1:1 conversation"
|
msgid "{0}, 1:1 conversation"
|
||||||
msgstr "{0}, 1:1 conversation"
|
msgstr "{0}, 1:1 conversation"
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, group conversation"
|
msgid "{0}, group conversation"
|
||||||
msgstr "{0}, group conversation"
|
msgstr "{0}, group conversation"
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, main conversation"
|
msgid "{0}, main conversation"
|
||||||
msgstr "{0}, main conversation"
|
msgstr "{0}, main conversation"
|
||||||
|
|
||||||
@ -339,6 +339,7 @@ msgstr "Action confirmations"
|
|||||||
#. placeholder {0}: sectionMenu.section.name
|
#. placeholder {0}: sectionMenu.section.name
|
||||||
#: src/pages/BotContextMenu.tsx
|
#: src/pages/BotContextMenu.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Actions for {0}"
|
msgid "Actions for {0}"
|
||||||
msgstr "Actions for {0}"
|
msgstr "Actions for {0}"
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ msgstr "Active"
|
|||||||
msgid "Active model"
|
msgid "Active model"
|
||||||
msgstr "Active model"
|
msgstr "Active model"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Activity"
|
msgid "Activity"
|
||||||
msgstr "Activity"
|
msgstr "Activity"
|
||||||
|
|
||||||
@ -647,7 +648,7 @@ msgstr "Archive"
|
|||||||
msgid "archived"
|
msgid "archived"
|
||||||
msgstr "archived"
|
msgstr "archived"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Archived"
|
msgid "Archived"
|
||||||
msgstr "Archived"
|
msgstr "Archived"
|
||||||
|
|
||||||
@ -1159,7 +1160,7 @@ msgid "Coder"
|
|||||||
msgstr "Coder"
|
msgstr "Coder"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Collapse {0}"
|
msgid "Collapse {0}"
|
||||||
msgstr "Collapse {0}"
|
msgstr "Collapse {0}"
|
||||||
|
|
||||||
@ -1743,9 +1744,9 @@ msgstr "Couldn't update avatars"
|
|||||||
msgid "Couldn't update messaging settings"
|
msgid "Couldn't update messaging settings"
|
||||||
msgstr "Couldn't update messaging settings"
|
msgstr "Couldn't update messaging settings"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
|
||||||
#: src/pages/shell/bot-panel.tsx
|
#: src/pages/shell/bot-panel.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr "Create"
|
msgstr "Create"
|
||||||
|
|
||||||
@ -1902,14 +1903,14 @@ msgstr "Default scope"
|
|||||||
#: src/pages/KnowledgeSection.tsx
|
#: src/pages/KnowledgeSection.tsx
|
||||||
#: src/pages/McpServersOverlay.tsx
|
#: src/pages/McpServersOverlay.tsx
|
||||||
#: src/pages/RoutineEditor.tsx
|
#: src/pages/RoutineEditor.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Delete"
|
msgstr "Delete"
|
||||||
|
|
||||||
#. placeholder {0}: bot.name
|
#. placeholder {0}: bot.name
|
||||||
#. placeholder {0}: group.name
|
#. placeholder {0}: group.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Delete {0}"
|
msgid "Delete {0}"
|
||||||
msgstr "Delete {0}"
|
msgstr "Delete {0}"
|
||||||
|
|
||||||
@ -2218,7 +2219,7 @@ msgid "Expand"
|
|||||||
msgstr "Expand"
|
msgstr "Expand"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Expand {0}"
|
msgid "Expand {0}"
|
||||||
msgstr "Expand {0}"
|
msgstr "Expand {0}"
|
||||||
|
|
||||||
@ -2791,7 +2792,7 @@ msgstr "Local Docker"
|
|||||||
msgid "Local Server Settings"
|
msgid "Local Server Settings"
|
||||||
msgstr "Local Server Settings"
|
msgstr "Local Server Settings"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "Log out"
|
msgstr "Log out"
|
||||||
|
|
||||||
@ -2974,7 +2975,7 @@ msgstr "Minimal"
|
|||||||
msgid "Minimize"
|
msgid "Minimize"
|
||||||
msgstr "Minimize"
|
msgstr "Minimize"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Minimize bots"
|
msgid "Minimize bots"
|
||||||
msgstr "Minimize bots"
|
msgstr "Minimize bots"
|
||||||
|
|
||||||
@ -3396,7 +3397,7 @@ msgid "Open"
|
|||||||
msgstr "Open"
|
msgstr "Open"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Open {0}"
|
msgid "Open {0}"
|
||||||
msgstr "Open {0}"
|
msgstr "Open {0}"
|
||||||
|
|
||||||
@ -3416,7 +3417,7 @@ msgstr "Open in browser"
|
|||||||
msgid "Open in full window"
|
msgid "Open in full window"
|
||||||
msgstr "Open in full window"
|
msgstr "Open in full window"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Open navigation"
|
msgid "Open navigation"
|
||||||
msgstr "Open navigation"
|
msgstr "Open navigation"
|
||||||
|
|
||||||
@ -3931,7 +3932,7 @@ msgstr "Resetting…"
|
|||||||
msgid "Restart to update"
|
msgid "Restart to update"
|
||||||
msgstr "Restart to update"
|
msgstr "Restart to update"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Restore"
|
msgid "Restore"
|
||||||
msgstr "Restore"
|
msgstr "Restore"
|
||||||
|
|
||||||
@ -4136,7 +4137,7 @@ msgid "Searching…"
|
|||||||
msgstr "Searching…"
|
msgstr "Searching…"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Select {0}"
|
msgid "Select {0}"
|
||||||
msgstr "Select {0}"
|
msgstr "Select {0}"
|
||||||
|
|
||||||
@ -4202,6 +4203,7 @@ msgstr "Set up voice"
|
|||||||
#: src/pages/MessagingSettingsOverlay.tsx
|
#: src/pages/MessagingSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Settings"
|
msgstr "Settings"
|
||||||
|
|
||||||
@ -4253,6 +4255,7 @@ msgid "Show all {0}"
|
|||||||
msgstr "Show all {0}"
|
msgstr "Show all {0}"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Show bots"
|
msgid "Show bots"
|
||||||
msgstr "Show bots"
|
msgstr "Show bots"
|
||||||
|
|
||||||
@ -4832,7 +4835,7 @@ msgstr "Upload"
|
|||||||
|
|
||||||
#: src/pages/AccountSettingsOverlay.tsx
|
#: src/pages/AccountSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Usage"
|
msgid "Usage"
|
||||||
msgstr "Usage"
|
msgstr "Usage"
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ msgstr ""
|
|||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: @lingui/cli\n"
|
"X-Generator: @lingui/cli\n"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid " (unread)"
|
msgid " (unread)"
|
||||||
msgstr " (sin leer)"
|
msgstr " (sin leer)"
|
||||||
|
|
||||||
@ -126,17 +126,17 @@ msgid "{0}, {label}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, 1:1 conversation"
|
msgid "{0}, 1:1 conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, group conversation"
|
msgid "{0}, group conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, main conversation"
|
msgid "{0}, main conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -339,6 +339,7 @@ msgstr "Confirmaciones de acción"
|
|||||||
#. placeholder {0}: sectionMenu.section.name
|
#. placeholder {0}: sectionMenu.section.name
|
||||||
#: src/pages/BotContextMenu.tsx
|
#: src/pages/BotContextMenu.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Actions for {0}"
|
msgid "Actions for {0}"
|
||||||
msgstr "Acciones para {0}"
|
msgstr "Acciones para {0}"
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ msgstr "Activo"
|
|||||||
msgid "Active model"
|
msgid "Active model"
|
||||||
msgstr "Modelo activo"
|
msgstr "Modelo activo"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Activity"
|
msgid "Activity"
|
||||||
msgstr "Actividad"
|
msgstr "Actividad"
|
||||||
|
|
||||||
@ -647,7 +648,7 @@ msgstr "Archivar"
|
|||||||
msgid "archived"
|
msgid "archived"
|
||||||
msgstr "archivado"
|
msgstr "archivado"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Archived"
|
msgid "Archived"
|
||||||
msgstr "Archivado"
|
msgstr "Archivado"
|
||||||
|
|
||||||
@ -1159,7 +1160,7 @@ msgid "Coder"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Collapse {0}"
|
msgid "Collapse {0}"
|
||||||
msgstr "Contraer {0}"
|
msgstr "Contraer {0}"
|
||||||
|
|
||||||
@ -1743,9 +1744,9 @@ msgstr "No se pudieron actualizar los avatares"
|
|||||||
msgid "Couldn't update messaging settings"
|
msgid "Couldn't update messaging settings"
|
||||||
msgstr "No se pudo actualizar la configuración de mensajería"
|
msgstr "No se pudo actualizar la configuración de mensajería"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
|
||||||
#: src/pages/shell/bot-panel.tsx
|
#: src/pages/shell/bot-panel.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr "Crear"
|
msgstr "Crear"
|
||||||
|
|
||||||
@ -1902,14 +1903,14 @@ msgstr "Alcance predeterminado"
|
|||||||
#: src/pages/KnowledgeSection.tsx
|
#: src/pages/KnowledgeSection.tsx
|
||||||
#: src/pages/McpServersOverlay.tsx
|
#: src/pages/McpServersOverlay.tsx
|
||||||
#: src/pages/RoutineEditor.tsx
|
#: src/pages/RoutineEditor.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Eliminar"
|
msgstr "Eliminar"
|
||||||
|
|
||||||
#. placeholder {0}: bot.name
|
#. placeholder {0}: bot.name
|
||||||
#. placeholder {0}: group.name
|
#. placeholder {0}: group.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Delete {0}"
|
msgid "Delete {0}"
|
||||||
msgstr "Eliminar {0}"
|
msgstr "Eliminar {0}"
|
||||||
|
|
||||||
@ -2218,7 +2219,7 @@ msgid "Expand"
|
|||||||
msgstr "Expandir"
|
msgstr "Expandir"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Expand {0}"
|
msgid "Expand {0}"
|
||||||
msgstr "Expandir {0}"
|
msgstr "Expandir {0}"
|
||||||
|
|
||||||
@ -2791,7 +2792,7 @@ msgstr ""
|
|||||||
msgid "Local Server Settings"
|
msgid "Local Server Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "Cerrar sesión"
|
msgstr "Cerrar sesión"
|
||||||
|
|
||||||
@ -2974,7 +2975,7 @@ msgstr "Mínimo"
|
|||||||
msgid "Minimize"
|
msgid "Minimize"
|
||||||
msgstr "Minimizar"
|
msgstr "Minimizar"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Minimize bots"
|
msgid "Minimize bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -3396,7 +3397,7 @@ msgid "Open"
|
|||||||
msgstr "Abrir"
|
msgstr "Abrir"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Open {0}"
|
msgid "Open {0}"
|
||||||
msgstr "Abrir {0}"
|
msgstr "Abrir {0}"
|
||||||
|
|
||||||
@ -3416,7 +3417,7 @@ msgstr ""
|
|||||||
msgid "Open in full window"
|
msgid "Open in full window"
|
||||||
msgstr "Abrir en ventana completa"
|
msgstr "Abrir en ventana completa"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Open navigation"
|
msgid "Open navigation"
|
||||||
msgstr "Abrir navegación"
|
msgstr "Abrir navegación"
|
||||||
|
|
||||||
@ -3931,7 +3932,7 @@ msgstr "Restableciendo…"
|
|||||||
msgid "Restart to update"
|
msgid "Restart to update"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Restore"
|
msgid "Restore"
|
||||||
msgstr "Restaurar"
|
msgstr "Restaurar"
|
||||||
|
|
||||||
@ -4136,7 +4137,7 @@ msgid "Searching…"
|
|||||||
msgstr "Buscando…"
|
msgstr "Buscando…"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Select {0}"
|
msgid "Select {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4202,6 +4203,7 @@ msgstr ""
|
|||||||
#: src/pages/MessagingSettingsOverlay.tsx
|
#: src/pages/MessagingSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Configuración"
|
msgstr "Configuración"
|
||||||
|
|
||||||
@ -4253,6 +4255,7 @@ msgid "Show all {0}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Show bots"
|
msgid "Show bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4832,7 +4835,7 @@ msgstr "Subir"
|
|||||||
|
|
||||||
#: src/pages/AccountSettingsOverlay.tsx
|
#: src/pages/AccountSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Usage"
|
msgid "Usage"
|
||||||
msgstr "Uso"
|
msgstr "Uso"
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ msgstr ""
|
|||||||
"Plural-Forms: \n"
|
"Plural-Forms: \n"
|
||||||
"X-Generator: @lingui/cli\n"
|
"X-Generator: @lingui/cli\n"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid " (unread)"
|
msgid " (unread)"
|
||||||
msgstr " (अपठित)"
|
msgstr " (अपठित)"
|
||||||
|
|
||||||
@ -126,17 +126,17 @@ msgid "{0}, {label}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, 1:1 conversation"
|
msgid "{0}, 1:1 conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, group conversation"
|
msgid "{0}, group conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, main conversation"
|
msgid "{0}, main conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -339,6 +339,7 @@ msgstr "कार्रवाई की पुष्टि"
|
|||||||
#. placeholder {0}: sectionMenu.section.name
|
#. placeholder {0}: sectionMenu.section.name
|
||||||
#: src/pages/BotContextMenu.tsx
|
#: src/pages/BotContextMenu.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Actions for {0}"
|
msgid "Actions for {0}"
|
||||||
msgstr "{0} के लिए कार्रवाइयां"
|
msgstr "{0} के लिए कार्रवाइयां"
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ msgstr ""
|
|||||||
msgid "Active model"
|
msgid "Active model"
|
||||||
msgstr "सक्रिय मॉडल"
|
msgstr "सक्रिय मॉडल"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Activity"
|
msgid "Activity"
|
||||||
msgstr "गतिविधि"
|
msgstr "गतिविधि"
|
||||||
|
|
||||||
@ -647,7 +648,7 @@ msgstr "आर्काइव करें"
|
|||||||
msgid "archived"
|
msgid "archived"
|
||||||
msgstr "आर्काइव किया गया"
|
msgstr "आर्काइव किया गया"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Archived"
|
msgid "Archived"
|
||||||
msgstr "आर्काइव किया गया"
|
msgstr "आर्काइव किया गया"
|
||||||
|
|
||||||
@ -1159,7 +1160,7 @@ msgid "Coder"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Collapse {0}"
|
msgid "Collapse {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -1743,9 +1744,9 @@ msgstr ""
|
|||||||
msgid "Couldn't update messaging settings"
|
msgid "Couldn't update messaging settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
|
||||||
#: src/pages/shell/bot-panel.tsx
|
#: src/pages/shell/bot-panel.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr "बनाएं"
|
msgstr "बनाएं"
|
||||||
|
|
||||||
@ -1902,14 +1903,14 @@ msgstr "डिफ़ॉल्ट स्कोप"
|
|||||||
#: src/pages/KnowledgeSection.tsx
|
#: src/pages/KnowledgeSection.tsx
|
||||||
#: src/pages/McpServersOverlay.tsx
|
#: src/pages/McpServersOverlay.tsx
|
||||||
#: src/pages/RoutineEditor.tsx
|
#: src/pages/RoutineEditor.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "डिलीट करें"
|
msgstr "डिलीट करें"
|
||||||
|
|
||||||
#. placeholder {0}: bot.name
|
#. placeholder {0}: bot.name
|
||||||
#. placeholder {0}: group.name
|
#. placeholder {0}: group.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Delete {0}"
|
msgid "Delete {0}"
|
||||||
msgstr "{0} डिलीट करें"
|
msgstr "{0} डिलीट करें"
|
||||||
|
|
||||||
@ -2218,7 +2219,7 @@ msgid "Expand"
|
|||||||
msgstr "विस्तृत करें"
|
msgstr "विस्तृत करें"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Expand {0}"
|
msgid "Expand {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -2791,7 +2792,7 @@ msgstr ""
|
|||||||
msgid "Local Server Settings"
|
msgid "Local Server Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "लॉग आउट"
|
msgstr "लॉग आउट"
|
||||||
|
|
||||||
@ -2974,7 +2975,7 @@ msgstr "न्यूनतम"
|
|||||||
msgid "Minimize"
|
msgid "Minimize"
|
||||||
msgstr "छोटा करें"
|
msgstr "छोटा करें"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Minimize bots"
|
msgid "Minimize bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -3396,7 +3397,7 @@ msgid "Open"
|
|||||||
msgstr "खोलें"
|
msgstr "खोलें"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Open {0}"
|
msgid "Open {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -3416,7 +3417,7 @@ msgstr ""
|
|||||||
msgid "Open in full window"
|
msgid "Open in full window"
|
||||||
msgstr "पूरी विंडो में खोलें"
|
msgstr "पूरी विंडो में खोलें"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Open navigation"
|
msgid "Open navigation"
|
||||||
msgstr "नेविगेशन खोलें"
|
msgstr "नेविगेशन खोलें"
|
||||||
|
|
||||||
@ -3931,7 +3932,7 @@ msgstr "रीसेट हो रहा है…"
|
|||||||
msgid "Restart to update"
|
msgid "Restart to update"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Restore"
|
msgid "Restore"
|
||||||
msgstr "बहाल करें"
|
msgstr "बहाल करें"
|
||||||
|
|
||||||
@ -4136,7 +4137,7 @@ msgid "Searching…"
|
|||||||
msgstr "खोजा जा रहा है…"
|
msgstr "खोजा जा रहा है…"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Select {0}"
|
msgid "Select {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4202,6 +4203,7 @@ msgstr ""
|
|||||||
#: src/pages/MessagingSettingsOverlay.tsx
|
#: src/pages/MessagingSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "सेटिंग्स"
|
msgstr "सेटिंग्स"
|
||||||
|
|
||||||
@ -4253,6 +4255,7 @@ msgid "Show all {0}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Show bots"
|
msgid "Show bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4832,7 +4835,7 @@ msgstr "अपलोड"
|
|||||||
|
|
||||||
#: src/pages/AccountSettingsOverlay.tsx
|
#: src/pages/AccountSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Usage"
|
msgid "Usage"
|
||||||
msgstr "उपयोग"
|
msgstr "उपयोग"
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ msgstr ""
|
|||||||
"Plural-Forms: \n"
|
"Plural-Forms: \n"
|
||||||
"X-Generator: @lingui/cli\n"
|
"X-Generator: @lingui/cli\n"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid " (unread)"
|
msgid " (unread)"
|
||||||
msgstr " (읽지 않음)"
|
msgstr " (읽지 않음)"
|
||||||
|
|
||||||
@ -126,17 +126,17 @@ msgid "{0}, {label}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, 1:1 conversation"
|
msgid "{0}, 1:1 conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, group conversation"
|
msgid "{0}, group conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, main conversation"
|
msgid "{0}, main conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -339,6 +339,7 @@ msgstr "작업 실행 전 확인"
|
|||||||
#. placeholder {0}: sectionMenu.section.name
|
#. placeholder {0}: sectionMenu.section.name
|
||||||
#: src/pages/BotContextMenu.tsx
|
#: src/pages/BotContextMenu.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Actions for {0}"
|
msgid "Actions for {0}"
|
||||||
msgstr "{0} 작업 메뉴"
|
msgstr "{0} 작업 메뉴"
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ msgstr "활성"
|
|||||||
msgid "Active model"
|
msgid "Active model"
|
||||||
msgstr "현재 모델"
|
msgstr "현재 모델"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Activity"
|
msgid "Activity"
|
||||||
msgstr "활동"
|
msgstr "활동"
|
||||||
|
|
||||||
@ -647,7 +648,7 @@ msgstr "보관"
|
|||||||
msgid "archived"
|
msgid "archived"
|
||||||
msgstr "보관됨"
|
msgstr "보관됨"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Archived"
|
msgid "Archived"
|
||||||
msgstr "보관됨"
|
msgstr "보관됨"
|
||||||
|
|
||||||
@ -1159,7 +1160,7 @@ msgid "Coder"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Collapse {0}"
|
msgid "Collapse {0}"
|
||||||
msgstr "{0} 접기"
|
msgstr "{0} 접기"
|
||||||
|
|
||||||
@ -1743,9 +1744,9 @@ msgstr "아바타를 업데이트할 수 없습니다"
|
|||||||
msgid "Couldn't update messaging settings"
|
msgid "Couldn't update messaging settings"
|
||||||
msgstr "메시징 설정을 업데이트할 수 없습니다"
|
msgstr "메시징 설정을 업데이트할 수 없습니다"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
|
||||||
#: src/pages/shell/bot-panel.tsx
|
#: src/pages/shell/bot-panel.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr "만들기"
|
msgstr "만들기"
|
||||||
|
|
||||||
@ -1902,14 +1903,14 @@ msgstr "기본 기억 범위"
|
|||||||
#: src/pages/KnowledgeSection.tsx
|
#: src/pages/KnowledgeSection.tsx
|
||||||
#: src/pages/McpServersOverlay.tsx
|
#: src/pages/McpServersOverlay.tsx
|
||||||
#: src/pages/RoutineEditor.tsx
|
#: src/pages/RoutineEditor.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "삭제"
|
msgstr "삭제"
|
||||||
|
|
||||||
#. placeholder {0}: bot.name
|
#. placeholder {0}: bot.name
|
||||||
#. placeholder {0}: group.name
|
#. placeholder {0}: group.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Delete {0}"
|
msgid "Delete {0}"
|
||||||
msgstr "{0} 삭제"
|
msgstr "{0} 삭제"
|
||||||
|
|
||||||
@ -2218,7 +2219,7 @@ msgid "Expand"
|
|||||||
msgstr "펼치기"
|
msgstr "펼치기"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Expand {0}"
|
msgid "Expand {0}"
|
||||||
msgstr "{0} 펼치기"
|
msgstr "{0} 펼치기"
|
||||||
|
|
||||||
@ -2791,7 +2792,7 @@ msgstr ""
|
|||||||
msgid "Local Server Settings"
|
msgid "Local Server Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "로그아웃"
|
msgstr "로그아웃"
|
||||||
|
|
||||||
@ -2974,7 +2975,7 @@ msgstr "최소"
|
|||||||
msgid "Minimize"
|
msgid "Minimize"
|
||||||
msgstr "최소화"
|
msgstr "최소화"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Minimize bots"
|
msgid "Minimize bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -3396,7 +3397,7 @@ msgid "Open"
|
|||||||
msgstr "열기"
|
msgstr "열기"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Open {0}"
|
msgid "Open {0}"
|
||||||
msgstr "{0} 열기"
|
msgstr "{0} 열기"
|
||||||
|
|
||||||
@ -3416,7 +3417,7 @@ msgstr ""
|
|||||||
msgid "Open in full window"
|
msgid "Open in full window"
|
||||||
msgstr "전체 창으로 열기"
|
msgstr "전체 창으로 열기"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Open navigation"
|
msgid "Open navigation"
|
||||||
msgstr "메뉴 열기"
|
msgstr "메뉴 열기"
|
||||||
|
|
||||||
@ -3931,7 +3932,7 @@ msgstr "재설정 중…"
|
|||||||
msgid "Restart to update"
|
msgid "Restart to update"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Restore"
|
msgid "Restore"
|
||||||
msgstr "복원"
|
msgstr "복원"
|
||||||
|
|
||||||
@ -4136,7 +4137,7 @@ msgid "Searching…"
|
|||||||
msgstr "검색 중…"
|
msgstr "검색 중…"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Select {0}"
|
msgid "Select {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4202,6 +4203,7 @@ msgstr ""
|
|||||||
#: src/pages/MessagingSettingsOverlay.tsx
|
#: src/pages/MessagingSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "설정"
|
msgstr "설정"
|
||||||
|
|
||||||
@ -4253,6 +4255,7 @@ msgid "Show all {0}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Show bots"
|
msgid "Show bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4832,7 +4835,7 @@ msgstr "업로드"
|
|||||||
|
|
||||||
#: src/pages/AccountSettingsOverlay.tsx
|
#: src/pages/AccountSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Usage"
|
msgid "Usage"
|
||||||
msgstr "사용량"
|
msgstr "사용량"
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ msgstr ""
|
|||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
"X-Generator: @lingui/cli\n"
|
"X-Generator: @lingui/cli\n"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid " (unread)"
|
msgid " (unread)"
|
||||||
msgstr " (não lido)"
|
msgstr " (não lido)"
|
||||||
|
|
||||||
@ -126,17 +126,17 @@ msgid "{0}, {label}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, 1:1 conversation"
|
msgid "{0}, 1:1 conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, group conversation"
|
msgid "{0}, group conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, main conversation"
|
msgid "{0}, main conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -339,6 +339,7 @@ msgstr "Confirmações de ação"
|
|||||||
#. placeholder {0}: sectionMenu.section.name
|
#. placeholder {0}: sectionMenu.section.name
|
||||||
#: src/pages/BotContextMenu.tsx
|
#: src/pages/BotContextMenu.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Actions for {0}"
|
msgid "Actions for {0}"
|
||||||
msgstr "Ações para {0}"
|
msgstr "Ações para {0}"
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ msgstr ""
|
|||||||
msgid "Active model"
|
msgid "Active model"
|
||||||
msgstr "Modelo ativo"
|
msgstr "Modelo ativo"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Activity"
|
msgid "Activity"
|
||||||
msgstr "Atividade"
|
msgstr "Atividade"
|
||||||
|
|
||||||
@ -647,7 +648,7 @@ msgstr "Arquivar"
|
|||||||
msgid "archived"
|
msgid "archived"
|
||||||
msgstr "arquivado"
|
msgstr "arquivado"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Archived"
|
msgid "Archived"
|
||||||
msgstr "Arquivado"
|
msgstr "Arquivado"
|
||||||
|
|
||||||
@ -1159,7 +1160,7 @@ msgid "Coder"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Collapse {0}"
|
msgid "Collapse {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -1743,9 +1744,9 @@ msgstr ""
|
|||||||
msgid "Couldn't update messaging settings"
|
msgid "Couldn't update messaging settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
|
||||||
#: src/pages/shell/bot-panel.tsx
|
#: src/pages/shell/bot-panel.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr "Criar"
|
msgstr "Criar"
|
||||||
|
|
||||||
@ -1902,14 +1903,14 @@ msgstr "Escopo padrão"
|
|||||||
#: src/pages/KnowledgeSection.tsx
|
#: src/pages/KnowledgeSection.tsx
|
||||||
#: src/pages/McpServersOverlay.tsx
|
#: src/pages/McpServersOverlay.tsx
|
||||||
#: src/pages/RoutineEditor.tsx
|
#: src/pages/RoutineEditor.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Excluir"
|
msgstr "Excluir"
|
||||||
|
|
||||||
#. placeholder {0}: bot.name
|
#. placeholder {0}: bot.name
|
||||||
#. placeholder {0}: group.name
|
#. placeholder {0}: group.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Delete {0}"
|
msgid "Delete {0}"
|
||||||
msgstr "Excluir {0}"
|
msgstr "Excluir {0}"
|
||||||
|
|
||||||
@ -2218,7 +2219,7 @@ msgid "Expand"
|
|||||||
msgstr "Expandir"
|
msgstr "Expandir"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Expand {0}"
|
msgid "Expand {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -2791,7 +2792,7 @@ msgstr ""
|
|||||||
msgid "Local Server Settings"
|
msgid "Local Server Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "Sair"
|
msgstr "Sair"
|
||||||
|
|
||||||
@ -2974,7 +2975,7 @@ msgstr "Mínimo"
|
|||||||
msgid "Minimize"
|
msgid "Minimize"
|
||||||
msgstr "Minimizar"
|
msgstr "Minimizar"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Minimize bots"
|
msgid "Minimize bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -3396,7 +3397,7 @@ msgid "Open"
|
|||||||
msgstr "Abrir"
|
msgstr "Abrir"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Open {0}"
|
msgid "Open {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -3416,7 +3417,7 @@ msgstr ""
|
|||||||
msgid "Open in full window"
|
msgid "Open in full window"
|
||||||
msgstr "Abrir em janela cheia"
|
msgstr "Abrir em janela cheia"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Open navigation"
|
msgid "Open navigation"
|
||||||
msgstr "Abrir a navegação"
|
msgstr "Abrir a navegação"
|
||||||
|
|
||||||
@ -3931,7 +3932,7 @@ msgstr "Redefinindo…"
|
|||||||
msgid "Restart to update"
|
msgid "Restart to update"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Restore"
|
msgid "Restore"
|
||||||
msgstr "Restaurar"
|
msgstr "Restaurar"
|
||||||
|
|
||||||
@ -4136,7 +4137,7 @@ msgid "Searching…"
|
|||||||
msgstr "Pesquisando…"
|
msgstr "Pesquisando…"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Select {0}"
|
msgid "Select {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4202,6 +4203,7 @@ msgstr ""
|
|||||||
#: src/pages/MessagingSettingsOverlay.tsx
|
#: src/pages/MessagingSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Configurações"
|
msgstr "Configurações"
|
||||||
|
|
||||||
@ -4253,6 +4255,7 @@ msgid "Show all {0}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Show bots"
|
msgid "Show bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4832,7 +4835,7 @@ msgstr "Enviar"
|
|||||||
|
|
||||||
#: src/pages/AccountSettingsOverlay.tsx
|
#: src/pages/AccountSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Usage"
|
msgid "Usage"
|
||||||
msgstr "Uso"
|
msgstr "Uso"
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ msgstr ""
|
|||||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
"X-Generator: @lingui/cli\n"
|
"X-Generator: @lingui/cli\n"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid " (unread)"
|
msgid " (unread)"
|
||||||
msgstr " (непрочитано)"
|
msgstr " (непрочитано)"
|
||||||
|
|
||||||
@ -126,17 +126,17 @@ msgid "{0}, {label}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, 1:1 conversation"
|
msgid "{0}, 1:1 conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, group conversation"
|
msgid "{0}, group conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, main conversation"
|
msgid "{0}, main conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -339,6 +339,7 @@ msgstr "Подтверждения действий"
|
|||||||
#. placeholder {0}: sectionMenu.section.name
|
#. placeholder {0}: sectionMenu.section.name
|
||||||
#: src/pages/BotContextMenu.tsx
|
#: src/pages/BotContextMenu.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Actions for {0}"
|
msgid "Actions for {0}"
|
||||||
msgstr "Действия для {0}"
|
msgstr "Действия для {0}"
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ msgstr "Активный"
|
|||||||
msgid "Active model"
|
msgid "Active model"
|
||||||
msgstr "Активная модель"
|
msgstr "Активная модель"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Activity"
|
msgid "Activity"
|
||||||
msgstr "Активность"
|
msgstr "Активность"
|
||||||
|
|
||||||
@ -647,7 +648,7 @@ msgstr "Архивировать"
|
|||||||
msgid "archived"
|
msgid "archived"
|
||||||
msgstr "в архиве"
|
msgstr "в архиве"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Archived"
|
msgid "Archived"
|
||||||
msgstr "В архиве"
|
msgstr "В архиве"
|
||||||
|
|
||||||
@ -1159,7 +1160,7 @@ msgid "Coder"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Collapse {0}"
|
msgid "Collapse {0}"
|
||||||
msgstr "Свернуть {0}"
|
msgstr "Свернуть {0}"
|
||||||
|
|
||||||
@ -1743,9 +1744,9 @@ msgstr "Не удалось обновить аватары"
|
|||||||
msgid "Couldn't update messaging settings"
|
msgid "Couldn't update messaging settings"
|
||||||
msgstr "Не удалось обновить настройки обмена сообщениями."
|
msgstr "Не удалось обновить настройки обмена сообщениями."
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
|
||||||
#: src/pages/shell/bot-panel.tsx
|
#: src/pages/shell/bot-panel.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr "Создать"
|
msgstr "Создать"
|
||||||
|
|
||||||
@ -1902,14 +1903,14 @@ msgstr "Область действия по умолчанию"
|
|||||||
#: src/pages/KnowledgeSection.tsx
|
#: src/pages/KnowledgeSection.tsx
|
||||||
#: src/pages/McpServersOverlay.tsx
|
#: src/pages/McpServersOverlay.tsx
|
||||||
#: src/pages/RoutineEditor.tsx
|
#: src/pages/RoutineEditor.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Удалить"
|
msgstr "Удалить"
|
||||||
|
|
||||||
#. placeholder {0}: bot.name
|
#. placeholder {0}: bot.name
|
||||||
#. placeholder {0}: group.name
|
#. placeholder {0}: group.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Delete {0}"
|
msgid "Delete {0}"
|
||||||
msgstr "Удалить {0}"
|
msgstr "Удалить {0}"
|
||||||
|
|
||||||
@ -2218,7 +2219,7 @@ msgid "Expand"
|
|||||||
msgstr "Развернуть"
|
msgstr "Развернуть"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Expand {0}"
|
msgid "Expand {0}"
|
||||||
msgstr "Развернуть {0}"
|
msgstr "Развернуть {0}"
|
||||||
|
|
||||||
@ -2791,7 +2792,7 @@ msgstr ""
|
|||||||
msgid "Local Server Settings"
|
msgid "Local Server Settings"
|
||||||
msgstr "Настройки локального сервера"
|
msgstr "Настройки локального сервера"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "Выйти"
|
msgstr "Выйти"
|
||||||
|
|
||||||
@ -2974,7 +2975,7 @@ msgstr "Минимальный"
|
|||||||
msgid "Minimize"
|
msgid "Minimize"
|
||||||
msgstr "Свернуть"
|
msgstr "Свернуть"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Minimize bots"
|
msgid "Minimize bots"
|
||||||
msgstr "Свернуть ботов"
|
msgstr "Свернуть ботов"
|
||||||
|
|
||||||
@ -3396,7 +3397,7 @@ msgid "Open"
|
|||||||
msgstr "Открыть"
|
msgstr "Открыть"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Open {0}"
|
msgid "Open {0}"
|
||||||
msgstr "Открыть {0}"
|
msgstr "Открыть {0}"
|
||||||
|
|
||||||
@ -3416,7 +3417,7 @@ msgstr ""
|
|||||||
msgid "Open in full window"
|
msgid "Open in full window"
|
||||||
msgstr "Открыть в полном окне"
|
msgstr "Открыть в полном окне"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Open navigation"
|
msgid "Open navigation"
|
||||||
msgstr "Открыть навигацию"
|
msgstr "Открыть навигацию"
|
||||||
|
|
||||||
@ -3931,7 +3932,7 @@ msgstr "Сброс…"
|
|||||||
msgid "Restart to update"
|
msgid "Restart to update"
|
||||||
msgstr "Перезапустить для обновления"
|
msgstr "Перезапустить для обновления"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Restore"
|
msgid "Restore"
|
||||||
msgstr "Восстановить"
|
msgstr "Восстановить"
|
||||||
|
|
||||||
@ -4136,7 +4137,7 @@ msgid "Searching…"
|
|||||||
msgstr "Поиск…"
|
msgstr "Поиск…"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Select {0}"
|
msgid "Select {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4202,6 +4203,7 @@ msgstr ""
|
|||||||
#: src/pages/MessagingSettingsOverlay.tsx
|
#: src/pages/MessagingSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Настройки"
|
msgstr "Настройки"
|
||||||
|
|
||||||
@ -4253,6 +4255,7 @@ msgid "Show all {0}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Show bots"
|
msgid "Show bots"
|
||||||
msgstr "Показать ботов"
|
msgstr "Показать ботов"
|
||||||
|
|
||||||
@ -4832,7 +4835,7 @@ msgstr "Загрузить"
|
|||||||
|
|
||||||
#: src/pages/AccountSettingsOverlay.tsx
|
#: src/pages/AccountSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Usage"
|
msgid "Usage"
|
||||||
msgstr "Использование"
|
msgstr "Использование"
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ msgstr ""
|
|||||||
"Plural-Forms: \n"
|
"Plural-Forms: \n"
|
||||||
"X-Generator: @lingui/cli\n"
|
"X-Generator: @lingui/cli\n"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid " (unread)"
|
msgid " (unread)"
|
||||||
msgstr " (okunmadı)"
|
msgstr " (okunmadı)"
|
||||||
|
|
||||||
@ -126,17 +126,17 @@ msgid "{0}, {label}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, 1:1 conversation"
|
msgid "{0}, 1:1 conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, group conversation"
|
msgid "{0}, group conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, main conversation"
|
msgid "{0}, main conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -339,6 +339,7 @@ msgstr "İşlem onayları"
|
|||||||
#. placeholder {0}: sectionMenu.section.name
|
#. placeholder {0}: sectionMenu.section.name
|
||||||
#: src/pages/BotContextMenu.tsx
|
#: src/pages/BotContextMenu.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Actions for {0}"
|
msgid "Actions for {0}"
|
||||||
msgstr "{0} için işlemler"
|
msgstr "{0} için işlemler"
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ msgstr ""
|
|||||||
msgid "Active model"
|
msgid "Active model"
|
||||||
msgstr "Etkin model"
|
msgstr "Etkin model"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Activity"
|
msgid "Activity"
|
||||||
msgstr "Etkinlik"
|
msgstr "Etkinlik"
|
||||||
|
|
||||||
@ -647,7 +648,7 @@ msgstr "Arşivle"
|
|||||||
msgid "archived"
|
msgid "archived"
|
||||||
msgstr "arşivlendi"
|
msgstr "arşivlendi"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Archived"
|
msgid "Archived"
|
||||||
msgstr "Arşivlendi"
|
msgstr "Arşivlendi"
|
||||||
|
|
||||||
@ -1159,7 +1160,7 @@ msgid "Coder"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Collapse {0}"
|
msgid "Collapse {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -1743,9 +1744,9 @@ msgstr ""
|
|||||||
msgid "Couldn't update messaging settings"
|
msgid "Couldn't update messaging settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
|
||||||
#: src/pages/shell/bot-panel.tsx
|
#: src/pages/shell/bot-panel.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr "Oluştur"
|
msgstr "Oluştur"
|
||||||
|
|
||||||
@ -1902,14 +1903,14 @@ msgstr "Varsayılan kapsam"
|
|||||||
#: src/pages/KnowledgeSection.tsx
|
#: src/pages/KnowledgeSection.tsx
|
||||||
#: src/pages/McpServersOverlay.tsx
|
#: src/pages/McpServersOverlay.tsx
|
||||||
#: src/pages/RoutineEditor.tsx
|
#: src/pages/RoutineEditor.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Sil"
|
msgstr "Sil"
|
||||||
|
|
||||||
#. placeholder {0}: bot.name
|
#. placeholder {0}: bot.name
|
||||||
#. placeholder {0}: group.name
|
#. placeholder {0}: group.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Delete {0}"
|
msgid "Delete {0}"
|
||||||
msgstr "{0} sil"
|
msgstr "{0} sil"
|
||||||
|
|
||||||
@ -2218,7 +2219,7 @@ msgid "Expand"
|
|||||||
msgstr "Genişlet"
|
msgstr "Genişlet"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Expand {0}"
|
msgid "Expand {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -2791,7 +2792,7 @@ msgstr ""
|
|||||||
msgid "Local Server Settings"
|
msgid "Local Server Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "Çıkış yap"
|
msgstr "Çıkış yap"
|
||||||
|
|
||||||
@ -2974,7 +2975,7 @@ msgstr "Minimal"
|
|||||||
msgid "Minimize"
|
msgid "Minimize"
|
||||||
msgstr "Küçült"
|
msgstr "Küçült"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Minimize bots"
|
msgid "Minimize bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -3396,7 +3397,7 @@ msgid "Open"
|
|||||||
msgstr "Aç"
|
msgstr "Aç"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Open {0}"
|
msgid "Open {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -3416,7 +3417,7 @@ msgstr ""
|
|||||||
msgid "Open in full window"
|
msgid "Open in full window"
|
||||||
msgstr "Tam pencerede aç"
|
msgstr "Tam pencerede aç"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Open navigation"
|
msgid "Open navigation"
|
||||||
msgstr "Gezinmeyi aç"
|
msgstr "Gezinmeyi aç"
|
||||||
|
|
||||||
@ -3931,7 +3932,7 @@ msgstr ""
|
|||||||
msgid "Restart to update"
|
msgid "Restart to update"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Restore"
|
msgid "Restore"
|
||||||
msgstr "Geri yükle"
|
msgstr "Geri yükle"
|
||||||
|
|
||||||
@ -4136,7 +4137,7 @@ msgid "Searching…"
|
|||||||
msgstr "Aranıyor…"
|
msgstr "Aranıyor…"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Select {0}"
|
msgid "Select {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4202,6 +4203,7 @@ msgstr ""
|
|||||||
#: src/pages/MessagingSettingsOverlay.tsx
|
#: src/pages/MessagingSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Ayarlar"
|
msgstr "Ayarlar"
|
||||||
|
|
||||||
@ -4253,6 +4255,7 @@ msgid "Show all {0}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Show bots"
|
msgid "Show bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4832,7 +4835,7 @@ msgstr "Yükle"
|
|||||||
|
|
||||||
#: src/pages/AccountSettingsOverlay.tsx
|
#: src/pages/AccountSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Usage"
|
msgid "Usage"
|
||||||
msgstr "Kullanım"
|
msgstr "Kullanım"
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ msgstr ""
|
|||||||
"Plural-Forms: \n"
|
"Plural-Forms: \n"
|
||||||
"X-Generator: @lingui/cli\n"
|
"X-Generator: @lingui/cli\n"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid " (unread)"
|
msgid " (unread)"
|
||||||
msgstr "(未读)"
|
msgstr "(未读)"
|
||||||
|
|
||||||
@ -126,17 +126,17 @@ msgid "{0}, {label}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, 1:1 conversation"
|
msgid "{0}, 1:1 conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, group conversation"
|
msgid "{0}, group conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: item.chat.name
|
#. placeholder {0}: item.chat.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/roster-rows.tsx
|
||||||
msgid "{0}, main conversation"
|
msgid "{0}, main conversation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -339,6 +339,7 @@ msgstr "操作确认"
|
|||||||
#. placeholder {0}: sectionMenu.section.name
|
#. placeholder {0}: sectionMenu.section.name
|
||||||
#: src/pages/BotContextMenu.tsx
|
#: src/pages/BotContextMenu.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Actions for {0}"
|
msgid "Actions for {0}"
|
||||||
msgstr "{0} 的操作"
|
msgstr "{0} 的操作"
|
||||||
|
|
||||||
@ -354,7 +355,7 @@ msgstr "启用"
|
|||||||
msgid "Active model"
|
msgid "Active model"
|
||||||
msgstr "当前模型"
|
msgstr "当前模型"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Activity"
|
msgid "Activity"
|
||||||
msgstr "动态"
|
msgstr "动态"
|
||||||
|
|
||||||
@ -647,7 +648,7 @@ msgstr "归档"
|
|||||||
msgid "archived"
|
msgid "archived"
|
||||||
msgstr "已归档"
|
msgstr "已归档"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Archived"
|
msgid "Archived"
|
||||||
msgstr "已归档"
|
msgstr "已归档"
|
||||||
|
|
||||||
@ -1159,7 +1160,7 @@ msgid "Coder"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Collapse {0}"
|
msgid "Collapse {0}"
|
||||||
msgstr "折叠 {0}"
|
msgstr "折叠 {0}"
|
||||||
|
|
||||||
@ -1743,9 +1744,9 @@ msgstr "无法更新头像"
|
|||||||
msgid "Couldn't update messaging settings"
|
msgid "Couldn't update messaging settings"
|
||||||
msgstr "无法更新消息设置"
|
msgstr "无法更新消息设置"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
|
||||||
#: src/pages/shell/bot-panel.tsx
|
#: src/pages/shell/bot-panel.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
|
#: src/pages/shell/sidebar-header.tsx
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr "创建"
|
msgstr "创建"
|
||||||
|
|
||||||
@ -1902,14 +1903,14 @@ msgstr "默认范围"
|
|||||||
#: src/pages/KnowledgeSection.tsx
|
#: src/pages/KnowledgeSection.tsx
|
||||||
#: src/pages/McpServersOverlay.tsx
|
#: src/pages/McpServersOverlay.tsx
|
||||||
#: src/pages/RoutineEditor.tsx
|
#: src/pages/RoutineEditor.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
#: src/pages/shell/dialogs.tsx
|
#: src/pages/shell/dialogs.tsx
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "删除"
|
msgstr "删除"
|
||||||
|
|
||||||
#. placeholder {0}: bot.name
|
#. placeholder {0}: bot.name
|
||||||
#. placeholder {0}: group.name
|
#. placeholder {0}: group.name
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Delete {0}"
|
msgid "Delete {0}"
|
||||||
msgstr "删除 {0}"
|
msgstr "删除 {0}"
|
||||||
|
|
||||||
@ -2218,7 +2219,7 @@ msgid "Expand"
|
|||||||
msgstr "展开"
|
msgstr "展开"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Expand {0}"
|
msgid "Expand {0}"
|
||||||
msgstr "展开 {0}"
|
msgstr "展开 {0}"
|
||||||
|
|
||||||
@ -2791,7 +2792,7 @@ msgstr ""
|
|||||||
msgid "Local Server Settings"
|
msgid "Local Server Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "退出登录"
|
msgstr "退出登录"
|
||||||
|
|
||||||
@ -2974,7 +2975,7 @@ msgstr "最低"
|
|||||||
msgid "Minimize"
|
msgid "Minimize"
|
||||||
msgstr "最小化"
|
msgstr "最小化"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Minimize bots"
|
msgid "Minimize bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -3396,7 +3397,7 @@ msgid "Open"
|
|||||||
msgstr "打开"
|
msgstr "打开"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Open {0}"
|
msgid "Open {0}"
|
||||||
msgstr "打开 {0}"
|
msgstr "打开 {0}"
|
||||||
|
|
||||||
@ -3416,7 +3417,7 @@ msgstr ""
|
|||||||
msgid "Open in full window"
|
msgid "Open in full window"
|
||||||
msgstr "在完整窗口中打开"
|
msgstr "在完整窗口中打开"
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Open navigation"
|
msgid "Open navigation"
|
||||||
msgstr "打开导航"
|
msgstr "打开导航"
|
||||||
|
|
||||||
@ -3931,7 +3932,7 @@ msgstr "正在重置…"
|
|||||||
msgid "Restart to update"
|
msgid "Restart to update"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/archived-section.tsx
|
||||||
msgid "Restore"
|
msgid "Restore"
|
||||||
msgstr "恢复"
|
msgstr "恢复"
|
||||||
|
|
||||||
@ -4136,7 +4137,7 @@ msgid "Searching…"
|
|||||||
msgstr "正在搜索…"
|
msgstr "正在搜索…"
|
||||||
|
|
||||||
#. placeholder {0}: group.title
|
#. placeholder {0}: group.title
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/sidebar-group-header.tsx
|
||||||
msgid "Select {0}"
|
msgid "Select {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4202,6 +4203,7 @@ msgstr ""
|
|||||||
#: src/pages/MessagingSettingsOverlay.tsx
|
#: src/pages/MessagingSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "设置"
|
msgstr "设置"
|
||||||
|
|
||||||
@ -4253,6 +4255,7 @@ msgid "Show all {0}"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/Shell.tsx
|
||||||
|
#: src/pages/shell/sidebar-toggle-buttons.tsx
|
||||||
msgid "Show bots"
|
msgid "Show bots"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4832,7 +4835,7 @@ msgstr "上传"
|
|||||||
|
|
||||||
#: src/pages/AccountSettingsOverlay.tsx
|
#: src/pages/AccountSettingsOverlay.tsx
|
||||||
#: src/pages/SettingsOverlay.tsx
|
#: src/pages/SettingsOverlay.tsx
|
||||||
#: src/pages/Shell.tsx
|
#: src/pages/shell/user-menu.tsx
|
||||||
msgid "Usage"
|
msgid "Usage"
|
||||||
msgstr "用量"
|
msgstr "用量"
|
||||||
|
|
||||||
|
|||||||
@ -84,25 +84,13 @@ import {
|
|||||||
Popover,
|
Popover,
|
||||||
PopoverContent,
|
PopoverContent,
|
||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
Wordmark,
|
|
||||||
} from "@rakazo/ui-web";
|
} from "@rakazo/ui-web";
|
||||||
import {
|
import {
|
||||||
ArrowLeft,
|
ArrowLeft,
|
||||||
Bell,
|
|
||||||
Calendar,
|
Calendar,
|
||||||
ChevronDown,
|
|
||||||
Folder,
|
|
||||||
Gauge,
|
|
||||||
Globe,
|
Globe,
|
||||||
GripVertical,
|
|
||||||
LayoutGrid,
|
LayoutGrid,
|
||||||
Lock,
|
|
||||||
LogOut,
|
|
||||||
Maximize2,
|
Maximize2,
|
||||||
Menu,
|
|
||||||
MoreHorizontal,
|
|
||||||
PanelLeftClose,
|
|
||||||
PanelLeftOpen,
|
|
||||||
PanelRight,
|
PanelRight,
|
||||||
Pencil,
|
Pencil,
|
||||||
Plus,
|
Plus,
|
||||||
@ -140,7 +128,7 @@ import { TeachRecordingChrome, TeachStopButton } from "../components/teach/Teach
|
|||||||
import { useSidebarResize } from "../hooks/useSidebarResize";
|
import { useSidebarResize } from "../hooks/useSidebarResize";
|
||||||
import { useWideLayout } from "../hooks/useWideLayout";
|
import { useWideLayout } from "../hooks/useWideLayout";
|
||||||
import { readActivityMode, writeActivityMode } from "../lib/activity-mode";
|
import { readActivityMode, writeActivityMode } from "../lib/activity-mode";
|
||||||
import { needsYouChipLabel, rosterActivitySubtitle, rosterStatusDot } from "../lib/agent-activity";
|
import { rosterActivitySubtitle } from "../lib/agent-activity";
|
||||||
import { agentPointerFeed } from "../lib/agent-pointer";
|
import { agentPointerFeed } from "../lib/agent-pointer";
|
||||||
import type { ArtifactTarget } from "../lib/artifact-open";
|
import type { ArtifactTarget } from "../lib/artifact-open";
|
||||||
import { attachmentMaxBytes, uploadAttachment } from "../lib/artifact-upload";
|
import { attachmentMaxBytes, uploadAttachment } from "../lib/artifact-upload";
|
||||||
@ -157,7 +145,6 @@ import {
|
|||||||
shouldNotifyBrowser,
|
shouldNotifyBrowser,
|
||||||
} from "../lib/browser-notifications";
|
} from "../lib/browser-notifications";
|
||||||
import { loadComputerScreen } from "../lib/computer-screen";
|
import { loadComputerScreen } from "../lib/computer-screen";
|
||||||
import { desktopBridge } from "../lib/desktop";
|
|
||||||
import { scheduleFocusPrompt } from "../lib/focus-prompt";
|
import { scheduleFocusPrompt } from "../lib/focus-prompt";
|
||||||
import { formatBytes } from "../lib/format-bytes";
|
import { formatBytes } from "../lib/format-bytes";
|
||||||
import {
|
import {
|
||||||
@ -216,8 +203,9 @@ import {
|
|||||||
} from "./RoutineEditor";
|
} from "./RoutineEditor";
|
||||||
import type { SettingsSection } from "./SettingsOverlay";
|
import type { SettingsSection } from "./SettingsOverlay";
|
||||||
import { SpaceSearchResults } from "./SpaceSearch";
|
import { SpaceSearchResults } from "./SpaceSearch";
|
||||||
|
import { ArchivedSection } from "./shell/archived-section";
|
||||||
import { BotSettings, CreateBotForm } from "./shell/bot-panel";
|
import { BotSettings, CreateBotForm } from "./shell/bot-panel";
|
||||||
import { BotCreatePicker, ConversationBotPicker } from "./shell/bot-picker";
|
import { ConversationBotPicker } from "./shell/bot-picker";
|
||||||
import {
|
import {
|
||||||
collapsedSidebarSectionsStorageKey,
|
collapsedSidebarSectionsStorageKey,
|
||||||
readCollapsedSidebarSections,
|
readCollapsedSidebarSections,
|
||||||
@ -243,15 +231,13 @@ import {
|
|||||||
} from "./shell/dialogs";
|
} from "./shell/dialogs";
|
||||||
import { MainConversationRow } from "./shell/main-conversation-row";
|
import { MainConversationRow } from "./shell/main-conversation-row";
|
||||||
import { cleanRosterPreview, formatRosterTime, stripSpaceTitlePrefix } from "./shell/roster-format";
|
import { cleanRosterPreview, formatRosterTime, stripSpaceTitlePrefix } from "./shell/roster-format";
|
||||||
import {
|
import { rosterRowClass } from "./shell/roster-row-style";
|
||||||
rosterNameClass,
|
import { ProjectRosterRow, TeamRosterRow } from "./shell/roster-rows";
|
||||||
rosterPreviewClass,
|
|
||||||
rosterRowClass,
|
|
||||||
rosterTimeClass,
|
|
||||||
rosterUnreadDotClass,
|
|
||||||
} from "./shell/roster-row-style";
|
|
||||||
import type { PendingAttachment } from "./shell/shell-types";
|
import type { PendingAttachment } from "./shell/shell-types";
|
||||||
import { FALLBACK_BOT_COLOR } from "./shell/shell-types";
|
import { FALLBACK_BOT_COLOR } from "./shell/shell-types";
|
||||||
|
import { SidebarGroupHeader } from "./shell/sidebar-group-header";
|
||||||
|
import { SidebarHeader } from "./shell/sidebar-header";
|
||||||
|
import { SidebarToggleButtons } from "./shell/sidebar-toggle-buttons";
|
||||||
import {
|
import {
|
||||||
applyThreadEvent,
|
applyThreadEvent,
|
||||||
firstThreadRoute,
|
firstThreadRoute,
|
||||||
@ -259,7 +245,7 @@ import {
|
|||||||
threadSnapshotSignal,
|
threadSnapshotSignal,
|
||||||
} from "./shell/thread-state";
|
} from "./shell/thread-state";
|
||||||
import { Transcript } from "./shell/transcript";
|
import { Transcript } from "./shell/transcript";
|
||||||
import { WindowChrome } from "./WindowChrome";
|
import { UserMenu } from "./shell/user-menu";
|
||||||
|
|
||||||
const BotContextMenu = lazyWithRecovery("BotContextMenu", () =>
|
const BotContextMenu = lazyWithRecovery("BotContextMenu", () =>
|
||||||
import("./BotContextMenu").then((module) => ({ default: module.BotContextMenu })),
|
import("./BotContextMenu").then((module) => ({ default: module.BotContextMenu })),
|
||||||
@ -326,7 +312,7 @@ function voiceStatusRefreshTimeout(): Promise<never> {
|
|||||||
|
|
||||||
export type NavPillar = "heute" | "team" | "projekte";
|
export type NavPillar = "heute" | "team" | "projekte";
|
||||||
|
|
||||||
import { ProjectDragGrip, SortableGroup } from "../components/SortableGroup";
|
import { SortableGroup } from "../components/SortableGroup";
|
||||||
|
|
||||||
export function ShellPage() {
|
export function ShellPage() {
|
||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
@ -3384,85 +3370,20 @@ export function ShellPage() {
|
|||||||
onPointerDown={startResizingLeft}
|
onPointerDown={startResizingLeft}
|
||||||
className="absolute -right-2 top-0 bottom-0 w-4 cursor-col-resize z-50 hidden md:block"
|
className="absolute -right-2 top-0 bottom-0 w-4 cursor-col-resize z-50 hidden md:block"
|
||||||
/>
|
/>
|
||||||
<div className="app-drag flex items-center justify-between px-4 lg:px-6 2xl:px-8 pb-3 pt-4">
|
<SidebarHeader
|
||||||
<WindowChrome />
|
activityMode={activityMode}
|
||||||
<div className="flex-1 px-1">
|
onToggleActivityMode={toggleActivityMode}
|
||||||
<Wordmark />
|
createMenuOpen={createMenuOpen}
|
||||||
</div>
|
onCreateMenuOpenChange={setCreateMenuOpen}
|
||||||
<div className="relative flex items-center gap-2.5">
|
onCloseMobileSidebar={() => setMobileSidebarOpen(false)}
|
||||||
<button
|
bots={bots}
|
||||||
type="button"
|
onCreateBot={() => setPanel("create")}
|
||||||
aria-label={t`Activity`}
|
onOpenBot={(id) => navigate(`/app/${id}`)}
|
||||||
aria-pressed={activityMode}
|
onCreateGroup={() => setPanel("create-group")}
|
||||||
title={t`Activity`}
|
onCreateSpace={() => openNewSpaceDialog("space")}
|
||||||
data-activity-mode={activityMode ? "on" : "off"}
|
onShowGroupInfo={() => setPickerInfoTopic("group")}
|
||||||
onClick={toggleActivityMode}
|
onShowSpaceInfo={() => setPickerInfoTopic("space")}
|
||||||
className={`app-no-drag flex size-control-sm items-center justify-center rounded-full ${
|
/>
|
||||||
activityMode
|
|
||||||
? "bg-primary text-primary-foreground"
|
|
||||||
: "rk-sidebar-muted hover:text-foreground/75"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<Bell
|
|
||||||
strokeWidth={1.8}
|
|
||||||
fill={activityMode ? "currentColor" : "none"}
|
|
||||||
aria-hidden="true"
|
|
||||||
className="size-icon-md"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<Popover open={createMenuOpen} onOpenChange={setCreateMenuOpen}>
|
|
||||||
<PopoverTrigger
|
|
||||||
className="app-no-drag text-[21px] rk-sidebar-muted hover:text-foreground/75"
|
|
||||||
title={t`Create`}
|
|
||||||
data-testid="create-menu-trigger"
|
|
||||||
>
|
|
||||||
+
|
|
||||||
</PopoverTrigger>
|
|
||||||
{/* Unmount with the state change so the panel it opens never coexists with the menu. */}
|
|
||||||
{createMenuOpen ? (
|
|
||||||
<PopoverContent
|
|
||||||
align="end"
|
|
||||||
className="app-no-drag w-auto gap-0 overflow-hidden p-0 data-closed:animate-none"
|
|
||||||
>
|
|
||||||
<BotCreatePicker
|
|
||||||
bots={bots}
|
|
||||||
onCreateBot={() => {
|
|
||||||
setCreateMenuOpen(false);
|
|
||||||
setMobileSidebarOpen(false);
|
|
||||||
setPanel("create");
|
|
||||||
}}
|
|
||||||
onOpenBot={(id) => {
|
|
||||||
setCreateMenuOpen(false);
|
|
||||||
setMobileSidebarOpen(false);
|
|
||||||
navigate(`/app/${id}`);
|
|
||||||
}}
|
|
||||||
onCreateGroup={() => {
|
|
||||||
setCreateMenuOpen(false);
|
|
||||||
setMobileSidebarOpen(false);
|
|
||||||
setPanel("create-group");
|
|
||||||
}}
|
|
||||||
onCreateSpace={() => {
|
|
||||||
setCreateMenuOpen(false);
|
|
||||||
setMobileSidebarOpen(false);
|
|
||||||
openNewSpaceDialog("space");
|
|
||||||
}}
|
|
||||||
onShowGroupInfo={() => {
|
|
||||||
setCreateMenuOpen(false);
|
|
||||||
setMobileSidebarOpen(false);
|
|
||||||
setPickerInfoTopic("group");
|
|
||||||
}}
|
|
||||||
onShowSpaceInfo={() => {
|
|
||||||
setCreateMenuOpen(false);
|
|
||||||
setMobileSidebarOpen(false);
|
|
||||||
setPickerInfoTopic("space");
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</PopoverContent>
|
|
||||||
) : null}
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<InputGroup
|
<InputGroup
|
||||||
data-testid="sidebar-search"
|
data-testid="sidebar-search"
|
||||||
@ -3598,229 +3519,41 @@ export function ShellPage() {
|
|||||||
return (
|
return (
|
||||||
<div key={group.key} data-sidebar-group={group.key}>
|
<div key={group.key} data-sidebar-group={group.key}>
|
||||||
{group.title ? (
|
{group.title ? (
|
||||||
<div className="flex items-center pt-3 pb-0.5">
|
<SidebarGroupHeader
|
||||||
<button
|
variant="conversation"
|
||||||
type="button"
|
group={group}
|
||||||
className="flex min-w-0 flex-1 items-center justify-between gap-2 rounded-lg px-2.5 py-1 text-ui-label font-semibold tracking-wider uppercase text-foreground/65 dark:text-muted-foreground/80 hover:text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring"
|
collapsed={collapsed}
|
||||||
onClick={() => {
|
activeSpaceId={bootstrapMe?.spaceId}
|
||||||
if (group.emptySpaceId) {
|
botSections={botSections}
|
||||||
openSpaceChat(group.emptySpaceId, "/onboarding");
|
spaces={spaces}
|
||||||
return;
|
onOpenEmptySpace={(spaceId) => openSpaceChat(spaceId, "/onboarding")}
|
||||||
}
|
onToggle={toggleSidebarSection}
|
||||||
toggleSidebarSection(group.key);
|
sectionMenuAnchor={sectionMenuAnchor}
|
||||||
}}
|
onSectionMenu={setSectionMenu}
|
||||||
onContextMenu={
|
spaceMenuAnchor={spaceMenuAnchor}
|
||||||
group.sectionId
|
onSpaceMenu={setSpaceMenu}
|
||||||
? (event) => {
|
/>
|
||||||
event.preventDefault();
|
|
||||||
// Prefer section rename over delete-space when both apply;
|
|
||||||
// the dedicated space-actions button still opens the space menu.
|
|
||||||
const sections =
|
|
||||||
group.spaceId === bootstrapMe?.spaceId
|
|
||||||
? botSections
|
|
||||||
: (spaces.find((space) => space.id === group.spaceId)
|
|
||||||
?.botSections ?? []);
|
|
||||||
const section = sections.find(
|
|
||||||
(item) => item.id === group.sectionId,
|
|
||||||
);
|
|
||||||
if (!section) return;
|
|
||||||
sectionMenuAnchor.current = event.currentTarget;
|
|
||||||
setSectionMenu({
|
|
||||||
section,
|
|
||||||
spaceId: group.spaceId,
|
|
||||||
position: { x: event.clientX, y: event.clientY },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
: group.canDeleteSpace
|
|
||||||
? (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
spaceMenuAnchor.current = event.currentTarget;
|
|
||||||
setSpaceMenu({
|
|
||||||
id: group.spaceId,
|
|
||||||
position: { x: event.clientX, y: event.clientY },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
aria-expanded={group.emptySpaceId ? undefined : !collapsed}
|
|
||||||
aria-label={
|
|
||||||
group.emptySpaceId
|
|
||||||
? t`Open ${group.title}`
|
|
||||||
: collapsed
|
|
||||||
? t`Expand ${group.title}`
|
|
||||||
: t`Collapse ${group.title}`
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span className="flex min-w-0 items-center gap-1.5 truncate">
|
|
||||||
<Folder strokeWidth={2} aria-hidden="true" className="size-icon-sm" />
|
|
||||||
<span className="truncate">{group.title}</span>
|
|
||||||
</span>
|
|
||||||
{group.emptySpaceId ? null : (
|
|
||||||
<ChevronDown
|
|
||||||
strokeWidth={1.8}
|
|
||||||
className={`size-icon-md ${collapsed ? "-rotate-90 transition-transform" : "transition-transform"}`}
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
{group.canDeleteSpace ? (
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon-sm"
|
|
||||||
aria-label={t`Actions for ${group.spaceName}`}
|
|
||||||
onClick={(event) => {
|
|
||||||
const rect = event.currentTarget.getBoundingClientRect();
|
|
||||||
spaceMenuAnchor.current = event.currentTarget;
|
|
||||||
setSpaceMenu({
|
|
||||||
id: group.spaceId,
|
|
||||||
position: { x: rect.left, y: rect.bottom },
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MoreHorizontal aria-hidden="true" className="size-icon-md" />
|
|
||||||
</Button>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
) : null}
|
) : null}
|
||||||
{!collapsed &&
|
{!collapsed &&
|
||||||
group.bots
|
group.bots
|
||||||
.slice(0, expandedTeamGroups[group.key] ? undefined : 4)
|
.slice(0, expandedTeamGroups[group.key] ? undefined : 4)
|
||||||
.map((item) => (
|
.map((item) => (
|
||||||
<button
|
<TeamRosterRow
|
||||||
key={`${item.kind}:${item.chat.id}`}
|
key={`${item.kind}:${item.chat.id}`}
|
||||||
type="button"
|
item={item}
|
||||||
draggable={item.kind === "bot"}
|
groupBotIds={groupBotIds}
|
||||||
data-roster-bot-id={item.kind === "bot" ? item.chat.id : undefined}
|
draggedBotId={draggedBotId}
|
||||||
aria-keyshortcuts={
|
onDraggedBotIdChange={setDraggedBotId}
|
||||||
item.kind === "bot" ? "Alt+ArrowUp Alt+ArrowDown" : undefined
|
onReorder={reorderRosterBot}
|
||||||
}
|
selected={!inGroup && active?.id === item.chat.id}
|
||||||
onDragStart={(event) => {
|
onOpen={() => {
|
||||||
if (item.kind !== "bot") return;
|
|
||||||
setDraggedBotId(item.chat.id);
|
|
||||||
event.dataTransfer.effectAllowed = "move";
|
|
||||||
event.dataTransfer.setData("text/plain", item.chat.id);
|
|
||||||
}}
|
|
||||||
onDragOver={(event) => {
|
|
||||||
if (
|
|
||||||
item.kind === "bot" &&
|
|
||||||
draggedBotId &&
|
|
||||||
groupBotIds.includes(draggedBotId)
|
|
||||||
) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.dataTransfer.dropEffect = "move";
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onDrop={(event) => {
|
|
||||||
if (item.kind !== "bot" || !draggedBotId) return;
|
|
||||||
event.preventDefault();
|
|
||||||
reorderRosterBot(draggedBotId, item.chat.id, groupBotIds);
|
|
||||||
setDraggedBotId(null);
|
|
||||||
}}
|
|
||||||
onDragEnd={() => setDraggedBotId(null)}
|
|
||||||
onKeyDown={(event) => {
|
|
||||||
if (
|
|
||||||
item.kind !== "bot" ||
|
|
||||||
!event.altKey ||
|
|
||||||
(event.key !== "ArrowUp" && event.key !== "ArrowDown")
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
const index = groupBotIds.indexOf(item.chat.id);
|
|
||||||
const target =
|
|
||||||
groupBotIds[index + (event.key === "ArrowUp" ? -1 : 1)];
|
|
||||||
if (!target) return;
|
|
||||||
event.preventDefault();
|
|
||||||
reorderRosterBot(item.chat.id, target, groupBotIds);
|
|
||||||
}}
|
|
||||||
aria-label={
|
|
||||||
item.kind === "bot"
|
|
||||||
? t`${item.chat.name}, 1:1 conversation`
|
|
||||||
: t`${item.chat.name}, group conversation`
|
|
||||||
}
|
|
||||||
onClick={() => {
|
|
||||||
setActiveNavPillar("team");
|
setActiveNavPillar("team");
|
||||||
openSpaceChat(item.chat.spaceId, `/app/${item.chat.id}`);
|
openSpaceChat(item.chat.spaceId, `/app/${item.chat.id}`);
|
||||||
}}
|
}}
|
||||||
onContextMenu={(event) => {
|
activeSpaceId={bootstrapMe?.spaceId}
|
||||||
if (item.chat.spaceId !== bootstrapMe?.spaceId) return;
|
menuAnchor={botMenuAnchor}
|
||||||
event.preventDefault();
|
onMenu={setBotMenu}
|
||||||
botMenuAnchor.current = event.currentTarget;
|
/>
|
||||||
setBotMenu({
|
|
||||||
kind: item.kind,
|
|
||||||
id: item.chat.id,
|
|
||||||
position: { x: event.clientX, y: event.clientY },
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
className={`${rosterRowClass(
|
|
||||||
!inGroup && active?.id === item.chat.id,
|
|
||||||
)} cursor-grab active:cursor-grabbing`}
|
|
||||||
style={{
|
|
||||||
opacity: draggedBotId === item.chat.id ? 0.55 : 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="relative shrink-0">
|
|
||||||
<BotAvatar
|
|
||||||
color={item.chat.color}
|
|
||||||
identity={item.chat.id}
|
|
||||||
size={40}
|
|
||||||
status={item.chat.status}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
className={`absolute -bottom-0.5 -right-0.5 size-2.5 rounded-full border-2 border-sidebar ${
|
|
||||||
rosterStatusDot(item.chat.status) === "idle"
|
|
||||||
? "bg-success"
|
|
||||||
: "bg-warning animate-pulse"
|
|
||||||
}`}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="min-w-0 flex-1">
|
|
||||||
<div className="flex items-center justify-between gap-1.5">
|
|
||||||
<div className="flex min-w-0 items-center gap-2 overflow-hidden">
|
|
||||||
<span
|
|
||||||
dir="auto"
|
|
||||||
data-roster-bot-name=""
|
|
||||||
className={`shrink-0 max-w-[170px] truncate text-ui-body tracking-tight ${rosterNameClass(
|
|
||||||
item.chat.unread,
|
|
||||||
)}`}
|
|
||||||
>
|
|
||||||
{item.chat.name}
|
|
||||||
</span>
|
|
||||||
{needsYouChipLabel(item.chat.status) ? (
|
|
||||||
<span className="shrink-0 rounded-full border border-warning/30 bg-warning/10 px-2 py-0.5 text-ui-label font-medium text-foreground dark:text-warning">
|
|
||||||
{needsYouChipLabel(item.chat.status)}
|
|
||||||
</span>
|
|
||||||
) : item.chat.title ? (
|
|
||||||
<span className="min-w-0 truncate rounded-full border border-border bg-muted px-2 py-0.5 text-ui-label font-medium text-muted-foreground">
|
|
||||||
{item.chat.title}
|
|
||||||
</span>
|
|
||||||
) : null}
|
|
||||||
{item.chat.unread ? (
|
|
||||||
<span className="sr-only">
|
|
||||||
<Trans> (unread)</Trans>
|
|
||||||
</span>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
<div className="flex shrink-0 items-center gap-1.5">
|
|
||||||
<span className={rosterTimeClass}>
|
|
||||||
{formatRosterTime(item.chat.updatedAt)}
|
|
||||||
</span>
|
|
||||||
{item.chat.unread ? (
|
|
||||||
<span aria-hidden="true" className={rosterUnreadDotClass} />
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
dir="auto"
|
|
||||||
className={`mt-0.5 truncate text-ui-body leading-snug ${rosterPreviewClass(
|
|
||||||
item.chat.unread,
|
|
||||||
)}`}
|
|
||||||
>
|
|
||||||
{rosterActivitySubtitle(
|
|
||||||
item.chat.status,
|
|
||||||
cleanRosterPreview(item.chat.preview),
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
))}
|
))}
|
||||||
{!collapsed && group.bots.length > 4 && (
|
{!collapsed && group.bots.length > 4 && (
|
||||||
<button
|
<button
|
||||||
@ -3894,98 +3627,20 @@ export function ShellPage() {
|
|||||||
<SortableGroup key={`proj-${group.key}`} group={group}>
|
<SortableGroup key={`proj-${group.key}`} group={group}>
|
||||||
<div data-sidebar-group={group.key}>
|
<div data-sidebar-group={group.key}>
|
||||||
{group.title ? (
|
{group.title ? (
|
||||||
<div className="flex items-center pt-3 pb-0.5 relative">
|
<SidebarGroupHeader
|
||||||
{/* Drag grip — positioned to the left of the title text */}
|
variant="project"
|
||||||
<ProjectDragGrip className="absolute left-1 top-1/2 -translate-y-1/2 w-6 h-6 rounded flex items-center justify-center text-muted-foreground/30 hover:text-muted-foreground/70 active:text-muted-foreground transition-colors cursor-grab active:cursor-grabbing">
|
group={group}
|
||||||
<GripVertical className="size-icon-sm" strokeWidth={2} />
|
collapsed={collapsed}
|
||||||
</ProjectDragGrip>
|
activeSpaceId={bootstrapMe?.spaceId}
|
||||||
<button
|
botSections={botSections}
|
||||||
type="button"
|
spaces={spaces}
|
||||||
className="flex min-w-0 flex-1 items-center justify-between gap-2 rounded-lg pl-8 py-1 text-ui-label font-semibold tracking-wider uppercase text-foreground/65 dark:text-muted-foreground/80 hover:text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring"
|
onOpenEmptySpace={(spaceId) => void startProject(spaceId)}
|
||||||
onClick={() => {
|
onToggle={toggleSidebarSection}
|
||||||
if (group.emptySpaceId) {
|
sectionMenuAnchor={sectionMenuAnchor}
|
||||||
void startProject(group.emptySpaceId);
|
onSectionMenu={setSectionMenu}
|
||||||
return;
|
spaceMenuAnchor={spaceMenuAnchor}
|
||||||
}
|
onSpaceMenu={setSpaceMenu}
|
||||||
toggleSidebarSection(group.key);
|
/>
|
||||||
}}
|
|
||||||
onContextMenu={
|
|
||||||
group.sectionId
|
|
||||||
? (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
const sections =
|
|
||||||
group.spaceId === bootstrapMe?.spaceId
|
|
||||||
? botSections
|
|
||||||
: (spaces.find(
|
|
||||||
(space) => space.id === group.spaceId,
|
|
||||||
)?.botSections ?? []);
|
|
||||||
const section = sections.find(
|
|
||||||
(item) => item.id === group.sectionId,
|
|
||||||
);
|
|
||||||
if (!section) return;
|
|
||||||
sectionMenuAnchor.current = event.currentTarget;
|
|
||||||
setSectionMenu({
|
|
||||||
section,
|
|
||||||
spaceId: group.spaceId,
|
|
||||||
position: { x: event.clientX, y: event.clientY },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
: group.canDeleteSpace
|
|
||||||
? (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
spaceMenuAnchor.current = event.currentTarget;
|
|
||||||
setSpaceMenu({
|
|
||||||
id: group.spaceId,
|
|
||||||
position: { x: event.clientX, y: event.clientY },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
aria-expanded={group.emptySpaceId ? undefined : !collapsed}
|
|
||||||
aria-label={
|
|
||||||
group.emptySpaceId
|
|
||||||
? t`Select ${group.title}`
|
|
||||||
: collapsed
|
|
||||||
? t`Expand ${group.title}`
|
|
||||||
: t`Collapse ${group.title}`
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span className="flex min-w-0 items-center gap-1.5 truncate">
|
|
||||||
{group.showLock ? (
|
|
||||||
<Lock
|
|
||||||
strokeWidth={2}
|
|
||||||
aria-hidden="true"
|
|
||||||
className="size-icon-sm"
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
<span className="truncate">{group.title}</span>
|
|
||||||
</span>
|
|
||||||
{group.emptySpaceId ? null : (
|
|
||||||
<ChevronDown
|
|
||||||
strokeWidth={1.8}
|
|
||||||
className={`size-icon-md ${collapsed ? "-rotate-90 transition-transform" : "transition-transform"}`}
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
{group.canDeleteSpace ? (
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon-sm"
|
|
||||||
aria-label={t`Actions for ${group.spaceName}`}
|
|
||||||
onClick={(event) => {
|
|
||||||
const rect = event.currentTarget.getBoundingClientRect();
|
|
||||||
spaceMenuAnchor.current = event.currentTarget;
|
|
||||||
setSpaceMenu({
|
|
||||||
id: group.spaceId,
|
|
||||||
position: { x: rect.left, y: rect.bottom },
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MoreHorizontal aria-hidden="true" className="size-icon-md" />
|
|
||||||
</Button>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
) : null}
|
) : null}
|
||||||
{!collapsed && group.startSpaceId ? (
|
{!collapsed && group.startSpaceId ? (
|
||||||
<div className="px-3 pb-2">
|
<div className="px-3 pb-2">
|
||||||
@ -4003,17 +3658,15 @@ export function ShellPage() {
|
|||||||
) : null}
|
) : null}
|
||||||
{!collapsed &&
|
{!collapsed &&
|
||||||
group.bots.map((item) => (
|
group.bots.map((item) => (
|
||||||
<button
|
<ProjectRosterRow
|
||||||
key={`${item.kind}:${item.chat.id}`}
|
key={`${item.kind}:${item.chat.id}`}
|
||||||
type="button"
|
item={item}
|
||||||
aria-label={
|
selected={
|
||||||
item.kind === "bot"
|
item.kind === "bot"
|
||||||
? t`${item.chat.name}, 1:1 conversation`
|
? !inGroup && active?.id === item.chat.id
|
||||||
: item.chat.kind === "main"
|
: inGroup && activeGroup?.id === item.chat.id
|
||||||
? t`${item.chat.name}, main conversation`
|
|
||||||
: t`${item.chat.name}, group conversation`
|
|
||||||
}
|
}
|
||||||
onClick={() => {
|
onOpen={() => {
|
||||||
setActiveNavPillar("projekte");
|
setActiveNavPillar("projekte");
|
||||||
openSpaceChat(
|
openSpaceChat(
|
||||||
item.chat.spaceId,
|
item.chat.spaceId,
|
||||||
@ -4022,71 +3675,10 @@ export function ShellPage() {
|
|||||||
: `/app/g/${item.chat.id}`,
|
: `/app/g/${item.chat.id}`,
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
onContextMenu={(event) => {
|
activeSpaceId={bootstrapMe?.spaceId}
|
||||||
// A project's main conversation has no chat actions.
|
menuAnchor={botMenuAnchor}
|
||||||
if (
|
onMenu={setBotMenu}
|
||||||
item.chat.spaceId !== bootstrapMe?.spaceId ||
|
/>
|
||||||
item.chat.kind === "main"
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
event.preventDefault();
|
|
||||||
botMenuAnchor.current = event.currentTarget;
|
|
||||||
setBotMenu({
|
|
||||||
kind: item.kind,
|
|
||||||
id: item.chat.id,
|
|
||||||
position: { x: event.clientX, y: event.clientY },
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
className={rosterRowClass(
|
|
||||||
item.kind === "bot"
|
|
||||||
? !inGroup && active?.id === item.chat.id
|
|
||||||
: inGroup && activeGroup?.id === item.chat.id,
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{item.kind === "bot" ? (
|
|
||||||
<BotAvatar
|
|
||||||
color={item.chat.color}
|
|
||||||
identity={item.chat.id}
|
|
||||||
size={40}
|
|
||||||
status={item.chat.status}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<GroupAvatar members={(item.chat as any).members} size={40} />
|
|
||||||
)}
|
|
||||||
<div className="min-w-0 flex-1">
|
|
||||||
<div className="flex items-center justify-between gap-1.5">
|
|
||||||
<div className="flex min-w-0 items-center gap-2 overflow-hidden">
|
|
||||||
<span
|
|
||||||
dir="auto"
|
|
||||||
className={`shrink-0 max-w-[170px] truncate text-ui-body tracking-tight ${rosterNameClass(
|
|
||||||
item.chat.unread,
|
|
||||||
)}`}
|
|
||||||
>
|
|
||||||
{item.chat.name}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex shrink-0 items-center gap-1.5">
|
|
||||||
<span className={rosterTimeClass}>
|
|
||||||
{formatRosterTime(item.chat.updatedAt)}
|
|
||||||
</span>
|
|
||||||
{item.chat.unread ? (
|
|
||||||
<span
|
|
||||||
aria-hidden="true"
|
|
||||||
className={rosterUnreadDotClass}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
dir="auto"
|
|
||||||
className={`mt-0.5 truncate text-ui-body leading-snug ${rosterPreviewClass(
|
|
||||||
item.chat.unread,
|
|
||||||
)}`}
|
|
||||||
>
|
|
||||||
{cleanRosterPreview(localizedPreview(item.chat))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</SortableGroup>
|
</SortableGroup>
|
||||||
@ -4099,154 +3691,46 @@ export function ShellPage() {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{archivedBots.length + archivedGroups.length > 0 && !showSpaceSearch ? (
|
{archivedBots.length + archivedGroups.length > 0 && !showSpaceSearch ? (
|
||||||
<div className="mt-2 border-t border-border pt-2">
|
<ArchivedSection
|
||||||
<button
|
bots={archivedBots}
|
||||||
type="button"
|
groups={archivedGroups}
|
||||||
aria-expanded={archivedOpen}
|
open={archivedOpen}
|
||||||
onClick={() => setArchivedOpen((open) => !open)}
|
onToggle={() => setArchivedOpen((open) => !open)}
|
||||||
className="flex w-full items-center justify-between rounded-lg px-2.5 py-2 text-ui-body rk-sidebar-muted hover:bg-sidebar-accent"
|
onRestoreBot={(bot) =>
|
||||||
>
|
void rpc.bots.restore({ botId: bot.id }).then(() => refreshBots(true))
|
||||||
<span>
|
}
|
||||||
<Trans>Archived</Trans>
|
onRestoreGroup={(group) =>
|
||||||
</span>
|
void rpc.groups.restore({ groupId: group.id }).then(() => refreshBots(true))
|
||||||
<span>{archivedBots.length + archivedGroups.length}</span>
|
}
|
||||||
</button>
|
onDeleteBot={setDeleteTarget}
|
||||||
{archivedOpen ? (
|
onDeleteGroup={setDeleteGroupTarget}
|
||||||
<>
|
/>
|
||||||
{archivedBots.map((bot) => (
|
|
||||||
<div key={bot.id} className="flex items-center gap-2 rounded-lg px-2.5 py-2">
|
|
||||||
<BotAvatar
|
|
||||||
color={bot.color}
|
|
||||||
identity={bot.id}
|
|
||||||
size={28}
|
|
||||||
status={bot.status}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
className="min-w-0 flex-1 truncate text-ui-body text-foreground/75"
|
|
||||||
dir="auto"
|
|
||||||
>
|
|
||||||
{bot.name}
|
|
||||||
</span>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="xs"
|
|
||||||
onClick={() =>
|
|
||||||
void rpc.bots.restore({ botId: bot.id }).then(() => refreshBots(true))
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Trans>Restore</Trans>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="xs"
|
|
||||||
className="text-destructive hover:text-destructive"
|
|
||||||
aria-label={t`Delete ${bot.name}`}
|
|
||||||
onClick={() => setDeleteTarget(bot)}
|
|
||||||
>
|
|
||||||
<Trans>Delete</Trans>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
{archivedGroups.map((group) => (
|
|
||||||
<div key={group.id} className="flex items-center gap-2 rounded-lg px-2.5 py-2">
|
|
||||||
<GroupAvatar members={group.members} size={28} />
|
|
||||||
<span
|
|
||||||
className="min-w-0 flex-1 truncate text-ui-body text-foreground/75"
|
|
||||||
dir="auto"
|
|
||||||
>
|
|
||||||
{group.name}
|
|
||||||
</span>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="xs"
|
|
||||||
onClick={() =>
|
|
||||||
void rpc.groups
|
|
||||||
.restore({ groupId: group.id })
|
|
||||||
.then(() => refreshBots(true))
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Trans>Restore</Trans>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="xs"
|
|
||||||
className="text-destructive hover:text-destructive"
|
|
||||||
aria-label={t`Delete ${group.name}`}
|
|
||||||
onClick={() => setDeleteGroupTarget(group)}
|
|
||||||
>
|
|
||||||
<Trans>Delete</Trans>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<Popover open={menuOpen} onOpenChange={setMenuOpen}>
|
<UserMenu
|
||||||
<PopoverTrigger
|
open={menuOpen}
|
||||||
data-testid="user-menu-trigger"
|
onOpenChange={setMenuOpen}
|
||||||
className="flex items-center gap-[11px] px-[18px] py-3.5"
|
initials={initials}
|
||||||
>
|
userName={userName}
|
||||||
<span className="grid size-control-lg place-items-center rounded-full bg-accent text-ui-body-sm text-foreground/75">
|
onOpenSettings={() => openSettings("general")}
|
||||||
{initials}
|
onOpenUsage={() => {
|
||||||
</span>
|
void rpc.usage
|
||||||
<span className="text-[14.5px] text-foreground/90">{userName}</span>
|
.summary()
|
||||||
</PopoverTrigger>
|
.then(setUsage)
|
||||||
{menuOpen ? (
|
.catch(() => undefined);
|
||||||
<PopoverContent
|
openSettings("usage");
|
||||||
side="top"
|
}}
|
||||||
align="start"
|
onLogOut={() =>
|
||||||
className="w-[calc(316px-1.5rem)] max-w-[calc(100vw-3rem)] gap-0 p-1 data-closed:animate-none"
|
// This browser stops receiving the account's pushes once it signs out.
|
||||||
>
|
void disableWebPush()
|
||||||
<Button
|
.catch(() => undefined)
|
||||||
variant="ghost"
|
.then(() => authClient.signOut())
|
||||||
className="w-full justify-start font-normal"
|
.then(() => {
|
||||||
aria-label={t`Settings`}
|
clearSpaceSelection();
|
||||||
onClick={() => {
|
navigate("/");
|
||||||
setMenuOpen(false);
|
})
|
||||||
openSettings("general");
|
}
|
||||||
}}
|
/>
|
||||||
>
|
|
||||||
<Settings className="text-muted-foreground" strokeWidth={1.75} />
|
|
||||||
<Trans>Settings</Trans>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
className="w-full justify-start font-normal"
|
|
||||||
aria-label={t`Usage`}
|
|
||||||
onClick={() => {
|
|
||||||
setMenuOpen(false);
|
|
||||||
void rpc.usage
|
|
||||||
.summary()
|
|
||||||
.then(setUsage)
|
|
||||||
.catch(() => undefined);
|
|
||||||
openSettings("usage");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Gauge className="text-muted-foreground" strokeWidth={1.75} />
|
|
||||||
<Trans>Usage</Trans>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
className="w-full justify-start font-normal"
|
|
||||||
onClick={() =>
|
|
||||||
// This browser stops receiving the account's pushes once it signs out.
|
|
||||||
void disableWebPush()
|
|
||||||
.catch(() => undefined)
|
|
||||||
.then(() => authClient.signOut())
|
|
||||||
.then(() => {
|
|
||||||
clearSpaceSelection();
|
|
||||||
navigate("/");
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<LogOut className="text-muted-foreground" strokeWidth={1.75} />
|
|
||||||
<Trans>Log out</Trans>
|
|
||||||
</Button>
|
|
||||||
</PopoverContent>
|
|
||||||
) : null}
|
|
||||||
</Popover>
|
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
@ -4301,29 +3785,11 @@ export function ShellPage() {
|
|||||||
<div className="flex h-full flex-1 flex-col overflow-hidden">
|
<div className="flex h-full flex-1 flex-col overflow-hidden">
|
||||||
<div className="app-drag flex items-center border-b border-sidebar-border px-3 py-[17px] md:px-[22px] lg:px-8 2xl:px-12">
|
<div className="app-drag flex items-center border-b border-sidebar-border px-3 py-[17px] md:px-[22px] lg:px-8 2xl:px-12">
|
||||||
<div className="flex min-w-0 items-center gap-2">
|
<div className="flex min-w-0 items-center gap-2">
|
||||||
{botsSidebarCollapsed && desktopBridge() ? <WindowChrome /> : null}
|
<SidebarToggleButtons
|
||||||
<button
|
collapsed={botsSidebarCollapsed}
|
||||||
type="button"
|
onCollapsedChange={setBotsSidebarCollapsedPref}
|
||||||
aria-label={t`Open navigation`}
|
onOpenNavigation={() => setMobileSidebarOpen(true)}
|
||||||
onClick={() => setMobileSidebarOpen(true)}
|
/>
|
||||||
className="app-no-drag grid size-control-lg shrink-0 place-items-center rounded-lg text-foreground/75 hover:bg-accent md:hidden"
|
|
||||||
>
|
|
||||||
<Menu strokeWidth={1.7} className="size-icon-lg" />
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
data-testid="toggle-bots-sidebar"
|
|
||||||
aria-label={botsSidebarCollapsed ? t`Show bots` : t`Minimize bots`}
|
|
||||||
title={botsSidebarCollapsed ? t`Show bots` : t`Minimize bots`}
|
|
||||||
onClick={() => setBotsSidebarCollapsedPref(!botsSidebarCollapsed)}
|
|
||||||
className="app-no-drag hidden size-control-lg shrink-0 place-items-center rounded-lg text-foreground/75 hover:bg-accent md:grid"
|
|
||||||
>
|
|
||||||
{botsSidebarCollapsed ? (
|
|
||||||
<PanelLeftOpen strokeWidth={1.7} aria-hidden="true" className="size-icon-lg" />
|
|
||||||
) : (
|
|
||||||
<PanelLeftClose strokeWidth={1.7} aria-hidden="true" className="size-icon-lg" />
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -4362,30 +3828,11 @@ export function ShellPage() {
|
|||||||
<>
|
<>
|
||||||
<div className="app-drag flex items-center justify-between border-b border-sidebar-border px-3.5 py-2 md:px-6 md:py-3 lg:px-8 lg:py-4 2xl:px-12 2xl:py-6 bg-background/80 backdrop-blur-md">
|
<div className="app-drag flex items-center justify-between border-b border-sidebar-border px-3.5 py-2 md:px-6 md:py-3 lg:px-8 lg:py-4 2xl:px-12 2xl:py-6 bg-background/80 backdrop-blur-md">
|
||||||
<div className="flex min-w-0 items-center gap-2.5">
|
<div className="flex min-w-0 items-center gap-2.5">
|
||||||
{/* Collapsed bots sidebar: this header is the leading edge for window chrome. */}
|
<SidebarToggleButtons
|
||||||
{botsSidebarCollapsed && desktopBridge() ? <WindowChrome /> : null}
|
collapsed={botsSidebarCollapsed}
|
||||||
<button
|
onCollapsedChange={setBotsSidebarCollapsedPref}
|
||||||
type="button"
|
onOpenNavigation={() => setMobileSidebarOpen(true)}
|
||||||
aria-label={t`Open navigation`}
|
/>
|
||||||
onClick={() => setMobileSidebarOpen(true)}
|
|
||||||
className="app-no-drag grid size-control-lg shrink-0 place-items-center rounded-lg text-foreground/75 hover:bg-accent md:hidden"
|
|
||||||
>
|
|
||||||
<Menu strokeWidth={1.7} className="size-icon-lg" />
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
data-testid="toggle-bots-sidebar"
|
|
||||||
aria-label={botsSidebarCollapsed ? t`Show bots` : t`Minimize bots`}
|
|
||||||
title={botsSidebarCollapsed ? t`Show bots` : t`Minimize bots`}
|
|
||||||
onClick={() => setBotsSidebarCollapsedPref(!botsSidebarCollapsed)}
|
|
||||||
className="app-no-drag hidden size-control-lg shrink-0 place-items-center rounded-lg text-foreground/75 hover:bg-accent md:grid"
|
|
||||||
>
|
|
||||||
{botsSidebarCollapsed ? (
|
|
||||||
<PanelLeftOpen strokeWidth={1.7} aria-hidden="true" className="size-icon-lg" />
|
|
||||||
) : (
|
|
||||||
<PanelLeftClose strokeWidth={1.7} aria-hidden="true" className="size-icon-lg" />
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
{inGroup && projectSessionKey ? (
|
{inGroup && projectSessionKey ? (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
85
apps/web/src/pages/shell/archived-section.tsx
Normal file
85
apps/web/src/pages/shell/archived-section.tsx
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import { Trans, useLingui } from "@lingui/react/macro";
|
||||||
|
import type { Bot, Group } from "@rakazo/contracts";
|
||||||
|
import { BotAvatar, Button, GroupAvatar } from "@rakazo/ui-web";
|
||||||
|
|
||||||
|
/** Collapsible list of archived bots and groups at the foot of the sidebar. */
|
||||||
|
export function ArchivedSection({
|
||||||
|
bots,
|
||||||
|
groups,
|
||||||
|
open,
|
||||||
|
onToggle,
|
||||||
|
onRestoreBot,
|
||||||
|
onRestoreGroup,
|
||||||
|
onDeleteBot,
|
||||||
|
onDeleteGroup,
|
||||||
|
}: {
|
||||||
|
bots: Bot[];
|
||||||
|
groups: Group[];
|
||||||
|
open: boolean;
|
||||||
|
onToggle: () => void;
|
||||||
|
onRestoreBot: (bot: Bot) => void;
|
||||||
|
onRestoreGroup: (group: Group) => void;
|
||||||
|
onDeleteBot: (bot: Bot) => void;
|
||||||
|
onDeleteGroup: (group: Group) => void;
|
||||||
|
}) {
|
||||||
|
const { t } = useLingui();
|
||||||
|
return (
|
||||||
|
<div className="mt-2 border-t border-border pt-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-expanded={open}
|
||||||
|
onClick={onToggle}
|
||||||
|
className="flex w-full items-center justify-between rounded-lg px-2.5 py-2 text-ui-body rk-sidebar-muted hover:bg-sidebar-accent"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<Trans>Archived</Trans>
|
||||||
|
</span>
|
||||||
|
<span>{bots.length + groups.length}</span>
|
||||||
|
</button>
|
||||||
|
{open ? (
|
||||||
|
<>
|
||||||
|
{bots.map((bot) => (
|
||||||
|
<div key={bot.id} className="flex items-center gap-2 rounded-lg px-2.5 py-2">
|
||||||
|
<BotAvatar color={bot.color} identity={bot.id} size={28} status={bot.status} />
|
||||||
|
<span className="min-w-0 flex-1 truncate text-ui-body text-foreground/75" dir="auto">
|
||||||
|
{bot.name}
|
||||||
|
</span>
|
||||||
|
<Button variant="ghost" size="xs" onClick={() => onRestoreBot(bot)}>
|
||||||
|
<Trans>Restore</Trans>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="xs"
|
||||||
|
className="text-destructive hover:text-destructive"
|
||||||
|
aria-label={t`Delete ${bot.name}`}
|
||||||
|
onClick={() => onDeleteBot(bot)}
|
||||||
|
>
|
||||||
|
<Trans>Delete</Trans>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{groups.map((group) => (
|
||||||
|
<div key={group.id} className="flex items-center gap-2 rounded-lg px-2.5 py-2">
|
||||||
|
<GroupAvatar members={group.members} size={28} />
|
||||||
|
<span className="min-w-0 flex-1 truncate text-ui-body text-foreground/75" dir="auto">
|
||||||
|
{group.name}
|
||||||
|
</span>
|
||||||
|
<Button variant="ghost" size="xs" onClick={() => onRestoreGroup(group)}>
|
||||||
|
<Trans>Restore</Trans>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="xs"
|
||||||
|
className="text-destructive hover:text-destructive"
|
||||||
|
aria-label={t`Delete ${group.name}`}
|
||||||
|
onClick={() => onDeleteGroup(group)}
|
||||||
|
>
|
||||||
|
<Trans>Delete</Trans>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
250
apps/web/src/pages/shell/roster-rows.tsx
Normal file
250
apps/web/src/pages/shell/roster-rows.tsx
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
import { Trans, useLingui } from "@lingui/react/macro";
|
||||||
|
import type { SpaceBot, SpaceGroup } from "@rakazo/contracts";
|
||||||
|
import { BotAvatar, GroupAvatar } from "@rakazo/ui-web";
|
||||||
|
import type { RefObject } from "react";
|
||||||
|
import {
|
||||||
|
needsYouChipLabel,
|
||||||
|
rosterActivitySubtitle,
|
||||||
|
rosterStatusDot,
|
||||||
|
} from "../../lib/agent-activity";
|
||||||
|
import { localizedPreview } from "../../lib/onboarding-copy";
|
||||||
|
import type { ContextMenuPosition } from "../BotContextMenu";
|
||||||
|
import { cleanRosterPreview, formatRosterTime } from "./roster-format";
|
||||||
|
import {
|
||||||
|
rosterNameClass,
|
||||||
|
rosterPreviewClass,
|
||||||
|
rosterRowClass,
|
||||||
|
rosterTimeClass,
|
||||||
|
rosterUnreadDotClass,
|
||||||
|
} from "./roster-row-style";
|
||||||
|
|
||||||
|
export type SidebarChatItem = { kind: "bot"; chat: SpaceBot } | { kind: "group"; chat: SpaceGroup };
|
||||||
|
|
||||||
|
export type BotMenuRequest = {
|
||||||
|
kind: "bot" | "group";
|
||||||
|
id: string;
|
||||||
|
position: ContextMenuPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A bot in the conversations section: reorderable by drag or Alt+Arrow within its group. */
|
||||||
|
export function TeamRosterRow({
|
||||||
|
item,
|
||||||
|
groupBotIds,
|
||||||
|
draggedBotId,
|
||||||
|
onDraggedBotIdChange,
|
||||||
|
onReorder,
|
||||||
|
selected,
|
||||||
|
onOpen,
|
||||||
|
activeSpaceId,
|
||||||
|
menuAnchor,
|
||||||
|
onMenu,
|
||||||
|
}: {
|
||||||
|
item: Extract<SidebarChatItem, { kind: "bot" }>;
|
||||||
|
groupBotIds: string[];
|
||||||
|
draggedBotId: string | null;
|
||||||
|
onDraggedBotIdChange: (botId: string | null) => void;
|
||||||
|
onReorder: (sourceId: string, targetId: string, groupBotIds: string[]) => void;
|
||||||
|
selected: boolean;
|
||||||
|
onOpen: () => void;
|
||||||
|
activeSpaceId: string | undefined;
|
||||||
|
menuAnchor: RefObject<HTMLElement | null>;
|
||||||
|
onMenu: (menu: BotMenuRequest) => void;
|
||||||
|
}) {
|
||||||
|
const { t } = useLingui();
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
draggable={item.kind === "bot"}
|
||||||
|
data-roster-bot-id={item.kind === "bot" ? item.chat.id : undefined}
|
||||||
|
aria-keyshortcuts={item.kind === "bot" ? "Alt+ArrowUp Alt+ArrowDown" : undefined}
|
||||||
|
onDragStart={(event) => {
|
||||||
|
if (item.kind !== "bot") return;
|
||||||
|
onDraggedBotIdChange(item.chat.id);
|
||||||
|
event.dataTransfer.effectAllowed = "move";
|
||||||
|
event.dataTransfer.setData("text/plain", item.chat.id);
|
||||||
|
}}
|
||||||
|
onDragOver={(event) => {
|
||||||
|
if (item.kind === "bot" && draggedBotId && groupBotIds.includes(draggedBotId)) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.dataTransfer.dropEffect = "move";
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onDrop={(event) => {
|
||||||
|
if (item.kind !== "bot" || !draggedBotId) return;
|
||||||
|
event.preventDefault();
|
||||||
|
onReorder(draggedBotId, item.chat.id, groupBotIds);
|
||||||
|
onDraggedBotIdChange(null);
|
||||||
|
}}
|
||||||
|
onDragEnd={() => onDraggedBotIdChange(null)}
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (
|
||||||
|
item.kind !== "bot" ||
|
||||||
|
!event.altKey ||
|
||||||
|
(event.key !== "ArrowUp" && event.key !== "ArrowDown")
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
const index = groupBotIds.indexOf(item.chat.id);
|
||||||
|
const target = groupBotIds[index + (event.key === "ArrowUp" ? -1 : 1)];
|
||||||
|
if (!target) return;
|
||||||
|
event.preventDefault();
|
||||||
|
onReorder(item.chat.id, target, groupBotIds);
|
||||||
|
}}
|
||||||
|
aria-label={
|
||||||
|
item.kind === "bot"
|
||||||
|
? t`${item.chat.name}, 1:1 conversation`
|
||||||
|
: t`${item.chat.name}, group conversation`
|
||||||
|
}
|
||||||
|
onClick={onOpen}
|
||||||
|
onContextMenu={(event) => {
|
||||||
|
if (item.chat.spaceId !== activeSpaceId) return;
|
||||||
|
event.preventDefault();
|
||||||
|
menuAnchor.current = event.currentTarget;
|
||||||
|
onMenu({
|
||||||
|
kind: item.kind,
|
||||||
|
id: item.chat.id,
|
||||||
|
position: { x: event.clientX, y: event.clientY },
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
className={`${rosterRowClass(selected)} cursor-grab active:cursor-grabbing`}
|
||||||
|
style={{
|
||||||
|
opacity: draggedBotId === item.chat.id ? 0.55 : 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="relative shrink-0">
|
||||||
|
<BotAvatar
|
||||||
|
color={item.chat.color}
|
||||||
|
identity={item.chat.id}
|
||||||
|
size={40}
|
||||||
|
status={item.chat.status}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className={`absolute -bottom-0.5 -right-0.5 size-2.5 rounded-full border-2 border-sidebar ${
|
||||||
|
rosterStatusDot(item.chat.status) === "idle" ? "bg-success" : "bg-warning animate-pulse"
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="min-w-0 flex-1">
|
||||||
|
<div className="flex items-center justify-between gap-1.5">
|
||||||
|
<div className="flex min-w-0 items-center gap-2 overflow-hidden">
|
||||||
|
<span
|
||||||
|
dir="auto"
|
||||||
|
data-roster-bot-name=""
|
||||||
|
className={`shrink-0 max-w-[170px] truncate text-ui-body tracking-tight ${rosterNameClass(
|
||||||
|
item.chat.unread,
|
||||||
|
)}`}
|
||||||
|
>
|
||||||
|
{item.chat.name}
|
||||||
|
</span>
|
||||||
|
{needsYouChipLabel(item.chat.status) ? (
|
||||||
|
<span className="shrink-0 rounded-full border border-warning/30 bg-warning/10 px-2 py-0.5 text-ui-label font-medium text-foreground dark:text-warning">
|
||||||
|
{needsYouChipLabel(item.chat.status)}
|
||||||
|
</span>
|
||||||
|
) : item.chat.title ? (
|
||||||
|
<span className="min-w-0 truncate rounded-full border border-border bg-muted px-2 py-0.5 text-ui-label font-medium text-muted-foreground">
|
||||||
|
{item.chat.title}
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
{item.chat.unread ? (
|
||||||
|
<span className="sr-only">
|
||||||
|
<Trans> (unread)</Trans>
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
<div className="flex shrink-0 items-center gap-1.5">
|
||||||
|
<span className={rosterTimeClass}>{formatRosterTime(item.chat.updatedAt)}</span>
|
||||||
|
{item.chat.unread ? <span aria-hidden="true" className={rosterUnreadDotClass} /> : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
dir="auto"
|
||||||
|
className={`mt-0.5 truncate text-ui-body leading-snug ${rosterPreviewClass(
|
||||||
|
item.chat.unread,
|
||||||
|
)}`}
|
||||||
|
>
|
||||||
|
{rosterActivitySubtitle(item.chat.status, cleanRosterPreview(item.chat.preview))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A conversation in the projects section; a project's main conversation has no chat actions. */
|
||||||
|
export function ProjectRosterRow({
|
||||||
|
item,
|
||||||
|
selected,
|
||||||
|
onOpen,
|
||||||
|
activeSpaceId,
|
||||||
|
menuAnchor,
|
||||||
|
onMenu,
|
||||||
|
}: {
|
||||||
|
item: SidebarChatItem;
|
||||||
|
selected: boolean;
|
||||||
|
onOpen: () => void;
|
||||||
|
activeSpaceId: string | undefined;
|
||||||
|
menuAnchor: RefObject<HTMLElement | null>;
|
||||||
|
onMenu: (menu: BotMenuRequest) => void;
|
||||||
|
}) {
|
||||||
|
const { t } = useLingui();
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-label={
|
||||||
|
item.kind === "bot"
|
||||||
|
? t`${item.chat.name}, 1:1 conversation`
|
||||||
|
: item.chat.kind === "main"
|
||||||
|
? t`${item.chat.name}, main conversation`
|
||||||
|
: t`${item.chat.name}, group conversation`
|
||||||
|
}
|
||||||
|
onClick={onOpen}
|
||||||
|
onContextMenu={(event) => {
|
||||||
|
// A project's main conversation has no chat actions.
|
||||||
|
if (item.chat.spaceId !== activeSpaceId || item.chat.kind === "main") return;
|
||||||
|
event.preventDefault();
|
||||||
|
menuAnchor.current = event.currentTarget;
|
||||||
|
onMenu({
|
||||||
|
kind: item.kind,
|
||||||
|
id: item.chat.id,
|
||||||
|
position: { x: event.clientX, y: event.clientY },
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
className={rosterRowClass(selected)}
|
||||||
|
>
|
||||||
|
{item.kind === "bot" ? (
|
||||||
|
<BotAvatar
|
||||||
|
color={item.chat.color}
|
||||||
|
identity={item.chat.id}
|
||||||
|
size={40}
|
||||||
|
status={item.chat.status}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<GroupAvatar members={(item.chat as any).members} size={40} />
|
||||||
|
)}
|
||||||
|
<div className="min-w-0 flex-1">
|
||||||
|
<div className="flex items-center justify-between gap-1.5">
|
||||||
|
<div className="flex min-w-0 items-center gap-2 overflow-hidden">
|
||||||
|
<span
|
||||||
|
dir="auto"
|
||||||
|
className={`shrink-0 max-w-[170px] truncate text-ui-body tracking-tight ${rosterNameClass(
|
||||||
|
item.chat.unread,
|
||||||
|
)}`}
|
||||||
|
>
|
||||||
|
{item.chat.name}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex shrink-0 items-center gap-1.5">
|
||||||
|
<span className={rosterTimeClass}>{formatRosterTime(item.chat.updatedAt)}</span>
|
||||||
|
{item.chat.unread ? <span aria-hidden="true" className={rosterUnreadDotClass} /> : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
dir="auto"
|
||||||
|
className={`mt-0.5 truncate text-ui-body leading-snug ${rosterPreviewClass(
|
||||||
|
item.chat.unread,
|
||||||
|
)}`}
|
||||||
|
>
|
||||||
|
{cleanRosterPreview(localizedPreview(item.chat))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
161
apps/web/src/pages/shell/sidebar-group-header.tsx
Normal file
161
apps/web/src/pages/shell/sidebar-group-header.tsx
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
import { useLingui } from "@lingui/react/macro";
|
||||||
|
import type { BotSection, Space } from "@rakazo/contracts";
|
||||||
|
import { Button } from "@rakazo/ui-web";
|
||||||
|
import { ChevronDown, Folder, GripVertical, Lock, MoreHorizontal } from "lucide-react";
|
||||||
|
import type { RefObject } from "react";
|
||||||
|
import { ProjectDragGrip } from "../../components/SortableGroup";
|
||||||
|
import type { ContextMenuPosition } from "../BotContextMenu";
|
||||||
|
|
||||||
|
export type SidebarGroupHeaderGroup = {
|
||||||
|
key: string;
|
||||||
|
title: string | null;
|
||||||
|
sectionId: string | null;
|
||||||
|
spaceId: string;
|
||||||
|
spaceName: string;
|
||||||
|
canDeleteSpace: boolean;
|
||||||
|
emptySpaceId: string | undefined;
|
||||||
|
showLock: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SpaceMenuRequest = { id: string; position: ContextMenuPosition };
|
||||||
|
|
||||||
|
export type SectionMenuRequest = {
|
||||||
|
section: BotSection;
|
||||||
|
spaceId: string;
|
||||||
|
position: ContextMenuPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collapsible title of a sidebar group. Project groups add a drag grip, show a lock for other
|
||||||
|
* spaces and select an empty space instead of opening it.
|
||||||
|
*/
|
||||||
|
export function SidebarGroupHeader({
|
||||||
|
variant,
|
||||||
|
group,
|
||||||
|
collapsed,
|
||||||
|
activeSpaceId,
|
||||||
|
botSections,
|
||||||
|
spaces,
|
||||||
|
onOpenEmptySpace,
|
||||||
|
onToggle,
|
||||||
|
sectionMenuAnchor,
|
||||||
|
onSectionMenu,
|
||||||
|
spaceMenuAnchor,
|
||||||
|
onSpaceMenu,
|
||||||
|
}: {
|
||||||
|
variant: "conversation" | "project";
|
||||||
|
group: SidebarGroupHeaderGroup;
|
||||||
|
collapsed: boolean;
|
||||||
|
activeSpaceId: string | undefined;
|
||||||
|
botSections: BotSection[];
|
||||||
|
spaces: Space[];
|
||||||
|
onOpenEmptySpace: (spaceId: string) => void;
|
||||||
|
onToggle: (key: string) => void;
|
||||||
|
sectionMenuAnchor: RefObject<HTMLElement | null>;
|
||||||
|
onSectionMenu: (menu: SectionMenuRequest) => void;
|
||||||
|
spaceMenuAnchor: RefObject<HTMLElement | null>;
|
||||||
|
onSpaceMenu: (menu: SpaceMenuRequest) => void;
|
||||||
|
}) {
|
||||||
|
const { t } = useLingui();
|
||||||
|
const project = variant === "project";
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
project ? "flex items-center pt-3 pb-0.5 relative" : "flex items-center pt-3 pb-0.5"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{project ? (
|
||||||
|
// Drag grip — positioned to the left of the title text
|
||||||
|
<ProjectDragGrip className="absolute left-1 top-1/2 -translate-y-1/2 w-6 h-6 rounded flex items-center justify-center text-muted-foreground/30 hover:text-muted-foreground/70 active:text-muted-foreground transition-colors cursor-grab active:cursor-grabbing">
|
||||||
|
<GripVertical className="size-icon-sm" strokeWidth={2} />
|
||||||
|
</ProjectDragGrip>
|
||||||
|
) : null}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={`flex min-w-0 flex-1 items-center justify-between gap-2 rounded-lg ${project ? "pl-8" : "px-2.5"} py-1 text-ui-label font-semibold tracking-wider uppercase text-foreground/65 dark:text-muted-foreground/80 hover:text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring`}
|
||||||
|
onClick={() => {
|
||||||
|
if (group.emptySpaceId) {
|
||||||
|
onOpenEmptySpace(group.emptySpaceId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onToggle(group.key);
|
||||||
|
}}
|
||||||
|
onContextMenu={
|
||||||
|
group.sectionId
|
||||||
|
? (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
// Prefer section rename over delete-space when both apply;
|
||||||
|
// the dedicated space-actions button still opens the space menu.
|
||||||
|
const sections =
|
||||||
|
group.spaceId === activeSpaceId
|
||||||
|
? botSections
|
||||||
|
: (spaces.find((space) => space.id === group.spaceId)?.botSections ?? []);
|
||||||
|
const section = sections.find((item) => item.id === group.sectionId);
|
||||||
|
if (!section) return;
|
||||||
|
sectionMenuAnchor.current = event.currentTarget;
|
||||||
|
onSectionMenu({
|
||||||
|
section,
|
||||||
|
spaceId: group.spaceId,
|
||||||
|
position: { x: event.clientX, y: event.clientY },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
: group.canDeleteSpace
|
||||||
|
? (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
spaceMenuAnchor.current = event.currentTarget;
|
||||||
|
onSpaceMenu({
|
||||||
|
id: group.spaceId,
|
||||||
|
position: { x: event.clientX, y: event.clientY },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
aria-expanded={group.emptySpaceId ? undefined : !collapsed}
|
||||||
|
aria-label={
|
||||||
|
group.emptySpaceId
|
||||||
|
? project
|
||||||
|
? t`Select ${group.title}`
|
||||||
|
: t`Open ${group.title}`
|
||||||
|
: collapsed
|
||||||
|
? t`Expand ${group.title}`
|
||||||
|
: t`Collapse ${group.title}`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<span className="flex min-w-0 items-center gap-1.5 truncate">
|
||||||
|
{project ? (
|
||||||
|
group.showLock ? (
|
||||||
|
<Lock strokeWidth={2} aria-hidden="true" className="size-icon-sm" />
|
||||||
|
) : null
|
||||||
|
) : (
|
||||||
|
<Folder strokeWidth={2} aria-hidden="true" className="size-icon-sm" />
|
||||||
|
)}
|
||||||
|
<span className="truncate">{group.title}</span>
|
||||||
|
</span>
|
||||||
|
{group.emptySpaceId ? null : (
|
||||||
|
<ChevronDown
|
||||||
|
strokeWidth={1.8}
|
||||||
|
className={`size-icon-md ${collapsed ? "-rotate-90 transition-transform" : "transition-transform"}`}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
{group.canDeleteSpace ? (
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon-sm"
|
||||||
|
aria-label={t`Actions for ${group.spaceName}`}
|
||||||
|
onClick={(event) => {
|
||||||
|
const rect = event.currentTarget.getBoundingClientRect();
|
||||||
|
spaceMenuAnchor.current = event.currentTarget;
|
||||||
|
onSpaceMenu({
|
||||||
|
id: group.spaceId,
|
||||||
|
position: { x: rect.left, y: rect.bottom },
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MoreHorizontal aria-hidden="true" className="size-icon-md" />
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
118
apps/web/src/pages/shell/sidebar-header.tsx
Normal file
118
apps/web/src/pages/shell/sidebar-header.tsx
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import { useLingui } from "@lingui/react/macro";
|
||||||
|
import type { Bot } from "@rakazo/contracts";
|
||||||
|
import { Popover, PopoverContent, PopoverTrigger, Wordmark } from "@rakazo/ui-web";
|
||||||
|
import { Bell } from "lucide-react";
|
||||||
|
import { WindowChrome } from "../WindowChrome";
|
||||||
|
import { BotCreatePicker } from "./bot-picker";
|
||||||
|
|
||||||
|
/** Window chrome, wordmark, the activity toggle and the create menu atop the sidebar. */
|
||||||
|
export function SidebarHeader({
|
||||||
|
activityMode,
|
||||||
|
onToggleActivityMode,
|
||||||
|
createMenuOpen,
|
||||||
|
onCreateMenuOpenChange,
|
||||||
|
onCloseMobileSidebar,
|
||||||
|
bots,
|
||||||
|
onCreateBot,
|
||||||
|
onOpenBot,
|
||||||
|
onCreateGroup,
|
||||||
|
onCreateSpace,
|
||||||
|
onShowGroupInfo,
|
||||||
|
onShowSpaceInfo,
|
||||||
|
}: {
|
||||||
|
activityMode: boolean;
|
||||||
|
onToggleActivityMode: () => void;
|
||||||
|
createMenuOpen: boolean;
|
||||||
|
onCreateMenuOpenChange: (open: boolean) => void;
|
||||||
|
onCloseMobileSidebar: () => void;
|
||||||
|
bots: Bot[];
|
||||||
|
onCreateBot: () => void;
|
||||||
|
onOpenBot: (id: string) => void;
|
||||||
|
onCreateGroup: () => void;
|
||||||
|
onCreateSpace: () => void;
|
||||||
|
onShowGroupInfo: () => void;
|
||||||
|
onShowSpaceInfo: () => void;
|
||||||
|
}) {
|
||||||
|
const { t } = useLingui();
|
||||||
|
return (
|
||||||
|
<div className="app-drag flex items-center justify-between px-4 lg:px-6 2xl:px-8 pb-3 pt-4">
|
||||||
|
<WindowChrome />
|
||||||
|
<div className="flex-1 px-1">
|
||||||
|
<Wordmark />
|
||||||
|
</div>
|
||||||
|
<div className="relative flex items-center gap-2.5">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-label={t`Activity`}
|
||||||
|
aria-pressed={activityMode}
|
||||||
|
title={t`Activity`}
|
||||||
|
data-activity-mode={activityMode ? "on" : "off"}
|
||||||
|
onClick={onToggleActivityMode}
|
||||||
|
className={`app-no-drag flex size-control-sm items-center justify-center rounded-full ${
|
||||||
|
activityMode
|
||||||
|
? "bg-primary text-primary-foreground"
|
||||||
|
: "rk-sidebar-muted hover:text-foreground/75"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<Bell
|
||||||
|
strokeWidth={1.8}
|
||||||
|
fill={activityMode ? "currentColor" : "none"}
|
||||||
|
aria-hidden="true"
|
||||||
|
className="size-icon-md"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Popover open={createMenuOpen} onOpenChange={onCreateMenuOpenChange}>
|
||||||
|
<PopoverTrigger
|
||||||
|
className="app-no-drag text-[21px] rk-sidebar-muted hover:text-foreground/75"
|
||||||
|
title={t`Create`}
|
||||||
|
data-testid="create-menu-trigger"
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</PopoverTrigger>
|
||||||
|
{/* Unmount with the state change so the panel it opens never coexists with the menu. */}
|
||||||
|
{createMenuOpen ? (
|
||||||
|
<PopoverContent
|
||||||
|
align="end"
|
||||||
|
className="app-no-drag w-auto gap-0 overflow-hidden p-0 data-closed:animate-none"
|
||||||
|
>
|
||||||
|
<BotCreatePicker
|
||||||
|
bots={bots}
|
||||||
|
onCreateBot={() => {
|
||||||
|
onCreateMenuOpenChange(false);
|
||||||
|
onCloseMobileSidebar();
|
||||||
|
onCreateBot();
|
||||||
|
}}
|
||||||
|
onOpenBot={(id) => {
|
||||||
|
onCreateMenuOpenChange(false);
|
||||||
|
onCloseMobileSidebar();
|
||||||
|
onOpenBot(id);
|
||||||
|
}}
|
||||||
|
onCreateGroup={() => {
|
||||||
|
onCreateMenuOpenChange(false);
|
||||||
|
onCloseMobileSidebar();
|
||||||
|
onCreateGroup();
|
||||||
|
}}
|
||||||
|
onCreateSpace={() => {
|
||||||
|
onCreateMenuOpenChange(false);
|
||||||
|
onCloseMobileSidebar();
|
||||||
|
onCreateSpace();
|
||||||
|
}}
|
||||||
|
onShowGroupInfo={() => {
|
||||||
|
onCreateMenuOpenChange(false);
|
||||||
|
onCloseMobileSidebar();
|
||||||
|
onShowGroupInfo();
|
||||||
|
}}
|
||||||
|
onShowSpaceInfo={() => {
|
||||||
|
onCreateMenuOpenChange(false);
|
||||||
|
onCloseMobileSidebar();
|
||||||
|
onShowSpaceInfo();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PopoverContent>
|
||||||
|
) : null}
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
45
apps/web/src/pages/shell/sidebar-toggle-buttons.tsx
Normal file
45
apps/web/src/pages/shell/sidebar-toggle-buttons.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { useLingui } from "@lingui/react/macro";
|
||||||
|
import { Menu, PanelLeftClose, PanelLeftOpen } from "lucide-react";
|
||||||
|
import { desktopBridge } from "../../lib/desktop";
|
||||||
|
import { WindowChrome } from "../WindowChrome";
|
||||||
|
|
||||||
|
/** Leading controls of a main header: open the mobile navigation or collapse the bots sidebar. */
|
||||||
|
export function SidebarToggleButtons({
|
||||||
|
collapsed,
|
||||||
|
onCollapsedChange,
|
||||||
|
onOpenNavigation,
|
||||||
|
}: {
|
||||||
|
collapsed: boolean;
|
||||||
|
onCollapsedChange: (collapsed: boolean) => void;
|
||||||
|
onOpenNavigation: () => void;
|
||||||
|
}) {
|
||||||
|
const { t } = useLingui();
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* Collapsed bots sidebar: this header is the leading edge for window chrome. */}
|
||||||
|
{collapsed && desktopBridge() ? <WindowChrome /> : null}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-label={t`Open navigation`}
|
||||||
|
onClick={onOpenNavigation}
|
||||||
|
className="app-no-drag grid size-control-lg shrink-0 place-items-center rounded-lg text-foreground/75 hover:bg-accent md:hidden"
|
||||||
|
>
|
||||||
|
<Menu strokeWidth={1.7} className="size-icon-lg" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
data-testid="toggle-bots-sidebar"
|
||||||
|
aria-label={collapsed ? t`Show bots` : t`Minimize bots`}
|
||||||
|
title={collapsed ? t`Show bots` : t`Minimize bots`}
|
||||||
|
onClick={() => onCollapsedChange(!collapsed)}
|
||||||
|
className="app-no-drag hidden size-control-lg shrink-0 place-items-center rounded-lg text-foreground/75 hover:bg-accent md:grid"
|
||||||
|
>
|
||||||
|
{collapsed ? (
|
||||||
|
<PanelLeftOpen strokeWidth={1.7} aria-hidden="true" className="size-icon-lg" />
|
||||||
|
) : (
|
||||||
|
<PanelLeftClose strokeWidth={1.7} aria-hidden="true" className="size-icon-lg" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
73
apps/web/src/pages/shell/user-menu.tsx
Normal file
73
apps/web/src/pages/shell/user-menu.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { Trans, useLingui } from "@lingui/react/macro";
|
||||||
|
import { Button, Popover, PopoverContent, PopoverTrigger } from "@rakazo/ui-web";
|
||||||
|
import { Gauge, LogOut, Settings } from "lucide-react";
|
||||||
|
|
||||||
|
/** The account button at the foot of the sidebar and its menu. */
|
||||||
|
export function UserMenu({
|
||||||
|
open,
|
||||||
|
onOpenChange,
|
||||||
|
initials,
|
||||||
|
userName,
|
||||||
|
onOpenSettings,
|
||||||
|
onOpenUsage,
|
||||||
|
onLogOut,
|
||||||
|
}: {
|
||||||
|
open: boolean;
|
||||||
|
onOpenChange: (open: boolean) => void;
|
||||||
|
initials: string;
|
||||||
|
userName: string;
|
||||||
|
onOpenSettings: () => void;
|
||||||
|
onOpenUsage: () => void;
|
||||||
|
onLogOut: () => void;
|
||||||
|
}) {
|
||||||
|
const { t } = useLingui();
|
||||||
|
return (
|
||||||
|
<Popover open={open} onOpenChange={onOpenChange}>
|
||||||
|
<PopoverTrigger
|
||||||
|
data-testid="user-menu-trigger"
|
||||||
|
className="flex items-center gap-[11px] px-[18px] py-3.5"
|
||||||
|
>
|
||||||
|
<span className="grid size-control-lg place-items-center rounded-full bg-accent text-ui-body-sm text-foreground/75">
|
||||||
|
{initials}
|
||||||
|
</span>
|
||||||
|
<span className="text-[14.5px] text-foreground/90">{userName}</span>
|
||||||
|
</PopoverTrigger>
|
||||||
|
{open ? (
|
||||||
|
<PopoverContent
|
||||||
|
side="top"
|
||||||
|
align="start"
|
||||||
|
className="w-[calc(316px-1.5rem)] max-w-[calc(100vw-3rem)] gap-0 p-1 data-closed:animate-none"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
className="w-full justify-start font-normal"
|
||||||
|
aria-label={t`Settings`}
|
||||||
|
onClick={() => {
|
||||||
|
onOpenChange(false);
|
||||||
|
onOpenSettings();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Settings className="text-muted-foreground" strokeWidth={1.75} />
|
||||||
|
<Trans>Settings</Trans>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
className="w-full justify-start font-normal"
|
||||||
|
aria-label={t`Usage`}
|
||||||
|
onClick={() => {
|
||||||
|
onOpenChange(false);
|
||||||
|
onOpenUsage();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Gauge className="text-muted-foreground" strokeWidth={1.75} />
|
||||||
|
<Trans>Usage</Trans>
|
||||||
|
</Button>
|
||||||
|
<Button variant="ghost" className="w-full justify-start font-normal" onClick={onLogOut}>
|
||||||
|
<LogOut className="text-muted-foreground" strokeWidth={1.75} />
|
||||||
|
<Trans>Log out</Trans>
|
||||||
|
</Button>
|
||||||
|
</PopoverContent>
|
||||||
|
) : null}
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user