Skip to content

Commit

Permalink
add optimistic updating to ai chat messages (#1542)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsladerman authored Nov 2, 2024
1 parent 1864096 commit 4ad23bb
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 115 deletions.
14 changes: 1 addition & 13 deletions assets/src/components/ai/AI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
useAiPinsQuery,
useChatThreadsQuery,
} from 'generated/graphql.ts'
import { useCallback, useMemo } from 'react'
import { useMemo } from 'react'
import { useNavigate } from 'react-router-dom'
import { GLOBAL_SETTINGS_ABS_PATH } from '../../routes/settingsRoutesConst.tsx'
import { AIPinsTable } from './AIPinsTable.tsx'
Expand All @@ -29,10 +29,6 @@ export default function AI() {
keyPath: ['aiPins'],
})

const refetchAll = useCallback(() => {
threadsQuery.refetch().then(() => pinsQuery.refetch())
}, [threadsQuery, pinsQuery])

const filteredPins = useMemo(
() =>
pinsQuery.data?.aiPins?.edges
Expand Down Expand Up @@ -70,12 +66,10 @@ export default function AI() {
height="100%"
>
<PinnedSection
refetch={refetchAll}
filteredPins={filteredPins}
pinsQuery={pinsQuery}
/>
<AllThreadsSection
refetch={refetchAll}
filteredThreads={filteredThreads}
threadsQuery={threadsQuery}
/>
Expand Down Expand Up @@ -111,11 +105,9 @@ function Header() {
function PinnedSection({
filteredPins,
pinsQuery,
refetch,
}: {
filteredPins: AiPinFragment[]
pinsQuery: FetchPaginatedDataResult<AiPinsQuery>
refetch: () => void
}) {
return (
<Flex
Expand All @@ -130,7 +122,6 @@ function PinnedSection({
secondPartialType="body2"
/>
<AIPinsTable
refetch={refetch}
filteredPins={filteredPins}
pinsQuery={pinsQuery}
/>
Expand All @@ -141,11 +132,9 @@ function PinnedSection({
function AllThreadsSection({
filteredThreads,
threadsQuery,
refetch,
}: {
filteredThreads: ChatThreadTinyFragment[]
threadsQuery: FetchPaginatedDataResult<ChatThreadsQuery>
refetch: () => void
}) {
return (
<Flex
Expand All @@ -160,7 +149,6 @@ function AllThreadsSection({
firstPartialType="subtitle2"
/>
<AIThreadsTable
refetch={refetch}
filteredThreads={filteredThreads}
threadsQuery={threadsQuery}
/>
Expand Down
4 changes: 0 additions & 4 deletions assets/src/components/ai/AIPinsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,13 @@ import { pinTableColumns } from './AIThreadsTable'
export function AIPinsTable({
filteredPins,
pinsQuery,
refetch,
}: {
filteredPins: AiPinFragment[]
pinsQuery: FetchPaginatedDataResult<AiPinsQuery>
refetch: () => void
}) {
const theme = useTheme()
const { data, loading, error, pageInfo, fetchNextPage, setVirtualSlice } =
pinsQuery
const reactTableOptions = { meta: { refetch } }

if (error) return <GqlError error={error} />
if (!data?.aiPins?.edges) return <TableSkeleton />
Expand All @@ -40,7 +37,6 @@ export function AIPinsTable({
isFetchingNextPage={loading}
onVirtualSliceChange={setVirtualSlice}
reactVirtualOptions={DEFAULT_REACT_VIRTUAL_OPTIONS}
reactTableOptions={reactTableOptions}
css={{
height: '100%',
overflowX: 'hidden',
Expand Down
73 changes: 39 additions & 34 deletions assets/src/components/ai/AIThreadsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ import {
useCreateAiPinMutation,
useDeleteAiPinMutation,
} from 'generated/graphql'
import { useMemo } from 'react'
import styled, { useTheme } from 'styled-components'
import { useChatbot } from './AIContext'
import { AiThreadsTableActions } from './AiThreadsTableActions'
import { useMemo } from 'react'

dayjs.extend(relativeTime)

Expand All @@ -58,7 +58,6 @@ export function AllThreadsTable() {
<AIThreadsTable
filteredThreads={filteredThreads}
threadsQuery={threadsQuery}
refetch={threadsQuery.refetch}
modal
/>
)
Expand All @@ -67,21 +66,24 @@ export function AllThreadsTable() {
export function AIThreadsTable({
filteredThreads,
threadsQuery,
refetch,
modal,
}: {
filteredThreads: ChatThreadTinyFragment[]
threadsQuery: FetchPaginatedDataResult<ChatThreadsQuery>
refetch: () => void
modal?: boolean | null
}) {
const theme = useTheme()
const { data, loading, error, pageInfo, fetchNextPage, setVirtualSlice } =
threadsQuery
const reactTableOptions = { meta: { refetch, modal } }
const reactTableOptions = { meta: { modal } }

if (error) return <GqlError error={error} />
if (!data?.chatThreads?.edges) return <TableSkeleton />
if (!data?.chatThreads?.edges)
return (
<TableSkeleton
styles={{ background: theme.colors['fill-one'], height: '100%' }}
/>
)

return (
<FullHeightTableWrap>
Expand Down Expand Up @@ -118,21 +120,22 @@ const ThreadRow = threadColumnHelper.accessor((thread) => thread, {
id: 'thread',
cell: function Cell({ getValue, table }) {
const thread = getValue()
const [pinThread, { loading: pinLoading }] = useCreateAiPinMutation({
const [pinThread, { loading }] = useCreateAiPinMutation({
awaitRefetchQueries: true,
refetchQueries: ['AIPins', 'ChatThreads'],
variables: {
attributes: {
threadId: thread.id,
insightId: thread.insight?.id,
name: thread.summary.substring(0, 250),
},
},
onCompleted: () => table.options.meta?.refetch?.(),
})
return (
<AITableRowBase
item={thread}
onClickPin={() => pinThread()}
pinLoading={pinLoading}
pinLoading={loading}
modal={table.options.meta?.modal || false}
/>
)
Expand All @@ -141,19 +144,20 @@ const ThreadRow = threadColumnHelper.accessor((thread) => thread, {

const PinRow = pinColumnHelper.accessor((pin) => pin, {
id: 'pin',
cell: function Cell({ getValue, table }) {
cell: function Cell({ getValue }) {
const pin = getValue()
const [unpinThread, { loading: unpinLoading }] = useDeleteAiPinMutation({
const [unpinThread, { loading }] = useDeleteAiPinMutation({
awaitRefetchQueries: true,
refetchQueries: ['AIPins', 'ChatThreads'],
variables: {
id: pin.id,
},
onCompleted: () => table.options.meta?.refetch?.(),
})
return (
<AITableRowBase
item={pin}
onClickPin={() => unpinThread()}
pinLoading={unpinLoading}
pinLoading={loading}
/>
)
},
Expand Down Expand Up @@ -210,27 +214,28 @@ function AITableRowBase({
).fromNow()}
</CaptionP>
{!modal && (
<Chip severity={isStale ? 'neutral' : 'success'}>
{isStale ? 'Stale' : 'Active'}
</Chip>
)}
{!modal && (
<IconFrame
clickable
onClick={(e) => {
e.stopPropagation()
onClickPin?.()
}}
icon={
pinLoading ? (
<Spinner />
) : isPin ? (
<PushPinFilledIcon color={theme.colors['icon-info']} />
) : (
<PushPinOutlineIcon />
)
}
/>
<>
<Chip severity={isStale ? 'neutral' : 'success'}>
{isStale ? 'Stale' : 'Active'}
</Chip>
<IconFrame
clickable
onClick={(e) => {
e.stopPropagation()
if (pinLoading) return
onClickPin?.()
}}
icon={
pinLoading ? (
<Spinner />
) : isPin ? (
<PushPinFilledIcon color={theme.colors['icon-info']} />
) : (
<PushPinOutlineIcon />
)
}
/>
</>
)}
<AiThreadsTableActions thread={thread} />
</ThreadEntrySC>
Expand Down
5 changes: 3 additions & 2 deletions assets/src/components/ai/chatbot/Chatbot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,14 @@ function ChatbotPanelInner({
onClose={onClose}
fullscreen={fullscreen}
/>
{currentThread && (
{currentThread ? (
<ChatbotPanelThread
currentThread={currentThread}
fullscreen={fullscreen}
/>
) : (
<AllThreadsTable />
)}
{!currentThread && <AllThreadsTable />}
</ChatbotFrameSC>
)
}
Expand Down
Loading

0 comments on commit 4ad23bb

Please sign in to comment.