node_modules ignore

This commit is contained in:
oier committed 2025-05-08 23:43:47 +02:00
1 parent e19d52f172
commit 4574544c9f
65041 files changed
+10593536

No files matched your search

@@ -0,0 +1,194 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var admin = require('@strapi/strapi/admin');
var reactIntl = require('react-intl');
var reactQuery = require('react-query');
var constants = require('../../constants.js');
require('lodash/isEmpty');
var getTrad = require('../../utils/getTrad.js');
var layout = require('./utils/layout.js');
var schema = require('./utils/schema.js');
const ProtectedAdvancedSettingsPage = ()=>/*#__PURE__*/ jsxRuntime.jsx(admin.Page.Protect, {
permissions: constants.PERMISSIONS.readAdvancedSettings,
children: /*#__PURE__*/ jsxRuntime.jsx(AdvancedSettingsPage, {})
});
const AdvancedSettingsPage = ()=>{
const { formatMessage } = reactIntl.useIntl();
const { toggleNotification } = admin.useNotification();
const { notifyStatus } = designSystem.useNotifyAT();
const queryClient = reactQuery.useQueryClient();
const { get, put } = admin.useFetchClient();
const { formatAPIError } = admin.useAPIErrorHandler();
const { isLoading: isLoadingForPermissions, allowedActions: { canUpdate } } = admin.useRBAC({
update: constants.PERMISSIONS.updateAdvancedSettings
});
const { isLoading: isLoadingData, data } = reactQuery.useQuery([
'users-permissions',
'advanced'
], async ()=>{
const { data } = await get('/users-permissions/advanced');
return data;
}, {
onSuccess () {
notifyStatus(formatMessage({
id: getTrad('Form.advancedSettings.data.loaded'),
defaultMessage: 'Advanced settings data has been loaded'
}));
},
onError () {
toggleNotification({
type: 'danger',
message: formatMessage({
id: getTrad('notification.error'),
defaultMessage: 'An error occured'
})
});
}
});
const isLoading = isLoadingForPermissions || isLoadingData;
const submitMutation = reactQuery.useMutation((body)=>put('/users-permissions/advanced', body), {
async onSuccess () {
await queryClient.invalidateQueries([
'users-permissions',
'advanced'
]);
toggleNotification({
type: 'success',
message: formatMessage({
id: getTrad('notification.success.saved'),
defaultMessage: 'Saved'
})
});
},
onError (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
},
refetchActive: true
});
const { isLoading: isSubmittingForm } = submitMutation;
const handleSubmit = async (body)=>{
submitMutation.mutate({
...body,
email_confirmation_redirection: body.email_confirmation ? body.email_confirmation_redirection : ''
});
};
if (isLoading) {
return /*#__PURE__*/ jsxRuntime.jsx(admin.Page.Loading, {});
}
return /*#__PURE__*/ jsxRuntime.jsxs(admin.Page.Main, {
"aria-busy": isSubmittingForm,
children: [
/*#__PURE__*/ jsxRuntime.jsx(admin.Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: formatMessage({
id: getTrad('HeaderNav.link.advancedSettings'),
defaultMessage: 'Advanced Settings'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(admin.Form, {
onSubmit: handleSubmit,
initialValues: data.settings,
validationSchema: schema,
children: ({ values, isSubmitting, modified })=>{
return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(admin.Layouts.Header, {
title: formatMessage({
id: getTrad('HeaderNav.link.advancedSettings'),
defaultMessage: 'Advanced Settings'
}),
primaryAction: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
loading: isSubmitting,
type: "submit",
disabled: !modified || !canUpdate,
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Check, {}),
size: "S",
children: formatMessage({
id: 'global.save',
defaultMessage: 'Save'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(admin.Layouts.Content, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
background: "neutral0",
hasRadius: true,
shadow: "filterShadow",
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 7,
paddingRight: 7,
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
direction: "column",
alignItems: "stretch",
gap: 4,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "delta",
tag: "h2",
children: formatMessage({
id: 'global.settings',
defaultMessage: 'Settings'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Root, {
gap: 6,
children: [
{
label: {
id: getTrad('EditForm.inputSelect.label.role'),
defaultMessage: 'Default role for authenticated users'
},
hint: {
id: getTrad('EditForm.inputSelect.description.role'),
defaultMessage: 'It will attach the new authenticated user to the selected role.'
},
options: data.roles.map((role)=>({
label: role.name,
value: role.type
})),
name: 'default_role',
size: 6,
type: 'enumeration'
},
...layout
].map(({ size, ...field })=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Item, {
col: size,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxRuntime.jsx(admin.InputRenderer, {
...field,
disabled: field.name === 'email_confirmation_redirection' && values.email_confirmation === false,
label: formatMessage(field.label),
hint: field.hint ? formatMessage(field.hint) : undefined,
placeholder: field.placeholder ? formatMessage(field.placeholder) : undefined
})
}, field.name))
})
]
})
})
})
]
});
}
})
]
});
};
exports.AdvancedSettingsPage = AdvancedSettingsPage;
exports.ProtectedAdvancedSettingsPage = ProtectedAdvancedSettingsPage;
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":["../../../../admin/src/pages/AdvancedSettings/index.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Flex, Grid, Typography, useNotifyAT } from '@strapi/design-system';\nimport { Check } from '@strapi/icons';\nimport {\n useAPIErrorHandler,\n Page,\n Form,\n InputRenderer,\n useNotification,\n useFetchClient,\n useRBAC,\n Layouts,\n} from '@strapi/strapi/admin';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery, useQueryClient } from 'react-query';\n\nimport { PERMISSIONS } from '../../constants';\nimport { getTrad } from '../../utils';\n\nimport layout from './utils/layout';\nimport schema from './utils/schema';\n\nconst ProtectedAdvancedSettingsPage = () => (\n <Page.Protect permissions={PERMISSIONS.readAdvancedSettings}>\n <AdvancedSettingsPage />\n </Page.Protect>\n);\n\nconst AdvancedSettingsPage = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { notifyStatus } = useNotifyAT();\n const queryClient = useQueryClient();\n const { get, put } = useFetchClient();\n const { formatAPIError } = useAPIErrorHandler();\n\n const {\n isLoading: isLoadingForPermissions,\n allowedActions: { canUpdate },\n } = useRBAC({ update: PERMISSIONS.updateAdvancedSettings });\n\n const { isLoading: isLoadingData, data } = useQuery(\n ['users-permissions', 'advanced'],\n async () => {\n const { data } = await get('/users-permissions/advanced');\n\n return data;\n },\n {\n onSuccess() {\n notifyStatus(\n formatMessage({\n id: getTrad('Form.advancedSettings.data.loaded'),\n defaultMessage: 'Advanced settings data has been loaded',\n })\n );\n },\n onError() {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: getTrad('notification.error'),\n defaultMessage: 'An error occured',\n }),\n });\n },\n }\n );\n\n const isLoading = isLoadingForPermissions || isLoadingData;\n\n const submitMutation = useMutation((body) => put('/users-permissions/advanced', body), {\n async onSuccess() {\n await queryClient.invalidateQueries(['users-permissions', 'advanced']);\n\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTrad('notification.success.saved'),\n defaultMessage: 'Saved',\n }),\n });\n },\n onError(error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n },\n refetchActive: true,\n });\n\n const { isLoading: isSubmittingForm } = submitMutation;\n\n const handleSubmit = async (body) => {\n submitMutation.mutate({\n ...body,\n email_confirmation_redirection: body.email_confirmation\n ? body.email_confirmation_redirection\n : '',\n });\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Page.Main aria-busy={isSubmittingForm}>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n {\n name: formatMessage({\n id: getTrad('HeaderNav.link.advancedSettings'),\n defaultMessage: 'Advanced Settings',\n }),\n }\n )}\n </Page.Title>\n <Form onSubmit={handleSubmit} initialValues={data.settings} validationSchema={schema}>\n {({ values, isSubmitting, modified }) => {\n return (\n <>\n <Layouts.Header\n title={formatMessage({\n id: getTrad('HeaderNav.link.advancedSettings'),\n defaultMessage: 'Advanced Settings',\n })}\n primaryAction={\n <Button\n loading={isSubmitting}\n type=\"submit\"\n disabled={!modified || !canUpdate}\n startIcon={<Check />}\n size=\"S\"\n >\n {formatMessage({ id: 'global.save', defaultMessage: 'Save' })}\n </Button>\n }\n />\n <Layouts.Content>\n <Box\n background=\"neutral0\"\n hasRadius\n shadow=\"filterShadow\"\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n >\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'global.settings',\n defaultMessage: 'Settings',\n })}\n </Typography>\n Line truncated
@@ -0,0 +1,191 @@
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import 'react';
import { useNotifyAT, Button, Box, Flex, Typography, Grid } from '@strapi/design-system';
import { Check } from '@strapi/icons';
import { Page, useNotification, useFetchClient, useAPIErrorHandler, useRBAC, Form, Layouts, InputRenderer } from '@strapi/strapi/admin';
import { useIntl } from 'react-intl';
import { useQueryClient, useQuery, useMutation } from 'react-query';
import { PERMISSIONS } from '../../constants.mjs';
import 'lodash/isEmpty';
import getTrad from '../../utils/getTrad.mjs';
import layout from './utils/layout.mjs';
import schema from './utils/schema.mjs';
const ProtectedAdvancedSettingsPage = ()=>/*#__PURE__*/ jsx(Page.Protect, {
permissions: PERMISSIONS.readAdvancedSettings,
children: /*#__PURE__*/ jsx(AdvancedSettingsPage, {})
});
const AdvancedSettingsPage = ()=>{
const { formatMessage } = useIntl();
const { toggleNotification } = useNotification();
const { notifyStatus } = useNotifyAT();
const queryClient = useQueryClient();
const { get, put } = useFetchClient();
const { formatAPIError } = useAPIErrorHandler();
const { isLoading: isLoadingForPermissions, allowedActions: { canUpdate } } = useRBAC({
update: PERMISSIONS.updateAdvancedSettings
});
const { isLoading: isLoadingData, data } = useQuery([
'users-permissions',
'advanced'
], async ()=>{
const { data } = await get('/users-permissions/advanced');
return data;
}, {
onSuccess () {
notifyStatus(formatMessage({
id: getTrad('Form.advancedSettings.data.loaded'),
defaultMessage: 'Advanced settings data has been loaded'
}));
},
onError () {
toggleNotification({
type: 'danger',
message: formatMessage({
id: getTrad('notification.error'),
defaultMessage: 'An error occured'
})
});
}
});
const isLoading = isLoadingForPermissions || isLoadingData;
const submitMutation = useMutation((body)=>put('/users-permissions/advanced', body), {
async onSuccess () {
await queryClient.invalidateQueries([
'users-permissions',
'advanced'
]);
toggleNotification({
type: 'success',
message: formatMessage({
id: getTrad('notification.success.saved'),
defaultMessage: 'Saved'
})
});
},
onError (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
},
refetchActive: true
});
const { isLoading: isSubmittingForm } = submitMutation;
const handleSubmit = async (body)=>{
submitMutation.mutate({
...body,
email_confirmation_redirection: body.email_confirmation ? body.email_confirmation_redirection : ''
});
};
if (isLoading) {
return /*#__PURE__*/ jsx(Page.Loading, {});
}
return /*#__PURE__*/ jsxs(Page.Main, {
"aria-busy": isSubmittingForm,
children: [
/*#__PURE__*/ jsx(Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: formatMessage({
id: getTrad('HeaderNav.link.advancedSettings'),
defaultMessage: 'Advanced Settings'
})
})
}),
/*#__PURE__*/ jsx(Form, {
onSubmit: handleSubmit,
initialValues: data.settings,
validationSchema: schema,
children: ({ values, isSubmitting, modified })=>{
return /*#__PURE__*/ jsxs(Fragment, {
children: [
/*#__PURE__*/ jsx(Layouts.Header, {
title: formatMessage({
id: getTrad('HeaderNav.link.advancedSettings'),
defaultMessage: 'Advanced Settings'
}),
primaryAction: /*#__PURE__*/ jsx(Button, {
loading: isSubmitting,
type: "submit",
disabled: !modified || !canUpdate,
startIcon: /*#__PURE__*/ jsx(Check, {}),
size: "S",
children: formatMessage({
id: 'global.save',
defaultMessage: 'Save'
})
})
}),
/*#__PURE__*/ jsx(Layouts.Content, {
children: /*#__PURE__*/ jsx(Box, {
background: "neutral0",
hasRadius: true,
shadow: "filterShadow",
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 7,
paddingRight: 7,
children: /*#__PURE__*/ jsxs(Flex, {
direction: "column",
alignItems: "stretch",
gap: 4,
children: [
/*#__PURE__*/ jsx(Typography, {
variant: "delta",
tag: "h2",
children: formatMessage({
id: 'global.settings',
defaultMessage: 'Settings'
})
}),
/*#__PURE__*/ jsx(Grid.Root, {
gap: 6,
children: [
{
label: {
id: getTrad('EditForm.inputSelect.label.role'),
defaultMessage: 'Default role for authenticated users'
},
hint: {
id: getTrad('EditForm.inputSelect.description.role'),
defaultMessage: 'It will attach the new authenticated user to the selected role.'
},
options: data.roles.map((role)=>({
label: role.name,
value: role.type
})),
name: 'default_role',
size: 6,
type: 'enumeration'
},
...layout
].map(({ size, ...field })=>/*#__PURE__*/ jsx(Grid.Item, {
col: size,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsx(InputRenderer, {
...field,
disabled: field.name === 'email_confirmation_redirection' && values.email_confirmation === false,
label: formatMessage(field.label),
hint: field.hint ? formatMessage(field.hint) : undefined,
placeholder: field.placeholder ? formatMessage(field.placeholder) : undefined
})
}, field.name))
})
]
})
})
})
]
});
}
})
]
});
};
export { AdvancedSettingsPage, ProtectedAdvancedSettingsPage };
//# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":["../../../../admin/src/pages/AdvancedSettings/index.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Flex, Grid, Typography, useNotifyAT } from '@strapi/design-system';\nimport { Check } from '@strapi/icons';\nimport {\n useAPIErrorHandler,\n Page,\n Form,\n InputRenderer,\n useNotification,\n useFetchClient,\n useRBAC,\n Layouts,\n} from '@strapi/strapi/admin';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery, useQueryClient } from 'react-query';\n\nimport { PERMISSIONS } from '../../constants';\nimport { getTrad } from '../../utils';\n\nimport layout from './utils/layout';\nimport schema from './utils/schema';\n\nconst ProtectedAdvancedSettingsPage = () => (\n <Page.Protect permissions={PERMISSIONS.readAdvancedSettings}>\n <AdvancedSettingsPage />\n </Page.Protect>\n);\n\nconst AdvancedSettingsPage = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { notifyStatus } = useNotifyAT();\n const queryClient = useQueryClient();\n const { get, put } = useFetchClient();\n const { formatAPIError } = useAPIErrorHandler();\n\n const {\n isLoading: isLoadingForPermissions,\n allowedActions: { canUpdate },\n } = useRBAC({ update: PERMISSIONS.updateAdvancedSettings });\n\n const { isLoading: isLoadingData, data } = useQuery(\n ['users-permissions', 'advanced'],\n async () => {\n const { data } = await get('/users-permissions/advanced');\n\n return data;\n },\n {\n onSuccess() {\n notifyStatus(\n formatMessage({\n id: getTrad('Form.advancedSettings.data.loaded'),\n defaultMessage: 'Advanced settings data has been loaded',\n })\n );\n },\n onError() {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: getTrad('notification.error'),\n defaultMessage: 'An error occured',\n }),\n });\n },\n }\n );\n\n const isLoading = isLoadingForPermissions || isLoadingData;\n\n const submitMutation = useMutation((body) => put('/users-permissions/advanced', body), {\n async onSuccess() {\n await queryClient.invalidateQueries(['users-permissions', 'advanced']);\n\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTrad('notification.success.saved'),\n defaultMessage: 'Saved',\n }),\n });\n },\n onError(error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n },\n refetchActive: true,\n });\n\n const { isLoading: isSubmittingForm } = submitMutation;\n\n const handleSubmit = async (body) => {\n submitMutation.mutate({\n ...body,\n email_confirmation_redirection: body.email_confirmation\n ? body.email_confirmation_redirection\n : '',\n });\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Page.Main aria-busy={isSubmittingForm}>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n {\n name: formatMessage({\n id: getTrad('HeaderNav.link.advancedSettings'),\n defaultMessage: 'Advanced Settings',\n }),\n }\n )}\n </Page.Title>\n <Form onSubmit={handleSubmit} initialValues={data.settings} validationSchema={schema}>\n {({ values, isSubmitting, modified }) => {\n return (\n <>\n <Layouts.Header\n title={formatMessage({\n id: getTrad('HeaderNav.link.advancedSettings'),\n defaultMessage: 'Advanced Settings',\n })}\n primaryAction={\n <Button\n loading={isSubmitting}\n type=\"submit\"\n disabled={!modified || !canUpdate}\n startIcon={<Check />}\n size=\"S\"\n >\n {formatMessage({ id: 'global.save', defaultMessage: 'Save' })}\n </Button>\n }\n />\n <Layouts.Content>\n <Box\n background=\"neutral0\"\n hasRadius\n shadow=\"filterShadow\"\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n >\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'global.settings',\n defaultMessage: 'Settings',\n })}\n </Typography>\n Line truncated
@@ -0,0 +1,83 @@
'use strict';
require('lodash/isEmpty');
var getTrad = require('../../../utils/getTrad.js');
const layout = [
{
label: {
id: getTrad('EditForm.inputToggle.label.email'),
defaultMessage: 'One account per email address'
},
hint: {
id: getTrad('EditForm.inputToggle.description.email'),
defaultMessage: 'Disallow the user to create multiple accounts using the same email address with different authentication providers.'
},
name: 'unique_email',
type: 'boolean',
size: 12
},
{
label: {
id: getTrad('EditForm.inputToggle.label.sign-up'),
defaultMessage: 'Enable sign-ups'
},
hint: {
id: getTrad('EditForm.inputToggle.description.sign-up'),
defaultMessage: 'When disabled (OFF), the registration process is forbidden. No one can subscribe anymore no matter the used provider.'
},
name: 'allow_register',
type: 'boolean',
size: 12
},
{
label: {
id: getTrad('EditForm.inputToggle.label.email-reset-password'),
defaultMessage: 'Reset password page'
},
hint: {
id: getTrad('EditForm.inputToggle.description.email-reset-password'),
defaultMessage: "URL of your application's reset password page."
},
placeholder: {
id: getTrad('EditForm.inputToggle.placeholder.email-reset-password'),
defaultMessage: 'ex: https://youtfrontend.com/reset-password'
},
name: 'email_reset_password',
type: 'string',
size: 12
},
{
label: {
id: getTrad('EditForm.inputToggle.label.email-confirmation'),
defaultMessage: 'Enable email confirmation'
},
hint: {
id: getTrad('EditForm.inputToggle.description.email-confirmation'),
defaultMessage: 'When enabled (ON), new registered users receive a confirmation email.'
},
name: 'email_confirmation',
type: 'boolean',
size: 12
},
{
label: {
id: getTrad('EditForm.inputToggle.label.email-confirmation-redirection'),
defaultMessage: 'Redirection url'
},
hint: {
id: getTrad('EditForm.inputToggle.description.email-confirmation-redirection'),
defaultMessage: 'After you confirmed your email, choose where you will be redirected.'
},
placeholder: {
id: getTrad('EditForm.inputToggle.placeholder.email-confirmation-redirection'),
defaultMessage: 'ex: https://youtfrontend.com/email-confirmation'
},
name: 'email_confirmation_redirection',
type: 'string',
size: 12
}
];
module.exports = layout;
//# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
{"version":3,"file":"layout.js","sources":["../../../../../admin/src/pages/AdvancedSettings/utils/layout.js"],"sourcesContent":["import { getTrad } from '../../../utils';\n\nconst layout = [\n {\n label: {\n id: getTrad('EditForm.inputToggle.label.email'),\n defaultMessage: 'One account per email address',\n },\n hint: {\n id: getTrad('EditForm.inputToggle.description.email'),\n defaultMessage:\n 'Disallow the user to create multiple accounts using the same email address with different authentication providers.',\n },\n name: 'unique_email',\n type: 'boolean',\n size: 12,\n },\n {\n label: {\n id: getTrad('EditForm.inputToggle.label.sign-up'),\n defaultMessage: 'Enable sign-ups',\n },\n hint: {\n id: getTrad('EditForm.inputToggle.description.sign-up'),\n defaultMessage:\n 'When disabled (OFF), the registration process is forbidden. No one can subscribe anymore no matter the used provider.',\n },\n name: 'allow_register',\n type: 'boolean',\n size: 12,\n },\n {\n label: {\n id: getTrad('EditForm.inputToggle.label.email-reset-password'),\n defaultMessage: 'Reset password page',\n },\n hint: {\n id: getTrad('EditForm.inputToggle.description.email-reset-password'),\n defaultMessage: \"URL of your application's reset password page.\",\n },\n placeholder: {\n id: getTrad('EditForm.inputToggle.placeholder.email-reset-password'),\n defaultMessage: 'ex: https://youtfrontend.com/reset-password',\n },\n name: 'email_reset_password',\n type: 'string',\n size: 12,\n },\n {\n label: {\n id: getTrad('EditForm.inputToggle.label.email-confirmation'),\n defaultMessage: 'Enable email confirmation',\n },\n hint: {\n id: getTrad('EditForm.inputToggle.description.email-confirmation'),\n defaultMessage: 'When enabled (ON), new registered users receive a confirmation email.',\n },\n name: 'email_confirmation',\n type: 'boolean',\n size: 12,\n },\n {\n label: {\n id: getTrad('EditForm.inputToggle.label.email-confirmation-redirection'),\n defaultMessage: 'Redirection url',\n },\n hint: {\n id: getTrad('EditForm.inputToggle.description.email-confirmation-redirection'),\n defaultMessage: 'After you confirmed your email, choose where you will be redirected.',\n },\n placeholder: {\n id: getTrad('EditForm.inputToggle.placeholder.email-confirmation-redirection'),\n defaultMessage: 'ex: https://youtfrontend.com/email-confirmation',\n },\n name: 'email_confirmation_redirection',\n type: 'string',\n size: 12,\n },\n];\n\nexport default layout;\n"],"names":["layout","label","id","getTrad","defaultMessage","hint","name","type","size","placeholder"],"mappings":";;;;;AAEA,MAAMA,MAAS,GAAA;AACb,IAAA;QACEC,KAAO,EAAA;AACLC,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,kCAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAC,IAAM,EAAA;AACJH,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,wCAAA,CAAA;YACZC,cACE,EAAA;AACJ,SAAA;QACAE,IAAM,EAAA,cAAA;QACNC,IAAM,EAAA,SAAA;QACNC,IAAM,EAAA;AACR,KAAA;AACA,IAAA;QACEP,KAAO,EAAA;AACLC,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,oCAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAC,IAAM,EAAA;AACJH,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,0CAAA,CAAA;YACZC,cACE,EAAA;AACJ,SAAA;QACAE,IAAM,EAAA,gBAAA;QACNC,IAAM,EAAA,SAAA;QACNC,IAAM,EAAA;AACR,KAAA;AACA,IAAA;QACEP,KAAO,EAAA;AACLC,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,iDAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAC,IAAM,EAAA;AACJH,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,uDAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAK,WAAa,EAAA;AACXP,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,uDAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAE,IAAM,EAAA,sBAAA;QACNC,IAAM,EAAA,QAAA;QACNC,IAAM,EAAA;AACR,KAAA;AACA,IAAA;QACEP,KAAO,EAAA;AACLC,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,+CAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAC,IAAM,EAAA;AACJH,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,qDAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAE,IAAM,EAAA,oBAAA;QACNC,IAAM,EAAA,SAAA;QACNC,IAAM,EAAA;AACR,KAAA;AACA,IAAA;QACEP,KAAO,EAAA;AACLC,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,2DAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAC,IAAM,EAAA;AACJH,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,iEAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAK,WAAa,EAAA;AACXP,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,iEAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAE,IAAM,EAAA,gCAAA;QACNC,IAAM,EAAA,QAAA;QACNC,IAAM,EAAA;AACR;AACD;;;;"}
@@ -0,0 +1,81 @@
import 'lodash/isEmpty';
import getTrad from '../../../utils/getTrad.mjs';
const layout = [
{
label: {
id: getTrad('EditForm.inputToggle.label.email'),
defaultMessage: 'One account per email address'
},
hint: {
id: getTrad('EditForm.inputToggle.description.email'),
defaultMessage: 'Disallow the user to create multiple accounts using the same email address with different authentication providers.'
},
name: 'unique_email',
type: 'boolean',
size: 12
},
{
label: {
id: getTrad('EditForm.inputToggle.label.sign-up'),
defaultMessage: 'Enable sign-ups'
},
hint: {
id: getTrad('EditForm.inputToggle.description.sign-up'),
defaultMessage: 'When disabled (OFF), the registration process is forbidden. No one can subscribe anymore no matter the used provider.'
},
name: 'allow_register',
type: 'boolean',
size: 12
},
{
label: {
id: getTrad('EditForm.inputToggle.label.email-reset-password'),
defaultMessage: 'Reset password page'
},
hint: {
id: getTrad('EditForm.inputToggle.description.email-reset-password'),
defaultMessage: "URL of your application's reset password page."
},
placeholder: {
id: getTrad('EditForm.inputToggle.placeholder.email-reset-password'),
defaultMessage: 'ex: https://youtfrontend.com/reset-password'
},
name: 'email_reset_password',
type: 'string',
size: 12
},
{
label: {
id: getTrad('EditForm.inputToggle.label.email-confirmation'),
defaultMessage: 'Enable email confirmation'
},
hint: {
id: getTrad('EditForm.inputToggle.description.email-confirmation'),
defaultMessage: 'When enabled (ON), new registered users receive a confirmation email.'
},
name: 'email_confirmation',
type: 'boolean',
size: 12
},
{
label: {
id: getTrad('EditForm.inputToggle.label.email-confirmation-redirection'),
defaultMessage: 'Redirection url'
},
hint: {
id: getTrad('EditForm.inputToggle.description.email-confirmation-redirection'),
defaultMessage: 'After you confirmed your email, choose where you will be redirected.'
},
placeholder: {
id: getTrad('EditForm.inputToggle.placeholder.email-confirmation-redirection'),
defaultMessage: 'ex: https://youtfrontend.com/email-confirmation'
},
name: 'email_confirmation_redirection',
type: 'string',
size: 12
}
];
export { layout as default };
//# sourceMappingURL=layout.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"layout.mjs","sources":["../../../../../admin/src/pages/AdvancedSettings/utils/layout.js"],"sourcesContent":["import { getTrad } from '../../../utils';\n\nconst layout = [\n {\n label: {\n id: getTrad('EditForm.inputToggle.label.email'),\n defaultMessage: 'One account per email address',\n },\n hint: {\n id: getTrad('EditForm.inputToggle.description.email'),\n defaultMessage:\n 'Disallow the user to create multiple accounts using the same email address with different authentication providers.',\n },\n name: 'unique_email',\n type: 'boolean',\n size: 12,\n },\n {\n label: {\n id: getTrad('EditForm.inputToggle.label.sign-up'),\n defaultMessage: 'Enable sign-ups',\n },\n hint: {\n id: getTrad('EditForm.inputToggle.description.sign-up'),\n defaultMessage:\n 'When disabled (OFF), the registration process is forbidden. No one can subscribe anymore no matter the used provider.',\n },\n name: 'allow_register',\n type: 'boolean',\n size: 12,\n },\n {\n label: {\n id: getTrad('EditForm.inputToggle.label.email-reset-password'),\n defaultMessage: 'Reset password page',\n },\n hint: {\n id: getTrad('EditForm.inputToggle.description.email-reset-password'),\n defaultMessage: \"URL of your application's reset password page.\",\n },\n placeholder: {\n id: getTrad('EditForm.inputToggle.placeholder.email-reset-password'),\n defaultMessage: 'ex: https://youtfrontend.com/reset-password',\n },\n name: 'email_reset_password',\n type: 'string',\n size: 12,\n },\n {\n label: {\n id: getTrad('EditForm.inputToggle.label.email-confirmation'),\n defaultMessage: 'Enable email confirmation',\n },\n hint: {\n id: getTrad('EditForm.inputToggle.description.email-confirmation'),\n defaultMessage: 'When enabled (ON), new registered users receive a confirmation email.',\n },\n name: 'email_confirmation',\n type: 'boolean',\n size: 12,\n },\n {\n label: {\n id: getTrad('EditForm.inputToggle.label.email-confirmation-redirection'),\n defaultMessage: 'Redirection url',\n },\n hint: {\n id: getTrad('EditForm.inputToggle.description.email-confirmation-redirection'),\n defaultMessage: 'After you confirmed your email, choose where you will be redirected.',\n },\n placeholder: {\n id: getTrad('EditForm.inputToggle.placeholder.email-confirmation-redirection'),\n defaultMessage: 'ex: https://youtfrontend.com/email-confirmation',\n },\n name: 'email_confirmation_redirection',\n type: 'string',\n size: 12,\n },\n];\n\nexport default layout;\n"],"names":["layout","label","id","getTrad","defaultMessage","hint","name","type","size","placeholder"],"mappings":";;;AAEA,MAAMA,MAAS,GAAA;AACb,IAAA;QACEC,KAAO,EAAA;AACLC,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,kCAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAC,IAAM,EAAA;AACJH,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,wCAAA,CAAA;YACZC,cACE,EAAA;AACJ,SAAA;QACAE,IAAM,EAAA,cAAA;QACNC,IAAM,EAAA,SAAA;QACNC,IAAM,EAAA;AACR,KAAA;AACA,IAAA;QACEP,KAAO,EAAA;AACLC,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,oCAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAC,IAAM,EAAA;AACJH,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,0CAAA,CAAA;YACZC,cACE,EAAA;AACJ,SAAA;QACAE,IAAM,EAAA,gBAAA;QACNC,IAAM,EAAA,SAAA;QACNC,IAAM,EAAA;AACR,KAAA;AACA,IAAA;QACEP,KAAO,EAAA;AACLC,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,iDAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAC,IAAM,EAAA;AACJH,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,uDAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAK,WAAa,EAAA;AACXP,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,uDAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAE,IAAM,EAAA,sBAAA;QACNC,IAAM,EAAA,QAAA;QACNC,IAAM,EAAA;AACR,KAAA;AACA,IAAA;QACEP,KAAO,EAAA;AACLC,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,+CAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAC,IAAM,EAAA;AACJH,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,qDAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAE,IAAM,EAAA,oBAAA;QACNC,IAAM,EAAA,SAAA;QACNC,IAAM,EAAA;AACR,KAAA;AACA,IAAA;QACEP,KAAO,EAAA;AACLC,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,2DAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAC,IAAM,EAAA;AACJH,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,iEAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAK,WAAa,EAAA;AACXP,YAAAA,EAAAA,EAAIC,OAAQ,CAAA,iEAAA,CAAA;YACZC,cAAgB,EAAA;AAClB,SAAA;QACAE,IAAM,EAAA,gCAAA;QACNC,IAAM,EAAA,QAAA;QACNC,IAAM,EAAA;AACR;AACD;;;;"}
@@ -0,0 +1,40 @@
'use strict';
var admin = require('@strapi/strapi/admin');
var yup = require('yup');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var yup__namespace = /*#__PURE__*/_interopNamespaceDefault(yup);
// eslint-disable-next-line prefer-regex-literals
const URL_REGEX = new RegExp('(^$)|((.+:\\/\\/.*)(d*)\\/?(.*))');
const schema = yup__namespace.object().shape({
email_confirmation_redirection: yup__namespace.mixed().when('email_confirmation', {
is: true,
then: yup__namespace.string().matches(URL_REGEX).required(),
otherwise: yup__namespace.string().nullable()
}),
email_reset_password: yup__namespace.string(admin.translatedErrors.string).matches(URL_REGEX, {
id: admin.translatedErrors.regex.id,
defaultMessage: 'This is not a valid URL'
}).nullable()
});
module.exports = schema;
//# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
{"version":3,"file":"schema.js","sources":["../../../../../admin/src/pages/AdvancedSettings/utils/schema.js"],"sourcesContent":["import { translatedErrors } from '@strapi/strapi/admin';\nimport * as yup from 'yup';\n\n// eslint-disable-next-line prefer-regex-literals\nconst URL_REGEX = new RegExp('(^$)|((.+:\\\\/\\\\/.*)(d*)\\\\/?(.*))');\n\nconst schema = yup.object().shape({\n email_confirmation_redirection: yup.mixed().when('email_confirmation', {\n is: true,\n then: yup.string().matches(URL_REGEX).required(),\n otherwise: yup.string().nullable(),\n }),\n email_reset_password: yup\n .string(translatedErrors.string)\n .matches(URL_REGEX, {\n id: translatedErrors.regex.id,\n defaultMessage: 'This is not a valid URL',\n })\n .nullable(),\n});\n\nexport default schema;\n"],"names":["URL_REGEX","RegExp","schema","yup","object","shape","email_confirmation_redirection","mixed","when","is","then","string","matches","required","otherwise","nullable","email_reset_password","translatedErrors","id","regex","defaultMessage"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAGA;AACA,MAAMA,SAAAA,GAAY,IAAIC,MAAO,CAAA,kCAAA,CAAA;AAE7B,MAAMC,MAASC,GAAAA,cAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAChCC,IAAAA,8BAAAA,EAAgCH,cAAII,CAAAA,KAAK,EAAGC,CAAAA,IAAI,CAAC,oBAAsB,EAAA;QACrEC,EAAI,EAAA,IAAA;AACJC,QAAAA,IAAAA,EAAMP,eAAIQ,MAAM,EAAA,CAAGC,OAAO,CAACZ,WAAWa,QAAQ,EAAA;QAC9CC,SAAWX,EAAAA,cAAAA,CAAIQ,MAAM,EAAA,CAAGI,QAAQ;AAClC,KAAA,CAAA;IACAC,oBAAsBb,EAAAA,cAAAA,CACnBQ,MAAM,CAACM,sBAAAA,CAAiBN,MAAM,CAC9BC,CAAAA,OAAO,CAACZ,SAAW,EAAA;QAClBkB,EAAID,EAAAA,sBAAAA,CAAiBE,KAAK,CAACD,EAAE;QAC7BE,cAAgB,EAAA;AAClB,KAAA,CAAA,CACCL,QAAQ;AACb,CAAA;;;;"}
@@ -0,0 +1,19 @@
import { translatedErrors } from '@strapi/strapi/admin';
import * as yup from 'yup';
// eslint-disable-next-line prefer-regex-literals
const URL_REGEX = new RegExp('(^$)|((.+:\\/\\/.*)(d*)\\/?(.*))');
const schema = yup.object().shape({
email_confirmation_redirection: yup.mixed().when('email_confirmation', {
is: true,
then: yup.string().matches(URL_REGEX).required(),
otherwise: yup.string().nullable()
}),
email_reset_password: yup.string(translatedErrors.string).matches(URL_REGEX, {
id: translatedErrors.regex.id,
defaultMessage: 'This is not a valid URL'
}).nullable()
});
export { schema as default };
//# sourceMappingURL=schema.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"schema.mjs","sources":["../../../../../admin/src/pages/AdvancedSettings/utils/schema.js"],"sourcesContent":["import { translatedErrors } from '@strapi/strapi/admin';\nimport * as yup from 'yup';\n\n// eslint-disable-next-line prefer-regex-literals\nconst URL_REGEX = new RegExp('(^$)|((.+:\\\\/\\\\/.*)(d*)\\\\/?(.*))');\n\nconst schema = yup.object().shape({\n email_confirmation_redirection: yup.mixed().when('email_confirmation', {\n is: true,\n then: yup.string().matches(URL_REGEX).required(),\n otherwise: yup.string().nullable(),\n }),\n email_reset_password: yup\n .string(translatedErrors.string)\n .matches(URL_REGEX, {\n id: translatedErrors.regex.id,\n defaultMessage: 'This is not a valid URL',\n })\n .nullable(),\n});\n\nexport default schema;\n"],"names":["URL_REGEX","RegExp","schema","yup","object","shape","email_confirmation_redirection","mixed","when","is","then","string","matches","required","otherwise","nullable","email_reset_password","translatedErrors","id","regex","defaultMessage"],"mappings":";;;AAGA;AACA,MAAMA,SAAAA,GAAY,IAAIC,MAAO,CAAA,kCAAA,CAAA;AAE7B,MAAMC,MAASC,GAAAA,GAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAChCC,IAAAA,8BAAAA,EAAgCH,GAAII,CAAAA,KAAK,EAAGC,CAAAA,IAAI,CAAC,oBAAsB,EAAA;QACrEC,EAAI,EAAA,IAAA;AACJC,QAAAA,IAAAA,EAAMP,IAAIQ,MAAM,EAAA,CAAGC,OAAO,CAACZ,WAAWa,QAAQ,EAAA;QAC9CC,SAAWX,EAAAA,GAAAA,CAAIQ,MAAM,EAAA,CAAGI,QAAQ;AAClC,KAAA,CAAA;IACAC,oBAAsBb,EAAAA,GAAAA,CACnBQ,MAAM,CAACM,gBAAAA,CAAiBN,MAAM,CAC9BC,CAAAA,OAAO,CAACZ,SAAW,EAAA;QAClBkB,EAAID,EAAAA,gBAAAA,CAAiBE,KAAK,CAACD,EAAE;QAC7BE,cAAgB,EAAA;AAClB,KAAA,CAAA,CACCL,QAAQ;AACb,CAAA;;;;"}
@@ -0,0 +1,171 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
require('react');
var designSystem = require('@strapi/design-system');
var admin = require('@strapi/strapi/admin');
var PropTypes = require('prop-types');
var reactIntl = require('react-intl');
require('lodash/isEmpty');
var getTrad = require('../../../utils/getTrad.js');
var schema = require('../utils/schema.js');
const EmailForm = ({ template = {}, onToggle, open, onSubmit })=>{
const { formatMessage } = reactIntl.useIntl();
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Root, {
open: open,
onOpenChange: onToggle,
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Content, {
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Header, {
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Breadcrumbs, {
label: `${formatMessage({
id: getTrad('PopUpForm.header.edit.email-templates'),
defaultMessage: 'Edit email template'
})}, ${template.display ? formatMessage({
id: getTrad(template.display),
defaultMessage: template.display
}) : ''}`,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Crumb, {
children: formatMessage({
id: getTrad('PopUpForm.header.edit.email-templates'),
defaultMessage: 'Edit email template'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Crumb, {
isCurrent: true,
children: template.display ? formatMessage({
id: getTrad(template.display),
defaultMessage: template.display
}) : ''
})
]
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.VisuallyHidden, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Title, {
children: `${formatMessage({
id: getTrad('PopUpForm.header.edit.email-templates'),
defaultMessage: 'Edit email template'
})}, ${template.display ? formatMessage({
id: getTrad(template.display),
defaultMessage: template.display
}) : ''}`
})
})
]
}),
/*#__PURE__*/ jsxRuntime.jsx(admin.Form, {
onSubmit: onSubmit,
initialValues: template,
validationSchema: schema,
children: ({ isSubmitting })=>{
return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Body, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Root, {
gap: 5,
children: [
{
label: formatMessage({
id: getTrad('PopUpForm.Email.options.from.name.label'),
defaultMessage: 'Shipper name'
}),
name: 'options.from.name',
size: 6,
type: 'string'
},
{
label: formatMessage({
id: getTrad('PopUpForm.Email.options.from.email.label'),
defaultMessage: 'Shipper email'
}),
name: 'options.from.email',
size: 6,
type: 'string'
},
{
label: formatMessage({
id: getTrad('PopUpForm.Email.options.response_email.label'),
defaultMessage: 'Response email'
}),
name: 'options.response_email',
size: 6,
type: 'string'
},
{
label: formatMessage({
id: getTrad('PopUpForm.Email.options.object.label'),
defaultMessage: 'Subject'
}),
name: 'options.object',
size: 6,
type: 'string'
},
{
label: formatMessage({
id: getTrad('PopUpForm.Email.options.message.label'),
defaultMessage: 'Message'
}),
name: 'options.message',
size: 12,
type: 'text'
}
].map(({ size, ...field })=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Item, {
col: size,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxRuntime.jsx(admin.InputRenderer, {
...field
})
}, field.name))
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Footer, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Close, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
variant: "tertiary",
children: "Cancel"
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
loading: isSubmitting,
type: "submit",
children: "Finish"
})
]
})
]
});
}
})
]
})
});
};
EmailForm.defaultProps = {
template: {}
};
EmailForm.propTypes = {
template: PropTypes.shape({
display: PropTypes.string,
icon: PropTypes.string,
options: PropTypes.shape({
from: PropTypes.shape({
name: PropTypes.string,
email: PropTypes.string
}),
message: PropTypes.string,
object: PropTypes.string,
response_email: PropTypes.string
})
}),
open: PropTypes.bool.isRequired,
onSubmit: PropTypes.func.isRequired,
onToggle: PropTypes.func.isRequired
};
module.exports = EmailForm;
//# sourceMappingURL=EmailForm.js.map
@@ -0,0 +1 @@
{"version":3,"file":"EmailForm.js","sources":["../../../../../admin/src/pages/EmailTemplates/components/EmailForm.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Button, Grid, Modal, Breadcrumbs, Crumb, VisuallyHidden } from '@strapi/design-system';\nimport { Form, InputRenderer } from '@strapi/strapi/admin';\nimport PropTypes from 'prop-types';\nimport { useIntl } from 'react-intl';\n\nimport { getTrad } from '../../../utils';\nimport schema from '../utils/schema';\n\nconst EmailForm = ({ template = {}, onToggle, open, onSubmit }) => {\n const { formatMessage } = useIntl();\n\n return (\n <Modal.Root open={open} onOpenChange={onToggle}>\n <Modal.Content>\n <Modal.Header>\n <Breadcrumbs\n label={`${formatMessage({\n id: getTrad('PopUpForm.header.edit.email-templates'),\n defaultMessage: 'Edit email template',\n })}, ${\n template.display\n ? formatMessage({\n id: getTrad(template.display),\n defaultMessage: template.display,\n })\n : ''\n }`}\n >\n <Crumb>\n {formatMessage({\n id: getTrad('PopUpForm.header.edit.email-templates'),\n defaultMessage: 'Edit email template',\n })}\n </Crumb>\n <Crumb isCurrent>\n {template.display\n ? formatMessage({ id: getTrad(template.display), defaultMessage: template.display })\n : ''}\n </Crumb>\n </Breadcrumbs>\n <VisuallyHidden>\n <Modal.Title>\n {`${formatMessage({\n id: getTrad('PopUpForm.header.edit.email-templates'),\n defaultMessage: 'Edit email template',\n })}, ${template.display ? formatMessage({ id: getTrad(template.display), defaultMessage: template.display }) : ''}`}\n </Modal.Title>\n </VisuallyHidden>\n </Modal.Header>\n <Form onSubmit={onSubmit} initialValues={template} validationSchema={schema}>\n {({ isSubmitting }) => {\n return (\n <>\n <Modal.Body>\n <Grid.Root gap={5}>\n {[\n {\n label: formatMessage({\n id: getTrad('PopUpForm.Email.options.from.name.label'),\n defaultMessage: 'Shipper name',\n }),\n name: 'options.from.name',\n size: 6,\n type: 'string',\n },\n {\n label: formatMessage({\n id: getTrad('PopUpForm.Email.options.from.email.label'),\n defaultMessage: 'Shipper email',\n }),\n name: 'options.from.email',\n size: 6,\n type: 'string',\n },\n {\n label: formatMessage({\n id: getTrad('PopUpForm.Email.options.response_email.label'),\n defaultMessage: 'Response email',\n }),\n name: 'options.response_email',\n size: 6,\n type: 'string',\n },\n {\n label: formatMessage({\n id: getTrad('PopUpForm.Email.options.object.label'),\n defaultMessage: 'Subject',\n }),\n name: 'options.object',\n size: 6,\n type: 'string',\n },\n {\n label: formatMessage({\n id: getTrad('PopUpForm.Email.options.message.label'),\n defaultMessage: 'Message',\n }),\n name: 'options.message',\n size: 12,\n type: 'text',\n },\n ].map(({ size, ...field }) => (\n <Grid.Item\n key={field.name}\n col={size}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <InputRenderer {...field} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </Modal.Body>\n <Modal.Footer>\n <Modal.Close>\n <Button variant=\"tertiary\">Cancel</Button>\n </Modal.Close>\n <Button loading={isSubmitting} type=\"submit\">\n Line truncated
@@ -0,0 +1,169 @@
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import 'react';
import { Modal, Breadcrumbs, Crumb, VisuallyHidden, Grid, Button } from '@strapi/design-system';
import { Form, InputRenderer } from '@strapi/strapi/admin';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import 'lodash/isEmpty';
import getTrad from '../../../utils/getTrad.mjs';
import schema from '../utils/schema.mjs';
const EmailForm = ({ template = {}, onToggle, open, onSubmit })=>{
const { formatMessage } = useIntl();
return /*#__PURE__*/ jsx(Modal.Root, {
open: open,
onOpenChange: onToggle,
children: /*#__PURE__*/ jsxs(Modal.Content, {
children: [
/*#__PURE__*/ jsxs(Modal.Header, {
children: [
/*#__PURE__*/ jsxs(Breadcrumbs, {
label: `${formatMessage({
id: getTrad('PopUpForm.header.edit.email-templates'),
defaultMessage: 'Edit email template'
})}, ${template.display ? formatMessage({
id: getTrad(template.display),
defaultMessage: template.display
}) : ''}`,
children: [
/*#__PURE__*/ jsx(Crumb, {
children: formatMessage({
id: getTrad('PopUpForm.header.edit.email-templates'),
defaultMessage: 'Edit email template'
})
}),
/*#__PURE__*/ jsx(Crumb, {
isCurrent: true,
children: template.display ? formatMessage({
id: getTrad(template.display),
defaultMessage: template.display
}) : ''
})
]
}),
/*#__PURE__*/ jsx(VisuallyHidden, {
children: /*#__PURE__*/ jsx(Modal.Title, {
children: `${formatMessage({
id: getTrad('PopUpForm.header.edit.email-templates'),
defaultMessage: 'Edit email template'
})}, ${template.display ? formatMessage({
id: getTrad(template.display),
defaultMessage: template.display
}) : ''}`
})
})
]
}),
/*#__PURE__*/ jsx(Form, {
onSubmit: onSubmit,
initialValues: template,
validationSchema: schema,
children: ({ isSubmitting })=>{
return /*#__PURE__*/ jsxs(Fragment, {
children: [
/*#__PURE__*/ jsx(Modal.Body, {
children: /*#__PURE__*/ jsx(Grid.Root, {
gap: 5,
children: [
{
label: formatMessage({
id: getTrad('PopUpForm.Email.options.from.name.label'),
defaultMessage: 'Shipper name'
}),
name: 'options.from.name',
size: 6,
type: 'string'
},
{
label: formatMessage({
id: getTrad('PopUpForm.Email.options.from.email.label'),
defaultMessage: 'Shipper email'
}),
name: 'options.from.email',
size: 6,
type: 'string'
},
{
label: formatMessage({
id: getTrad('PopUpForm.Email.options.response_email.label'),
defaultMessage: 'Response email'
}),
name: 'options.response_email',
size: 6,
type: 'string'
},
{
label: formatMessage({
id: getTrad('PopUpForm.Email.options.object.label'),
defaultMessage: 'Subject'
}),
name: 'options.object',
size: 6,
type: 'string'
},
{
label: formatMessage({
id: getTrad('PopUpForm.Email.options.message.label'),
defaultMessage: 'Message'
}),
name: 'options.message',
size: 12,
type: 'text'
}
].map(({ size, ...field })=>/*#__PURE__*/ jsx(Grid.Item, {
col: size,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsx(InputRenderer, {
...field
})
}, field.name))
})
}),
/*#__PURE__*/ jsxs(Modal.Footer, {
children: [
/*#__PURE__*/ jsx(Modal.Close, {
children: /*#__PURE__*/ jsx(Button, {
variant: "tertiary",
children: "Cancel"
})
}),
/*#__PURE__*/ jsx(Button, {
loading: isSubmitting,
type: "submit",
children: "Finish"
})
]
})
]
});
}
})
]
})
});
};
EmailForm.defaultProps = {
template: {}
};
EmailForm.propTypes = {
template: PropTypes.shape({
display: PropTypes.string,
icon: PropTypes.string,
options: PropTypes.shape({
from: PropTypes.shape({
name: PropTypes.string,
email: PropTypes.string
}),
message: PropTypes.string,
object: PropTypes.string,
response_email: PropTypes.string
})
}),
open: PropTypes.bool.isRequired,
onSubmit: PropTypes.func.isRequired,
onToggle: PropTypes.func.isRequired
};
export { EmailForm as default };
//# sourceMappingURL=EmailForm.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"EmailForm.mjs","sources":["../../../../../admin/src/pages/EmailTemplates/components/EmailForm.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Button, Grid, Modal, Breadcrumbs, Crumb, VisuallyHidden } from '@strapi/design-system';\nimport { Form, InputRenderer } from '@strapi/strapi/admin';\nimport PropTypes from 'prop-types';\nimport { useIntl } from 'react-intl';\n\nimport { getTrad } from '../../../utils';\nimport schema from '../utils/schema';\n\nconst EmailForm = ({ template = {}, onToggle, open, onSubmit }) => {\n const { formatMessage } = useIntl();\n\n return (\n <Modal.Root open={open} onOpenChange={onToggle}>\n <Modal.Content>\n <Modal.Header>\n <Breadcrumbs\n label={`${formatMessage({\n id: getTrad('PopUpForm.header.edit.email-templates'),\n defaultMessage: 'Edit email template',\n })}, ${\n template.display\n ? formatMessage({\n id: getTrad(template.display),\n defaultMessage: template.display,\n })\n : ''\n }`}\n >\n <Crumb>\n {formatMessage({\n id: getTrad('PopUpForm.header.edit.email-templates'),\n defaultMessage: 'Edit email template',\n })}\n </Crumb>\n <Crumb isCurrent>\n {template.display\n ? formatMessage({ id: getTrad(template.display), defaultMessage: template.display })\n : ''}\n </Crumb>\n </Breadcrumbs>\n <VisuallyHidden>\n <Modal.Title>\n {`${formatMessage({\n id: getTrad('PopUpForm.header.edit.email-templates'),\n defaultMessage: 'Edit email template',\n })}, ${template.display ? formatMessage({ id: getTrad(template.display), defaultMessage: template.display }) : ''}`}\n </Modal.Title>\n </VisuallyHidden>\n </Modal.Header>\n <Form onSubmit={onSubmit} initialValues={template} validationSchema={schema}>\n {({ isSubmitting }) => {\n return (\n <>\n <Modal.Body>\n <Grid.Root gap={5}>\n {[\n {\n label: formatMessage({\n id: getTrad('PopUpForm.Email.options.from.name.label'),\n defaultMessage: 'Shipper name',\n }),\n name: 'options.from.name',\n size: 6,\n type: 'string',\n },\n {\n label: formatMessage({\n id: getTrad('PopUpForm.Email.options.from.email.label'),\n defaultMessage: 'Shipper email',\n }),\n name: 'options.from.email',\n size: 6,\n type: 'string',\n },\n {\n label: formatMessage({\n id: getTrad('PopUpForm.Email.options.response_email.label'),\n defaultMessage: 'Response email',\n }),\n name: 'options.response_email',\n size: 6,\n type: 'string',\n },\n {\n label: formatMessage({\n id: getTrad('PopUpForm.Email.options.object.label'),\n defaultMessage: 'Subject',\n }),\n name: 'options.object',\n size: 6,\n type: 'string',\n },\n {\n label: formatMessage({\n id: getTrad('PopUpForm.Email.options.message.label'),\n defaultMessage: 'Message',\n }),\n name: 'options.message',\n size: 12,\n type: 'text',\n },\n ].map(({ size, ...field }) => (\n <Grid.Item\n key={field.name}\n col={size}\n direction=\"column\"\n alignItems=\"stretch\"\n >\n <InputRenderer {...field} />\n </Grid.Item>\n ))}\n </Grid.Root>\n </Modal.Body>\n <Modal.Footer>\n <Modal.Close>\n <Button variant=\"tertiary\">Cancel</Button>\n </Modal.Close>\n <Button loading={isSubmitting} type=\"submit\">\n Line truncated
@@ -0,0 +1,145 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var PropTypes = require('prop-types');
var reactIntl = require('react-intl');
require('lodash/isEmpty');
var getTrad = require('../../../utils/getTrad.js');
const EmailTable = ({ canUpdate, onEditClick })=>{
const { formatMessage } = reactIntl.useIntl();
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Table, {
colCount: 3,
rowCount: 3,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Thead, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tr, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
width: "1%",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.VisuallyHidden, {
children: formatMessage({
id: getTrad('Email.template.table.icon.label'),
defaultMessage: 'icon'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: getTrad('Email.template.table.name.label'),
defaultMessage: 'name'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
width: "1%",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.VisuallyHidden, {
children: formatMessage({
id: getTrad('Email.template.table.action.label'),
defaultMessage: 'action'
})
})
})
]
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tbody, {
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tr, {
cursor: "pointer",
onClick: ()=>onEditClick('reset_password'),
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
width: "3.2rem",
height: "3.2rem",
padding: "0.8rem",
children: /*#__PURE__*/ jsxRuntime.jsx(icons.ArrowClockwise, {
"aria-label": formatMessage({
id: 'global.reset-password',
defaultMessage: 'Reset password'
})
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
children: formatMessage({
id: 'global.reset-password',
defaultMessage: 'Reset password'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
onClick: (e)=>e.stopPropagation(),
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
onClick: ()=>onEditClick('reset_password'),
label: formatMessage({
id: getTrad('Email.template.form.edit.label'),
defaultMessage: 'Edit a template'
}),
variant: "ghost",
disabled: !canUpdate,
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Pencil, {})
})
})
]
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tr, {
cursor: "pointer",
onClick: ()=>onEditClick('email_confirmation'),
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
width: "3.2rem",
height: "3.2rem",
padding: "0.8rem",
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Check, {
"aria-label": formatMessage({
id: getTrad('Email.template.email_confirmation'),
defaultMessage: 'Email address confirmation'
})
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
children: formatMessage({
id: getTrad('Email.template.email_confirmation'),
defaultMessage: 'Email address confirmation'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
onClick: (e)=>e.stopPropagation(),
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
onClick: ()=>onEditClick('email_confirmation'),
label: formatMessage({
id: getTrad('Email.template.form.edit.label'),
defaultMessage: 'Edit a template'
}),
variant: "ghost",
disabled: !canUpdate,
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Pencil, {})
})
})
]
})
]
})
]
});
};
EmailTable.propTypes = {
canUpdate: PropTypes.bool.isRequired,
onEditClick: PropTypes.func.isRequired
};
module.exports = EmailTable;
//# sourceMappingURL=EmailTable.js.map
@@ -0,0 +1 @@
{"version":3,"file":"EmailTable.js","sources":["../../../../../admin/src/pages/EmailTemplates/components/EmailTable.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n IconButton,\n Table,\n Tbody,\n Td,\n Th,\n Thead,\n Tr,\n Typography,\n VisuallyHidden,\n Box,\n} from '@strapi/design-system';\nimport { Check, Pencil, ArrowClockwise as Refresh } from '@strapi/icons';\nimport PropTypes from 'prop-types';\nimport { useIntl } from 'react-intl';\n\nimport { getTrad } from '../../../utils';\n\nconst EmailTable = ({ canUpdate, onEditClick }) => {\n const { formatMessage } = useIntl();\n\n return (\n <Table colCount={3} rowCount={3}>\n <Thead>\n <Tr>\n <Th width=\"1%\">\n <VisuallyHidden>\n {formatMessage({\n id: getTrad('Email.template.table.icon.label'),\n defaultMessage: 'icon',\n })}\n </VisuallyHidden>\n </Th>\n <Th>\n <Typography variant=\"sigma\" textColor=\"neutral600\">\n {formatMessage({\n id: getTrad('Email.template.table.name.label'),\n defaultMessage: 'name',\n })}\n </Typography>\n </Th>\n <Th width=\"1%\">\n <VisuallyHidden>\n {formatMessage({\n id: getTrad('Email.template.table.action.label'),\n defaultMessage: 'action',\n })}\n </VisuallyHidden>\n </Th>\n </Tr>\n </Thead>\n <Tbody>\n <Tr cursor=\"pointer\" onClick={() => onEditClick('reset_password')}>\n <Td>\n <Box width=\"3.2rem\" height=\"3.2rem\" padding=\"0.8rem\">\n <Refresh\n aria-label={formatMessage({\n id: 'global.reset-password',\n defaultMessage: 'Reset password',\n })}\n />\n </Box>\n </Td>\n <Td>\n <Typography>\n {formatMessage({\n id: 'global.reset-password',\n defaultMessage: 'Reset password',\n })}\n </Typography>\n </Td>\n <Td onClick={(e) => e.stopPropagation()}>\n <IconButton\n onClick={() => onEditClick('reset_password')}\n label={formatMessage({\n id: getTrad('Email.template.form.edit.label'),\n defaultMessage: 'Edit a template',\n })}\n variant=\"ghost\"\n disabled={!canUpdate}\n >\n <Pencil />\n </IconButton>\n </Td>\n </Tr>\n <Tr cursor=\"pointer\" onClick={() => onEditClick('email_confirmation')}>\n <Td>\n <Box width=\"3.2rem\" height=\"3.2rem\" padding=\"0.8rem\">\n <Check\n aria-label={formatMessage({\n id: getTrad('Email.template.email_confirmation'),\n defaultMessage: 'Email address confirmation',\n })}\n />\n </Box>\n </Td>\n <Td>\n <Typography>\n {formatMessage({\n id: getTrad('Email.template.email_confirmation'),\n defaultMessage: 'Email address confirmation',\n })}\n </Typography>\n </Td>\n <Td onClick={(e) => e.stopPropagation()}>\n <IconButton\n onClick={() => onEditClick('email_confirmation')}\n label={formatMessage({\n id: getTrad('Email.template.form.edit.label'),\n defaultMessage: 'Edit a template',\n })}\n variant=\"ghost\"\n disabled={!canUpdate}\n >\n <Pencil />\n </IconButton>\n </Td>\n </Tr>\n </Tbody>\n </Table>\n );\n};\n\nEmailTable.propTypes = {\n canUpdate: PropTypes.bool.isRequired,\n onEditClick: PropTypes.func.isRequired,\n};\n\nexport default EmailTable;\n"],"names":["EmailTable","canUpdate","onEditClick","formatMessage","useIntl","_jsxs","Table","colCount","rowCount","_jsx","Thead","Tr","Th","width","VisuallyHidden","id","getTrad","defaultMessage","Typography","variant","textColor","Tbody","cursor","onClick","Td","Box","height","padding","Refresh","aria-label","e","stopPropagation","IconButton","label","disabled","Pencil","Check","propTypes","PropTypes","bool","isRequired","func"],"mappings":";;;;;;;;;;;AAoBA,MAAMA,aAAa,CAAC,EAAEC,SAAS,EAAEC,WAAW,EAAE,GAAA;IAC5C,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAE1B,IAAA,qBACEC,eAACC,CAAAA,kBAAAA,EAAAA;QAAMC,QAAU,EAAA,CAAA;QAAGC,QAAU,EAAA,CAAA;;0BAC5BC,cAACC,CAAAA,kBAAAA,EAAAA;AACC,gBAAA,QAAA,gBAAAL,eAACM,CAAAA,eAAAA,EAAAA;;sCACCF,cAACG,CAAAA,eAAAA,EAAAA;4BAAGC,KAAM,EAAA,IAAA;AACR,4BAAA,QAAA,gBAAAJ,cAACK,CAAAA,2BAAAA,EAAAA;0CACEX,aAAc,CAAA;AACbY,oCAAAA,EAAAA,EAAIC,OAAQ,CAAA,iCAAA,CAAA;oCACZC,cAAgB,EAAA;AAClB,iCALine truncated
@@ -0,0 +1,143 @@
import { jsxs, jsx } from 'react/jsx-runtime';
import 'react';
import { Table, Thead, Tr, Th, VisuallyHidden, Typography, Tbody, Td, Box, IconButton } from '@strapi/design-system';
import { ArrowClockwise, Pencil, Check } from '@strapi/icons';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import 'lodash/isEmpty';
import getTrad from '../../../utils/getTrad.mjs';
const EmailTable = ({ canUpdate, onEditClick })=>{
const { formatMessage } = useIntl();
return /*#__PURE__*/ jsxs(Table, {
colCount: 3,
rowCount: 3,
children: [
/*#__PURE__*/ jsx(Thead, {
children: /*#__PURE__*/ jsxs(Tr, {
children: [
/*#__PURE__*/ jsx(Th, {
width: "1%",
children: /*#__PURE__*/ jsx(VisuallyHidden, {
children: formatMessage({
id: getTrad('Email.template.table.icon.label'),
defaultMessage: 'icon'
})
})
}),
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: getTrad('Email.template.table.name.label'),
defaultMessage: 'name'
})
})
}),
/*#__PURE__*/ jsx(Th, {
width: "1%",
children: /*#__PURE__*/ jsx(VisuallyHidden, {
children: formatMessage({
id: getTrad('Email.template.table.action.label'),
defaultMessage: 'action'
})
})
})
]
})
}),
/*#__PURE__*/ jsxs(Tbody, {
children: [
/*#__PURE__*/ jsxs(Tr, {
cursor: "pointer",
onClick: ()=>onEditClick('reset_password'),
children: [
/*#__PURE__*/ jsx(Td, {
children: /*#__PURE__*/ jsx(Box, {
width: "3.2rem",
height: "3.2rem",
padding: "0.8rem",
children: /*#__PURE__*/ jsx(ArrowClockwise, {
"aria-label": formatMessage({
id: 'global.reset-password',
defaultMessage: 'Reset password'
})
})
})
}),
/*#__PURE__*/ jsx(Td, {
children: /*#__PURE__*/ jsx(Typography, {
children: formatMessage({
id: 'global.reset-password',
defaultMessage: 'Reset password'
})
})
}),
/*#__PURE__*/ jsx(Td, {
onClick: (e)=>e.stopPropagation(),
children: /*#__PURE__*/ jsx(IconButton, {
onClick: ()=>onEditClick('reset_password'),
label: formatMessage({
id: getTrad('Email.template.form.edit.label'),
defaultMessage: 'Edit a template'
}),
variant: "ghost",
disabled: !canUpdate,
children: /*#__PURE__*/ jsx(Pencil, {})
})
})
]
}),
/*#__PURE__*/ jsxs(Tr, {
cursor: "pointer",
onClick: ()=>onEditClick('email_confirmation'),
children: [
/*#__PURE__*/ jsx(Td, {
children: /*#__PURE__*/ jsx(Box, {
width: "3.2rem",
height: "3.2rem",
padding: "0.8rem",
children: /*#__PURE__*/ jsx(Check, {
"aria-label": formatMessage({
id: getTrad('Email.template.email_confirmation'),
defaultMessage: 'Email address confirmation'
})
})
})
}),
/*#__PURE__*/ jsx(Td, {
children: /*#__PURE__*/ jsx(Typography, {
children: formatMessage({
id: getTrad('Email.template.email_confirmation'),
defaultMessage: 'Email address confirmation'
})
})
}),
/*#__PURE__*/ jsx(Td, {
onClick: (e)=>e.stopPropagation(),
children: /*#__PURE__*/ jsx(IconButton, {
onClick: ()=>onEditClick('email_confirmation'),
label: formatMessage({
id: getTrad('Email.template.form.edit.label'),
defaultMessage: 'Edit a template'
}),
variant: "ghost",
disabled: !canUpdate,
children: /*#__PURE__*/ jsx(Pencil, {})
})
})
]
})
]
})
]
});
};
EmailTable.propTypes = {
canUpdate: PropTypes.bool.isRequired,
onEditClick: PropTypes.func.isRequired
};
export { EmailTable as default };
//# sourceMappingURL=EmailTable.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"EmailTable.mjs","sources":["../../../../../admin/src/pages/EmailTemplates/components/EmailTable.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n IconButton,\n Table,\n Tbody,\n Td,\n Th,\n Thead,\n Tr,\n Typography,\n VisuallyHidden,\n Box,\n} from '@strapi/design-system';\nimport { Check, Pencil, ArrowClockwise as Refresh } from '@strapi/icons';\nimport PropTypes from 'prop-types';\nimport { useIntl } from 'react-intl';\n\nimport { getTrad } from '../../../utils';\n\nconst EmailTable = ({ canUpdate, onEditClick }) => {\n const { formatMessage } = useIntl();\n\n return (\n <Table colCount={3} rowCount={3}>\n <Thead>\n <Tr>\n <Th width=\"1%\">\n <VisuallyHidden>\n {formatMessage({\n id: getTrad('Email.template.table.icon.label'),\n defaultMessage: 'icon',\n })}\n </VisuallyHidden>\n </Th>\n <Th>\n <Typography variant=\"sigma\" textColor=\"neutral600\">\n {formatMessage({\n id: getTrad('Email.template.table.name.label'),\n defaultMessage: 'name',\n })}\n </Typography>\n </Th>\n <Th width=\"1%\">\n <VisuallyHidden>\n {formatMessage({\n id: getTrad('Email.template.table.action.label'),\n defaultMessage: 'action',\n })}\n </VisuallyHidden>\n </Th>\n </Tr>\n </Thead>\n <Tbody>\n <Tr cursor=\"pointer\" onClick={() => onEditClick('reset_password')}>\n <Td>\n <Box width=\"3.2rem\" height=\"3.2rem\" padding=\"0.8rem\">\n <Refresh\n aria-label={formatMessage({\n id: 'global.reset-password',\n defaultMessage: 'Reset password',\n })}\n />\n </Box>\n </Td>\n <Td>\n <Typography>\n {formatMessage({\n id: 'global.reset-password',\n defaultMessage: 'Reset password',\n })}\n </Typography>\n </Td>\n <Td onClick={(e) => e.stopPropagation()}>\n <IconButton\n onClick={() => onEditClick('reset_password')}\n label={formatMessage({\n id: getTrad('Email.template.form.edit.label'),\n defaultMessage: 'Edit a template',\n })}\n variant=\"ghost\"\n disabled={!canUpdate}\n >\n <Pencil />\n </IconButton>\n </Td>\n </Tr>\n <Tr cursor=\"pointer\" onClick={() => onEditClick('email_confirmation')}>\n <Td>\n <Box width=\"3.2rem\" height=\"3.2rem\" padding=\"0.8rem\">\n <Check\n aria-label={formatMessage({\n id: getTrad('Email.template.email_confirmation'),\n defaultMessage: 'Email address confirmation',\n })}\n />\n </Box>\n </Td>\n <Td>\n <Typography>\n {formatMessage({\n id: getTrad('Email.template.email_confirmation'),\n defaultMessage: 'Email address confirmation',\n })}\n </Typography>\n </Td>\n <Td onClick={(e) => e.stopPropagation()}>\n <IconButton\n onClick={() => onEditClick('email_confirmation')}\n label={formatMessage({\n id: getTrad('Email.template.form.edit.label'),\n defaultMessage: 'Edit a template',\n })}\n variant=\"ghost\"\n disabled={!canUpdate}\n >\n <Pencil />\n </IconButton>\n </Td>\n </Tr>\n </Tbody>\n </Table>\n );\n};\n\nEmailTable.propTypes = {\n canUpdate: PropTypes.bool.isRequired,\n onEditClick: PropTypes.func.isRequired,\n};\n\nexport default EmailTable;\n"],"names":["EmailTable","canUpdate","onEditClick","formatMessage","useIntl","_jsxs","Table","colCount","rowCount","_jsx","Thead","Tr","Th","width","VisuallyHidden","id","getTrad","defaultMessage","Typography","variant","textColor","Tbody","cursor","onClick","Td","Box","height","padding","Refresh","aria-label","e","stopPropagation","IconButton","label","disabled","Pencil","Check","propTypes","PropTypes","bool","isRequired","func"],"mappings":";;;;;;;;;AAoBA,MAAMA,aAAa,CAAC,EAAEC,SAAS,EAAEC,WAAW,EAAE,GAAA;IAC5C,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAE1B,IAAA,qBACEC,IAACC,CAAAA,KAAAA,EAAAA;QAAMC,QAAU,EAAA,CAAA;QAAGC,QAAU,EAAA,CAAA;;0BAC5BC,GAACC,CAAAA,KAAAA,EAAAA;AACC,gBAAA,QAAA,gBAAAL,IAACM,CAAAA,EAAAA,EAAAA;;sCACCF,GAACG,CAAAA,EAAAA,EAAAA;4BAAGC,KAAM,EAAA,IAAA;AACR,4BAAA,QAAA,gBAAAJ,GAACK,CAAAA,cAAAA,EAAAA;0CACEX,aAAc,CAAA;AACbY,oCAAAA,EAAAA,EAAIC,OAAQ,CAAA,iCAAA,CAAA;oCACZC,cAAgB,EAAA;AAClB,iCAAA;;;Line truncated
@@ -0,0 +1,157 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var strapiAdmin = require('@strapi/admin/strapi-admin');
var designSystem = require('@strapi/design-system');
var admin = require('@strapi/strapi/admin');
var reactIntl = require('react-intl');
var reactQuery = require('react-query');
var constants = require('../../constants.js');
require('lodash/isEmpty');
var getTrad = require('../../utils/getTrad.js');
var EmailForm = require('./components/EmailForm.js');
var EmailTable = require('./components/EmailTable.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const ProtectedEmailTemplatesPage = ()=>/*#__PURE__*/ jsxRuntime.jsx(admin.Page.Protect, {
permissions: constants.PERMISSIONS.readEmailTemplates,
children: /*#__PURE__*/ jsxRuntime.jsx(EmailTemplatesPage, {})
});
const EmailTemplatesPage = ()=>{
const { formatMessage } = reactIntl.useIntl();
const { trackUsage } = strapiAdmin.useTracking();
const { notifyStatus } = designSystem.useNotifyAT();
const { toggleNotification } = admin.useNotification();
const queryClient = reactQuery.useQueryClient();
const { get, put } = admin.useFetchClient();
const { formatAPIError } = admin.useAPIErrorHandler();
const [isModalOpen, setIsModalOpen] = React__namespace.useState(false);
const [templateToEdit, setTemplateToEdit] = React__namespace.useState(null);
const { isLoading: isLoadingForPermissions, allowedActions: { canUpdate } } = admin.useRBAC({
update: constants.PERMISSIONS.updateEmailTemplates
});
const { isLoading: isLoadingData, data } = reactQuery.useQuery([
'users-permissions',
'email-templates'
], async ()=>{
const { data } = await get('/users-permissions/email-templates');
return data;
}, {
onSuccess () {
notifyStatus(formatMessage({
id: getTrad('Email.template.data.loaded'),
defaultMessage: 'Email templates has been loaded'
}));
},
onError (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
}
});
const isLoading = isLoadingForPermissions || isLoadingData;
const handleToggle = ()=>{
setIsModalOpen((prev)=>!prev);
};
const handleEditClick = (template)=>{
setTemplateToEdit(template);
handleToggle();
};
const submitMutation = reactQuery.useMutation((body)=>put('/users-permissions/email-templates', {
'email-templates': body
}), {
async onSuccess () {
await queryClient.invalidateQueries([
'users-permissions',
'email-templates'
]);
toggleNotification({
type: 'success',
message: formatMessage({
id: 'notification.success.saved',
defaultMessage: 'Saved'
})
});
trackUsage('didEditEmailTemplates');
handleToggle();
},
onError (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
},
refetchActive: true
});
const handleSubmit = (body)=>{
trackUsage('willEditEmailTemplates');
const editedTemplates = {
...data,
[templateToEdit]: body
};
submitMutation.mutate(editedTemplates);
};
if (isLoading) {
return /*#__PURE__*/ jsxRuntime.jsx(admin.Page.Loading, {});
}
return /*#__PURE__*/ jsxRuntime.jsxs(admin.Page.Main, {
"aria-busy": submitMutation.isLoading,
children: [
/*#__PURE__*/ jsxRuntime.jsx(admin.Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: formatMessage({
id: getTrad('HeaderNav.link.emailTemplates'),
defaultMessage: 'Email templates'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(admin.Layouts.Header, {
title: formatMessage({
id: getTrad('HeaderNav.link.emailTemplates'),
defaultMessage: 'Email templates'
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(admin.Layouts.Content, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(EmailTable, {
onEditClick: handleEditClick,
canUpdate: canUpdate
}),
/*#__PURE__*/ jsxRuntime.jsx(EmailForm, {
template: data[templateToEdit],
onToggle: handleToggle,
open: isModalOpen,
onSubmit: handleSubmit
})
]
})
]
});
};
exports.EmailTemplatesPage = EmailTemplatesPage;
exports.ProtectedEmailTemplatesPage = ProtectedEmailTemplatesPage;
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":["../../../../admin/src/pages/EmailTemplates/index.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useTracking } from '@strapi/admin/strapi-admin';\nimport { useNotifyAT } from '@strapi/design-system';\nimport {\n Page,\n useAPIErrorHandler,\n useNotification,\n useFetchClient,\n useRBAC,\n Layouts,\n} from '@strapi/strapi/admin';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery, useQueryClient } from 'react-query';\n\nimport { PERMISSIONS } from '../../constants';\nimport { getTrad } from '../../utils';\n\nimport EmailForm from './components/EmailForm';\nimport EmailTable from './components/EmailTable';\n\nconst ProtectedEmailTemplatesPage = () => (\n <Page.Protect permissions={PERMISSIONS.readEmailTemplates}>\n <EmailTemplatesPage />\n </Page.Protect>\n);\nconst EmailTemplatesPage = () => {\n const { formatMessage } = useIntl();\n const { trackUsage } = useTracking();\n const { notifyStatus } = useNotifyAT();\n const { toggleNotification } = useNotification();\n const queryClient = useQueryClient();\n const { get, put } = useFetchClient();\n const { formatAPIError } = useAPIErrorHandler();\n\n const [isModalOpen, setIsModalOpen] = React.useState(false);\n const [templateToEdit, setTemplateToEdit] = React.useState(null);\n\n const {\n isLoading: isLoadingForPermissions,\n allowedActions: { canUpdate },\n } = useRBAC({ update: PERMISSIONS.updateEmailTemplates });\n\n const { isLoading: isLoadingData, data } = useQuery(\n ['users-permissions', 'email-templates'],\n async () => {\n const { data } = await get('/users-permissions/email-templates');\n\n return data;\n },\n {\n onSuccess() {\n notifyStatus(\n formatMessage({\n id: getTrad('Email.template.data.loaded'),\n defaultMessage: 'Email templates has been loaded',\n })\n );\n },\n onError(error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n },\n }\n );\n\n const isLoading = isLoadingForPermissions || isLoadingData;\n\n const handleToggle = () => {\n setIsModalOpen((prev) => !prev);\n };\n\n const handleEditClick = (template) => {\n setTemplateToEdit(template);\n handleToggle();\n };\n\n const submitMutation = useMutation(\n (body) => put('/users-permissions/email-templates', { 'email-templates': body }),\n {\n async onSuccess() {\n await queryClient.invalidateQueries(['users-permissions', 'email-templates']);\n\n toggleNotification({\n type: 'success',\n message: formatMessage({ id: 'notification.success.saved', defaultMessage: 'Saved' }),\n });\n\n trackUsage('didEditEmailTemplates');\n\n handleToggle();\n },\n onError(error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n },\n refetchActive: true,\n }\n );\n\n const handleSubmit = (body) => {\n trackUsage('willEditEmailTemplates');\n\n const editedTemplates = { ...data, [templateToEdit]: body };\n submitMutation.mutate(editedTemplates);\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Page.Main aria-busy={submitMutation.isLoading}>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n {\n name: formatMessage({\n id: getTrad('HeaderNav.link.emailTemplates'),\n defaultMessage: 'Email templates',\n }),\n }\n )}\n </Page.Title>\n <Layouts.Header\n title={formatMessage({\n id: getTrad('HeaderNav.link.emailTemplates'),\n defaultMessage: 'Email templates',\n })}\n />\n <Layouts.Content>\n <EmailTable onEditClick={handleEditClick} canUpdate={canUpdate} />\n <EmailForm\n template={data[templateToEdit]}\n onToggle={handleToggle}\n open={isModalOpen}\n onSubmit={handleSubmit}\n />\n </Layouts.Content>\n </Page.Main>\n );\n};\n\nexport { ProtectedEmailTemplatesPage, EmailTemplatesPage };\n"],"names":["ProtectedEmailTemplatesPage","_jsx","Page","Protect","permissions","PERMISSIONS","readEmailTemplates","EmailTemplatesPage","formatMessage","useIntl","trackUsage","useTracking","notifyStatus","useNotifyAT","toggleNotification","useNotification","queryClient","useQueryClient","get","put","useFetchClient","formatAPIError","useAPIErrorHandler","isModalOpen","setIsModalOpen","React","useState","templateToEdit","setTemplateToEdit","isLoading","isLoadingForPermissions","allowedActions","canUpdate","useRBAC","update","updateEmailTemplates","isLoadingData","data","useQuery","onSuccess","id","getTrad","defaultMessage","onError","error","type","message","handleToggle","prev","handlLine truncated
@@ -0,0 +1,135 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import * as React from 'react';
import { useTracking } from '@strapi/admin/strapi-admin';
import { useNotifyAT } from '@strapi/design-system';
import { Page, useNotification, useFetchClient, useAPIErrorHandler, useRBAC, Layouts } from '@strapi/strapi/admin';
import { useIntl } from 'react-intl';
import { useQueryClient, useQuery, useMutation } from 'react-query';
import { PERMISSIONS } from '../../constants.mjs';
import 'lodash/isEmpty';
import getTrad from '../../utils/getTrad.mjs';
import EmailForm from './components/EmailForm.mjs';
import EmailTable from './components/EmailTable.mjs';
const ProtectedEmailTemplatesPage = ()=>/*#__PURE__*/ jsx(Page.Protect, {
permissions: PERMISSIONS.readEmailTemplates,
children: /*#__PURE__*/ jsx(EmailTemplatesPage, {})
});
const EmailTemplatesPage = ()=>{
const { formatMessage } = useIntl();
const { trackUsage } = useTracking();
const { notifyStatus } = useNotifyAT();
const { toggleNotification } = useNotification();
const queryClient = useQueryClient();
const { get, put } = useFetchClient();
const { formatAPIError } = useAPIErrorHandler();
const [isModalOpen, setIsModalOpen] = React.useState(false);
const [templateToEdit, setTemplateToEdit] = React.useState(null);
const { isLoading: isLoadingForPermissions, allowedActions: { canUpdate } } = useRBAC({
update: PERMISSIONS.updateEmailTemplates
});
const { isLoading: isLoadingData, data } = useQuery([
'users-permissions',
'email-templates'
], async ()=>{
const { data } = await get('/users-permissions/email-templates');
return data;
}, {
onSuccess () {
notifyStatus(formatMessage({
id: getTrad('Email.template.data.loaded'),
defaultMessage: 'Email templates has been loaded'
}));
},
onError (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
}
});
const isLoading = isLoadingForPermissions || isLoadingData;
const handleToggle = ()=>{
setIsModalOpen((prev)=>!prev);
};
const handleEditClick = (template)=>{
setTemplateToEdit(template);
handleToggle();
};
const submitMutation = useMutation((body)=>put('/users-permissions/email-templates', {
'email-templates': body
}), {
async onSuccess () {
await queryClient.invalidateQueries([
'users-permissions',
'email-templates'
]);
toggleNotification({
type: 'success',
message: formatMessage({
id: 'notification.success.saved',
defaultMessage: 'Saved'
})
});
trackUsage('didEditEmailTemplates');
handleToggle();
},
onError (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
},
refetchActive: true
});
const handleSubmit = (body)=>{
trackUsage('willEditEmailTemplates');
const editedTemplates = {
...data,
[templateToEdit]: body
};
submitMutation.mutate(editedTemplates);
};
if (isLoading) {
return /*#__PURE__*/ jsx(Page.Loading, {});
}
return /*#__PURE__*/ jsxs(Page.Main, {
"aria-busy": submitMutation.isLoading,
children: [
/*#__PURE__*/ jsx(Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: formatMessage({
id: getTrad('HeaderNav.link.emailTemplates'),
defaultMessage: 'Email templates'
})
})
}),
/*#__PURE__*/ jsx(Layouts.Header, {
title: formatMessage({
id: getTrad('HeaderNav.link.emailTemplates'),
defaultMessage: 'Email templates'
})
}),
/*#__PURE__*/ jsxs(Layouts.Content, {
children: [
/*#__PURE__*/ jsx(EmailTable, {
onEditClick: handleEditClick,
canUpdate: canUpdate
}),
/*#__PURE__*/ jsx(EmailForm, {
template: data[templateToEdit],
onToggle: handleToggle,
open: isModalOpen,
onSubmit: handleSubmit
})
]
})
]
});
};
export { EmailTemplatesPage, ProtectedEmailTemplatesPage };
//# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":["../../../../admin/src/pages/EmailTemplates/index.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useTracking } from '@strapi/admin/strapi-admin';\nimport { useNotifyAT } from '@strapi/design-system';\nimport {\n Page,\n useAPIErrorHandler,\n useNotification,\n useFetchClient,\n useRBAC,\n Layouts,\n} from '@strapi/strapi/admin';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery, useQueryClient } from 'react-query';\n\nimport { PERMISSIONS } from '../../constants';\nimport { getTrad } from '../../utils';\n\nimport EmailForm from './components/EmailForm';\nimport EmailTable from './components/EmailTable';\n\nconst ProtectedEmailTemplatesPage = () => (\n <Page.Protect permissions={PERMISSIONS.readEmailTemplates}>\n <EmailTemplatesPage />\n </Page.Protect>\n);\nconst EmailTemplatesPage = () => {\n const { formatMessage } = useIntl();\n const { trackUsage } = useTracking();\n const { notifyStatus } = useNotifyAT();\n const { toggleNotification } = useNotification();\n const queryClient = useQueryClient();\n const { get, put } = useFetchClient();\n const { formatAPIError } = useAPIErrorHandler();\n\n const [isModalOpen, setIsModalOpen] = React.useState(false);\n const [templateToEdit, setTemplateToEdit] = React.useState(null);\n\n const {\n isLoading: isLoadingForPermissions,\n allowedActions: { canUpdate },\n } = useRBAC({ update: PERMISSIONS.updateEmailTemplates });\n\n const { isLoading: isLoadingData, data } = useQuery(\n ['users-permissions', 'email-templates'],\n async () => {\n const { data } = await get('/users-permissions/email-templates');\n\n return data;\n },\n {\n onSuccess() {\n notifyStatus(\n formatMessage({\n id: getTrad('Email.template.data.loaded'),\n defaultMessage: 'Email templates has been loaded',\n })\n );\n },\n onError(error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n },\n }\n );\n\n const isLoading = isLoadingForPermissions || isLoadingData;\n\n const handleToggle = () => {\n setIsModalOpen((prev) => !prev);\n };\n\n const handleEditClick = (template) => {\n setTemplateToEdit(template);\n handleToggle();\n };\n\n const submitMutation = useMutation(\n (body) => put('/users-permissions/email-templates', { 'email-templates': body }),\n {\n async onSuccess() {\n await queryClient.invalidateQueries(['users-permissions', 'email-templates']);\n\n toggleNotification({\n type: 'success',\n message: formatMessage({ id: 'notification.success.saved', defaultMessage: 'Saved' }),\n });\n\n trackUsage('didEditEmailTemplates');\n\n handleToggle();\n },\n onError(error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n },\n refetchActive: true,\n }\n );\n\n const handleSubmit = (body) => {\n trackUsage('willEditEmailTemplates');\n\n const editedTemplates = { ...data, [templateToEdit]: body };\n submitMutation.mutate(editedTemplates);\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Page.Main aria-busy={submitMutation.isLoading}>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n {\n name: formatMessage({\n id: getTrad('HeaderNav.link.emailTemplates'),\n defaultMessage: 'Email templates',\n }),\n }\n )}\n </Page.Title>\n <Layouts.Header\n title={formatMessage({\n id: getTrad('HeaderNav.link.emailTemplates'),\n defaultMessage: 'Email templates',\n })}\n />\n <Layouts.Content>\n <EmailTable onEditClick={handleEditClick} canUpdate={canUpdate} />\n <EmailForm\n template={data[templateToEdit]}\n onToggle={handleToggle}\n open={isModalOpen}\n onSubmit={handleSubmit}\n />\n </Layouts.Content>\n </Page.Main>\n );\n};\n\nexport { ProtectedEmailTemplatesPage, EmailTemplatesPage };\n"],"names":["ProtectedEmailTemplatesPage","_jsx","Page","Protect","permissions","PERMISSIONS","readEmailTemplates","EmailTemplatesPage","formatMessage","useIntl","trackUsage","useTracking","notifyStatus","useNotifyAT","toggleNotification","useNotification","queryClient","useQueryClient","get","put","useFetchClient","formatAPIError","useAPIErrorHandler","isModalOpen","setIsModalOpen","React","useState","templateToEdit","setTemplateToEdit","isLoading","isLoadingForPermissions","allowedActions","canUpdate","useRBAC","update","updateEmailTemplates","isLoadingData","data","useQuery","onSuccess","id","getTrad","defaultMessage","onError","error","type","message","handleToggle","prev","handLine truncated
@@ -0,0 +1,50 @@
'use strict';
var admin = require('@strapi/strapi/admin');
var yup = require('yup');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var yup__namespace = /*#__PURE__*/_interopNamespaceDefault(yup);
const schema = yup__namespace.object().shape({
options: yup__namespace.object().shape({
from: yup__namespace.object().shape({
name: yup__namespace.string().required({
id: admin.translatedErrors.required.id,
defaultMessage: 'This field is required'
}),
email: yup__namespace.string().email(admin.translatedErrors.email).required({
id: admin.translatedErrors.required.id,
defaultMessage: 'This field is required'
})
}).required(),
response_email: yup__namespace.string().email(admin.translatedErrors.email),
object: yup__namespace.string().required({
id: admin.translatedErrors.required.id,
defaultMessage: 'This field is required'
}),
message: yup__namespace.string().required({
id: admin.translatedErrors.required.id,
defaultMessage: 'This field is required'
})
}).required(admin.translatedErrors.required.id)
});
module.exports = schema;
//# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
{"version":3,"file":"schema.js","sources":["../../../../../admin/src/pages/EmailTemplates/utils/schema.js"],"sourcesContent":["import { translatedErrors } from '@strapi/strapi/admin';\nimport * as yup from 'yup';\n\nconst schema = yup.object().shape({\n options: yup\n .object()\n .shape({\n from: yup\n .object()\n .shape({\n name: yup.string().required({\n id: translatedErrors.required.id,\n defaultMessage: 'This field is required',\n }),\n email: yup.string().email(translatedErrors.email).required({\n id: translatedErrors.required.id,\n defaultMessage: 'This field is required',\n }),\n })\n .required(),\n response_email: yup.string().email(translatedErrors.email),\n object: yup.string().required({\n id: translatedErrors.required.id,\n defaultMessage: 'This field is required',\n }),\n message: yup.string().required({\n id: translatedErrors.required.id,\n defaultMessage: 'This field is required',\n }),\n })\n .required(translatedErrors.required.id),\n});\n\nexport default schema;\n"],"names":["schema","yup","object","shape","options","from","name","string","required","id","translatedErrors","defaultMessage","email","response_email","message"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAGA,MAAMA,MAASC,GAAAA,cAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAChCC,IAAAA,OAAAA,EAASH,cACNC,CAAAA,MAAM,EACNC,CAAAA,KAAK,CAAC;AACLE,QAAAA,IAAAA,EAAMJ,cACHC,CAAAA,MAAM,EACNC,CAAAA,KAAK,CAAC;AACLG,YAAAA,IAAAA,EAAML,cAAIM,CAAAA,MAAM,EAAGC,CAAAA,QAAQ,CAAC;gBAC1BC,EAAIC,EAAAA,sBAAAA,CAAiBF,QAAQ,CAACC,EAAE;gBAChCE,cAAgB,EAAA;AAClB,aAAA,CAAA;YACAC,KAAOX,EAAAA,cAAAA,CAAIM,MAAM,EAAGK,CAAAA,KAAK,CAACF,sBAAiBE,CAAAA,KAAK,CAAEJ,CAAAA,QAAQ,CAAC;gBACzDC,EAAIC,EAAAA,sBAAAA,CAAiBF,QAAQ,CAACC,EAAE;gBAChCE,cAAgB,EAAA;AAClB,aAAA;AACF,SAAA,CAAA,CACCH,QAAQ,EAAA;AACXK,QAAAA,cAAAA,EAAgBZ,eAAIM,MAAM,EAAA,CAAGK,KAAK,CAACF,uBAAiBE,KAAK,CAAA;AACzDV,QAAAA,MAAAA,EAAQD,cAAIM,CAAAA,MAAM,EAAGC,CAAAA,QAAQ,CAAC;YAC5BC,EAAIC,EAAAA,sBAAAA,CAAiBF,QAAQ,CAACC,EAAE;YAChCE,cAAgB,EAAA;AAClB,SAAA,CAAA;AACAG,QAAAA,OAAAA,EAASb,cAAIM,CAAAA,MAAM,EAAGC,CAAAA,QAAQ,CAAC;YAC7BC,EAAIC,EAAAA,sBAAAA,CAAiBF,QAAQ,CAACC,EAAE;YAChCE,cAAgB,EAAA;AAClB,SAAA;AACF,KAAA,CAAA,CACCH,QAAQ,CAACE,sBAAiBF,CAAAA,QAAQ,CAACC,EAAE;AAC1C,CAAA;;;;"}
@@ -0,0 +1,29 @@
import { translatedErrors } from '@strapi/strapi/admin';
import * as yup from 'yup';
const schema = yup.object().shape({
options: yup.object().shape({
from: yup.object().shape({
name: yup.string().required({
id: translatedErrors.required.id,
defaultMessage: 'This field is required'
}),
email: yup.string().email(translatedErrors.email).required({
id: translatedErrors.required.id,
defaultMessage: 'This field is required'
})
}).required(),
response_email: yup.string().email(translatedErrors.email),
object: yup.string().required({
id: translatedErrors.required.id,
defaultMessage: 'This field is required'
}),
message: yup.string().required({
id: translatedErrors.required.id,
defaultMessage: 'This field is required'
})
}).required(translatedErrors.required.id)
});
export { schema as default };
//# sourceMappingURL=schema.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"schema.mjs","sources":["../../../../../admin/src/pages/EmailTemplates/utils/schema.js"],"sourcesContent":["import { translatedErrors } from '@strapi/strapi/admin';\nimport * as yup from 'yup';\n\nconst schema = yup.object().shape({\n options: yup\n .object()\n .shape({\n from: yup\n .object()\n .shape({\n name: yup.string().required({\n id: translatedErrors.required.id,\n defaultMessage: 'This field is required',\n }),\n email: yup.string().email(translatedErrors.email).required({\n id: translatedErrors.required.id,\n defaultMessage: 'This field is required',\n }),\n })\n .required(),\n response_email: yup.string().email(translatedErrors.email),\n object: yup.string().required({\n id: translatedErrors.required.id,\n defaultMessage: 'This field is required',\n }),\n message: yup.string().required({\n id: translatedErrors.required.id,\n defaultMessage: 'This field is required',\n }),\n })\n .required(translatedErrors.required.id),\n});\n\nexport default schema;\n"],"names":["schema","yup","object","shape","options","from","name","string","required","id","translatedErrors","defaultMessage","email","response_email","message"],"mappings":";;;AAGA,MAAMA,MAASC,GAAAA,GAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;AAChCC,IAAAA,OAAAA,EAASH,GACNC,CAAAA,MAAM,EACNC,CAAAA,KAAK,CAAC;AACLE,QAAAA,IAAAA,EAAMJ,GACHC,CAAAA,MAAM,EACNC,CAAAA,KAAK,CAAC;AACLG,YAAAA,IAAAA,EAAML,GAAIM,CAAAA,MAAM,EAAGC,CAAAA,QAAQ,CAAC;gBAC1BC,EAAIC,EAAAA,gBAAAA,CAAiBF,QAAQ,CAACC,EAAE;gBAChCE,cAAgB,EAAA;AAClB,aAAA,CAAA;YACAC,KAAOX,EAAAA,GAAAA,CAAIM,MAAM,EAAGK,CAAAA,KAAK,CAACF,gBAAiBE,CAAAA,KAAK,CAAEJ,CAAAA,QAAQ,CAAC;gBACzDC,EAAIC,EAAAA,gBAAAA,CAAiBF,QAAQ,CAACC,EAAE;gBAChCE,cAAgB,EAAA;AAClB,aAAA;AACF,SAAA,CAAA,CACCH,QAAQ,EAAA;AACXK,QAAAA,cAAAA,EAAgBZ,IAAIM,MAAM,EAAA,CAAGK,KAAK,CAACF,iBAAiBE,KAAK,CAAA;AACzDV,QAAAA,MAAAA,EAAQD,GAAIM,CAAAA,MAAM,EAAGC,CAAAA,QAAQ,CAAC;YAC5BC,EAAIC,EAAAA,gBAAAA,CAAiBF,QAAQ,CAACC,EAAE;YAChCE,cAAgB,EAAA;AAClB,SAAA,CAAA;AACAG,QAAAA,OAAAA,EAASb,GAAIM,CAAAA,MAAM,EAAGC,CAAAA,QAAQ,CAAC;YAC7BC,EAAIC,EAAAA,gBAAAA,CAAiBF,QAAQ,CAACC,EAAE;YAChCE,cAAgB,EAAA;AAClB,SAAA;AACF,KAAA,CAAA,CACCH,QAAQ,CAACE,gBAAiBF,CAAAA,QAAQ,CAACC,EAAE;AAC1C,CAAA;;;;"}
@@ -0,0 +1,278 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var strapiAdmin = require('@strapi/admin/strapi-admin');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var admin = require('@strapi/strapi/admin');
var upperFirst = require('lodash/upperFirst');
var reactIntl = require('react-intl');
var reactQuery = require('react-query');
var index = require('../../components/FormModal/index.js');
var constants = require('../../constants.js');
require('lodash/isEmpty');
var getTrad = require('../../utils/getTrad.js');
var forms = require('./utils/forms.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const ProvidersPage = ()=>{
const { formatMessage, locale } = reactIntl.useIntl();
const queryClient = reactQuery.useQueryClient();
const { trackUsage } = strapiAdmin.useTracking();
const [isOpen, setIsOpen] = React__namespace.useState(false);
const [providerToEditName, setProviderToEditName] = React__namespace.useState(null);
const { toggleNotification } = admin.useNotification();
const { get, put } = admin.useFetchClient();
const { formatAPIError } = admin.useAPIErrorHandler();
const formatter = designSystem.useCollator(locale, {
sensitivity: 'base'
});
const { isLoading: isLoadingPermissions, allowedActions: { canUpdate } } = admin.useRBAC({
update: constants.PERMISSIONS.updateProviders
});
const { isLoading: isLoadingData, data } = reactQuery.useQuery([
'users-permissions',
'get-providers'
], async ()=>{
const { data } = await get('/users-permissions/providers');
return data;
}, {
initialData: {}
});
const submitMutation = reactQuery.useMutation((body)=>put('/users-permissions/providers', body), {
async onSuccess () {
await queryClient.invalidateQueries([
'users-permissions',
'get-providers'
]);
toggleNotification({
type: 'success',
message: formatMessage({
id: getTrad('notification.success.submit')
})
});
trackUsage('didEditAuthenticationProvider');
handleToggleModal();
},
onError (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
},
refetchActive: false
});
const providers = Object.entries(data).reduce((acc, [name, provider])=>{
const { icon, enabled, subdomain } = provider;
acc.push({
name,
icon: icon === 'envelope' ? [
'fas',
'envelope'
] : [
'fab',
icon
],
enabled,
subdomain
});
return acc;
}, []).sort((a, b)=>formatter.compare(a.name, b.name));
const isLoading = isLoadingData || isLoadingPermissions;
const isProviderWithSubdomain = React__namespace.useMemo(()=>{
if (!providerToEditName) {
return false;
}
const providerToEdit = providers.find((obj)=>obj.name === providerToEditName);
return !!providerToEdit?.subdomain;
}, [
providers,
providerToEditName
]);
const layoutToRender = React__namespace.useMemo(()=>{
if (providerToEditName === 'email') {
return forms.email;
}
if (isProviderWithSubdomain) {
return forms.providersWithSubdomain;
}
return forms.providers;
}, [
providerToEditName,
isProviderWithSubdomain
]);
const handleToggleModal = ()=>{
setIsOpen((prev)=>!prev);
};
const handleClickEdit = (provider)=>{
if (canUpdate) {
setProviderToEditName(provider.name);
handleToggleModal();
}
};
const handleSubmit = async (values)=>{
trackUsage('willEditAuthenticationProvider');
submitMutation.mutate({
providers: {
...data,
[providerToEditName]: values
}
});
};
if (isLoading) {
return /*#__PURE__*/ jsxRuntime.jsx(admin.Page.Loading, {});
}
return /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.Layouts.Root, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(admin.Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: formatMessage({
id: getTrad('HeaderNav.link.providers'),
defaultMessage: 'Providers'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(admin.Page.Main, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Layouts.Header, {
title: formatMessage({
id: getTrad('HeaderNav.link.providers'),
defaultMessage: 'Providers'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Layouts.Content, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Table, {
colCount: 3,
rowCount: providers.length + 1,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Thead, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tr, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: 'global.name',
defaultMessage: 'Name'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: getTrad('Providers.status'),
defaultMessage: 'Status'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "sigma",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.VisuallyHidden, {
children: formatMessage({
id: 'global.settings',
defaultMessage: 'Settings'
})
})
})
})
]
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Tbody, {
children: providers.map((provider)=>/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tr, {
onClick: ()=>canUpdate ? handleClickEdit(provider) : undefined,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
width: "45%",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
fontWeight: "semiBold",
textColor: "neutral800",
children: provider.name
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
width: "65%",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
textColor: provider.enabled ? 'success600' : 'danger600',
"data-testid": `enable-${provider.name}`,
children: provider.enabled ? formatMessage({
id: 'global.enabled',
defaultMessage: 'Enabled'
}) : formatMessage({
id: 'global.disabled',
defaultMessage: 'Disabled'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
onClick: (e)=>e.stopPropagation(),
children: canUpdate && /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
onClick: ()=>handleClickEdit(provider),
variant: "ghost",
label: "Edit",
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Pencil, {})
})
})
]
}, provider.name))
})
]
})
})
]
}),
/*#__PURE__*/ jsxRuntime.jsx(index, {
initialData: data[providerToEditName],
isOpen: isOpen,
isSubmiting: submitMutation.isLoading,
layout: layoutToRender,
headerBreadcrumbs: [
formatMessage({
id: getTrad('PopUpForm.header.edit.providers'),
defaultMessage: 'Edit Provider'
}),
upperFirst(providerToEditName)
],
onToggle: handleToggleModal,
onSubmit: handleSubmit,
providerToEditName: providerToEditName
})
]
});
};
const ProtectedProvidersPage = ()=>/*#__PURE__*/ jsxRuntime.jsx(admin.Page.Protect, {
permissions: constants.PERMISSIONS.readProviders,
children: /*#__PURE__*/ jsxRuntime.jsx(ProvidersPage, {})
});
exports.ProvidersPage = ProvidersPage;
exports.default = ProtectedProvidersPage;
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":["../../../../admin/src/pages/Providers/index.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useTracking, Layouts } from '@strapi/admin/strapi-admin';\nimport {\n IconButton,\n Table,\n Tbody,\n Td,\n Th,\n Thead,\n Tr,\n Typography,\n VisuallyHidden,\n useCollator,\n} from '@strapi/design-system';\nimport { Pencil } from '@strapi/icons';\nimport {\n Page,\n useAPIErrorHandler,\n useNotification,\n useFetchClient,\n useRBAC,\n} from '@strapi/strapi/admin';\nimport upperFirst from 'lodash/upperFirst';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery, useQueryClient } from 'react-query';\n\nimport FormModal from '../../components/FormModal';\nimport { PERMISSIONS } from '../../constants';\nimport { getTrad } from '../../utils';\n\nimport forms from './utils/forms';\n\nexport const ProvidersPage = () => {\n const { formatMessage, locale } = useIntl();\n const queryClient = useQueryClient();\n const { trackUsage } = useTracking();\n const [isOpen, setIsOpen] = React.useState(false);\n const [providerToEditName, setProviderToEditName] = React.useState(null);\n const { toggleNotification } = useNotification();\n const { get, put } = useFetchClient();\n const { formatAPIError } = useAPIErrorHandler();\n const formatter = useCollator(locale, {\n sensitivity: 'base',\n });\n\n const {\n isLoading: isLoadingPermissions,\n allowedActions: { canUpdate },\n } = useRBAC({ update: PERMISSIONS.updateProviders });\n\n const { isLoading: isLoadingData, data } = useQuery(\n ['users-permissions', 'get-providers'],\n async () => {\n const { data } = await get('/users-permissions/providers');\n\n return data;\n },\n {\n initialData: {},\n }\n );\n\n const submitMutation = useMutation((body) => put('/users-permissions/providers', body), {\n async onSuccess() {\n await queryClient.invalidateQueries(['users-permissions', 'get-providers']);\n\n toggleNotification({\n type: 'success',\n message: formatMessage({ id: getTrad('notification.success.submit') }),\n });\n\n trackUsage('didEditAuthenticationProvider');\n\n handleToggleModal();\n },\n onError(error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n },\n refetchActive: false,\n });\n\n const providers = Object.entries(data)\n .reduce((acc, [name, provider]) => {\n const { icon, enabled, subdomain } = provider;\n\n acc.push({\n name,\n icon: icon === 'envelope' ? ['fas', 'envelope'] : ['fab', icon],\n enabled,\n subdomain,\n });\n\n return acc;\n }, [])\n .sort((a, b) => formatter.compare(a.name, b.name));\n\n const isLoading = isLoadingData || isLoadingPermissions;\n\n const isProviderWithSubdomain = React.useMemo(() => {\n if (!providerToEditName) {\n return false;\n }\n\n const providerToEdit = providers.find((obj) => obj.name === providerToEditName);\n\n return !!providerToEdit?.subdomain;\n }, [providers, providerToEditName]);\n\n const layoutToRender = React.useMemo(() => {\n if (providerToEditName === 'email') {\n return forms.email;\n }\n\n if (isProviderWithSubdomain) {\n return forms.providersWithSubdomain;\n }\n\n return forms.providers;\n }, [providerToEditName, isProviderWithSubdomain]);\n\n const handleToggleModal = () => {\n setIsOpen((prev) => !prev);\n };\n\n const handleClickEdit = (provider) => {\n if (canUpdate) {\n setProviderToEditName(provider.name);\n handleToggleModal();\n }\n };\n\n const handleSubmit = async (values) => {\n trackUsage('willEditAuthenticationProvider');\n\n submitMutation.mutate({ providers: { ...data, [providerToEditName]: values } });\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Layouts.Root>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n {\n name: formatMessage({\n id: getTrad('HeaderNav.link.providers'),\n defaultMessage: 'Providers',\n }),\n }\n )}\n </Page.Title>\n <Page.Main>\n <Layouts.Header\n title={formatMessage({\n id: getTrad('HeaderNav.link.providers'),\n defaultMessage: 'Providers',\n })}\n />\n <Layouts.Content>\n <Table colCount={3} rowCount={providers.length + 1}>\n <Thead>\n <Tr>\n <Th>\n <Typography variant=\"sigma\" textColor=\"neutral600\">\n {formatMessage({ id: 'global.name', defaultMessage: 'Name' })}\n </Typography>\n </Th>\n <Th>\n <Typography variant=\"sigma\" textColor=\"neutral600\">\n {formLine truncated
@@ -0,0 +1,254 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import * as React from 'react';
import { useTracking, Layouts } from '@strapi/admin/strapi-admin';
import { useCollator, Table, Thead, Tr, Th, Typography, VisuallyHidden, Tbody, Td, IconButton } from '@strapi/design-system';
import { Pencil } from '@strapi/icons';
import { useNotification, useFetchClient, useAPIErrorHandler, useRBAC, Page } from '@strapi/strapi/admin';
import upperFirst from 'lodash/upperFirst';
import { useIntl } from 'react-intl';
import { useQueryClient, useQuery, useMutation } from 'react-query';
import FormModal from '../../components/FormModal/index.mjs';
import { PERMISSIONS } from '../../constants.mjs';
import 'lodash/isEmpty';
import getTrad from '../../utils/getTrad.mjs';
import forms from './utils/forms.mjs';
const ProvidersPage = ()=>{
const { formatMessage, locale } = useIntl();
const queryClient = useQueryClient();
const { trackUsage } = useTracking();
const [isOpen, setIsOpen] = React.useState(false);
const [providerToEditName, setProviderToEditName] = React.useState(null);
const { toggleNotification } = useNotification();
const { get, put } = useFetchClient();
const { formatAPIError } = useAPIErrorHandler();
const formatter = useCollator(locale, {
sensitivity: 'base'
});
const { isLoading: isLoadingPermissions, allowedActions: { canUpdate } } = useRBAC({
update: PERMISSIONS.updateProviders
});
const { isLoading: isLoadingData, data } = useQuery([
'users-permissions',
'get-providers'
], async ()=>{
const { data } = await get('/users-permissions/providers');
return data;
}, {
initialData: {}
});
const submitMutation = useMutation((body)=>put('/users-permissions/providers', body), {
async onSuccess () {
await queryClient.invalidateQueries([
'users-permissions',
'get-providers'
]);
toggleNotification({
type: 'success',
message: formatMessage({
id: getTrad('notification.success.submit')
})
});
trackUsage('didEditAuthenticationProvider');
handleToggleModal();
},
onError (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
},
refetchActive: false
});
const providers = Object.entries(data).reduce((acc, [name, provider])=>{
const { icon, enabled, subdomain } = provider;
acc.push({
name,
icon: icon === 'envelope' ? [
'fas',
'envelope'
] : [
'fab',
icon
],
enabled,
subdomain
});
return acc;
}, []).sort((a, b)=>formatter.compare(a.name, b.name));
const isLoading = isLoadingData || isLoadingPermissions;
const isProviderWithSubdomain = React.useMemo(()=>{
if (!providerToEditName) {
return false;
}
const providerToEdit = providers.find((obj)=>obj.name === providerToEditName);
return !!providerToEdit?.subdomain;
}, [
providers,
providerToEditName
]);
const layoutToRender = React.useMemo(()=>{
if (providerToEditName === 'email') {
return forms.email;
}
if (isProviderWithSubdomain) {
return forms.providersWithSubdomain;
}
return forms.providers;
}, [
providerToEditName,
isProviderWithSubdomain
]);
const handleToggleModal = ()=>{
setIsOpen((prev)=>!prev);
};
const handleClickEdit = (provider)=>{
if (canUpdate) {
setProviderToEditName(provider.name);
handleToggleModal();
}
};
const handleSubmit = async (values)=>{
trackUsage('willEditAuthenticationProvider');
submitMutation.mutate({
providers: {
...data,
[providerToEditName]: values
}
});
};
if (isLoading) {
return /*#__PURE__*/ jsx(Page.Loading, {});
}
return /*#__PURE__*/ jsxs(Layouts.Root, {
children: [
/*#__PURE__*/ jsx(Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: formatMessage({
id: getTrad('HeaderNav.link.providers'),
defaultMessage: 'Providers'
})
})
}),
/*#__PURE__*/ jsxs(Page.Main, {
children: [
/*#__PURE__*/ jsx(Layouts.Header, {
title: formatMessage({
id: getTrad('HeaderNav.link.providers'),
defaultMessage: 'Providers'
})
}),
/*#__PURE__*/ jsx(Layouts.Content, {
children: /*#__PURE__*/ jsxs(Table, {
colCount: 3,
rowCount: providers.length + 1,
children: [
/*#__PURE__*/ jsx(Thead, {
children: /*#__PURE__*/ jsxs(Tr, {
children: [
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: 'global.name',
defaultMessage: 'Name'
})
})
}),
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: getTrad('Providers.status'),
defaultMessage: 'Status'
})
})
}),
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(Typography, {
variant: "sigma",
children: /*#__PURE__*/ jsx(VisuallyHidden, {
children: formatMessage({
id: 'global.settings',
defaultMessage: 'Settings'
})
})
})
})
]
})
}),
/*#__PURE__*/ jsx(Tbody, {
children: providers.map((provider)=>/*#__PURE__*/ jsxs(Tr, {
onClick: ()=>canUpdate ? handleClickEdit(provider) : undefined,
children: [
/*#__PURE__*/ jsx(Td, {
width: "45%",
children: /*#__PURE__*/ jsx(Typography, {
fontWeight: "semiBold",
textColor: "neutral800",
children: provider.name
})
}),
/*#__PURE__*/ jsx(Td, {
width: "65%",
children: /*#__PURE__*/ jsx(Typography, {
textColor: provider.enabled ? 'success600' : 'danger600',
"data-testid": `enable-${provider.name}`,
children: provider.enabled ? formatMessage({
id: 'global.enabled',
defaultMessage: 'Enabled'
}) : formatMessage({
id: 'global.disabled',
defaultMessage: 'Disabled'
})
})
}),
/*#__PURE__*/ jsx(Td, {
onClick: (e)=>e.stopPropagation(),
children: canUpdate && /*#__PURE__*/ jsx(IconButton, {
onClick: ()=>handleClickEdit(provider),
variant: "ghost",
label: "Edit",
children: /*#__PURE__*/ jsx(Pencil, {})
})
})
]
}, provider.name))
})
]
})
})
]
}),
/*#__PURE__*/ jsx(FormModal, {
initialData: data[providerToEditName],
isOpen: isOpen,
isSubmiting: submitMutation.isLoading,
layout: layoutToRender,
headerBreadcrumbs: [
formatMessage({
id: getTrad('PopUpForm.header.edit.providers'),
defaultMessage: 'Edit Provider'
}),
upperFirst(providerToEditName)
],
onToggle: handleToggleModal,
onSubmit: handleSubmit,
providerToEditName: providerToEditName
})
]
});
};
const ProtectedProvidersPage = ()=>/*#__PURE__*/ jsx(Page.Protect, {
permissions: PERMISSIONS.readProviders,
children: /*#__PURE__*/ jsx(ProvidersPage, {})
});
export { ProvidersPage, ProtectedProvidersPage as default };
//# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":["../../../../admin/src/pages/Providers/index.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useTracking, Layouts } from '@strapi/admin/strapi-admin';\nimport {\n IconButton,\n Table,\n Tbody,\n Td,\n Th,\n Thead,\n Tr,\n Typography,\n VisuallyHidden,\n useCollator,\n} from '@strapi/design-system';\nimport { Pencil } from '@strapi/icons';\nimport {\n Page,\n useAPIErrorHandler,\n useNotification,\n useFetchClient,\n useRBAC,\n} from '@strapi/strapi/admin';\nimport upperFirst from 'lodash/upperFirst';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery, useQueryClient } from 'react-query';\n\nimport FormModal from '../../components/FormModal';\nimport { PERMISSIONS } from '../../constants';\nimport { getTrad } from '../../utils';\n\nimport forms from './utils/forms';\n\nexport const ProvidersPage = () => {\n const { formatMessage, locale } = useIntl();\n const queryClient = useQueryClient();\n const { trackUsage } = useTracking();\n const [isOpen, setIsOpen] = React.useState(false);\n const [providerToEditName, setProviderToEditName] = React.useState(null);\n const { toggleNotification } = useNotification();\n const { get, put } = useFetchClient();\n const { formatAPIError } = useAPIErrorHandler();\n const formatter = useCollator(locale, {\n sensitivity: 'base',\n });\n\n const {\n isLoading: isLoadingPermissions,\n allowedActions: { canUpdate },\n } = useRBAC({ update: PERMISSIONS.updateProviders });\n\n const { isLoading: isLoadingData, data } = useQuery(\n ['users-permissions', 'get-providers'],\n async () => {\n const { data } = await get('/users-permissions/providers');\n\n return data;\n },\n {\n initialData: {},\n }\n );\n\n const submitMutation = useMutation((body) => put('/users-permissions/providers', body), {\n async onSuccess() {\n await queryClient.invalidateQueries(['users-permissions', 'get-providers']);\n\n toggleNotification({\n type: 'success',\n message: formatMessage({ id: getTrad('notification.success.submit') }),\n });\n\n trackUsage('didEditAuthenticationProvider');\n\n handleToggleModal();\n },\n onError(error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n },\n refetchActive: false,\n });\n\n const providers = Object.entries(data)\n .reduce((acc, [name, provider]) => {\n const { icon, enabled, subdomain } = provider;\n\n acc.push({\n name,\n icon: icon === 'envelope' ? ['fas', 'envelope'] : ['fab', icon],\n enabled,\n subdomain,\n });\n\n return acc;\n }, [])\n .sort((a, b) => formatter.compare(a.name, b.name));\n\n const isLoading = isLoadingData || isLoadingPermissions;\n\n const isProviderWithSubdomain = React.useMemo(() => {\n if (!providerToEditName) {\n return false;\n }\n\n const providerToEdit = providers.find((obj) => obj.name === providerToEditName);\n\n return !!providerToEdit?.subdomain;\n }, [providers, providerToEditName]);\n\n const layoutToRender = React.useMemo(() => {\n if (providerToEditName === 'email') {\n return forms.email;\n }\n\n if (isProviderWithSubdomain) {\n return forms.providersWithSubdomain;\n }\n\n return forms.providers;\n }, [providerToEditName, isProviderWithSubdomain]);\n\n const handleToggleModal = () => {\n setIsOpen((prev) => !prev);\n };\n\n const handleClickEdit = (provider) => {\n if (canUpdate) {\n setProviderToEditName(provider.name);\n handleToggleModal();\n }\n };\n\n const handleSubmit = async (values) => {\n trackUsage('willEditAuthenticationProvider');\n\n submitMutation.mutate({ providers: { ...data, [providerToEditName]: values } });\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Layouts.Root>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n {\n name: formatMessage({\n id: getTrad('HeaderNav.link.providers'),\n defaultMessage: 'Providers',\n }),\n }\n )}\n </Page.Title>\n <Page.Main>\n <Layouts.Header\n title={formatMessage({\n id: getTrad('HeaderNav.link.providers'),\n defaultMessage: 'Providers',\n })}\n />\n <Layouts.Content>\n <Table colCount={3} rowCount={providers.length + 1}>\n <Thead>\n <Tr>\n <Th>\n <Typography variant=\"sigma\" textColor=\"neutral600\">\n {formatMessage({ id: 'global.name', defaultMessage: 'Name' })}\n </Typography>\n </Th>\n <Th>\n <Typography variant=\"sigma\" textColor=\"neutral600\">\n {forLine truncated
@@ -0,0 +1,281 @@
'use strict';
var admin = require('@strapi/strapi/admin');
var yup = require('yup');
require('lodash/isEmpty');
var getTrad = require('../../../utils/getTrad.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var yup__namespace = /*#__PURE__*/_interopNamespaceDefault(yup);
const callbackLabel = {
id: getTrad('PopUpForm.Providers.redirectURL.front-end.label'),
defaultMessage: 'The redirect URL to your front-end app'
};
const callbackPlaceholder = {
id: 'http://www.client-app.com',
defaultMessage: 'http://www.client-app.com'
};
const enabledDescription = {
id: getTrad('PopUpForm.Providers.enabled.description'),
defaultMessage: "If disabled, users won't be able to use this provider."
};
const enabledLabel = {
id: getTrad('PopUpForm.Providers.enabled.label'),
defaultMessage: 'Enable'
};
const keyLabel = {
id: getTrad('PopUpForm.Providers.key.label'),
defaultMessage: 'Client ID'
};
const hintLabel = {
id: getTrad('PopUpForm.Providers.redirectURL.label'),
defaultMessage: 'The redirect URL to add in your {provider} application configurations'
};
const textPlaceholder = {
id: getTrad('PopUpForm.Providers.key.placeholder'),
defaultMessage: 'TEXT'
};
const secretLabel = {
id: getTrad('PopUpForm.Providers.secret.label'),
defaultMessage: 'Client Secret'
};
const CALLBACK_REGEX = /^$|^[a-z][a-z0-9+.-]*:\/\/[^\s/$.?#](?:[^\s]*[^\s/$.?#])?$/i;
const SUBDOMAIN_REGEX = /^(([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+)(:\d+)?(\/\S*)?$/i;
const forms = {
email: {
form: [
[
{
intlLabel: enabledLabel,
name: 'enabled',
type: 'bool',
description: enabledDescription,
size: 6
}
]
],
schema: yup__namespace.object().shape({
enabled: yup__namespace.bool().required(admin.translatedErrors.required.id)
})
},
providers: {
form: [
[
{
intlLabel: enabledLabel,
name: 'enabled',
type: 'bool',
description: enabledDescription,
size: 6,
validations: {
required: true
}
}
],
[
{
intlLabel: keyLabel,
name: 'key',
type: 'text',
placeholder: textPlaceholder,
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: secretLabel,
name: 'secret',
type: 'text',
placeholder: textPlaceholder,
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: callbackLabel,
placeholder: callbackPlaceholder,
name: 'callback',
type: 'text',
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: hintLabel,
name: 'noName',
type: 'text',
validations: {},
size: 12,
disabled: true
}
]
],
schema: yup__namespace.object().shape({
enabled: yup__namespace.bool().required(admin.translatedErrors.required.id),
key: yup__namespace.string().when('enabled', {
is: true,
then: yup__namespace.string().required(admin.translatedErrors.required.id),
otherwise: yup__namespace.string()
}),
secret: yup__namespace.string().when('enabled', {
is: true,
then: yup__namespace.string().required(admin.translatedErrors.required.id),
otherwise: yup__namespace.string()
}),
callback: yup__namespace.string().when('enabled', {
is: true,
then: yup__namespace.string().matches(CALLBACK_REGEX, admin.translatedErrors.regex.id).required(admin.translatedErrors.required.id),
otherwise: yup__namespace.string()
})
})
},
providersWithSubdomain: {
form: [
[
{
intlLabel: enabledLabel,
name: 'enabled',
type: 'bool',
description: enabledDescription,
size: 6,
validations: {
required: true
}
}
],
[
{
intlLabel: keyLabel,
name: 'key',
type: 'text',
placeholder: textPlaceholder,
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: secretLabel,
name: 'secret',
type: 'text',
placeholder: textPlaceholder,
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: {
id: getTrad({
id: 'PopUpForm.Providers.jwksurl.label'
}),
defaultMessage: 'JWKS URL'
},
name: 'jwksurl',
type: 'text',
placeholder: textPlaceholder,
size: 12,
validations: {
required: false
}
}
],
[
{
intlLabel: {
id: getTrad('PopUpForm.Providers.subdomain.label'),
defaultMessage: 'Host URI (Subdomain)'
},
name: 'subdomain',
type: 'text',
placeholder: {
id: getTrad('PopUpForm.Providers.subdomain.placeholder'),
defaultMessage: 'my.subdomain.com'
},
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: callbackLabel,
placeholder: callbackPlaceholder,
name: 'callback',
type: 'text',
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: hintLabel,
name: 'noName',
type: 'text',
validations: {},
size: 12,
disabled: true
}
]
],
schema: yup__namespace.object().shape({
enabled: yup__namespace.bool().required(admin.translatedErrors.required.id),
key: yup__namespace.string().when('enabled', {
is: true,
then: yup__namespace.string().required(admin.translatedErrors.required.id),
otherwise: yup__namespace.string()
}),
secret: yup__namespace.string().when('enabled', {
is: true,
then: yup__namespace.string().required(admin.translatedErrors.required.id),
otherwise: yup__namespace.string()
}),
subdomain: yup__namespace.string().when('enabled', {
is: true,
then: yup__namespace.string().matches(SUBDOMAIN_REGEX, admin.translatedErrors.regex.id).required(admin.translatedErrors.required.id),
otherwise: yup__namespace.string()
}),
callback: yup__namespace.string().when('enabled', {
is: true,
then: yup__namespace.string().matches(CALLBACK_REGEX, admin.translatedErrors.regex.id).required(admin.translatedErrors.required.id),
otherwise: yup__namespace.string()
})
})
}
};
module.exports = forms;
//# sourceMappingURL=forms.js.map
@@ -0,0 +1 @@
{"version":3,"file":"forms.js","sources":["../../../../../admin/src/pages/Providers/utils/forms.js"],"sourcesContent":["import { translatedErrors } from '@strapi/strapi/admin';\nimport * as yup from 'yup';\n\nimport { getTrad } from '../../../utils';\n\nconst callbackLabel = {\n id: getTrad('PopUpForm.Providers.redirectURL.front-end.label'),\n defaultMessage: 'The redirect URL to your front-end app',\n};\nconst callbackPlaceholder = {\n id: 'http://www.client-app.com',\n defaultMessage: 'http://www.client-app.com',\n};\nconst enabledDescription = {\n id: getTrad('PopUpForm.Providers.enabled.description'),\n defaultMessage: \"If disabled, users won't be able to use this provider.\",\n};\nconst enabledLabel = {\n id: getTrad('PopUpForm.Providers.enabled.label'),\n defaultMessage: 'Enable',\n};\nconst keyLabel = { id: getTrad('PopUpForm.Providers.key.label'), defaultMessage: 'Client ID' };\nconst hintLabel = {\n id: getTrad('PopUpForm.Providers.redirectURL.label'),\n defaultMessage: 'The redirect URL to add in your {provider} application configurations',\n};\nconst textPlaceholder = {\n id: getTrad('PopUpForm.Providers.key.placeholder'),\n defaultMessage: 'TEXT',\n};\n\nconst secretLabel = {\n id: getTrad('PopUpForm.Providers.secret.label'),\n defaultMessage: 'Client Secret',\n};\n\nconst CALLBACK_REGEX = /^$|^[a-z][a-z0-9+.-]*:\\/\\/[^\\s/$.?#](?:[^\\s]*[^\\s/$.?#])?$/i;\nconst SUBDOMAIN_REGEX = /^(([a-zA-Z0-9-]+\\.)*[a-zA-Z0-9-]+)(:\\d+)?(\\/\\S*)?$/i;\n\nconst forms = {\n email: {\n form: [\n [\n {\n intlLabel: enabledLabel,\n name: 'enabled',\n type: 'bool',\n description: enabledDescription,\n size: 6,\n // TODO check if still needed\n // validations: {\n // required: true,\n // },\n },\n ],\n ],\n schema: yup.object().shape({\n enabled: yup.bool().required(translatedErrors.required.id),\n }),\n },\n providers: {\n form: [\n [\n {\n intlLabel: enabledLabel,\n name: 'enabled',\n type: 'bool',\n description: enabledDescription,\n size: 6,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: keyLabel,\n name: 'key',\n type: 'text',\n placeholder: textPlaceholder,\n size: 12,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: secretLabel,\n name: 'secret',\n type: 'text',\n placeholder: textPlaceholder,\n size: 12,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: callbackLabel,\n placeholder: callbackPlaceholder,\n name: 'callback',\n type: 'text',\n size: 12,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: hintLabel,\n name: 'noName',\n type: 'text',\n validations: {},\n size: 12,\n disabled: true,\n },\n ],\n ],\n schema: yup.object().shape({\n enabled: yup.bool().required(translatedErrors.required.id),\n key: yup.string().when('enabled', {\n is: true,\n then: yup.string().required(translatedErrors.required.id),\n otherwise: yup.string(),\n }),\n secret: yup.string().when('enabled', {\n is: true,\n then: yup.string().required(translatedErrors.required.id),\n otherwise: yup.string(),\n }),\n callback: yup.string().when('enabled', {\n is: true,\n then: yup\n .string()\n .matches(CALLBACK_REGEX, translatedErrors.regex.id)\n .required(translatedErrors.required.id),\n otherwise: yup.string(),\n }),\n }),\n },\n providersWithSubdomain: {\n form: [\n [\n {\n intlLabel: enabledLabel,\n name: 'enabled',\n type: 'bool',\n description: enabledDescription,\n size: 6,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: keyLabel,\n name: 'key',\n type: 'text',\n placeholder: textPlaceholder,\n size: 12,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: secretLabel,\n name: 'secret',\n type: 'text',\n placeholder: textPlaceholder,\n size: 12,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: {\n id: getTrad({ id: 'PopUpForm.Providers.jwksurl.label' }),\n defaultMessage: 'JWKS URL',\n },\n nameLine truncated
@@ -0,0 +1,260 @@
import { translatedErrors } from '@strapi/strapi/admin';
import * as yup from 'yup';
import 'lodash/isEmpty';
import getTrad from '../../../utils/getTrad.mjs';
const callbackLabel = {
id: getTrad('PopUpForm.Providers.redirectURL.front-end.label'),
defaultMessage: 'The redirect URL to your front-end app'
};
const callbackPlaceholder = {
id: 'http://www.client-app.com',
defaultMessage: 'http://www.client-app.com'
};
const enabledDescription = {
id: getTrad('PopUpForm.Providers.enabled.description'),
defaultMessage: "If disabled, users won't be able to use this provider."
};
const enabledLabel = {
id: getTrad('PopUpForm.Providers.enabled.label'),
defaultMessage: 'Enable'
};
const keyLabel = {
id: getTrad('PopUpForm.Providers.key.label'),
defaultMessage: 'Client ID'
};
const hintLabel = {
id: getTrad('PopUpForm.Providers.redirectURL.label'),
defaultMessage: 'The redirect URL to add in your {provider} application configurations'
};
const textPlaceholder = {
id: getTrad('PopUpForm.Providers.key.placeholder'),
defaultMessage: 'TEXT'
};
const secretLabel = {
id: getTrad('PopUpForm.Providers.secret.label'),
defaultMessage: 'Client Secret'
};
const CALLBACK_REGEX = /^$|^[a-z][a-z0-9+.-]*:\/\/[^\s/$.?#](?:[^\s]*[^\s/$.?#])?$/i;
const SUBDOMAIN_REGEX = /^(([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+)(:\d+)?(\/\S*)?$/i;
const forms = {
email: {
form: [
[
{
intlLabel: enabledLabel,
name: 'enabled',
type: 'bool',
description: enabledDescription,
size: 6
}
]
],
schema: yup.object().shape({
enabled: yup.bool().required(translatedErrors.required.id)
})
},
providers: {
form: [
[
{
intlLabel: enabledLabel,
name: 'enabled',
type: 'bool',
description: enabledDescription,
size: 6,
validations: {
required: true
}
}
],
[
{
intlLabel: keyLabel,
name: 'key',
type: 'text',
placeholder: textPlaceholder,
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: secretLabel,
name: 'secret',
type: 'text',
placeholder: textPlaceholder,
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: callbackLabel,
placeholder: callbackPlaceholder,
name: 'callback',
type: 'text',
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: hintLabel,
name: 'noName',
type: 'text',
validations: {},
size: 12,
disabled: true
}
]
],
schema: yup.object().shape({
enabled: yup.bool().required(translatedErrors.required.id),
key: yup.string().when('enabled', {
is: true,
then: yup.string().required(translatedErrors.required.id),
otherwise: yup.string()
}),
secret: yup.string().when('enabled', {
is: true,
then: yup.string().required(translatedErrors.required.id),
otherwise: yup.string()
}),
callback: yup.string().when('enabled', {
is: true,
then: yup.string().matches(CALLBACK_REGEX, translatedErrors.regex.id).required(translatedErrors.required.id),
otherwise: yup.string()
})
})
},
providersWithSubdomain: {
form: [
[
{
intlLabel: enabledLabel,
name: 'enabled',
type: 'bool',
description: enabledDescription,
size: 6,
validations: {
required: true
}
}
],
[
{
intlLabel: keyLabel,
name: 'key',
type: 'text',
placeholder: textPlaceholder,
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: secretLabel,
name: 'secret',
type: 'text',
placeholder: textPlaceholder,
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: {
id: getTrad({
id: 'PopUpForm.Providers.jwksurl.label'
}),
defaultMessage: 'JWKS URL'
},
name: 'jwksurl',
type: 'text',
placeholder: textPlaceholder,
size: 12,
validations: {
required: false
}
}
],
[
{
intlLabel: {
id: getTrad('PopUpForm.Providers.subdomain.label'),
defaultMessage: 'Host URI (Subdomain)'
},
name: 'subdomain',
type: 'text',
placeholder: {
id: getTrad('PopUpForm.Providers.subdomain.placeholder'),
defaultMessage: 'my.subdomain.com'
},
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: callbackLabel,
placeholder: callbackPlaceholder,
name: 'callback',
type: 'text',
size: 12,
validations: {
required: true
}
}
],
[
{
intlLabel: hintLabel,
name: 'noName',
type: 'text',
validations: {},
size: 12,
disabled: true
}
]
],
schema: yup.object().shape({
enabled: yup.bool().required(translatedErrors.required.id),
key: yup.string().when('enabled', {
is: true,
then: yup.string().required(translatedErrors.required.id),
otherwise: yup.string()
}),
secret: yup.string().when('enabled', {
is: true,
then: yup.string().required(translatedErrors.required.id),
otherwise: yup.string()
}),
subdomain: yup.string().when('enabled', {
is: true,
then: yup.string().matches(SUBDOMAIN_REGEX, translatedErrors.regex.id).required(translatedErrors.required.id),
otherwise: yup.string()
}),
callback: yup.string().when('enabled', {
is: true,
then: yup.string().matches(CALLBACK_REGEX, translatedErrors.regex.id).required(translatedErrors.required.id),
otherwise: yup.string()
})
})
}
};
export { forms as default };
//# sourceMappingURL=forms.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"forms.mjs","sources":["../../../../../admin/src/pages/Providers/utils/forms.js"],"sourcesContent":["import { translatedErrors } from '@strapi/strapi/admin';\nimport * as yup from 'yup';\n\nimport { getTrad } from '../../../utils';\n\nconst callbackLabel = {\n id: getTrad('PopUpForm.Providers.redirectURL.front-end.label'),\n defaultMessage: 'The redirect URL to your front-end app',\n};\nconst callbackPlaceholder = {\n id: 'http://www.client-app.com',\n defaultMessage: 'http://www.client-app.com',\n};\nconst enabledDescription = {\n id: getTrad('PopUpForm.Providers.enabled.description'),\n defaultMessage: \"If disabled, users won't be able to use this provider.\",\n};\nconst enabledLabel = {\n id: getTrad('PopUpForm.Providers.enabled.label'),\n defaultMessage: 'Enable',\n};\nconst keyLabel = { id: getTrad('PopUpForm.Providers.key.label'), defaultMessage: 'Client ID' };\nconst hintLabel = {\n id: getTrad('PopUpForm.Providers.redirectURL.label'),\n defaultMessage: 'The redirect URL to add in your {provider} application configurations',\n};\nconst textPlaceholder = {\n id: getTrad('PopUpForm.Providers.key.placeholder'),\n defaultMessage: 'TEXT',\n};\n\nconst secretLabel = {\n id: getTrad('PopUpForm.Providers.secret.label'),\n defaultMessage: 'Client Secret',\n};\n\nconst CALLBACK_REGEX = /^$|^[a-z][a-z0-9+.-]*:\\/\\/[^\\s/$.?#](?:[^\\s]*[^\\s/$.?#])?$/i;\nconst SUBDOMAIN_REGEX = /^(([a-zA-Z0-9-]+\\.)*[a-zA-Z0-9-]+)(:\\d+)?(\\/\\S*)?$/i;\n\nconst forms = {\n email: {\n form: [\n [\n {\n intlLabel: enabledLabel,\n name: 'enabled',\n type: 'bool',\n description: enabledDescription,\n size: 6,\n // TODO check if still needed\n // validations: {\n // required: true,\n // },\n },\n ],\n ],\n schema: yup.object().shape({\n enabled: yup.bool().required(translatedErrors.required.id),\n }),\n },\n providers: {\n form: [\n [\n {\n intlLabel: enabledLabel,\n name: 'enabled',\n type: 'bool',\n description: enabledDescription,\n size: 6,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: keyLabel,\n name: 'key',\n type: 'text',\n placeholder: textPlaceholder,\n size: 12,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: secretLabel,\n name: 'secret',\n type: 'text',\n placeholder: textPlaceholder,\n size: 12,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: callbackLabel,\n placeholder: callbackPlaceholder,\n name: 'callback',\n type: 'text',\n size: 12,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: hintLabel,\n name: 'noName',\n type: 'text',\n validations: {},\n size: 12,\n disabled: true,\n },\n ],\n ],\n schema: yup.object().shape({\n enabled: yup.bool().required(translatedErrors.required.id),\n key: yup.string().when('enabled', {\n is: true,\n then: yup.string().required(translatedErrors.required.id),\n otherwise: yup.string(),\n }),\n secret: yup.string().when('enabled', {\n is: true,\n then: yup.string().required(translatedErrors.required.id),\n otherwise: yup.string(),\n }),\n callback: yup.string().when('enabled', {\n is: true,\n then: yup\n .string()\n .matches(CALLBACK_REGEX, translatedErrors.regex.id)\n .required(translatedErrors.required.id),\n otherwise: yup.string(),\n }),\n }),\n },\n providersWithSubdomain: {\n form: [\n [\n {\n intlLabel: enabledLabel,\n name: 'enabled',\n type: 'bool',\n description: enabledDescription,\n size: 6,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: keyLabel,\n name: 'key',\n type: 'text',\n placeholder: textPlaceholder,\n size: 12,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: secretLabel,\n name: 'secret',\n type: 'text',\n placeholder: textPlaceholder,\n size: 12,\n validations: {\n required: true,\n },\n },\n ],\n [\n {\n intlLabel: {\n id: getTrad({ id: 'PopUpForm.Providers.jwksurl.label' }),\n defaultMessage: 'JWKS URL',\n },\n namLine truncated
@@ -0,0 +1,31 @@
'use strict';
var admin = require('@strapi/strapi/admin');
var yup = require('yup');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var yup__namespace = /*#__PURE__*/_interopNamespaceDefault(yup);
const createRoleSchema = yup__namespace.object().shape({
name: yup__namespace.string().required(admin.translatedErrors.required.id),
description: yup__namespace.string().required(admin.translatedErrors.required.id)
});
exports.createRoleSchema = createRoleSchema;
//# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
{"version":3,"file":"constants.js","sources":["../../../../admin/src/pages/Roles/constants.js"],"sourcesContent":["import { translatedErrors } from '@strapi/strapi/admin';\nimport * as yup from 'yup';\n\nexport const createRoleSchema = yup.object().shape({\n name: yup.string().required(translatedErrors.required.id),\n description: yup.string().required(translatedErrors.required.id),\n});\n"],"names":["createRoleSchema","yup","object","shape","name","string","required","translatedErrors","id","description"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;MAGaA,gBAAmBC,GAAAA,cAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;IACjDC,IAAMH,EAAAA,cAAAA,CAAII,MAAM,EAAGC,CAAAA,QAAQ,CAACC,sBAAiBD,CAAAA,QAAQ,CAACE,EAAE,CAAA;IACxDC,WAAaR,EAAAA,cAAAA,CAAII,MAAM,EAAGC,CAAAA,QAAQ,CAACC,sBAAiBD,CAAAA,QAAQ,CAACE,EAAE;AACjE,CAAG;;;;"}
@@ -0,0 +1,10 @@
import { translatedErrors } from '@strapi/strapi/admin';
import * as yup from 'yup';
const createRoleSchema = yup.object().shape({
name: yup.string().required(translatedErrors.required.id),
description: yup.string().required(translatedErrors.required.id)
});
export { createRoleSchema };
//# sourceMappingURL=constants.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"constants.mjs","sources":["../../../../admin/src/pages/Roles/constants.js"],"sourcesContent":["import { translatedErrors } from '@strapi/strapi/admin';\nimport * as yup from 'yup';\n\nexport const createRoleSchema = yup.object().shape({\n name: yup.string().required(translatedErrors.required.id),\n description: yup.string().required(translatedErrors.required.id),\n});\n"],"names":["createRoleSchema","yup","object","shape","name","string","required","translatedErrors","id","description"],"mappings":";;;MAGaA,gBAAmBC,GAAAA,GAAAA,CAAIC,MAAM,EAAA,CAAGC,KAAK,CAAC;IACjDC,IAAMH,EAAAA,GAAAA,CAAII,MAAM,EAAGC,CAAAA,QAAQ,CAACC,gBAAiBD,CAAAA,QAAQ,CAACE,EAAE,CAAA;IACxDC,WAAaR,EAAAA,GAAAA,CAAII,MAAM,EAAGC,CAAAA,QAAQ,CAACC,gBAAiBD,CAAAA,QAAQ,CAACE,EAAE;AACjE,CAAG;;;;"}
@@ -0,0 +1,78 @@
'use strict';
var React = require('react');
var admin = require('@strapi/strapi/admin');
var reactQuery = require('react-query');
var cleanPermissions = require('../../../utils/cleanPermissions.js');
var getTrad = require('../../../utils/getTrad.js');
const usePlugins = ()=>{
const { toggleNotification } = admin.useNotification();
const { get } = admin.useFetchClient();
const { formatAPIError } = admin.useAPIErrorHandler(getTrad);
const [{ data: permissions, isLoading: isLoadingPermissions, error: permissionsError, refetch: refetchPermissions }, { data: routes, isLoading: isLoadingRoutes, error: routesError, refetch: refetchRoutes }] = reactQuery.useQueries([
{
queryKey: [
'users-permissions',
'permissions'
],
async queryFn () {
const { data: { permissions } } = await get(`/users-permissions/permissions`);
return permissions;
}
},
{
queryKey: [
'users-permissions',
'routes'
],
async queryFn () {
const { data: { routes } } = await get(`/users-permissions/routes`);
return routes;
}
}
]);
const refetchQueries = async ()=>{
await Promise.all([
refetchPermissions(),
refetchRoutes()
]);
};
React.useEffect(()=>{
if (permissionsError) {
toggleNotification({
type: 'danger',
message: formatAPIError(permissionsError)
});
}
}, [
toggleNotification,
permissionsError,
formatAPIError
]);
React.useEffect(()=>{
if (routesError) {
toggleNotification({
type: 'danger',
message: formatAPIError(routesError)
});
}
}, [
toggleNotification,
routesError,
formatAPIError
]);
const isLoading = isLoadingPermissions || isLoadingRoutes;
return {
// TODO: these return values need to be memoized, otherwise
// they will create infinite rendering loops when used as
// effect dependencies
permissions: permissions ? cleanPermissions(permissions) : {},
routes: routes ?? {},
getData: refetchQueries,
isLoading
};
};
exports.usePlugins = usePlugins;
//# sourceMappingURL=usePlugins.js.map
@@ -0,0 +1 @@
{"version":3,"file":"usePlugins.js","sources":["../../../../../admin/src/pages/Roles/hooks/usePlugins.js"],"sourcesContent":["import { useEffect } from 'react';\n\nimport { useAPIErrorHandler, useNotification, useFetchClient } from '@strapi/strapi/admin';\nimport { useQueries } from 'react-query';\n\nimport { cleanPermissions, getTrad } from '../../../utils';\n\nexport const usePlugins = () => {\n const { toggleNotification } = useNotification();\n const { get } = useFetchClient();\n const { formatAPIError } = useAPIErrorHandler(getTrad);\n\n const [\n {\n data: permissions,\n isLoading: isLoadingPermissions,\n error: permissionsError,\n refetch: refetchPermissions,\n },\n { data: routes, isLoading: isLoadingRoutes, error: routesError, refetch: refetchRoutes },\n ] = useQueries([\n {\n queryKey: ['users-permissions', 'permissions'],\n async queryFn() {\n const {\n data: { permissions },\n } = await get(`/users-permissions/permissions`);\n\n return permissions;\n },\n },\n {\n queryKey: ['users-permissions', 'routes'],\n async queryFn() {\n const {\n data: { routes },\n } = await get(`/users-permissions/routes`);\n\n return routes;\n },\n },\n ]);\n\n const refetchQueries = async () => {\n await Promise.all([refetchPermissions(), refetchRoutes()]);\n };\n\n useEffect(() => {\n if (permissionsError) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(permissionsError),\n });\n }\n }, [toggleNotification, permissionsError, formatAPIError]);\n\n useEffect(() => {\n if (routesError) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(routesError),\n });\n }\n }, [toggleNotification, routesError, formatAPIError]);\n\n const isLoading = isLoadingPermissions || isLoadingRoutes;\n\n return {\n // TODO: these return values need to be memoized, otherwise\n // they will create infinite rendering loops when used as\n // effect dependencies\n permissions: permissions ? cleanPermissions(permissions) : {},\n routes: routes ?? {},\n\n getData: refetchQueries,\n isLoading,\n };\n};\n"],"names":["usePlugins","toggleNotification","useNotification","get","useFetchClient","formatAPIError","useAPIErrorHandler","getTrad","data","permissions","isLoading","isLoadingPermissions","error","permissionsError","refetch","refetchPermissions","routes","isLoadingRoutes","routesError","refetchRoutes","useQueries","queryKey","queryFn","refetchQueries","Promise","all","useEffect","type","message","cleanPermissions","getData"],"mappings":";;;;;;;;MAOaA,UAAa,GAAA,IAAA;IACxB,MAAM,EAAEC,kBAAkB,EAAE,GAAGC,qBAAAA,EAAAA;IAC/B,MAAM,EAAEC,GAAG,EAAE,GAAGC,oBAAAA,EAAAA;AAChB,IAAA,MAAM,EAAEC,cAAc,EAAE,GAAGC,wBAAmBC,CAAAA,OAAAA,CAAAA;AAE9C,IAAA,MAAM,CACJ,EACEC,IAAMC,EAAAA,WAAW,EACjBC,SAAAA,EAAWC,oBAAoB,EAC/BC,KAAOC,EAAAA,gBAAgB,EACvBC,OAAAA,EAASC,kBAAkB,EAC5B,EACD,EAAEP,IAAAA,EAAMQ,MAAM,EAAEN,SAAWO,EAAAA,eAAe,EAAEL,KAAAA,EAAOM,WAAW,EAAEJ,OAASK,EAAAA,aAAa,EAAE,CACzF,GAAGC,qBAAW,CAAA;AACb,QAAA;YACEC,QAAU,EAAA;AAAC,gBAAA,mBAAA;AAAqB,gBAAA;AAAc,aAAA;YAC9C,MAAMC,OAAAA,CAAAA,GAAAA;gBACJ,MAAM,EACJd,IAAM,EAAA,EAAEC,WAAW,EAAE,EACtB,GAAG,MAAMN,GAAAA,CAAI,CAAC,8BAA8B,CAAC,CAAA;gBAE9C,OAAOM,WAAAA;AACT;AACF,SAAA;AACA,QAAA;YACEY,QAAU,EAAA;AAAC,gBAAA,mBAAA;AAAqB,gBAAA;AAAS,aAAA;YACzC,MAAMC,OAAAA,CAAAA,GAAAA;gBACJ,MAAM,EACJd,IAAM,EAAA,EAAEQ,MAAM,EAAE,EACjB,GAAG,MAAMb,GAAAA,CAAI,CAAC,yBAAyB,CAAC,CAAA;gBAEzC,OAAOa,MAAAA;AACT;AACF;AACD,KAAA,CAAA;AAED,IAAA,MAAMO,cAAiB,GAAA,UAAA;QACrB,MAAMC,OAAAA,CAAQC,GAAG,CAAC;AAACV,YAAAA,kBAAAA,EAAAA;AAAsBI,YAAAA,aAAAA;AAAgB,SAAA,CAAA;AAC3D,KAAA;IAEAO,eAAU,CAAA,IAAA;AACR,QAAA,IAAIb,gBAAkB,EAAA;YACpBZ,kBAAmB,CAAA;gBACjB0B,IAAM,EAAA,QAAA;AACNC,gBAAAA,OAAAA,EAASvB,cAAeQ,CAAAA,gBAAAA;AAC1B,aAAA,CAAA;AACF;KACC,EAAA;AAACZ,QAAAA,kBAAAA;AAAoBY,QAAAA,gBAAAA;AAAkBR,QAAAA;AAAe,KAAA,CAAA;IAEzDqB,eAAU,CAAA,IAAA;AACR,QAAA,IAAIR,WAAa,EAAA;YACfjB,kBAAmB,CAAA;gBACjB0B,IAAM,EAAA,QAAA;AACNC,gBAAAA,OAAAA,EAASvB,cAAea,CAAAA,WAAAA;AAC1B,aAAA,CAAA;AACF;KACC,EAAA;AAACjB,QAAAA,kBAAAA;AAAoBiB,QAAAA,WAAAA;AAAab,QAAAA;AAAe,KAAA,CAAA;AAEpD,IAAA,MAAMK,YAAYC,oBAAwBM,IAAAA,eAAAA;IAE1C,OAAO;;;;QAILR,WAAaA,EAAAA,WAAAA,GAAcoB,gBAAiBpB,CAAAA,WAAAA,CAAAA,GAAe,EAAC;AAC5DO,QAAAA,MAAAA,EAAQA,UAAU,EAAC;QAEnBc,OAASP,EAAAA,cAAAA;AACTb,QAAAA;AACF,KAAA;AACF;;;;"}
@@ -0,0 +1,76 @@
import { useEffect } from 'react';
import { useNotification, useFetchClient, useAPIErrorHandler } from '@strapi/strapi/admin';
import { useQueries } from 'react-query';
import cleanPermissions from '../../../utils/cleanPermissions.mjs';
import getTrad from '../../../utils/getTrad.mjs';
const usePlugins = ()=>{
const { toggleNotification } = useNotification();
const { get } = useFetchClient();
const { formatAPIError } = useAPIErrorHandler(getTrad);
const [{ data: permissions, isLoading: isLoadingPermissions, error: permissionsError, refetch: refetchPermissions }, { data: routes, isLoading: isLoadingRoutes, error: routesError, refetch: refetchRoutes }] = useQueries([
{
queryKey: [
'users-permissions',
'permissions'
],
async queryFn () {
const { data: { permissions } } = await get(`/users-permissions/permissions`);
return permissions;
}
},
{
queryKey: [
'users-permissions',
'routes'
],
async queryFn () {
const { data: { routes } } = await get(`/users-permissions/routes`);
return routes;
}
}
]);
const refetchQueries = async ()=>{
await Promise.all([
refetchPermissions(),
refetchRoutes()
]);
};
useEffect(()=>{
if (permissionsError) {
toggleNotification({
type: 'danger',
message: formatAPIError(permissionsError)
});
}
}, [
toggleNotification,
permissionsError,
formatAPIError
]);
useEffect(()=>{
if (routesError) {
toggleNotification({
type: 'danger',
message: formatAPIError(routesError)
});
}
}, [
toggleNotification,
routesError,
formatAPIError
]);
const isLoading = isLoadingPermissions || isLoadingRoutes;
return {
// TODO: these return values need to be memoized, otherwise
// they will create infinite rendering loops when used as
// effect dependencies
permissions: permissions ? cleanPermissions(permissions) : {},
routes: routes ?? {},
getData: refetchQueries,
isLoading
};
};
export { usePlugins };
//# sourceMappingURL=usePlugins.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"usePlugins.mjs","sources":["../../../../../admin/src/pages/Roles/hooks/usePlugins.js"],"sourcesContent":["import { useEffect } from 'react';\n\nimport { useAPIErrorHandler, useNotification, useFetchClient } from '@strapi/strapi/admin';\nimport { useQueries } from 'react-query';\n\nimport { cleanPermissions, getTrad } from '../../../utils';\n\nexport const usePlugins = () => {\n const { toggleNotification } = useNotification();\n const { get } = useFetchClient();\n const { formatAPIError } = useAPIErrorHandler(getTrad);\n\n const [\n {\n data: permissions,\n isLoading: isLoadingPermissions,\n error: permissionsError,\n refetch: refetchPermissions,\n },\n { data: routes, isLoading: isLoadingRoutes, error: routesError, refetch: refetchRoutes },\n ] = useQueries([\n {\n queryKey: ['users-permissions', 'permissions'],\n async queryFn() {\n const {\n data: { permissions },\n } = await get(`/users-permissions/permissions`);\n\n return permissions;\n },\n },\n {\n queryKey: ['users-permissions', 'routes'],\n async queryFn() {\n const {\n data: { routes },\n } = await get(`/users-permissions/routes`);\n\n return routes;\n },\n },\n ]);\n\n const refetchQueries = async () => {\n await Promise.all([refetchPermissions(), refetchRoutes()]);\n };\n\n useEffect(() => {\n if (permissionsError) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(permissionsError),\n });\n }\n }, [toggleNotification, permissionsError, formatAPIError]);\n\n useEffect(() => {\n if (routesError) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(routesError),\n });\n }\n }, [toggleNotification, routesError, formatAPIError]);\n\n const isLoading = isLoadingPermissions || isLoadingRoutes;\n\n return {\n // TODO: these return values need to be memoized, otherwise\n // they will create infinite rendering loops when used as\n // effect dependencies\n permissions: permissions ? cleanPermissions(permissions) : {},\n routes: routes ?? {},\n\n getData: refetchQueries,\n isLoading,\n };\n};\n"],"names":["usePlugins","toggleNotification","useNotification","get","useFetchClient","formatAPIError","useAPIErrorHandler","getTrad","data","permissions","isLoading","isLoadingPermissions","error","permissionsError","refetch","refetchPermissions","routes","isLoadingRoutes","routesError","refetchRoutes","useQueries","queryKey","queryFn","refetchQueries","Promise","all","useEffect","type","message","cleanPermissions","getData"],"mappings":";;;;;;MAOaA,UAAa,GAAA,IAAA;IACxB,MAAM,EAAEC,kBAAkB,EAAE,GAAGC,eAAAA,EAAAA;IAC/B,MAAM,EAAEC,GAAG,EAAE,GAAGC,cAAAA,EAAAA;AAChB,IAAA,MAAM,EAAEC,cAAc,EAAE,GAAGC,kBAAmBC,CAAAA,OAAAA,CAAAA;AAE9C,IAAA,MAAM,CACJ,EACEC,IAAMC,EAAAA,WAAW,EACjBC,SAAAA,EAAWC,oBAAoB,EAC/BC,KAAOC,EAAAA,gBAAgB,EACvBC,OAAAA,EAASC,kBAAkB,EAC5B,EACD,EAAEP,IAAAA,EAAMQ,MAAM,EAAEN,SAAWO,EAAAA,eAAe,EAAEL,KAAAA,EAAOM,WAAW,EAAEJ,OAASK,EAAAA,aAAa,EAAE,CACzF,GAAGC,UAAW,CAAA;AACb,QAAA;YACEC,QAAU,EAAA;AAAC,gBAAA,mBAAA;AAAqB,gBAAA;AAAc,aAAA;YAC9C,MAAMC,OAAAA,CAAAA,GAAAA;gBACJ,MAAM,EACJd,IAAM,EAAA,EAAEC,WAAW,EAAE,EACtB,GAAG,MAAMN,GAAAA,CAAI,CAAC,8BAA8B,CAAC,CAAA;gBAE9C,OAAOM,WAAAA;AACT;AACF,SAAA;AACA,QAAA;YACEY,QAAU,EAAA;AAAC,gBAAA,mBAAA;AAAqB,gBAAA;AAAS,aAAA;YACzC,MAAMC,OAAAA,CAAAA,GAAAA;gBACJ,MAAM,EACJd,IAAM,EAAA,EAAEQ,MAAM,EAAE,EACjB,GAAG,MAAMb,GAAAA,CAAI,CAAC,yBAAyB,CAAC,CAAA;gBAEzC,OAAOa,MAAAA;AACT;AACF;AACD,KAAA,CAAA;AAED,IAAA,MAAMO,cAAiB,GAAA,UAAA;QACrB,MAAMC,OAAAA,CAAQC,GAAG,CAAC;AAACV,YAAAA,kBAAAA,EAAAA;AAAsBI,YAAAA,aAAAA;AAAgB,SAAA,CAAA;AAC3D,KAAA;IAEAO,SAAU,CAAA,IAAA;AACR,QAAA,IAAIb,gBAAkB,EAAA;YACpBZ,kBAAmB,CAAA;gBACjB0B,IAAM,EAAA,QAAA;AACNC,gBAAAA,OAAAA,EAASvB,cAAeQ,CAAAA,gBAAAA;AAC1B,aAAA,CAAA;AACF;KACC,EAAA;AAACZ,QAAAA,kBAAAA;AAAoBY,QAAAA,gBAAAA;AAAkBR,QAAAA;AAAe,KAAA,CAAA;IAEzDqB,SAAU,CAAA,IAAA;AACR,QAAA,IAAIR,WAAa,EAAA;YACfjB,kBAAmB,CAAA;gBACjB0B,IAAM,EAAA,QAAA;AACNC,gBAAAA,OAAAA,EAASvB,cAAea,CAAAA,WAAAA;AAC1B,aAAA,CAAA;AACF;KACC,EAAA;AAACjB,QAAAA,kBAAAA;AAAoBiB,QAAAA,WAAAA;AAAab,QAAAA;AAAe,KAAA,CAAA;AAEpD,IAAA,MAAMK,YAAYC,oBAAwBM,IAAAA,eAAAA;IAE1C,OAAO;;;;QAILR,WAAaA,EAAAA,WAAAA,GAAcoB,gBAAiBpB,CAAAA,WAAAA,CAAAA,GAAe,EAAC;AAC5DO,QAAAA,MAAAA,EAAQA,UAAU,EAAC;QAEnBc,OAASP,EAAAA,cAAAA;AACTb,QAAAA;AACF,KAAA;AACF;;;;"}
@@ -0,0 +1,35 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
require('react');
var admin = require('@strapi/strapi/admin');
var reactRouterDom = require('react-router-dom');
var constants = require('../../constants.js');
var CreatePage = require('./pages/CreatePage.js');
var EditPage = require('./pages/EditPage.js');
var index = require('./pages/ListPage/index.js');
const Roles = ()=>{
return /*#__PURE__*/ jsxRuntime.jsx(admin.Page.Protect, {
permissions: constants.PERMISSIONS.accessRoles,
children: /*#__PURE__*/ jsxRuntime.jsxs(reactRouterDom.Routes, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.Route, {
index: true,
element: /*#__PURE__*/ jsxRuntime.jsx(index.ProtectedRolesListPage, {})
}),
/*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.Route, {
path: "new",
element: /*#__PURE__*/ jsxRuntime.jsx(CreatePage.ProtectedRolesCreatePage, {})
}),
/*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.Route, {
path: ":id",
element: /*#__PURE__*/ jsxRuntime.jsx(EditPage.ProtectedRolesEditPage, {})
})
]
})
});
};
module.exports = Roles;
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":["../../../../admin/src/pages/Roles/index.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Page } from '@strapi/strapi/admin';\nimport { Route, Routes } from 'react-router-dom';\n\nimport { PERMISSIONS } from '../../constants';\n\nimport { ProtectedRolesCreatePage } from './pages/CreatePage';\nimport { ProtectedRolesEditPage } from './pages/EditPage';\nimport { ProtectedRolesListPage } from './pages/ListPage';\n\nconst Roles = () => {\n return (\n <Page.Protect permissions={PERMISSIONS.accessRoles}>\n <Routes>\n <Route index element={<ProtectedRolesListPage />} />\n <Route path=\"new\" element={<ProtectedRolesCreatePage />} />\n <Route path=\":id\" element={<ProtectedRolesEditPage />} />\n </Routes>\n </Page.Protect>\n );\n};\n\nexport default Roles;\n"],"names":["Roles","_jsx","Page","Protect","permissions","PERMISSIONS","accessRoles","_jsxs","Routes","Route","index","element","ProtectedRolesListPage","path","ProtectedRolesCreatePage","ProtectedRolesEditPage"],"mappings":";;;;;;;;;;;AAWA,MAAMA,KAAQ,GAAA,IAAA;IACZ,qBACEC,cAAA,CAACC,WAAKC,OAAO,EAAA;AAACC,QAAAA,WAAAA,EAAaC,sBAAYC,WAAW;AAChD,QAAA,QAAA,gBAAAC,eAACC,CAAAA,qBAAAA,EAAAA;;8BACCP,cAACQ,CAAAA,oBAAAA,EAAAA;oBAAMC,KAAK,EAAA,IAAA;AAACC,oBAAAA,OAAAA,gBAASV,cAACW,CAAAA,4BAAAA,EAAAA,EAAAA;;8BACvBX,cAACQ,CAAAA,oBAAAA,EAAAA;oBAAMI,IAAK,EAAA,KAAA;AAAMF,oBAAAA,OAAAA,gBAASV,cAACa,CAAAA,mCAAAA,EAAAA,EAAAA;;8BAC5Bb,cAACQ,CAAAA,oBAAAA,EAAAA;oBAAMI,IAAK,EAAA,KAAA;AAAMF,oBAAAA,OAAAA,gBAASV,cAACc,CAAAA,+BAAAA,EAAAA,EAAAA;;;;;AAIpC;;;;"}
@@ -0,0 +1,33 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import 'react';
import { Page } from '@strapi/strapi/admin';
import { Routes, Route } from 'react-router-dom';
import { PERMISSIONS } from '../../constants.mjs';
import { ProtectedRolesCreatePage } from './pages/CreatePage.mjs';
import { ProtectedRolesEditPage } from './pages/EditPage.mjs';
import { ProtectedRolesListPage } from './pages/ListPage/index.mjs';
const Roles = ()=>{
return /*#__PURE__*/ jsx(Page.Protect, {
permissions: PERMISSIONS.accessRoles,
children: /*#__PURE__*/ jsxs(Routes, {
children: [
/*#__PURE__*/ jsx(Route, {
index: true,
element: /*#__PURE__*/ jsx(ProtectedRolesListPage, {})
}),
/*#__PURE__*/ jsx(Route, {
path: "new",
element: /*#__PURE__*/ jsx(ProtectedRolesCreatePage, {})
}),
/*#__PURE__*/ jsx(Route, {
path: ":id",
element: /*#__PURE__*/ jsx(ProtectedRolesEditPage, {})
})
]
})
});
};
export { Roles as default };
//# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":["../../../../admin/src/pages/Roles/index.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Page } from '@strapi/strapi/admin';\nimport { Route, Routes } from 'react-router-dom';\n\nimport { PERMISSIONS } from '../../constants';\n\nimport { ProtectedRolesCreatePage } from './pages/CreatePage';\nimport { ProtectedRolesEditPage } from './pages/EditPage';\nimport { ProtectedRolesListPage } from './pages/ListPage';\n\nconst Roles = () => {\n return (\n <Page.Protect permissions={PERMISSIONS.accessRoles}>\n <Routes>\n <Route index element={<ProtectedRolesListPage />} />\n <Route path=\"new\" element={<ProtectedRolesCreatePage />} />\n <Route path=\":id\" element={<ProtectedRolesEditPage />} />\n </Routes>\n </Page.Protect>\n );\n};\n\nexport default Roles;\n"],"names":["Roles","_jsx","Page","Protect","permissions","PERMISSIONS","accessRoles","_jsxs","Routes","Route","index","element","ProtectedRolesListPage","path","ProtectedRolesCreatePage","ProtectedRolesEditPage"],"mappings":";;;;;;;;;AAWA,MAAMA,KAAQ,GAAA,IAAA;IACZ,qBACEC,GAAA,CAACC,KAAKC,OAAO,EAAA;AAACC,QAAAA,WAAAA,EAAaC,YAAYC,WAAW;AAChD,QAAA,QAAA,gBAAAC,IAACC,CAAAA,MAAAA,EAAAA;;8BACCP,GAACQ,CAAAA,KAAAA,EAAAA;oBAAMC,KAAK,EAAA,IAAA;AAACC,oBAAAA,OAAAA,gBAASV,GAACW,CAAAA,sBAAAA,EAAAA,EAAAA;;8BACvBX,GAACQ,CAAAA,KAAAA,EAAAA;oBAAMI,IAAK,EAAA,KAAA;AAAMF,oBAAAA,OAAAA,gBAASV,GAACa,CAAAA,wBAAAA,EAAAA,EAAAA;;8BAC5Bb,GAACQ,CAAAA,KAAAA,EAAAA;oBAAMI,IAAK,EAAA,KAAA;AAAMF,oBAAAA,OAAAA,gBAASV,GAACc,CAAAA,sBAAAA,EAAAA,EAAAA;;;;;AAIpC;;;;"}
@@ -0,0 +1,225 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var admin = require('@strapi/strapi/admin');
var formik = require('formik');
var reactIntl = require('react-intl');
var reactQuery = require('react-query');
var reactRouterDom = require('react-router-dom');
var index = require('../../../components/UsersPermissions/index.js');
var constants = require('../../../constants.js');
var getTrad = require('../../../utils/getTrad.js');
var constants$1 = require('../constants.js');
var usePlugins = require('../hooks/usePlugins.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const CreatePage = ()=>{
const { formatMessage } = reactIntl.useIntl();
const { toggleNotification } = admin.useNotification();
const navigate = reactRouterDom.useNavigate();
const { isLoading: isLoadingPlugins, permissions, routes } = usePlugins.usePlugins();
const { trackUsage } = admin.useTracking();
const permissionsRef = React__namespace.useRef();
const { post } = admin.useFetchClient();
const mutation = reactQuery.useMutation((body)=>post(`/users-permissions/roles`, body), {
onError () {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occurred'
})
});
},
onSuccess () {
trackUsage('didCreateRole');
toggleNotification({
type: 'success',
message: formatMessage({
id: getTrad('Settings.roles.created'),
defaultMessage: 'Role created'
})
});
// Forcing redirecting since we don't have the id in the response
navigate(-1);
}
});
const handleCreateRoleSubmit = async (data)=>{
// TODO: refactor. Child -> parent component communication is evil;
// We should either move the provider one level up or move the state
// straight into redux.
const permissions = permissionsRef.current.getPermissions();
await mutation.mutate({
...data,
...permissions,
users: []
});
};
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Main, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(admin.Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: 'Roles'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(formik.Formik, {
enableReinitialize: true,
initialValues: {
name: '',
description: ''
},
onSubmit: handleCreateRoleSubmit,
validationSchema: constants$1.createRoleSchema,
children: ({ handleSubmit, values, handleChange, errors })=>/*#__PURE__*/ jsxRuntime.jsxs(formik.Form, {
noValidate: true,
onSubmit: handleSubmit,
children: [
/*#__PURE__*/ jsxRuntime.jsx(admin.Layouts.Header, {
primaryAction: !isLoadingPlugins && /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
type: "submit",
loading: mutation.isLoading,
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Check, {}),
children: formatMessage({
id: 'global.save',
defaultMessage: 'Save'
})
}),
title: formatMessage({
id: 'Settings.roles.create.title',
defaultMessage: 'Create a role'
}),
subtitle: formatMessage({
id: 'Settings.roles.create.description',
defaultMessage: 'Define the rights given to the role'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(admin.Layouts.Content, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
background: "neutral0",
direction: "column",
alignItems: "stretch",
gap: 7,
hasRadius: true,
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 7,
paddingRight: 7,
shadow: "filterShadow",
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
direction: "column",
alignItems: "stretch",
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "delta",
tag: "h2",
children: formatMessage({
id: getTrad('EditPage.form.roles'),
defaultMessage: 'Role details'
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Grid.Root, {
gap: 4,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Item, {
col: 6,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
name: "name",
error: errors?.name ? formatMessage({
id: errors.name,
defaultMessage: 'Name is required'
}) : false,
required: true,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
children: formatMessage({
id: 'global.name',
defaultMessage: 'Name'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.TextInput, {
value: values.name || '',
onChange: handleChange
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Item, {
col: 6,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
name: "description",
error: errors?.description ? formatMessage({
id: errors.description,
defaultMessage: 'Description is required'
}) : false,
required: true,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
children: formatMessage({
id: 'global.description',
defaultMessage: 'Description'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Textarea, {
value: values.description || '',
onChange: handleChange
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
})
})
]
})
]
}),
!isLoadingPlugins && /*#__PURE__*/ jsxRuntime.jsx(index, {
ref: permissionsRef,
permissions: permissions,
routes: routes
})
]
})
})
]
})
})
]
});
};
const ProtectedRolesCreatePage = ()=>/*#__PURE__*/ jsxRuntime.jsx(admin.Page.Protect, {
permissions: constants.PERMISSIONS.createRole,
children: /*#__PURE__*/ jsxRuntime.jsx(CreatePage, {})
});
exports.CreatePage = CreatePage;
exports.ProtectedRolesCreatePage = ProtectedRolesCreatePage;
//# sourceMappingURL=CreatePage.js.map
@@ -0,0 +1 @@
{"version":3,"file":"CreatePage.js","sources":["../../../../../admin/src/pages/Roles/pages/CreatePage.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Button,\n Flex,\n Grid,\n Main,\n Textarea,\n TextInput,\n Typography,\n Field,\n} from '@strapi/design-system';\nimport { Check } from '@strapi/icons';\nimport { Page, useTracking, useNotification, useFetchClient, Layouts } from '@strapi/strapi/admin';\nimport { Formik, Form } from 'formik';\nimport { useIntl } from 'react-intl';\nimport { useMutation } from 'react-query';\nimport { useNavigate } from 'react-router-dom';\n\nimport UsersPermissions from '../../../components/UsersPermissions';\nimport { PERMISSIONS } from '../../../constants';\nimport getTrad from '../../../utils/getTrad';\nimport { createRoleSchema } from '../constants';\nimport { usePlugins } from '../hooks/usePlugins';\n\nexport const CreatePage = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const navigate = useNavigate();\n const { isLoading: isLoadingPlugins, permissions, routes } = usePlugins();\n const { trackUsage } = useTracking();\n const permissionsRef = React.useRef();\n const { post } = useFetchClient();\n const mutation = useMutation((body) => post(`/users-permissions/roles`, body), {\n onError() {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: 'notification.error',\n defaultMessage: 'An error occurred',\n }),\n });\n },\n\n onSuccess() {\n trackUsage('didCreateRole');\n\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTrad('Settings.roles.created'),\n defaultMessage: 'Role created',\n }),\n });\n\n // Forcing redirecting since we don't have the id in the response\n navigate(-1);\n },\n });\n\n const handleCreateRoleSubmit = async (data) => {\n // TODO: refactor. Child -> parent component communication is evil;\n // We should either move the provider one level up or move the state\n // straight into redux.\n const permissions = permissionsRef.current.getPermissions();\n\n await mutation.mutate({ ...data, ...permissions, users: [] });\n };\n\n return (\n <Main>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n { name: 'Roles' }\n )}\n </Page.Title>\n <Formik\n enableReinitialize\n initialValues={{ name: '', description: '' }}\n onSubmit={handleCreateRoleSubmit}\n validationSchema={createRoleSchema}\n >\n {({ handleSubmit, values, handleChange, errors }) => (\n <Form noValidate onSubmit={handleSubmit}>\n <Layouts.Header\n primaryAction={\n !isLoadingPlugins && (\n <Button type=\"submit\" loading={mutation.isLoading} startIcon={<Check />}>\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n )\n }\n title={formatMessage({\n id: 'Settings.roles.create.title',\n defaultMessage: 'Create a role',\n })}\n subtitle={formatMessage({\n id: 'Settings.roles.create.description',\n defaultMessage: 'Define the rights given to the role',\n })}\n />\n <Layouts.Content>\n <Flex\n background=\"neutral0\"\n direction=\"column\"\n alignItems=\"stretch\"\n gap={7}\n hasRadius\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n shadow=\"filterShadow\"\n >\n <Flex direction=\"column\" alignItems=\"stretch\">\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTrad('EditPage.form.roles'),\n defaultMessage: 'Role details',\n })}\n </Typography>\n\n <Grid.Root gap={4}>\n <Grid.Item col={6} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n name=\"name\"\n error={\n errors?.name\n ? formatMessage({ id: errors.name, defaultMessage: 'Name is required' })\n : false\n }\n required\n >\n <Field.Label>\n {formatMessage({\n id: 'global.name',\n Line truncated
@@ -0,0 +1,203 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import * as React from 'react';
import { Main, Button, Flex, Typography, Grid, Field, TextInput, Textarea } from '@strapi/design-system';
import { Check } from '@strapi/icons';
import { Page, useNotification, useTracking, useFetchClient, Layouts } from '@strapi/strapi/admin';
import { Formik, Form } from 'formik';
import { useIntl } from 'react-intl';
import { useMutation } from 'react-query';
import { useNavigate } from 'react-router-dom';
import UsersPermissions from '../../../components/UsersPermissions/index.mjs';
import { PERMISSIONS } from '../../../constants.mjs';
import getTrad from '../../../utils/getTrad.mjs';
import { createRoleSchema } from '../constants.mjs';
import { usePlugins } from '../hooks/usePlugins.mjs';
const CreatePage = ()=>{
const { formatMessage } = useIntl();
const { toggleNotification } = useNotification();
const navigate = useNavigate();
const { isLoading: isLoadingPlugins, permissions, routes } = usePlugins();
const { trackUsage } = useTracking();
const permissionsRef = React.useRef();
const { post } = useFetchClient();
const mutation = useMutation((body)=>post(`/users-permissions/roles`, body), {
onError () {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occurred'
})
});
},
onSuccess () {
trackUsage('didCreateRole');
toggleNotification({
type: 'success',
message: formatMessage({
id: getTrad('Settings.roles.created'),
defaultMessage: 'Role created'
})
});
// Forcing redirecting since we don't have the id in the response
navigate(-1);
}
});
const handleCreateRoleSubmit = async (data)=>{
// TODO: refactor. Child -> parent component communication is evil;
// We should either move the provider one level up or move the state
// straight into redux.
const permissions = permissionsRef.current.getPermissions();
await mutation.mutate({
...data,
...permissions,
users: []
});
};
return /*#__PURE__*/ jsxs(Main, {
children: [
/*#__PURE__*/ jsx(Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: 'Roles'
})
}),
/*#__PURE__*/ jsx(Formik, {
enableReinitialize: true,
initialValues: {
name: '',
description: ''
},
onSubmit: handleCreateRoleSubmit,
validationSchema: createRoleSchema,
children: ({ handleSubmit, values, handleChange, errors })=>/*#__PURE__*/ jsxs(Form, {
noValidate: true,
onSubmit: handleSubmit,
children: [
/*#__PURE__*/ jsx(Layouts.Header, {
primaryAction: !isLoadingPlugins && /*#__PURE__*/ jsx(Button, {
type: "submit",
loading: mutation.isLoading,
startIcon: /*#__PURE__*/ jsx(Check, {}),
children: formatMessage({
id: 'global.save',
defaultMessage: 'Save'
})
}),
title: formatMessage({
id: 'Settings.roles.create.title',
defaultMessage: 'Create a role'
}),
subtitle: formatMessage({
id: 'Settings.roles.create.description',
defaultMessage: 'Define the rights given to the role'
})
}),
/*#__PURE__*/ jsx(Layouts.Content, {
children: /*#__PURE__*/ jsxs(Flex, {
background: "neutral0",
direction: "column",
alignItems: "stretch",
gap: 7,
hasRadius: true,
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 7,
paddingRight: 7,
shadow: "filterShadow",
children: [
/*#__PURE__*/ jsxs(Flex, {
direction: "column",
alignItems: "stretch",
children: [
/*#__PURE__*/ jsx(Typography, {
variant: "delta",
tag: "h2",
children: formatMessage({
id: getTrad('EditPage.form.roles'),
defaultMessage: 'Role details'
})
}),
/*#__PURE__*/ jsxs(Grid.Root, {
gap: 4,
children: [
/*#__PURE__*/ jsx(Grid.Item, {
col: 6,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxs(Field.Root, {
name: "name",
error: errors?.name ? formatMessage({
id: errors.name,
defaultMessage: 'Name is required'
}) : false,
required: true,
children: [
/*#__PURE__*/ jsx(Field.Label, {
children: formatMessage({
id: 'global.name',
defaultMessage: 'Name'
})
}),
/*#__PURE__*/ jsx(TextInput, {
value: values.name || '',
onChange: handleChange
}),
/*#__PURE__*/ jsx(Field.Error, {})
]
})
}),
/*#__PURE__*/ jsx(Grid.Item, {
col: 6,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxs(Field.Root, {
name: "description",
error: errors?.description ? formatMessage({
id: errors.description,
defaultMessage: 'Description is required'
}) : false,
required: true,
children: [
/*#__PURE__*/ jsx(Field.Label, {
children: formatMessage({
id: 'global.description',
defaultMessage: 'Description'
})
}),
/*#__PURE__*/ jsx(Textarea, {
value: values.description || '',
onChange: handleChange
}),
/*#__PURE__*/ jsx(Field.Error, {})
]
})
})
]
})
]
}),
!isLoadingPlugins && /*#__PURE__*/ jsx(UsersPermissions, {
ref: permissionsRef,
permissions: permissions,
routes: routes
})
]
})
})
]
})
})
]
});
};
const ProtectedRolesCreatePage = ()=>/*#__PURE__*/ jsx(Page.Protect, {
permissions: PERMISSIONS.createRole,
children: /*#__PURE__*/ jsx(CreatePage, {})
});
export { CreatePage, ProtectedRolesCreatePage };
//# sourceMappingURL=CreatePage.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"CreatePage.mjs","sources":["../../../../../admin/src/pages/Roles/pages/CreatePage.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Button,\n Flex,\n Grid,\n Main,\n Textarea,\n TextInput,\n Typography,\n Field,\n} from '@strapi/design-system';\nimport { Check } from '@strapi/icons';\nimport { Page, useTracking, useNotification, useFetchClient, Layouts } from '@strapi/strapi/admin';\nimport { Formik, Form } from 'formik';\nimport { useIntl } from 'react-intl';\nimport { useMutation } from 'react-query';\nimport { useNavigate } from 'react-router-dom';\n\nimport UsersPermissions from '../../../components/UsersPermissions';\nimport { PERMISSIONS } from '../../../constants';\nimport getTrad from '../../../utils/getTrad';\nimport { createRoleSchema } from '../constants';\nimport { usePlugins } from '../hooks/usePlugins';\n\nexport const CreatePage = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const navigate = useNavigate();\n const { isLoading: isLoadingPlugins, permissions, routes } = usePlugins();\n const { trackUsage } = useTracking();\n const permissionsRef = React.useRef();\n const { post } = useFetchClient();\n const mutation = useMutation((body) => post(`/users-permissions/roles`, body), {\n onError() {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: 'notification.error',\n defaultMessage: 'An error occurred',\n }),\n });\n },\n\n onSuccess() {\n trackUsage('didCreateRole');\n\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTrad('Settings.roles.created'),\n defaultMessage: 'Role created',\n }),\n });\n\n // Forcing redirecting since we don't have the id in the response\n navigate(-1);\n },\n });\n\n const handleCreateRoleSubmit = async (data) => {\n // TODO: refactor. Child -> parent component communication is evil;\n // We should either move the provider one level up or move the state\n // straight into redux.\n const permissions = permissionsRef.current.getPermissions();\n\n await mutation.mutate({ ...data, ...permissions, users: [] });\n };\n\n return (\n <Main>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n { name: 'Roles' }\n )}\n </Page.Title>\n <Formik\n enableReinitialize\n initialValues={{ name: '', description: '' }}\n onSubmit={handleCreateRoleSubmit}\n validationSchema={createRoleSchema}\n >\n {({ handleSubmit, values, handleChange, errors }) => (\n <Form noValidate onSubmit={handleSubmit}>\n <Layouts.Header\n primaryAction={\n !isLoadingPlugins && (\n <Button type=\"submit\" loading={mutation.isLoading} startIcon={<Check />}>\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n )\n }\n title={formatMessage({\n id: 'Settings.roles.create.title',\n defaultMessage: 'Create a role',\n })}\n subtitle={formatMessage({\n id: 'Settings.roles.create.description',\n defaultMessage: 'Define the rights given to the role',\n })}\n />\n <Layouts.Content>\n <Flex\n background=\"neutral0\"\n direction=\"column\"\n alignItems=\"stretch\"\n gap={7}\n hasRadius\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n shadow=\"filterShadow\"\n >\n <Flex direction=\"column\" alignItems=\"stretch\">\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTrad('EditPage.form.roles'),\n defaultMessage: 'Role details',\n })}\n </Typography>\n\n <Grid.Root gap={4}>\n <Grid.Item col={6} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n name=\"name\"\n error={\n errors?.name\n ? formatMessage({ id: errors.name, defaultMessage: 'Name is required' })\n : false\n }\n required\n >\n <Field.Label>\n {formatMessage({\n id: 'global.name',\n Line truncated
@@ -0,0 +1,229 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var admin = require('@strapi/strapi/admin');
var formik = require('formik');
var reactIntl = require('react-intl');
var reactQuery = require('react-query');
var reactRouterDom = require('react-router-dom');
var index = require('../../../components/UsersPermissions/index.js');
var constants = require('../../../constants.js');
var getTrad = require('../../../utils/getTrad.js');
var constants$1 = require('../constants.js');
var usePlugins = require('../hooks/usePlugins.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
const EditPage = ()=>{
const { formatMessage } = reactIntl.useIntl();
const { toggleNotification } = admin.useNotification();
const { params: { id } } = reactRouterDom.useMatch(`/settings/users-permissions/roles/:id`);
const { get } = admin.useFetchClient();
const { isLoading: isLoadingPlugins, routes } = usePlugins.usePlugins();
const { data: role, isLoading: isLoadingRole, refetch: refetchRole } = reactQuery.useQuery([
'users-permissions',
'role',
id
], async ()=>{
// TODO: why doesn't this endpoint follow the admin API conventions?
const { data: { role } } = await get(`/users-permissions/roles/${id}`);
return role;
});
const permissionsRef = React__namespace.useRef();
const { put } = admin.useFetchClient();
const { formatAPIError } = admin.useAPIErrorHandler();
const mutation = reactQuery.useMutation((body)=>put(`/users-permissions/roles/${id}`, body), {
onError (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
},
async onSuccess () {
toggleNotification({
type: 'success',
message: formatMessage({
id: getTrad('Settings.roles.created'),
defaultMessage: 'Role edited'
})
});
await refetchRole();
}
});
const handleEditRoleSubmit = async (data)=>{
const permissions = permissionsRef.current.getPermissions();
await mutation.mutate({
...data,
...permissions,
users: []
});
};
if (isLoadingRole) {
return /*#__PURE__*/ jsxRuntime.jsx(admin.Page.Loading, {});
}
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Main, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(admin.Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: 'Roles'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(formik.Formik, {
enableReinitialize: true,
initialValues: {
name: role.name,
description: role.description
},
onSubmit: handleEditRoleSubmit,
validationSchema: constants$1.createRoleSchema,
children: ({ handleSubmit, values, handleChange, errors })=>/*#__PURE__*/ jsxRuntime.jsxs(formik.Form, {
noValidate: true,
onSubmit: handleSubmit,
children: [
/*#__PURE__*/ jsxRuntime.jsx(admin.Layouts.Header, {
primaryAction: !isLoadingPlugins ? /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
disabled: role.code === 'strapi-super-admin',
type: "submit",
loading: mutation.isLoading,
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Check, {}),
children: formatMessage({
id: 'global.save',
defaultMessage: 'Save'
})
}) : null,
title: role.name,
subtitle: role.description,
navigationAction: /*#__PURE__*/ jsxRuntime.jsx(admin.BackButton, {
fallback: ".."
})
}),
/*#__PURE__*/ jsxRuntime.jsx(admin.Layouts.Content, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
background: "neutral0",
direction: "column",
alignItems: "stretch",
gap: 7,
hasRadius: true,
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 7,
paddingRight: 7,
shadow: "filterShadow",
children: [
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
direction: "column",
alignItems: "stretch",
gap: 4,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "delta",
tag: "h2",
children: formatMessage({
id: getTrad('EditPage.form.roles'),
defaultMessage: 'Role details'
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Grid.Root, {
gap: 4,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Item, {
col: 6,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
name: "name",
error: errors?.name ? formatMessage({
id: errors.name,
defaultMessage: 'Name is required'
}) : false,
required: true,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
children: formatMessage({
id: 'global.name',
defaultMessage: 'Name'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.TextInput, {
value: values.name || '',
onChange: handleChange
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Item, {
col: 6,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Field.Root, {
name: "description",
error: errors?.description ? formatMessage({
id: errors.description,
defaultMessage: 'Description is required'
}) : false,
required: true,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Label, {
children: formatMessage({
id: 'global.description',
defaultMessage: 'Description'
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Textarea, {
value: values.description || '',
onChange: handleChange
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Field.Error, {})
]
})
})
]
})
]
}),
!isLoadingPlugins && /*#__PURE__*/ jsxRuntime.jsx(index, {
ref: permissionsRef,
permissions: role.permissions,
routes: routes
})
]
})
})
]
})
})
]
});
};
const ProtectedRolesEditPage = ()=>/*#__PURE__*/ jsxRuntime.jsx(admin.Page.Protect, {
permissions: constants.PERMISSIONS.updateRole,
children: /*#__PURE__*/ jsxRuntime.jsx(EditPage, {})
});
exports.EditPage = EditPage;
exports.ProtectedRolesEditPage = ProtectedRolesEditPage;
//# sourceMappingURL=EditPage.js.map
@@ -0,0 +1 @@
{"version":3,"file":"EditPage.js","sources":["../../../../../admin/src/pages/Roles/pages/EditPage.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Main,\n Button,\n Flex,\n TextInput,\n Textarea,\n Typography,\n Grid,\n Field,\n} from '@strapi/design-system';\nimport { Check } from '@strapi/icons';\nimport {\n Page,\n BackButton,\n useAPIErrorHandler,\n useNotification,\n useFetchClient,\n Layouts,\n} from '@strapi/strapi/admin';\nimport { Formik, Form } from 'formik';\nimport { useIntl } from 'react-intl';\nimport { useQuery, useMutation } from 'react-query';\nimport { useMatch } from 'react-router-dom';\n\nimport UsersPermissions from '../../../components/UsersPermissions';\nimport { PERMISSIONS } from '../../../constants';\nimport getTrad from '../../../utils/getTrad';\nimport { createRoleSchema } from '../constants';\nimport { usePlugins } from '../hooks/usePlugins';\n\nexport const EditPage = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const {\n params: { id },\n } = useMatch(`/settings/users-permissions/roles/:id`);\n const { get } = useFetchClient();\n const { isLoading: isLoadingPlugins, routes } = usePlugins();\n const {\n data: role,\n isLoading: isLoadingRole,\n refetch: refetchRole,\n } = useQuery(['users-permissions', 'role', id], async () => {\n // TODO: why doesn't this endpoint follow the admin API conventions?\n const {\n data: { role },\n } = await get(`/users-permissions/roles/${id}`);\n\n return role;\n });\n\n const permissionsRef = React.useRef();\n const { put } = useFetchClient();\n const { formatAPIError } = useAPIErrorHandler();\n const mutation = useMutation((body) => put(`/users-permissions/roles/${id}`, body), {\n onError(error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n },\n\n async onSuccess() {\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTrad('Settings.roles.created'),\n defaultMessage: 'Role edited',\n }),\n });\n\n await refetchRole();\n },\n });\n\n const handleEditRoleSubmit = async (data) => {\n const permissions = permissionsRef.current.getPermissions();\n\n await mutation.mutate({ ...data, ...permissions, users: [] });\n };\n\n if (isLoadingRole) {\n return <Page.Loading />;\n }\n\n return (\n <Main>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n { name: 'Roles' }\n )}\n </Page.Title>\n <Formik\n enableReinitialize\n initialValues={{ name: role.name, description: role.description }}\n onSubmit={handleEditRoleSubmit}\n validationSchema={createRoleSchema}\n >\n {({ handleSubmit, values, handleChange, errors }) => (\n <Form noValidate onSubmit={handleSubmit}>\n <Layouts.Header\n primaryAction={\n !isLoadingPlugins ? (\n <Button\n disabled={role.code === 'strapi-super-admin'}\n type=\"submit\"\n loading={mutation.isLoading}\n startIcon={<Check />}\n >\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n ) : null\n }\n title={role.name}\n subtitle={role.description}\n navigationAction={<BackButton fallback=\"..\" />}\n />\n <Layouts.Content>\n <Flex\n background=\"neutral0\"\n direction=\"column\"\n alignItems=\"stretch\"\n gap={7}\n hasRadius\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n shadow=\"filterShadow\"\n >\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTrad('EditPage.form.roles'),\n defaultMessage: 'Role details',\n })}\n </Typography>\n\n <Grid.Root gap={4}>\n <Grid.Item col={6} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n name=\"name\"\n error={\n errors?.name\n ? formatMessage({\n id: errors.name,\n defaultMessage: 'Name is required',\n })\n Line truncated
@@ -0,0 +1,207 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import * as React from 'react';
import { Main, Button, Flex, Typography, Grid, Field, TextInput, Textarea } from '@strapi/design-system';
import { Check } from '@strapi/icons';
import { Page, useNotification, useFetchClient, useAPIErrorHandler, Layouts, BackButton } from '@strapi/strapi/admin';
import { Formik, Form } from 'formik';
import { useIntl } from 'react-intl';
import { useQuery, useMutation } from 'react-query';
import { useMatch } from 'react-router-dom';
import UsersPermissions from '../../../components/UsersPermissions/index.mjs';
import { PERMISSIONS } from '../../../constants.mjs';
import getTrad from '../../../utils/getTrad.mjs';
import { createRoleSchema } from '../constants.mjs';
import { usePlugins } from '../hooks/usePlugins.mjs';
const EditPage = ()=>{
const { formatMessage } = useIntl();
const { toggleNotification } = useNotification();
const { params: { id } } = useMatch(`/settings/users-permissions/roles/:id`);
const { get } = useFetchClient();
const { isLoading: isLoadingPlugins, routes } = usePlugins();
const { data: role, isLoading: isLoadingRole, refetch: refetchRole } = useQuery([
'users-permissions',
'role',
id
], async ()=>{
// TODO: why doesn't this endpoint follow the admin API conventions?
const { data: { role } } = await get(`/users-permissions/roles/${id}`);
return role;
});
const permissionsRef = React.useRef();
const { put } = useFetchClient();
const { formatAPIError } = useAPIErrorHandler();
const mutation = useMutation((body)=>put(`/users-permissions/roles/${id}`, body), {
onError (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
},
async onSuccess () {
toggleNotification({
type: 'success',
message: formatMessage({
id: getTrad('Settings.roles.created'),
defaultMessage: 'Role edited'
})
});
await refetchRole();
}
});
const handleEditRoleSubmit = async (data)=>{
const permissions = permissionsRef.current.getPermissions();
await mutation.mutate({
...data,
...permissions,
users: []
});
};
if (isLoadingRole) {
return /*#__PURE__*/ jsx(Page.Loading, {});
}
return /*#__PURE__*/ jsxs(Main, {
children: [
/*#__PURE__*/ jsx(Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: 'Roles'
})
}),
/*#__PURE__*/ jsx(Formik, {
enableReinitialize: true,
initialValues: {
name: role.name,
description: role.description
},
onSubmit: handleEditRoleSubmit,
validationSchema: createRoleSchema,
children: ({ handleSubmit, values, handleChange, errors })=>/*#__PURE__*/ jsxs(Form, {
noValidate: true,
onSubmit: handleSubmit,
children: [
/*#__PURE__*/ jsx(Layouts.Header, {
primaryAction: !isLoadingPlugins ? /*#__PURE__*/ jsx(Button, {
disabled: role.code === 'strapi-super-admin',
type: "submit",
loading: mutation.isLoading,
startIcon: /*#__PURE__*/ jsx(Check, {}),
children: formatMessage({
id: 'global.save',
defaultMessage: 'Save'
})
}) : null,
title: role.name,
subtitle: role.description,
navigationAction: /*#__PURE__*/ jsx(BackButton, {
fallback: ".."
})
}),
/*#__PURE__*/ jsx(Layouts.Content, {
children: /*#__PURE__*/ jsxs(Flex, {
background: "neutral0",
direction: "column",
alignItems: "stretch",
gap: 7,
hasRadius: true,
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 7,
paddingRight: 7,
shadow: "filterShadow",
children: [
/*#__PURE__*/ jsxs(Flex, {
direction: "column",
alignItems: "stretch",
gap: 4,
children: [
/*#__PURE__*/ jsx(Typography, {
variant: "delta",
tag: "h2",
children: formatMessage({
id: getTrad('EditPage.form.roles'),
defaultMessage: 'Role details'
})
}),
/*#__PURE__*/ jsxs(Grid.Root, {
gap: 4,
children: [
/*#__PURE__*/ jsx(Grid.Item, {
col: 6,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxs(Field.Root, {
name: "name",
error: errors?.name ? formatMessage({
id: errors.name,
defaultMessage: 'Name is required'
}) : false,
required: true,
children: [
/*#__PURE__*/ jsx(Field.Label, {
children: formatMessage({
id: 'global.name',
defaultMessage: 'Name'
})
}),
/*#__PURE__*/ jsx(TextInput, {
value: values.name || '',
onChange: handleChange
}),
/*#__PURE__*/ jsx(Field.Error, {})
]
})
}),
/*#__PURE__*/ jsx(Grid.Item, {
col: 6,
direction: "column",
alignItems: "stretch",
children: /*#__PURE__*/ jsxs(Field.Root, {
name: "description",
error: errors?.description ? formatMessage({
id: errors.description,
defaultMessage: 'Description is required'
}) : false,
required: true,
children: [
/*#__PURE__*/ jsx(Field.Label, {
children: formatMessage({
id: 'global.description',
defaultMessage: 'Description'
})
}),
/*#__PURE__*/ jsx(Textarea, {
value: values.description || '',
onChange: handleChange
}),
/*#__PURE__*/ jsx(Field.Error, {})
]
})
})
]
})
]
}),
!isLoadingPlugins && /*#__PURE__*/ jsx(UsersPermissions, {
ref: permissionsRef,
permissions: role.permissions,
routes: routes
})
]
})
})
]
})
})
]
});
};
const ProtectedRolesEditPage = ()=>/*#__PURE__*/ jsx(Page.Protect, {
permissions: PERMISSIONS.updateRole,
children: /*#__PURE__*/ jsx(EditPage, {})
});
export { EditPage, ProtectedRolesEditPage };
//# sourceMappingURL=EditPage.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"EditPage.mjs","sources":["../../../../../admin/src/pages/Roles/pages/EditPage.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Main,\n Button,\n Flex,\n TextInput,\n Textarea,\n Typography,\n Grid,\n Field,\n} from '@strapi/design-system';\nimport { Check } from '@strapi/icons';\nimport {\n Page,\n BackButton,\n useAPIErrorHandler,\n useNotification,\n useFetchClient,\n Layouts,\n} from '@strapi/strapi/admin';\nimport { Formik, Form } from 'formik';\nimport { useIntl } from 'react-intl';\nimport { useQuery, useMutation } from 'react-query';\nimport { useMatch } from 'react-router-dom';\n\nimport UsersPermissions from '../../../components/UsersPermissions';\nimport { PERMISSIONS } from '../../../constants';\nimport getTrad from '../../../utils/getTrad';\nimport { createRoleSchema } from '../constants';\nimport { usePlugins } from '../hooks/usePlugins';\n\nexport const EditPage = () => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const {\n params: { id },\n } = useMatch(`/settings/users-permissions/roles/:id`);\n const { get } = useFetchClient();\n const { isLoading: isLoadingPlugins, routes } = usePlugins();\n const {\n data: role,\n isLoading: isLoadingRole,\n refetch: refetchRole,\n } = useQuery(['users-permissions', 'role', id], async () => {\n // TODO: why doesn't this endpoint follow the admin API conventions?\n const {\n data: { role },\n } = await get(`/users-permissions/roles/${id}`);\n\n return role;\n });\n\n const permissionsRef = React.useRef();\n const { put } = useFetchClient();\n const { formatAPIError } = useAPIErrorHandler();\n const mutation = useMutation((body) => put(`/users-permissions/roles/${id}`, body), {\n onError(error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n },\n\n async onSuccess() {\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTrad('Settings.roles.created'),\n defaultMessage: 'Role edited',\n }),\n });\n\n await refetchRole();\n },\n });\n\n const handleEditRoleSubmit = async (data) => {\n const permissions = permissionsRef.current.getPermissions();\n\n await mutation.mutate({ ...data, ...permissions, users: [] });\n };\n\n if (isLoadingRole) {\n return <Page.Loading />;\n }\n\n return (\n <Main>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n { name: 'Roles' }\n )}\n </Page.Title>\n <Formik\n enableReinitialize\n initialValues={{ name: role.name, description: role.description }}\n onSubmit={handleEditRoleSubmit}\n validationSchema={createRoleSchema}\n >\n {({ handleSubmit, values, handleChange, errors }) => (\n <Form noValidate onSubmit={handleSubmit}>\n <Layouts.Header\n primaryAction={\n !isLoadingPlugins ? (\n <Button\n disabled={role.code === 'strapi-super-admin'}\n type=\"submit\"\n loading={mutation.isLoading}\n startIcon={<Check />}\n >\n {formatMessage({\n id: 'global.save',\n defaultMessage: 'Save',\n })}\n </Button>\n ) : null\n }\n title={role.name}\n subtitle={role.description}\n navigationAction={<BackButton fallback=\"..\" />}\n />\n <Layouts.Content>\n <Flex\n background=\"neutral0\"\n direction=\"column\"\n alignItems=\"stretch\"\n gap={7}\n hasRadius\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n shadow=\"filterShadow\"\n >\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: getTrad('EditPage.form.roles'),\n defaultMessage: 'Role details',\n })}\n </Typography>\n\n <Grid.Root gap={4}>\n <Grid.Item col={6} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n name=\"name\"\n error={\n errors?.name\n ? formatMessage({\n id: errors.name,\n defaultMessage: 'Name is required',\n })\n Line truncated
@@ -0,0 +1,125 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var PropTypes = require('prop-types');
var reactIntl = require('react-intl');
var reactRouterDom = require('react-router-dom');
var styledComponents = require('styled-components');
const EditLink = styledComponents.styled(designSystem.Link)`
align-items: center;
height: 3.2rem;
width: 3.2rem;
display: flex;
justify-content: center;
padding: ${({ theme })=>`${theme.spaces[2]}`};
svg {
height: 1.6rem;
width: 1.6rem;
path {
fill: ${({ theme })=>theme.colors.neutral500};
}
}
&:hover,
&:focus {
svg {
path {
fill: ${({ theme })=>theme.colors.neutral800};
}
}
}
`;
const TableBody = ({ sortedRoles, canDelete, canUpdate, setRoleToDelete, onDelete })=>{
const { formatMessage } = reactIntl.useIntl();
const navigate = reactRouterDom.useNavigate();
const [showConfirmDelete, setShowConfirmDelete] = onDelete;
const checkCanDeleteRole = (role)=>canDelete && ![
'public',
'authenticated'
].includes(role.type);
const handleClickDelete = (id)=>{
setRoleToDelete(id);
setShowConfirmDelete(!showConfirmDelete);
};
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Tbody, {
children: sortedRoles?.map((role)=>/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tr, {
cursor: "pointer",
onClick: ()=>navigate(role.id.toString()),
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
width: "20%",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
children: role.name
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
width: "50%",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
children: role.description
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
width: "30%",
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
children: formatMessage({
id: 'Roles.RoleRow.user-count',
defaultMessage: '{number, plural, =0 {# user} one {# user} other {# users}}'
}, {
number: role.nb_users
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Td, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
justifyContent: "end",
onClick: (e)=>e.stopPropagation(),
children: [
canUpdate ? /*#__PURE__*/ jsxRuntime.jsx(EditLink, {
tag: reactRouterDom.NavLink,
to: role.id.toString(),
"aria-label": formatMessage({
id: 'app.component.table.edit',
defaultMessage: 'Edit {target}'
}, {
target: `${role.name}`
}),
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Pencil, {})
}) : null,
checkCanDeleteRole(role) && /*#__PURE__*/ jsxRuntime.jsx(designSystem.IconButton, {
onClick: ()=>handleClickDelete(role.id.toString()),
variant: "ghost",
label: formatMessage({
id: 'global.delete-target',
defaultMessage: 'Delete {target}'
}, {
target: `${role.name}`
}),
children: /*#__PURE__*/ jsxRuntime.jsx(icons.Trash, {})
})
]
})
})
]
}, role.name))
});
};
TableBody.defaultProps = {
canDelete: false,
canUpdate: false
};
TableBody.propTypes = {
onDelete: PropTypes.array.isRequired,
setRoleToDelete: PropTypes.func.isRequired,
sortedRoles: PropTypes.array.isRequired,
canDelete: PropTypes.bool,
canUpdate: PropTypes.bool
};
module.exports = TableBody;
//# sourceMappingURL=TableBody.js.map
@@ -0,0 +1 @@
{"version":3,"file":"TableBody.js","sources":["../../../../../../../admin/src/pages/Roles/pages/ListPage/components/TableBody.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Flex, IconButton, Link, Tbody, Td, Tr, Typography } from '@strapi/design-system';\nimport { Pencil, Trash } from '@strapi/icons';\nimport PropTypes from 'prop-types';\nimport { useIntl } from 'react-intl';\nimport { useNavigate, NavLink } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nconst EditLink = styled(Link)`\n align-items: center;\n height: 3.2rem;\n width: 3.2rem;\n display: flex;\n justify-content: center;\n padding: ${({ theme }) => `${theme.spaces[2]}`};\n\n svg {\n height: 1.6rem;\n width: 1.6rem;\n\n path {\n fill: ${({ theme }) => theme.colors.neutral500};\n }\n }\n\n &:hover,\n &:focus {\n svg {\n path {\n fill: ${({ theme }) => theme.colors.neutral800};\n }\n }\n }\n`;\n\nconst TableBody = ({ sortedRoles, canDelete, canUpdate, setRoleToDelete, onDelete }) => {\n const { formatMessage } = useIntl();\n const navigate = useNavigate();\n const [showConfirmDelete, setShowConfirmDelete] = onDelete;\n\n const checkCanDeleteRole = (role) =>\n canDelete && !['public', 'authenticated'].includes(role.type);\n\n const handleClickDelete = (id) => {\n setRoleToDelete(id);\n setShowConfirmDelete(!showConfirmDelete);\n };\n\n return (\n <Tbody>\n {sortedRoles?.map((role) => (\n <Tr cursor=\"pointer\" key={role.name} onClick={() => navigate(role.id.toString())}>\n <Td width=\"20%\">\n <Typography>{role.name}</Typography>\n </Td>\n <Td width=\"50%\">\n <Typography>{role.description}</Typography>\n </Td>\n <Td width=\"30%\">\n <Typography>\n {formatMessage(\n {\n id: 'Roles.RoleRow.user-count',\n defaultMessage: '{number, plural, =0 {# user} one {# user} other {# users}}',\n },\n { number: role.nb_users }\n )}\n </Typography>\n </Td>\n <Td>\n <Flex justifyContent=\"end\" onClick={(e) => e.stopPropagation()}>\n {canUpdate ? (\n <EditLink\n tag={NavLink}\n to={role.id.toString()}\n aria-label={formatMessage(\n { id: 'app.component.table.edit', defaultMessage: 'Edit {target}' },\n { target: `${role.name}` }\n )}\n >\n <Pencil />\n </EditLink>\n ) : null}\n\n {checkCanDeleteRole(role) && (\n <IconButton\n onClick={() => handleClickDelete(role.id.toString())}\n variant=\"ghost\"\n label={formatMessage(\n { id: 'global.delete-target', defaultMessage: 'Delete {target}' },\n { target: `${role.name}` }\n )}\n >\n <Trash />\n </IconButton>\n )}\n </Flex>\n </Td>\n </Tr>\n ))}\n </Tbody>\n );\n};\n\nexport default TableBody;\n\nTableBody.defaultProps = {\n canDelete: false,\n canUpdate: false,\n};\n\nTableBody.propTypes = {\n onDelete: PropTypes.array.isRequired,\n setRoleToDelete: PropTypes.func.isRequired,\n sortedRoles: PropTypes.array.isRequired,\n canDelete: PropTypes.bool,\n canUpdate: PropTypes.bool,\n};\n"],"names":["EditLink","styled","Link","theme","spaces","colors","neutral500","neutral800","TableBody","sortedRoles","canDelete","canUpdate","setRoleToDelete","onDelete","formatMessage","useIntl","navigate","useNavigate","showConfirmDelete","setShowConfirmDelete","checkCanDeleteRole","role","includes","type","handleClickDelete","id","_jsx","Tbody","map","_jsxs","Tr","cursor","onClick","toString","Td","width","Typography","name","description","defaultMessage","number","nb_users","Flex","justifyContent","e","stopPropagation","tag","NavLink","to","aria-label","target","Pencil","IconButton","variant","label","Trash","defaultProps","propTypes","PropTypes","array","isRequired","func","bool"],"mappings":";;;;;;;;;;;AASA,MAAMA,QAAAA,GAAWC,uBAAOC,CAAAA,iBAAAA,CAAK;;;;;;AAMlB,WAAA,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAK,CAAC,EAAEA,KAAAA,CAAMC,MAAM,CAAC,CAAE,CAAA,CAAC,CAAC,CAAC;;;;;;;YAOrC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAME,CAAAA,MAAM,CAACC,UAAU,CAAC;;;;;;;;cAQvC,EAAE,CAAC,EAAEH,KAAK,EAAE,GAAKA,KAAME,CAAAA,MAAM,CAACE,UAAU,CAAC;;;;AAIvD,CAAC;AAED,MAAMC,SAAY,GAAA,CAAC,EAAEC,WAAW,EAAEC,SAAS,EAAEC,SAAS,EAAEC,eAAe,EAAEC,QAAQ,EAAE,GAAA;IACjF,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAWC,GAAAA,0BAAAA,EAAAA;IACjB,MAAM,CAACC,iBAAmBC,EAAAA,oBAAAA,CAAqB,GAAGN,QAAAA;AAElD,IAAA,MAAMO,kBAAqB,GAAA,CAACC,IAC1BX,GAAAA,SAAAA,IAAa,CAAC;AAAC,YAAA,QAAA;AAAU,YAAA;SAAgB,CAACY,QAAQ,CAACD,IAAAA,CAALine truncated
@@ -0,0 +1,123 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import 'react';
import { Link, Tbody, Tr, Td, Typography, Flex, IconButton } from '@strapi/design-system';
import { Pencil, Trash } from '@strapi/icons';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import { useNavigate, NavLink } from 'react-router-dom';
import { styled } from 'styled-components';
const EditLink = styled(Link)`
align-items: center;
height: 3.2rem;
width: 3.2rem;
display: flex;
justify-content: center;
padding: ${({ theme })=>`${theme.spaces[2]}`};
svg {
height: 1.6rem;
width: 1.6rem;
path {
fill: ${({ theme })=>theme.colors.neutral500};
}
}
&:hover,
&:focus {
svg {
path {
fill: ${({ theme })=>theme.colors.neutral800};
}
}
}
`;
const TableBody = ({ sortedRoles, canDelete, canUpdate, setRoleToDelete, onDelete })=>{
const { formatMessage } = useIntl();
const navigate = useNavigate();
const [showConfirmDelete, setShowConfirmDelete] = onDelete;
const checkCanDeleteRole = (role)=>canDelete && ![
'public',
'authenticated'
].includes(role.type);
const handleClickDelete = (id)=>{
setRoleToDelete(id);
setShowConfirmDelete(!showConfirmDelete);
};
return /*#__PURE__*/ jsx(Tbody, {
children: sortedRoles?.map((role)=>/*#__PURE__*/ jsxs(Tr, {
cursor: "pointer",
onClick: ()=>navigate(role.id.toString()),
children: [
/*#__PURE__*/ jsx(Td, {
width: "20%",
children: /*#__PURE__*/ jsx(Typography, {
children: role.name
})
}),
/*#__PURE__*/ jsx(Td, {
width: "50%",
children: /*#__PURE__*/ jsx(Typography, {
children: role.description
})
}),
/*#__PURE__*/ jsx(Td, {
width: "30%",
children: /*#__PURE__*/ jsx(Typography, {
children: formatMessage({
id: 'Roles.RoleRow.user-count',
defaultMessage: '{number, plural, =0 {# user} one {# user} other {# users}}'
}, {
number: role.nb_users
})
})
}),
/*#__PURE__*/ jsx(Td, {
children: /*#__PURE__*/ jsxs(Flex, {
justifyContent: "end",
onClick: (e)=>e.stopPropagation(),
children: [
canUpdate ? /*#__PURE__*/ jsx(EditLink, {
tag: NavLink,
to: role.id.toString(),
"aria-label": formatMessage({
id: 'app.component.table.edit',
defaultMessage: 'Edit {target}'
}, {
target: `${role.name}`
}),
children: /*#__PURE__*/ jsx(Pencil, {})
}) : null,
checkCanDeleteRole(role) && /*#__PURE__*/ jsx(IconButton, {
onClick: ()=>handleClickDelete(role.id.toString()),
variant: "ghost",
label: formatMessage({
id: 'global.delete-target',
defaultMessage: 'Delete {target}'
}, {
target: `${role.name}`
}),
children: /*#__PURE__*/ jsx(Trash, {})
})
]
})
})
]
}, role.name))
});
};
TableBody.defaultProps = {
canDelete: false,
canUpdate: false
};
TableBody.propTypes = {
onDelete: PropTypes.array.isRequired,
setRoleToDelete: PropTypes.func.isRequired,
sortedRoles: PropTypes.array.isRequired,
canDelete: PropTypes.bool,
canUpdate: PropTypes.bool
};
export { TableBody as default };
//# sourceMappingURL=TableBody.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"TableBody.mjs","sources":["../../../../../../../admin/src/pages/Roles/pages/ListPage/components/TableBody.jsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Flex, IconButton, Link, Tbody, Td, Tr, Typography } from '@strapi/design-system';\nimport { Pencil, Trash } from '@strapi/icons';\nimport PropTypes from 'prop-types';\nimport { useIntl } from 'react-intl';\nimport { useNavigate, NavLink } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nconst EditLink = styled(Link)`\n align-items: center;\n height: 3.2rem;\n width: 3.2rem;\n display: flex;\n justify-content: center;\n padding: ${({ theme }) => `${theme.spaces[2]}`};\n\n svg {\n height: 1.6rem;\n width: 1.6rem;\n\n path {\n fill: ${({ theme }) => theme.colors.neutral500};\n }\n }\n\n &:hover,\n &:focus {\n svg {\n path {\n fill: ${({ theme }) => theme.colors.neutral800};\n }\n }\n }\n`;\n\nconst TableBody = ({ sortedRoles, canDelete, canUpdate, setRoleToDelete, onDelete }) => {\n const { formatMessage } = useIntl();\n const navigate = useNavigate();\n const [showConfirmDelete, setShowConfirmDelete] = onDelete;\n\n const checkCanDeleteRole = (role) =>\n canDelete && !['public', 'authenticated'].includes(role.type);\n\n const handleClickDelete = (id) => {\n setRoleToDelete(id);\n setShowConfirmDelete(!showConfirmDelete);\n };\n\n return (\n <Tbody>\n {sortedRoles?.map((role) => (\n <Tr cursor=\"pointer\" key={role.name} onClick={() => navigate(role.id.toString())}>\n <Td width=\"20%\">\n <Typography>{role.name}</Typography>\n </Td>\n <Td width=\"50%\">\n <Typography>{role.description}</Typography>\n </Td>\n <Td width=\"30%\">\n <Typography>\n {formatMessage(\n {\n id: 'Roles.RoleRow.user-count',\n defaultMessage: '{number, plural, =0 {# user} one {# user} other {# users}}',\n },\n { number: role.nb_users }\n )}\n </Typography>\n </Td>\n <Td>\n <Flex justifyContent=\"end\" onClick={(e) => e.stopPropagation()}>\n {canUpdate ? (\n <EditLink\n tag={NavLink}\n to={role.id.toString()}\n aria-label={formatMessage(\n { id: 'app.component.table.edit', defaultMessage: 'Edit {target}' },\n { target: `${role.name}` }\n )}\n >\n <Pencil />\n </EditLink>\n ) : null}\n\n {checkCanDeleteRole(role) && (\n <IconButton\n onClick={() => handleClickDelete(role.id.toString())}\n variant=\"ghost\"\n label={formatMessage(\n { id: 'global.delete-target', defaultMessage: 'Delete {target}' },\n { target: `${role.name}` }\n )}\n >\n <Trash />\n </IconButton>\n )}\n </Flex>\n </Td>\n </Tr>\n ))}\n </Tbody>\n );\n};\n\nexport default TableBody;\n\nTableBody.defaultProps = {\n canDelete: false,\n canUpdate: false,\n};\n\nTableBody.propTypes = {\n onDelete: PropTypes.array.isRequired,\n setRoleToDelete: PropTypes.func.isRequired,\n sortedRoles: PropTypes.array.isRequired,\n canDelete: PropTypes.bool,\n canUpdate: PropTypes.bool,\n};\n"],"names":["EditLink","styled","Link","theme","spaces","colors","neutral500","neutral800","TableBody","sortedRoles","canDelete","canUpdate","setRoleToDelete","onDelete","formatMessage","useIntl","navigate","useNavigate","showConfirmDelete","setShowConfirmDelete","checkCanDeleteRole","role","includes","type","handleClickDelete","id","_jsx","Tbody","map","_jsxs","Tr","cursor","onClick","toString","Td","width","Typography","name","description","defaultMessage","number","nb_users","Flex","justifyContent","e","stopPropagation","tag","NavLink","to","aria-label","target","Pencil","IconButton","variant","label","Trash","defaultProps","propTypes","PropTypes","array","isRequired","func","bool"],"mappings":";;;;;;;;;AASA,MAAMA,QAAAA,GAAWC,MAAOC,CAAAA,IAAAA,CAAK;;;;;;AAMlB,WAAA,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAK,CAAC,EAAEA,KAAAA,CAAMC,MAAM,CAAC,CAAE,CAAA,CAAC,CAAC,CAAC;;;;;;;YAOrC,EAAE,CAAC,EAAED,KAAK,EAAE,GAAKA,KAAME,CAAAA,MAAM,CAACC,UAAU,CAAC;;;;;;;;cAQvC,EAAE,CAAC,EAAEH,KAAK,EAAE,GAAKA,KAAME,CAAAA,MAAM,CAACE,UAAU,CAAC;;;;AAIvD,CAAC;AAED,MAAMC,SAAY,GAAA,CAAC,EAAEC,WAAW,EAAEC,SAAS,EAAEC,SAAS,EAAEC,eAAe,EAAEC,QAAQ,EAAE,GAAA;IACjF,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAWC,GAAAA,WAAAA,EAAAA;IACjB,MAAM,CAACC,iBAAmBC,EAAAA,oBAAAA,CAAqB,GAAGN,QAAAA;AAElD,IAAA,MAAMO,kBAAqB,GAAA,CAACC,IAC1BX,GAAAA,SAAAA,IAAa,CAAC;AAAC,YAAA,QAAA;AAAU,YAAA;SAAgB,CAACY,QAAQ,CAACD,IAAAA,CAAKE,IALine truncated
@@ -0,0 +1,237 @@
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var designSystem = require('@strapi/design-system');
var icons = require('@strapi/icons');
var admin = require('@strapi/strapi/admin');
var reactIntl = require('react-intl');
var reactQuery = require('react-query');
var reactRouterDom = require('react-router-dom');
var constants = require('../../../../constants.js');
require('lodash/isEmpty');
var getTrad = require('../../../../utils/getTrad.js');
var TableBody = require('./components/TableBody.js');
const RolesListPage = ()=>{
const { trackUsage } = admin.useTracking();
const { formatMessage, locale } = reactIntl.useIntl();
const { toggleNotification } = admin.useNotification();
const { notifyStatus } = designSystem.useNotifyAT();
const [{ query }] = admin.useQueryParams();
const _q = query?._q || '';
const [showConfirmDelete, setShowConfirmDelete] = React.useState(false);
const [roleToDelete, setRoleToDelete] = React.useState();
const { del, get } = admin.useFetchClient();
const { isLoading: isLoadingForPermissions, allowedActions: { canRead, canDelete, canCreate, canUpdate } } = admin.useRBAC({
create: constants.PERMISSIONS.createRole,
read: constants.PERMISSIONS.readRoles,
update: constants.PERMISSIONS.updateRole,
delete: constants.PERMISSIONS.deleteRole
});
const { isLoading: isLoadingForData, data: { roles }, isFetching, refetch } = reactQuery.useQuery('get-roles', ()=>fetchData(toggleNotification, formatMessage, notifyStatus), {
initialData: {},
enabled: canRead
});
const { contains } = designSystem.useFilter(locale, {
sensitivity: 'base'
});
/**
* @type {Intl.Collator}
*/ const formatter = designSystem.useCollator(locale, {
sensitivity: 'base'
});
const isLoading = isLoadingForData || isFetching || isLoadingForPermissions;
const handleShowConfirmDelete = ()=>{
setShowConfirmDelete(!showConfirmDelete);
};
const deleteData = async (id, formatMessage, toggleNotification)=>{
try {
await del(`/users-permissions/roles/${id}`);
} catch (error) {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occured'
})
});
}
};
const fetchData = async (toggleNotification, formatMessage, notifyStatus)=>{
try {
const { data } = await get('/users-permissions/roles');
notifyStatus('The roles have loaded successfully');
return data;
} catch (err) {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occurred'
})
});
throw new Error(err);
}
};
const emptyLayout = {
roles: {
id: getTrad('Roles.empty'),
defaultMessage: "You don't have any roles yet."
},
search: {
id: getTrad('Roles.empty.search'),
defaultMessage: 'No roles match the search.'
}
};
const pageTitle = formatMessage({
id: 'global.roles',
defaultMessage: 'Roles'
});
const deleteMutation = reactQuery.useMutation((id)=>deleteData(id, formatMessage, toggleNotification), {
async onSuccess () {
await refetch();
}
});
const handleConfirmDelete = async ()=>{
await deleteMutation.mutateAsync(roleToDelete);
setShowConfirmDelete(!showConfirmDelete);
};
const sortedRoles = (roles || []).filter((role)=>contains(role.name, _q) || contains(role.description, _q)).sort((a, b)=>formatter.compare(a.name, b.name) || formatter.compare(a.description, b.description));
const emptyContent = _q && !sortedRoles.length ? 'search' : 'roles';
const colCount = 4;
const rowCount = (roles?.length || 0) + 1;
if (isLoading) {
return /*#__PURE__*/ jsxRuntime.jsx(admin.Page.Loading, {});
}
return /*#__PURE__*/ jsxRuntime.jsxs(admin.Layouts.Root, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(admin.Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: pageTitle
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(admin.Page.Main, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(admin.Layouts.Header, {
title: formatMessage({
id: 'global.roles',
defaultMessage: 'Roles'
}),
subtitle: formatMessage({
id: 'Settings.roles.list.description',
defaultMessage: 'List of roles'
}),
primaryAction: canCreate ? /*#__PURE__*/ jsxRuntime.jsx(designSystem.LinkButton, {
to: "new",
tag: reactRouterDom.NavLink,
onClick: ()=>trackUsage('willCreateRole'),
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Plus, {}),
size: "S",
children: formatMessage({
id: getTrad('List.button.roles'),
defaultMessage: 'Add new role'
})
}) : null
}),
/*#__PURE__*/ jsxRuntime.jsx(admin.Layouts.Action, {
startActions: /*#__PURE__*/ jsxRuntime.jsx(admin.SearchInput, {
label: formatMessage({
id: 'app.component.search.label',
defaultMessage: 'Search'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsxs(admin.Layouts.Content, {
children: [
!canRead && /*#__PURE__*/ jsxRuntime.jsx(admin.Page.NoPermissions, {}),
canRead && sortedRoles && sortedRoles?.length ? /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Table, {
colCount: colCount,
rowCount: rowCount,
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Thead, {
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Tr, {
children: [
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: 'global.name',
defaultMessage: 'Name'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: 'global.description',
defaultMessage: 'Description'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: 'global.users',
defaultMessage: 'Users'
})
})
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Th, {
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.VisuallyHidden, {
children: formatMessage({
id: 'global.actions',
defaultMessage: 'Actions'
})
})
})
]
})
}),
/*#__PURE__*/ jsxRuntime.jsx(TableBody, {
sortedRoles: sortedRoles,
canDelete: canDelete,
canUpdate: canUpdate,
permissions: constants.PERMISSIONS,
setRoleToDelete: setRoleToDelete,
onDelete: [
showConfirmDelete,
setShowConfirmDelete
]
})
]
}) : /*#__PURE__*/ jsxRuntime.jsx(designSystem.EmptyStateLayout, {
content: formatMessage(emptyLayout[emptyContent])
})
]
}),
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Dialog.Root, {
open: showConfirmDelete,
onOpenChange: handleShowConfirmDelete,
children: /*#__PURE__*/ jsxRuntime.jsx(admin.ConfirmDialog, {
onConfirm: handleConfirmDelete
})
})
]
})
]
});
};
const ProtectedRolesListPage = ()=>{
return /*#__PURE__*/ jsxRuntime.jsx(admin.Page.Protect, {
permissions: constants.PERMISSIONS.accessRoles,
children: /*#__PURE__*/ jsxRuntime.jsx(RolesListPage, {})
});
};
exports.ProtectedRolesListPage = ProtectedRolesListPage;
exports.RolesListPage = RolesListPage;
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sources":["../../../../../../admin/src/pages/Roles/pages/ListPage/index.jsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport {\n Table,\n Th,\n Thead,\n Tr,\n Typography,\n useNotifyAT,\n VisuallyHidden,\n EmptyStateLayout,\n useCollator,\n useFilter,\n LinkButton,\n Dialog,\n} from '@strapi/design-system';\nimport { Plus } from '@strapi/icons';\nimport {\n ConfirmDialog,\n useTracking,\n Page,\n SearchInput,\n useNotification,\n useQueryParams,\n useFetchClient,\n useRBAC,\n Layouts,\n} from '@strapi/strapi/admin';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery } from 'react-query';\nimport { NavLink } from 'react-router-dom';\n\nimport { PERMISSIONS } from '../../../../constants';\nimport { getTrad } from '../../../../utils';\n\nimport TableBody from './components/TableBody';\n\nexport const RolesListPage = () => {\n const { trackUsage } = useTracking();\n const { formatMessage, locale } = useIntl();\n const { toggleNotification } = useNotification();\n const { notifyStatus } = useNotifyAT();\n const [{ query }] = useQueryParams();\n const _q = query?._q || '';\n const [showConfirmDelete, setShowConfirmDelete] = useState(false);\n const [roleToDelete, setRoleToDelete] = useState();\n const { del, get } = useFetchClient();\n\n const {\n isLoading: isLoadingForPermissions,\n allowedActions: { canRead, canDelete, canCreate, canUpdate },\n } = useRBAC({\n create: PERMISSIONS.createRole,\n read: PERMISSIONS.readRoles,\n update: PERMISSIONS.updateRole,\n delete: PERMISSIONS.deleteRole,\n });\n\n const {\n isLoading: isLoadingForData,\n data: { roles },\n isFetching,\n refetch,\n } = useQuery('get-roles', () => fetchData(toggleNotification, formatMessage, notifyStatus), {\n initialData: {},\n enabled: canRead,\n });\n\n const { contains } = useFilter(locale, {\n sensitivity: 'base',\n });\n\n /**\n * @type {Intl.Collator}\n */\n const formatter = useCollator(locale, {\n sensitivity: 'base',\n });\n\n const isLoading = isLoadingForData || isFetching || isLoadingForPermissions;\n\n const handleShowConfirmDelete = () => {\n setShowConfirmDelete(!showConfirmDelete);\n };\n\n const deleteData = async (id, formatMessage, toggleNotification) => {\n try {\n await del(`/users-permissions/roles/${id}`);\n } catch (error) {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occured' }),\n });\n }\n };\n\n const fetchData = async (toggleNotification, formatMessage, notifyStatus) => {\n try {\n const { data } = await get('/users-permissions/roles');\n notifyStatus('The roles have loaded successfully');\n\n return data;\n } catch (err) {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n\n throw new Error(err);\n }\n };\n\n const emptyLayout = {\n roles: {\n id: getTrad('Roles.empty'),\n defaultMessage: \"You don't have any roles yet.\",\n },\n search: {\n id: getTrad('Roles.empty.search'),\n defaultMessage: 'No roles match the search.',\n },\n };\n\n const pageTitle = formatMessage({\n id: 'global.roles',\n defaultMessage: 'Roles',\n });\n\n const deleteMutation = useMutation((id) => deleteData(id, formatMessage, toggleNotification), {\n async onSuccess() {\n await refetch();\n },\n });\n\n const handleConfirmDelete = async () => {\n await deleteMutation.mutateAsync(roleToDelete);\n setShowConfirmDelete(!showConfirmDelete);\n };\n\n const sortedRoles = (roles || [])\n .filter((role) => contains(role.name, _q) || contains(role.description, _q))\n .sort(\n (a, b) => formatter.compare(a.name, b.name) || formatter.compare(a.description, b.description)\n );\n\n const emptyContent = _q && !sortedRoles.length ? 'search' : 'roles';\n\n const colCount = 4;\n const rowCount = (roles?.length || 0) + 1;\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Layouts.Root>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n { name: pageTitle }\n )}\n </Page.Title>\n <Page.Main>\n <Layouts.Header\n title={formatMessage({\n id: 'global.roles',\n defaultMessage: 'Roles',\n })}\n subtitle={formatMessage({\n id: 'Settings.roles.list.description',\n defaultMessage: 'List of roles',\n })}\n primaryAction={\n canCreate ? (\n <LinkButton\n to=\"new\"\n tag={NavLink}\n onClick={() => trackUsage('willCreateRole')}\n startIcon={<Plus />}\n sLine truncated
@@ -0,0 +1,234 @@
import { jsx, jsxs } from 'react/jsx-runtime';
import { useState } from 'react';
import { useNotifyAT, useFilter, useCollator, LinkButton, Table, Thead, Tr, Th, Typography, VisuallyHidden, EmptyStateLayout, Dialog } from '@strapi/design-system';
import { Plus } from '@strapi/icons';
import { Page, useTracking, useNotification, useQueryParams, useFetchClient, useRBAC, Layouts, SearchInput, ConfirmDialog } from '@strapi/strapi/admin';
import { useIntl } from 'react-intl';
import { useQuery, useMutation } from 'react-query';
import { NavLink } from 'react-router-dom';
import { PERMISSIONS } from '../../../../constants.mjs';
import 'lodash/isEmpty';
import getTrad from '../../../../utils/getTrad.mjs';
import TableBody from './components/TableBody.mjs';
const RolesListPage = ()=>{
const { trackUsage } = useTracking();
const { formatMessage, locale } = useIntl();
const { toggleNotification } = useNotification();
const { notifyStatus } = useNotifyAT();
const [{ query }] = useQueryParams();
const _q = query?._q || '';
const [showConfirmDelete, setShowConfirmDelete] = useState(false);
const [roleToDelete, setRoleToDelete] = useState();
const { del, get } = useFetchClient();
const { isLoading: isLoadingForPermissions, allowedActions: { canRead, canDelete, canCreate, canUpdate } } = useRBAC({
create: PERMISSIONS.createRole,
read: PERMISSIONS.readRoles,
update: PERMISSIONS.updateRole,
delete: PERMISSIONS.deleteRole
});
const { isLoading: isLoadingForData, data: { roles }, isFetching, refetch } = useQuery('get-roles', ()=>fetchData(toggleNotification, formatMessage, notifyStatus), {
initialData: {},
enabled: canRead
});
const { contains } = useFilter(locale, {
sensitivity: 'base'
});
/**
* @type {Intl.Collator}
*/ const formatter = useCollator(locale, {
sensitivity: 'base'
});
const isLoading = isLoadingForData || isFetching || isLoadingForPermissions;
const handleShowConfirmDelete = ()=>{
setShowConfirmDelete(!showConfirmDelete);
};
const deleteData = async (id, formatMessage, toggleNotification)=>{
try {
await del(`/users-permissions/roles/${id}`);
} catch (error) {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occured'
})
});
}
};
const fetchData = async (toggleNotification, formatMessage, notifyStatus)=>{
try {
const { data } = await get('/users-permissions/roles');
notifyStatus('The roles have loaded successfully');
return data;
} catch (err) {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occurred'
})
});
throw new Error(err);
}
};
const emptyLayout = {
roles: {
id: getTrad('Roles.empty'),
defaultMessage: "You don't have any roles yet."
},
search: {
id: getTrad('Roles.empty.search'),
defaultMessage: 'No roles match the search.'
}
};
const pageTitle = formatMessage({
id: 'global.roles',
defaultMessage: 'Roles'
});
const deleteMutation = useMutation((id)=>deleteData(id, formatMessage, toggleNotification), {
async onSuccess () {
await refetch();
}
});
const handleConfirmDelete = async ()=>{
await deleteMutation.mutateAsync(roleToDelete);
setShowConfirmDelete(!showConfirmDelete);
};
const sortedRoles = (roles || []).filter((role)=>contains(role.name, _q) || contains(role.description, _q)).sort((a, b)=>formatter.compare(a.name, b.name) || formatter.compare(a.description, b.description));
const emptyContent = _q && !sortedRoles.length ? 'search' : 'roles';
const colCount = 4;
const rowCount = (roles?.length || 0) + 1;
if (isLoading) {
return /*#__PURE__*/ jsx(Page.Loading, {});
}
return /*#__PURE__*/ jsxs(Layouts.Root, {
children: [
/*#__PURE__*/ jsx(Page.Title, {
children: formatMessage({
id: 'Settings.PageTitle',
defaultMessage: 'Settings - {name}'
}, {
name: pageTitle
})
}),
/*#__PURE__*/ jsxs(Page.Main, {
children: [
/*#__PURE__*/ jsx(Layouts.Header, {
title: formatMessage({
id: 'global.roles',
defaultMessage: 'Roles'
}),
subtitle: formatMessage({
id: 'Settings.roles.list.description',
defaultMessage: 'List of roles'
}),
primaryAction: canCreate ? /*#__PURE__*/ jsx(LinkButton, {
to: "new",
tag: NavLink,
onClick: ()=>trackUsage('willCreateRole'),
startIcon: /*#__PURE__*/ jsx(Plus, {}),
size: "S",
children: formatMessage({
id: getTrad('List.button.roles'),
defaultMessage: 'Add new role'
})
}) : null
}),
/*#__PURE__*/ jsx(Layouts.Action, {
startActions: /*#__PURE__*/ jsx(SearchInput, {
label: formatMessage({
id: 'app.component.search.label',
defaultMessage: 'Search'
})
})
}),
/*#__PURE__*/ jsxs(Layouts.Content, {
children: [
!canRead && /*#__PURE__*/ jsx(Page.NoPermissions, {}),
canRead && sortedRoles && sortedRoles?.length ? /*#__PURE__*/ jsxs(Table, {
colCount: colCount,
rowCount: rowCount,
children: [
/*#__PURE__*/ jsx(Thead, {
children: /*#__PURE__*/ jsxs(Tr, {
children: [
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: 'global.name',
defaultMessage: 'Name'
})
})
}),
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: 'global.description',
defaultMessage: 'Description'
})
})
}),
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(Typography, {
variant: "sigma",
textColor: "neutral600",
children: formatMessage({
id: 'global.users',
defaultMessage: 'Users'
})
})
}),
/*#__PURE__*/ jsx(Th, {
children: /*#__PURE__*/ jsx(VisuallyHidden, {
children: formatMessage({
id: 'global.actions',
defaultMessage: 'Actions'
})
})
})
]
})
}),
/*#__PURE__*/ jsx(TableBody, {
sortedRoles: sortedRoles,
canDelete: canDelete,
canUpdate: canUpdate,
permissions: PERMISSIONS,
setRoleToDelete: setRoleToDelete,
onDelete: [
showConfirmDelete,
setShowConfirmDelete
]
})
]
}) : /*#__PURE__*/ jsx(EmptyStateLayout, {
content: formatMessage(emptyLayout[emptyContent])
})
]
}),
/*#__PURE__*/ jsx(Dialog.Root, {
open: showConfirmDelete,
onOpenChange: handleShowConfirmDelete,
children: /*#__PURE__*/ jsx(ConfirmDialog, {
onConfirm: handleConfirmDelete
})
})
]
})
]
});
};
const ProtectedRolesListPage = ()=>{
return /*#__PURE__*/ jsx(Page.Protect, {
permissions: PERMISSIONS.accessRoles,
children: /*#__PURE__*/ jsx(RolesListPage, {})
});
};
export { ProtectedRolesListPage, RolesListPage };
//# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"index.mjs","sources":["../../../../../../admin/src/pages/Roles/pages/ListPage/index.jsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport {\n Table,\n Th,\n Thead,\n Tr,\n Typography,\n useNotifyAT,\n VisuallyHidden,\n EmptyStateLayout,\n useCollator,\n useFilter,\n LinkButton,\n Dialog,\n} from '@strapi/design-system';\nimport { Plus } from '@strapi/icons';\nimport {\n ConfirmDialog,\n useTracking,\n Page,\n SearchInput,\n useNotification,\n useQueryParams,\n useFetchClient,\n useRBAC,\n Layouts,\n} from '@strapi/strapi/admin';\nimport { useIntl } from 'react-intl';\nimport { useMutation, useQuery } from 'react-query';\nimport { NavLink } from 'react-router-dom';\n\nimport { PERMISSIONS } from '../../../../constants';\nimport { getTrad } from '../../../../utils';\n\nimport TableBody from './components/TableBody';\n\nexport const RolesListPage = () => {\n const { trackUsage } = useTracking();\n const { formatMessage, locale } = useIntl();\n const { toggleNotification } = useNotification();\n const { notifyStatus } = useNotifyAT();\n const [{ query }] = useQueryParams();\n const _q = query?._q || '';\n const [showConfirmDelete, setShowConfirmDelete] = useState(false);\n const [roleToDelete, setRoleToDelete] = useState();\n const { del, get } = useFetchClient();\n\n const {\n isLoading: isLoadingForPermissions,\n allowedActions: { canRead, canDelete, canCreate, canUpdate },\n } = useRBAC({\n create: PERMISSIONS.createRole,\n read: PERMISSIONS.readRoles,\n update: PERMISSIONS.updateRole,\n delete: PERMISSIONS.deleteRole,\n });\n\n const {\n isLoading: isLoadingForData,\n data: { roles },\n isFetching,\n refetch,\n } = useQuery('get-roles', () => fetchData(toggleNotification, formatMessage, notifyStatus), {\n initialData: {},\n enabled: canRead,\n });\n\n const { contains } = useFilter(locale, {\n sensitivity: 'base',\n });\n\n /**\n * @type {Intl.Collator}\n */\n const formatter = useCollator(locale, {\n sensitivity: 'base',\n });\n\n const isLoading = isLoadingForData || isFetching || isLoadingForPermissions;\n\n const handleShowConfirmDelete = () => {\n setShowConfirmDelete(!showConfirmDelete);\n };\n\n const deleteData = async (id, formatMessage, toggleNotification) => {\n try {\n await del(`/users-permissions/roles/${id}`);\n } catch (error) {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occured' }),\n });\n }\n };\n\n const fetchData = async (toggleNotification, formatMessage, notifyStatus) => {\n try {\n const { data } = await get('/users-permissions/roles');\n notifyStatus('The roles have loaded successfully');\n\n return data;\n } catch (err) {\n toggleNotification({\n type: 'danger',\n message: formatMessage({ id: 'notification.error', defaultMessage: 'An error occurred' }),\n });\n\n throw new Error(err);\n }\n };\n\n const emptyLayout = {\n roles: {\n id: getTrad('Roles.empty'),\n defaultMessage: \"You don't have any roles yet.\",\n },\n search: {\n id: getTrad('Roles.empty.search'),\n defaultMessage: 'No roles match the search.',\n },\n };\n\n const pageTitle = formatMessage({\n id: 'global.roles',\n defaultMessage: 'Roles',\n });\n\n const deleteMutation = useMutation((id) => deleteData(id, formatMessage, toggleNotification), {\n async onSuccess() {\n await refetch();\n },\n });\n\n const handleConfirmDelete = async () => {\n await deleteMutation.mutateAsync(roleToDelete);\n setShowConfirmDelete(!showConfirmDelete);\n };\n\n const sortedRoles = (roles || [])\n .filter((role) => contains(role.name, _q) || contains(role.description, _q))\n .sort(\n (a, b) => formatter.compare(a.name, b.name) || formatter.compare(a.description, b.description)\n );\n\n const emptyContent = _q && !sortedRoles.length ? 'search' : 'roles';\n\n const colCount = 4;\n const rowCount = (roles?.length || 0) + 1;\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Layouts.Root>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n { name: pageTitle }\n )}\n </Page.Title>\n <Page.Main>\n <Layouts.Header\n title={formatMessage({\n id: 'global.roles',\n defaultMessage: 'Roles',\n })}\n subtitle={formatMessage({\n id: 'Settings.roles.list.description',\n defaultMessage: 'List of roles',\n })}\n primaryAction={\n canCreate ? (\n <LinkButton\n to=\"new\"\n tag={NavLink}\n onClick={() => trackUsage('willCreateRole')}\n startIcon={<Plus />}\n Line truncated