Skip to content

Commit 2e24657

Browse files
ClemsazertSimonClo
authored andcommitted
✨ useGristTable hook
1 parent eee0536 commit 2e24657

File tree

7 files changed

+138
-6
lines changed

7 files changed

+138
-6
lines changed

src/frontend/apps/impress/.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
NEXT_PUBLIC_API_ORIGIN=
22
NEXT_PUBLIC_SW_DEACTIVATED=
33
NEXT_PUBLIC_PUBLISH_AS_MIT=true
4+
NEXT_PUBLIC_GRIST_API_KEY=

src/frontend/apps/impress/src/api/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ export const backendUrl = () =>
2020
*/
2121
export const baseApiUrl = (apiVersion: string = '1.0') =>
2222
`${backendUrl()}/api/v${apiVersion}/`;
23+
24+
export const gristApiUrl = () => 'http://localhost:8484/api/';
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { gristApiUrl } from './config';
2+
3+
export const gristFetchApi = async (input: string, init?: RequestInit) => {
4+
const apiUrl = `${gristApiUrl()}${input}`;
5+
const bearerToken = `Bearer ${process.env.NEXT_PUBLIC_GRIST_API_KEY}`;
6+
7+
const headers = {
8+
'Content-Type': 'application/json',
9+
Authorization: bearerToken,
10+
};
11+
12+
return await fetch(apiUrl, {
13+
...init,
14+
headers,
15+
});
16+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from './APIError';
22
export * from './config';
33
export * from './fetchApi';
4+
export * from './gristApi';
45
export * from './helpers';
56
export * from './types';
67
export * from './utils';

src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/DatabaseBlock.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { TFunction } from 'i18next';
55
import React, { useEffect } from 'react';
66

77
import { Box, Icon } from '@/components';
8+
import { useGristTable } from '@/features/grist';
89

910
import { DocsBlockNoteEditor } from '../../types';
1011

@@ -14,22 +15,34 @@ export const DatabaseBlock = createReactBlockSpec(
1415
propSchema: {
1516
textAlignment: defaultProps.textAlignment,
1617
backgroundColor: defaultProps.backgroundColor,
18+
documentId: {
19+
type: 'string',
20+
default: '',
21+
},
22+
tableId: {
23+
type: 'string',
24+
default: '',
25+
},
1726
},
1827
content: 'inline',
1928
},
2029
{
21-
render: ({ block, editor }) => {
22-
// Temporary: sets a orange background color to a database block when added by
23-
// the user, while keeping the colors menu on the drag handler usable for
24-
// this custom block.
30+
render: ({ block, editor, contentRef }) => {
31+
const { tableData } = useGristTable({
32+
tableId: block.props.tableId,
33+
documentId: block.props.documentId,
34+
});
35+
2536
useEffect(() => {
2637
if (
2738
!block.content.length &&
2839
block.props.backgroundColor === 'default'
2940
) {
3041
editor.updateBlock(block, { props: { backgroundColor: 'orange' } });
42+
} else {
43+
editor.updateBlock(block, { content: JSON.stringify(tableData) });
3144
}
32-
}, [block, editor]);
45+
}, [block, editor, tableData]);
3346

3447
return (
3548
<Box
@@ -40,7 +53,7 @@ export const DatabaseBlock = createReactBlockSpec(
4053
flexDirection: 'row',
4154
}}
4255
>
43-
<Box as="p">🏗️ Database block is in development</Box>{' '}
56+
<Box as="p" className="inline-content" ref={contentRef} />
4457
</Box>
4558
);
4659
},
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './useGristTable';
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { useEffect, useState } from 'react';
2+
3+
import { APIError, errorCauses, gristFetchApi } from '@/api';
4+
5+
export type UseGristTableArguments = { documentId?: string; tableId?: string };
6+
7+
export const useGristTable = ({
8+
documentId,
9+
tableId,
10+
}: UseGristTableArguments) => {
11+
const [tableData, setTableData] = useState<unknown[]>([]);
12+
13+
useEffect(() => {
14+
const fetchData = async () => {
15+
const url = `docs/${documentId}/tables/${tableId}/table`;
16+
const response = await gristFetchApi(url);
17+
if (!response.ok) {
18+
throw new APIError(
19+
'Failed to request ai transform',
20+
await errorCauses(response),
21+
);
22+
}
23+
return (await response.json()) as Promise<unknown[]>;
24+
};
25+
26+
const createDocument = async (workspaceId: string) => {
27+
const url = `workspaces/${workspaceId}/docs`;
28+
const response = await gristFetchApi(url, {
29+
method: 'POST',
30+
body: JSON.stringify({ name: 'New Doc' }),
31+
});
32+
if (!response.ok) {
33+
throw new APIError(
34+
'Failed to create Grist document',
35+
await errorCauses(response),
36+
);
37+
}
38+
return (await response.json()) as Promise<string>;
39+
};
40+
41+
const createTable = async (documentId: string) => {
42+
const url = `docs/${documentId}/tables`;
43+
const response = await gristFetchApi(url, {
44+
method: 'POST',
45+
body: JSON.stringify({
46+
tables: [{ id: 'New Table', columns: [] }],
47+
}),
48+
});
49+
if (!response.ok) {
50+
throw new APIError(
51+
'Failed to create Grist table',
52+
await errorCauses(response),
53+
);
54+
}
55+
return (await response.json()) as Promise<string>;
56+
};
57+
58+
if (!documentId) {
59+
const DEFAULT_WORKSPACE_ID = '2';
60+
createDocument(DEFAULT_WORKSPACE_ID)
61+
.then((newDocumentId) => {
62+
createTable(newDocumentId)
63+
.then((newTableId) => {
64+
console.log(
65+
`Created new Grist document with ID: ${newDocumentId} and table ID: ${newTableId}`,
66+
);
67+
})
68+
.catch((error) => {
69+
console.error('Error creating Grist table:', error);
70+
});
71+
})
72+
.catch((error) => {
73+
console.error('Error creating Grist document:', error);
74+
});
75+
}
76+
77+
if (!tableId) {
78+
createTable(documentId ?? '')
79+
.then((newTableId) => {
80+
console.log(`Created new Grist table with ID: ${newTableId}`);
81+
})
82+
.catch((error) => {
83+
console.error('Error creating Grist table:', error);
84+
});
85+
}
86+
87+
fetchData()
88+
.then((res) => {
89+
setTableData(res);
90+
})
91+
.catch((error) => {
92+
console.error('Error fetching Grist table data:', error);
93+
});
94+
}, [documentId, tableId]);
95+
return {
96+
tableData,
97+
};
98+
};

0 commit comments

Comments
 (0)