diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/DatabaseBlock/AddRowButton.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/DatabaseBlock/AddRowButton.tsx index 52fdde5913..8774ed3e7b 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/DatabaseBlock/AddRowButton.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/DatabaseBlock/AddRowButton.tsx @@ -31,7 +31,7 @@ export const AddRowButton = ({ return updatedRows; }); - void createRecords(documentId, tableId, [{ fields: newRow }]); + createRecords({ documentId, tableId, records: [{ fields: newRow }] }); }; const color = '#817E77'; diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/DatabaseBlock/DatabaseGrid.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/DatabaseBlock/DatabaseGrid.tsx index d30d112613..b468024d85 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/DatabaseBlock/DatabaseGrid.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/DatabaseBlock/DatabaseGrid.tsx @@ -46,7 +46,7 @@ export const DatabaseGrid = ({ const { colDefs, setColDefs } = useColumns(); useEffect(() => { - const filteredEntries = Object.entries(tableData).filter( + const filteredEntries = Object.entries(tableData || {}).filter( ([key]) => key !== 'manualSort', ); @@ -124,15 +124,19 @@ export const DatabaseGrid = ({ return [...(prev !== undefined ? prev : []), newColDef]; }); - void createColumns(documentId, tableId, [ - { - id: columnName, - fields: { - label: columnName, - type: ColumnType.TEXT, + createColumns({ + documentId, + tableId, + columns: [ + { + id: columnName, + fields: { + label: columnName, + type: ColumnType.TEXT, + }, }, - }, - ]); + ], + }); }; const onCellEditingStopped = useCallback( diff --git a/src/frontend/apps/impress/src/features/grist/useGristCrudColumns.ts b/src/frontend/apps/impress/src/features/grist/useGristCrudColumns.ts index 0cd79d85e0..2e50dfe308 100644 --- a/src/frontend/apps/impress/src/features/grist/useGristCrudColumns.ts +++ b/src/frontend/apps/impress/src/features/grist/useGristCrudColumns.ts @@ -1,4 +1,5 @@ import { gristFetchApi } from '@/api'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; export enum ColumnType { TEXT = 'Text', @@ -11,35 +12,44 @@ type ColumnInput = { label: string; }; -export const useGristCrudColumns = () => { - const createColumns = async ( - documentId: string, - tableId: string, - columns: { id: string; fields: ColumnInput }[], - ) => { - const url = `docs/${documentId}/tables/${tableId}/columns`; - try { - const response = await gristFetchApi(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ columns }), - }); +const _createColumns = async ({ + documentId, + tableId, + columns, +}: { + documentId: string; + tableId: string; + columns: { id: string; fields: ColumnInput }[]; +}) => { + const url = `docs/${documentId}/tables/${tableId}/columns`; + const response = await gristFetchApi(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ columns }), + }); - if (!response.ok) { - const errorBody = await response.text(); - throw new Error( - `Failed to create columns: ${response.status} ${response.statusText} - ${errorBody}`, - ); - } + if (!response.ok) { + const errorBody = await response.text(); + throw new Error( + `Failed to create columns: ${response.status} ${response.statusText} - ${errorBody}`, + ); + } - return (await response.json()) as Promise<{ records: { id: string }[] }>; - } catch (error) { - console.error('Error creating Grist record:', error); - throw error; - } - }; + return (await response.json()) as Promise<{ records: { id: string }[] }>; +}; + +export const useGristCrudColumns = () => { + const queryClient = useQueryClient(); + const { mutate: createColumns } = useMutation({ + mutationFn: _createColumns, + onSuccess: (_, variables) => { + queryClient.invalidateQueries({ + queryKey: ['getTableData', variables.documentId, variables.tableId], + }); + }, + }); const deleteColumns = async ( documentId: string, diff --git a/src/frontend/apps/impress/src/features/grist/useGristCrudRecords.ts b/src/frontend/apps/impress/src/features/grist/useGristCrudRecords.ts index e90715d030..b9e4bac09a 100644 --- a/src/frontend/apps/impress/src/features/grist/useGristCrudRecords.ts +++ b/src/frontend/apps/impress/src/features/grist/useGristCrudRecords.ts @@ -1,34 +1,44 @@ import { gristFetchApi } from '@/api'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; -export const useGristCrudRecords = () => { - const createRecords = async ( - documentId: string, - tableId: string, - records: { fields: unknown }[], - ) => { - const url = `docs/${documentId}/tables/${tableId}/records`; - try { - const response = await gristFetchApi(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ records }), - }); +const _createRecords = async ({ + documentId, + tableId, + records, +}: { + documentId: string; + tableId: string; + records: { fields: unknown }[]; +}) => { + const url = `docs/${documentId}/tables/${tableId}/records`; + const response = await gristFetchApi(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ records }), + }); - if (!response.ok) { - const errorBody = await response.text(); - throw new Error( - `Failed to create record: ${response.status} ${response.statusText} - ${errorBody}`, - ); - } + if (!response.ok) { + const errorBody = await response.text(); + throw new Error( + `Failed to create record: ${response.status} ${response.statusText} - ${errorBody}`, + ); + } - return (await response.json()) as Promise<{ records: { id: string }[] }>; - } catch (error) { - console.error('Error creating Grist record:', error); - throw error; - } - }; + return (await response.json()) as Promise<{ records: { id: string }[] }>; +}; + +export const useGristCrudRecords = () => { + const queryClient = useQueryClient(); + const { mutate: createRecords } = useMutation({ + mutationFn: _createRecords, + onSuccess: (_, variables) => { + queryClient.invalidateQueries({ + queryKey: ['getTableData', variables.documentId, variables.tableId], + }); + }, + }); const deleteRecords = async ( documentId: string, diff --git a/src/frontend/apps/impress/src/features/grist/useGristTableData.ts b/src/frontend/apps/impress/src/features/grist/useGristTableData.ts index 531b6cf356..c14971a0f3 100644 --- a/src/frontend/apps/impress/src/features/grist/useGristTableData.ts +++ b/src/frontend/apps/impress/src/features/grist/useGristTableData.ts @@ -1,42 +1,36 @@ -import { useEffect, useState } from 'react'; - import { APIError, errorCauses, gristFetchApi } from '@/api'; +import { useQuery } from '@tanstack/react-query'; export type UseGristTableDataArguments = { documentId: string; tableId: string; }; +const getTableData = async (documentId: string, tableId: string) => { + const url = `docs/${documentId}/tables/${tableId}/data`; + const response = await gristFetchApi(url); + if (!response.ok) { + throw new APIError( + 'Failed to fetch Grist table data', + await errorCauses(response), + ); + } + return (await response.json()) as Promise< + Record + >; +}; + export const useGristTableData = ({ documentId, tableId, }: UseGristTableDataArguments) => { - const [tableData, setTableData] = useState< - Record - >({}); - - useEffect(() => { - const fetchData = async () => { - const url = `docs/${documentId}/tables/${tableId}/data`; - const response = await gristFetchApi(url); - if (!response.ok) { - throw new APIError( - 'Failed to fetch Grist table data', - await errorCauses(response), - ); - } - return (await response.json()) as Promise; - }; + const { data: tableData, isLoading } = useQuery({ + queryKey: ['getTableData', documentId, tableId], + queryFn: () => getTableData(documentId, tableId), + }); - fetchData() - .then((res) => { - setTableData(res as Record); - }) - .catch((error) => { - console.error('Error fetching Grist table data:', error); - }); - }, [documentId, tableId]); return { tableData, + isLoading, }; };