Skip to content

Commit 4fa4bc7

Browse files
feat: merge google-docs-quality feature branch [INTEG-3527] (#10689)
* feat: extend timeout to 50 minutes and add in timing markers (#10608) * fix: update AGENT_ANALYZER_ID constant to reflect new workflow agent name (#10613) * fix: update local agents API URL to use constant for base URL * fix(google-docs): add pagination for content type fetching [INTEG-3491] (#10674) * feat: implement pagination for content type fetching in SelectContentTypeModal * fix: add checks to avoid infinite loop * chore: add env example * chore: update readme * fix: cleanup test modal [INTEG-3496] (#10682) * feat(google-docs): make the test modal more dev friendly * fix(google-docs): cleanup content type ids and spacing * fix(google-docs): implement temporary workaround for content type ID handling in workflows (#10688) * chore: rename useAnalyzePrompt hook to useWorkflowAgent * chore: remove logs * chore: remove logs in useGeneratePreview hook --------- Co-authored-by: ryunsong-contentful <124832189+ryunsong-contentful@users.noreply.github.com>
1 parent b2759e7 commit 4fa4bc7

File tree

9 files changed

+565
-103
lines changed

9 files changed

+565
-103
lines changed

apps/google-docs/.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
STATIC_S3_BASE=
2+
GOOGLE_DOCS_CLOUDFRONT_DIST_ID=
3+
CONTENTFUL_ACCESS_TOKEN=

apps/google-docs/README.md

Lines changed: 35 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,55 @@
1-
This project was bootstrapped with [Create Contentful App](https://github.com/contentful/create-contentful-app).
1+
# Google Docs App for Contentful
22

3-
## How to use
3+
A Contentful App that enables importing content from Google Docs into Contentful entries.
44

5-
Execute create-contentful-app with npm, npx or yarn to bootstrap the example:
65

7-
```bash
8-
# npx
9-
npx create-contentful-app --typescript
10-
11-
# npm
12-
npm init contentful-app -- --typescript
6+
## Frontend Setup
137

14-
# Yarn
15-
yarn create contentful-app --typescript
8+
1. Clone the repository
9+
2. Navigate to the app directory:
10+
```bash
11+
cd apps/google-docs
1612
```
1713

18-
## Available Scripts
19-
20-
In the project directory, you can run:
21-
22-
#### `npm start`
23-
24-
Creates or updates your app definition in Contentful, and runs the app in development mode.
25-
Open your app to view it in the browser.
26-
27-
The page will reload if you make edits.
28-
You will also see any lint errors in the console.
29-
30-
#### `npm run build`
31-
32-
Builds the app for production to the `build` folder.
33-
It correctly bundles React in production mode and optimizes the build for the best performance.
34-
35-
The build is minified and the filenames include the hashes.
36-
Your app is ready to be deployed!
37-
38-
#### `npm run upload`
39-
40-
Uploads the build folder to contentful and creates a bundle that is automatically activated.
41-
The command guides you through the deployment process and asks for all required arguments.
42-
Read [here](https://www.contentful.com/developers/docs/extensibility/app-framework/create-contentful-app/#deploy-with-contentful) for more information about the deployment process.
43-
44-
#### `npm run upload-ci`
14+
3. Install dependencies:
15+
```bash
16+
npm install
17+
```
4518

46-
Similar to `npm run upload` it will upload your app to contentful and activate it. The only difference is
47-
that with this command all required arguments are read from the environment variables, for example when you add
48-
the upload command to your CI pipeline.
19+
4. Copy the example environment file and configure it:
20+
```bash
21+
cp .env.example .env
22+
```
4923

50-
For this command to work, the following environment variables must be set:
24+
5. Edit `.env` and add your API keys and tokens
5125

52-
- `CONTENTFUL_ORG_ID` - The ID of your organization
53-
- `CONTENTFUL_APP_DEF_ID` - The ID of the app to which to add the bundle
54-
- `CONTENTFUL_ACCESS_TOKEN` - A personal [access token](https://www.contentful.com/developers/docs/references/content-management-api/#/reference/personal-access-tokens)
26+
6. To run locally
5527

56-
## Libraries to use
28+
```bash
29+
npm run dev
30+
```
5731

58-
To make your app look and feel like Contentful use the following libraries:
32+
Note: To run the backend locally follow the read me in the agents-api repo
5933

60-
- [Forma 36](https://f36.contentful.com/) – Contentful's design system
61-
- [Contentful Field Editors](https://www.contentful.com/developers/docs/extensibility/field-editors/) – Contentful's field editor React components
6234

63-
## Using the `contentful-management` SDK
35+
### Deployment
6436

65-
In the default create contentful app output, a contentful management client is
66-
passed into each location. This can be used to interact with Contentful's
67-
management API. For example
37+
#### Development Environments
6838

69-
```js
70-
// Use the client
71-
cma.locale.getMany({}).then((locales) => console.log(locales));
39+
```bash
40+
npm run deploy:dev # Deploy to dev environment
41+
npm run deploy:dev2 # Deploy to dev2 environment
42+
npm run deploy:staging # Deploy to staging environment
7243
```
7344

74-
Visit the [`contentful-management` documentation](https://www.contentful.com/developers/docs/extensibility/app-framework/sdk/#using-the-contentful-management-library)
75-
to find out more.
76-
77-
## Schema Convention
45+
#### Production
7846

79-
This app supports an optional schema convention that allows you to explicitly mark entry boundaries, content types, and references in your Google Docs. Using schema markers significantly improves AI accuracy.
80-
81-
**Quick Start:**
82-
- Use `**!CT:contentTypeId!**` to mark the start of an entry
83-
- Use `**!REF:tempId!**` to mark references between entries
84-
- Use `**!END!**` to mark the end of an entry (optional)
85-
86-
Example:
87-
```
88-
**!CT:blogPost!**
89-
My Blog Post Title
90-
Content goes here...
91-
**!CT:author!**
92-
John Doe
93-
Bio: Author information...
47+
```bash
48+
npm run deploy:prod # Deploy to production
9449
```
9550

96-
97-
## Learn More
98-
99-
[Read more](https://www.contentful.com/developers/docs/extensibility/app-framework/create-contentful-app/) and check out the video on how to use the CLI.
51+
**Note**: Deployment scripts require additional environment variables:
52+
- `STATIC_S3_BASE` - S3 bucket base path for dev/staging
53+
- `PROD_STATIC_S3_BASE` - S3 bucket base path for production
54+
- `GOOGLE_DOCS_TEST_CLOUDFRONT_DIST_ID` - CloudFront distribution for dev/staging
55+
- `GOOGLE_DOCS_PROD_CLOUDFRONT_DIST_ID` - CloudFront distribution for production

apps/google-docs/src/hooks/useGeneratePreview.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
POLL_INTERVAL_MS,
77
MAX_POLL_ATTEMPTS,
88
USE_LOCAL_AGENTS_API,
9+
LOCAL_AGENTS_API_BASE_URL,
910
} from '../utils/constants/agent';
1011
import { PreviewEntry } from '../locations/Page/components/modals/step_3/types';
1112
import { getEntryTitle } from '../utils/getEntryTitle';
@@ -155,7 +156,7 @@ const startAgentRun = (sdk: PageAppSDK, params: AgentCallParams): string => {
155156

156157
if (USE_LOCAL_AGENTS_API) {
157158
fetch(
158-
`http://localhost:4111/spaces/${spaceId}/environments/${environmentId}/ai_agents/agents/${AGENT_ID}/generate`,
159+
`${LOCAL_AGENTS_API_BASE_URL}/spaces/${spaceId}/environments/${environmentId}/ai_agents/agents/${AGENT_ID}/generate`,
159160
{
160161
method: 'POST',
161162
headers: {
@@ -200,7 +201,7 @@ const pollAgentRun = async (
200201

201202
if (USE_LOCAL_AGENTS_API) {
202203
const response = await fetch(
203-
`http://localhost:4111/spaces/${spaceId}/environments/${environmentId}/ai_agents/runs/${runId}`,
204+
`${LOCAL_AGENTS_API_BASE_URL}/spaces/${spaceId}/environments/${environmentId}/ai_agents/runs/${runId}`,
204205
{
205206
headers: {
206207
'x-contentful-enable-alpha-feature': 'agents-api',
@@ -216,7 +217,6 @@ const pollAgentRun = async (
216217
if (!response.ok) {
217218
throw new Error(`Failed to poll agent run: ${response.status} ${response.statusText}`);
218219
}
219-
220220
runData = (await response.json()) as AgentRunData;
221221
} else {
222222
try {
@@ -233,8 +233,8 @@ const pollAgentRun = async (
233233
throw error;
234234
}
235235
}
236-
237-
if (getAgentPayload(runData)) {
236+
const assistantTextContent = getAgentPayload(runData);
237+
if (assistantTextContent) {
238238
return parseAgentResponse(runData);
239239
}
240240

apps/google-docs/src/hooks/useModalManagement.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useState } from 'react';
33
interface ModalStates {
44
isUploadModalOpen: boolean;
55
isContentTypePickerOpen: boolean;
6+
isConfirmPromptModalOpen: boolean;
67
isConfirmCancelModalOpen: boolean;
78
isPreviewModalOpen: boolean;
89
isErrorPreviewModalOpen: boolean;
@@ -13,6 +14,7 @@ interface ModalStates {
1314
interface ModalSetters {
1415
setIsUploadModalOpen: (value: boolean) => void;
1516
setIsContentTypePickerOpen: (value: boolean) => void;
17+
setIsConfirmPromptModalOpen: (value: boolean) => void;
1618
setIsConfirmCancelModalOpen: (value: boolean) => void;
1719
setIsPreviewModalOpen: (value: boolean) => void;
1820
setIsErrorPreviewModalOpen: (value: boolean) => void;
@@ -23,6 +25,7 @@ interface ModalSetters {
2325
export enum ModalType {
2426
UPLOAD = 'upload',
2527
CONTENT_TYPE_PICKER = 'contentTypePicker',
28+
CONFIRM_PROMPT = 'confirmPrompt',
2629
CONFIRM_CANCEL = 'confirmCancel',
2730
PREVIEW = 'preview',
2831
ERROR_PREVIEW = 'errorPreview',
@@ -33,6 +36,7 @@ export enum ModalType {
3336
export const useModalManagement = () => {
3437
const [isUploadModalOpen, setIsUploadModalOpen] = useState<boolean>(false);
3538
const [isContentTypePickerOpen, setIsContentTypePickerOpen] = useState<boolean>(false);
39+
const [isConfirmPromptModalOpen, setIsConfirmPromptModalOpen] = useState<boolean>(false);
3640
const [isConfirmCancelModalOpen, setIsConfirmCancelModalOpen] = useState<boolean>(false);
3741
const [isPreviewModalOpen, setIsPreviewModalOpen] = useState<boolean>(false);
3842
const [isErrorPreviewModalOpen, setIsErrorPreviewModalOpen] = useState<boolean>(false);
@@ -47,6 +51,9 @@ export const useModalManagement = () => {
4751
case ModalType.CONTENT_TYPE_PICKER:
4852
setIsContentTypePickerOpen(true);
4953
break;
54+
case ModalType.CONFIRM_PROMPT:
55+
setIsConfirmPromptModalOpen(true);
56+
break;
5057
case ModalType.CONFIRM_CANCEL:
5158
setIsConfirmCancelModalOpen(true);
5259
break;
@@ -73,6 +80,9 @@ export const useModalManagement = () => {
7380
case ModalType.CONTENT_TYPE_PICKER:
7481
setIsContentTypePickerOpen(false);
7582
break;
83+
case ModalType.CONFIRM_PROMPT:
84+
setIsConfirmPromptModalOpen(false);
85+
break;
7686
case ModalType.CONFIRM_CANCEL:
7787
setIsConfirmCancelModalOpen(false);
7888
break;
@@ -95,6 +105,7 @@ export const useModalManagement = () => {
95105
modalStates: {
96106
isUploadModalOpen,
97107
isContentTypePickerOpen,
108+
isConfirmPromptModalOpen,
98109
isConfirmCancelModalOpen,
99110
isPreviewModalOpen,
100111
isErrorPreviewModalOpen,
@@ -104,6 +115,7 @@ export const useModalManagement = () => {
104115
setModalStates: {
105116
setIsUploadModalOpen,
106117
setIsContentTypePickerOpen,
118+
setIsConfirmPromptModalOpen,
107119
setIsConfirmCancelModalOpen,
108120
setIsPreviewModalOpen,
109121
setIsErrorPreviewModalOpen,

0 commit comments

Comments
 (0)