Files
pole-book/server/node_modules/@strapi/content-manager/dist/admin/pages/ComponentConfigurationPage.mjs

227 lines
9.2 KiB
JavaScript

import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import * as React from 'react';
import { useNotification, useAPIErrorHandler, Page } from '@strapi/admin/strapi-admin';
import { useIntl } from 'react-intl';
import { useParams } from 'react-router-dom';
import { TEMP_FIELD_NAME } from '../components/ConfigurationForm/Fields.mjs';
import { ConfigurationForm } from '../components/ConfigurationForm/Form.mjs';
import { extractContentTypeComponents } from '../hooks/useContentTypeSchema.mjs';
import { DEFAULT_SETTINGS, convertEditLayoutToFieldLayouts } from '../hooks/useDocumentLayout.mjs';
import { useTypedSelector } from '../modules/hooks.mjs';
import { useGetComponentConfigurationQuery, useUpdateComponentConfigurationMutation } from '../services/components.mjs';
import { useGetInitialDataQuery } from '../services/init.mjs';
import { setIn } from '../utils/objects.mjs';
/* -------------------------------------------------------------------------------------------------
* ComponentConfigurationPage
* -----------------------------------------------------------------------------------------------*/ const ComponentConfigurationPage = ()=>{
/**
* useDocumentLayout only works for documents, not components,
* it feels weird to make that hook work for both when this is SUCH
* a unique use case and we only do it here, so in short, we essentially
* just extracted the logic to make an edit view layout and reproduced it here.
*/ const { slug: model } = useParams();
const { toggleNotification } = useNotification();
const { formatMessage } = useIntl();
const { _unstableFormatAPIError: formatAPIError } = useAPIErrorHandler();
const { components, fieldSizes, schema, error: errorSchema, isLoading: isLoadingSchema, isFetching: isFetchingSchema } = useGetInitialDataQuery(undefined, {
selectFromResult: (res)=>{
const schema = res.data?.components.find((ct)=>ct.uid === model);
const componentsByKey = res.data?.components.reduce((acc, component)=>{
acc[component.uid] = component;
return acc;
}, {});
const components = extractContentTypeComponents(schema?.attributes, componentsByKey);
const fieldSizes = Object.entries(res.data?.fieldSizes ?? {}).reduce((acc, [attributeName, { default: size }])=>{
acc[attributeName] = size;
return acc;
}, {});
return {
isFetching: res.isFetching,
isLoading: res.isLoading,
error: res.error,
components,
schema,
fieldSizes
};
}
});
React.useEffect(()=>{
if (errorSchema) {
toggleNotification({
type: 'danger',
message: formatAPIError(errorSchema)
});
}
}, [
errorSchema,
formatAPIError,
toggleNotification
]);
const { data, isLoading: isLoadingConfig, isFetching: isFetchingConfig, error } = useGetComponentConfigurationQuery(model ?? '');
React.useEffect(()=>{
if (error) {
toggleNotification({
type: 'danger',
message: formatAPIError(error)
});
}
}, [
error,
formatAPIError,
toggleNotification
]);
/**
* you **must** check if we're loading or fetching in case the component gets new props
* but nothing was unmounted, it then becomes a fetch, not a load.
*/ const isLoading = isLoadingConfig || isLoadingSchema || isFetchingConfig || isFetchingSchema;
const editLayout = React.useMemo(()=>data && !isLoading ? formatEditLayout(data, {
schema,
components
}) : {
layout: [],
components: {},
metadatas: {},
options: {},
settings: DEFAULT_SETTINGS
}, [
data,
isLoading,
schema,
components
]);
const [updateConfiguration] = useUpdateComponentConfigurationMutation();
const handleSubmit = async (formData)=>{
try {
/**
* We reconstruct the metadatas object by taking the existing list metadatas
* and re-merging that by attribute name with the current list metadatas, whilst overwriting
* the data from the form we've built.
*/ const meta = Object.entries(data?.component.metadatas ?? {}).reduce((acc, [name, { edit, list }])=>{
const { __temp_key__, size: _size, name: _name, ...editedMetadata } = formData.layout.flatMap((row)=>row.children).find((field)=>field.name === name) ?? {};
acc[name] = {
edit: {
...edit,
...editedMetadata
},
list
};
return acc;
}, {});
const res = await updateConfiguration({
layouts: {
edit: formData.layout.map((row)=>row.children.reduce((acc, { name, size })=>{
if (name !== TEMP_FIELD_NAME) {
return [
...acc,
{
name,
size
}
];
}
return acc;
}, [])),
list: data?.component.layouts.list
},
settings: setIn(formData.settings, 'displayName', undefined),
metadatas: meta,
uid: model
});
if ('data' in res) {
toggleNotification({
type: 'success',
message: formatMessage({
id: 'notification.success.saved',
defaultMessage: 'Saved'
})
});
} else {
toggleNotification({
type: 'danger',
message: formatAPIError(res.error)
});
}
} catch {
toggleNotification({
type: 'danger',
message: formatMessage({
id: 'notification.error',
defaultMessage: 'An error occurred'
})
});
}
};
if (isLoading) {
return /*#__PURE__*/ jsx(Page.Loading, {});
}
if (error || errorSchema || !schema) {
return /*#__PURE__*/ jsx(Page.Error, {});
}
return /*#__PURE__*/ jsxs(Fragment, {
children: [
/*#__PURE__*/ jsx(Page.Title, {
children: `Configure ${editLayout.settings.displayName} Edit View`
}),
/*#__PURE__*/ jsx(ConfigurationForm, {
onSubmit: handleSubmit,
attributes: schema.attributes,
fieldSizes: fieldSizes,
layout: editLayout
})
]
});
};
/* -------------------------------------------------------------------------------------------------
* Header
* -----------------------------------------------------------------------------------------------*/ const formatEditLayout = (data, { schema, components })=>{
const editAttributes = convertEditLayoutToFieldLayouts(data.component.layouts.edit, schema?.attributes, data.component.metadatas, {
configurations: data.components,
schemas: components
});
const componentEditAttributes = Object.entries(data.components).reduce((acc, [uid, configuration])=>{
acc[uid] = {
layout: convertEditLayoutToFieldLayouts(configuration.layouts.edit, components[uid].attributes, configuration.metadatas),
settings: {
...configuration.settings,
icon: components[uid].info.icon,
displayName: components[uid].info.displayName
}
};
return acc;
}, {});
const editMetadatas = Object.entries(data.component.metadatas).reduce((acc, [attribute, metadata])=>{
return {
...acc,
[attribute]: metadata.edit
};
}, {});
return {
layout: [
editAttributes
],
components: componentEditAttributes,
metadatas: editMetadatas,
options: {
...schema?.options,
...schema?.pluginOptions
},
settings: {
...data.component.settings,
displayName: schema?.info.displayName
}
};
};
/* -------------------------------------------------------------------------------------------------
* Header
* -----------------------------------------------------------------------------------------------*/ const ProtectedComponentConfigurationPage = ()=>{
const permissions = useTypedSelector((state)=>state.admin_app.permissions.contentManager?.componentsConfigurations);
return /*#__PURE__*/ jsx(Page.Protect, {
permissions: permissions,
children: /*#__PURE__*/ jsx(ComponentConfigurationPage, {})
});
};
export { ComponentConfigurationPage, ProtectedComponentConfigurationPage };
//# sourceMappingURL=ComponentConfigurationPage.mjs.map