Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion desktop/src/app/AppShell.helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export type AppView =
| "agents"
| "workflows"
| "pulse"
| "projects";
| "projects"
| "workstreamBoard";

const WINDOW_DRAG_HANDLE_HEIGHT = 44;
const TAURI_DRAG_REGION_ATTR = "data-tauri-drag-region";
Expand Down Expand Up @@ -181,6 +182,13 @@ export function deriveShellRoute(pathname: string): {
};
}

if (pathname === "/workstreams" || pathname.startsWith("/workstreams/")) {
return {
selectedChannelId: null,
selectedView: "workstreamBoard",
};
}

if (pathname === "/pulse") {
return {
selectedChannelId: null,
Expand Down
2 changes: 2 additions & 0 deletions desktop/src/app/AppShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export function AppShell() {
goPulse,
goSettings,
goWorkflows,
goWorkstreams,
closeSettings,
openSearchHit,
} = useAppNavigation();
Expand Down Expand Up @@ -878,6 +879,7 @@ export function AppShell() {
onSelectPulse={() => void goPulse()}
onSelectSettings={handleOpenSettings}
onSelectWorkflows={() => void goWorkflows()}
onSelectWorkstreamBoard={() => void goWorkstreams()}
onSetPresenceStatus={(status) =>
presenceSession.setStatus(status)
}
Expand Down
12 changes: 12 additions & 0 deletions desktop/src/app/navigation/useAppNavigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,17 @@ export function useAppNavigation() {
[commitNavigation],
);

const goWorkstreams = React.useCallback(
(behavior?: NavigationBehavior) =>
commitNavigation(
{
to: "/workstreams",
},
behavior,
),
[commitNavigation],
);

const goWorkflow = React.useCallback(
(workflowId: string, behavior?: NavigationBehavior) =>
commitNavigation(
Expand Down Expand Up @@ -340,6 +351,7 @@ export function useAppNavigation() {
goSettings,
goWorkflow,
goWorkflows,
goWorkstreams,
openSearchHit,
};
}
21 changes: 21 additions & 0 deletions desktop/src/app/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.

import { Route as rootRouteImport } from "./routes/root";
import { Route as workstreamsRouteImport } from "./routes/workstreams";
import { Route as workflowsRouteImport } from "./routes/workflows";
import { Route as settingsRouteImport } from "./routes/settings";
import { Route as remindersRouteImport } from "./routes/reminders";
Expand All @@ -18,6 +19,11 @@ import { Route as messagesDotnewRouteImport } from "./routes/messages.new";
import { Route as channelsDotchannelIdRouteImport } from "./routes/channels.$channelId";
import { Route as channelsDotchannelIdDotpostsDotpostIdRouteImport } from "./routes/channels.$channelId.posts.$postId";

const workstreamsRoute = workstreamsRouteImport.update({
id: "/workstreams",
path: "/workstreams",
getParentRoute: () => rootRouteImport,
} as any);
const workflowsRoute = workflowsRouteImport.update({
id: "/workflows",
path: "/workflows",
Expand Down Expand Up @@ -88,6 +94,7 @@ export interface FileRoutesByFullPath {
"/reminders": typeof remindersRoute;
"/settings": typeof settingsRoute;
"/workflows": typeof workflowsRoute;
"/workstreams": typeof workstreamsRoute;
"/channels/$channelId": typeof channelsDotchannelIdRoute;
"/messages/new": typeof messagesDotnewRoute;
"/projects/$projectId": typeof projectsDotprojectIdRoute;
Expand All @@ -102,6 +109,7 @@ export interface FileRoutesByTo {
"/reminders": typeof remindersRoute;
"/settings": typeof settingsRoute;
"/workflows": typeof workflowsRoute;
"/workstreams": typeof workstreamsRoute;
"/channels/$channelId": typeof channelsDotchannelIdRoute;
"/messages/new": typeof messagesDotnewRoute;
"/projects/$projectId": typeof projectsDotprojectIdRoute;
Expand All @@ -117,6 +125,7 @@ export interface FileRoutesById {
"/reminders": typeof remindersRoute;
"/settings": typeof settingsRoute;
"/workflows": typeof workflowsRoute;
"/workstreams": typeof workstreamsRoute;
"/channels/$channelId": typeof channelsDotchannelIdRoute;
"/messages/new": typeof messagesDotnewRoute;
"/projects/$projectId": typeof projectsDotprojectIdRoute;
Expand All @@ -133,6 +142,7 @@ export interface FileRouteTypes {
| "/reminders"
| "/settings"
| "/workflows"
| "/workstreams"
| "/channels/$channelId"
| "/messages/new"
| "/projects/$projectId"
Expand All @@ -147,6 +157,7 @@ export interface FileRouteTypes {
| "/reminders"
| "/settings"
| "/workflows"
| "/workstreams"
| "/channels/$channelId"
| "/messages/new"
| "/projects/$projectId"
Expand All @@ -161,6 +172,7 @@ export interface FileRouteTypes {
| "/reminders"
| "/settings"
| "/workflows"
| "/workstreams"
| "/channels/$channelId"
| "/messages/new"
| "/projects/$projectId"
Expand All @@ -176,6 +188,7 @@ export interface RootRouteChildren {
remindersRoute: typeof remindersRoute;
settingsRoute: typeof settingsRoute;
workflowsRoute: typeof workflowsRoute;
workstreamsRoute: typeof workstreamsRoute;
channelsDotchannelIdRoute: typeof channelsDotchannelIdRoute;
messagesDotnewRoute: typeof messagesDotnewRoute;
projectsDotprojectIdRoute: typeof projectsDotprojectIdRoute;
Expand All @@ -185,6 +198,13 @@ export interface RootRouteChildren {

declare module "@tanstack/react-router" {
interface FileRoutesByPath {
"/workstreams": {
id: "/workstreams";
path: "/workstreams";
fullPath: "/workstreams";
preLoaderRoute: typeof workstreamsRouteImport;
parentRoute: typeof rootRouteImport;
};
"/workflows": {
id: "/workflows";
path: "/workflows";
Expand Down Expand Up @@ -280,6 +300,7 @@ const rootRouteChildren: RootRouteChildren = {
remindersRoute: remindersRoute,
settingsRoute: settingsRoute,
workflowsRoute: workflowsRoute,
workstreamsRoute: workstreamsRoute,
channelsDotchannelIdRoute: channelsDotchannelIdRoute,
messagesDotnewRoute: messagesDotnewRoute,
projectsDotprojectIdRoute: projectsDotprojectIdRoute,
Expand Down
1 change: 1 addition & 0 deletions desktop/src/app/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const routes = rootRoute("root.tsx", [
route("/workflows/$workflowId", "workflows.$workflowId.tsx"),
route("/projects", "projects.tsx"),
route("/projects/$projectId", "projects.$projectId.tsx"),
route("/workstreams", "workstreams.tsx"),
route("/messages/new", "messages.new.tsx"),
route("/channels/$channelId", "channels.$channelId.tsx"),
route(
Expand Down
25 changes: 25 additions & 0 deletions desktop/src/app/routes/workstreams.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as React from "react";
import { createFileRoute } from "@tanstack/react-router";

import { usePreviewFeatureWarning } from "@/shared/features";
import { ViewLoadingFallback } from "@/shared/ui/ViewLoadingFallback";

const WorkstreamBoardScreen = React.lazy(async () => {
const module = await import(
"@/features/workstream-board/ui/WorkstreamBoardScreen"
);
return { default: module.WorkstreamBoardScreen };
});

export const Route = createFileRoute("/workstreams")({
component: WorkstreamsRouteComponent,
});

function WorkstreamsRouteComponent() {
usePreviewFeatureWarning("workstreamBoard");
return (
<React.Suspense fallback={<ViewLoadingFallback kind="projects" />}>
<WorkstreamBoardScreen />
</React.Suspense>
);
}
2 changes: 2 additions & 0 deletions desktop/src/features/sidebar/ui/AppSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export function AppSidebar({
onSelectProjects,
onSelectPulse,
onSelectWorkflows,
onSelectWorkstreamBoard,
onSelectHome,
onSelectChannel,
onOpenSearchResult,
Expand Down Expand Up @@ -511,6 +512,7 @@ export function AppSidebar({
onSelectProjects={onSelectProjects}
onSelectPulse={onSelectPulse}
onSelectWorkflows={onSelectWorkflows}
onSelectWorkstreamBoard={onSelectWorkstreamBoard}
projectsOverviewActive={projectsOverviewActive}
selectedView={selectedView}
/>
Expand Down
4 changes: 3 additions & 1 deletion desktop/src/features/sidebar/ui/AppSidebar.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export type AppSidebarProps = {
| "agents"
| "workflows"
| "pulse"
| "projects";
| "projects"
| "workstreamBoard";
unreadChannelCounts: ReadonlyMap<string, number>;
unreadChannelIds: ReadonlySet<string>;
previewActivityChannelIds: ReadonlySet<string>;
Expand Down Expand Up @@ -86,6 +87,7 @@ export type AppSidebarProps = {
onSelectProjects: () => void;
onSelectPulse: () => void;
onSelectWorkflows: () => void;
onSelectWorkstreamBoard: () => void;
onSelectHome: () => void;
onSelectChannel: (channelId: string) => void;
onOpenSearchResult: (hit: SearchHit) => void;
Expand Down
21 changes: 19 additions & 2 deletions desktop/src/features/sidebar/ui/AppSidebarPinnedHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Activity, Bot, Folders, Inbox, Zap } from "lucide-react";
import { Activity, Bot, Folders, Inbox, Kanban, Zap } from "lucide-react";

import { TopbarSearch } from "@/features/search/ui/TopbarSearch";
import { SidebarProjectsSection } from "@/features/sidebar/ui/SidebarProjectsSection";
Expand All @@ -20,7 +20,8 @@ type SidebarSelectedView =
| "agents"
| "workflows"
| "pulse"
| "projects";
| "projects"
| "workstreamBoard";

type AppSidebarPinnedHeaderProps = {
channelLabels: Record<string, string>;
Expand All @@ -45,6 +46,7 @@ type AppSidebarPrimaryMenuProps = {
onSelectProjects: () => void;
onSelectPulse: () => void;
onSelectWorkflows: () => void;
onSelectWorkstreamBoard: () => void;
projectsOverviewActive: boolean;
selectedView: SidebarSelectedView;
};
Expand Down Expand Up @@ -95,6 +97,7 @@ export function AppSidebarPrimaryMenu({
onSelectProjects,
onSelectPulse,
onSelectWorkflows,
onSelectWorkstreamBoard,
projectsOverviewActive,
selectedView,
}: AppSidebarPrimaryMenuProps) {
Expand Down Expand Up @@ -181,6 +184,20 @@ export function AppSidebarPrimaryMenu({
</SidebarMenuButton>
</SidebarMenuItem>
</FeatureGate>
<FeatureGate feature="workstreamBoard">
<SidebarMenuItem>
<SidebarMenuButton
data-testid="open-workstream-board-view"
isActive={selectedView === "workstreamBoard"}
onClick={onSelectWorkstreamBoard}
tooltip="Workstream Board"
type="button"
>
<Kanban className="h-4 w-4" />
<SidebarMenuLabel>Workstream Board</SidebarMenuLabel>
</SidebarMenuButton>
</SidebarMenuItem>
</FeatureGate>
</SidebarMenu>
</SidebarHeader>
<SidebarProjectsSection />
Expand Down
Loading
Loading