mirror of https://github.com/buster-so/buster.git
Make slack cards better
This commit is contained in:
parent
35a160301a
commit
6f6e70c54c
|
@ -1,7 +1,4 @@
|
|||
import type {
|
||||
GetIntegrationResponse,
|
||||
GetChannelsResponse
|
||||
} from '@buster/server-shared/slack';
|
||||
import type { GetIntegrationResponse, GetChannelsResponse } from '@buster/server-shared/slack';
|
||||
import { queryOptions } from '@tanstack/react-query';
|
||||
|
||||
export const slackGetIntegration = queryOptions<GetIntegrationResponse>({
|
||||
|
@ -9,10 +6,10 @@ export const slackGetIntegration = queryOptions<GetIntegrationResponse>({
|
|||
});
|
||||
|
||||
export const slackGetChannels = queryOptions<GetChannelsResponse>({
|
||||
queryKey: ['slack', 'channels']
|
||||
queryKey: ['slack', 'channels', 'list']
|
||||
});
|
||||
|
||||
export const slackQueryKeys = {
|
||||
slackGetIntegration,
|
||||
slackGetChannels
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { SettingsCards } from '../settings/SettingsCard';
|
||||
import { SlackIcon } from '@/components/ui/icons/customIcons/SlackIcon';
|
||||
import { Text } from '@/components/ui/typography';
|
||||
|
@ -15,25 +15,34 @@ import {
|
|||
import { Dropdown, type DropdownItems } from '@/components/ui/dropdown';
|
||||
import { LinkSlash, Refresh2 } from '@/components/ui/icons';
|
||||
import { Select } from '@/components/ui/select';
|
||||
import { StatusCard } from '@/components/ui/card/StatusCard';
|
||||
import { useMemoizedFn } from '@/hooks';
|
||||
|
||||
export const SlackIntegrations = React.memo(() => {
|
||||
const { data: slackIntegration } = useGetSlackIntegration();
|
||||
const {
|
||||
data: slackIntegration,
|
||||
isFetched: isFetchedSlackIntegration,
|
||||
error: slackIntegrationError
|
||||
} = useGetSlackIntegration();
|
||||
const isConnected = slackIntegration?.connected ?? false;
|
||||
|
||||
return (
|
||||
<SettingsCards
|
||||
title="Slack"
|
||||
description="Connect Buster with Slack"
|
||||
cards={[
|
||||
{
|
||||
sections: [
|
||||
<ConnectSlackCard key="connect-slack-card" />,
|
||||
isConnected && <ConnectedSlackChannels key="connected-slack-channels" />
|
||||
].filter(Boolean)
|
||||
}
|
||||
]}
|
||||
/>
|
||||
);
|
||||
const cards = useMemo(() => {
|
||||
const sections = [
|
||||
<ConnectSlackCard key="connect-slack-card" />,
|
||||
isConnected && <ConnectedSlackChannels key="connected-slack-channels" />
|
||||
].filter(Boolean);
|
||||
return [{ sections }];
|
||||
}, [isConnected]);
|
||||
|
||||
if (slackIntegrationError) {
|
||||
return <StatusCard message="Error fetching slack integration." variant={'danger'} />;
|
||||
}
|
||||
|
||||
if (!isFetchedSlackIntegration) {
|
||||
return <div className="bg-gray-light/50 h-24 w-full animate-pulse rounded"></div>;
|
||||
}
|
||||
|
||||
return <SettingsCards title="Slack" description="Connect Buster with Slack" cards={cards} />;
|
||||
});
|
||||
|
||||
SlackIntegrations.displayName = 'SlackIntegrations';
|
||||
|
@ -112,6 +121,21 @@ const ConnectedSlackChannels = React.memo(() => {
|
|||
const channels = slackChannelsData?.channels || [];
|
||||
const selectedChannelId = slackIntegration?.integration?.default_channel?.id;
|
||||
|
||||
const items = useMemo(() => {
|
||||
return channels.map((channel) => ({
|
||||
label: channel.name,
|
||||
value: channel.id
|
||||
}));
|
||||
}, [channels]);
|
||||
|
||||
const onChange = useMemoizedFn((channelId: string) => {
|
||||
const channel = channels.find((channel) => channel.id === channelId);
|
||||
if (!channel) return;
|
||||
updateSlackIntegration({
|
||||
default_channel: channel
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between space-x-4">
|
||||
<div className="flex flex-col space-y-0.5">
|
||||
|
@ -125,7 +149,7 @@ const ConnectedSlackChannels = React.memo(() => {
|
|||
<>
|
||||
{isFetchedSlackChannels && (
|
||||
<Button
|
||||
size={'small'}
|
||||
size={'tall'}
|
||||
variant="ghost"
|
||||
suffix={<Refresh2 />}
|
||||
onClick={() => refetchSlackChannels()}>
|
||||
|
@ -135,19 +159,10 @@ const ConnectedSlackChannels = React.memo(() => {
|
|||
|
||||
<Select
|
||||
className="w-fit min-w-40"
|
||||
items={channels.map((channel) => ({
|
||||
label: channel.name,
|
||||
value: channel.id
|
||||
}))}
|
||||
items={items}
|
||||
placeholder="Select a channel"
|
||||
value={selectedChannelId}
|
||||
onChange={(channelId) => {
|
||||
const channel = channels.find((channel) => channel.id === channelId);
|
||||
if (!channel) return;
|
||||
updateSlackIntegration({
|
||||
default_channel: channel
|
||||
});
|
||||
}}
|
||||
onChange={onChange}
|
||||
loading={isLoadingSlackChannels || isLoadingSlackIntegration}
|
||||
/>
|
||||
</>
|
||||
|
|
|
@ -10,21 +10,24 @@ interface SettingsCardsProps {
|
|||
}[];
|
||||
}
|
||||
|
||||
export const SettingsCards: React.FC<SettingsCardsProps> = ({ title, description, cards }) => {
|
||||
return (
|
||||
<div className="flex flex-col space-y-3.5">
|
||||
<div className="flex flex-col space-y-1.5">
|
||||
<Title as="h3" className="text-lg">
|
||||
{title}
|
||||
</Title>
|
||||
<Paragraph variant="secondary">{description}</Paragraph>
|
||||
export const SettingsCards: React.FC<SettingsCardsProps> = React.memo(
|
||||
({ title, description, cards }) => {
|
||||
return (
|
||||
<div className="flex flex-col space-y-3.5">
|
||||
<div className="flex flex-col space-y-1.5">
|
||||
<Title as="h3" className="text-lg">
|
||||
{title}
|
||||
</Title>
|
||||
<Paragraph variant="secondary">{description}</Paragraph>
|
||||
</div>
|
||||
{cards.map((card, index) => (
|
||||
<SettingsCard key={index} sections={card.sections} />
|
||||
))}
|
||||
</div>
|
||||
{cards.map((card, index) => (
|
||||
<SettingsCard key={index} sections={card.sections} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
);
|
||||
}
|
||||
);
|
||||
SettingsCards.displayName = 'SettingsCards';
|
||||
|
||||
const SettingsCard = ({ sections }: { sections: React.ReactNode[] }) => {
|
||||
return (
|
||||
|
|
|
@ -8,7 +8,7 @@ const buster = packageJson.version;
|
|||
|
||||
export const PERSIST_TIME = 1000 * 60 * 60 * 24 * 7; // 7 days
|
||||
|
||||
export const PERSISTED_QUERIES = [].map(hashKey);
|
||||
export const PERSISTED_QUERIES = [queryKeys.slackGetChannels.queryKey].map(hashKey);
|
||||
|
||||
export const PERMANENT_QUERIES = [queryKeys.getCurrencies.queryKey].map(hashKey);
|
||||
|
||||
|
|
Loading…
Reference in New Issue