-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(open-forms-embed): create strapi open-forms-embed field
- Loading branch information
1 parent
a481c82
commit 1941b14
Showing
32 changed files
with
544 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Strapi Plugin: strapi-plugin-open-forms-embed | ||
|
||
This custom field serves as a dropdown representation of available OpenForms within the Strapi dashboard. It retrieves the `name` and `uuid` through a fetch function that calls the OpenForms API. | ||
|
||
## Installation | ||
|
||
```shell | ||
|
||
yarn install @frameless/strapi-plugin-open-forms-embed | ||
|
||
``` | ||
|
||
## Usage | ||
|
||
Navigate to the Strapi dashboard's `config/plugins.ts`. | ||
|
||
```ts | ||
export default ({ env }) => ({ | ||
"open-forms-embed": { | ||
enabled: true, | ||
config: { | ||
api_url: env("OPEN_FORMS_API_URL"), | ||
token: env("OPEN_FORMS_API_TOKEN"), | ||
}, | ||
}, | ||
}); | ||
``` | ||
|
||
**Build the dashboard**: | ||
|
||
```shell | ||
yarn build | ||
|
||
``` |
24 changes: 24 additions & 0 deletions
24
packages/strapi-plugin-open-forms-embed/admin/src/components/ComboboxIcon/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { Flex } from '@strapi/design-system/Flex'; | ||
import { Icon } from '@strapi/design-system/Icon'; | ||
import User from '@strapi/icons/User'; | ||
import React from 'react'; | ||
import styled from 'styled-components'; | ||
|
||
const IconBox = styled(Flex)` | ||
background-color: #f0f0ff; /* primary100 */ | ||
border: 1px solid #d9d8ff; /* primary200 */ | ||
svg > path { | ||
fill: #4945ff; /* primary600 */ | ||
} | ||
`; | ||
|
||
function ComboboxIcon() { | ||
return ( | ||
<IconBox justifyContent="center" alignItems="center" width={7} height={6} hasRadius aria-hidden> | ||
<Icon as={User} /> | ||
</IconBox> | ||
); | ||
} | ||
|
||
export default ComboboxIcon; |
103 changes: 103 additions & 0 deletions
103
packages/strapi-plugin-open-forms-embed/admin/src/components/CustomCombobox/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { Combobox, ComboboxOption } from '@strapi/design-system/Combobox'; | ||
import { Field, FieldError, FieldHint, FieldLabel } from '@strapi/design-system/Field'; | ||
import { Stack } from '@strapi/design-system/Stack'; | ||
import React, { useEffect } from 'react'; | ||
import { useIntl } from 'react-intl'; | ||
import usePluginConfig from '../../hooks/use-plugin-config'; | ||
|
||
interface CustomComboboxProps { | ||
intlLabel: any; | ||
// eslint-disable-next-line no-unused-vars | ||
onChange: (param: any) => {}; | ||
attribute: any; | ||
name: string; | ||
description: any; | ||
disabled: boolean; | ||
error: string; | ||
labelAction: any; | ||
required: boolean; | ||
value: string; | ||
placeholder: any; | ||
} | ||
|
||
function CustomCombobox({ | ||
value, | ||
onChange, | ||
name, | ||
intlLabel, | ||
labelAction, | ||
required, | ||
attribute, | ||
description, | ||
placeholder, | ||
disabled, | ||
error, | ||
}: CustomComboboxProps) { | ||
const { formatMessage } = useIntl(); | ||
const [openForms, setOpenForms] = React.useState([]); | ||
const { config } = usePluginConfig(); | ||
const apiUrl = config.api_url?.endsWith('/') ? `${config.api_url}forms` : `${config.api_url}/forms`; | ||
|
||
const fetchAllOpenForms = async () => { | ||
try { | ||
const response = await fetch(apiUrl, { | ||
mode: 'cors', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Accept: 'application/json', | ||
Authorization: `Token ${config.token}`, | ||
}, | ||
}); | ||
const data = await response.json(); | ||
setOpenForms(data); | ||
} catch (error) { | ||
// eslint-disable-next-line no-console | ||
console.log(error); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
if (config?.api_url && config?.token && apiUrl) { | ||
fetchAllOpenForms(); | ||
} | ||
}, [config?.api_url, config?.token]); | ||
|
||
const generateOpenFormsData = (params) => { | ||
return new URLSearchParams({ ...params }).toString(); | ||
}; | ||
return ( | ||
<Field name={name} id={name} error={error} hint={description && formatMessage(description)}> | ||
<Stack spacing={1}> | ||
<FieldLabel action={labelAction} required={required}> | ||
{formatMessage(intlLabel)} | ||
</FieldLabel> | ||
<Combobox | ||
placeholder={placeholder && formatMessage(placeholder)} | ||
aria-label={formatMessage(intlLabel)} | ||
aria-disabled={disabled} | ||
disabled={disabled} | ||
value={value} | ||
onChange={(url: string) => onChange({ target: { name, value: url, type: attribute.type } })} | ||
> | ||
{openForms?.length > 0 && | ||
openForms?.map(({ uuid, name, slug }) => ( | ||
<ComboboxOption | ||
value={generateOpenFormsData({ | ||
uuid, | ||
slug, | ||
label: name, | ||
})} | ||
key={uuid} | ||
> | ||
{name} | ||
</ComboboxOption> | ||
))} | ||
</Combobox> | ||
<FieldHint /> | ||
<FieldError /> | ||
</Stack> | ||
</Field> | ||
); | ||
} | ||
|
||
export default CustomCombobox; |
3 changes: 3 additions & 0 deletions
3
packages/strapi-plugin-open-forms-embed/admin/src/constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import pluginId from './pluginId'; | ||
|
||
export const RESOLVE_CONFIG = `${pluginId}/resolve-config`; |
60 changes: 60 additions & 0 deletions
60
packages/strapi-plugin-open-forms-embed/admin/src/hooks/use-plugin-config.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { useFetchClient, useNotification } from '@strapi/helper-plugin'; | ||
import { useEffect } from 'react'; | ||
import { useDispatch, useSelector } from 'react-redux'; | ||
import { RESOLVE_CONFIG } from '../constants'; | ||
import pluginId from '../pluginId'; | ||
|
||
const usePluginConfig = () => { | ||
const dispatch = useDispatch(); | ||
const toggleNotification = useNotification(); | ||
|
||
const { isLoading, config } = useSelector((state: any) => state[`${pluginId}_config`]); | ||
const client = useFetchClient(); | ||
|
||
useEffect(() => { | ||
// Do nothing if we have already loaded the config data. | ||
if (!isLoading && !!config) { | ||
return; | ||
} | ||
|
||
const abortController = new AbortController(); | ||
|
||
// eslint-disable-next-line consistent-return | ||
const fetchData = async () => { | ||
try { | ||
const endpoint = `/${pluginId}/config`; | ||
const { data } = await client.get(endpoint, { | ||
signal: abortController.signal, | ||
}); | ||
|
||
return data ?? {}; | ||
} catch (err) { | ||
// eslint-disable-next-line no-console | ||
console.error(err); | ||
|
||
if (!abortController.signal.aborted) { | ||
toggleNotification({ | ||
type: 'warning', | ||
message: { id: 'notification.error' }, | ||
}); | ||
|
||
return err; | ||
} | ||
} | ||
}; | ||
|
||
fetchData() | ||
.then((data) => dispatch({ type: RESOLVE_CONFIG, data })) | ||
.catch((error) => { | ||
// eslint-disable-next-line no-console | ||
console.error(error); | ||
}); | ||
|
||
// eslint-disable-next-line consistent-return | ||
return () => abortController.abort(); | ||
}, [client, config, dispatch, isLoading, toggleNotification]); | ||
|
||
return { config: config, isLoading: isLoading }; | ||
}; | ||
|
||
export default usePluginConfig; |
74 changes: 74 additions & 0 deletions
74
packages/strapi-plugin-open-forms-embed/admin/src/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { prefixPluginTranslations } from '@strapi/helper-plugin'; | ||
import ComboboxIcon from './components/ComboboxIcon'; | ||
import pluginId from './pluginId'; | ||
import reducers from './reducers'; | ||
import getTrad from './utils/getTrad'; | ||
|
||
export default { | ||
register(app: any) { | ||
app.addReducers(reducers); | ||
app.customFields.register({ | ||
name: pluginId, | ||
pluginId, | ||
type: 'string', | ||
icon: ComboboxIcon, | ||
intlLabel: { | ||
id: getTrad('open-forms-embed.label'), | ||
defaultMessage: 'Choose an Embedded Open Form', | ||
}, | ||
intlDescription: { | ||
id: getTrad('open-forms-embed.description'), | ||
defaultMessage: | ||
'Upon selecting a form, its unique identifier (UUID) will be stored in the database for future reference.', | ||
}, | ||
components: { | ||
Input: async () => import('./components/CustomCombobox'), | ||
}, | ||
options: { | ||
advanced: [ | ||
{ | ||
sectionTitle: { | ||
id: 'global.settings', | ||
defaultMessage: 'Settings', | ||
}, | ||
items: [ | ||
{ | ||
name: 'required', | ||
type: 'checkbox', | ||
intlLabel: { | ||
id: 'form.attribute.item.requiredField', | ||
defaultMessage: 'Required field', | ||
}, | ||
description: { | ||
id: 'form.attribute.item.requiredField.description', | ||
defaultMessage: "You won't be able to create an entry if this field is empty", | ||
}, | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
}); | ||
}, | ||
async registerTrads({ locales }: any) { | ||
const importedTrads = await Promise.all( | ||
locales.map((locale: any) => { | ||
return import(`./translations/${locale}.json`) | ||
.then(({ default: data }) => { | ||
return { | ||
data: prefixPluginTranslations(data, pluginId), | ||
locale, | ||
}; | ||
}) | ||
.catch(() => { | ||
return { | ||
data: {}, | ||
locale, | ||
}; | ||
}); | ||
}), | ||
); | ||
|
||
return Promise.resolve(importedTrads); | ||
}, | ||
}; |
5 changes: 5 additions & 0 deletions
5
packages/strapi-plugin-open-forms-embed/admin/src/pluginId.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import pluginPkg from '../../package.json'; | ||
|
||
const pluginId = pluginPkg.name.replace(/^@frameless\/(@[^-,.][\w,-]+\/|strapi-)plugin-/i, ''); | ||
|
||
export default pluginId; |
24 changes: 24 additions & 0 deletions
24
packages/strapi-plugin-open-forms-embed/admin/src/reducers/config.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import produce from 'immer'; | ||
import { RESOLVE_CONFIG } from '../constants'; | ||
|
||
const initialState = { | ||
isLoading: true, | ||
config: {}, | ||
}; | ||
|
||
const configReducer = produce((state = initialState, action) => { | ||
switch (action.type) { | ||
case RESOLVE_CONFIG: { | ||
state.isLoading = false; | ||
state.config = action.data; | ||
break; | ||
} | ||
|
||
default: | ||
return state; | ||
} | ||
|
||
return state; | ||
}); | ||
|
||
export default configReducer; |
8 changes: 8 additions & 0 deletions
8
packages/strapi-plugin-open-forms-embed/admin/src/reducers/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import config from './config'; | ||
import pluginId from '../pluginId'; | ||
|
||
const reducers = { | ||
[`${pluginId}_config`]: config, | ||
}; | ||
|
||
export default reducers; |
4 changes: 4 additions & 0 deletions
4
packages/strapi-plugin-open-forms-embed/admin/src/translations/en.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"open-forms-embed.label": "Choose an Embedded Open Form", | ||
"open-forms-embed.description": "Upon selecting a form, its unique identifier (UUID) will be stored in the database for future reference." | ||
} |
4 changes: 4 additions & 0 deletions
4
packages/strapi-plugin-open-forms-embed/admin/src/translations/nl.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"open-forms-embed.label": "Kies een ingebed open formulier", | ||
"open-forms-embed.description": "Bij het selecteren van een formulier wordt de unieke identificatie (UUID) ervan opgeslagen in de database voor toekomstige referentie." | ||
} |
5 changes: 5 additions & 0 deletions
5
packages/strapi-plugin-open-forms-embed/admin/src/utils/getTrad.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import pluginId from '../pluginId'; | ||
|
||
const getTrad = (id: string) => `${pluginId}.${id}`; | ||
|
||
export default getTrad; |
Oops, something went wrong.