Skip to content

Commit 3115ead

Browse files
committed
sig: add paused status indicator to inbox toolbar
1 parent 0906f11 commit 3115ead

5 files changed

Lines changed: 93 additions & 2 deletions

File tree

apps/code/src/renderer/api/posthogClient.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
AvailableSuggestedReviewersResponse,
44
SandboxEnvironment,
55
SandboxEnvironmentInput,
6+
SignalProcessingStateResponse,
67
SignalReport,
78
SignalReportArtefact,
89
SignalReportArtefactsResponse,
@@ -1025,6 +1026,32 @@ export class PostHogAPIClient {
10251026
};
10261027
}
10271028

1029+
async getSignalProcessingState(): Promise<SignalProcessingStateResponse> {
1030+
const teamId = await this.getTeamId();
1031+
const url = new URL(
1032+
`${this.api.baseUrl}/api/projects/${teamId}/signal_processing/`,
1033+
);
1034+
const path = `/api/projects/${teamId}/signal_processing/`;
1035+
1036+
const response = await this.api.fetcher.fetch({
1037+
method: "get",
1038+
url,
1039+
path,
1040+
});
1041+
1042+
if (!response.ok) {
1043+
throw new Error(
1044+
`Failed to fetch signal processing state: ${response.statusText}`,
1045+
);
1046+
}
1047+
1048+
const data = await response.json();
1049+
return {
1050+
paused_until:
1051+
typeof data?.paused_until === "string" ? data.paused_until : null,
1052+
};
1053+
}
1054+
10281055
async getAvailableSuggestedReviewers(
10291056
query?: string,
10301057
): Promise<AvailableSuggestedReviewersResponse> {

apps/code/src/renderer/features/inbox/components/InboxSignalsTab.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { InboxSourcesDialog } from "@features/inbox/components/InboxSourcesDialo
99
import {
1010
useInboxAvailableSuggestedReviewers,
1111
useInboxReportsInfinite,
12+
useInboxSignalProcessingState,
1213
} from "@features/inbox/hooks/useInboxReports";
1314
import { useSignalSourceConfigs } from "@features/inbox/hooks/useSignalSourceConfigs";
1415
import { useInboxReportSelectionStore } from "@features/inbox/stores/inboxReportSelectionStore";
@@ -118,6 +119,13 @@ export function InboxSignalsTab() {
118119
[allReports, searchQuery],
119120
);
120121

122+
const { data: signalProcessingState } = useInboxSignalProcessingState({
123+
enabled: isInboxView,
124+
refetchInterval: inboxPollingActive ? INBOX_REFETCH_INTERVAL_MS : false,
125+
refetchIntervalInBackground: false,
126+
staleTime: inboxPollingActive ? INBOX_REFETCH_INTERVAL_MS : 12_000,
127+
});
128+
121129
const readyCount = useMemo(
122130
() => allReports.filter((r) => r.status === "ready").length,
123131
[allReports],
@@ -378,6 +386,7 @@ export function InboxSignalsTab() {
378386
livePolling={inboxPollingActive}
379387
readyCount={readyCount}
380388
processingCount={processingCount}
389+
pipelinePausedUntil={signalProcessingState?.paused_until}
381390
reports={reports}
382391
/>
383392
</Box>
@@ -447,6 +456,7 @@ export function InboxSignalsTab() {
447456
totalCount={0}
448457
filteredCount={0}
449458
isSearchActive={false}
459+
pipelinePausedUntil={signalProcessingState?.paused_until}
450460
searchDisabledReason={searchDisabledReason}
451461
hideFilters
452462
/>

apps/code/src/renderer/features/inbox/components/list/SignalsToolbar.tsx

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,46 @@ interface SignalsToolbarProps {
3232
livePolling?: boolean;
3333
readyCount?: number;
3434
processingCount?: number;
35+
pipelinePausedUntil?: string | null;
3536
searchDisabledReason?: string | null;
3637
hideFilters?: boolean;
3738
reports?: SignalReport[];
3839
}
3940

41+
function formatPauseRemaining(pausedUntil: string): string {
42+
const diffMs = new Date(pausedUntil).getTime() - Date.now();
43+
44+
if (diffMs <= 0) {
45+
return "resuming soon";
46+
}
47+
48+
const totalMinutes = Math.ceil(diffMs / 60_000);
49+
50+
if (totalMinutes < 60) {
51+
return `${totalMinutes}m`;
52+
}
53+
54+
const hours = Math.floor(totalMinutes / 60);
55+
const minutes = totalMinutes % 60;
56+
57+
if (hours < 24) {
58+
return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
59+
}
60+
61+
const days = Math.floor(hours / 24);
62+
const remainingHours = hours % 24;
63+
64+
return remainingHours > 0 ? `${days}d ${remainingHours}h` : `${days}d`;
65+
}
66+
4067
export function SignalsToolbar({
4168
totalCount,
4269
filteredCount,
4370
isSearchActive,
4471
livePolling = false,
4572
readyCount,
4673
processingCount = 0,
74+
pipelinePausedUntil,
4775
searchDisabledReason,
4876
hideFilters,
4977
reports = [],
@@ -79,10 +107,17 @@ export function SignalsToolbar({
79107
? `${filteredCount} of ${totalCount}`
80108
: `${totalCount}`;
81109

82-
const pipelineHint =
110+
const pipelineHintParts = [
83111
readyCount != null && processingCount > 0
84112
? `${readyCount} ready · ${processingCount} in pipeline`
85-
: null;
113+
: null,
114+
pipelinePausedUntil
115+
? `Pipeline paused · resumes in ${formatPauseRemaining(pipelinePausedUntil)}`
116+
: "Pipeline running",
117+
].filter(Boolean);
118+
119+
const pipelineHint =
120+
pipelineHintParts.length > 0 ? pipelineHintParts.join(" · ") : null;
86121

87122
const handleConfirmSuppress = async () => {
88123
const ok = await suppressSelected();

apps/code/src/renderer/features/inbox/hooks/useInboxReports.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useAuthenticatedInfiniteQuery } from "@hooks/useAuthenticatedInfiniteQu
77
import { useAuthenticatedQuery } from "@hooks/useAuthenticatedQuery";
88
import type {
99
AvailableSuggestedReviewersResponse,
10+
SignalProcessingStateResponse,
1011
SignalReportArtefactsResponse,
1112
SignalReportSignalsResponse,
1213
SignalReportsQueryParams,
@@ -32,6 +33,7 @@ const reportKeys = {
3233
authIdentity ?? "anonymous",
3334
"available-reviewers",
3435
] as const,
36+
signalProcessingState: ["inbox", "signal-processing-state"] as const,
3537
};
3638

3739
export function useInboxReports(
@@ -149,6 +151,19 @@ export function useInboxAvailableSuggestedReviewers(options?: {
149151
return query;
150152
}
151153

154+
export function useInboxSignalProcessingState(options?: {
155+
enabled?: boolean;
156+
refetchInterval?: number | false | (() => number | false | undefined);
157+
refetchIntervalInBackground?: boolean;
158+
staleTime?: number;
159+
}) {
160+
return useAuthenticatedQuery<SignalProcessingStateResponse>(
161+
reportKeys.signalProcessingState,
162+
(client) => client.getSignalProcessingState(),
163+
options,
164+
);
165+
}
166+
152167
export function useInboxReportArtefacts(
153168
reportId: string,
154169
options?: { enabled?: boolean },

apps/code/src/shared/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,10 @@ export interface SignalReportsResponse {
282282
count: number;
283283
}
284284

285+
export interface SignalProcessingStateResponse {
286+
paused_until: string | null;
287+
}
288+
285289
export interface AvailableSuggestedReviewersResponse {
286290
results: AvailableSuggestedReviewer[];
287291
count: number;

0 commit comments

Comments
 (0)