Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ interface IntegrationStore {
interface IntegrationSelectors {
githubIntegrations: Integration[];
hasGithubIntegration: boolean;
slackIntegrations: Integration[];
hasSlackIntegration: boolean;
}

export const useIntegrationStore = create<IntegrationStore>((set) => ({
Expand All @@ -36,9 +38,12 @@ export const useIntegrationStore = create<IntegrationStore>((set) => ({
export const useIntegrationSelectors = (): IntegrationSelectors => {
const integrations = useIntegrationStore((state) => state.integrations);
const githubIntegrations = integrations.filter((i) => i.kind === "github");
const slackIntegrations = integrations.filter((i) => i.kind === "slack");

return {
githubIntegrations,
hasGithubIntegration: githubIntegrations.length > 0,
slackIntegrations,
hasSlackIntegration: slackIntegrations.length > 0,
};
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { useAuthStateValue } from "@features/auth/hooks/authQueries";
import { ArrowSquareOutIcon } from "@phosphor-icons/react";
import { Button, Flex, Text, Tooltip } from "@radix-ui/themes";
import {
type Integration,
useIntegrationSelectors,
} from "@features/integrations/stores/integrationStore";
import { useIntegrations } from "@hooks/useIntegrations";
import { ArrowSquareOutIcon, SlackLogoIcon } from "@phosphor-icons/react";
import { Box, Button, Flex, Spinner, Text, Tooltip } from "@radix-ui/themes";
import { formatRelativeTimeLong } from "@renderer/utils/time";
import { openUrlInBrowser } from "@utils/browser";
import { getPostHogUrl } from "@utils/urls";

export function SlackSettings() {
const projectId = useAuthStateValue((s) => s.projectId);
const cloudRegion = useAuthStateValue((s) => s.cloudRegion);
const { isLoading } = useIntegrations();
const { slackIntegrations, hasSlackIntegration } = useIntegrationSelectors();

const slackSettingsUrl = projectId
? getPostHogUrl(
Expand All @@ -15,7 +23,7 @@ export function SlackSettings() {
)
: null;

const button = (
const manageButton = (
<Button
size="1"
disabled={!slackSettingsUrl}
Expand All @@ -28,19 +36,77 @@ export function SlackSettings() {
</Button>
);

const manageButtonWithTooltip = slackSettingsUrl ? (
manageButton
) : (
<Tooltip content="Sign in to a PostHog project to manage the Slack integration">
{manageButton}
</Tooltip>
);

return (
<Flex direction="column" gap="3">
<Text className="text-(--gray-11) text-[13px]">
Connect Slack to PostHog Code to kick off tasks like pull requests
directly from Slack.
</Text>
<Flex>
{slackSettingsUrl ? (
button

<Flex direction="column" className="border-(--gray-5) border-t">
{isLoading ? (
<Flex align="center" gap="2" py="4">
<Spinner size="1" />
<Text className="text-(--gray-11) text-[13px]">Loading…</Text>
</Flex>
) : hasSlackIntegration ? (
slackIntegrations.map((integration) => (
<SlackIntegrationRow
key={integration.id}
integration={integration}
/>
))
) : (
<Tooltip content="Sign in to a PostHog project to manage the Slack integration">
{button}
</Tooltip>
<Flex align="center" gap="3" py="4">
<Box className="shrink-0 text-(--gray-11)">
<SlackLogoIcon size={20} />
</Box>
<Text className="text-(--gray-11) text-[13px]">
No Slack workspace connected yet.
</Text>
</Flex>
)}
</Flex>

<Flex>{manageButtonWithTooltip}</Flex>
</Flex>
);
}

interface SlackIntegrationRowProps {
integration: Integration;
}

function SlackIntegrationRow({ integration }: SlackIntegrationRowProps) {
const rawDisplayName = integration.display_name;
const workspaceName =
(typeof rawDisplayName === "string" && rawDisplayName.trim()) ||
"Slack workspace";
const createdAt =
typeof integration.created_at === "string" ? integration.created_at : null;

return (
<Flex align="start" gap="3" py="3" className="border-(--gray-5) border-b">
<Box className="shrink-0 text-(--gray-11)">
<SlackLogoIcon size={28} />
</Box>
<Flex direction="column" gap="1" className="min-w-0">
<Text className="text-(--gray-12) text-sm">
<Text className="font-medium">Connected</Text> to{" "}
<Text className="font-medium">{workspaceName}</Text>
</Text>
{createdAt && (
<Text className="text-(--gray-11) text-[13px]">
Created {formatRelativeTimeLong(createdAt)}
</Text>
)}
</Flex>
</Flex>
Expand Down
Loading