From a86bd613c096545d7c845c5e79a4c3ba95900d61 Mon Sep 17 00:00:00 2001 From: Victor Fernandez de Alba Date: Tue, 3 Nov 2026 11:19:43 -0300 Subject: [PATCH] Follow the reviewed @content-types API plone.restapi's review renamed a type's item count to content_count, replaced the default page setting with in_navigation, and reports the whole workflow chain. The control panel follows: "Show in navigation" replaces "Can be used as a folder's default page", and the Workflow tab mentions the other workflows of a chain. Assisted-by: Claude Opus 5.5 --- .../acceptance/tests/content-types.test.ts | 5 ++++ .../news/+restapi-review.feature | 1 + .../components/SettingsTab/SettingsTab.tsx | 12 ++++---- .../WorkflowTab/WorkflowTab.test.tsx | 22 +++++++++++++++ .../components/WorkflowTab/WorkflowTab.tsx | 13 +++++++++ .../src/content-types/driver.tsx | 4 +-- .../src/content-types/editableSettings.ts | 10 +++---- .../src/content-types/messages.ts | 18 +++++++----- .../content-types/mock/createMockDriver.ts | 6 ++-- .../src/content-types/mock/fixtures/index.ts | 6 ++-- .../restapi/contentTypesService.test.ts | 28 +++++++++++++++---- .../restapi/contentTypesService.ts | 21 ++++++++------ .../restapi/createRestApiDriver.test.ts | 2 +- .../controlpanels/src/content-types/types.ts | 7 ++++- .../controlpanels/src/locales/ca/common.json | 5 ++-- .../controlpanels/src/locales/de/common.json | 5 ++-- .../controlpanels/src/locales/en/common.json | 5 ++-- .../controlpanels/src/locales/es/common.json | 5 ++-- .../controlpanels/src/locales/it/common.json | 5 ++-- .../src/locales/pt-BR/common.json | 5 ++-- 20 files changed, 131 insertions(+), 54 deletions(-) create mode 100644 packages/controlpanels/news/+restapi-review.feature diff --git a/packages/cmsui/acceptance/tests/content-types.test.ts b/packages/cmsui/acceptance/tests/content-types.test.ts index 614f3910b..415e3f724 100644 --- a/packages/cmsui/acceptance/tests/content-types.test.ts +++ b/packages/cmsui/acceptance/tests/content-types.test.ts @@ -508,6 +508,8 @@ test.describe('A content type, on a backend with @content-types', () => { await openNewType(page, 'settings'); await page.getByText('Show in search results', { exact: true }).click(); + // New types aren't in the navigation. + await page.getByText('Show in navigation', { exact: true }).click(); await page .getByRole('radiogroup', { name: 'Versioning' }) .getByText('Automatic', { exact: true }) @@ -518,6 +520,9 @@ test.describe('A content type, on a backend with @content-types', () => { await expect( page.getByRole('switch', { name: 'Show in search results' }), ).not.toBeChecked(); + await expect( + page.getByRole('switch', { name: 'Show in navigation' }), + ).toBeChecked(); await expect(page.getByRole('radio', { name: /^Automatic/ })).toBeChecked(); }); diff --git a/packages/controlpanels/news/+restapi-review.feature b/packages/controlpanels/news/+restapi-review.feature new file mode 100644 index 000000000..de0fa478d --- /dev/null +++ b/packages/controlpanels/news/+restapi-review.feature @@ -0,0 +1 @@ +Follow the reviewed plone.restapi content types API (plone/plone.restapi#2070, #2090): a type's number of items is `content_count`, the Settings tab has "Show in navigation" instead of "Can be used as a folder's default page", and the Workflow tab says when a type's chain has other workflows, which changing the workflow replaces. The capability and settings field `defaultPage` is now `inNavigation`. @sneridagh diff --git a/packages/controlpanels/src/content-types/components/SettingsTab/SettingsTab.tsx b/packages/controlpanels/src/content-types/components/SettingsTab/SettingsTab.tsx index c29bdb1c6..b872e593b 100644 --- a/packages/controlpanels/src/content-types/components/SettingsTab/SettingsTab.tsx +++ b/packages/controlpanels/src/content-types/components/SettingsTab/SettingsTab.tsx @@ -186,7 +186,7 @@ export function SettingsTab({ type, types }: SettingsTabProps) { const missing = !capabilities.globalAllow || !capabilities.searchable || - !capabilities.defaultPage || + !capabilities.inNavigation || !capabilities.allowDiscussion || !capabilities.versioning; @@ -203,7 +203,7 @@ export function SettingsTab({ type, types }: SettingsTabProps) { )} {type.folderish && } - {(capabilities.searchable || capabilities.defaultPage) && ( + {(capabilities.searchable || capabilities.inNavigation) && (
{capabilities.searchable && ( )} - {capabilities.defaultPage && ( + {capabilities.inNavigation && ( )}
diff --git a/packages/controlpanels/src/content-types/components/WorkflowTab/WorkflowTab.test.tsx b/packages/controlpanels/src/content-types/components/WorkflowTab/WorkflowTab.test.tsx index ffcac6156..535375185 100644 --- a/packages/controlpanels/src/content-types/components/WorkflowTab/WorkflowTab.test.tsx +++ b/packages/controlpanels/src/content-types/components/WorkflowTab/WorkflowTab.test.tsx @@ -42,6 +42,28 @@ async function openAndChoose(name: RegExp) { } describe('WorkflowTab', () => { + it('mentions the other workflows of a chain', async () => { + const base = createMockDriver(); + const driver = { + ...base, + getType: async (id: string) => { + const type = await base.getType(id); + return { + ...type, + workflow: { + workflow: 'simple_publication_workflow', + chain: ['simple_publication_workflow', 'intranet_workflow'], + followsDefault: false, + }, + }; + }, + }; + renderWorkflow(driver); + expect( + await screen.findByText(/Its chain also has Intranet/), + ).toHaveTextContent('Changing the workflow replaces the whole chain.'); + }); + it('shows the states of the current workflow', async () => { renderWorkflow(); const states = await screen.findByRole('list', { name: 'States' }); diff --git a/packages/controlpanels/src/content-types/components/WorkflowTab/WorkflowTab.tsx b/packages/controlpanels/src/content-types/components/WorkflowTab/WorkflowTab.tsx index 24a0d071b..39308638c 100644 --- a/packages/controlpanels/src/content-types/components/WorkflowTab/WorkflowTab.tsx +++ b/packages/controlpanels/src/content-types/components/WorkflowTab/WorkflowTab.tsx @@ -75,6 +75,19 @@ export function WorkflowTab({ {workflow?.description && (

{workflow.description}

)} + {assignment.chain && assignment.chain.length > 1 && ( +

+ {t(messages.otherWorkflows, { + workflows: assignment.chain + .slice(1) + .map( + (id) => + workflows.find((entry) => entry.id === id)?.title ?? id, + ) + .join(', '), + })} +

+ )} {workflow ? (