Skip to content

Commit 0a5148a

Browse files
authored
Revert/typeform changes (#10544)
* Revert "fix(typeform): issues with package-lock.json [] (#10528)" This reverts commit bd06214. * Revert "Feat: support for eu region [ZEND-7492] (#10514)" This reverts commit 96b9488.
1 parent b77a3cd commit 0a5148a

23 files changed

+18459
-13684
lines changed

apps/typeform/frontend/package-lock.json

Lines changed: 101 additions & 227 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/typeform/frontend/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
"@contentful/app-sdk": "4.23.0",
1717
"@contentful/f36-components": "^4.70.0",
1818
"@contentful/f36-icons": "^4.29.0",
19-
"@contentful/f36-multiselect": "^4.81.0",
2019
"@contentful/f36-tokens": "^4.0.5",
2120
"@emotion/css": "^11.13.0",
2221
"@testing-library/react": "^10.0.1",
@@ -25,7 +24,6 @@
2524
"@types/lodash": "^4.14.149",
2625
"@vitejs/plugin-react": "^4.3.1",
2726
"@vitest/coverage-v8": "^2.1.1",
28-
"contentful-management": "^11.54.1",
2927
"core-js": "^3.2.1",
3028
"happy-dom": "^15.7.4",
3129
"jest-environment-jsdom": "^29.0.1",

apps/typeform/frontend/src/AppConfig/AppConfig.tsx

Lines changed: 127 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,30 @@ import {
99
Option,
1010
FormLabel,
1111
Note,
12-
Flex,
13-
Box,
14-
Subheading,
15-
Stack,
1612
} from '@contentful/f36-components';
17-
import ContentTypeMultiSelect, { ContentType } from '../components/ContentTypeMultiSelect';
18-
import { OAuthConnector } from '../components/OAuthConnector';
19-
import { InstallationParameters, WorkspaceOption, WorkspacesResponse } from '../typings';
20-
import { validateParameters, getToken, resetLocalStorage } from '../utils';
13+
import FieldSelector from './FieldSelector';
14+
import {
15+
CompatibleFields,
16+
ContentType,
17+
Hash,
18+
EditorInterface,
19+
InstallationParameters,
20+
SelectedFields,
21+
WorkspaceOption,
22+
WorkspacesResponse,
23+
} from '../typings';
24+
import {
25+
getCompatibleFields,
26+
editorInterfacesToSelectedFields,
27+
selectedFieldsToTargetState,
28+
validateParameters,
29+
getToken,
30+
resetLocalStorage,
31+
} from '../utils';
2132
import { styles } from './styles';
22-
import { BASE_URL } from '../constants';
33+
34+
// @ts-ignore 2307
35+
import logo from './config-screen-logo.svg';
2336

2437
const AUTH_ERROR_CODES = [401, 403];
2538

@@ -30,18 +43,22 @@ interface Props {
3043

3144
interface State {
3245
selectedWorkspaceId: string;
33-
baseUrl: string;
3446
accessToken: string;
3547
workspaces: WorkspaceOption[];
36-
selectedContentTypes: ContentType[];
48+
contentTypes: ContentType[];
49+
selectedContentTypes: string[];
50+
selectedFields: SelectedFields;
51+
compatibleFields: CompatibleFields;
3752
}
3853

3954
export class AppConfig extends React.Component<Props, State> {
4055
state: State = {
56+
contentTypes: [],
57+
compatibleFields: {},
4158
workspaces: [],
4259
selectedContentTypes: [],
60+
selectedFields: {},
4361
selectedWorkspaceId: '',
44-
baseUrl: BASE_URL,
4562
accessToken: getToken(),
4663
};
4764

@@ -50,61 +67,51 @@ export class AppConfig extends React.Component<Props, State> {
5067

5168
sdk.app.onConfigure(this.onAppConfigure);
5269

53-
const paramsResponse = await sdk.app.getParameters();
70+
const [contentTypesResponse, eisResponse, paramsResponse] = await Promise.all([
71+
sdk.space.getContentTypes(),
72+
sdk.space.getEditorInterfaces(),
73+
sdk.app.getParameters(),
74+
this.fetchWorkspaces(),
75+
]);
76+
77+
const contentTypes = (contentTypesResponse as Hash).items as ContentType[];
78+
const editorInterfaces = (eisResponse as Hash).items as EditorInterface[];
79+
const compatibleFields = getCompatibleFields(contentTypes);
80+
const filteredContentTypes = contentTypes.filter((ct) => {
81+
const fields = compatibleFields[ct.sys.id];
82+
return fields && fields.length > 0;
83+
});
84+
5485
const parameters: InstallationParameters = paramsResponse as InstallationParameters;
55-
const effectiveBaseUrl = get(parameters, ['baseUrl'], BASE_URL);
56-
const effectiveAccessToken = getToken(effectiveBaseUrl);
5786

5887
this.setState(
5988
{
6089
selectedWorkspaceId: get(parameters, ['selectedWorkspaceId'], ''),
61-
baseUrl: effectiveBaseUrl,
62-
accessToken: effectiveAccessToken,
90+
compatibleFields,
91+
contentTypes: filteredContentTypes,
92+
selectedFields: editorInterfacesToSelectedFields(editorInterfaces, sdk.ids.app),
6393
},
64-
() => {
65-
sdk.app.setReady();
66-
// Fetch workspaces after state is set
67-
if (effectiveAccessToken) {
68-
this.fetchWorkspaces();
69-
}
70-
}
94+
() => sdk.app.setReady()
7195
);
7296
}
7397

7498
fetchWorkspaces = async () => {
7599
try {
76-
const { baseUrl, accessToken } = this.state;
77-
78-
if (!accessToken) {
79-
return;
80-
}
81-
82-
const apiUrl = `${window.location.origin}/workspaces?baseUrl=${encodeURIComponent(baseUrl)}`;
83-
const response = await fetch(apiUrl, {
100+
const response = await fetch(`/workspaces`, {
84101
headers: {
85-
Authorization: `Bearer ${accessToken}`,
102+
Authorization: `Bearer ${this.state.accessToken}`,
86103
},
87104
});
88105

89106
if (AUTH_ERROR_CODES.includes(response.status)) {
90-
resetLocalStorage(baseUrl);
107+
resetLocalStorage();
91108
this.setState({ accessToken: '' });
92109
return;
93110
}
94111

95-
if (!response.ok) {
96-
const errorText = await response.text();
97-
if (AUTH_ERROR_CODES.includes(response.status)) {
98-
resetLocalStorage(baseUrl);
99-
this.setState({ accessToken: '' });
100-
return;
101-
}
102-
throw new Error(`Failed to fetch workspaces: ${response.status} ${errorText}`);
103-
}
104-
105-
const result: WorkspacesResponse = (await response.json()) as WorkspacesResponse;
112+
const result: WorkspacesResponse = await response.json();
106113
this.setState({ workspaces: this.normalizeWorkspaceResponse(result) });
107-
} catch (error) {
114+
} catch (_error) {
108115
this.props.sdk.notifier.error(
109116
'There was a problem fetching your Typeform workspaces. Please try again.'
110117
);
@@ -119,7 +126,7 @@ export class AppConfig extends React.Component<Props, State> {
119126
};
120127

121128
onAppConfigure = () => {
122-
const { accessToken, selectedWorkspaceId, baseUrl, selectedContentTypes } = this.state;
129+
const { accessToken, selectedWorkspaceId, contentTypes, selectedFields } = this.state;
123130
const parameters = { selectedWorkspaceId, accessToken };
124131
const error = validateParameters(parameters);
125132
const hasStaleWorkspaceIdSelected = !this.selectedWorkspaceIdIsValid();
@@ -134,19 +141,9 @@ export class AppConfig extends React.Component<Props, State> {
134141
return false;
135142
}
136143

137-
// Convert selectedContentTypes to targetState format
138-
const editorInterface = selectedContentTypes.reduce((acc, contentType) => {
139-
return {
140-
...acc,
141-
[contentType.id]: {
142-
sidebar: { position: 0 },
143-
},
144-
};
145-
}, {});
146-
147144
return {
148-
parameters: { selectedWorkspaceId, baseUrl },
149-
targetState: { EditorInterface: editorInterface },
145+
parameters: { selectedWorkspaceId },
146+
targetState: selectedFieldsToTargetState(contentTypes, selectedFields),
150147
};
151148
};
152149

@@ -160,26 +157,16 @@ export class AppConfig extends React.Component<Props, State> {
160157
this.setState({ selectedWorkspaceId: id.trim() });
161158
};
162159

163-
setBaseUrl = (baseUrl: string) => {
164-
const trimmedBaseUrl = baseUrl.trim();
165-
const tokenForNewBaseUrl = getToken(trimmedBaseUrl);
166-
this.setState({ baseUrl: trimmedBaseUrl, accessToken: tokenForNewBaseUrl }, () => {
167-
if (tokenForNewBaseUrl) {
168-
this.fetchWorkspaces();
169-
}
170-
});
160+
setAccessToken = (token: string) => {
161+
this.setState({ accessToken: token.trim() });
171162
};
172163

173-
setAccessToken = (token: string) => {
174-
this.setState({ accessToken: token.trim() }, () => {
175-
if (token) {
176-
this.fetchWorkspaces();
177-
}
178-
});
164+
onSelectedFieldsChange = (selectedFields: SelectedFields) => {
165+
this.setState({ selectedFields });
179166
};
180167

181168
render() {
182-
const { selectedWorkspaceId, baseUrl, workspaces, selectedContentTypes, accessToken } =
169+
const { contentTypes, compatibleFields, selectedFields, selectedWorkspaceId, workspaces } =
183170
this.state;
184171

185172
const { sdk } = this.props;
@@ -188,50 +175,29 @@ export class AppConfig extends React.Component<Props, State> {
188175
} = sdk;
189176

190177
return (
191-
<Flex justifyContent="center" alignItems="center">
192-
<Box marginBottom="spacing2Xl" marginTop="spacing2Xl" className={styles.body}>
193-
<Heading marginBottom="spacingS">Set up Typeform</Heading>
194-
<Paragraph marginBottom="spacingXl">
195-
The{' '}
196-
<TextLink href="https://www.typeform.com/" target="_blank" rel="noopener noreferrer">
197-
Typeform
198-
</TextLink>{' '}
199-
app allows you to reference your forms from Typeform without leaving Contentful.
200-
</Paragraph>
201-
202-
<Subheading marginTop="spacingXl" marginBottom="spacing2Xs">
203-
Configure access
204-
</Subheading>
205-
<Paragraph marginBottom="spacingM">Section subtitle with basic instructions</Paragraph>
206-
207-
<Box marginBottom="spacingL">
208-
<OAuthConnector
209-
sdk={sdk}
210-
baseUrl={baseUrl}
211-
onBaseUrlChange={this.setBaseUrl}
212-
onTokenChange={this.setAccessToken}
213-
expireSoon={this.props.expireSoon}
214-
/>
215-
</Box>
216-
217-
<Box marginBottom="spacingL">
218-
<FormLabel htmlFor="baseUrl" marginBottom="spacingXs">
219-
Typeform region
220-
</FormLabel>
221-
<Select
222-
id="baseUrl"
223-
name="baseUrl"
224-
onChange={(event: any) => this.setBaseUrl(event.currentTarget.value)}
225-
value={baseUrl}
226-
data-test-id="typeform-base-url-select">
227-
<Option value="https://api.typeform.com">US (typeform.com)</Option>
228-
<Option value="https://api.typeform.eu">EU (typeform.eu)</Option>
229-
</Select>
230-
</Box>
231-
232-
{accessToken && (
233-
<>
234-
<Box marginBottom="spacingL">
178+
<div>
179+
<div className={styles.background('#262627')} />
180+
<div className={styles.body}>
181+
<div>
182+
<div>
183+
<>
184+
<Heading>About Typeform</Heading>
185+
<Paragraph className={styles.aboutP}>
186+
The{' '}
187+
<TextLink
188+
href="https://www.typeform.com/"
189+
target="_blank"
190+
rel="noopener noreferrer">
191+
Typeform
192+
</TextLink>{' '}
193+
app allows you to reference your forms from Typeform without leaving Contentful.
194+
</Paragraph>
195+
</>
196+
<hr className={styles.splitter} />
197+
</div>
198+
<div>
199+
<>
200+
<Heading>Configuration</Heading>
235201
<FormLabel htmlFor="workspaceId" isRequired>
236202
Typeform workspace
237203
</FormLabel>
@@ -251,32 +217,49 @@ export class AppConfig extends React.Component<Props, State> {
251217
</Option>
252218
))}
253219
</Select>
254-
</Box>
255-
</>
256-
)}
257-
258-
<hr className={styles.splitter} />
259-
260-
<Subheading marginTop="spacingXl" marginBottom="spacing2Xs">
261-
Assign content types
262-
</Subheading>
263-
<Paragraph marginBottom="spacingM">
264-
Select the content type(s) you want to use with Typeform. You can change this anytime by
265-
navigating to the 'Sidebar' tab in your content model.
266-
</Paragraph>
267-
<Paragraph marginBottom="spacingXs" style={{ fontWeight: '600' }}>
268-
Content types
269-
</Paragraph>
270-
<ContentTypeMultiSelect
271-
selectedContentTypes={selectedContentTypes}
272-
setSelectedContentTypes={(contentTypes) =>
273-
this.setState({ selectedContentTypes: contentTypes })
274-
}
275-
sdk={sdk}
276-
cma={sdk.cma}
277-
/>
278-
</Box>
279-
</Flex>
220+
</>
221+
<hr className={styles.splitter} />
222+
<>
223+
<Heading>Assign to content types</Heading>
224+
{contentTypes.length > 0 ? (
225+
<>
226+
<Paragraph>
227+
This app can only be used with <strong>Short text</strong> fields. Select
228+
which content types to use with the Typeform App.
229+
</Paragraph>
230+
<FieldSelector
231+
contentTypes={contentTypes}
232+
compatibleFields={compatibleFields}
233+
selectedFields={selectedFields}
234+
onSelectedFieldsChange={this.onSelectedFieldsChange}
235+
/>
236+
</>
237+
) : (
238+
<Note variant="warning">
239+
There are <strong>no content types with fields of type Short Text</strong>{' '}
240+
fields in this environment. You can add one in your{' '}
241+
<TextLink
242+
variant="primary"
243+
target="_blank"
244+
rel="noopener noreferrer"
245+
href={
246+
environment === 'master'
247+
? `https://${sdk.hostnames.webapp}/spaces/${space}/content_types`
248+
: `https://${sdk.hostnames.webapp}/spaces/${space}/environments/${environment}/content_types`
249+
}>
250+
content model
251+
</TextLink>{' '}
252+
and assign it to the app from this screen.
253+
</Note>
254+
)}
255+
</>
256+
</div>
257+
</div>
258+
</div>
259+
<div className={styles.icon}>
260+
<img src={logo} alt="typeform logo" />
261+
</div>
262+
</div>
280263
);
281264
}
282265
}

0 commit comments

Comments
 (0)