UNPKG

strapi-plugin-users-permissions

Version:

Protect your API with a full-authentication process based on JWT

284 lines (251 loc) 8.43 kB
import React, { useCallback, useMemo, useRef, useState } from 'react'; import { useIntl } from 'react-intl'; import { Header, List } from '@buffetjs/custom'; import { Text } from '@buffetjs/core'; import { Pencil } from '@buffetjs/icons'; import { SettingsPageTitle, SizedInput, useGlobalContext, getYupInnerErrors, request, } from 'strapi-helper-plugin'; import { get, upperFirst, has } from 'lodash'; import { Row } from 'reactstrap'; import pluginPermissions from '../../permissions'; import { useForm } from '../../hooks'; import { getRequestURL, getTrad } from '../../utils'; import ListBaselineAlignment from '../../components/ListBaselineAlignment'; import ListRow from '../../components/ListRow'; import ModalForm from '../../components/ModalForm'; import createProvidersArray from './utils/createProvidersArray'; import forms from './utils/forms'; const ProvidersPage = () => { const { formatMessage } = useIntl(); const { emitEvent } = useGlobalContext(); const emitEventRef = useRef(emitEvent); const [isOpen, setIsOpen] = useState(false); const [isSubmiting, setIsSubmiting] = useState(false); const buttonSubmitRef = useRef(null); const [showForm, setShowForm] = useState(false); const [providerToEditName, setProviderToEditName] = useState(null); const updatePermissions = useMemo(() => { return { update: pluginPermissions.updateProviders }; }, []); const { allowedActions: { canUpdate }, dispatchResetForm, dispatchSetFormErrors, dispatchSubmitSucceeded, formErrors, handleChange, isLoading, isLoadingForPermissions, modifiedData, } = useForm('providers', updatePermissions); const providers = useMemo(() => createProvidersArray(modifiedData), [modifiedData]); const enabledProvidersCount = useMemo( () => providers.filter(provider => provider.enabled).length, [providers] ); const isProviderWithSubdomain = useMemo(() => { if (!providerToEditName) { return false; } const providerToEdit = providers.find(obj => obj.name === providerToEditName); return has(providerToEdit, 'subdomain'); }, [providers, providerToEditName]); const disabledProvidersCount = useMemo(() => { return providers.length - enabledProvidersCount; }, [providers, enabledProvidersCount]); const listTitle = useMemo(() => { const enabledMessage = formatMessage( { id: getTrad( `List.title.providers.enabled.${enabledProvidersCount > 1 ? 'plural' : 'singular'}` ), }, { number: enabledProvidersCount } ); const disabledMessage = formatMessage( { id: getTrad( `List.title.providers.disabled.${disabledProvidersCount > 1 ? 'plural' : 'singular'}` ), }, { number: disabledProvidersCount } ); return `${enabledMessage} ${disabledMessage}`; }, [formatMessage, enabledProvidersCount, disabledProvidersCount]); const pageTitle = formatMessage({ id: getTrad('HeaderNav.link.providers') }); const formToRender = useMemo(() => { if (providerToEditName === 'email') { return forms.email; } if (isProviderWithSubdomain) { return forms.providersWithSubdomain; } return forms.providers; }, [providerToEditName, isProviderWithSubdomain]); const handleClick = useCallback(() => { buttonSubmitRef.current.click(); }, []); const handleToggle = useCallback(() => { setIsOpen(prev => !prev); }, []); const handleClickEdit = useCallback( provider => { if (canUpdate) { setProviderToEditName(provider.name); handleToggle(); } }, [canUpdate, handleToggle] ); const handleClosed = useCallback(() => { setProviderToEditName(null); setShowForm(false); dispatchResetForm(); }, [dispatchResetForm]); const handleOpened = useCallback(() => { setShowForm(true); }, []); const handleSubmit = useCallback( async e => { e.preventDefault(); const { schema } = formToRender; let errors = {}; setIsSubmiting(true); try { await schema.validate(modifiedData[providerToEditName], { abortEarly: false }); strapi.lockAppWithOverlay(); try { emitEventRef.current('willEditAuthenticationProvider'); await request(getRequestURL('providers'), { method: 'PUT', body: { providers: modifiedData }, }); emitEventRef.current('didEditAuthenticationProvider'); strapi.notification.toggle({ type: 'success', message: { id: getTrad('notification.success.submit') }, }); dispatchSubmitSucceeded(); handleToggle(); } catch (err) { console.error(err); strapi.notification.toggle({ type: 'warning', message: { id: 'notification.error' }, }); } } catch (err) { console.error(err); errors = getYupInnerErrors(err); console.log(errors); } dispatchSetFormErrors(errors); setIsSubmiting(false); strapi.unlockApp(); }, [ dispatchSetFormErrors, dispatchSubmitSucceeded, formToRender, handleToggle, modifiedData, providerToEditName, ] ); return ( <> <SettingsPageTitle name={pageTitle} /> <div> <Header title={{ label: pageTitle }} isLoading={isLoadingForPermissions || isLoading} /> <ListBaselineAlignment /> <List title={listTitle} items={providers} isLoading={isLoadingForPermissions || isLoading} customRowComponent={provider => ( <ListRow {...provider} onClick={() => handleClickEdit(provider)} links={[ { icon: canUpdate ? <Pencil fill="#0e1622" /> : null, onClick: e => { e.stopPropagation(); handleClickEdit(provider); }, }, ]} > <td key="enabled"> <Text fontWeight="semiBold" lineHeight="18px" color={provider.enabled ? 'green' : 'lightOrange'} > {provider.enabled ? formatMessage({ id: getTrad('List.row.provider.enabled'), defaultMessage: 'Enabled', }) : formatMessage({ id: getTrad('List.row.provider.disabled'), defaultMessage: 'Disabled', })} </Text> </td> </ListRow> )} /> </div> <ModalForm isOpen={isOpen} onClick={handleClick} onCancel={handleToggle} isLoading={isSubmiting} onOpened={handleOpened} onClosed={handleClosed} onToggle={handleToggle} headerBreadcrumbs={[ getTrad('PopUpForm.header.edit.providers'), upperFirst(providerToEditName), ]} > {showForm && ( <form onSubmit={handleSubmit}> <Row> {formToRender.form.map(input => { const label = input.label.params ? { ...input.label, params: { provider: upperFirst(providerToEditName) } } : input.label; const value = input.name === 'noName' ? `${strapi.backendURL}/connect/${providerToEditName}/callback` : get(modifiedData, [providerToEditName, ...input.name.split('.')], ''); return ( <SizedInput key={input.name} {...input} label={label} error={formErrors[input.name]} name={`${providerToEditName}.${input.name}`} onChange={handleChange} value={value} /> ); })} </Row> <button type="submit" style={{ display: 'none' }} ref={buttonSubmitRef}> hidden button to use the native form event </button> </form> )} </ModalForm> </> ); }; export default ProvidersPage;