Skip to content
Open
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
4 changes: 3 additions & 1 deletion apps/code/src/renderer/api/posthogClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export interface ExternalDataSourceSchema {
id: string;
name: string;
should_sync: boolean;
/** e.g. `full_refresh` (full table replication), `incremental`, `append` */
sync_type?: string | null;
}

export interface ExternalDataSource {
Expand Down Expand Up @@ -327,7 +329,7 @@ export class PostHogAPIClient {
async updateExternalDataSchema(
projectId: number,
schemaId: string,
updates: { should_sync: boolean },
updates: { should_sync: boolean; sync_type?: string },
): Promise<void> {
const urlPath = `/api/projects/${projectId}/external_data_schemas/${schemaId}/`;
const url = new URL(`${this.api.baseUrl}${urlPath}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ const REQUIRED_SCHEMAS: Record<DataSourceType, string[]> = {
zendesk: ["tickets"],
};

/** PostHog DWH: full table replication (non-incremental); API enum value `full_refresh`. */
const FULL_TABLE_REPLICATION = "full_refresh" as const;

function schemasPayload(source: DataSourceType) {
return REQUIRED_SCHEMAS[source].map((name) => ({
name,
should_sync: true,
sync_type: "full_refresh" as const,
sync_type: FULL_TABLE_REPLICATION,
}));
}

Expand Down Expand Up @@ -64,13 +67,20 @@ function GitHubSetup({ onComplete, onCancel }: SetupFormProps) {
}, [repo, repositories]);

const handleSubmit = useCallback(async () => {
if (!projectId || !client || !repo) return;
if (!projectId || !client || !repo || !githubIntegration) return;

setLoading(true);
try {
await client.createExternalDataSource(projectId, {
source_type: "Github",
payload: { repository: repo, schemas: schemasPayload("github") },
payload: {
repository: repo,
auth_method: {
selection: "oauth",
github_integration_id: githubIntegration.id,
},
schemas: schemasPayload("github"),
},
});
toast.success("GitHub data source created");
onComplete();
Expand All @@ -81,11 +91,11 @@ function GitHubSetup({ onComplete, onCancel }: SetupFormProps) {
} finally {
setLoading(false);
}
}, [projectId, client, repo, onComplete]);
}, [projectId, client, repo, githubIntegration, onComplete]);

if (!githubIntegration) {
return (
<SetupFormContainer title="Connect GitHub" onCancel={onCancel}>
<SetupFormContainer title="Connect GitHub">
<Text size="2" style={{ color: "var(--gray-11)" }}>
No GitHub integration found. Please connect GitHub during onboarding
first.
Expand All @@ -95,7 +105,7 @@ function GitHubSetup({ onComplete, onCancel }: SetupFormProps) {
}

return (
<SetupFormContainer title="Connect GitHub" onCancel={onCancel}>
<SetupFormContainer title="Connect GitHub">
<Flex direction="column" gap="3">
<GitHubRepoPicker
value={repo}
Expand All @@ -122,7 +132,7 @@ function GitHubSetup({ onComplete, onCancel }: SetupFormProps) {
const POLL_INTERVAL_MS = 3_000;
const POLL_TIMEOUT_MS = 300_000; // 5 minutes

function LinearSetup({ onComplete, onCancel }: SetupFormProps) {
function LinearSetup({ onComplete }: SetupFormProps) {
const cloudRegion = useAuthStore((s) => s.cloudRegion);
const projectId = useAuthStore((s) => s.projectId);
const client = useAuthStore((s) => s.client);
Expand Down Expand Up @@ -210,7 +220,7 @@ function LinearSetup({ onComplete, onCancel }: SetupFormProps) {
}, [projectId, client, onComplete]);

return (
<SetupFormContainer title="Connect Linear" onCancel={onCancel}>
<SetupFormContainer title="Connect Linear">
<Flex direction="column" gap="3">
<Button
size="2"
Expand All @@ -222,7 +232,7 @@ function LinearSetup({ onComplete, onCancel }: SetupFormProps) {
? "Linear connected"
: loading
? "Waiting for authorization..."
: "Connect Linear"}
: "Log into Linear to continue"}
</Button>

{pollError && (
Expand Down Expand Up @@ -285,7 +295,7 @@ function ZendeskSetup({ onComplete, onCancel }: SetupFormProps) {
const canSubmit = subdomain.trim() && apiKey.trim() && email.trim();

return (
<SetupFormContainer title="Connect Zendesk" onCancel={onCancel}>
<SetupFormContainer title="Connect Zendesk">
<Flex direction="column" gap="3">
<TextField.Root
placeholder="Subdomain (e.g. mycompany)"
Expand Down Expand Up @@ -324,11 +334,9 @@ function ZendeskSetup({ onComplete, onCancel }: SetupFormProps) {

function SetupFormContainer({
title,
onCancel,
children,
}: {
title: string;
onCancel: () => void;
children: React.ReactNode;
}) {
return (
Expand All @@ -344,9 +352,6 @@ function SetupFormContainer({
<Text size="2" weight="medium" style={{ color: "var(--gray-12)" }}>
{title}
</Text>
<Button size="1" variant="ghost" onClick={onCancel}>
Cancel
</Button>
</Flex>
{children}
</Flex>
Expand Down
30 changes: 30 additions & 0 deletions apps/code/src/renderer/features/inbox/components/InboxLiveRail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
interface InboxLiveRailProps {
active: boolean;
}

/**
* Thin “instrument” scan line while live polling is active — industrial / lab aesthetic.
*/
export function InboxLiveRail({ active }: InboxLiveRailProps) {
if (!active) {
return null;
}

return (
<div
className="relative mb-0 h-px w-full overflow-hidden"
style={{ background: "var(--gray-5)" }}
aria-hidden
>
<div
className="absolute inset-y-0 w-[28%] opacity-95"
style={{
background:
"linear-gradient(90deg, transparent, var(--amber-9), var(--orange-9), transparent)",
animation:
"inboxLiveRailSweep 2.1s cubic-bezier(0.45, 0, 0.55, 1) infinite",
}}
/>
</div>
);
}
Loading
Loading