Skip to content

Commit 9101745

Browse files
authored
[INTEG-3297] mock google doc selector (#10271)
* installing gdrive picker component * hardcoded test docs * chore: cleanup package.json * remove content preview * installing gdrive picker component * adding test doc button to page * cleanup
1 parent 868d21d commit 9101745

11 files changed

+30182
-126
lines changed
Lines changed: 70 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1-
import { useState, useEffect } from 'react';
2-
import { Box, Button, Form, FormControl, TextInput } from '@contentful/f36-components';
1+
import { useState } from 'react';
2+
import {
3+
Box,
4+
Button,
5+
Form,
6+
FormControl,
7+
Modal,
8+
Stack,
9+
Text,
10+
Card,
11+
} from '@contentful/f36-components';
312
import { PageAppSDK } from '@contentful/app-sdk';
13+
import { TEST_DOCUMENTS } from '../../utils/test_docs_json';
414

515
interface GoogleDocUploaderProps {
616
sdk: PageAppSDK;
@@ -9,107 +19,33 @@ interface GoogleDocUploaderProps {
919
isDisabled?: boolean;
1020
}
1121

12-
function isValidGoogleDocUrl(url: string): boolean {
13-
return /^https:\/\/docs\.google\.com\/document\/d\/[A-Za-z0-9_-]+\/edit(?:\?[^#]*)?$/.test(url);
14-
}
15-
16-
const extractGoogleDocId = (url: string): string | null => {
17-
const patterns = [
18-
/\/document\/d\/([a-zA-Z0-9_-]+)/, // https://docs.google.com/document/d/{id}/...
19-
/\/u\/\d\/d\/([a-zA-Z0-9_-]+)/, // https://docs.google.com/document/u/0/d/{id}/...
20-
];
21-
for (const rx of patterns) {
22-
const m = url.match(rx);
23-
if (m && m[1]) return m[1];
24-
}
25-
return null;
26-
};
27-
28-
const extractPublishedDocId = (url: string): string | null => {
29-
// Published Google Docs use /document/d/e/{publishedId}/...
30-
const m = url.match(/\/document\/d\/e\/([a-zA-Z0-9_-]+)/);
31-
return m && m[1] ? m[1] : null;
32-
};
33-
34-
const fetchGoogleDoc = async (url: string) => {
35-
// If this is a "published to web" URL, fetch from the public export endpoint (no OAuth needed)
36-
const publishedId = extractPublishedDocId(url);
37-
if (publishedId) {
38-
const publishedExportUrl = `https://docs.google.com/document/d/e/${publishedId}/export?format=html`;
39-
const publishedResp = await fetch(publishedExportUrl, { method: 'GET' });
40-
if (!publishedResp.ok) {
41-
throw new Error(`Failed to fetch published document (status ${publishedResp.status}).`);
42-
}
43-
const publishedHtml = await publishedResp.text();
44-
return { title: 'Google Document', html: publishedHtml };
45-
}
46-
47-
const docId = extractGoogleDocId(url);
48-
if (!docId) {
49-
throw new Error('Unable to extract Google Doc ID from URL.');
50-
}
51-
// Try docs.google.com export first (no OAuth); if that fails, fall back to Drive API
52-
try {
53-
const directExportUrl = `https://docs.google.com/document/d/${encodeURIComponent(
54-
docId
55-
)}/export?format=html`;
56-
const directResp = await fetch(directExportUrl, { method: 'GET' });
57-
if (directResp.ok) {
58-
const directHtml = await directResp.text();
59-
return { title: 'Google Document', html: directHtml };
60-
}
61-
} catch {
62-
// ignore and continue
63-
}
64-
return { title: 'Google Document', html: null };
65-
};
66-
6722
export const GoogleDocUploader = ({
6823
sdk,
6924
onSuccess,
7025
onError,
7126
isDisabled,
7227
}: GoogleDocUploaderProps) => {
73-
const [googleDocUrl, setGoogleDocUrl] = useState<string>('');
74-
const [googleDocUrlValid, setGoogleDocUrlValid] = useState<boolean>(true);
28+
const [selectedDocument, setSelectedDocument] = useState<string>('');
7529
const [isUploading, setIsUploading] = useState<boolean>(false);
30+
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
7631

77-
const validateGoogleDocUrl = (value: string) => {
78-
const trimmed = value.trim();
79-
if (trimmed.length === 0) {
80-
setGoogleDocUrlValid(true);
81-
return true;
82-
}
83-
// Minimal validation: must be a docs.google.com document URL
84-
const isValid =
85-
/^https?:\/\/docs\.google\.com\/document\/d\/[a-zA-Z0-9-_]+/.test(trimmed) ||
86-
/^https?:\/\/docs\.google\.com\/document\/u\/\d\/d\/[a-zA-Z0-9-_]+/.test(trimmed);
87-
setGoogleDocUrlValid(isValid);
88-
return isValid;
89-
};
90-
91-
useEffect(() => {
92-
if (googleDocUrl) {
93-
validateGoogleDocUrl(googleDocUrl);
94-
}
95-
}, [googleDocUrl]);
32+
const handleSelectDocument = async (docId: string, title: string, documentData: any) => {
33+
setSelectedDocument(title);
34+
setIsModalOpen(false);
9635

97-
const onSubmitGoogleDoc = async () => {
98-
const isValid = validateGoogleDocUrl(googleDocUrl);
99-
if (!isValid) {
100-
sdk.notifier.error('Please enter a valid public Google Doc link.');
101-
return;
102-
}
10336
try {
10437
setIsUploading(true);
105-
const result = await fetchGoogleDoc(googleDocUrl);
106-
onSuccess(result.title, result.html);
107-
sdk.notifier.success('Google Doc uploaded successfully');
38+
39+
// Log the document data to console
40+
console.log('Selected document:', title);
41+
console.log('Document data:', documentData);
42+
43+
sdk.notifier.success(`Document "${title}" loaded successfully`);
44+
45+
// Proceed to content type selector with the document data
46+
onSuccess(title, JSON.stringify(documentData));
10847
} catch (e: unknown) {
109-
const message =
110-
e instanceof Error
111-
? e.message
112-
: 'Failed to fetch Google Doc. Ensure it is publicly accessible.';
48+
const message = e instanceof Error ? e.message : 'Failed to load document.';
11349
onError(message);
11450
sdk.notifier.error(message);
11551
} finally {
@@ -120,45 +56,54 @@ export const GoogleDocUploader = ({
12056
return (
12157
<Form>
12258
<FormControl>
123-
<FormControl.Label>Public Google Doc link</FormControl.Label>
124-
<TextInput
125-
id="googleDocUrl"
126-
name="googleDocUrl"
127-
value={googleDocUrl}
128-
isInvalid={!googleDocUrlValid}
129-
placeholder="https://docs.google.com/document/d/..."
130-
onChange={(e) => {
131-
const url = e.target.value;
132-
setGoogleDocUrl(url);
133-
setGoogleDocUrlValid(isValidGoogleDocUrl(url));
134-
}}
135-
/>
136-
<FormControl.HelpText>
137-
Must be a publicly accessible Google Docs URL (View access)
138-
</FormControl.HelpText>
139-
{googleDocUrlValid && googleDocUrl && (
59+
<Button
60+
variant="secondary"
61+
onClick={() => setIsModalOpen(true)}
62+
isDisabled={isDisabled || isUploading}>
63+
{selectedDocument ? 'Change Document' : 'Select Document'}
64+
</Button>
65+
66+
{selectedDocument && (
14067
<Box marginTop="spacingS">
141-
<a
142-
href={encodeURI(googleDocUrl.replace('/edit', '/preview'))}
143-
target="_blank"
144-
rel="noopener noreferrer">
145-
Open original (best formatting)
146-
</a>
68+
<Text fontWeight="fontWeightDemiBold">Selected: {selectedDocument}</Text>
14769
</Box>
14870
)}
149-
{!googleDocUrlValid && (
150-
<FormControl.ValidationMessage>
151-
Enter a valid Google Doc URL.
152-
</FormControl.ValidationMessage>
71+
72+
{isUploading && (
73+
<Box marginTop="spacingS">
74+
<Text fontColor="gray500" fontSize="fontSizeS">
75+
Processing document...
76+
</Text>
77+
</Box>
15378
)}
154-
<Box marginTop="spacingS">
155-
<Button
156-
isDisabled={isDisabled || isUploading || !googleDocUrl || !googleDocUrlValid}
157-
onClick={onSubmitGoogleDoc}>
158-
{isUploading ? 'Uploading...' : 'Upload Google Doc'}
159-
</Button>
160-
</Box>
79+
80+
<FormControl.HelpText>
81+
Choose a test document to process with the agent
82+
</FormControl.HelpText>
16183
</FormControl>
84+
85+
<Modal onClose={() => setIsModalOpen(false)} isShown={isModalOpen} size="large">
86+
{() => (
87+
<>
88+
<Modal.Header title="Select a Test Document" onClose={() => setIsModalOpen(false)} />
89+
<Modal.Content>
90+
<Stack flexDirection="column" spacing="spacingS">
91+
{TEST_DOCUMENTS.map((doc, index) => (
92+
<Card
93+
key={index}
94+
as="button"
95+
onClick={() => handleSelectDocument(doc.id, doc.title, doc.data)}
96+
style={{ cursor: 'pointer', textAlign: 'left', padding: '12px' }}>
97+
<Stack flexDirection="column" spacing="spacingXs">
98+
<Text fontWeight="fontWeightDemiBold">{doc.title}</Text>
99+
</Stack>
100+
</Card>
101+
))}
102+
</Stack>
103+
</Modal.Content>
104+
</>
105+
)}
106+
</Modal>
162107
</Form>
163108
);
164109
};

apps/google-docs/src/locations/Page.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { PageAppSDK } from '@contentful/app-sdk';
1313
import { useSDK } from '@contentful/react-apps-toolkit';
1414
import { ContentTypeSelector } from '../components';
1515
import { createEntriesFromDocumentAction } from '../utils/appFunctionUtils';
16+
import { GoogleDocUploader } from '../components/page/GoogleDocUploader';
1617

1718
const Page = () => {
1819
const sdk = useSDK<PageAppSDK>();
@@ -57,6 +58,14 @@ const Page = () => {
5758
}
5859
};
5960

61+
const handleSuccess = (title: string, html: string | null) => {
62+
setGoogleDocUrl(html || '');
63+
};
64+
65+
const handleError = (message: string) => {
66+
setErrorMessage(message);
67+
};
68+
6069
return (
6170
<Flex flexDirection="column" alignItems="stretch">
6271
<Box
@@ -69,12 +78,13 @@ const Page = () => {
6978
border: '1px solid #e5e5e5',
7079
borderRadius: '8px',
7180
}}>
72-
<Heading as="h2">Document Uploader</Heading>
81+
<Heading as="h2">Upload Document</Heading>
7382
<Paragraph marginBottom="spacingL">
7483
Upload a public Google Doc link or a document file to send for processing.
7584
</Paragraph>
7685

7786
<Stack spacing="spacingXl" flexDirection="column" alignItems="stretch">
87+
<GoogleDocUploader sdk={sdk} onSuccess={handleSuccess} onError={handleError} />
7888
<Box>
7989
<TextInput
8090
value={googleDocUrl}

0 commit comments

Comments
 (0)