@strapi/admin 5.42.1 → 5.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/admin/src/StrapiApp.js +17 -4
- package/dist/admin/admin/src/StrapiApp.js.map +1 -1
- package/dist/admin/admin/src/StrapiApp.mjs +18 -5
- package/dist/admin/admin/src/StrapiApp.mjs.map +1 -1
- package/dist/admin/admin/src/components/Form.js +29 -18
- package/dist/admin/admin/src/components/Form.js.map +1 -1
- package/dist/admin/admin/src/components/Form.mjs +29 -18
- package/dist/admin/admin/src/components/Form.mjs.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Date.js +2 -2
- package/dist/admin/admin/src/components/FormInputs/Date.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Date.mjs +2 -2
- package/dist/admin/admin/src/components/FormInputs/Date.mjs.map +1 -1
- package/dist/admin/admin/src/components/GuidedTour/Context.js +3 -2
- package/dist/admin/admin/src/components/GuidedTour/Context.js.map +1 -1
- package/dist/admin/admin/src/components/GuidedTour/Context.mjs +3 -2
- package/dist/admin/admin/src/components/GuidedTour/Context.mjs.map +1 -1
- package/dist/admin/admin/src/components/Layouts/Layout.js +1 -0
- package/dist/admin/admin/src/components/Layouts/Layout.js.map +1 -1
- package/dist/admin/admin/src/components/Layouts/Layout.mjs +1 -0
- package/dist/admin/admin/src/components/Layouts/Layout.mjs.map +1 -1
- package/dist/admin/admin/src/components/PageHelpers.js +1 -1
- package/dist/admin/admin/src/components/PageHelpers.js.map +1 -1
- package/dist/admin/admin/src/components/PageHelpers.mjs +1 -1
- package/dist/admin/admin/src/components/PageHelpers.mjs.map +1 -1
- package/dist/admin/admin/src/components/Table.js +28 -15
- package/dist/admin/admin/src/components/Table.js.map +1 -1
- package/dist/admin/admin/src/components/Table.mjs +29 -16
- package/dist/admin/admin/src/components/Table.mjs.map +1 -1
- package/dist/admin/admin/src/components/Widgets.js +52 -0
- package/dist/admin/admin/src/components/Widgets.js.map +1 -1
- package/dist/admin/admin/src/components/Widgets.mjs +54 -3
- package/dist/admin/admin/src/components/Widgets.mjs.map +1 -1
- package/dist/admin/admin/src/core/store/configure.js +3 -1
- package/dist/admin/admin/src/core/store/configure.js.map +1 -1
- package/dist/admin/admin/src/core/store/configure.mjs +3 -1
- package/dist/admin/admin/src/core/store/configure.mjs.map +1 -1
- package/dist/admin/admin/src/hooks/usePersistentState.js +9 -4
- package/dist/admin/admin/src/hooks/usePersistentState.js.map +1 -1
- package/dist/admin/admin/src/hooks/usePersistentState.mjs +10 -6
- package/dist/admin/admin/src/hooks/usePersistentState.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.js +4 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.mjs +4 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.mjs.map +1 -1
- package/dist/admin/admin/src/render.js +2 -0
- package/dist/admin/admin/src/render.js.map +1 -1
- package/dist/admin/admin/src/render.mjs +2 -0
- package/dist/admin/admin/src/render.mjs.map +1 -1
- package/dist/admin/admin/src/services/api.js +2 -2
- package/dist/admin/admin/src/services/api.js.map +1 -1
- package/dist/admin/admin/src/services/api.mjs +2 -2
- package/dist/admin/admin/src/services/api.mjs.map +1 -1
- package/dist/admin/admin/src/translations/ar.json.js +4 -1
- package/dist/admin/admin/src/translations/ar.json.js.map +1 -1
- package/dist/admin/admin/src/translations/ar.json.mjs +4 -1
- package/dist/admin/admin/src/translations/ar.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/cs.json.js +736 -13
- package/dist/admin/admin/src/translations/cs.json.js.map +1 -1
- package/dist/admin/admin/src/translations/cs.json.mjs +728 -14
- package/dist/admin/admin/src/translations/cs.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/de.json.js +4 -1
- package/dist/admin/admin/src/translations/de.json.js.map +1 -1
- package/dist/admin/admin/src/translations/de.json.mjs +4 -1
- package/dist/admin/admin/src/translations/de.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/en.json.js +4 -1
- package/dist/admin/admin/src/translations/en.json.js.map +1 -1
- package/dist/admin/admin/src/translations/en.json.mjs +4 -1
- package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/es.json.js +4 -1
- package/dist/admin/admin/src/translations/es.json.js.map +1 -1
- package/dist/admin/admin/src/translations/es.json.mjs +4 -1
- package/dist/admin/admin/src/translations/es.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/fr.json.js +4 -1
- package/dist/admin/admin/src/translations/fr.json.js.map +1 -1
- package/dist/admin/admin/src/translations/fr.json.mjs +4 -1
- package/dist/admin/admin/src/translations/fr.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/it.json.js +4 -1
- package/dist/admin/admin/src/translations/it.json.js.map +1 -1
- package/dist/admin/admin/src/translations/it.json.mjs +4 -1
- package/dist/admin/admin/src/translations/it.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/nl.json.js +394 -89
- package/dist/admin/admin/src/translations/nl.json.js.map +1 -1
- package/dist/admin/admin/src/translations/nl.json.mjs +393 -90
- package/dist/admin/admin/src/translations/nl.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/ru.json.js +32 -19
- package/dist/admin/admin/src/translations/ru.json.js.map +1 -1
- package/dist/admin/admin/src/translations/ru.json.mjs +32 -19
- package/dist/admin/admin/src/translations/ru.json.mjs.map +1 -1
- package/dist/admin/admin/src/translations/zh-Hans.json.js +4 -1
- package/dist/admin/admin/src/translations/zh-Hans.json.js.map +1 -1
- package/dist/admin/admin/src/translations/zh-Hans.json.mjs +4 -1
- package/dist/admin/admin/src/translations/zh-Hans.json.mjs.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.js +29 -3
- package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs +29 -3
- package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
- package/dist/admin/ee/admin/src/hooks/useAIUsageWarning.js +1 -1
- package/dist/admin/ee/admin/src/hooks/useAIUsageWarning.js.map +1 -1
- package/dist/admin/ee/admin/src/hooks/useAIUsageWarning.mjs +2 -2
- package/dist/admin/ee/admin/src/hooks/useAIUsageWarning.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs +2 -2
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs.map +1 -1
- package/dist/admin/ee/admin/src/services/ai.js +7 -7
- package/dist/admin/ee/admin/src/services/ai.js.map +1 -1
- package/dist/admin/ee/admin/src/services/ai.mjs +6 -6
- package/dist/admin/ee/admin/src/services/ai.mjs.map +1 -1
- package/dist/admin/ee.js +2 -2
- package/dist/admin/ee.mjs +1 -1
- package/dist/admin/index.js +1 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/src/components/Widgets.d.ts +2 -1
- package/dist/admin/src/core/store/configure.d.ts +2 -2
- package/dist/admin/src/core/store/hooks.d.ts +2 -2
- package/dist/admin/src/ee.d.ts +1 -1
- package/dist/admin/src/hooks/useAdminRoles.d.ts +1 -1
- package/dist/admin/src/hooks/usePersistentState.d.ts +2 -1
- package/dist/admin/src/index.d.ts +1 -1
- package/dist/admin/src/pages/Settings/pages/Webhooks/hooks/useWebhooks.d.ts +4 -4
- package/dist/admin/src/selectors.d.ts +2 -2
- package/dist/admin/src/services/admin.d.ts +6 -6
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/apiTokens.d.ts +1 -1
- package/dist/admin/src/services/auth.d.ts +11 -11
- package/dist/admin/src/services/contentApi.d.ts +1 -1
- package/dist/admin/src/services/contentManager.d.ts +1 -1
- package/dist/admin/src/services/homepage.d.ts +3 -3
- package/dist/admin/src/services/transferTokens.d.ts +1 -1
- package/dist/admin/src/services/users.d.ts +8 -8
- package/dist/admin/src/services/webhooks.d.ts +2 -2
- package/dist/admin/src/utils/getFetchClient.d.ts +14 -1
- package/dist/admin/tests/utils.d.ts +1 -1
- package/dist/ee/admin/src/services/ai.d.ts +6 -6
- package/dist/ee/admin/src/services/auditLogs.d.ts +1 -1
- package/dist/ee/server/src/index.d.ts +0 -16
- package/dist/ee/server/src/index.d.ts.map +1 -1
- package/dist/server/ee/server/src/index.js +0 -16
- package/dist/server/ee/server/src/index.js.map +1 -1
- package/dist/server/ee/server/src/index.mjs +0 -16
- package/dist/server/ee/server/src/index.mjs.map +1 -1
- package/dist/server/server/src/ai/controllers/ai.js +52 -0
- package/dist/server/server/src/ai/controllers/ai.js.map +1 -0
- package/dist/server/server/src/ai/controllers/ai.mjs +50 -0
- package/dist/server/server/src/ai/controllers/ai.mjs.map +1 -0
- package/dist/server/{ee/server → server}/src/ai/routes/ai.js +1 -2
- package/dist/server/server/src/ai/routes/ai.js.map +1 -0
- package/dist/server/{ee/server → server}/src/ai/routes/ai.mjs +1 -2
- package/dist/server/server/src/ai/routes/ai.mjs.map +1 -0
- package/dist/server/{ee/server/src/ai/containers → server/src/ai/services}/ai.js +107 -32
- package/dist/server/server/src/ai/services/ai.js.map +1 -0
- package/dist/server/{ee/server/src/ai/containers → server/src/ai/services}/ai.mjs +107 -32
- package/dist/server/server/src/ai/services/ai.mjs.map +1 -0
- package/dist/server/server/src/controllers/index.js +3 -1
- package/dist/server/server/src/controllers/index.js.map +1 -1
- package/dist/server/server/src/controllers/index.mjs +3 -1
- package/dist/server/server/src/controllers/index.mjs.map +1 -1
- package/dist/server/server/src/register.js +4 -0
- package/dist/server/server/src/register.js.map +1 -1
- package/dist/server/server/src/register.mjs +4 -0
- package/dist/server/server/src/register.mjs.map +1 -1
- package/dist/server/server/src/routes/index.js +3 -1
- package/dist/server/server/src/routes/index.js.map +1 -1
- package/dist/server/server/src/routes/index.mjs +3 -1
- package/dist/server/server/src/routes/index.mjs.map +1 -1
- package/dist/{ee/server → server}/src/ai/controllers/ai.d.ts +1 -1
- package/dist/server/src/ai/controllers/ai.d.ts.map +1 -0
- package/dist/server/src/ai/routes/ai.d.ts.map +1 -0
- package/dist/server/src/ai/services/ai.d.ts +30 -0
- package/dist/server/src/ai/services/ai.d.ts.map +1 -0
- package/dist/server/src/controllers/index.d.ts +5 -0
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +5 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/shared/contracts/ai.d.ts +3 -3
- package/package.json +11 -11
- package/dist/ee/server/src/ai/containers/ai.d.ts +0 -15
- package/dist/ee/server/src/ai/containers/ai.d.ts.map +0 -1
- package/dist/ee/server/src/ai/controllers/ai.d.ts.map +0 -1
- package/dist/ee/server/src/ai/routes/ai.d.ts.map +0 -1
- package/dist/server/ee/server/src/ai/containers/ai.js.map +0 -1
- package/dist/server/ee/server/src/ai/containers/ai.mjs.map +0 -1
- package/dist/server/ee/server/src/ai/controllers/ai.js +0 -121
- package/dist/server/ee/server/src/ai/controllers/ai.js.map +0 -1
- package/dist/server/ee/server/src/ai/controllers/ai.mjs +0 -119
- package/dist/server/ee/server/src/ai/controllers/ai.mjs.map +0 -1
- package/dist/server/ee/server/src/ai/routes/ai.js.map +0 -1
- package/dist/server/ee/server/src/ai/routes/ai.mjs.map +0 -1
- /package/dist/{ee/server → server}/src/ai/routes/ai.d.ts +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Date.js","sources":["../../../../../../admin/src/components/FormInputs/Date.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { DatePicker, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst DateInput = React.forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, type: _type, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n const composedRefs = useComposedRefs(ref, fieldRef);\n const [lastValidDate, setLastValidDate] = React.useState<Date | null>(null);\n\n const value = typeof field.value === 'string' ? new Date(field.value) : field.value;\n\n const handleDateChange = (date: Date | undefined) => {\n if (!date) {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }\n\n // Convert to UTC midnight\n const utcDate = toUTCMidnight(date);\n // Save as ISO string in UTC format\n field.onChange(name, utcDate.toISOString());\n setLastValidDate(utcDate);\n };\n\n // Render the DatePicker with UTC date\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <DatePicker\n ref={composedRefs}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n onChange={handleDateChange}\n onClear={() => {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }}\n onBlur={() => {\n // When the input is blurred, revert to the last valid date if the current value is invalid\n if (field.value && !value) {\n field.onChange(name
|
|
1
|
+
{"version":3,"file":"Date.js","sources":["../../../../../../admin/src/components/FormInputs/Date.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { DatePicker, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst DateInput = React.forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, type: _type, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n const composedRefs = useComposedRefs(ref, fieldRef);\n const [lastValidDate, setLastValidDate] = React.useState<Date | null>(null);\n\n const value = typeof field.value === 'string' ? new Date(field.value) : field.value;\n\n const handleDateChange = (date: Date | undefined) => {\n if (!date) {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }\n\n // Convert to UTC midnight\n const utcDate = toUTCMidnight(date);\n // Save as ISO string in UTC format\n field.onChange(name, utcDate.toISOString().split('T')[0]);\n setLastValidDate(utcDate);\n };\n\n // Render the DatePicker with UTC date\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <DatePicker\n ref={composedRefs}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n onChange={handleDateChange}\n onClear={() => {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }}\n onBlur={() => {\n // When the input is blurred, revert to the last valid date if the current value is invalid\n if (field.value && !value) {\n field.onChange(\n name,\n lastValidDate ? lastValidDate.toISOString().split('T')[0] : null\n );\n }\n }}\n value={value}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\n// Ensure the conversion to UTC midnight\nconst toUTCMidnight = (date: Date) => {\n return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n};\n\nconst MemoizedDateInput = React.memo(DateInput);\n\nexport { MemoizedDateInput as DateInput };\n"],"names":["DateInput","React","forwardRef","name","required","label","hint","labelAction","type","_type","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","lastValidDate","setLastValidDate","useState","value","Date","handleDateChange","date","onChange","utcDate","toUTCMidnight","toISOString","split","_jsxs","Field","Root","error","_jsx","Label","action","DatePicker","clearLabel","id","defaultMessage","onClear","onBlur","Hint","Error","UTC","getFullYear","getMonth","getDate","MemoizedDateInput","memo"],"mappings":"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"}
|
|
@@ -21,7 +21,7 @@ const DateInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint,
|
|
|
21
21
|
// Convert to UTC midnight
|
|
22
22
|
const utcDate = toUTCMidnight(date);
|
|
23
23
|
// Save as ISO string in UTC format
|
|
24
|
-
field.onChange(name, utcDate.toISOString());
|
|
24
|
+
field.onChange(name, utcDate.toISOString().split('T')[0]);
|
|
25
25
|
setLastValidDate(utcDate);
|
|
26
26
|
};
|
|
27
27
|
// Render the DatePicker with UTC date
|
|
@@ -50,7 +50,7 @@ const DateInput = /*#__PURE__*/ React.forwardRef(({ name, required, label, hint,
|
|
|
50
50
|
onBlur: ()=>{
|
|
51
51
|
// When the input is blurred, revert to the last valid date if the current value is invalid
|
|
52
52
|
if (field.value && !value) {
|
|
53
|
-
field.onChange(name, lastValidDate
|
|
53
|
+
field.onChange(name, lastValidDate ? lastValidDate.toISOString().split('T')[0] : null);
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
value: value,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Date.mjs","sources":["../../../../../../admin/src/components/FormInputs/Date.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { DatePicker, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst DateInput = React.forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, type: _type, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n const composedRefs = useComposedRefs(ref, fieldRef);\n const [lastValidDate, setLastValidDate] = React.useState<Date | null>(null);\n\n const value = typeof field.value === 'string' ? new Date(field.value) : field.value;\n\n const handleDateChange = (date: Date | undefined) => {\n if (!date) {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }\n\n // Convert to UTC midnight\n const utcDate = toUTCMidnight(date);\n // Save as ISO string in UTC format\n field.onChange(name, utcDate.toISOString());\n setLastValidDate(utcDate);\n };\n\n // Render the DatePicker with UTC date\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <DatePicker\n ref={composedRefs}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n onChange={handleDateChange}\n onClear={() => {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }}\n onBlur={() => {\n // When the input is blurred, revert to the last valid date if the current value is invalid\n if (field.value && !value) {\n field.onChange(name
|
|
1
|
+
{"version":3,"file":"Date.mjs","sources":["../../../../../../admin/src/components/FormInputs/Date.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { DatePicker, useComposedRefs, Field } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { useFocusInputField } from '../../hooks/useFocusInputField';\nimport { useField } from '../Form';\n\nimport { InputProps } from './types';\n\nconst DateInput = React.forwardRef<HTMLInputElement, InputProps>(\n ({ name, required, label, hint, labelAction, type: _type, ...props }, ref) => {\n const { formatMessage } = useIntl();\n const field = useField(name);\n const fieldRef = useFocusInputField<HTMLInputElement>(name);\n const composedRefs = useComposedRefs(ref, fieldRef);\n const [lastValidDate, setLastValidDate] = React.useState<Date | null>(null);\n\n const value = typeof field.value === 'string' ? new Date(field.value) : field.value;\n\n const handleDateChange = (date: Date | undefined) => {\n if (!date) {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }\n\n // Convert to UTC midnight\n const utcDate = toUTCMidnight(date);\n // Save as ISO string in UTC format\n field.onChange(name, utcDate.toISOString().split('T')[0]);\n setLastValidDate(utcDate);\n };\n\n // Render the DatePicker with UTC date\n return (\n <Field.Root error={field.error} name={name} hint={hint} required={required}>\n <Field.Label action={labelAction}>{label}</Field.Label>\n <DatePicker\n ref={composedRefs}\n clearLabel={formatMessage({ id: 'clearLabel', defaultMessage: 'Clear' })}\n onChange={handleDateChange}\n onClear={() => {\n field.onChange(name, null);\n setLastValidDate(null);\n return;\n }}\n onBlur={() => {\n // When the input is blurred, revert to the last valid date if the current value is invalid\n if (field.value && !value) {\n field.onChange(\n name,\n lastValidDate ? lastValidDate.toISOString().split('T')[0] : null\n );\n }\n }}\n value={value}\n {...props}\n />\n <Field.Hint />\n <Field.Error />\n </Field.Root>\n );\n }\n);\n\n// Ensure the conversion to UTC midnight\nconst toUTCMidnight = (date: Date) => {\n return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n};\n\nconst MemoizedDateInput = React.memo(DateInput);\n\nexport { MemoizedDateInput as DateInput };\n"],"names":["DateInput","React","forwardRef","name","required","label","hint","labelAction","type","_type","props","ref","formatMessage","useIntl","field","useField","fieldRef","useFocusInputField","composedRefs","useComposedRefs","lastValidDate","setLastValidDate","useState","value","Date","handleDateChange","date","onChange","utcDate","toUTCMidnight","toISOString","split","_jsxs","Field","Root","error","_jsx","Label","action","DatePicker","clearLabel","id","defaultMessage","onClear","onBlur","Hint","Error","UTC","getFullYear","getMonth","getDate","MemoizedDateInput","memo"],"mappings":"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"}
|
|
@@ -119,8 +119,9 @@ const GuidedTourContext = ({ children, enabled = true })=>{
|
|
|
119
119
|
}, [
|
|
120
120
|
isDesktop
|
|
121
121
|
]);
|
|
122
|
-
// Sync
|
|
123
|
-
|
|
122
|
+
// Sync into usePersistentState in the layout phase so localStorage is updated before the
|
|
123
|
+
// browser follows an external link (e.g. Strapi Cloud "Read documentation").
|
|
124
|
+
React__namespace.useLayoutEffect(()=>{
|
|
124
125
|
setStoredTours(state);
|
|
125
126
|
}, [
|
|
126
127
|
state,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Context.js","sources":["../../../../../../admin/src/components/GuidedTour/Context.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { produce } from 'immer';\n\nimport { useTracking } from '../../features/Tracking';\nimport { useIsDesktop } from '../../hooks/useMediaQuery';\nimport { usePersistentState } from '../../hooks/usePersistentState';\nimport { createContext } from '../Context';\n\nimport { type Tours, tours as guidedTours } from './Tours';\nimport { GUIDED_TOUR_REQUIRED_ACTIONS } from './utils/constants';\nimport { migrateTours } from './utils/migrations';\n\n/* -------------------------------------------------------------------------------------------------\n * GuidedTourProvider\n * -----------------------------------------------------------------------------------------------*/\n\ntype ValidTourName = keyof Tours;\n\n/**\n * Derive the union of all string literal values from GUIDED_TOUR_REQUIRED_ACTIONS\n * (ie didCreateContentTypeSchema | didCreateContent etc...)\n */\ntype ValueOf<T> = T[keyof T];\ntype NonEmptyValueOf<T> = T extends Record<string, never> ? never : ValueOf<T>;\nexport type CompletedActions = NonEmptyValueOf<ValueOf<typeof GUIDED_TOUR_REQUIRED_ACTIONS>>[];\n\ntype Action =\n | {\n type: 'next_step';\n payload: ValidTourName;\n }\n | {\n type: 'previous_step';\n payload: ValidTourName;\n }\n | {\n type: 'go_to_step';\n payload: {\n tourName: ValidTourName;\n step: number;\n };\n }\n | {\n type: 'skip_tour';\n payload: ValidTourName;\n }\n | {\n type: 'skip_all_tours';\n }\n | {\n type: 'reset_all_tours';\n }\n | {\n type: 'set_completed_actions';\n payload: CompletedActions;\n }\n | {\n type: 'remove_completed_action';\n payload: ValueOf<CompletedActions>;\n }\n | {\n type: 'set_tour_type';\n payload: {\n tourName: ValidTourName;\n tourType: 'ContentTypeBuilderAI' | 'ContentTypeBuilderNoAI';\n };\n }\n | {\n type: 'set_hidden';\n payload: boolean;\n };\n\ntype TourState = Record<\n ValidTourName,\n { currentStep: number; isCompleted: boolean; tourType?: string }\n>;\ntype State = {\n tours: TourState;\n enabled: boolean;\n hidden?: boolean;\n completedActions: CompletedActions;\n};\n\nconst [GuidedTourProviderImpl, useGuidedTour] = createContext<{\n state: State;\n dispatch: React.Dispatch<Action>;\n}>('GuidedTour');\n\nconst getInitialTourState = (tours: Tours) => {\n return Object.keys(tours).reduce((acc, tourName) => {\n acc[tourName as ValidTourName] = {\n currentStep: 0,\n isCompleted: false,\n tourType: undefined,\n };\n\n return acc;\n }, {} as TourState);\n};\n\nconst getCompletedTours = (tours: TourState): ValidTourName[] => {\n return Object.keys(tours).filter(\n (tourName) => tours[tourName as ValidTourName].isCompleted\n ) as ValidTourName[];\n};\n\nconst areAllToursCompleted = (tours: TourState) => Object.values(tours).every((t) => t.isCompleted);\n\nfunction reducer(state: State, action: Action): State {\n return produce(state, (draft) => {\n if (action.type === 'next_step') {\n const currentStep = draft.tours[action.payload].currentStep;\n const tourLength = guidedTours[action.payload]._meta.totalStepCount;\n\n const nextStep = currentStep + 1;\n draft.tours[action.payload].currentStep = nextStep;\n draft.tours[action.payload].isCompleted = nextStep >= tourLength;\n }\n\n if (action.type === 'previous_step') {\n const currentStep = draft.tours[action.payload].currentStep;\n\n if (currentStep <= 0) return;\n\n const previousStep = currentStep - 1;\n draft.tours[action.payload].currentStep = previousStep;\n }\n\n if (action.type === 'skip_tour') {\n draft.tours[action.payload].isCompleted = true;\n }\n\n if (action.type === 'set_completed_actions') {\n draft.completedActions = [...new Set([...draft.completedActions, ...action.payload])];\n }\n\n if (action.type === 'remove_completed_action') {\n draft.completedActions = draft.completedActions.filter(\n (completedAction) => completedAction !== action.payload\n );\n }\n\n if (action.type === 'skip_all_tours') {\n draft.enabled = false;\n }\n\n if (action.type === 'set_hidden') {\n draft.hidden = action.payload;\n }\n\n if (action.type === 'reset_all_tours') {\n draft.enabled = true;\n draft.tours = getInitialTourState(guidedTours);\n draft.completedActions = [];\n }\n\n if (action.type === 'go_to_step') {\n draft.tours[action.payload.tourName].currentStep = action.payload.step;\n }\n\n if (action.type === 'set_tour_type') {\n const { tourName, tourType } = action.payload;\n const currentTour = draft.tours[tourName];\n\n // If tour type changes and tour is not completed, reset to step 0\n if (currentTour.tourType && currentTour.tourType !== tourType && !currentTour.isCompleted) {\n currentTour.currentStep = 0;\n }\n\n currentTour.tourType = tourType;\n }\n });\n}\n\nconst STORAGE_KEY = 'STRAPI_GUIDED_TOUR';\nconst GuidedTourContext = ({\n children,\n enabled = true,\n}: {\n children: React.ReactNode;\n enabled?: boolean;\n}) => {\n const isDesktop = useIsDesktop();\n const { trackUsage } = useTracking();\n const [storedTours, setStoredTours] = usePersistentState<State>(STORAGE_KEY, {\n tours: getInitialTourState(guidedTours),\n enabled,\n hidden: !isDesktop,\n completedActions: [],\n });\n const migratedTourState = migrateTours(storedTours);\n const [state, dispatch] = React.useReducer(reducer, migratedTourState);\n\n // Watch for changes to enabled prop to update state\n React.useEffect(() => {\n dispatch({ type: 'set_hidden', payload: !isDesktop });\n }, [isDesktop]);\n\n // Sync local storage\n React.useEffect(() => {\n setStoredTours(state);\n }, [state, setStoredTours]);\n\n // Derive all completed tours from state\n const currentAllCompletedState = areAllToursCompleted(state.tours);\n // Store completed state in ref to survive a re-render,\n // when current state changes this will persist and be used for comparison\n const previousAllCompletedStateRef = React.useRef(currentAllCompletedState);\n React.useEffect(() => {\n const previousAllCompletedState = previousAllCompletedStateRef.current;\n // When the previous state was not complete but the current state is now complete, fire the event\n if (!previousAllCompletedState && currentAllCompletedState) {\n trackUsage('didCompleteGuidedTour', { name: 'all' });\n }\n\n // When the current state has all tours completed so will the previous state, the tracking event won't fire again\n previousAllCompletedStateRef.current = currentAllCompletedState;\n }, [currentAllCompletedState, trackUsage]);\n\n return (\n <GuidedTourProviderImpl state={state} dispatch={dispatch}>\n {children}\n </GuidedTourProviderImpl>\n );\n};\n\nexport type { Action, State, ValidTourName };\nexport { GuidedTourContext, useGuidedTour, reducer, getCompletedTours };\n"],"names":["GuidedTourProviderImpl","useGuidedTour","createContext","getInitialTourState","tours","Object","keys","reduce","acc","tourName","currentStep","isCompleted","tourType","undefined","getCompletedTours","filter","areAllToursCompleted","values","every","t","reducer","state","action","produce","draft","type","payload","tourLength","guidedTours","_meta","totalStepCount","nextStep","previousStep","completedActions","Set","completedAction","enabled","hidden","step","currentTour","STORAGE_KEY","GuidedTourContext","children","isDesktop","useIsDesktop","trackUsage","useTracking","storedTours","setStoredTours","usePersistentState","migratedTourState","migrateTours","dispatch","React","useReducer","useEffect","currentAllCompletedState","previousAllCompletedStateRef","useRef","previousAllCompletedState","current","name","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Context.js","sources":["../../../../../../admin/src/components/GuidedTour/Context.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { produce } from 'immer';\n\nimport { useTracking } from '../../features/Tracking';\nimport { useIsDesktop } from '../../hooks/useMediaQuery';\nimport { usePersistentState } from '../../hooks/usePersistentState';\nimport { createContext } from '../Context';\n\nimport { type Tours, tours as guidedTours } from './Tours';\nimport { GUIDED_TOUR_REQUIRED_ACTIONS } from './utils/constants';\nimport { migrateTours } from './utils/migrations';\n\n/* -------------------------------------------------------------------------------------------------\n * GuidedTourProvider\n * -----------------------------------------------------------------------------------------------*/\n\ntype ValidTourName = keyof Tours;\n\n/**\n * Derive the union of all string literal values from GUIDED_TOUR_REQUIRED_ACTIONS\n * (ie didCreateContentTypeSchema | didCreateContent etc...)\n */\ntype ValueOf<T> = T[keyof T];\ntype NonEmptyValueOf<T> = T extends Record<string, never> ? never : ValueOf<T>;\nexport type CompletedActions = NonEmptyValueOf<ValueOf<typeof GUIDED_TOUR_REQUIRED_ACTIONS>>[];\n\ntype Action =\n | {\n type: 'next_step';\n payload: ValidTourName;\n }\n | {\n type: 'previous_step';\n payload: ValidTourName;\n }\n | {\n type: 'go_to_step';\n payload: {\n tourName: ValidTourName;\n step: number;\n };\n }\n | {\n type: 'skip_tour';\n payload: ValidTourName;\n }\n | {\n type: 'skip_all_tours';\n }\n | {\n type: 'reset_all_tours';\n }\n | {\n type: 'set_completed_actions';\n payload: CompletedActions;\n }\n | {\n type: 'remove_completed_action';\n payload: ValueOf<CompletedActions>;\n }\n | {\n type: 'set_tour_type';\n payload: {\n tourName: ValidTourName;\n tourType: 'ContentTypeBuilderAI' | 'ContentTypeBuilderNoAI';\n };\n }\n | {\n type: 'set_hidden';\n payload: boolean;\n };\n\ntype TourState = Record<\n ValidTourName,\n { currentStep: number; isCompleted: boolean; tourType?: string }\n>;\ntype State = {\n tours: TourState;\n enabled: boolean;\n hidden?: boolean;\n completedActions: CompletedActions;\n};\n\nconst [GuidedTourProviderImpl, useGuidedTour] = createContext<{\n state: State;\n dispatch: React.Dispatch<Action>;\n}>('GuidedTour');\n\nconst getInitialTourState = (tours: Tours) => {\n return Object.keys(tours).reduce((acc, tourName) => {\n acc[tourName as ValidTourName] = {\n currentStep: 0,\n isCompleted: false,\n tourType: undefined,\n };\n\n return acc;\n }, {} as TourState);\n};\n\nconst getCompletedTours = (tours: TourState): ValidTourName[] => {\n return Object.keys(tours).filter(\n (tourName) => tours[tourName as ValidTourName].isCompleted\n ) as ValidTourName[];\n};\n\nconst areAllToursCompleted = (tours: TourState) => Object.values(tours).every((t) => t.isCompleted);\n\nfunction reducer(state: State, action: Action): State {\n return produce(state, (draft) => {\n if (action.type === 'next_step') {\n const currentStep = draft.tours[action.payload].currentStep;\n const tourLength = guidedTours[action.payload]._meta.totalStepCount;\n\n const nextStep = currentStep + 1;\n draft.tours[action.payload].currentStep = nextStep;\n draft.tours[action.payload].isCompleted = nextStep >= tourLength;\n }\n\n if (action.type === 'previous_step') {\n const currentStep = draft.tours[action.payload].currentStep;\n\n if (currentStep <= 0) return;\n\n const previousStep = currentStep - 1;\n draft.tours[action.payload].currentStep = previousStep;\n }\n\n if (action.type === 'skip_tour') {\n draft.tours[action.payload].isCompleted = true;\n }\n\n if (action.type === 'set_completed_actions') {\n draft.completedActions = [...new Set([...draft.completedActions, ...action.payload])];\n }\n\n if (action.type === 'remove_completed_action') {\n draft.completedActions = draft.completedActions.filter(\n (completedAction) => completedAction !== action.payload\n );\n }\n\n if (action.type === 'skip_all_tours') {\n draft.enabled = false;\n }\n\n if (action.type === 'set_hidden') {\n draft.hidden = action.payload;\n }\n\n if (action.type === 'reset_all_tours') {\n draft.enabled = true;\n draft.tours = getInitialTourState(guidedTours);\n draft.completedActions = [];\n }\n\n if (action.type === 'go_to_step') {\n draft.tours[action.payload.tourName].currentStep = action.payload.step;\n }\n\n if (action.type === 'set_tour_type') {\n const { tourName, tourType } = action.payload;\n const currentTour = draft.tours[tourName];\n\n // If tour type changes and tour is not completed, reset to step 0\n if (currentTour.tourType && currentTour.tourType !== tourType && !currentTour.isCompleted) {\n currentTour.currentStep = 0;\n }\n\n currentTour.tourType = tourType;\n }\n });\n}\n\nconst STORAGE_KEY = 'STRAPI_GUIDED_TOUR';\nconst GuidedTourContext = ({\n children,\n enabled = true,\n}: {\n children: React.ReactNode;\n enabled?: boolean;\n}) => {\n const isDesktop = useIsDesktop();\n const { trackUsage } = useTracking();\n const [storedTours, setStoredTours] = usePersistentState<State>(STORAGE_KEY, {\n tours: getInitialTourState(guidedTours),\n enabled,\n hidden: !isDesktop,\n completedActions: [],\n });\n const migratedTourState = migrateTours(storedTours);\n const [state, dispatch] = React.useReducer(reducer, migratedTourState);\n\n // Watch for changes to enabled prop to update state\n React.useEffect(() => {\n dispatch({ type: 'set_hidden', payload: !isDesktop });\n }, [isDesktop]);\n\n // Sync into usePersistentState in the layout phase so localStorage is updated before the\n // browser follows an external link (e.g. Strapi Cloud \"Read documentation\").\n React.useLayoutEffect(() => {\n setStoredTours(state);\n }, [state, setStoredTours]);\n\n // Derive all completed tours from state\n const currentAllCompletedState = areAllToursCompleted(state.tours);\n // Store completed state in ref to survive a re-render,\n // when current state changes this will persist and be used for comparison\n const previousAllCompletedStateRef = React.useRef(currentAllCompletedState);\n React.useEffect(() => {\n const previousAllCompletedState = previousAllCompletedStateRef.current;\n // When the previous state was not complete but the current state is now complete, fire the event\n if (!previousAllCompletedState && currentAllCompletedState) {\n trackUsage('didCompleteGuidedTour', { name: 'all' });\n }\n\n // When the current state has all tours completed so will the previous state, the tracking event won't fire again\n previousAllCompletedStateRef.current = currentAllCompletedState;\n }, [currentAllCompletedState, trackUsage]);\n\n return (\n <GuidedTourProviderImpl state={state} dispatch={dispatch}>\n {children}\n </GuidedTourProviderImpl>\n );\n};\n\nexport type { Action, State, ValidTourName };\nexport { GuidedTourContext, useGuidedTour, reducer, getCompletedTours };\n"],"names":["GuidedTourProviderImpl","useGuidedTour","createContext","getInitialTourState","tours","Object","keys","reduce","acc","tourName","currentStep","isCompleted","tourType","undefined","getCompletedTours","filter","areAllToursCompleted","values","every","t","reducer","state","action","produce","draft","type","payload","tourLength","guidedTours","_meta","totalStepCount","nextStep","previousStep","completedActions","Set","completedAction","enabled","hidden","step","currentTour","STORAGE_KEY","GuidedTourContext","children","isDesktop","useIsDesktop","trackUsage","useTracking","storedTours","setStoredTours","usePersistentState","migratedTourState","migrateTours","dispatch","React","useReducer","useEffect","useLayoutEffect","currentAllCompletedState","previousAllCompletedStateRef","useRef","previousAllCompletedState","current","name","_jsx"],"mappings":"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"}
|
|
@@ -98,8 +98,9 @@ const GuidedTourContext = ({ children, enabled = true })=>{
|
|
|
98
98
|
}, [
|
|
99
99
|
isDesktop
|
|
100
100
|
]);
|
|
101
|
-
// Sync
|
|
102
|
-
|
|
101
|
+
// Sync into usePersistentState in the layout phase so localStorage is updated before the
|
|
102
|
+
// browser follows an external link (e.g. Strapi Cloud "Read documentation").
|
|
103
|
+
React.useLayoutEffect(()=>{
|
|
103
104
|
setStoredTours(state);
|
|
104
105
|
}, [
|
|
105
106
|
state,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Context.mjs","sources":["../../../../../../admin/src/components/GuidedTour/Context.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { produce } from 'immer';\n\nimport { useTracking } from '../../features/Tracking';\nimport { useIsDesktop } from '../../hooks/useMediaQuery';\nimport { usePersistentState } from '../../hooks/usePersistentState';\nimport { createContext } from '../Context';\n\nimport { type Tours, tours as guidedTours } from './Tours';\nimport { GUIDED_TOUR_REQUIRED_ACTIONS } from './utils/constants';\nimport { migrateTours } from './utils/migrations';\n\n/* -------------------------------------------------------------------------------------------------\n * GuidedTourProvider\n * -----------------------------------------------------------------------------------------------*/\n\ntype ValidTourName = keyof Tours;\n\n/**\n * Derive the union of all string literal values from GUIDED_TOUR_REQUIRED_ACTIONS\n * (ie didCreateContentTypeSchema | didCreateContent etc...)\n */\ntype ValueOf<T> = T[keyof T];\ntype NonEmptyValueOf<T> = T extends Record<string, never> ? never : ValueOf<T>;\nexport type CompletedActions = NonEmptyValueOf<ValueOf<typeof GUIDED_TOUR_REQUIRED_ACTIONS>>[];\n\ntype Action =\n | {\n type: 'next_step';\n payload: ValidTourName;\n }\n | {\n type: 'previous_step';\n payload: ValidTourName;\n }\n | {\n type: 'go_to_step';\n payload: {\n tourName: ValidTourName;\n step: number;\n };\n }\n | {\n type: 'skip_tour';\n payload: ValidTourName;\n }\n | {\n type: 'skip_all_tours';\n }\n | {\n type: 'reset_all_tours';\n }\n | {\n type: 'set_completed_actions';\n payload: CompletedActions;\n }\n | {\n type: 'remove_completed_action';\n payload: ValueOf<CompletedActions>;\n }\n | {\n type: 'set_tour_type';\n payload: {\n tourName: ValidTourName;\n tourType: 'ContentTypeBuilderAI' | 'ContentTypeBuilderNoAI';\n };\n }\n | {\n type: 'set_hidden';\n payload: boolean;\n };\n\ntype TourState = Record<\n ValidTourName,\n { currentStep: number; isCompleted: boolean; tourType?: string }\n>;\ntype State = {\n tours: TourState;\n enabled: boolean;\n hidden?: boolean;\n completedActions: CompletedActions;\n};\n\nconst [GuidedTourProviderImpl, useGuidedTour] = createContext<{\n state: State;\n dispatch: React.Dispatch<Action>;\n}>('GuidedTour');\n\nconst getInitialTourState = (tours: Tours) => {\n return Object.keys(tours).reduce((acc, tourName) => {\n acc[tourName as ValidTourName] = {\n currentStep: 0,\n isCompleted: false,\n tourType: undefined,\n };\n\n return acc;\n }, {} as TourState);\n};\n\nconst getCompletedTours = (tours: TourState): ValidTourName[] => {\n return Object.keys(tours).filter(\n (tourName) => tours[tourName as ValidTourName].isCompleted\n ) as ValidTourName[];\n};\n\nconst areAllToursCompleted = (tours: TourState) => Object.values(tours).every((t) => t.isCompleted);\n\nfunction reducer(state: State, action: Action): State {\n return produce(state, (draft) => {\n if (action.type === 'next_step') {\n const currentStep = draft.tours[action.payload].currentStep;\n const tourLength = guidedTours[action.payload]._meta.totalStepCount;\n\n const nextStep = currentStep + 1;\n draft.tours[action.payload].currentStep = nextStep;\n draft.tours[action.payload].isCompleted = nextStep >= tourLength;\n }\n\n if (action.type === 'previous_step') {\n const currentStep = draft.tours[action.payload].currentStep;\n\n if (currentStep <= 0) return;\n\n const previousStep = currentStep - 1;\n draft.tours[action.payload].currentStep = previousStep;\n }\n\n if (action.type === 'skip_tour') {\n draft.tours[action.payload].isCompleted = true;\n }\n\n if (action.type === 'set_completed_actions') {\n draft.completedActions = [...new Set([...draft.completedActions, ...action.payload])];\n }\n\n if (action.type === 'remove_completed_action') {\n draft.completedActions = draft.completedActions.filter(\n (completedAction) => completedAction !== action.payload\n );\n }\n\n if (action.type === 'skip_all_tours') {\n draft.enabled = false;\n }\n\n if (action.type === 'set_hidden') {\n draft.hidden = action.payload;\n }\n\n if (action.type === 'reset_all_tours') {\n draft.enabled = true;\n draft.tours = getInitialTourState(guidedTours);\n draft.completedActions = [];\n }\n\n if (action.type === 'go_to_step') {\n draft.tours[action.payload.tourName].currentStep = action.payload.step;\n }\n\n if (action.type === 'set_tour_type') {\n const { tourName, tourType } = action.payload;\n const currentTour = draft.tours[tourName];\n\n // If tour type changes and tour is not completed, reset to step 0\n if (currentTour.tourType && currentTour.tourType !== tourType && !currentTour.isCompleted) {\n currentTour.currentStep = 0;\n }\n\n currentTour.tourType = tourType;\n }\n });\n}\n\nconst STORAGE_KEY = 'STRAPI_GUIDED_TOUR';\nconst GuidedTourContext = ({\n children,\n enabled = true,\n}: {\n children: React.ReactNode;\n enabled?: boolean;\n}) => {\n const isDesktop = useIsDesktop();\n const { trackUsage } = useTracking();\n const [storedTours, setStoredTours] = usePersistentState<State>(STORAGE_KEY, {\n tours: getInitialTourState(guidedTours),\n enabled,\n hidden: !isDesktop,\n completedActions: [],\n });\n const migratedTourState = migrateTours(storedTours);\n const [state, dispatch] = React.useReducer(reducer, migratedTourState);\n\n // Watch for changes to enabled prop to update state\n React.useEffect(() => {\n dispatch({ type: 'set_hidden', payload: !isDesktop });\n }, [isDesktop]);\n\n // Sync local storage\n React.useEffect(() => {\n setStoredTours(state);\n }, [state, setStoredTours]);\n\n // Derive all completed tours from state\n const currentAllCompletedState = areAllToursCompleted(state.tours);\n // Store completed state in ref to survive a re-render,\n // when current state changes this will persist and be used for comparison\n const previousAllCompletedStateRef = React.useRef(currentAllCompletedState);\n React.useEffect(() => {\n const previousAllCompletedState = previousAllCompletedStateRef.current;\n // When the previous state was not complete but the current state is now complete, fire the event\n if (!previousAllCompletedState && currentAllCompletedState) {\n trackUsage('didCompleteGuidedTour', { name: 'all' });\n }\n\n // When the current state has all tours completed so will the previous state, the tracking event won't fire again\n previousAllCompletedStateRef.current = currentAllCompletedState;\n }, [currentAllCompletedState, trackUsage]);\n\n return (\n <GuidedTourProviderImpl state={state} dispatch={dispatch}>\n {children}\n </GuidedTourProviderImpl>\n );\n};\n\nexport type { Action, State, ValidTourName };\nexport { GuidedTourContext, useGuidedTour, reducer, getCompletedTours };\n"],"names":["GuidedTourProviderImpl","useGuidedTour","createContext","getInitialTourState","tours","Object","keys","reduce","acc","tourName","currentStep","isCompleted","tourType","undefined","getCompletedTours","filter","areAllToursCompleted","values","every","t","reducer","state","action","produce","draft","type","payload","tourLength","guidedTours","_meta","totalStepCount","nextStep","previousStep","completedActions","Set","completedAction","enabled","hidden","step","currentTour","STORAGE_KEY","GuidedTourContext","children","isDesktop","useIsDesktop","trackUsage","useTracking","storedTours","setStoredTours","usePersistentState","migratedTourState","migrateTours","dispatch","React","useReducer","useEffect","currentAllCompletedState","previousAllCompletedStateRef","useRef","previousAllCompletedState","current","name","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Context.mjs","sources":["../../../../../../admin/src/components/GuidedTour/Context.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { produce } from 'immer';\n\nimport { useTracking } from '../../features/Tracking';\nimport { useIsDesktop } from '../../hooks/useMediaQuery';\nimport { usePersistentState } from '../../hooks/usePersistentState';\nimport { createContext } from '../Context';\n\nimport { type Tours, tours as guidedTours } from './Tours';\nimport { GUIDED_TOUR_REQUIRED_ACTIONS } from './utils/constants';\nimport { migrateTours } from './utils/migrations';\n\n/* -------------------------------------------------------------------------------------------------\n * GuidedTourProvider\n * -----------------------------------------------------------------------------------------------*/\n\ntype ValidTourName = keyof Tours;\n\n/**\n * Derive the union of all string literal values from GUIDED_TOUR_REQUIRED_ACTIONS\n * (ie didCreateContentTypeSchema | didCreateContent etc...)\n */\ntype ValueOf<T> = T[keyof T];\ntype NonEmptyValueOf<T> = T extends Record<string, never> ? never : ValueOf<T>;\nexport type CompletedActions = NonEmptyValueOf<ValueOf<typeof GUIDED_TOUR_REQUIRED_ACTIONS>>[];\n\ntype Action =\n | {\n type: 'next_step';\n payload: ValidTourName;\n }\n | {\n type: 'previous_step';\n payload: ValidTourName;\n }\n | {\n type: 'go_to_step';\n payload: {\n tourName: ValidTourName;\n step: number;\n };\n }\n | {\n type: 'skip_tour';\n payload: ValidTourName;\n }\n | {\n type: 'skip_all_tours';\n }\n | {\n type: 'reset_all_tours';\n }\n | {\n type: 'set_completed_actions';\n payload: CompletedActions;\n }\n | {\n type: 'remove_completed_action';\n payload: ValueOf<CompletedActions>;\n }\n | {\n type: 'set_tour_type';\n payload: {\n tourName: ValidTourName;\n tourType: 'ContentTypeBuilderAI' | 'ContentTypeBuilderNoAI';\n };\n }\n | {\n type: 'set_hidden';\n payload: boolean;\n };\n\ntype TourState = Record<\n ValidTourName,\n { currentStep: number; isCompleted: boolean; tourType?: string }\n>;\ntype State = {\n tours: TourState;\n enabled: boolean;\n hidden?: boolean;\n completedActions: CompletedActions;\n};\n\nconst [GuidedTourProviderImpl, useGuidedTour] = createContext<{\n state: State;\n dispatch: React.Dispatch<Action>;\n}>('GuidedTour');\n\nconst getInitialTourState = (tours: Tours) => {\n return Object.keys(tours).reduce((acc, tourName) => {\n acc[tourName as ValidTourName] = {\n currentStep: 0,\n isCompleted: false,\n tourType: undefined,\n };\n\n return acc;\n }, {} as TourState);\n};\n\nconst getCompletedTours = (tours: TourState): ValidTourName[] => {\n return Object.keys(tours).filter(\n (tourName) => tours[tourName as ValidTourName].isCompleted\n ) as ValidTourName[];\n};\n\nconst areAllToursCompleted = (tours: TourState) => Object.values(tours).every((t) => t.isCompleted);\n\nfunction reducer(state: State, action: Action): State {\n return produce(state, (draft) => {\n if (action.type === 'next_step') {\n const currentStep = draft.tours[action.payload].currentStep;\n const tourLength = guidedTours[action.payload]._meta.totalStepCount;\n\n const nextStep = currentStep + 1;\n draft.tours[action.payload].currentStep = nextStep;\n draft.tours[action.payload].isCompleted = nextStep >= tourLength;\n }\n\n if (action.type === 'previous_step') {\n const currentStep = draft.tours[action.payload].currentStep;\n\n if (currentStep <= 0) return;\n\n const previousStep = currentStep - 1;\n draft.tours[action.payload].currentStep = previousStep;\n }\n\n if (action.type === 'skip_tour') {\n draft.tours[action.payload].isCompleted = true;\n }\n\n if (action.type === 'set_completed_actions') {\n draft.completedActions = [...new Set([...draft.completedActions, ...action.payload])];\n }\n\n if (action.type === 'remove_completed_action') {\n draft.completedActions = draft.completedActions.filter(\n (completedAction) => completedAction !== action.payload\n );\n }\n\n if (action.type === 'skip_all_tours') {\n draft.enabled = false;\n }\n\n if (action.type === 'set_hidden') {\n draft.hidden = action.payload;\n }\n\n if (action.type === 'reset_all_tours') {\n draft.enabled = true;\n draft.tours = getInitialTourState(guidedTours);\n draft.completedActions = [];\n }\n\n if (action.type === 'go_to_step') {\n draft.tours[action.payload.tourName].currentStep = action.payload.step;\n }\n\n if (action.type === 'set_tour_type') {\n const { tourName, tourType } = action.payload;\n const currentTour = draft.tours[tourName];\n\n // If tour type changes and tour is not completed, reset to step 0\n if (currentTour.tourType && currentTour.tourType !== tourType && !currentTour.isCompleted) {\n currentTour.currentStep = 0;\n }\n\n currentTour.tourType = tourType;\n }\n });\n}\n\nconst STORAGE_KEY = 'STRAPI_GUIDED_TOUR';\nconst GuidedTourContext = ({\n children,\n enabled = true,\n}: {\n children: React.ReactNode;\n enabled?: boolean;\n}) => {\n const isDesktop = useIsDesktop();\n const { trackUsage } = useTracking();\n const [storedTours, setStoredTours] = usePersistentState<State>(STORAGE_KEY, {\n tours: getInitialTourState(guidedTours),\n enabled,\n hidden: !isDesktop,\n completedActions: [],\n });\n const migratedTourState = migrateTours(storedTours);\n const [state, dispatch] = React.useReducer(reducer, migratedTourState);\n\n // Watch for changes to enabled prop to update state\n React.useEffect(() => {\n dispatch({ type: 'set_hidden', payload: !isDesktop });\n }, [isDesktop]);\n\n // Sync into usePersistentState in the layout phase so localStorage is updated before the\n // browser follows an external link (e.g. Strapi Cloud \"Read documentation\").\n React.useLayoutEffect(() => {\n setStoredTours(state);\n }, [state, setStoredTours]);\n\n // Derive all completed tours from state\n const currentAllCompletedState = areAllToursCompleted(state.tours);\n // Store completed state in ref to survive a re-render,\n // when current state changes this will persist and be used for comparison\n const previousAllCompletedStateRef = React.useRef(currentAllCompletedState);\n React.useEffect(() => {\n const previousAllCompletedState = previousAllCompletedStateRef.current;\n // When the previous state was not complete but the current state is now complete, fire the event\n if (!previousAllCompletedState && currentAllCompletedState) {\n trackUsage('didCompleteGuidedTour', { name: 'all' });\n }\n\n // When the current state has all tours completed so will the previous state, the tracking event won't fire again\n previousAllCompletedStateRef.current = currentAllCompletedState;\n }, [currentAllCompletedState, trackUsage]);\n\n return (\n <GuidedTourProviderImpl state={state} dispatch={dispatch}>\n {children}\n </GuidedTourProviderImpl>\n );\n};\n\nexport type { Action, State, ValidTourName };\nexport { GuidedTourContext, useGuidedTour, reducer, getCompletedTours };\n"],"names":["GuidedTourProviderImpl","useGuidedTour","createContext","getInitialTourState","tours","Object","keys","reduce","acc","tourName","currentStep","isCompleted","tourType","undefined","getCompletedTours","filter","areAllToursCompleted","values","every","t","reducer","state","action","produce","draft","type","payload","tourLength","guidedTours","_meta","totalStepCount","nextStep","previousStep","completedActions","Set","completedAction","enabled","hidden","step","currentTour","STORAGE_KEY","GuidedTourContext","children","isDesktop","useIsDesktop","trackUsage","useTracking","storedTours","setStoredTours","usePersistentState","migratedTourState","migrateTours","dispatch","React","useReducer","useEffect","useLayoutEffect","currentAllCompletedState","previousAllCompletedStateRef","useRef","previousAllCompletedState","current","name","_jsx"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Layout.js","sources":["../../../../../../admin/src/components/Layouts/Layout.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, BoxProps, Flex } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\nimport { RESPONSIVE_DEFAULT_SPACING } from '../../constants/theme';\n\nimport { ActionLayout } from './ActionLayout';\nimport { ContentLayout } from './ContentLayout';\nimport { GridLayout, GridLayoutProps } from './GridLayout';\nimport { HeaderLayout, BaseHeaderLayout } from './HeaderLayout';\n\ninterface LayoutProps extends BoxProps {\n children: React.ReactNode;\n sideNav?: React.ReactNode;\n}\n\nconst GridContainer = styled(Box)<{ $hasSideNav: boolean }>`\n width: 100%;\n flex: 1;\n display: grid;\n grid-template-columns: 1fr;\n padding: 0;\n\n ${({ theme }) => theme.breakpoints.medium} {\n overflow: hidden;\n grid-template-columns: ${({ $hasSideNav }) => ($hasSideNav ? `auto 1fr` : '1fr')};\n }\n`;\n\nconst SideNavContainer = styled(Flex)`\n overflow: hidden;\n display: none;\n background: ${({ theme }) => theme.colors.neutral0};\n\n ${({ theme }) => theme.breakpoints.medium} {\n display: block;\n box-shadow: none;\n transform: none;\n }\n`;\n\nconst OverflowingItem = styled(Box)`\n overflow-x: hidden;\n\n ${({ theme }) => theme.breakpoints.medium} {\n transform: none;\n width: auto;\n }\n`;\n\nconst RootLayout = ({ sideNav, children, ...restProps }: LayoutProps) => (\n <GridContainer $hasSideNav={Boolean(sideNav)} {...restProps}>\n {sideNav && <SideNavContainer>{sideNav}</SideNavContainer>}\n <OverflowingItem paddingBottom={RESPONSIVE_DEFAULT_SPACING} data-strapi-main-content>\n {children}\n </OverflowingItem>\n </GridContainer>\n);\n\nconst Layouts = {\n Root: RootLayout,\n Header: HeaderLayout,\n BaseHeader: BaseHeaderLayout,\n Grid: GridLayout,\n Action: ActionLayout,\n Content: ContentLayout,\n};\n\nexport { Layouts, type LayoutProps, type GridLayoutProps };\n"],"names":["GridContainer","styled","Box","theme","breakpoints","medium","$hasSideNav","SideNavContainer","Flex","colors","neutral0","OverflowingItem","RootLayout","sideNav","children","restProps","_jsxs","Boolean","_jsx","paddingBottom","RESPONSIVE_DEFAULT_SPACING","data-strapi-main-content","Layouts","Root","Header","HeaderLayout","BaseHeader","BaseHeaderLayout","Grid","GridLayout","Action","ActionLayout","Content","ContentLayout"],"mappings":";;;;;;;;;;;;AAiBA,MAAMA,aAAAA,GAAgBC,aAAAA,CAAOC,gBAAAA,CAA8B;;;;;;;EAOzD,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;;2BAEjB,EAAE,CAAC,EAAEC,WAAW,EAAE,GAAMA,cAAc,CAAC,QAAQ,CAAC,GAAG,KAAA,CAAO;;AAErF,CAAC;AAED,MAAMC,gBAAAA,GAAmBN,aAAAA,CAAOO,iBAAAA,CAAK;;;cAGvB,EAAE,CAAC,EAAEL,KAAK,EAAE,GAAKA,KAAAA,CAAMM,MAAM,CAACC,QAAQ,CAAC;;EAEnD,EAAE,CAAC,EAAEP,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;;;;;AAK5C,CAAC;AAED,MAAMM,eAAAA,GAAkBV,aAAAA,CAAOC,gBAAAA,CAAI
|
|
1
|
+
{"version":3,"file":"Layout.js","sources":["../../../../../../admin/src/components/Layouts/Layout.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, BoxProps, Flex } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\nimport { RESPONSIVE_DEFAULT_SPACING } from '../../constants/theme';\n\nimport { ActionLayout } from './ActionLayout';\nimport { ContentLayout } from './ContentLayout';\nimport { GridLayout, GridLayoutProps } from './GridLayout';\nimport { HeaderLayout, BaseHeaderLayout } from './HeaderLayout';\n\ninterface LayoutProps extends BoxProps {\n children: React.ReactNode;\n sideNav?: React.ReactNode;\n}\n\nconst GridContainer = styled(Box)<{ $hasSideNav: boolean }>`\n width: 100%;\n flex: 1;\n display: grid;\n grid-template-columns: 1fr;\n padding: 0;\n\n ${({ theme }) => theme.breakpoints.medium} {\n overflow: hidden;\n grid-template-columns: ${({ $hasSideNav }) => ($hasSideNav ? `auto 1fr` : '1fr')};\n }\n`;\n\nconst SideNavContainer = styled(Flex)`\n overflow: hidden;\n display: none;\n background: ${({ theme }) => theme.colors.neutral0};\n\n ${({ theme }) => theme.breakpoints.medium} {\n display: block;\n box-shadow: none;\n transform: none;\n }\n`;\n\nconst OverflowingItem = styled(Box)`\n position: relative;\n overflow-x: hidden;\n\n ${({ theme }) => theme.breakpoints.medium} {\n transform: none;\n width: auto;\n }\n`;\n\nconst RootLayout = ({ sideNav, children, ...restProps }: LayoutProps) => (\n <GridContainer $hasSideNav={Boolean(sideNav)} {...restProps}>\n {sideNav && <SideNavContainer>{sideNav}</SideNavContainer>}\n <OverflowingItem paddingBottom={RESPONSIVE_DEFAULT_SPACING} data-strapi-main-content>\n {children}\n </OverflowingItem>\n </GridContainer>\n);\n\nconst Layouts = {\n Root: RootLayout,\n Header: HeaderLayout,\n BaseHeader: BaseHeaderLayout,\n Grid: GridLayout,\n Action: ActionLayout,\n Content: ContentLayout,\n};\n\nexport { Layouts, type LayoutProps, type GridLayoutProps };\n"],"names":["GridContainer","styled","Box","theme","breakpoints","medium","$hasSideNav","SideNavContainer","Flex","colors","neutral0","OverflowingItem","RootLayout","sideNav","children","restProps","_jsxs","Boolean","_jsx","paddingBottom","RESPONSIVE_DEFAULT_SPACING","data-strapi-main-content","Layouts","Root","Header","HeaderLayout","BaseHeader","BaseHeaderLayout","Grid","GridLayout","Action","ActionLayout","Content","ContentLayout"],"mappings":";;;;;;;;;;;;AAiBA,MAAMA,aAAAA,GAAgBC,aAAAA,CAAOC,gBAAAA,CAA8B;;;;;;;EAOzD,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;;2BAEjB,EAAE,CAAC,EAAEC,WAAW,EAAE,GAAMA,cAAc,CAAC,QAAQ,CAAC,GAAG,KAAA,CAAO;;AAErF,CAAC;AAED,MAAMC,gBAAAA,GAAmBN,aAAAA,CAAOO,iBAAAA,CAAK;;;cAGvB,EAAE,CAAC,EAAEL,KAAK,EAAE,GAAKA,KAAAA,CAAMM,MAAM,CAACC,QAAQ,CAAC;;EAEnD,EAAE,CAAC,EAAEP,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;;;;;AAK5C,CAAC;AAED,MAAMM,eAAAA,GAAkBV,aAAAA,CAAOC,gBAAAA,CAAI;;;;EAIjC,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;;;;AAI5C,CAAC;AAED,MAAMO,UAAAA,GAAa,CAAC,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGC,SAAAA,EAAwB,iBAClEC,eAAA,CAAChB,aAAAA,EAAAA;AAAcM,QAAAA,WAAAA,EAAaW,OAAAA,CAAQJ,OAAAA,CAAAA;AAAW,QAAA,GAAGE,SAAS;;AACxDF,YAAAA,OAAAA,kBAAWK,cAAA,CAACX,gBAAAA,EAAAA;AAAkBM,gBAAAA,QAAAA,EAAAA;;0BAC/BK,cAAA,CAACP,eAAAA,EAAAA;gBAAgBQ,aAAAA,EAAeC,gCAAAA;gBAA4BC,0BAAwB,EAAA,IAAA;AACjFP,gBAAAA,QAAAA,EAAAA;;;;AAKP,MAAMQ,OAAAA,GAAU;IACdC,IAAAA,EAAMX,UAAAA;IACNY,MAAAA,EAAQC,yBAAAA;IACRC,UAAAA,EAAYC,6BAAAA;IACZC,IAAAA,EAAMC,qBAAAA;IACNC,MAAAA,EAAQC,yBAAAA;IACRC,OAAAA,EAASC;AACX;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Layout.mjs","sources":["../../../../../../admin/src/components/Layouts/Layout.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, BoxProps, Flex } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\nimport { RESPONSIVE_DEFAULT_SPACING } from '../../constants/theme';\n\nimport { ActionLayout } from './ActionLayout';\nimport { ContentLayout } from './ContentLayout';\nimport { GridLayout, GridLayoutProps } from './GridLayout';\nimport { HeaderLayout, BaseHeaderLayout } from './HeaderLayout';\n\ninterface LayoutProps extends BoxProps {\n children: React.ReactNode;\n sideNav?: React.ReactNode;\n}\n\nconst GridContainer = styled(Box)<{ $hasSideNav: boolean }>`\n width: 100%;\n flex: 1;\n display: grid;\n grid-template-columns: 1fr;\n padding: 0;\n\n ${({ theme }) => theme.breakpoints.medium} {\n overflow: hidden;\n grid-template-columns: ${({ $hasSideNav }) => ($hasSideNav ? `auto 1fr` : '1fr')};\n }\n`;\n\nconst SideNavContainer = styled(Flex)`\n overflow: hidden;\n display: none;\n background: ${({ theme }) => theme.colors.neutral0};\n\n ${({ theme }) => theme.breakpoints.medium} {\n display: block;\n box-shadow: none;\n transform: none;\n }\n`;\n\nconst OverflowingItem = styled(Box)`\n overflow-x: hidden;\n\n ${({ theme }) => theme.breakpoints.medium} {\n transform: none;\n width: auto;\n }\n`;\n\nconst RootLayout = ({ sideNav, children, ...restProps }: LayoutProps) => (\n <GridContainer $hasSideNav={Boolean(sideNav)} {...restProps}>\n {sideNav && <SideNavContainer>{sideNav}</SideNavContainer>}\n <OverflowingItem paddingBottom={RESPONSIVE_DEFAULT_SPACING} data-strapi-main-content>\n {children}\n </OverflowingItem>\n </GridContainer>\n);\n\nconst Layouts = {\n Root: RootLayout,\n Header: HeaderLayout,\n BaseHeader: BaseHeaderLayout,\n Grid: GridLayout,\n Action: ActionLayout,\n Content: ContentLayout,\n};\n\nexport { Layouts, type LayoutProps, type GridLayoutProps };\n"],"names":["GridContainer","styled","Box","theme","breakpoints","medium","$hasSideNav","SideNavContainer","Flex","colors","neutral0","OverflowingItem","RootLayout","sideNav","children","restProps","_jsxs","Boolean","_jsx","paddingBottom","RESPONSIVE_DEFAULT_SPACING","data-strapi-main-content","Layouts","Root","Header","HeaderLayout","BaseHeader","BaseHeaderLayout","Grid","GridLayout","Action","ActionLayout","Content","ContentLayout"],"mappings":";;;;;;;;;;AAiBA,MAAMA,aAAAA,GAAgBC,MAAAA,CAAOC,GAAAA,CAA8B;;;;;;;EAOzD,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;;2BAEjB,EAAE,CAAC,EAAEC,WAAW,EAAE,GAAMA,cAAc,CAAC,QAAQ,CAAC,GAAG,KAAA,CAAO;;AAErF,CAAC;AAED,MAAMC,gBAAAA,GAAmBN,MAAAA,CAAOO,IAAAA,CAAK;;;cAGvB,EAAE,CAAC,EAAEL,KAAK,EAAE,GAAKA,KAAAA,CAAMM,MAAM,CAACC,QAAQ,CAAC;;EAEnD,EAAE,CAAC,EAAEP,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;;;;;AAK5C,CAAC;AAED,MAAMM,eAAAA,GAAkBV,MAAAA,CAAOC,GAAAA,CAAI
|
|
1
|
+
{"version":3,"file":"Layout.mjs","sources":["../../../../../../admin/src/components/Layouts/Layout.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, BoxProps, Flex } from '@strapi/design-system';\nimport { styled } from 'styled-components';\n\nimport { RESPONSIVE_DEFAULT_SPACING } from '../../constants/theme';\n\nimport { ActionLayout } from './ActionLayout';\nimport { ContentLayout } from './ContentLayout';\nimport { GridLayout, GridLayoutProps } from './GridLayout';\nimport { HeaderLayout, BaseHeaderLayout } from './HeaderLayout';\n\ninterface LayoutProps extends BoxProps {\n children: React.ReactNode;\n sideNav?: React.ReactNode;\n}\n\nconst GridContainer = styled(Box)<{ $hasSideNav: boolean }>`\n width: 100%;\n flex: 1;\n display: grid;\n grid-template-columns: 1fr;\n padding: 0;\n\n ${({ theme }) => theme.breakpoints.medium} {\n overflow: hidden;\n grid-template-columns: ${({ $hasSideNav }) => ($hasSideNav ? `auto 1fr` : '1fr')};\n }\n`;\n\nconst SideNavContainer = styled(Flex)`\n overflow: hidden;\n display: none;\n background: ${({ theme }) => theme.colors.neutral0};\n\n ${({ theme }) => theme.breakpoints.medium} {\n display: block;\n box-shadow: none;\n transform: none;\n }\n`;\n\nconst OverflowingItem = styled(Box)`\n position: relative;\n overflow-x: hidden;\n\n ${({ theme }) => theme.breakpoints.medium} {\n transform: none;\n width: auto;\n }\n`;\n\nconst RootLayout = ({ sideNav, children, ...restProps }: LayoutProps) => (\n <GridContainer $hasSideNav={Boolean(sideNav)} {...restProps}>\n {sideNav && <SideNavContainer>{sideNav}</SideNavContainer>}\n <OverflowingItem paddingBottom={RESPONSIVE_DEFAULT_SPACING} data-strapi-main-content>\n {children}\n </OverflowingItem>\n </GridContainer>\n);\n\nconst Layouts = {\n Root: RootLayout,\n Header: HeaderLayout,\n BaseHeader: BaseHeaderLayout,\n Grid: GridLayout,\n Action: ActionLayout,\n Content: ContentLayout,\n};\n\nexport { Layouts, type LayoutProps, type GridLayoutProps };\n"],"names":["GridContainer","styled","Box","theme","breakpoints","medium","$hasSideNav","SideNavContainer","Flex","colors","neutral0","OverflowingItem","RootLayout","sideNav","children","restProps","_jsxs","Boolean","_jsx","paddingBottom","RESPONSIVE_DEFAULT_SPACING","data-strapi-main-content","Layouts","Root","Header","HeaderLayout","BaseHeader","BaseHeaderLayout","Grid","GridLayout","Action","ActionLayout","Content","ContentLayout"],"mappings":";;;;;;;;;;AAiBA,MAAMA,aAAAA,GAAgBC,MAAAA,CAAOC,GAAAA,CAA8B;;;;;;;EAOzD,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;;2BAEjB,EAAE,CAAC,EAAEC,WAAW,EAAE,GAAMA,cAAc,CAAC,QAAQ,CAAC,GAAG,KAAA,CAAO;;AAErF,CAAC;AAED,MAAMC,gBAAAA,GAAmBN,MAAAA,CAAOO,IAAAA,CAAK;;;cAGvB,EAAE,CAAC,EAAEL,KAAK,EAAE,GAAKA,KAAAA,CAAMM,MAAM,CAACC,QAAQ,CAAC;;EAEnD,EAAE,CAAC,EAAEP,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;;;;;AAK5C,CAAC;AAED,MAAMM,eAAAA,GAAkBV,MAAAA,CAAOC,GAAAA,CAAI;;;;EAIjC,EAAE,CAAC,EAAEC,KAAK,EAAE,GAAKA,KAAAA,CAAMC,WAAW,CAACC,MAAM,CAAC;;;;AAI5C,CAAC;AAED,MAAMO,UAAAA,GAAa,CAAC,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGC,SAAAA,EAAwB,iBAClEC,IAAA,CAAChB,aAAAA,EAAAA;AAAcM,QAAAA,WAAAA,EAAaW,OAAAA,CAAQJ,OAAAA,CAAAA;AAAW,QAAA,GAAGE,SAAS;;AACxDF,YAAAA,OAAAA,kBAAWK,GAAA,CAACX,gBAAAA,EAAAA;AAAkBM,gBAAAA,QAAAA,EAAAA;;0BAC/BK,GAAA,CAACP,eAAAA,EAAAA;gBAAgBQ,aAAAA,EAAeC,0BAAAA;gBAA4BC,0BAAwB,EAAA,IAAA;AACjFP,gBAAAA,QAAAA,EAAAA;;;;AAKP,MAAMQ,OAAAA,GAAU;IACdC,IAAAA,EAAMX,UAAAA;IACNY,MAAAA,EAAQC,YAAAA;IACRC,UAAAA,EAAYC,gBAAAA;IACZC,IAAAA,EAAMC,UAAAA;IACNC,MAAAA,EAAQC,YAAAA;IACRC,OAAAA,EAASC;AACX;;;;"}
|
|
@@ -155,7 +155,7 @@ const PageMain = ({ children, ...restProps })=>{
|
|
|
155
155
|
const userPermissions = Auth.useAuth('Protect', (state)=>state.permissions);
|
|
156
156
|
const { toggleNotification } = Notifications.useNotification();
|
|
157
157
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler.useAPIErrorHandler();
|
|
158
|
-
const matchingPermissions = userPermissions.filter((permission)=>permissions.findIndex((perm)=>perm.action === permission.action && perm.subject === permission.subject) >= 0);
|
|
158
|
+
const matchingPermissions = (userPermissions || []).filter((permission)=>permissions.findIndex((perm)=>perm.action === permission.action && perm.subject === permission.subject) >= 0);
|
|
159
159
|
const shouldCheckConditions = matchingPermissions.some((perm)=>Array.isArray(perm.conditions) && perm.conditions.length > 0);
|
|
160
160
|
const { isLoading, error, data } = auth.useCheckPermissionsQuery({
|
|
161
161
|
permissions: matchingPermissions.map((perm)=>({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageHelpers.js","sources":["../../../../../admin/src/components/PageHelpers.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Box,\n EmptyStateLayout,\n type EmptyStateLayoutProps,\n Flex,\n Loader,\n Main,\n MainProps,\n} from '@strapi/design-system';\nimport { WarningCircle } from '@strapi/icons';\nimport { EmptyPermissions, EmptyDocuments } from '@strapi/icons/symbols';\nimport { useIntl } from 'react-intl';\n\nimport { useAuth, Permission } from '../features/Auth';\nimport { useNotification } from '../features/Notifications';\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useCheckPermissionsQuery } from '../services/auth';\n\n/* -------------------------------------------------------------------------------------------------\n * Main\n * -----------------------------------------------------------------------------------------------*/\ninterface PageMainProps extends MainProps {\n children: React.ReactNode;\n}\n\nconst PageMain = ({ children, ...restProps }: PageMainProps) => {\n return <Main {...restProps}>{children}</Main>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Loading\n * -----------------------------------------------------------------------------------------------*/\ninterface LoadingProps {\n /**\n * @default 'Loading content.'\n */\n children?: React.ReactNode;\n}\n\n/**\n * @public\n * @description A loading component that should be rendered as the page\n * whilst you load the content for the aforementioned page.\n */\nconst Loading = ({ children = 'Loading content.' }: LoadingProps) => {\n return (\n <PageMain height=\"100dvh\" aria-busy={true}>\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <Loader>{children}</Loader>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Error\n * -----------------------------------------------------------------------------------------------*/\ninterface ErrorProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * TODO: should we start passing our errors here so they're persisted on the screen?\n * This could follow something similar to how the global app error works...?\n */\n\n/**\n * @public\n * @description An error component that should be rendered as the page\n * when an error occurs.\n */\nconst Error = (props: ErrorProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\">\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <EmptyStateLayout\n icon={<WarningCircle width=\"16rem\" />}\n content={formatMessage({\n id: 'anErrorOccurred',\n defaultMessage: 'Whoops! Something went wrong. Please, try again.',\n })}\n {...props}\n />\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * NoPermissions\n * -----------------------------------------------------------------------------------------------*/\ninterface NoPermissionsProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * @public\n * @description A component that should be rendered as the page\n * when the user does not have the permissions to access the content.\n * This component does not check any permissions, it's up to you to decide\n * when it should be rendered.\n */\nconst NoPermissions = (props: NoPermissionsProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\">\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <Box minWidth=\"50%\">\n <EmptyStateLayout\n icon={<EmptyPermissions width=\"16rem\" />}\n content={formatMessage({\n id: 'app.components.EmptyStateLayout.content-permissions',\n defaultMessage: \"You don't have the permissions to access that content\",\n })}\n {...props}\n />\n </Box>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * NoData\n * -----------------------------------------------------------------------------------------------*/\ninterface NoDataProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * @public\n * @description A component that should be rendered as the page\n * when there is no data available to display.\n * This component does not check any permissions, it's up to you to decide\n * when it should be rendered.\n */\nconst NoData = (props: NoDataProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\" background=\"neutral100\">\n <Flex alignItems=\"center\" height=\"100%\" width=\"100%\" justifyContent=\"center\">\n <Box minWidth=\"50%\">\n <EmptyStateLayout\n icon={<EmptyDocuments width=\"16rem\" />}\n action={props.action}\n content={formatMessage({\n id: 'app.components.EmptyStateLayout.content-document',\n defaultMessage: 'No content found',\n })}\n {...props}\n />\n </Box>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Protect\n * -----------------------------------------------------------------------------------------------*/\nexport interface ProtectProps {\n /**\n * The children to render if the user has the required permissions.\n * If providing a function, it will be called with an object containing\n * the permissions the user has based on the array you passed to the component.\n */\n children: React.ReactNode | ((args: { permissions: Permission[] }) => React.ReactNode);\n /**\n * The permissions the user needs to have to access the content.\n */\n permissions?: Array<Omit<Partial<Permission>, 'action'> & Pick<Permission, 'action'>>;\n}\n\n/**\n * @public\n * @description A wrapper component that should be used to protect a page. It will check the permissions\n * you pass to it and render the children if the user has the required permissions. If a user does not have ALL\n * the required permissions, it will redirect the user to the home page. Whilst these checks happen it will render\n * the loading component and should the check fail it will render the error component with a notification.\n */\nconst Protect = ({ permissions = [], children }: ProtectProps) => {\n const userPermissions = useAuth('Protect', (state) => state.permissions);\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n\n const matchingPermissions = userPermissions.filter(\n (permission) =>\n permissions.findIndex(\n (perm) => perm.action === permission.action && perm.subject === permission.subject\n ) >= 0\n );\n\n const shouldCheckConditions = matchingPermissions.some(\n (perm) => Array.isArray(perm.conditions) && perm.conditions.length > 0\n );\n\n const { isLoading, error, data } = useCheckPermissionsQuery(\n {\n permissions: matchingPermissions.map((perm) => ({\n action: perm.action,\n subject: perm.subject,\n })),\n },\n {\n skip: !shouldCheckConditions,\n }\n );\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n }\n }, [error, formatAPIError, toggleNotification]);\n\n if (isLoading) {\n return <Loading />;\n }\n\n if (error) {\n return <Error />;\n }\n\n const { data: permissionsData } = data || {};\n\n const canAccess =\n shouldCheckConditions && permissionsData\n ? !permissionsData.includes(false)\n : matchingPermissions.length > 0;\n\n if (!canAccess) {\n return <NoPermissions />;\n }\n\n return (\n <>\n {typeof children === 'function' ? children({ permissions: matchingPermissions }) : children}\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Title\n * -----------------------------------------------------------------------------------------------*/\nexport interface TitleProps {\n children: string;\n}\n\n/**\n * @public\n * @description This component takes the children (must be a string) and sets\n * it as the title of the html.\n */\nconst Title = ({ children: title }: TitleProps) => {\n React.useEffect(() => {\n document.title = `${title} | Strapi`;\n }, [title]);\n\n return null;\n};\n\nconst Page = {\n Error,\n Loading,\n NoPermissions,\n Protect,\n NoData,\n Main: PageMain,\n Title,\n};\n\nexport { Page };\nexport type { ErrorProps, LoadingProps, NoPermissionsProps, PageMainProps as MainProps };\n"],"names":["PageMain","children","restProps","_jsx","Main","Loading","height","aria-busy","Flex","alignItems","justifyContent","Loader","Error","props","formatMessage","useIntl","EmptyStateLayout","icon","WarningCircle","width","content","id","defaultMessage","NoPermissions","Box","minWidth","EmptyPermissions","NoData","background","EmptyDocuments","action","Protect","permissions","userPermissions","useAuth","state","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","matchingPermissions","filter","permission","findIndex","perm","subject","shouldCheckConditions","some","Array","isArray","conditions","length","isLoading","error","data","useCheckPermissionsQuery","map","skip","React","useEffect","type","message","permissionsData","canAccess","includes","_Fragment","Title","title","document","Page"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PageHelpers.js","sources":["../../../../../admin/src/components/PageHelpers.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Box,\n EmptyStateLayout,\n type EmptyStateLayoutProps,\n Flex,\n Loader,\n Main,\n MainProps,\n} from '@strapi/design-system';\nimport { WarningCircle } from '@strapi/icons';\nimport { EmptyPermissions, EmptyDocuments } from '@strapi/icons/symbols';\nimport { useIntl } from 'react-intl';\n\nimport { useAuth, Permission } from '../features/Auth';\nimport { useNotification } from '../features/Notifications';\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useCheckPermissionsQuery } from '../services/auth';\n\n/* -------------------------------------------------------------------------------------------------\n * Main\n * -----------------------------------------------------------------------------------------------*/\ninterface PageMainProps extends MainProps {\n children: React.ReactNode;\n}\n\nconst PageMain = ({ children, ...restProps }: PageMainProps) => {\n return <Main {...restProps}>{children}</Main>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Loading\n * -----------------------------------------------------------------------------------------------*/\ninterface LoadingProps {\n /**\n * @default 'Loading content.'\n */\n children?: React.ReactNode;\n}\n\n/**\n * @public\n * @description A loading component that should be rendered as the page\n * whilst you load the content for the aforementioned page.\n */\nconst Loading = ({ children = 'Loading content.' }: LoadingProps) => {\n return (\n <PageMain height=\"100dvh\" aria-busy={true}>\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <Loader>{children}</Loader>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Error\n * -----------------------------------------------------------------------------------------------*/\ninterface ErrorProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * TODO: should we start passing our errors here so they're persisted on the screen?\n * This could follow something similar to how the global app error works...?\n */\n\n/**\n * @public\n * @description An error component that should be rendered as the page\n * when an error occurs.\n */\nconst Error = (props: ErrorProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\">\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <EmptyStateLayout\n icon={<WarningCircle width=\"16rem\" />}\n content={formatMessage({\n id: 'anErrorOccurred',\n defaultMessage: 'Whoops! Something went wrong. Please, try again.',\n })}\n {...props}\n />\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * NoPermissions\n * -----------------------------------------------------------------------------------------------*/\ninterface NoPermissionsProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * @public\n * @description A component that should be rendered as the page\n * when the user does not have the permissions to access the content.\n * This component does not check any permissions, it's up to you to decide\n * when it should be rendered.\n */\nconst NoPermissions = (props: NoPermissionsProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\">\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <Box minWidth=\"50%\">\n <EmptyStateLayout\n icon={<EmptyPermissions width=\"16rem\" />}\n content={formatMessage({\n id: 'app.components.EmptyStateLayout.content-permissions',\n defaultMessage: \"You don't have the permissions to access that content\",\n })}\n {...props}\n />\n </Box>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * NoData\n * -----------------------------------------------------------------------------------------------*/\ninterface NoDataProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * @public\n * @description A component that should be rendered as the page\n * when there is no data available to display.\n * This component does not check any permissions, it's up to you to decide\n * when it should be rendered.\n */\nconst NoData = (props: NoDataProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\" background=\"neutral100\">\n <Flex alignItems=\"center\" height=\"100%\" width=\"100%\" justifyContent=\"center\">\n <Box minWidth=\"50%\">\n <EmptyStateLayout\n icon={<EmptyDocuments width=\"16rem\" />}\n action={props.action}\n content={formatMessage({\n id: 'app.components.EmptyStateLayout.content-document',\n defaultMessage: 'No content found',\n })}\n {...props}\n />\n </Box>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Protect\n * -----------------------------------------------------------------------------------------------*/\nexport interface ProtectProps {\n /**\n * The children to render if the user has the required permissions.\n * If providing a function, it will be called with an object containing\n * the permissions the user has based on the array you passed to the component.\n */\n children: React.ReactNode | ((args: { permissions: Permission[] }) => React.ReactNode);\n /**\n * The permissions the user needs to have to access the content.\n */\n permissions?: Array<Omit<Partial<Permission>, 'action'> & Pick<Permission, 'action'>>;\n}\n\n/**\n * @public\n * @description A wrapper component that should be used to protect a page. It will check the permissions\n * you pass to it and render the children if the user has the required permissions. If a user does not have ALL\n * the required permissions, it will redirect the user to the home page. Whilst these checks happen it will render\n * the loading component and should the check fail it will render the error component with a notification.\n */\nconst Protect = ({ permissions = [], children }: ProtectProps) => {\n const userPermissions = useAuth('Protect', (state) => state.permissions);\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n\n const matchingPermissions = (userPermissions || []).filter(\n (permission) =>\n permissions.findIndex(\n (perm) => perm.action === permission.action && perm.subject === permission.subject\n ) >= 0\n );\n\n const shouldCheckConditions = matchingPermissions.some(\n (perm) => Array.isArray(perm.conditions) && perm.conditions.length > 0\n );\n\n const { isLoading, error, data } = useCheckPermissionsQuery(\n {\n permissions: matchingPermissions.map((perm) => ({\n action: perm.action,\n subject: perm.subject,\n })),\n },\n {\n skip: !shouldCheckConditions,\n }\n );\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n }\n }, [error, formatAPIError, toggleNotification]);\n\n if (isLoading) {\n return <Loading />;\n }\n\n if (error) {\n return <Error />;\n }\n\n const { data: permissionsData } = data || {};\n\n const canAccess =\n shouldCheckConditions && permissionsData\n ? !permissionsData.includes(false)\n : matchingPermissions.length > 0;\n\n if (!canAccess) {\n return <NoPermissions />;\n }\n\n return (\n <>\n {typeof children === 'function' ? children({ permissions: matchingPermissions }) : children}\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Title\n * -----------------------------------------------------------------------------------------------*/\nexport interface TitleProps {\n children: string;\n}\n\n/**\n * @public\n * @description This component takes the children (must be a string) and sets\n * it as the title of the html.\n */\nconst Title = ({ children: title }: TitleProps) => {\n React.useEffect(() => {\n document.title = `${title} | Strapi`;\n }, [title]);\n\n return null;\n};\n\nconst Page = {\n Error,\n Loading,\n NoPermissions,\n Protect,\n NoData,\n Main: PageMain,\n Title,\n};\n\nexport { Page };\nexport type { ErrorProps, LoadingProps, NoPermissionsProps, PageMainProps as MainProps };\n"],"names":["PageMain","children","restProps","_jsx","Main","Loading","height","aria-busy","Flex","alignItems","justifyContent","Loader","Error","props","formatMessage","useIntl","EmptyStateLayout","icon","WarningCircle","width","content","id","defaultMessage","NoPermissions","Box","minWidth","EmptyPermissions","NoData","background","EmptyDocuments","action","Protect","permissions","userPermissions","useAuth","state","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","matchingPermissions","filter","permission","findIndex","perm","subject","shouldCheckConditions","some","Array","isArray","conditions","length","isLoading","error","data","useCheckPermissionsQuery","map","skip","React","useEffect","type","message","permissionsData","canAccess","includes","_Fragment","Title","title","document","Page"],"mappings":"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"}
|
|
@@ -134,7 +134,7 @@ const PageMain = ({ children, ...restProps })=>{
|
|
|
134
134
|
const userPermissions = useAuth('Protect', (state)=>state.permissions);
|
|
135
135
|
const { toggleNotification } = useNotification();
|
|
136
136
|
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
|
|
137
|
-
const matchingPermissions = userPermissions.filter((permission)=>permissions.findIndex((perm)=>perm.action === permission.action && perm.subject === permission.subject) >= 0);
|
|
137
|
+
const matchingPermissions = (userPermissions || []).filter((permission)=>permissions.findIndex((perm)=>perm.action === permission.action && perm.subject === permission.subject) >= 0);
|
|
138
138
|
const shouldCheckConditions = matchingPermissions.some((perm)=>Array.isArray(perm.conditions) && perm.conditions.length > 0);
|
|
139
139
|
const { isLoading, error, data } = useCheckPermissionsQuery({
|
|
140
140
|
permissions: matchingPermissions.map((perm)=>({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageHelpers.mjs","sources":["../../../../../admin/src/components/PageHelpers.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Box,\n EmptyStateLayout,\n type EmptyStateLayoutProps,\n Flex,\n Loader,\n Main,\n MainProps,\n} from '@strapi/design-system';\nimport { WarningCircle } from '@strapi/icons';\nimport { EmptyPermissions, EmptyDocuments } from '@strapi/icons/symbols';\nimport { useIntl } from 'react-intl';\n\nimport { useAuth, Permission } from '../features/Auth';\nimport { useNotification } from '../features/Notifications';\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useCheckPermissionsQuery } from '../services/auth';\n\n/* -------------------------------------------------------------------------------------------------\n * Main\n * -----------------------------------------------------------------------------------------------*/\ninterface PageMainProps extends MainProps {\n children: React.ReactNode;\n}\n\nconst PageMain = ({ children, ...restProps }: PageMainProps) => {\n return <Main {...restProps}>{children}</Main>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Loading\n * -----------------------------------------------------------------------------------------------*/\ninterface LoadingProps {\n /**\n * @default 'Loading content.'\n */\n children?: React.ReactNode;\n}\n\n/**\n * @public\n * @description A loading component that should be rendered as the page\n * whilst you load the content for the aforementioned page.\n */\nconst Loading = ({ children = 'Loading content.' }: LoadingProps) => {\n return (\n <PageMain height=\"100dvh\" aria-busy={true}>\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <Loader>{children}</Loader>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Error\n * -----------------------------------------------------------------------------------------------*/\ninterface ErrorProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * TODO: should we start passing our errors here so they're persisted on the screen?\n * This could follow something similar to how the global app error works...?\n */\n\n/**\n * @public\n * @description An error component that should be rendered as the page\n * when an error occurs.\n */\nconst Error = (props: ErrorProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\">\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <EmptyStateLayout\n icon={<WarningCircle width=\"16rem\" />}\n content={formatMessage({\n id: 'anErrorOccurred',\n defaultMessage: 'Whoops! Something went wrong. Please, try again.',\n })}\n {...props}\n />\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * NoPermissions\n * -----------------------------------------------------------------------------------------------*/\ninterface NoPermissionsProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * @public\n * @description A component that should be rendered as the page\n * when the user does not have the permissions to access the content.\n * This component does not check any permissions, it's up to you to decide\n * when it should be rendered.\n */\nconst NoPermissions = (props: NoPermissionsProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\">\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <Box minWidth=\"50%\">\n <EmptyStateLayout\n icon={<EmptyPermissions width=\"16rem\" />}\n content={formatMessage({\n id: 'app.components.EmptyStateLayout.content-permissions',\n defaultMessage: \"You don't have the permissions to access that content\",\n })}\n {...props}\n />\n </Box>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * NoData\n * -----------------------------------------------------------------------------------------------*/\ninterface NoDataProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * @public\n * @description A component that should be rendered as the page\n * when there is no data available to display.\n * This component does not check any permissions, it's up to you to decide\n * when it should be rendered.\n */\nconst NoData = (props: NoDataProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\" background=\"neutral100\">\n <Flex alignItems=\"center\" height=\"100%\" width=\"100%\" justifyContent=\"center\">\n <Box minWidth=\"50%\">\n <EmptyStateLayout\n icon={<EmptyDocuments width=\"16rem\" />}\n action={props.action}\n content={formatMessage({\n id: 'app.components.EmptyStateLayout.content-document',\n defaultMessage: 'No content found',\n })}\n {...props}\n />\n </Box>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Protect\n * -----------------------------------------------------------------------------------------------*/\nexport interface ProtectProps {\n /**\n * The children to render if the user has the required permissions.\n * If providing a function, it will be called with an object containing\n * the permissions the user has based on the array you passed to the component.\n */\n children: React.ReactNode | ((args: { permissions: Permission[] }) => React.ReactNode);\n /**\n * The permissions the user needs to have to access the content.\n */\n permissions?: Array<Omit<Partial<Permission>, 'action'> & Pick<Permission, 'action'>>;\n}\n\n/**\n * @public\n * @description A wrapper component that should be used to protect a page. It will check the permissions\n * you pass to it and render the children if the user has the required permissions. If a user does not have ALL\n * the required permissions, it will redirect the user to the home page. Whilst these checks happen it will render\n * the loading component and should the check fail it will render the error component with a notification.\n */\nconst Protect = ({ permissions = [], children }: ProtectProps) => {\n const userPermissions = useAuth('Protect', (state) => state.permissions);\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n\n const matchingPermissions = userPermissions.filter(\n (permission) =>\n permissions.findIndex(\n (perm) => perm.action === permission.action && perm.subject === permission.subject\n ) >= 0\n );\n\n const shouldCheckConditions = matchingPermissions.some(\n (perm) => Array.isArray(perm.conditions) && perm.conditions.length > 0\n );\n\n const { isLoading, error, data } = useCheckPermissionsQuery(\n {\n permissions: matchingPermissions.map((perm) => ({\n action: perm.action,\n subject: perm.subject,\n })),\n },\n {\n skip: !shouldCheckConditions,\n }\n );\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n }\n }, [error, formatAPIError, toggleNotification]);\n\n if (isLoading) {\n return <Loading />;\n }\n\n if (error) {\n return <Error />;\n }\n\n const { data: permissionsData } = data || {};\n\n const canAccess =\n shouldCheckConditions && permissionsData\n ? !permissionsData.includes(false)\n : matchingPermissions.length > 0;\n\n if (!canAccess) {\n return <NoPermissions />;\n }\n\n return (\n <>\n {typeof children === 'function' ? children({ permissions: matchingPermissions }) : children}\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Title\n * -----------------------------------------------------------------------------------------------*/\nexport interface TitleProps {\n children: string;\n}\n\n/**\n * @public\n * @description This component takes the children (must be a string) and sets\n * it as the title of the html.\n */\nconst Title = ({ children: title }: TitleProps) => {\n React.useEffect(() => {\n document.title = `${title} | Strapi`;\n }, [title]);\n\n return null;\n};\n\nconst Page = {\n Error,\n Loading,\n NoPermissions,\n Protect,\n NoData,\n Main: PageMain,\n Title,\n};\n\nexport { Page };\nexport type { ErrorProps, LoadingProps, NoPermissionsProps, PageMainProps as MainProps };\n"],"names":["PageMain","children","restProps","_jsx","Main","Loading","height","aria-busy","Flex","alignItems","justifyContent","Loader","Error","props","formatMessage","useIntl","EmptyStateLayout","icon","WarningCircle","width","content","id","defaultMessage","NoPermissions","Box","minWidth","EmptyPermissions","NoData","background","EmptyDocuments","action","Protect","permissions","userPermissions","useAuth","state","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","matchingPermissions","filter","permission","findIndex","perm","subject","shouldCheckConditions","some","Array","isArray","conditions","length","isLoading","error","data","useCheckPermissionsQuery","map","skip","React","useEffect","type","message","permissionsData","canAccess","includes","_Fragment","Title","title","document","Page"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PageHelpers.mjs","sources":["../../../../../admin/src/components/PageHelpers.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n Box,\n EmptyStateLayout,\n type EmptyStateLayoutProps,\n Flex,\n Loader,\n Main,\n MainProps,\n} from '@strapi/design-system';\nimport { WarningCircle } from '@strapi/icons';\nimport { EmptyPermissions, EmptyDocuments } from '@strapi/icons/symbols';\nimport { useIntl } from 'react-intl';\n\nimport { useAuth, Permission } from '../features/Auth';\nimport { useNotification } from '../features/Notifications';\nimport { useAPIErrorHandler } from '../hooks/useAPIErrorHandler';\nimport { useCheckPermissionsQuery } from '../services/auth';\n\n/* -------------------------------------------------------------------------------------------------\n * Main\n * -----------------------------------------------------------------------------------------------*/\ninterface PageMainProps extends MainProps {\n children: React.ReactNode;\n}\n\nconst PageMain = ({ children, ...restProps }: PageMainProps) => {\n return <Main {...restProps}>{children}</Main>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Loading\n * -----------------------------------------------------------------------------------------------*/\ninterface LoadingProps {\n /**\n * @default 'Loading content.'\n */\n children?: React.ReactNode;\n}\n\n/**\n * @public\n * @description A loading component that should be rendered as the page\n * whilst you load the content for the aforementioned page.\n */\nconst Loading = ({ children = 'Loading content.' }: LoadingProps) => {\n return (\n <PageMain height=\"100dvh\" aria-busy={true}>\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <Loader>{children}</Loader>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Error\n * -----------------------------------------------------------------------------------------------*/\ninterface ErrorProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * TODO: should we start passing our errors here so they're persisted on the screen?\n * This could follow something similar to how the global app error works...?\n */\n\n/**\n * @public\n * @description An error component that should be rendered as the page\n * when an error occurs.\n */\nconst Error = (props: ErrorProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\">\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <EmptyStateLayout\n icon={<WarningCircle width=\"16rem\" />}\n content={formatMessage({\n id: 'anErrorOccurred',\n defaultMessage: 'Whoops! Something went wrong. Please, try again.',\n })}\n {...props}\n />\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * NoPermissions\n * -----------------------------------------------------------------------------------------------*/\ninterface NoPermissionsProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * @public\n * @description A component that should be rendered as the page\n * when the user does not have the permissions to access the content.\n * This component does not check any permissions, it's up to you to decide\n * when it should be rendered.\n */\nconst NoPermissions = (props: NoPermissionsProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\">\n <Flex alignItems=\"center\" height=\"100%\" justifyContent=\"center\">\n <Box minWidth=\"50%\">\n <EmptyStateLayout\n icon={<EmptyPermissions width=\"16rem\" />}\n content={formatMessage({\n id: 'app.components.EmptyStateLayout.content-permissions',\n defaultMessage: \"You don't have the permissions to access that content\",\n })}\n {...props}\n />\n </Box>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * NoData\n * -----------------------------------------------------------------------------------------------*/\ninterface NoDataProps extends Partial<EmptyStateLayoutProps> {}\n\n/**\n * @public\n * @description A component that should be rendered as the page\n * when there is no data available to display.\n * This component does not check any permissions, it's up to you to decide\n * when it should be rendered.\n */\nconst NoData = (props: NoDataProps) => {\n const { formatMessage } = useIntl();\n\n return (\n <PageMain height=\"100%\" background=\"neutral100\">\n <Flex alignItems=\"center\" height=\"100%\" width=\"100%\" justifyContent=\"center\">\n <Box minWidth=\"50%\">\n <EmptyStateLayout\n icon={<EmptyDocuments width=\"16rem\" />}\n action={props.action}\n content={formatMessage({\n id: 'app.components.EmptyStateLayout.content-document',\n defaultMessage: 'No content found',\n })}\n {...props}\n />\n </Box>\n </Flex>\n </PageMain>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Protect\n * -----------------------------------------------------------------------------------------------*/\nexport interface ProtectProps {\n /**\n * The children to render if the user has the required permissions.\n * If providing a function, it will be called with an object containing\n * the permissions the user has based on the array you passed to the component.\n */\n children: React.ReactNode | ((args: { permissions: Permission[] }) => React.ReactNode);\n /**\n * The permissions the user needs to have to access the content.\n */\n permissions?: Array<Omit<Partial<Permission>, 'action'> & Pick<Permission, 'action'>>;\n}\n\n/**\n * @public\n * @description A wrapper component that should be used to protect a page. It will check the permissions\n * you pass to it and render the children if the user has the required permissions. If a user does not have ALL\n * the required permissions, it will redirect the user to the home page. Whilst these checks happen it will render\n * the loading component and should the check fail it will render the error component with a notification.\n */\nconst Protect = ({ permissions = [], children }: ProtectProps) => {\n const userPermissions = useAuth('Protect', (state) => state.permissions);\n const { toggleNotification } = useNotification();\n const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();\n\n const matchingPermissions = (userPermissions || []).filter(\n (permission) =>\n permissions.findIndex(\n (perm) => perm.action === permission.action && perm.subject === permission.subject\n ) >= 0\n );\n\n const shouldCheckConditions = matchingPermissions.some(\n (perm) => Array.isArray(perm.conditions) && perm.conditions.length > 0\n );\n\n const { isLoading, error, data } = useCheckPermissionsQuery(\n {\n permissions: matchingPermissions.map((perm) => ({\n action: perm.action,\n subject: perm.subject,\n })),\n },\n {\n skip: !shouldCheckConditions,\n }\n );\n\n React.useEffect(() => {\n if (error) {\n toggleNotification({\n type: 'danger',\n message: formatAPIError(error),\n });\n }\n }, [error, formatAPIError, toggleNotification]);\n\n if (isLoading) {\n return <Loading />;\n }\n\n if (error) {\n return <Error />;\n }\n\n const { data: permissionsData } = data || {};\n\n const canAccess =\n shouldCheckConditions && permissionsData\n ? !permissionsData.includes(false)\n : matchingPermissions.length > 0;\n\n if (!canAccess) {\n return <NoPermissions />;\n }\n\n return (\n <>\n {typeof children === 'function' ? children({ permissions: matchingPermissions }) : children}\n </>\n );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Title\n * -----------------------------------------------------------------------------------------------*/\nexport interface TitleProps {\n children: string;\n}\n\n/**\n * @public\n * @description This component takes the children (must be a string) and sets\n * it as the title of the html.\n */\nconst Title = ({ children: title }: TitleProps) => {\n React.useEffect(() => {\n document.title = `${title} | Strapi`;\n }, [title]);\n\n return null;\n};\n\nconst Page = {\n Error,\n Loading,\n NoPermissions,\n Protect,\n NoData,\n Main: PageMain,\n Title,\n};\n\nexport { Page };\nexport type { ErrorProps, LoadingProps, NoPermissionsProps, PageMainProps as MainProps };\n"],"names":["PageMain","children","restProps","_jsx","Main","Loading","height","aria-busy","Flex","alignItems","justifyContent","Loader","Error","props","formatMessage","useIntl","EmptyStateLayout","icon","WarningCircle","width","content","id","defaultMessage","NoPermissions","Box","minWidth","EmptyPermissions","NoData","background","EmptyDocuments","action","Protect","permissions","userPermissions","useAuth","state","toggleNotification","useNotification","_unstableFormatAPIError","formatAPIError","useAPIErrorHandler","matchingPermissions","filter","permission","findIndex","perm","subject","shouldCheckConditions","some","Array","isArray","conditions","length","isLoading","error","data","useCheckPermissionsQuery","map","skip","React","useEffect","type","message","permissionsData","canAccess","includes","_Fragment","Title","title","document","Page"],"mappings":"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"}
|
|
@@ -116,27 +116,40 @@ const Root = ({ children, defaultSelectedRows, footer, headers = [], isLoading =
|
|
|
116
116
|
}, 'push', true);
|
|
117
117
|
}
|
|
118
118
|
};
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
119
|
+
const handleKeyDown = (e)=>{
|
|
120
|
+
if (sortable && (e.key === 'Enter' || e.key === ' ')) {
|
|
121
|
+
e.preventDefault();
|
|
122
|
+
handleClickSort();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
return /*#__PURE__*/ jsxRuntime.jsx(SortableTh, {
|
|
126
|
+
onClick: sortable ? handleClickSort : undefined,
|
|
127
|
+
onKeyDown: sortable ? handleKeyDown : undefined,
|
|
128
|
+
tabIndex: sortable ? 0 : undefined,
|
|
129
|
+
"aria-sort": isSorted ? sortOrder === 'ASC' ? 'ascending' : 'descending' : undefined,
|
|
130
|
+
$sortable: !!sortable,
|
|
128
131
|
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Tooltip, {
|
|
129
132
|
label: sortable ? sortLabel : label,
|
|
130
|
-
children: /*#__PURE__*/ jsxRuntime.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
134
|
+
gap: 1,
|
|
135
|
+
children: [
|
|
136
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
137
|
+
textColor: "neutral600",
|
|
138
|
+
tag: "span",
|
|
139
|
+
variant: "sigma",
|
|
140
|
+
children: label
|
|
141
|
+
}),
|
|
142
|
+
isSorted && sortable && /*#__PURE__*/ jsxRuntime.jsx(SortIcon, {
|
|
143
|
+
$isUp: sortOrder === 'ASC'
|
|
144
|
+
})
|
|
145
|
+
]
|
|
136
146
|
})
|
|
137
147
|
})
|
|
138
148
|
});
|
|
139
149
|
};
|
|
150
|
+
const SortableTh = styled.styled(designSystem.Th)`
|
|
151
|
+
cursor: ${({ $sortable })=>$sortable ? 'pointer' : 'default'};
|
|
152
|
+
`;
|
|
140
153
|
const SortIcon = styled.styled(icons.CaretDown)`
|
|
141
154
|
transform: ${({ $isUp })=>`rotate(${$isUp ? '180' : '0'}deg)`};
|
|
142
155
|
`;
|