mirror of
https://github.com/strapi/strapi.git
synced 2025-09-26 08:52:26 +00:00
enhancement: promote preview configuration docs (#23961)
* enhancement: promote preview configuration docs * chore: add tests * fix: api test * fix: don't show panel in create mode
This commit is contained in:
parent
5aa166b6d1
commit
39b256a9a2
@ -31,22 +31,59 @@ const PreviewSidePanel: PanelComponent = ({ model, documentId, document }) => {
|
||||
const { pathname } = useLocation();
|
||||
const [{ query }] = useQueryParams();
|
||||
const isModified = useForm('PreviewSidePanel', (state) => state.modified);
|
||||
const isUnsaved = Boolean(!document || !document.id);
|
||||
|
||||
const title = formatMessage({
|
||||
id: 'content-manager.preview.panel.title',
|
||||
defaultMessage: 'Preview',
|
||||
});
|
||||
|
||||
/**
|
||||
* The preview URL isn't used in this component, we just fetch it to know if preview is enabled
|
||||
* for the content type. If it's not, the panel is not displayed. If it is, we display a link to
|
||||
* /preview, and the URL will already be loaded in the RTK query cache.
|
||||
*/
|
||||
const { data, error } = useGetPreviewUrlQuery({
|
||||
params: {
|
||||
contentType: model as UID.ContentType,
|
||||
const { data, error } = useGetPreviewUrlQuery(
|
||||
{
|
||||
params: {
|
||||
contentType: model as UID.ContentType,
|
||||
},
|
||||
query: {
|
||||
documentId,
|
||||
locale: document?.locale,
|
||||
status: document?.status,
|
||||
},
|
||||
},
|
||||
query: {
|
||||
documentId,
|
||||
locale: document?.locale,
|
||||
status: document?.status,
|
||||
},
|
||||
});
|
||||
// Don't bother making the request since we won't show any UI
|
||||
{ skip: isUnsaved }
|
||||
);
|
||||
|
||||
if (isUnsaved) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Preview was not configured but not disabled either (otherwise it would be a success 204).
|
||||
// So we encourage the user to set it up.
|
||||
if (error && error.name === 'NotFoundError') {
|
||||
return {
|
||||
title,
|
||||
content: (
|
||||
<Button
|
||||
variant="tertiary"
|
||||
tag={Link}
|
||||
to="https://docs.strapi.io/cms/features/preview"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
width="100%"
|
||||
>
|
||||
{formatMessage({
|
||||
id: 'content-manager.preview.panel.button-configuration',
|
||||
defaultMessage: 'Set up preview',
|
||||
})}
|
||||
</Button>
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
if (!data?.data?.url || error) {
|
||||
return null;
|
||||
@ -59,7 +96,7 @@ const PreviewSidePanel: PanelComponent = ({ model, documentId, document }) => {
|
||||
};
|
||||
|
||||
return {
|
||||
title: formatMessage({ id: 'content-manager.preview.panel.title', defaultMessage: 'Preview' }),
|
||||
title,
|
||||
content: (
|
||||
<ConditionalTooltip
|
||||
label={formatMessage({
|
||||
|
@ -241,6 +241,7 @@
|
||||
"popover.display-relations.label": "Display relations",
|
||||
"preview.panel.title": "Preview",
|
||||
"preview.panel.button": "Open preview",
|
||||
"preview.panel.button-configuration": "Set up preview",
|
||||
"preview.panel.button-disabled-tooltip": "Please save to open the preview",
|
||||
"preview.page-title": "{contentType} preview",
|
||||
"preview.header.close": "Close preview",
|
||||
|
@ -30,7 +30,49 @@ describe('Preview Config', () => {
|
||||
expect(createPreviewConfigService({ strapi }).isEnabled()).toBe(true);
|
||||
});
|
||||
|
||||
describe('Validation', () => {
|
||||
describe('isConfigured', () => {
|
||||
test('Is configured when preview is explicitly disabled', () => {
|
||||
const strapi = {
|
||||
config: {
|
||||
get: () => ({ enabled: false }),
|
||||
},
|
||||
} as any;
|
||||
|
||||
expect(createPreviewConfigService({ strapi }).isConfigured()).toBe(true);
|
||||
});
|
||||
|
||||
test('Is configured when handler is configured', () => {
|
||||
const strapi = {
|
||||
config: {
|
||||
get: () => getConfig(true, () => {}),
|
||||
},
|
||||
} as any;
|
||||
|
||||
expect(createPreviewConfigService({ strapi }).isConfigured()).toBe(true);
|
||||
});
|
||||
|
||||
test('Is not configured when preview is neither disabled nor configured', () => {
|
||||
const strapi = {
|
||||
config: {
|
||||
get: () => ({ enabled: true }),
|
||||
},
|
||||
} as any;
|
||||
|
||||
expect(createPreviewConfigService({ strapi }).isConfigured()).toBe(false);
|
||||
});
|
||||
|
||||
test('Is not configured when no config is provided', () => {
|
||||
const strapi = {
|
||||
config: {
|
||||
get: () => undefined,
|
||||
},
|
||||
} as any;
|
||||
|
||||
expect(createPreviewConfigService({ strapi }).isConfigured()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('validate', () => {
|
||||
test('Passes on valid configuration', () => {
|
||||
const strapi = {
|
||||
config: {
|
||||
|
@ -0,0 +1,58 @@
|
||||
import { errors } from '@strapi/utils';
|
||||
import { createPreviewService } from '../preview';
|
||||
|
||||
const mockConfig = {
|
||||
isConfigured: jest.fn(),
|
||||
getPreviewHandler: jest.fn(),
|
||||
};
|
||||
|
||||
const mockStrapi = {
|
||||
log: {
|
||||
error: jest.fn(),
|
||||
},
|
||||
} as any;
|
||||
|
||||
const mockGetService = jest.fn().mockReturnValue(mockConfig);
|
||||
|
||||
jest.mock('../../utils', () => ({
|
||||
getService: jest.fn().mockImplementation(() => mockGetService()),
|
||||
}));
|
||||
|
||||
describe('Preview Service', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('Throws 404 when preview is not configured', async () => {
|
||||
mockConfig.isConfigured.mockReturnValue(false);
|
||||
|
||||
const previewService = createPreviewService({ strapi: mockStrapi });
|
||||
|
||||
await expect(
|
||||
previewService.getPreviewUrl('api::article.article', {
|
||||
documentId: '',
|
||||
locale: '',
|
||||
status: 'published',
|
||||
})
|
||||
).rejects.toThrow(new errors.NotFoundError('Preview config not found'));
|
||||
|
||||
expect(mockConfig.isConfigured).toHaveBeenCalled();
|
||||
expect(mockConfig.getPreviewHandler).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Calls handler when preview is configured', async () => {
|
||||
const mockHandler = jest.fn().mockResolvedValue('http://preview.example.com');
|
||||
mockConfig.isConfigured.mockReturnValue(true);
|
||||
mockConfig.getPreviewHandler.mockReturnValue(mockHandler);
|
||||
|
||||
const previewService = createPreviewService({ strapi: mockStrapi });
|
||||
const params = { documentId: '1', locale: 'en', status: 'published' as const };
|
||||
|
||||
const result = await previewService.getPreviewUrl('api::article.article', params);
|
||||
|
||||
expect(result).toBe('http://preview.example.com');
|
||||
expect(mockConfig.isConfigured).toHaveBeenCalled();
|
||||
expect(mockConfig.getPreviewHandler).toHaveBeenCalled();
|
||||
expect(mockHandler).toHaveBeenCalledWith('api::article.article', params);
|
||||
});
|
||||
});
|
@ -81,6 +81,11 @@ const createPreviewConfigService = ({ strapi }: { strapi: Core.Strapi }) => {
|
||||
}
|
||||
},
|
||||
|
||||
isConfigured() {
|
||||
const config = strapi.config.get('admin.preview') as PreviewConfig;
|
||||
return config?.enabled === false || config?.config?.handler != null;
|
||||
},
|
||||
|
||||
isEnabled() {
|
||||
const config = strapi.config.get('admin.preview') as PreviewConfig;
|
||||
|
||||
@ -113,8 +118,6 @@ const createPreviewConfigService = ({ strapi }: { strapi: Core.Strapi }) => {
|
||||
* Utility to get the preview handler from the configuration
|
||||
*/
|
||||
getPreviewHandler(): PreviewConfig['config']['handler'] {
|
||||
const config = strapi.config.get('admin.preview') as PreviewConfig;
|
||||
|
||||
const emptyHandler = () => {
|
||||
return undefined;
|
||||
};
|
||||
@ -123,6 +126,8 @@ const createPreviewConfigService = ({ strapi }: { strapi: Core.Strapi }) => {
|
||||
return emptyHandler;
|
||||
}
|
||||
|
||||
const config = strapi.config.get('admin.preview') as PreviewConfig;
|
||||
|
||||
return config?.config?.handler || emptyHandler;
|
||||
},
|
||||
};
|
||||
|
@ -12,6 +12,12 @@ const createPreviewService = ({ strapi }: { strapi: Core.Strapi }) => {
|
||||
|
||||
return {
|
||||
async getPreviewUrl(uid: UID.ContentType, params: HandlerParams) {
|
||||
const isConfigured = config.isConfigured();
|
||||
|
||||
if (!isConfigured) {
|
||||
throw new errors.NotFoundError('Preview config not found');
|
||||
}
|
||||
|
||||
const handler = config.getPreviewHandler();
|
||||
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user