mirror of https://github.com/buster-so/buster.git
add provider for chats
This commit is contained in:
parent
604bfbdd6c
commit
d5ee691de4
Binary file not shown.
|
@ -1,3 +1,6 @@
|
||||||
|
import type { FileType } from '../config';
|
||||||
|
|
||||||
export type BusterCollectionAsset = {
|
export type BusterCollectionAsset = {
|
||||||
id: string;
|
id: string;
|
||||||
|
type: FileType.COLLECTION;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import type { BusterDashboardMetric } from '../../../buster_rest/dashboards';
|
import type { BusterDashboardMetric } from '../../../buster_rest/dashboards';
|
||||||
import type { DashboardConfig } from '../../dashboards';
|
import type { DashboardConfig } from '../../dashboards';
|
||||||
|
import type { FileType } from '../config';
|
||||||
|
|
||||||
export type BusterDashboardAsset = {
|
export type BusterDashboardAsset = {
|
||||||
id: string;
|
id: string;
|
||||||
|
type: FileType.DASHBOARD;
|
||||||
metrics: BusterDashboardMetric[];
|
metrics: BusterDashboardMetric[];
|
||||||
config: DashboardConfig;
|
config: DashboardConfig;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import type { FileType } from '../config';
|
||||||
|
|
||||||
export type BusterDatasetAsset = {
|
export type BusterDatasetAsset = {
|
||||||
id: string;
|
id: string;
|
||||||
|
type: FileType.DATASET;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import type { BusterChartConfigProps } from '@/components/charts';
|
import type { BusterChartConfigProps } from '@/components/charts';
|
||||||
|
import type { FileType } from '../config';
|
||||||
|
|
||||||
export type BusterMetricAsset = {
|
export type BusterMetricAsset = {
|
||||||
id: string;
|
id: string;
|
||||||
|
type: FileType.METRIC;
|
||||||
title: string;
|
title: string;
|
||||||
description: string | null;
|
description: string | null;
|
||||||
time_frame: string;
|
time_frame: string;
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import type { FileType } from '../config';
|
||||||
|
|
||||||
export type BusterTermAsset = {
|
export type BusterTermAsset = {
|
||||||
id: string;
|
id: string;
|
||||||
|
type: FileType.TERM;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import type { FileType } from '../config';
|
||||||
|
|
||||||
export type BusterValueAsset = {
|
export type BusterValueAsset = {
|
||||||
id: string;
|
id: string;
|
||||||
|
type: FileType.VALUE;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { BusterChatMessage } from './chatMessageInterfaces';
|
import type { BusterChatMessage } from './chatMessageInterfaces';
|
||||||
|
|
||||||
export interface BusterChat {
|
export interface IBusterChat {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
is_favorited: boolean;
|
is_favorited: boolean;
|
||||||
|
|
|
@ -19,7 +19,7 @@ export type ChatUnsubscribeFromChat = BusterSocketRequestBase<'/chats/unsubscrib
|
||||||
|
|
||||||
export type ChatGetChatAsset = BusterSocketRequestBase<
|
export type ChatGetChatAsset = BusterSocketRequestBase<
|
||||||
'/chats/get/asset',
|
'/chats/get/asset',
|
||||||
{ id: string; type: FileType; version_id?: string }
|
{ chat_id?: string; asset_id: string; type: FileType; version_id?: string }
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type ChatListEmitPayload = BusterSocketRequestBase<
|
export type ChatListEmitPayload = BusterSocketRequestBase<
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { RustApiError } from '../../buster_rest/errors';
|
import type { RustApiError } from '../../buster_rest/errors';
|
||||||
import type { BusterChatAsset } from './chatAssetInterfaces';
|
import type { BusterChatAsset } from './chatAssetInterfaces';
|
||||||
import type { BusterChat, BusterChatListItem } from './chatInterfaces';
|
import type { IBusterChat, BusterChatListItem } from './chatInterfaces';
|
||||||
|
|
||||||
export enum ChatsResponses {
|
export enum ChatsResponses {
|
||||||
'/chats/list:getChatsList' = '/chats/list:getChatsList',
|
'/chats/list:getChatsList' = '/chats/list:getChatsList',
|
||||||
|
@ -25,7 +25,7 @@ export type Chat_unsubscribed = {
|
||||||
|
|
||||||
export type Chat_getChat = {
|
export type Chat_getChat = {
|
||||||
route: '/chats/get:getChat';
|
route: '/chats/get:getChat';
|
||||||
callback: (d: BusterChat) => void;
|
callback: (d: IBusterChat) => void;
|
||||||
onError?: (d: unknown | RustApiError) => void;
|
onError?: (d: unknown | RustApiError) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,13 +39,13 @@ export type Chat_getChatAsset = {
|
||||||
|
|
||||||
export type ChatPost_initializeChat = {
|
export type ChatPost_initializeChat = {
|
||||||
route: '/chats/post:initializeChat';
|
route: '/chats/post:initializeChat';
|
||||||
callback: (d: BusterChat) => void;
|
callback: (d: IBusterChat) => void;
|
||||||
onError?: (d: unknown | RustApiError) => void;
|
onError?: (d: unknown | RustApiError) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ChatPost_generatingTitle = {
|
export type ChatPost_generatingTitle = {
|
||||||
route: '/chats/post:generatingTitle';
|
route: '/chats/post:generatingTitle';
|
||||||
callback: (d: BusterChat) => void;
|
callback: (d: IBusterChat) => void;
|
||||||
onError?: (d: unknown | RustApiError) => void;
|
onError?: (d: unknown | RustApiError) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
export * from './chatAssetInterfaces';
|
export * from './chatAssetInterfaces';
|
||||||
|
export * from './chatInterfaces';
|
||||||
export * from './chatRequests';
|
export * from './chatRequests';
|
||||||
export * from './chatResponses';
|
export * from './chatResponses';
|
||||||
|
export * from './config';
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {
|
||||||
OrganizationResponsesTypes,
|
OrganizationResponsesTypes,
|
||||||
OrganizationsEmits
|
OrganizationsEmits
|
||||||
} from './organizations';
|
} from './organizations';
|
||||||
|
import { ChatEmits, ChatResponseTypes, ChatsResponses } from './chats';
|
||||||
|
|
||||||
export type BusterSocketRequest =
|
export type BusterSocketRequest =
|
||||||
| ThreadEmits
|
| ThreadEmits
|
||||||
|
@ -31,7 +32,8 @@ export type BusterSocketRequest =
|
||||||
| TermsEmits
|
| TermsEmits
|
||||||
| PermissionsEmits
|
| PermissionsEmits
|
||||||
| BusterSearchEmits
|
| BusterSearchEmits
|
||||||
| OrganizationsEmits;
|
| OrganizationsEmits
|
||||||
|
| ChatEmits;
|
||||||
|
|
||||||
export type BusterSocketResponse =
|
export type BusterSocketResponse =
|
||||||
| ThreadResponseTypes
|
| ThreadResponseTypes
|
||||||
|
@ -45,7 +47,8 @@ export type BusterSocketResponse =
|
||||||
| TermsResponseTypes
|
| TermsResponseTypes
|
||||||
| PermissionsResponseTypes
|
| PermissionsResponseTypes
|
||||||
| SearchResponseTypes
|
| SearchResponseTypes
|
||||||
| OrganizationResponsesTypes;
|
| OrganizationResponsesTypes
|
||||||
|
| ChatResponseTypes;
|
||||||
|
|
||||||
export type BusterSocketResponseRoute =
|
export type BusterSocketResponseRoute =
|
||||||
| keyof typeof ThreadResponses
|
| keyof typeof ThreadResponses
|
||||||
|
@ -59,4 +62,5 @@ export type BusterSocketResponseRoute =
|
||||||
| keyof typeof TermsResponses
|
| keyof typeof TermsResponses
|
||||||
| keyof typeof PermissionsResponses
|
| keyof typeof PermissionsResponses
|
||||||
| keyof typeof SearchResponses
|
| keyof typeof SearchResponses
|
||||||
| keyof typeof OrganizationResponses;
|
| keyof typeof OrganizationResponses
|
||||||
|
| keyof typeof ChatsResponses;
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { BusterAssetsProvider } from './Assets/BusterAssetsProvider';
|
||||||
import { BusterUserResponse } from '@/api/buster_rest/users';
|
import { BusterUserResponse } from '@/api/buster_rest/users';
|
||||||
import { BusterPosthogProvider } from './Posthog/usePosthog';
|
import { BusterPosthogProvider } from './Posthog/usePosthog';
|
||||||
import { BusterNotificationsProvider } from './BusterNotifications';
|
import { BusterNotificationsProvider } from './BusterNotifications';
|
||||||
|
import { BusterChatProvider } from './Chats';
|
||||||
import { RoutePrefetcher } from './RoutePrefetcher';
|
import { RoutePrefetcher } from './RoutePrefetcher';
|
||||||
import { BusterMessageDataProvider } from './MessageData';
|
import { BusterMessageDataProvider } from './MessageData';
|
||||||
|
|
||||||
|
@ -66,16 +67,19 @@ export const AppProviders: React.FC<
|
||||||
<BusterCollectionsProvider>
|
<BusterCollectionsProvider>
|
||||||
<BusterMessageDataProvider>
|
<BusterMessageDataProvider>
|
||||||
<BusterDashboardProvider>
|
<BusterDashboardProvider>
|
||||||
|
{/* TODO: remove when we are ready to use chats */}
|
||||||
<BusterThreadsProvider>
|
<BusterThreadsProvider>
|
||||||
<BusterSQLProvider>
|
<BusterSQLProvider>
|
||||||
<BusterTermsProvider>
|
<BusterTermsProvider>
|
||||||
<BusterPermissionsProvider>
|
<BusterPermissionsProvider>
|
||||||
|
<BusterChatProvider>
|
||||||
<AppHotKeysProvider>
|
<AppHotKeysProvider>
|
||||||
<BusterPosthogProvider>
|
<BusterPosthogProvider>
|
||||||
{children}
|
{children}
|
||||||
<RoutePrefetcher />
|
<RoutePrefetcher />
|
||||||
</BusterPosthogProvider>
|
</BusterPosthogProvider>
|
||||||
</AppHotKeysProvider>
|
</AppHotKeysProvider>
|
||||||
|
</BusterChatProvider>
|
||||||
</BusterPermissionsProvider>
|
</BusterPermissionsProvider>
|
||||||
</BusterTermsProvider>
|
</BusterTermsProvider>
|
||||||
</BusterSQLProvider>
|
</BusterSQLProvider>
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
import React, { useCallback, useRef, useState, useTransition } from 'react';
|
||||||
|
import {
|
||||||
|
createContext,
|
||||||
|
ContextSelector,
|
||||||
|
useContextSelector
|
||||||
|
} from '@fluentui/react-context-selector';
|
||||||
|
import { useBusterWebSocket } from '../BusterWebSocket';
|
||||||
|
import type { BusterChatAsset, IBusterChat } from '@/api/buster_socket/chats';
|
||||||
|
import { useMemoizedFn, useMount, useUnmount } from 'ahooks';
|
||||||
|
import type { FileType } from '@/api/buster_socket/chats';
|
||||||
|
|
||||||
|
export const useBusterChat = () => {
|
||||||
|
const busterSocket = useBusterWebSocket();
|
||||||
|
const [isPending, startTransition] = useTransition();
|
||||||
|
const chatsRef = useRef<Record<string, IBusterChat>>({});
|
||||||
|
const [seletedAssetId, setSeletedAssetId] = useState<Record<string, string | null>>({});
|
||||||
|
|
||||||
|
// GETTERS
|
||||||
|
|
||||||
|
const getSelectedAssetId = useCallback(
|
||||||
|
(chatId: string) => {
|
||||||
|
return seletedAssetId[chatId] || null;
|
||||||
|
},
|
||||||
|
[seletedAssetId]
|
||||||
|
);
|
||||||
|
|
||||||
|
// SETTERS
|
||||||
|
|
||||||
|
const onSetSelectedAssetId = useMemoizedFn((chatId: string, assetId: string | null) => {
|
||||||
|
setSeletedAssetId((prev) => ({ ...prev, [chatId]: assetId }));
|
||||||
|
});
|
||||||
|
|
||||||
|
// LISTENERS
|
||||||
|
|
||||||
|
const _onGetChat = useMemoizedFn((chat: IBusterChat) => {
|
||||||
|
chatsRef.current[chat.id] = chat;
|
||||||
|
startTransition(() => {
|
||||||
|
//just used to trigger UI update
|
||||||
|
});
|
||||||
|
return chat;
|
||||||
|
});
|
||||||
|
|
||||||
|
const _onGetChatAsset = useMemoizedFn((asset: BusterChatAsset) => {
|
||||||
|
const { id, type } = asset;
|
||||||
|
console.log('TODO: handle this. Put the asset in their respective chat');
|
||||||
|
return asset;
|
||||||
|
});
|
||||||
|
|
||||||
|
// EMITTERS
|
||||||
|
|
||||||
|
const unsubscribeFromChat = useMemoizedFn(({ chatId }: { chatId: string }) => {
|
||||||
|
return busterSocket.emit({
|
||||||
|
route: '/chats/unsubscribe',
|
||||||
|
payload: {
|
||||||
|
id: chatId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const subscribeToChat = useMemoizedFn(({ chatId }: { chatId: string }) => {
|
||||||
|
return busterSocket.emitAndOnce({
|
||||||
|
emitEvent: {
|
||||||
|
route: '/chats/get',
|
||||||
|
payload: {
|
||||||
|
id: chatId
|
||||||
|
}
|
||||||
|
},
|
||||||
|
responseEvent: {
|
||||||
|
route: '/chats/get:getChat',
|
||||||
|
callback: _onGetChat
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const getChatAsset = useMemoizedFn(
|
||||||
|
({
|
||||||
|
chatId: chat_id,
|
||||||
|
assetId: asset_id,
|
||||||
|
type,
|
||||||
|
versionId: version_id
|
||||||
|
}: {
|
||||||
|
chatId?: string;
|
||||||
|
assetId: string;
|
||||||
|
type: FileType;
|
||||||
|
versionId?: string;
|
||||||
|
}) => {
|
||||||
|
return busterSocket.emitAndOnce({
|
||||||
|
emitEvent: {
|
||||||
|
route: '/chats/get/asset',
|
||||||
|
payload: {
|
||||||
|
type,
|
||||||
|
chat_id,
|
||||||
|
asset_id,
|
||||||
|
version_id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
responseEvent: {
|
||||||
|
route: '/chats/get:getChatAsset',
|
||||||
|
callback: _onGetChatAsset
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
getSelectedAssetId,
|
||||||
|
chats: chatsRef.current,
|
||||||
|
unsubscribeFromChat,
|
||||||
|
subscribeToChat,
|
||||||
|
getChatAsset,
|
||||||
|
onSetSelectedAssetId
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const BusterChat = createContext<ReturnType<typeof useBusterChat>>(
|
||||||
|
{} as ReturnType<typeof useBusterChat>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const BusterChatProvider: React.FC<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}> = ({ children }) => {
|
||||||
|
const value = useBusterChat();
|
||||||
|
|
||||||
|
return <BusterChat.Provider value={value}>{children}</BusterChat.Provider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useBusterChatContextSelector = <T,>(
|
||||||
|
selector: ContextSelector<ReturnType<typeof useBusterChat>, T>
|
||||||
|
) => useContextSelector(BusterChat, selector);
|
||||||
|
|
||||||
|
export const useBusterChatIndividual = ({ chatId }: { chatId: string }) => {
|
||||||
|
const chat = useBusterChatContextSelector((x) => x.chats[chatId]);
|
||||||
|
const subscribeToChat = useBusterChatContextSelector((x) => x.subscribeToChat);
|
||||||
|
const unsubscribeFromChat = useBusterChatContextSelector((x) => x.unsubscribeFromChat);
|
||||||
|
const selectedAssetId = useBusterChatContextSelector((x) => x.getSelectedAssetId(chatId));
|
||||||
|
const onSetSelectedAssetId = useBusterChatContextSelector((x) => x.onSetSelectedAssetId);
|
||||||
|
|
||||||
|
useMount(() => {
|
||||||
|
subscribeToChat({ chatId });
|
||||||
|
});
|
||||||
|
|
||||||
|
useUnmount(() => {
|
||||||
|
unsubscribeFromChat({ chatId });
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
chat,
|
||||||
|
selectedAssetId,
|
||||||
|
onSetSelectedAssetId
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './ChatProvider';
|
|
@ -1,35 +1,12 @@
|
||||||
import {
|
import { useParams } from 'next/navigation';
|
||||||
BusterDashboard,
|
import React, { PropsWithChildren, useEffect, useLayoutEffect, useState } from 'react';
|
||||||
BusterDashboardListItem,
|
|
||||||
BusterDashboardResponse,
|
|
||||||
BusterMetricDataResponse,
|
|
||||||
BusterVerificationStatus,
|
|
||||||
IBusterDashboardMetric
|
|
||||||
} from '@/api/buster_rest';
|
|
||||||
import { useParams, useRouter } from 'next/navigation';
|
|
||||||
import React, {
|
|
||||||
PropsWithChildren,
|
|
||||||
useContext,
|
|
||||||
useEffect,
|
|
||||||
useLayoutEffect,
|
|
||||||
useRef,
|
|
||||||
useState
|
|
||||||
} from 'react';
|
|
||||||
import { useBusterWebSocket } from '../BusterWebSocket';
|
|
||||||
import { useAppLayoutContextSelector } from '../BusterAppLayout';
|
import { useAppLayoutContextSelector } from '../BusterAppLayout';
|
||||||
import { BusterRoutes, createBusterRoute } from '@/routes';
|
import { useUnmount } from 'ahooks';
|
||||||
import { DashboardUpdate, DashboardsListEmitPayload } from '@/api/buster_socket/dashboards';
|
|
||||||
import isEqual from 'lodash/isEqual';
|
|
||||||
import { useMemoizedFn, useMount, useUnmount } from 'ahooks';
|
|
||||||
import { useBusterAssetsContextSelector } from '@/context/Assets/BusterAssetsProvider';
|
|
||||||
import { upgradeDashboardMetric } from './dashboardContextHelper';
|
|
||||||
import { useBusterNotifications } from '../BusterNotifications';
|
|
||||||
import {
|
import {
|
||||||
useContextSelector,
|
useContextSelector,
|
||||||
createContext,
|
createContext,
|
||||||
ContextSelector
|
ContextSelector
|
||||||
} from '@fluentui/react-context-selector';
|
} from '@fluentui/react-context-selector';
|
||||||
import { useBusterMessageDataContextSelector } from '../MessageData';
|
|
||||||
import { useDashboardLists } from './useDashboardLists';
|
import { useDashboardLists } from './useDashboardLists';
|
||||||
import { useDashboardIndividual } from './useDashboardIndividual';
|
import { useDashboardIndividual } from './useDashboardIndividual';
|
||||||
import { useDashboardMetrics } from './useDashboardMetrics';
|
import { useDashboardMetrics } from './useDashboardMetrics';
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
import { BusterNewThreadsProvider } from './BusterNewThreadsProvider';
|
import { BusterNewThreadsProvider } from './BusterNewThreadsProvider';
|
||||||
import { BusterThreadsListProvider } from './BusterThreadsListProvider';
|
import { BusterThreadsListProvider } from './BusterThreadsListProvider';
|
||||||
import { defaultIBusterThread } from './config';
|
import { defaultIBusterThread } from './config';
|
||||||
import { useDebounceFn, useMemoizedFn, useMount, useWhyDidYouUpdate } from 'ahooks';
|
import { useDebounceFn, useMemoizedFn, useMount, useUnmount } from 'ahooks';
|
||||||
import type { IBusterThread, IBusterThreadMessage } from './interfaces';
|
import type { IBusterThread, IBusterThreadMessage } from './interfaces';
|
||||||
import type { BusterThread, BusterThreadUser, BusterVerificationStatus } from '@/api/buster_rest';
|
import type { BusterThread, BusterThreadUser, BusterVerificationStatus } from '@/api/buster_rest';
|
||||||
import { useBusterWebSocket } from '../BusterWebSocket';
|
import { useBusterWebSocket } from '../BusterWebSocket';
|
||||||
|
|
Loading…
Reference in New Issue