diff --git a/.github/workflows/deployment_tests.yml b/.github/workflows/api-first.yml similarity index 56% rename from .github/workflows/deployment_tests.yml rename to .github/workflows/api-first.yml index 9f6edc6e22..8edf0f2f8e 100644 --- a/.github/workflows/deployment_tests.yml +++ b/.github/workflows/api-first.yml @@ -1,12 +1,49 @@ -name: Deployment Tests +name: API-first story Tests on: [push, pull_request] env: node-version: 22.x jobs: - vitessr: - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + config: + runs-on: ubuntu-latest + outputs: + ENVIRONMENT: ${{ steps.vars.outputs.ENVIRONMENT }} + STACK_NAME: ${{ steps.vars.outputs.STACK_NAME }} + nextjs: ${{ steps.filter.outputs.nextjs }} + remix: ${{ steps.filter.outputs.remix }} + rr7: ${{ steps.filter.outputs.rr7 }} + tss: ${{ steps.filter.outputs.tss }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set Env Vars + id: vars + run: | + ENVIRONMENT=${{ vars.LIVE_ENV }} + echo "ENVIRONMENT=${ENVIRONMENT}" >> $GITHUB_OUTPUT + echo "STACK_NAME=${ENVIRONMENT//./-}" >> $GITHUB_OUTPUT + + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + nextjs: + - 'apps/nextjs/**' + - '.github/workflows/api-first.yml' + remix: + - 'apps/remix/**' + - '.github/workflows/api-first.yml' + rr7: + - 'apps/rr7/**' + - '.github/workflows/api-first.yml' + tss: + - 'apps/vite-ssr/**' + - '.github/workflows/api-first.yml' + + tss: + if: ${{ needs.config.outputs.tss == 'true' }} && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) runs-on: ubuntu-latest name: Vite SSR timeout-minutes: 5 @@ -68,7 +105,8 @@ jobs: run: make backend-docker-detached-stop nextjs: - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + # if: ${{ needs.config.outputs.nextjs == 'true' }} && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) + if: false runs-on: ubuntu-latest name: Next.JS timeout-minutes: 5 @@ -130,7 +168,7 @@ jobs: run: make backend-docker-detached-stop remix: - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + if: ${{ needs.config.outputs.remix == 'true' }} && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) runs-on: ubuntu-latest name: Remix timeout-minutes: 5 @@ -174,7 +212,63 @@ jobs: run: pnpm --filter plone-remix build - name: Start server - run: nohup pnpm --filter plone-remix start:prod & + run: PLONE_API_PATH=http://localhost:8080/Plone nohup pnpm --filter plone-remix start:prod & + + - name: Wait + run: packages/scripts/node_modules/.bin/wait-on --httpTimeout 20000 http-get://127.0.0.1:8080/Plone + + - name: Run tests + run: node packages/scripts/check_deployment.js + + - name: Stop backend + run: make backend-docker-detached-stop + + rr7: + if: ${{ needs.config.outputs.rr7 == 'true' }} && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) + runs-on: ubuntu-latest + name: ReactRouter 7 + timeout-minutes: 5 + strategy: + fail-fast: false + steps: + - uses: actions/checkout@v4 + + # node setup + - name: Use Node.js ${{ env.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.node-version }} + + - name: Enable corepack + run: corepack enable + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - uses: actions/cache@v4 + name: Setup pnpm cache + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build dependencies + run: pnpm build:all + + - name: Start backend + run: make backend-docker-detached-start + + - name: Build + run: pnpm --filter plone-rr7 build + + - name: Start server + run: PLONE_API_PATH=http://localhost:8080/Plone nohup pnpm --filter plone-rr7 start:prod & - name: Wait run: packages/scripts/node_modules/.bin/wait-on --httpTimeout 20000 http-get://127.0.0.1:8080/Plone diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 418c2c4f18..b9616ac57d 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -20,7 +20,7 @@ jobs: - name: Install towncrier run: pip install towncrier - - uses: dorny/paths-filter@v2 + - uses: dorny/paths-filter@v3 id: filter with: filters: | @@ -42,6 +42,12 @@ jobs: - 'packages/scripts/**' voltoSlate: - 'packages/volto-slate/**' + blocks: + - 'packages/blocks/**' + slots: + - 'packages/slots/**' + theming: + - 'packages/theming/**' wrongNews: - added|modified: 'news/**' @@ -120,6 +126,30 @@ jobs: env: BASE_BRANCH: ${{ github.base_ref }} + - name: Blocks changelog check + if: steps.filter.outputs.blocks == 'true' + run: | + git fetch --no-tags origin main + towncrier check --compare-with origin/main --dir packages/blocks + env: + BASE_BRANCH: ${{ github.base_ref }} + + - name: Slots changelog check + if: steps.filter.outputs.slots == 'true' + run: | + git fetch --no-tags origin main + towncrier check --compare-with origin/main --dir packages/slots + env: + BASE_BRANCH: ${{ github.base_ref }} + + - name: Theming changelog check + if: steps.filter.outputs.theming == 'true' + run: | + git fetch --no-tags origin main + towncrier check --compare-with origin/main --dir packages/theming + env: + BASE_BRANCH: ${{ github.base_ref }} + - name: Wrong location of news changelog check if: steps.filter.outputs.wrongNews == 'true' run: echo "News items should be moved from the repository root to the appropriate package root in `packages/package-name`." && exit 1 diff --git a/.stylelintignore b/.stylelintignore index 1521c8b765..4b2be235a0 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -1 +1,4 @@ dist +docs +node_modules +packages/registry/lib diff --git a/README.md b/README.md index 63877d3e46..9327b2f737 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,30 @@ You can build your own or choose from the community released ones: You can try a Volto online demo at [https://demo.plone.org/](https://demo.plone.org/). +## Monorepo structure + +Since version 18.0.0-alpha4, the Volto core repository has had the shape of a monorepo, where "mono" means "single" and "repo" is short for "repository". +This means that several apps and libraries related to each other are stored in the same repository. +They are managed together but released individually. +This allows the code to be shared effectively, and unifies tracking of changes across all of the apps and libraries. + +| Package | Location | +|---|---| +| [`@plone/client`](https://www.npmjs.com/package/@plone/client) | [`packages/client`](https://github.com/plone/volto/tree/main/packages/client#readme) | +| [`@plone/components`](https://www.npmjs.com/package/@plone/components) | [`packages/components`](https://github.com/plone/volto/tree/main/packages/components#readme) | +| [`@plone/generator-volto`](https://www.npmjs.com/package/@plone/generator-volto) | [`packages/generator-volto`](https://github.com/plone/volto/tree/main/packages/generator-volto#readme) | +| [`@plone/helpers`](https://www.npmjs.com/package/@plone/helpers) | [`packages/helpers`](https://github.com/plone/volto/tree/main/packages/helpers#readme) | +| [`@plone/providers`](https://www.npmjs.com/package/@plone/providers) | [`packages/providers`](https://github.com/plone/volto/tree/main/packages/providers#readme) | +| [`@plone/registry`](https://www.npmjs.com/package/@plone/registry) | [`packages/registry`](https://github.com/plone/volto/tree/main/packages/registry#readme) | +| [`@plone/scripts`](https://www.npmjs.com/package/@plone/scripts) | [`packages/scripts`](https://github.com/plone/volto/tree/main/packages/scripts#readme) | +| [`@plone/types`](https://www.npmjs.com/package/@plone/types) | [`packages/types`](https://github.com/plone/volto/tree/main/packages/types#readme) | +| none | [`packages/volto-guillotina`](https://github.com/plone/volto/tree/main/packages/volto-guillotina) | +| [`@plone/volto-slate`](https://www.npmjs.com/package/@plone/volto-slate) | [`packages/volto-slate`](https://github.com/plone/volto/tree/main/packages/volto-slate#readme) | +| [`@plone/volto-testing`](https://www.npmjs.com/package/@plone/volto-testing) | [`packages/volto-testing`](https://github.com/plone/volto/tree/main/packages/volto-testing) | + +See also [Monorepo structure](https://6.docs.plone.org/volto/contributing/developing-core.html#monorepo-structure). + + ## Create a Volto project To start a new project using Volto, follow the [Plone installation documentation](https://6.docs.plone.org/install/create-project.html). diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json index 8b935ff8bb..de9e413a71 100644 --- a/apps/nextjs/package.json +++ b/apps/nextjs/package.json @@ -18,7 +18,7 @@ "@tanstack/react-query": "^5.59.0", "next": "14.2.14", "react": "^18", - "react-aria-components": "^1.4.0", + "react-aria-components": "^1.5.0", "react-dom": "^18" }, "devDependencies": { diff --git a/apps/remix/.gitignore b/apps/remix/.gitignore index 3f7bf98da3..8bf74e0cf1 100644 --- a/apps/remix/.gitignore +++ b/apps/remix/.gitignore @@ -4,3 +4,4 @@ node_modules /build /public/build .env +.registry.loader.js diff --git a/apps/remix/app/client.ts b/apps/remix/app/client.ts index 0eec9cd62e..db178fa7f7 100644 --- a/apps/remix/app/client.ts +++ b/apps/remix/app/client.ts @@ -2,7 +2,7 @@ import ploneClient from '@plone/client'; import config from '@plone/registry'; const cli = ploneClient.initialize({ - apiPath: config.settings.apiPath, + apiPath: config.settings.internalApiPath || config.settings.apiPath, }); export { cli as ploneClient }; diff --git a/apps/remix/app/config.ts b/apps/remix/app/config.ts index ae8881a358..88d1de718f 100644 --- a/apps/remix/app/config.ts +++ b/apps/remix/app/config.ts @@ -1,15 +1,15 @@ import config from '@plone/registry'; -import { blocksConfig, slate } from '@plone/blocks'; - -const settings = { - apiPath: 'http://localhost:8080/Plone', - slate, -}; - -// @ts-expect-error We need to fix typing -config.set('settings', settings); - -// @ts-expect-error We need to fix typing -config.set('blocks', { blocksConfig }); - -export default config; +import applyAddonConfiguration from '@plone/registry/addons-loader'; + +export default function install() { + applyAddonConfiguration(config); + config.settings.apiPath = + process.env.PLONE_API_PATH || 'http://localhost:3000'; + config.settings.internalApiPath = process.env.PLONE_INTERNAL_API_PATH || ''; + console.log('API_PATH is:', config.settings.apiPath); + console.log( + 'INTERNAL_API_PATH is:', + config.settings.internalApiPath || 'not set', + ); + return config; +} diff --git a/apps/remix/app/routes/_index.tsx b/apps/remix/app/content.tsx similarity index 61% rename from apps/remix/app/routes/_index.tsx rename to apps/remix/app/content.tsx index 2ad6a19bbe..3e8a562784 100644 --- a/apps/remix/app/routes/_index.tsx +++ b/apps/remix/app/content.tsx @@ -7,14 +7,16 @@ import { dehydrate, QueryClient, HydrationBoundary, + useQueryClient, useQuery, } from '@tanstack/react-query'; -import { flattenToAppURL } from '../utils'; +import { flattenToAppURL } from './utils'; import { useLoaderData, useLocation } from '@remix-run/react'; import { usePloneClient } from '@plone/providers'; -import { Breadcrumbs, RenderBlocks } from '@plone/components'; -import config from '@plone/registry'; -import { ploneClient } from '../client'; +// import { Breadcrumbs, RenderBlocks } from '@plone/components'; +// import config from '@plone/registry'; +import { ploneClient } from './client'; +import App from '@plone/slots/components/App'; export const meta: MetaFunction = () => { return [ @@ -23,7 +25,7 @@ export const meta: MetaFunction = () => { ]; }; -const expand = ['breadcrumbs', 'navigation']; +const expand = ['navroot', 'breadcrumbs', 'navigation']; // eslint-disable-next-line @typescript-eslint/no-unused-vars export const loader = async ({ params, request }: LoaderFunctionArgs) => { @@ -40,7 +42,7 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => { const { getContentQuery } = ploneClient; await queryClient.prefetchQuery( - getContentQuery({ path: flattenToAppURL(request.url), expand }), + getContentQuery({ path: flattenToAppURL(request.url || '/'), expand }), ); return json({ dehydratedState: dehydrate(queryClient) }); @@ -48,31 +50,23 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => { function Page() { const { getContentQuery } = usePloneClient(); - const pathname = useLocation().pathname; - const { data } = useQuery(getContentQuery({ path: pathname, expand })); + const { pathname } = useLocation(); + const { data } = useQuery(getContentQuery({ path: pathname || '/', expand })); if (!data) return null; return ( <> - - + ); } -export default function Index() { +export default function Content() { const { dehydratedState } = useLoaderData(); + const queryClient = useQueryClient(); return ( - + ); diff --git a/apps/remix/app/entry.client.tsx b/apps/remix/app/entry.client.tsx index 4680b84a57..b1f2b5cf0b 100644 --- a/apps/remix/app/entry.client.tsx +++ b/apps/remix/app/entry.client.tsx @@ -3,11 +3,12 @@ * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨ * For more information, see https://remix.run/file-conventions/entry.client */ - +import install from './config'; import { RemixBrowser } from '@remix-run/react'; import { startTransition, StrictMode } from 'react'; import { hydrateRoot } from 'react-dom/client'; -import './config'; + +install(); startTransition(() => { hydrateRoot( diff --git a/apps/remix/app/entry.server.tsx b/apps/remix/app/entry.server.tsx index 9af132970a..64f8029dd8 100644 --- a/apps/remix/app/entry.server.tsx +++ b/apps/remix/app/entry.server.tsx @@ -11,10 +11,12 @@ import { createReadableStreamFromReadable } from '@remix-run/node'; import { RemixServer } from '@remix-run/react'; import { isbot } from 'isbot'; import { renderToPipeableStream } from 'react-dom/server'; -import './config'; +import install from './config'; const ABORT_DELAY = 5_000; +install(); + export default function handleRequest( request: Request, responseStatusCode: number, diff --git a/apps/remix/app/root.tsx b/apps/remix/app/root.tsx index ecfb28c8be..5d49a06f99 100644 --- a/apps/remix/app/root.tsx +++ b/apps/remix/app/root.tsx @@ -17,18 +17,16 @@ import PloneClient from '@plone/client'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import '@plone/components/dist/basic.css'; +import '@plone/slots/main.css'; import { flattenToAppURL } from './utils'; import { PloneProvider } from '@plone/providers'; + import config from '@plone/registry'; export const links: LinksFunction = () => [ ...(cssBundleHref ? [{ rel: 'stylesheet', href: cssBundleHref }] : []), ]; -function useHrefLocal(to: string) { - return useHref(flattenToAppURL(to)); -} - export default function App() { const [queryClient] = useState( () => @@ -55,6 +53,10 @@ export default function App() { return RRNavigate(flattenToAppURL(to)); }; + function useHrefLocal(to: string) { + return useHref(flattenToAppURL(to)); + } + return ( @@ -71,6 +73,7 @@ export default function App() { useParams={useParams} useHref={useHrefLocal} navigate={navigate} + flattenToAppURL={flattenToAppURL} > diff --git a/apps/remix/app/routes/$.tsx b/apps/remix/app/routes/$.tsx deleted file mode 100644 index abd1fd4bbd..0000000000 --- a/apps/remix/app/routes/$.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { - json, - type LoaderFunctionArgs, - type MetaFunction, -} from '@remix-run/node'; -import { - dehydrate, - QueryClient, - HydrationBoundary, - useQuery, -} from '@tanstack/react-query'; -import { flattenToAppURL } from '../utils'; -import { useLoaderData, useLocation } from '@remix-run/react'; -import { usePloneClient } from '@plone/providers'; -import { Breadcrumbs, RenderBlocks } from '@plone/components'; -import config from '@plone/registry'; -import { ploneClient } from '../client'; - -export const meta: MetaFunction = () => { - return [ - { title: 'Plone on Remix' }, - { name: 'description', content: 'Welcome to Plone on Remix!' }, - ]; -}; - -const expand = ['breadcrumbs', 'navigation']; - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export const loader = async ({ params, request }: LoaderFunctionArgs) => { - const queryClient = new QueryClient({ - defaultOptions: { - queries: { - // With SSR, we usually want to set some default staleTime - // above 0 to avoid refetching immediately on the client - staleTime: 60 * 1000, - }, - }, - }); - - const { getContentQuery } = ploneClient; - - await queryClient.prefetchQuery( - getContentQuery({ path: flattenToAppURL(request.url), expand }), - ); - - return json({ dehydratedState: dehydrate(queryClient) }); -}; - -function Page() { - const { getContentQuery } = usePloneClient(); - const pathname = useLocation().pathname; - const { data } = useQuery(getContentQuery({ path: pathname, expand })); - - if (!data) return null; - return ( - <> - - - - ); -} - -export default function Index() { - const { dehydratedState } = useLoaderData(); - - return ( - - - - ); -} diff --git a/apps/remix/app/utils.ts b/apps/remix/app/utils.ts index c297613f90..186833cc1d 100644 --- a/apps/remix/app/utils.ts +++ b/apps/remix/app/utils.ts @@ -1,4 +1,4 @@ -import config from './config'; +import config from '@plone/registry'; /** * Flatten to app server URL - Given a URL if it starts with the API server URL @@ -9,9 +9,11 @@ import config from './config'; */ export function flattenToAppURL(url: string) { const { settings } = config; - - return ( + const result = url && - url.replace(settings.apiPath, '').replace('http://localhost:3000', '') - ); + url + .replace(settings.apiPath, '') + .replace(settings.internalApiPath || '', '') + .replace('http://localhost:3000', ''); + return result; } diff --git a/apps/remix/package.json b/apps/remix/package.json index 31d7ec65e8..4af4ff9935 100644 --- a/apps/remix/package.json +++ b/apps/remix/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "@plone/blocks": "workspace: *", + "@plone/slots": "workspace: *", "@plone/client": "workspace: *", "@plone/components": "workspace: *", "@plone/providers": "workspace: *", diff --git a/apps/remix/registry.config.ts b/apps/remix/registry.config.ts new file mode 100644 index 0000000000..15b9c3f5d2 --- /dev/null +++ b/apps/remix/registry.config.ts @@ -0,0 +1,4 @@ +const addons = ['@plone/blocks', '@plone/slots']; +const theme = ''; + +export { addons, theme }; diff --git a/apps/remix/remix.config.js b/apps/remix/remix.config.js deleted file mode 100644 index 812df9d051..0000000000 --- a/apps/remix/remix.config.js +++ /dev/null @@ -1,8 +0,0 @@ -/** @type {import('@remix-run/dev').AppConfig} */ -export default { - ignoredRouteFiles: ['**/.*'], - // appDirectory: "app", - // assetsBuildDirectory: "public/build", - // publicPath: "/build/", - // serverBuildPath: "build/index.js", -}; diff --git a/apps/remix/vite.config.ts b/apps/remix/vite.config.ts index 03bfa30a99..d8694b0580 100644 --- a/apps/remix/vite.config.ts +++ b/apps/remix/vite.config.ts @@ -4,8 +4,41 @@ import tsconfigPaths from 'vite-tsconfig-paths'; import { PloneRegistryVitePlugin } from '@plone/registry/vite-plugin'; export default defineConfig({ + server: { + port: 3000, + proxy: { + '^/\\+\\+api\\+\\+($$|/.*)': { + target: + 'http://localhost:8080/VirtualHostBase/http/localhost:3000/Plone/++api++/VirtualHostRoot', + rewrite: (path) => { + console.log(path); + return path.replace('/++api++', ''); + }, + }, + }, + }, plugins: [ remix({ + routes: async (defineRoutes) => { + // If you need to do async work, do it before calling `defineRoutes`, we use + // the call stack of `route` inside to set nesting. + + return defineRoutes((route) => { + route('/', 'content.tsx', { id: 'index' }); + route('*', 'content.tsx', { id: 'splat' }); + // A common use for this is catchall routes. + // - The first argument is the React Router path to match against + // - The second is the relative filename of the route handler + // route("/some/path/*", "catchall.tsx"); + + // if you want to nest routes, use the optional callback argument + // route("some/:path", "some/route/file.js", () => { + // // - path is relative to parent path + // // - filenames are still relative to the app directory + // route("relative/path", "some/other/file"); + // }); + }); + }, future: { v3_fetcherPersist: true, v3_relativeSplatPath: true, @@ -15,7 +48,4 @@ export default defineConfig({ tsconfigPaths(), PloneRegistryVitePlugin(), ], - server: { - port: 3000, - }, }); diff --git a/apps/rr7/.eslintrc.cjs b/apps/rr7/.eslintrc.cjs index b4a6a65b4d..d1480fca9f 100644 --- a/apps/rr7/.eslintrc.cjs +++ b/apps/rr7/.eslintrc.cjs @@ -38,6 +38,7 @@ module.exports = { react: { version: 'detect', }, + 'import/core-modules': ['@plone/registry/addons-loader'], formComponents: ['Form'], linkComponents: [ { name: 'Link', linkAttribute: 'to' }, diff --git a/apps/rr7/app/client.ts b/apps/rr7/app/client.ts deleted file mode 100644 index 0eec9cd62e..0000000000 --- a/apps/rr7/app/client.ts +++ /dev/null @@ -1,8 +0,0 @@ -import ploneClient from '@plone/client'; -import config from '@plone/registry'; - -const cli = ploneClient.initialize({ - apiPath: config.settings.apiPath, -}); - -export { cli as ploneClient }; diff --git a/apps/rr7/app/config.server.ts b/apps/rr7/app/config.server.ts new file mode 100644 index 0000000000..2d7c951f7d --- /dev/null +++ b/apps/rr7/app/config.server.ts @@ -0,0 +1,32 @@ +/** + * This is the server side config entry point + */ +import config from '@plone/registry'; +import ploneClient from '@plone/client'; +import applyAddonConfiguration from '@plone/registry/addons-loader'; + +export default function install() { + applyAddonConfiguration(config); + + config.settings.apiPath = + process.env.PLONE_API_PATH || 'http://localhost:3000'; + config.settings.internalApiPath = + process.env.PLONE_INTERNAL_API_PATH || undefined; + + const cli = ploneClient.initialize({ + apiPath: config.settings.internalApiPath || config.settings.apiPath, + }); + + config.registerUtility({ + name: 'ploneClient', + type: 'client', + method: () => cli, + }); + + console.log('API_PATH is:', config.settings.apiPath); + console.log( + 'INTERNAL_API_PATH is:', + config.settings.internalApiPath || 'not set', + ); + return config; +} diff --git a/apps/rr7/app/config.ts b/apps/rr7/app/config.ts index e7133efdce..7f2026e538 100644 --- a/apps/rr7/app/config.ts +++ b/apps/rr7/app/config.ts @@ -1,15 +1,11 @@ +/** + * This is the client side config entry point + */ import config from '@plone/registry'; -import { blocksConfig, slate } from '@plone/blocks'; +import applyAddonConfiguration from '@plone/registry/addons-loader'; -const settings = { - apiPath: 'http://localhost:3000', - slate, -}; - -// @ts-expect-error We need to fix typing -config.set('settings', settings); - -// @ts-expect-error We need to fix typing -config.set('blocks', { blocksConfig }); - -export default config; +export default function install() { + applyAddonConfiguration(config); + config.settings.apiPath = 'http://localhost:3000'; + return config; +} diff --git a/apps/rr7/app/routes/home.tsx b/apps/rr7/app/content.tsx similarity index 63% rename from apps/rr7/app/routes/home.tsx rename to apps/rr7/app/content.tsx index c470ad9f42..5433ba9fda 100644 --- a/apps/rr7/app/routes/home.tsx +++ b/apps/rr7/app/content.tsx @@ -1,4 +1,4 @@ -import type { LoaderArgs } from '../routes/+types.home'; +import type { LoaderArgs } from './routes/+types.home'; import { dehydrate, QueryClient, @@ -6,14 +6,13 @@ import { useQuery, useQueryClient, } from '@tanstack/react-query'; -import { flattenToAppURL } from '../utils'; import { useLoaderData, useLocation } from 'react-router'; +import type { MetaFunction } from 'react-router'; import { usePloneClient } from '@plone/providers'; -import { Breadcrumbs, RenderBlocks } from '@plone/components'; +import PloneClient from '@plone/client'; +import App from '@plone/slots/components/App'; +import { flattenToAppURL } from './utils'; import config from '@plone/registry'; -import { ploneClient } from '../client'; - -import type { MetaFunction } from 'react-router'; export const meta: MetaFunction = () => { return [ @@ -22,7 +21,7 @@ export const meta: MetaFunction = () => { ]; }; -const expand = ['breadcrumbs', 'navigation']; +const expand = ['navroot', 'breadcrumbs', 'navigation']; // eslint-disable-next-line @typescript-eslint/no-unused-vars export async function loader({ params, request }: LoaderArgs) { @@ -36,11 +35,28 @@ export async function loader({ params, request }: LoaderArgs) { }, }); - const { getContentQuery } = ploneClient; + const ploneClient = config + .getUtility({ + name: 'ploneClient', + type: 'client', + }) + .method(); - await queryClient.prefetchQuery( - getContentQuery({ path: flattenToAppURL(request.url), expand }), - ); + const { getContentQuery } = ploneClient as PloneClient; + + const path = flattenToAppURL(request.url); + if ( + !( + /^https?:\/\//.test(path) || + /^favicon.ico\/\//.test(path) || + /expand/.test(path) || + /^\/@@images/.test(path) || + /^\/@@download/.test(path) || + /^\/assets/.test(path) + ) + ) { + await queryClient.prefetchQuery(getContentQuery({ path, expand })); + } return { dehydratedState: dehydrate(queryClient) }; } @@ -51,20 +67,7 @@ function Page() { const { data } = useQuery(getContentQuery({ path: pathname, expand })); if (!data) return 'Loading...'; - return ( - <> - - - - ); + return ; } export default function Content() { diff --git a/apps/rr7/app/okroute.tsx b/apps/rr7/app/okroute.tsx new file mode 100644 index 0000000000..56472e1bb6 --- /dev/null +++ b/apps/rr7/app/okroute.tsx @@ -0,0 +1,5 @@ +export async function loader() { + return new Response(null, { + status: 200, + }); +} diff --git a/apps/rr7/app/root.tsx b/apps/rr7/app/root.tsx index 50808c5b17..d1c4bb5bae 100644 --- a/apps/rr7/app/root.tsx +++ b/apps/rr7/app/root.tsx @@ -7,8 +7,9 @@ import { ScrollRestoration, useHref, useLocation, - useNavigate, + useNavigate as useRRNavigate, useParams, + useLoaderData, } from 'react-router'; import type { LinksFunction } from 'react-router'; @@ -18,9 +19,18 @@ import PloneClient from '@plone/client'; import { PloneProvider } from '@plone/providers'; import { flattenToAppURL } from './utils'; import config from '@plone/registry'; -import './config'; +import install from './config'; +import installSSR from './config.server'; -import '@plone/components/dist/basic.css'; +install(); + +import '@plone/theming/styles/main.css'; +import '@plone/slots/main.css'; + +function useNavigate() { + const navigate = useRRNavigate(); + return (to: string) => navigate(flattenToAppURL(to)); +} function useHrefLocal(to: string) { return useHref(flattenToAppURL(to)); @@ -35,11 +45,24 @@ export const links: LinksFunction = () => [ }, { rel: 'stylesheet', - href: 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap', + href: 'https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap', }, ]; +export async function loader() { + const ssrConfig = installSSR(); + + return { + env: { + PLONE_API_PATH: ssrConfig.settings.apiPath, + PLONE_INTERNAL_API_PATH: ssrConfig.settings.internalApiPath, + }, + }; +} + export function Layout({ children }: { children: React.ReactNode }) { + const data = useLoaderData(); + return ( @@ -51,6 +74,11 @@ export function Layout({ children }: { children: React.ReactNode }) { {children} + \ No newline at end of file diff --git a/packages/slots/.storybook/preview.ts b/packages/slots/.storybook/preview.ts new file mode 100644 index 0000000000..362843c9bc --- /dev/null +++ b/packages/slots/.storybook/preview.ts @@ -0,0 +1,24 @@ +import './storybook-base.css'; +import '@plone/components/dist/basic.css'; +import '../main.css'; +import config from '@plone/registry'; +import installSlots from '../config'; +import installBlocks from '@plone/blocks'; + +config.set('slots', {}); +config.set('utilities', {}); +installSlots(config); +installBlocks(config); + +export const parameters = { + backgrounds: { + default: 'light', + }, + actions: { argTypesRegex: '^on[A-Z].*' }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, +}; diff --git a/packages/slots/.storybook/storybook-base.css b/packages/slots/.storybook/storybook-base.css new file mode 100644 index 0000000000..f55ba4bf27 --- /dev/null +++ b/packages/slots/.storybook/storybook-base.css @@ -0,0 +1,19 @@ +/* Base styles */ +:root { + --basic-font-family: system-ui; + --basic-font-size: 16px; + background: var(--background-color); + font-family: var(--basic-font-family); + font-size: var(--basic-font-size); + line-height: 1.5; +} + +.sbdocs.sbdocs-content { + p { + font-size: 16px; + } +} + +#storybook-root { + width: 100vw; +} diff --git a/packages/slots/.storybook/theme.ts b/packages/slots/.storybook/theme.ts new file mode 100644 index 0000000000..3262e1f700 --- /dev/null +++ b/packages/slots/.storybook/theme.ts @@ -0,0 +1,10 @@ +import { create } from '@storybook/theming/create'; +import logo from './Logo.svg'; + +export default create({ + base: 'light', + brandTitle: '@plone/components StoryBook', + brandUrl: 'https://plone-components.netlify.app/', + brandImage: logo, + brandTarget: '_self', +}); diff --git a/packages/slots/.stylelintrc b/packages/slots/.stylelintrc new file mode 100644 index 0000000000..8ac62f8d0f --- /dev/null +++ b/packages/slots/.stylelintrc @@ -0,0 +1,14 @@ +{ + "extends": ["stylelint-config-idiomatic-order"], + "plugins": ["stylelint-prettier"], + "overrides": [ + { + "files": ["**/*.scss"], + "customSyntax": "postcss-scss" + } + ], + "rules": { + "prettier/prettier": true, + "order/properties-alphabetical-order": null + } +} diff --git a/packages/slots/CHANGELOG.md b/packages/slots/CHANGELOG.md new file mode 100644 index 0000000000..1eb8ee8211 --- /dev/null +++ b/packages/slots/CHANGELOG.md @@ -0,0 +1,11 @@ +# @plone/slots Release Notes + + + + + +## 1.0.0 (unreleased) diff --git a/packages/slots/README.md b/packages/slots/README.md index c77e2bb2de..8dae40cad3 100644 --- a/packages/slots/README.md +++ b/packages/slots/README.md @@ -1,6 +1,6 @@ -# `@plone/blocks` +# `@plone/slots` -This package contains the default blocks provided by Plone. +This package provides default structural slots for Plone 7 and the API-first story. > [!WARNING] > This package or app is experimental. diff --git a/packages/slots/SlotRenderer.tsx b/packages/slots/SlotRenderer.tsx new file mode 100644 index 0000000000..df2501d721 --- /dev/null +++ b/packages/slots/SlotRenderer.tsx @@ -0,0 +1,58 @@ +import config from '@plone/registry'; +import type { GetSlotArgs } from '@plone/types'; + +export type SlotComponentProps = { + content: GetSlotArgs['content']; + location: GetSlotArgs['location']; + navRoot?: GetSlotArgs['navRoot']; +}; + +/* + * The SlotRenderer component is used to render the components registered for a + * given slot. + * + * Usage: + * + */ +const SlotRenderer = ({ + name, + content, + location, + navRoot, +}: { + name: string; + content: GetSlotArgs['content']; + location: GetSlotArgs['location']; + navRoot?: GetSlotArgs['navRoot']; +}) => { + let slots = config.getSlot(name, { + content, + location, + // This is to cover the use case while adding a new content and we don't have + // the navRoot information in the initial content. This will be + // useful for SlotRenderers rendered in the `Add` route. + navRoot: content?.['@components']?.navroot?.navroot || navRoot, + }); + + if (!slots) { + return null; + } + + return ( + <> + {slots.map(({ component, name }) => { + const SlotComponent = component; + return ( + + ); + })} + + ); +}; + +export default SlotRenderer; diff --git a/packages/slots/components/App.stories.tsx b/packages/slots/components/App.stories.tsx new file mode 100644 index 0000000000..6dce553dfb --- /dev/null +++ b/packages/slots/components/App.stories.tsx @@ -0,0 +1,61 @@ +import App from './App'; + +import type { Meta, StoryObj } from '@storybook/react'; +import { storyData } from '../stories'; + +const meta = { + title: 'App', + component: App, + parameters: { + layout: 'centered', + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: (args: any) => , + args: { + content: { + '@id': 'http://localhost:3000/Plone', + title: 'Plone site', + description: 'Welcome to Plone', + items: [], + blocks: { + ...storyData.blocks, + }, + blocks_layout: { + ...storyData.blocks_layout, + }, + '@components': { + navigation: { + items: [ + { + '@id': 'http://localhost:3000/Plone', + title: 'Home', + }, + { + '@id': 'http://localhost:3000/Plone/news', + title: 'News', + }, + { + '@id': 'http://localhost:3000/Plone/about', + title: 'About', + }, + ], + }, + navroot: { + // @ts-expect-error This is a test object, missing all content properties + navroot: { + '@id': 'http://localhost:3000/Plone', + title: 'Plone site', + }, + }, + site: { + 'plone.site_title': 'Plone site', + }, + }, + }, + }, +}; diff --git a/packages/slots/components/App.tsx b/packages/slots/components/App.tsx new file mode 100644 index 0000000000..9f703a2be2 --- /dev/null +++ b/packages/slots/components/App.tsx @@ -0,0 +1,25 @@ +import type { GetSlotArgs } from '@plone/types'; +import SlotRenderer from '../SlotRenderer'; + +type AppProps = { + content: GetSlotArgs['content']; + location: GetSlotArgs['location']; +}; + +const App = (props: AppProps) => { + const { content, location } = props; + + return ( +
+
+ +
+ +
+ +
+
+ ); +}; + +export default App; diff --git a/packages/slots/components/ContentArea.tsx b/packages/slots/components/ContentArea.tsx new file mode 100644 index 0000000000..5d6324a793 --- /dev/null +++ b/packages/slots/components/ContentArea.tsx @@ -0,0 +1,19 @@ +import RenderBlocks from '@plone/blocks/RenderBlocks/RenderBlocks'; +import type { SlotComponentProps } from '../SlotRenderer'; +import config from '@plone/registry'; + +const ContentArea = (props: SlotComponentProps) => { + const { content } = props; + + return ( + <> + + + ); +}; + +export default ContentArea; diff --git a/packages/slots/components/Footer.tsx b/packages/slots/components/Footer.tsx new file mode 100644 index 0000000000..626340a642 --- /dev/null +++ b/packages/slots/components/Footer.tsx @@ -0,0 +1,21 @@ +import type { GetSlotArgs } from '@plone/types'; +import SlotRenderer from '../SlotRenderer'; + +type FooterProps = { + content: GetSlotArgs['content']; + location: GetSlotArgs['location']; +}; + +const Footer = (props: FooterProps) => { + const { content, location } = props; + + return ( + <> + + + + + ); +}; + +export default Footer; diff --git a/packages/slots/components/Header.stories.tsx b/packages/slots/components/Header.stories.tsx new file mode 100644 index 0000000000..d90e0f251f --- /dev/null +++ b/packages/slots/components/Header.stories.tsx @@ -0,0 +1,55 @@ +import Header from './Header'; + +import type { Meta, StoryObj } from '@storybook/react'; + +const meta = { + title: 'Header', + component: Header, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: (args: any) =>
, + args: { + content: { + '@id': 'http://localhost:3000/Plone', + title: 'Plone site', + description: 'Welcome to Plone', + items: [], + '@components': { + navigation: { + items: [ + { + '@id': 'http://localhost:3000/Plone', + title: 'Home', + }, + { + '@id': 'http://localhost:3000/Plone/news', + title: 'News', + }, + { + '@id': 'http://localhost:3000/Plone/about', + title: 'About', + }, + ], + }, + navroot: { + // @ts-expect-error This is a test object, missing all content properties + navroot: { + '@id': 'http://localhost:3000/Plone', + title: 'Plone site', + }, + }, + site: { + 'plone.site_title': 'Plone site', + }, + }, + }, + }, +}; diff --git a/packages/slots/components/Header.tsx b/packages/slots/components/Header.tsx new file mode 100644 index 0000000000..1b2d743082 --- /dev/null +++ b/packages/slots/components/Header.tsx @@ -0,0 +1,28 @@ +import type { GetSlotArgs } from '@plone/types'; +import SlotRenderer from '../SlotRenderer'; +import { Container } from '@plone/components'; + +type HeaderProps = { + content: GetSlotArgs['content']; + location: GetSlotArgs['location']; +}; + +const Header = (props: HeaderProps) => { + const { content, location } = props; + + return ( + + + +
+ +
+
+ ); +}; + +export default Header; diff --git a/packages/slots/components/Logo.stories.tsx b/packages/slots/components/Logo.stories.tsx new file mode 100644 index 0000000000..348dc836dc --- /dev/null +++ b/packages/slots/components/Logo.stories.tsx @@ -0,0 +1,39 @@ +import Logo from './Logo'; + +import type { Meta, StoryObj } from '@storybook/react'; + +const meta = { + title: 'Logo', + component: Logo, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: (args: any) => , + args: { + content: { + '@id': 'http://localhost:3000/Plone', + title: 'Plone site', + description: 'Welcome to Plone', + items: [], + '@components': { + navroot: { + // @ts-expect-error This is a test object, missing all content properties + navroot: { + '@id': 'http://localhost:3000/Plone', + title: 'Plone site', + }, + }, + site: { + 'plone.site_title': 'Plone site', + }, + }, + }, + }, +}; diff --git a/packages/slots/components/Logo.svg b/packages/slots/components/Logo.svg new file mode 100644 index 0000000000..5a7ba56902 --- /dev/null +++ b/packages/slots/components/Logo.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/slots/components/Logo.tsx b/packages/slots/components/Logo.tsx new file mode 100644 index 0000000000..3b17c02603 --- /dev/null +++ b/packages/slots/components/Logo.tsx @@ -0,0 +1,27 @@ +import type { SlotComponentProps } from '../SlotRenderer'; +import { Link } from '@plone/components'; +import LogoImage from './Logo.svg'; +import config from '@plone/registry'; +import { messages } from './messages'; + +const Logo = (props: SlotComponentProps) => { + const { content } = props; + const intl: (id: string) => string = config.getUtility({ + name: 'translation', + type: 'factory', + }).method; + const navRootPath = content['@components'].navroot?.navroot?.['@id'] || '/'; + const site = content['@components'].site; + const siteTitle = site?.['plone.site_title'] || ''; + const logoUrl = site?.['plone.site_logo'] + ? site['plone.site_logo'] + : LogoImage; + + return ( + + {intl(messages.logoOf) + + ); +}; + +export default Logo; diff --git a/packages/slots/components/Main.tsx b/packages/slots/components/Main.tsx new file mode 100644 index 0000000000..454ed36d78 --- /dev/null +++ b/packages/slots/components/Main.tsx @@ -0,0 +1,22 @@ +import type { GetSlotArgs } from '@plone/types'; +import SlotRenderer from '../SlotRenderer'; +import { Container } from '@plone/components'; + +type MainProps = { + content: GetSlotArgs['content']; + location: GetSlotArgs['location']; +}; + +const Main = (props: MainProps) => { + const { content, location } = props; + + return ( + + + + + + ); +}; + +export default Main; diff --git a/packages/slots/components/MainFooter.tsx b/packages/slots/components/MainFooter.tsx new file mode 100644 index 0000000000..f5f3c39c38 --- /dev/null +++ b/packages/slots/components/MainFooter.tsx @@ -0,0 +1,38 @@ +import type { SlotComponentProps } from '../SlotRenderer'; +import { Container, Link } from '@plone/components'; +import Logo from './Logo'; + +const Footer = (props: SlotComponentProps) => { + const { content, location } = props; + const siteActions = content?.['@components']?.actions?.site_actions || []; + + return ( + + {/* TODO: i18n properly */} +
+ The Plone® Open Source CMS/WCM is © 2000-2024 by the Plone Foundation + and friends.
+ Distributed under the GNU GPL license. +
+
    + {siteActions?.length + ? siteActions.map((item) => ( +
  • + + {item?.title} + +
  • + )) + : null} +
+ + + + + Powered by Plone & Python + +
+ ); +}; + +export default Footer; diff --git a/packages/slots/components/Navigation.stories.tsx b/packages/slots/components/Navigation.stories.tsx new file mode 100644 index 0000000000..e94ad2cbd2 --- /dev/null +++ b/packages/slots/components/Navigation.stories.tsx @@ -0,0 +1,45 @@ +import Navigation from './Navigation'; + +import type { Meta, StoryObj } from '@storybook/react'; + +const meta = { + title: 'Navigation', + component: Navigation, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: (args: any) => , + args: { + content: { + '@id': 'http://localhost:3000/Plone', + title: 'Plone site', + description: 'Welcome to Plone', + items: [], + '@components': { + navigation: { + items: [ + { + '@id': 'http://localhost:3000/Plone', + title: 'Plone site', + }, + { + '@id': 'http://localhost:3000/Plone/news', + title: 'News', + }, + { + '@id': 'http://localhost:3000/Plone/about', + title: 'About', + }, + ], + }, + }, + }, + }, +}; diff --git a/packages/slots/components/Navigation.tsx b/packages/slots/components/Navigation.tsx new file mode 100644 index 0000000000..afccd4ae93 --- /dev/null +++ b/packages/slots/components/Navigation.tsx @@ -0,0 +1,26 @@ +import type { SlotComponentProps } from '../SlotRenderer'; +import { Link } from '@plone/components'; + +type NavItem = { + '@id': string; + title: string; +}; + +const Navigation = (props: SlotComponentProps) => { + const { content } = props; + const navItems = content['@components'].navigation?.items || []; + + return ( + + ); +}; + +export default Navigation; diff --git a/packages/slots/components/Tools.tsx b/packages/slots/components/Tools.tsx new file mode 100644 index 0000000000..6718f028e1 --- /dev/null +++ b/packages/slots/components/Tools.tsx @@ -0,0 +1,6 @@ +const HeaderTools = (props) => { + const { content, location } = props; + return 'The tools'; +}; + +export default HeaderTools; diff --git a/packages/slots/components/messages.ts b/packages/slots/components/messages.ts new file mode 100644 index 0000000000..2e2e95fd7d --- /dev/null +++ b/packages/slots/components/messages.ts @@ -0,0 +1,5 @@ +export const messages = { + home: 'Home', + siteLogo: 'Site logo', + logoOf: 'Logo of', +}; diff --git a/packages/slots/index.ts b/packages/slots/index.ts new file mode 100644 index 0000000000..885e8d2778 --- /dev/null +++ b/packages/slots/index.ts @@ -0,0 +1,78 @@ +import type { ConfigType } from '@plone/registry'; +import App from './components/App'; +import Header from './components/Header'; +import Main from './components/Main'; +import Footer from './components/Footer'; +import Logo from './components/Logo'; +import Navigation from './components/Navigation'; +import HeaderTools from './components/Tools'; +import ContentArea from './components/ContentArea'; +import MainFooter from './components/MainFooter'; + +export default function install(config: ConfigType) { + // Translation factory + config.registerUtility({ + name: 'translation', + type: 'factory', + method: (id: string) => id, + }); + + // Main App Slot + config.registerSlotComponent({ name: 'App', slot: 'App', component: App }); + + // Header Slot + config.registerSlotComponent({ + name: 'Header', + slot: 'header', + component: Header, + }); + + // Logo + config.registerSlotComponent({ + name: 'Logo', + slot: 'logo', + component: Logo, + }); + + // Navigation + config.registerSlotComponent({ + name: 'Navigation', + slot: 'navigation', + component: Navigation, + }); + + // Tools + config.registerSlotComponent({ + name: 'Tools', + slot: 'headertools', + component: HeaderTools, + }); + + // Main Slot + config.registerSlotComponent({ + name: 'Main', + slot: 'main', + component: Main, + }); + + config.registerSlotComponent({ + name: 'contentArea', + slot: 'contentArea', + component: ContentArea, + }); + + // Footer Slot + config.registerSlotComponent({ + name: 'Footer', + slot: 'footer', + component: Footer, + }); + + config.registerSlotComponent({ + name: 'mainFooter', + slot: 'mainFooter', + component: MainFooter, + }); + + return config; +} diff --git a/packages/slots/main.css b/packages/slots/main.css new file mode 100644 index 0000000000..32062cf557 --- /dev/null +++ b/packages/slots/main.css @@ -0,0 +1,100 @@ +:root { + /* These should come from @plone/components by default */ + --layout-container-width: 1440px; + --default-container-width: 940px; + --narrow-container-width: 620px; + + --align-right: end; + --align-left: start; + --align-center: center; +} + +body { + /* This needs a proper reset */ + margin: 0; +} + +.app-slot { + display: grid; + height: 100vh; + margin: 0; + grid-template-areas: + 'header' + 'content' + 'footer'; + grid-template-columns: 1fr; + grid-template-rows: auto 1fr auto; +} + +.header-logo-nav-tools-wrapper { + display: flex; + flex-direction: row; + align-items: baseline; + justify-content: space-between; + padding-top: 25px; + padding-bottom: 35px; +} + +.logo { + flex: 1 1 0; + align-self: center; +} + +.navigation { + display: flex; + flex: 3.5 1 0; + align-self: center; + justify-content: center; + + ul { + display: flex; + padding: 0; + margin: 0; + list-style: none; + + li a { + padding: 1rem 0; + margin-left: 1rem; + } + + li:first-child a { + margin-left: 0; + } + } +} + +.header-tools { + display: flex; + flex: 1 1 0; + flex-direction: row-reverse; +} + +main { + grid-area: 'content'; +} + +.content-area > * { + max-width: var(--default-container-width); + margin-right: auto; + margin-left: auto; +} + +figure img { + width: 100%; +} + +footer { + margin-top: 100px; +} + +.footer { + display: flex; + flex-direction: column; + padding: 2rem 0; + text-align: center; + + .logo { + margin: 20px 0; + place-self: center; + } +} diff --git a/packages/slots/news/.gitkeep b/packages/slots/news/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/slots/news/6409.internal b/packages/slots/news/6409.internal new file mode 100644 index 0000000000..5712bbc003 --- /dev/null +++ b/packages/slots/news/6409.internal @@ -0,0 +1 @@ +Initial commit, first steps. @sneridagh diff --git a/packages/slots/news/6536.internal b/packages/slots/news/6536.internal new file mode 100644 index 0000000000..27c8bbd143 --- /dev/null +++ b/packages/slots/news/6536.internal @@ -0,0 +1 @@ +Centralize `tsconfig`. @sneridagh diff --git a/packages/slots/package.json b/packages/slots/package.json index 9766de2823..208b14f0c4 100644 --- a/packages/slots/package.json +++ b/packages/slots/package.json @@ -28,13 +28,17 @@ "publishConfig": { "access": "public" }, - "main": "src/index.ts", + "type": "module", + "main": "index.ts", "scripts": { "test": "vitest", + "check-ts": "tsc --project tsconfig.json", "dry-release": "release-it --dry-run", "release": "release-it", "release-major-alpha": "release-it major --preRelease=alpha", - "release-alpha": "release-it --preRelease=alpha" + "release-alpha": "release-it --preRelease=alpha", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0", @@ -46,16 +50,33 @@ } }, "dependencies": { - "@plone/providers": "workspace:*", - "@plone/registry": "workspace:*" + "@plone/blocks": "workspace:*", + "@plone/client": "workspace:*", + "@plone/components": "workspace:*", + "@plone/registry": "workspace:*", + "react-aria-components": "^1.5.0" }, "devDependencies": { "@plone/types": "workspace:*", + "@storybook/addon-essentials": "^8.0.4", + "@storybook/addon-interactions": "^8.0.4", + "@storybook/addon-links": "^8.0.4", + "@storybook/addon-mdx-gfm": "^8.0.4", + "@storybook/blocks": "^8.0.4", + "@storybook/manager-api": "^8.0.4", + "@storybook/react": "^8.0.4", + "@storybook/react-vite": "^8.0.4", + "@storybook/theming": "^8.0.4", "@types/react": "^18", "@types/react-dom": "^18", + "eslint-plugin-storybook": "^0.8.0", + "jest-axe": "^8.0.0", "release-it": "17.1.1", + "storybook": "^8.0.4", "tsconfig": "workspace:*", "typescript": "^5.6.3", - "vitest": "^2.1.3" + "vite": "^5.4.8", + "vitest": "^2.1.3", + "vitest-axe": "^0.1.0" } } diff --git a/packages/slots/setupTesting.ts b/packages/slots/setupTesting.ts new file mode 100644 index 0000000000..8bc87fa36e --- /dev/null +++ b/packages/slots/setupTesting.ts @@ -0,0 +1,3 @@ +import '@testing-library/jest-dom'; +import { toHaveNoViolations } from 'jest-axe'; +expect.extend(toHaveNoViolations); diff --git a/packages/slots/src/SlotRenderer.tsx b/packages/slots/src/SlotRenderer.tsx deleted file mode 100644 index a2567dee6f..0000000000 --- a/packages/slots/src/SlotRenderer.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react'; -import { useRouterLocation } from '@plone/providers'; -import config from '@plone/registry'; - -import type { Content } from '@plone/types'; - -/* -Usage: - -*/ - -const SlotRenderer = ({ - name, - content, - navRoot, -}: { - name: string; - content: Content; - navRoot?: Content; -}) => { - const pathname = useRouterLocation().pathname; - - let slots = config.getSlot(name, { - content, - pathname, - // This is to cover the use case while adding a new content and we don't have - // have the navRoot information in the initial content. This will be - // useful for SlotRenderers rendered in the `Add` route. - navRoot: content?.['@components']?.navroot?.navroot || navRoot, - }); - - if (!slots) { - return null; - } - - return ( - <> - {slots.map( - ({ - component, - name, - }: { - component: React.ComponentType; - name: string; - }) => { - // ^^ Weird compilation issue for Jest tests, that forced to re-declare the type above - const SlotComponent = component; - return ( - - ); - }, - )} - - ); -}; - -export default SlotRenderer; diff --git a/packages/slots/src/index.ts b/packages/slots/src/index.ts deleted file mode 100644 index 6fe8d63809..0000000000 --- a/packages/slots/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './SlotRenderer'; diff --git a/packages/slots/stories.ts b/packages/slots/stories.ts new file mode 100644 index 0000000000..6a668df163 --- /dev/null +++ b/packages/slots/stories.ts @@ -0,0 +1,22 @@ +export const storyData = { + blocks: { + '7ab29abe-b38c-406b-94d7-b270e544a998': { + '@type': 'slate', + value: [ + { + type: 'p', + children: [ + { + text: 'Lorem ipsum dolor sit amet eu tempus ornare elit. Curabitur egestas quisque molestie pellentesque nunc imperdiet posuere morbi nunc eleifend. Volutpat enim augue blandit aliquam interdum pulvinar eu mattis congue. Eleifend mauris ut fermentum egestas mi faucibus adipiscing arcu nibh scelerisque justo habitasse. Mi consectetur hac maecenas leo dictumst vitae phasellus quam praesent vivamus nullam imperdiet integer mauris.', + }, + ], + }, + ], + plaintext: + 'Lorem ipsum dolor sit amet eu tempus ornare elit. Curabitur egestas quisque molestie pellentesque nunc imperdiet posuere morbi nunc eleifend. Volutpat enim augue blandit aliquam interdum pulvinar eu mattis congue. Eleifend mauris ut fermentum egestas mi faucibus adipiscing arcu nibh scelerisque justo habitasse. Mi consectetur hac maecenas leo dictumst vitae phasellus quam praesent vivamus nullam imperdiet integer mauris.', + }, + }, + blocks_layout: { + items: ['7ab29abe-b38c-406b-94d7-b270e544a998'], + }, +}; diff --git a/packages/slots/towncrier.toml b/packages/slots/towncrier.toml new file mode 100644 index 0000000000..3ef721f378 --- /dev/null +++ b/packages/slots/towncrier.toml @@ -0,0 +1,33 @@ +[tool.towncrier] +filename = "CHANGELOG.md" +directory = "news/" +title_format = "## {version} ({project_date})" +underlines = ["", "", ""] +template = "../scripts/templates/towncrier_template.jinja" +start_string = "\n" +issue_format = "[#{issue}](https://github.com/plone/volto/issues/{issue})" + +[[tool.towncrier.type]] +directory = "breaking" +name = "Breaking" +showcontent = true + +[[tool.towncrier.type]] +directory = "feature" +name = "Feature" +showcontent = true + +[[tool.towncrier.type]] +directory = "bugfix" +name = "Bugfix" +showcontent = true + +[[tool.towncrier.type]] +directory = "internal" +name = "Internal" +showcontent = true + +[[tool.towncrier.type]] +directory = "documentation" +name = "Documentation" +showcontent = true diff --git a/packages/slots/tsconfig.json b/packages/slots/tsconfig.json index 27e48db56e..2965402840 100644 --- a/packages/slots/tsconfig.json +++ b/packages/slots/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "tsconfig/react-library.json", - "include": ["src", "src/**/*.js", "../providers/src/RouterLocation.tsx"], + "include": ["**/*.ts", "**/*.tsx"], "exclude": [ "node_modules", "build", diff --git a/packages/slots/vitest.config.ts b/packages/slots/vitest.config.ts new file mode 100644 index 0000000000..fddf5f61f7 --- /dev/null +++ b/packages/slots/vitest.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from 'vitest/config'; + +// https://vitejs.dev/config/ +export default defineConfig({ + test: { + globals: true, + environment: 'jsdom', + setupFiles: './setupTesting.ts', + // you might want to disable it, if you don't have tests that rely on CSS + // since parsing CSS is slow + css: true, + exclude: ['**/node_modules/**', '**/lib/**'], + }, +}); diff --git a/packages/theming/.release-it.json b/packages/theming/.release-it.json new file mode 100644 index 0000000000..708ed7fca5 --- /dev/null +++ b/packages/theming/.release-it.json @@ -0,0 +1,29 @@ +{ + "plugins": { + "../scripts/prepublish.js": {} + }, + "hooks": { + "after:bump": [ + "pipx run towncrier build --draft --yes --version ${version} > .changelog.draft", + "pipx run towncrier build --yes --version ${version}" + ], + "after:release": "rm .changelog.draft" + }, + "npm": { + "publish": false + }, + "git": { + "commitArgs": ["--no-verify"], + "changelog": "pipx run towncrier build --draft --yes --version 0.0.0", + "requireUpstream": false, + "requireCleanWorkingDir": false, + "commitMessage": "Release @plone/theming ${version}", + "tagName": "plone-theming-${version}", + "tagAnnotation": "Release @plone/theming ${version}" + }, + "github": { + "release": true, + "releaseName": "@plone/theming ${version}", + "releaseNotes": "cat .changelog.draft" + } +} diff --git a/packages/theming/.stylelintrc b/packages/theming/.stylelintrc new file mode 100644 index 0000000000..8ac62f8d0f --- /dev/null +++ b/packages/theming/.stylelintrc @@ -0,0 +1,14 @@ +{ + "extends": ["stylelint-config-idiomatic-order"], + "plugins": ["stylelint-prettier"], + "overrides": [ + { + "files": ["**/*.scss"], + "customSyntax": "postcss-scss" + } + ], + "rules": { + "prettier/prettier": true, + "order/properties-alphabetical-order": null + } +} diff --git a/packages/theming/CHANGELOG.md b/packages/theming/CHANGELOG.md new file mode 100644 index 0000000000..d3ab18563b --- /dev/null +++ b/packages/theming/CHANGELOG.md @@ -0,0 +1,11 @@ +# @plone/theming Release Notes + + + + + +## 1.0.0 (unreleased) diff --git a/packages/theming/README.md b/packages/theming/README.md new file mode 100644 index 0000000000..6d4db8dc8e --- /dev/null +++ b/packages/theming/README.md @@ -0,0 +1,8 @@ +# @plone/theming + +Base fundamental theming infrastructure for Plone 7 and the API-first story. + +> [!WARNING] +> This package or app is experimental. +> The community offers no support whatsoever for it. +> Breaking changes may occur without notice. diff --git a/packages/theming/index.ts b/packages/theming/index.ts new file mode 100644 index 0000000000..7258290153 --- /dev/null +++ b/packages/theming/index.ts @@ -0,0 +1,5 @@ +import type { ConfigType } from '@plone/registry'; + +export default function install(config: ConfigType) { + return config; +} diff --git a/packages/theming/news/.gitkeep b/packages/theming/news/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/theming/news/6409.internal b/packages/theming/news/6409.internal new file mode 100644 index 0000000000..5712bbc003 --- /dev/null +++ b/packages/theming/news/6409.internal @@ -0,0 +1 @@ +Initial commit, first steps. @sneridagh diff --git a/packages/theming/news/6536.internal b/packages/theming/news/6536.internal new file mode 100644 index 0000000000..27c8bbd143 --- /dev/null +++ b/packages/theming/news/6536.internal @@ -0,0 +1 @@ +Centralize `tsconfig`. @sneridagh diff --git a/packages/theming/package.json b/packages/theming/package.json new file mode 100644 index 0000000000..688bd0231c --- /dev/null +++ b/packages/theming/package.json @@ -0,0 +1,79 @@ +{ + "name": "@plone/theming", + "description": "Plone base foundamental theming", + "maintainers": [ + { + "name": "Plone Foundation", + "url": "https://plone.org" + } + ], + "funding": "https://github.com/sponsors/plone", + "license": "MIT", + "version": "1.0.0", + "repository": { + "type": "git", + "url": "https://github.com/plone/volto.git" + }, + "bugs": { + "url": "https://github.com/plone/volto/issues" + }, + "homepage": "https://plone.org", + "keywords": [ + "volto", + "plone", + "plone6", + "react", + "helpers" + ], + "publishConfig": { + "access": "public" + }, + "main": "index.ts", + "scripts": { + "test": "vitest", + "dry-release": "release-it --dry-run", + "release": "release-it", + "release-major-alpha": "release-it major --preRelease=alpha", + "release-alpha": "release-it --preRelease=alpha", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + }, + "dependencies": { + "@plone/components": "workspace:*", + "@plone/registry": "workspace:*", + "lightningcss": "1.28.1", + "lightningcss-cli": "1.28.1" + }, + "devDependencies": { + "@plone/types": "workspace:*", + "@storybook/addon-essentials": "^8.0.4", + "@storybook/addon-interactions": "^8.0.4", + "@storybook/addon-links": "^8.0.4", + "@storybook/addon-mdx-gfm": "^8.0.4", + "@storybook/blocks": "^8.0.4", + "@storybook/manager-api": "^8.0.4", + "@storybook/react": "^8.0.4", + "@storybook/react-vite": "^8.0.4", + "@storybook/theming": "^8.0.4", + "@types/react": "^18", + "@types/react-dom": "^18", + "eslint-plugin-storybook": "^0.8.0", + "jest-axe": "^8.0.0", + "release-it": "17.1.1", + "storybook": "^8.0.4", + "tsconfig": "workspace:*", + "typescript": "^5.6.3", + "vite": "^5.4.8", + "vitest": "^2.1.3", + "vitest-axe": "^0.1.0" + } +} diff --git a/packages/theming/styles/base.css b/packages/theming/styles/base.css new file mode 100644 index 0000000000..66bee507e3 --- /dev/null +++ b/packages/theming/styles/base.css @@ -0,0 +1,8 @@ +body { + font-family: var(--basic-font-family, system-ui); + font-size: var(--basic-font-size, 16px); +} + +figure { + margin: 0; +} diff --git a/packages/theming/styles/layout.css b/packages/theming/styles/layout.css new file mode 100644 index 0000000000..630985a3f3 --- /dev/null +++ b/packages/theming/styles/layout.css @@ -0,0 +1,3 @@ +/* body { + background-color: red; +} */ diff --git a/packages/theming/styles/main.css b/packages/theming/styles/main.css new file mode 100644 index 0000000000..c3db9e90b1 --- /dev/null +++ b/packages/theming/styles/main.css @@ -0,0 +1,5 @@ +@layer reset, plone-components, layout, addons, theme; +@import 'reset.css'; +@import 'base.css'; +@import '@plone/components/dist/basic.css'; +@import 'layout.css'; diff --git a/packages/theming/styles/reset.css b/packages/theming/styles/reset.css new file mode 100644 index 0000000000..31cdac9449 --- /dev/null +++ b/packages/theming/styles/reset.css @@ -0,0 +1,224 @@ +/* Borrowed from https://www.miriamsuzanne.com */ +@layer reset { + /* @docs + label: Core Remedies + version: 0.1.0-beta.2 + + note: | + These remedies are recommended + as a starter for any project. + + category: file + */ + /* @docs + label: Box Sizing + + note: | + Use border-box by default, globally. + + category: global + */ + *, + ::before, + ::after { + box-sizing: border-box; + } + /* @docs + label: Line Sizing + + note: | + Consistent line-spacing, + even when inline elements have different line-heights. + + links: + - https://drafts.csswg.org/css-inline-3/#line-sizing-property + + category: global + */ + html { + line-sizing: normal; + } + /* @docs + label: Body Margins + + note: | + Remove the tiny space around the edge of the page. + + category: global + */ + body { + margin: 0; + } + /* @docs + label: Heading Sizes + + note: | + Switch to rem units for headings + + category: typography + */ + h1 { + font-size: 2rem; + } + h2 { + font-size: 1.5rem; + } + h3 { + font-size: 1.17rem; + } + h4 { + font-size: 1rem; + } + h5 { + font-size: 0.83rem; + } + h6 { + font-size: 0.67rem; + } + /* @docs + label: H1 Margins + + note: | + Keep h1 margins consistent, even when nested. + + category: typography + */ + h1 { + margin: 0.67em 0; + } + /* @docs + label: Pre Wrapping + + note: | + Overflow by default is bad... + + category: typography + */ + pre { + white-space: pre-wrap; + } + /* @docs + label: Horizontal Rule + + note: | + 1. Solid, thin horizontal rules + 2. Remove Firefox `color: gray` + 3. Remove default `1px` height, and common `overflow: hidden` + + category: typography + */ + hr { + overflow: visible; + height: 0; + border-width: 1px 0 0; + border-style: solid; + color: inherit; + } + /* @docs + label: Responsive Embeds + + note: | + 1. Block display is usually what we want + 2. Remove strange space-below when inline + 3. Responsive by default + + category: embedded elements + */ + img, + svg, + video, + canvas, + audio, + iframe, + embed, + object { + display: block; + max-width: 100%; + vertical-align: middle; + } + /* @docs + label: Aspect Ratios + + note: | + Maintain intrinsic aspect ratios when `max-width` is applied. + `iframe`, `embed`, and `object` are also embedded, + but have no intrinsic ratio, + so their `height` needs to be set explicitly. + + category: embedded elements + */ + img, + svg, + video, + canvas { + height: auto; + } + /* @docs + label: Audio Width + + note: | + There is no good reason elements default to 300px, + and audio files are unlikely to come with a width attribute. + + category: embedded elements + */ + audio { + width: 100%; + } + /* @docs + label: Image Borders + + note: | + Remove the border on images inside links in IE 10 and earlier. + + category: legacy browsers + */ + img { + border-style: none; + } + /* @docs + label: SVG Overflow + + note: | + Hide the overflow in IE 10 and earlier. + + category: legacy browsers + */ + svg { + overflow: hidden; + } + /* @docs + label: HTML5 Elements + + note: | + Default block display on HTML5 elements + + category: legacy browsers + */ + article, + aside, + figcaption, + figure, + footer, + header, + hgroup, + main, + nav, + section { + display: block; + } + /* @docs + label: Checkbox & Radio Inputs + + note: | + 1. Add the correct box sizing in IE 10 + 2. Remove the padding in IE 10 + + category: legacy browsers + */ + [type='checkbox'], + [type='radio'] { + box-sizing: border-box; + padding: 0; + } +} diff --git a/packages/theming/towncrier.toml b/packages/theming/towncrier.toml new file mode 100644 index 0000000000..3ef721f378 --- /dev/null +++ b/packages/theming/towncrier.toml @@ -0,0 +1,33 @@ +[tool.towncrier] +filename = "CHANGELOG.md" +directory = "news/" +title_format = "## {version} ({project_date})" +underlines = ["", "", ""] +template = "../scripts/templates/towncrier_template.jinja" +start_string = "\n" +issue_format = "[#{issue}](https://github.com/plone/volto/issues/{issue})" + +[[tool.towncrier.type]] +directory = "breaking" +name = "Breaking" +showcontent = true + +[[tool.towncrier.type]] +directory = "feature" +name = "Feature" +showcontent = true + +[[tool.towncrier.type]] +directory = "bugfix" +name = "Bugfix" +showcontent = true + +[[tool.towncrier.type]] +directory = "internal" +name = "Internal" +showcontent = true + +[[tool.towncrier.type]] +directory = "documentation" +name = "Documentation" +showcontent = true diff --git a/packages/theming/tsconfig.json b/packages/theming/tsconfig.json new file mode 100644 index 0000000000..87cd5d54b7 --- /dev/null +++ b/packages/theming/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "tsconfig/react-library.json", + "include": ["index.ts"] +} diff --git a/packages/tsconfig/base.json b/packages/tsconfig/base.json index d8aaba63d9..f3e404842e 100644 --- a/packages/tsconfig/base.json +++ b/packages/tsconfig/base.json @@ -2,22 +2,27 @@ "$schema": "https://json.schemastore.org/tsconfig", "display": "Default", "compilerOptions": { - "target": "ESNext", - "lib": ["DOM", "DOM.Iterable", "ESNext"], - "module": "commonjs", - "allowJs": true, - "skipLibCheck": true, "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "strictPropertyInitialization": false, - "moduleResolution": "Node", + "skipLibCheck": true, + "target": "es2022", + "allowJs": true, "resolveJsonModule": true, + "moduleDetection": "force", "isolatedModules": true, + "verbatimModuleSyntax": true, + + "strict": true, + "noImplicitOverride": true, + + "lib": ["es2022", "dom", "dom.iterable"], + "module": "preserve", "noEmit": true, - "noImplicitAny": false, - "strict": false + + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + + "paths": {} }, "include": ["src"], - "exclude": ["node_modules"] + "exclude": ["node_modules", "build", "public", "coverage"] } diff --git a/packages/tsconfig/baseAdobe.json b/packages/tsconfig/baseAdobe.json deleted file mode 100644 index ea57d949d4..0000000000 --- a/packages/tsconfig/baseAdobe.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "compilerOptions": { - // we can explicitly declare `any`, but we don't want to infer `any` - "noImplicitAny": false, - // maybe bump to 'esNext'? - "target": "es6", - // allows react jsx in tsx files - "jsx": "react", - // Eventually turn off, one we have no more assumed default exports. - // Allow default imports from modules with no default export. - "allowSyntheticDefaultImports": true, - // allows importing of json files, needed for locales as of right now - "resolveJsonModule": true, - // Search under node_modules for non-relative imports. - "moduleResolution": "node", - // Process & infer types from .js files. - "allowJs": true, - // Don't emit; allow Babel to transform files. - "noEmit": true, - // Disallow features that require cross-file information for emit. - "isolatedModules": true, - // Import non-ES modules as default imports. - "esModuleInterop": true, - // if 'target' is updated, this should be updated as well - "lib": [ - "esnext", - "dom", - "dom.iterable" - ], - "skipLibCheck": false, - "strict": false, - }, - "include": [ - "src" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/packages/tsconfig/baseold.json b/packages/tsconfig/baseold.json deleted file mode 100644 index 622286411a..0000000000 --- a/packages/tsconfig/baseold.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Default", - "compilerOptions": { - "esModuleInterop": true, - "skipLibCheck": true, - "target": "es2022", - "resolveJsonModule": true, - "isolatedModules": true, - "moduleDetection": "force", - "strict": true, - "noUncheckedIndexedAccess": true, - "moduleResolution": "Bundler", - "module": "ESNext", - "noEmit": true, - "lib": ["es2022", "dom", "dom.iterable"] - }, - "exclude": ["node_modules"] -} diff --git a/packages/tsconfig/nextjs.json b/packages/tsconfig/nextjs.json deleted file mode 100644 index e3748f2006..0000000000 --- a/packages/tsconfig/nextjs.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "display": "Next.js", - "extends": "./base.json", - "compilerOptions": { - "plugins": [{ "name": "next" }], - "incremental": true, - "allowJs": true, - "jsx": "preserve" - }, - "include": ["src", "next-env.d.ts"], - "exclude": ["node_modules"] -} diff --git a/packages/types/.release-it.json b/packages/types/.release-it.json index 11f1e08e9e..3db3e87c46 100644 --- a/packages/types/.release-it.json +++ b/packages/types/.release-it.json @@ -4,7 +4,8 @@ }, "hooks": { "after:bump": [ - "pipx run towncrier build --draft --yes --version ${version} > .changelog.draft && pipx run towncrier build --yes --version ${version}" + "pipx run towncrier build --draft --yes --version ${version} > .changelog.draft", + "pipx run towncrier build --yes --version ${version}" ], "after:release": "rm .changelog.draft" }, diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index 7ff1b32ec2..348c505930 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,4 +1,4 @@ -# @plone/volto-types Release Notes +# @plone/types Release Notes +## 1.2.0 (2024-12-17) + +### Feature + +- Added the typing for the new `cssLayers` configuration object setting. @sneridagh [#6539](https://github.com/plone/volto/issues/6539) + +## 1.1.0 (2024-12-12) + +### Feature + +- Added block category type. @sneridagh [#6409](https://github.com/plone/volto/issues/6409) + ## 1.0.0 (2024-10-31) ### Internal -- Release 1.0.0 @sneridagh +- Release 1.0.0 @sneridagh ## 1.0.0-alpha.22 (2024-10-30) diff --git a/packages/types/package.json b/packages/types/package.json index d19561a391..6c2370a064 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -9,7 +9,7 @@ ], "funding": "https://github.com/sponsors/plone", "license": "MIT", - "version": "1.0.0", + "version": "1.2.0", "repository": { "type": "git", "url": "https://github.com/plone/volto.git" diff --git a/packages/types/src/config/Blocks.d.ts b/packages/types/src/config/Blocks.d.ts index 70bf61c5cf..ae5f50fc83 100644 --- a/packages/types/src/config/Blocks.d.ts +++ b/packages/types/src/config/Blocks.d.ts @@ -51,6 +51,10 @@ export interface BlockConfigBase { * The group of the block */ group: string; + /** + * The category of the block + */ + category: string; /** * The view mode component */ diff --git a/packages/types/src/config/Settings.d.ts b/packages/types/src/config/Settings.d.ts index 68419e2db2..61e87a8955 100644 --- a/packages/types/src/config/Settings.d.ts +++ b/packages/types/src/config/Settings.d.ts @@ -101,4 +101,5 @@ export interface SettingsConfig { includeSiteTitle: boolean; titleAndSiteTitleSeparator: string; }; + cssLayers: string[]; } diff --git a/packages/volto-slate/CHANGELOG.md b/packages/volto-slate/CHANGELOG.md index 1693cb8f47..a76fe74282 100644 --- a/packages/volto-slate/CHANGELOG.md +++ b/packages/volto-slate/CHANGELOG.md @@ -8,6 +8,12 @@ +## 18.0.4 (2024-12-12) + +### Bugfix + +- Stylelint in less file. @sneridagh [#6409](https://github.com/plone/volto/issues/6409) + ## 18.0.3 (2024-12-09) ### Internal diff --git a/packages/volto-slate/package.json b/packages/volto-slate/package.json index c0e41e043d..b98b7b27bc 100644 --- a/packages/volto-slate/package.json +++ b/packages/volto-slate/package.json @@ -1,6 +1,6 @@ { "name": "@plone/volto-slate", - "version": "18.0.3", + "version": "18.0.4", "description": "Slate.js integration with Volto", "main": "src/index.js", "author": "European Environment Agency: IDM2 A-Team", diff --git a/packages/volto-slate/src/editor/less/editor.less b/packages/volto-slate/src/editor/less/editor.less index e6006e3c19..9fb0538eef 100644 --- a/packages/volto-slate/src/editor/less/editor.less +++ b/packages/volto-slate/src/editor/less/editor.less @@ -27,9 +27,9 @@ } .link-form-container { - margin-left: 2px; display: flex; align-items: center; + margin-left: 2px; } } @@ -44,6 +44,7 @@ .slate-toolbar { display: flex; + min-width: 300px; // needed for image widget slate toolbar box-sizing: border-box; padding: 3px; border: none; @@ -53,7 +54,6 @@ font-family: 'Poppins', 'Helvetica Neue', Arial, Helvetica, sans-serif; font-size: 1rem; font-weight: normal; - min-width: 300px; // needed for image widget slate toolbar .expando { flex-grow: 1; diff --git a/packages/volto/.release-it.json b/packages/volto/.release-it.json index ecce30528b..0395373591 100644 --- a/packages/volto/.release-it.json +++ b/packages/volto/.release-it.json @@ -3,7 +3,7 @@ "../scripts/prepublish.js": {} }, "hooks": { - "before:bump": ["pnpm i18n"], + "before:bump": ["pnpm i18n", "pnpm build:types", "git add types"], "after:bump": [ "pipx run towncrier build --draft --yes --version ${version} > .changelog.draft", "pipx run towncrier build --yes --version ${version}", diff --git a/packages/volto/CHANGELOG.md b/packages/volto/CHANGELOG.md index e5524fc087..03e6e00c0c 100644 --- a/packages/volto/CHANGELOG.md +++ b/packages/volto/CHANGELOG.md @@ -17,6 +17,33 @@ myst: +## 18.4.0 (2024-12-17) + +### Feature + +- Added a setting in the `config` object to set the site's CSS layers, if required. @sneridagh [#6539](https://github.com/plone/volto/issues/6539) + +### Internal + +- Fixed and re-enabled the types declaration extractor from core Volto. @sneridagh [#6534](https://github.com/plone/volto/issues/6534) + +### Documentation + +- Add monorepo structure to the README. Update the monorepo structure file tree. @stevepiercy [#6542](https://github.com/plone/volto/issues/6542) + +## 18.3.0 (2024-12-12) + +### Feature + +- Add disable Teaser block Align handlers for teasers inside containers. @sneridagh [#6527](https://github.com/plone/volto/issues/6527) + +### Bugfix + +- Fix inline comment in `SlotRenderer`. @sneridagh [#6409](https://github.com/plone/volto/issues/6409) +- Enhanced linkintegrity popup and moved all logic in a separate component ContentsDeleteModal @giuliaghisini [#6516](https://github.com/plone/volto/issues/6516) +- Disable initial scroll to top after SSR completion. @Faakhir30 [#6523](https://github.com/plone/volto/issues/6523) +- Add missing styleWrapper style builder information in container/Grid. @sneridagh [#6527](https://github.com/plone/volto/issues/6527) + ## 18.2.3 (2024-12-09) ### Bugfix diff --git a/packages/volto/README.md b/packages/volto/README.md index 63877d3e46..9327b2f737 100644 --- a/packages/volto/README.md +++ b/packages/volto/README.md @@ -36,6 +36,30 @@ You can build your own or choose from the community released ones: You can try a Volto online demo at [https://demo.plone.org/](https://demo.plone.org/). +## Monorepo structure + +Since version 18.0.0-alpha4, the Volto core repository has had the shape of a monorepo, where "mono" means "single" and "repo" is short for "repository". +This means that several apps and libraries related to each other are stored in the same repository. +They are managed together but released individually. +This allows the code to be shared effectively, and unifies tracking of changes across all of the apps and libraries. + +| Package | Location | +|---|---| +| [`@plone/client`](https://www.npmjs.com/package/@plone/client) | [`packages/client`](https://github.com/plone/volto/tree/main/packages/client#readme) | +| [`@plone/components`](https://www.npmjs.com/package/@plone/components) | [`packages/components`](https://github.com/plone/volto/tree/main/packages/components#readme) | +| [`@plone/generator-volto`](https://www.npmjs.com/package/@plone/generator-volto) | [`packages/generator-volto`](https://github.com/plone/volto/tree/main/packages/generator-volto#readme) | +| [`@plone/helpers`](https://www.npmjs.com/package/@plone/helpers) | [`packages/helpers`](https://github.com/plone/volto/tree/main/packages/helpers#readme) | +| [`@plone/providers`](https://www.npmjs.com/package/@plone/providers) | [`packages/providers`](https://github.com/plone/volto/tree/main/packages/providers#readme) | +| [`@plone/registry`](https://www.npmjs.com/package/@plone/registry) | [`packages/registry`](https://github.com/plone/volto/tree/main/packages/registry#readme) | +| [`@plone/scripts`](https://www.npmjs.com/package/@plone/scripts) | [`packages/scripts`](https://github.com/plone/volto/tree/main/packages/scripts#readme) | +| [`@plone/types`](https://www.npmjs.com/package/@plone/types) | [`packages/types`](https://github.com/plone/volto/tree/main/packages/types#readme) | +| none | [`packages/volto-guillotina`](https://github.com/plone/volto/tree/main/packages/volto-guillotina) | +| [`@plone/volto-slate`](https://www.npmjs.com/package/@plone/volto-slate) | [`packages/volto-slate`](https://github.com/plone/volto/tree/main/packages/volto-slate#readme) | +| [`@plone/volto-testing`](https://www.npmjs.com/package/@plone/volto-testing) | [`packages/volto-testing`](https://github.com/plone/volto/tree/main/packages/volto-testing) | + +See also [Monorepo structure](https://6.docs.plone.org/volto/contributing/developing-core.html#monorepo-structure). + + ## Create a Volto project To start a new project using Volto, follow the [Plone installation documentation](https://6.docs.plone.org/install/create-project.html). diff --git a/packages/volto/locales/ca/LC_MESSAGES/volto.po b/packages/volto/locales/ca/LC_MESSAGES/volto.po index 19cca9d4c5..3e7b0dfe67 100644 --- a/packages/volto/locales/ca/LC_MESSAGES/volto.po +++ b/packages/volto/locales/ca/LC_MESSAGES/volto.po @@ -559,6 +559,7 @@ msgstr "No es pot editar el disseny per al tipus de contingut {type}{type} kann nicht verändert werden, da das #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1058,12 +1059,12 @@ msgid "Delete row" msgstr "Zeile löschen" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "" @@ -1073,7 +1074,7 @@ msgid "Deleted" msgstr "Gelöscht" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "" @@ -2358,6 +2359,11 @@ msgstr "Schmal" msgid "Navigate back" msgstr "Zurück navigieren" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3245,6 +3251,11 @@ msgstr "Anzuzeigende Spalten wählen" msgid "Select relation" msgstr "Wählen Sie eine Relation" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3442,12 +3453,12 @@ msgid "Small" msgstr "Klein" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "" #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "" @@ -3815,6 +3826,11 @@ msgstr "Es gibt Fehler" msgid "There were some errors." msgstr "Es sind Fehler aufgetreten." +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3836,7 +3852,7 @@ msgid "This is a working copy of {title}" msgstr "Das ist eine Arbeitskopie von {title}" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "" @@ -4245,7 +4261,7 @@ msgid "View changes" msgstr "Änderungen anzeigen" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "" @@ -4674,12 +4690,12 @@ msgid "intranet" msgstr "Intranet" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "" @@ -4698,6 +4714,21 @@ msgstr "Mein Nutzername lautet" msgid "leadimage" msgstr "Lead-Bild" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4823,15 +4854,20 @@ msgid "rebuild relations" msgstr "Relationen neu indizieren" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/en/LC_MESSAGES/volto.po b/packages/volto/locales/en/LC_MESSAGES/volto.po index 8d95529fc2..9ad7a604aa 100644 --- a/packages/volto/locales/en/LC_MESSAGES/volto.po +++ b/packages/volto/locales/en/LC_MESSAGES/volto.po @@ -553,6 +553,7 @@ msgstr "" #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1053,12 +1054,12 @@ msgid "Delete row" msgstr "" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "" @@ -1068,7 +1069,7 @@ msgid "Deleted" msgstr "" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "" @@ -2353,6 +2354,11 @@ msgstr "" msgid "Navigate back" msgstr "" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3240,6 +3246,11 @@ msgstr "" msgid "Select relation" msgstr "" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3437,12 +3448,12 @@ msgid "Small" msgstr "" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "" #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "" @@ -3810,6 +3821,11 @@ msgstr "" msgid "There were some errors." msgstr "" +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3831,7 +3847,7 @@ msgid "This is a working copy of {title}" msgstr "" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "" @@ -4240,7 +4256,7 @@ msgid "View changes" msgstr "" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "" @@ -4669,12 +4685,12 @@ msgid "intranet" msgstr "" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "" @@ -4693,6 +4709,21 @@ msgstr "" msgid "leadimage" msgstr "" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4818,15 +4849,20 @@ msgid "rebuild relations" msgstr "" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/es/LC_MESSAGES/volto.po b/packages/volto/locales/es/LC_MESSAGES/volto.po index 76243e7616..ff5b8c2299 100644 --- a/packages/volto/locales/es/LC_MESSAGES/volto.po +++ b/packages/volto/locales/es/LC_MESSAGES/volto.po @@ -560,6 +560,7 @@ msgstr "No se puede editar la plantilla de {type} porque el sop #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1060,12 +1061,12 @@ msgid "Delete row" msgstr "Eliminar fila" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "¿Eliminar elementos seleccionados?" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "¿Eliminar este elemento?" @@ -1075,7 +1076,7 @@ msgid "Deleted" msgstr "Eliminado" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "" @@ -2360,6 +2361,11 @@ msgstr "Filtrar" msgid "Navigate back" msgstr "Navegar hacia atrás" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3247,6 +3253,11 @@ msgstr "Seleccionar columnas a mostrar" msgid "Select relation" msgstr "Seleccionar relación" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3444,12 +3455,12 @@ msgid "Small" msgstr "Pequeño" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "" #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "Algunos elementos están referenciados por otros contenidos. Al eliminarlos, {brokenReferences} {variation} se romperá." @@ -3817,6 +3828,11 @@ msgstr "Ha habido algunos errores" msgid "There were some errors." msgstr "Hay algunos errores." +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3838,7 +3854,7 @@ msgid "This is a working copy of {title}" msgstr "Es una copia de trabajo de {title}" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "" @@ -4247,7 +4263,7 @@ msgid "View changes" msgstr "Mostrar los cambios" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "" @@ -4676,12 +4692,12 @@ msgid "intranet" msgstr "Intranet" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "elemento" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "elementos" @@ -4700,6 +4716,21 @@ msgstr "Mi nombre de usuario es" msgid "leadimage" msgstr "Imagen Principal" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4825,15 +4856,20 @@ msgid "rebuild relations" msgstr "reconstruir relaciones" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "referencia" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "referencias" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/eu/LC_MESSAGES/volto.po b/packages/volto/locales/eu/LC_MESSAGES/volto.po index 8022537f14..aa260e34fa 100644 --- a/packages/volto/locales/eu/LC_MESSAGES/volto.po +++ b/packages/volto/locales/eu/LC_MESSAGES/volto.po @@ -560,6 +560,7 @@ msgstr "Ezin da {type} elementu-motaren itxura aldatu, #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1060,12 +1061,12 @@ msgid "Delete row" msgstr "Ezabatu errenkada" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "" @@ -1075,7 +1076,7 @@ msgid "Deleted" msgstr "Ezabatuta" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "" @@ -2360,6 +2361,11 @@ msgstr "Estutu" msgid "Navigate back" msgstr "Atzera joan" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3247,6 +3253,11 @@ msgstr "Aukeratu erakutsiko diren zutabeak" msgid "Select relation" msgstr "" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3444,12 +3455,12 @@ msgid "Small" msgstr "Txikia" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "" #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "" @@ -3817,6 +3828,11 @@ msgstr "Errorea gertatu da" msgid "There were some errors." msgstr "Errorea gertatu da" +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3838,7 +3854,7 @@ msgid "This is a working copy of {title}" msgstr "Hau {title} elementuaren lan-bertsioa da" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "" @@ -4247,7 +4263,7 @@ msgid "View changes" msgstr "Aldaketak ikusi" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "" @@ -4676,12 +4692,12 @@ msgid "intranet" msgstr "Intraneta" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "" @@ -4700,6 +4716,21 @@ msgstr "Nire erabiltzaile izena da" msgid "leadimage" msgstr "Irudi nagusiaren eremua" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4825,15 +4856,20 @@ msgid "rebuild relations" msgstr "" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/fi/LC_MESSAGES/volto.po b/packages/volto/locales/fi/LC_MESSAGES/volto.po index 256144fecf..99c1f6ff04 100644 --- a/packages/volto/locales/fi/LC_MESSAGES/volto.po +++ b/packages/volto/locales/fi/LC_MESSAGES/volto.po @@ -558,6 +558,7 @@ msgstr "Sisältötyypin {type} asettelua ei voi muokata, koska #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1058,12 +1059,12 @@ msgid "Delete row" msgstr "Poista valittu rivi" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "" @@ -1073,7 +1074,7 @@ msgid "Deleted" msgstr "Poistettu" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "" @@ -2358,6 +2359,11 @@ msgstr "Kavenna" msgid "Navigate back" msgstr "Takaisin" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3245,6 +3251,11 @@ msgstr "Näytettävät sarakkeet" msgid "Select relation" msgstr "" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3442,12 +3453,12 @@ msgid "Small" msgstr "Pieni" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "" #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "" @@ -3815,6 +3826,11 @@ msgstr "Lomakkeesta löytyi virheitä" msgid "There were some errors." msgstr "Löytyi joitakin puutteita tai virheitä." +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3836,7 +3852,7 @@ msgid "This is a working copy of {title}" msgstr "" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "" @@ -4245,7 +4261,7 @@ msgid "View changes" msgstr "Näytä muutokset" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "" @@ -4674,12 +4690,12 @@ msgid "intranet" msgstr "inranet" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "" @@ -4698,6 +4714,21 @@ msgstr "Käyttäjätunnukseni" msgid "leadimage" msgstr "nostokuva" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4823,15 +4854,20 @@ msgid "rebuild relations" msgstr "" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/fr/LC_MESSAGES/volto.po b/packages/volto/locales/fr/LC_MESSAGES/volto.po index e21a46a903..120eda4ebe 100644 --- a/packages/volto/locales/fr/LC_MESSAGES/volto.po +++ b/packages/volto/locales/fr/LC_MESSAGES/volto.po @@ -560,6 +560,7 @@ msgstr "Impossible de modifier la mise en page pour le type de contenu { #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1060,12 +1061,12 @@ msgid "Delete row" msgstr "Supprimer la ligne" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "" @@ -1075,7 +1076,7 @@ msgid "Deleted" msgstr "Supprimé" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "" @@ -2360,6 +2361,11 @@ msgstr "Étroit" msgid "Navigate back" msgstr "Retour en arrière" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3247,6 +3253,11 @@ msgstr "Sélectionnez les colonnes à afficher" msgid "Select relation" msgstr "" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3444,12 +3455,12 @@ msgid "Small" msgstr "Petit" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "" #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "" @@ -3817,6 +3828,11 @@ msgstr "Il y a eu quelques erreurs" msgid "There were some errors." msgstr "Il y a eu quelques erreurs." +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3838,7 +3854,7 @@ msgid "This is a working copy of {title}" msgstr "Il sagit d'une copie de travail de {title}" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "" @@ -4247,7 +4263,7 @@ msgid "View changes" msgstr "Voir les changements" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "" @@ -4676,12 +4692,12 @@ msgid "intranet" msgstr "Intranet" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "" @@ -4700,6 +4716,21 @@ msgstr "Mon nom d'utilisateur est" msgid "leadimage" msgstr "image de garde" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4825,15 +4856,20 @@ msgid "rebuild relations" msgstr "" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/hi/LC_MESSAGES/volto.po b/packages/volto/locales/hi/LC_MESSAGES/volto.po index 2d6df284df..0219651642 100644 --- a/packages/volto/locales/hi/LC_MESSAGES/volto.po +++ b/packages/volto/locales/hi/LC_MESSAGES/volto.po @@ -553,6 +553,7 @@ msgstr "" #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1053,12 +1054,12 @@ msgid "Delete row" msgstr "पंक्ति हटाएँ" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "चयनित आइटम हटाएं?" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "क्या आप इस आइटम को हटाना चाहते हैं?" @@ -1068,7 +1069,7 @@ msgid "Deleted" msgstr "हटा दिया गया" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "इस आइटम को हटाने से {brokenReferences} {variation} टूट जाता है।" @@ -2353,6 +2354,11 @@ msgstr "संकीर्ण" msgid "Navigate back" msgstr "पिछले पृष्ठ पर जाएं" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3240,6 +3246,11 @@ msgstr "प्रदर्शित करने के लिए स्तं msgid "Select relation" msgstr "रिश्ता चुनें" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3437,12 +3448,12 @@ msgid "Small" msgstr "छोटा" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "कुछ आइटम एक फ़ोल्डर भी हो सकते हैं। उन्हें हटा कर आप {containedItemsToDelete} {variation} फ़ोल्डर के अंदर में हटा देंगे।" #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "कुछ आइटम अन्य सामग्रियों द्वारा संदर्भित होते हैं। उन्हें हटा कर आप {brokenReferences} {variation} टूट जाएगा।" @@ -3810,6 +3821,11 @@ msgstr "कुछ त्रुटियाँ थीं" msgid "There were some errors." msgstr "कुछ त्रुटियाँ थीं।" +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3831,7 +3847,7 @@ msgid "This is a working copy of {title}" msgstr "यह {title} की काम की प्रतिलिपि है" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "यह आइटम एक फ़ोल्डर भी है। इसे हटाकर आप {containedItemsToDelete} {variation} फ़ोल्डर के अंदर हटा देंगे।" @@ -4240,7 +4256,7 @@ msgid "View changes" msgstr "परिवर्तन देखें" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "इस आइटम के लिए लिंक और संदर्भ देखें" @@ -4669,12 +4685,12 @@ msgid "intranet" msgstr "इंट्रानेट" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "आइटम" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "आइटम्स" @@ -4693,6 +4709,21 @@ msgstr "मेरा उपयोगकर्ता नाम है" msgid "leadimage" msgstr "प्रमुख छवि फ़ील्ड" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4818,15 +4849,20 @@ msgid "rebuild relations" msgstr "रिश्तों को पुनः निर्माण करें" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "संदर्भ" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "संदर्भ" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/it/LC_MESSAGES/volto.po b/packages/volto/locales/it/LC_MESSAGES/volto.po index 2e55284578..6cccb3d46b 100644 --- a/packages/volto/locales/it/LC_MESSAGES/volto.po +++ b/packages/volto/locales/it/LC_MESSAGES/volto.po @@ -90,7 +90,7 @@ msgstr "Aggiungi Add-ons" #. Default: "Add Alternative URL" #: components/manage/Controlpanels/Aliases msgid "Add Alternative URL" -msgstr "" +msgstr "Aggiungi un URL alternativo" #. Default: "Add Content…" #: components/manage/Toolbar/Types @@ -311,12 +311,12 @@ msgstr "L'alias è stato aggiunto" #. Default: "Aliases have been removed." #: components/manage/Controlpanels/Aliases msgid "Aliases have been removed." -msgstr "" +msgstr "Gli Alias sono stati rimossi." #. Default: "Aliases have been uploaded." #: components/manage/Controlpanels/Aliases msgid "Aliases have been uploaded." -msgstr "" +msgstr "Gli Alias sono stati caricati." #. Default: "Alignment" #: components/manage/Blocks/Image/schema @@ -429,7 +429,7 @@ msgstr "Assegnazione" #. Default: "Automatically" #: components/manage/Controlpanels/Aliases msgid "Automatically" -msgstr "" +msgstr "Automaticamente" #. Default: "Available" #: components/manage/Controlpanels/AddonsControlpanel @@ -493,7 +493,7 @@ msgstr "Blocco" #. Default: "Both" #: components/manage/Controlpanels/Aliases msgid "Both" -msgstr "" +msgstr "Entrambi" #. Default: "Both email address and password are case sensitive, check that caps lock is not enabled." #: components/theme/Login/Login @@ -524,7 +524,7 @@ msgstr "Sfoglia i contenuti, rilascia un'immagine o digita un URL" #. Default: "Bulk upload CSV" #: components/manage/Controlpanels/Aliases msgid "BulkUploadAltUrls" -msgstr "" +msgstr "Caricamento massivo CSV" #. Default: "By default, permissions from the container of this item are inherited. If you disable this, only the explicitly defined sharing permissions will be valid. In the overview, the symbol {inherited} indicates an inherited value. Similarly, the symbol {global} indicates a global role, which is managed by the site administrator." #: components/manage/Sharing/Sharing @@ -553,6 +553,7 @@ msgstr "Non è possibile modificare il Layout per il tipo {type}, &, #, /, ?, or others that are illegal in URLs. Cannot start with: _, aq_, @@, ++. Cannot end with __. Cannot be: request,contributors, ., .., "". Cannot contain new lines." #: components/manage/Widgets/IdWidget msgid "Only 7-bit bytes characters are allowed. Cannot contain uppercase letters, special characters: <, >, &, #, /, ?, or others that are illegal in URLs. Cannot start with: _, aq_, @@, ++. Cannot end with __. Cannot be: request,contributors, ., .., "". Cannot contain new lines." -msgstr "" +msgstr "Sono ammessi solo 7-bit bytes di caratteri. Non può contenere lettere maiuscole, caratteris speciali come: <, >, &, #, /, ?, o altri che non sono ammessi negli URLs. Non può iniziare con: _, aq_, @@, ++. Non può finire con: __. Non può essere: request,contributors, ., .., "" Non può contenere nuove righe." #. Default: "Open in a new tab" #: components/manage/Blocks/Image/schema @@ -3240,6 +3246,11 @@ msgstr "Seleziona le colonne da mostrare" msgid "Select relation" msgstr "Seleziona relazione" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "Seleziona una regola" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3437,14 +3448,14 @@ msgid "Small" msgstr "Piccolo" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "Alcuni elementi sono anche una cartella. Eliminandoli eliminerai {containedItemsToDelete} {variation} dentro le cartelle." #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -msgstr "" +msgstr "Alcuni elementi sono referenziati da altri contenuti. Eliminandoli, {brokenReferences} {variation} si romperanno." #. Default: "Some relations are broken. Please fix." #: components/manage/Controlpanels/Relations/Relations @@ -3810,6 +3821,11 @@ msgstr "Si sono verificati degli errori" msgid "There were some errors." msgstr "Si sono verificati degli errori." +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "Questi elementi avranno dei collegamenti rotti" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3831,9 +3847,9 @@ msgid "This is a working copy of {title}" msgstr "Questa è una copia di lavoro di {title}" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -msgstr "" +msgstr "Questo elemento è anche una cartella. Eliminandola eliminerai anche i {containedItemsToDelete} {variation} contenuti in questa cartella." #. Default: "This item was locked by {creator} on {date}" #: components/manage/LockingToastsFactory/LockingToastsFactory @@ -4205,7 +4221,7 @@ msgstr "Utenti e gruppi" #. Default: "Using this form, you can manage alternative urls for an item. This is an easy way to make an item available under two different URLs." #: components/manage/Aliases/Aliases msgid "Using this form, you can manage alternative urls for an item. This is an easy way to make an item available under two different URLs." -msgstr "Utilizzando questo modulo, è possibile gestire url alternativi per gli elementi per rendere un elemento disponibile sotto due diversi indirizzi in modo facile." +msgstr "Utilizzando questo modulo, è possibile creare URL alternativi per i contenuti in modo da renderli disponibili con due diversi indirizzi URL. Digitando su browser l'URL alternativo creato per un contenuto verrà fatto un redirect all'URL originale del contenuto stesso." #. Default: "Variation" #: helpers/Extensions/withBlockSchemaEnhancer @@ -4240,7 +4256,7 @@ msgid "View changes" msgstr "Mostra le modifiche" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "Visualizza i collegamenti e i riferimenti a questo elemento" @@ -4480,7 +4496,7 @@ msgstr "Viste disponibili" #. Default: "Error in the block field {errorField}." #: helpers/MessageLabels/MessageLabels msgid "blocksFieldsErrorTitle" -msgstr "" +msgstr "Errore nel campo {errorField} del blocco." #. Default: "Forgot your password?" #: components/theme/Login/Login @@ -4491,7 +4507,7 @@ msgstr "Hai dimenticato la tua password?" #. Default: "Add many alternative URLs at once by uploading a CSV file. The first column should be the path to redirect from; the second, the path to redirect to. Both paths must be Plone-site-relative, starting with a slash (/). An optional third column can contain a date and time. An optional fourth column can contain a boolean to mark as a manual redirect (default true)." #: components/manage/Controlpanels/Aliases msgid "bulkUploadUrlsHelp" -msgstr "" +msgstr "Aggiungi molte URLs alternative contemporaneamente caricando un file CSV. La prima colonna deve contenere il percorso da cui reindirizzare (sorgente); la seconda colonna, il path a cui reindirizzare (destinazione). Entrambi i percorsi devono essere url relativi, e quindi devono iniziare con lo slash (/). Una terza colonna opzionale può contenere data e ora. Una quarta colonna opzionale può contenere un valore booleano (true/false) per poter contrassegnare come reindirizzamento manuale (predefinito: true)" #. Default: "Checkbox" #: config/Blocks @@ -4521,7 +4537,7 @@ msgstr "Confronta con" #. Default: "{countofrelation} broken {countofrelation, plural, one {relation} other {relations}} of type {typeofrelation}" #: components/manage/Controlpanels/Relations/BrokenRelations msgid "countBrokenRelations" -msgstr "" +msgstr "{countofrelation} {countofrelation, plural, one {relazione rotta} other {relazioni rotte}} di tipo {typeofrelation}" #. Default: "Date Range" #: config/Blocks @@ -4669,12 +4685,12 @@ msgid "intranet" msgstr "Pubblicato internamente" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "elemento" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "elementi" @@ -4693,6 +4709,21 @@ msgstr "Il mio nome utente è" msgid "leadimage" msgstr "Immagine di testata" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "Elimina" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "Elimina questo elemento e rompi i collegamenti" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "Sto verificando i riferimenti a questo contenuto..." + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4818,15 +4849,20 @@ msgid "rebuild relations" msgstr "ricrea le relazioni" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "riferimento" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "riferimenti" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "fa riferimento a" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/ja/LC_MESSAGES/volto.po b/packages/volto/locales/ja/LC_MESSAGES/volto.po index c419f24891..e4c74c3188 100644 --- a/packages/volto/locales/ja/LC_MESSAGES/volto.po +++ b/packages/volto/locales/ja/LC_MESSAGES/volto.po @@ -558,6 +558,7 @@ msgstr "ふるまいのブロックが有効で、かつ{type}-contenttype o #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1057,12 +1058,12 @@ msgid "Delete row" msgstr "Rij verwijderen" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "Geselecteerde items verwijderen?" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "Dit item verwijderen?" @@ -1072,7 +1073,7 @@ msgid "Deleted" msgstr "Verwijderd" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "Dit item verwijderen breekt {brokenReferences} {variation}." @@ -2357,6 +2358,11 @@ msgstr "Smal" msgid "Navigate back" msgstr "Navigeer terug" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3244,6 +3250,11 @@ msgstr "Selecteer de te tonen kolommen" msgid "Select relation" msgstr "Selecteer relatie" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3441,12 +3452,12 @@ msgid "Small" msgstr "Klein" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "Bepaalde items zijn ook een map. Door het verwijderen ervan, verwijder je tevens {containedItemsToDelete} {variation} in de mappen." #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "Bepaalde items worden gerefereerd door andere inhoud. Door het verwijderen ervan, worden {brokenReferences} {variation} gebroken." @@ -3814,6 +3825,11 @@ msgstr "Er zijn fouten opgetreden" msgid "There were some errors." msgstr "Er zijn fouten opgetreden." +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3835,7 +3851,7 @@ msgid "This is a working copy of {title}" msgstr "Dit is een werkkopij van {title}" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "Dit item is ook een map. Door deze te verwijderen, verwijder je eveneens {containedItemsToDelete} {variation} in de map." @@ -4244,7 +4260,7 @@ msgid "View changes" msgstr "Bekijk wijzigingen" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "Bekijk koppelingen en referenties naar dit item" @@ -4673,12 +4689,12 @@ msgid "intranet" msgstr "Intranet" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "item" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "items" @@ -4697,6 +4713,21 @@ msgstr "Mijn gebruikersnaam is" msgid "leadimage" msgstr "Veld leidende afbeelding" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4822,15 +4853,20 @@ msgid "rebuild relations" msgstr "hetbouw relaties" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "referentie" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "referenties" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/pt/LC_MESSAGES/volto.po b/packages/volto/locales/pt/LC_MESSAGES/volto.po index bc08dfa8be..8f4040495a 100644 --- a/packages/volto/locales/pt/LC_MESSAGES/volto.po +++ b/packages/volto/locales/pt/LC_MESSAGES/volto.po @@ -558,6 +558,7 @@ msgstr "" #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1058,12 +1059,12 @@ msgid "Delete row" msgstr "Eliminar linha" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "" @@ -1073,7 +1074,7 @@ msgid "Deleted" msgstr "" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "" @@ -2358,6 +2359,11 @@ msgstr "" msgid "Navigate back" msgstr "" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3245,6 +3251,11 @@ msgstr "Seleccione colunas a apresentar" msgid "Select relation" msgstr "" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3442,12 +3453,12 @@ msgid "Small" msgstr "" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "" #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "" @@ -3815,6 +3826,11 @@ msgstr "" msgid "There were some errors." msgstr "Ocorreram alguns erros." +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3836,7 +3852,7 @@ msgid "This is a working copy of {title}" msgstr "" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "" @@ -4245,7 +4261,7 @@ msgid "View changes" msgstr "Ver modificações" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "" @@ -4674,12 +4690,12 @@ msgid "intranet" msgstr "" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "" @@ -4698,6 +4714,21 @@ msgstr "Meu nome de usuário é" msgid "leadimage" msgstr "" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4823,15 +4854,20 @@ msgid "rebuild relations" msgstr "" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/pt_BR/LC_MESSAGES/volto.po b/packages/volto/locales/pt_BR/LC_MESSAGES/volto.po index 7355fa4ef4..76a25c310c 100644 --- a/packages/volto/locales/pt_BR/LC_MESSAGES/volto.po +++ b/packages/volto/locales/pt_BR/LC_MESSAGES/volto.po @@ -559,6 +559,7 @@ msgstr "Não é possível editar layout para o tipo de conteúdo {type}< #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1059,12 +1060,12 @@ msgid "Delete row" msgstr "Excluir linha" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "Excluir os itens selecionados?" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "Apagar este item?" @@ -1074,7 +1075,7 @@ msgid "Deleted" msgstr "Removida" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "A exclusão desse item quebra {brokenReferences} {variation}." @@ -2359,6 +2360,11 @@ msgstr "Estreito" msgid "Navigate back" msgstr "Voltar" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3246,6 +3252,11 @@ msgstr "Selecione colunas para mostrar" msgid "Select relation" msgstr "Selecione um relacionamento" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3443,12 +3454,12 @@ msgid "Small" msgstr "Pequeno" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "Alguns itens também são uma pasta. Ao excluí-los, você excluirá {containedItemsToDelete} {variation} dentro destas pastas." #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "Alguns itens são referenciados por outros conteúdos. Ao excluí-los, {brokenReferences} {variation} podem ser quebrados." @@ -3816,6 +3827,11 @@ msgstr "Houve alguns erros" msgid "There were some errors." msgstr "Houve alguns erros." +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3837,7 +3853,7 @@ msgid "This is a working copy of {title}" msgstr "Esta é uma cópia de trabalho de {title}" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "Esse item também é uma pasta. Ao excluí-lo, você excluirá {containedItemsToDelete} {variation} dentro da pasta." @@ -4246,7 +4262,7 @@ msgid "View changes" msgstr "Ver mudanças" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "Exibir links e referências a este item" @@ -4675,12 +4691,12 @@ msgid "intranet" msgstr "Intranet" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "Item" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "Itens" @@ -4699,6 +4715,21 @@ msgstr "Meu nome de usuário é " msgid "leadimage" msgstr "Imagem principal" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4824,15 +4855,20 @@ msgid "rebuild relations" msgstr "reconstruir relacionamentos" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "referência" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "referências" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/ro/LC_MESSAGES/volto.po b/packages/volto/locales/ro/LC_MESSAGES/volto.po index 6f9ce222b6..9199570724 100644 --- a/packages/volto/locales/ro/LC_MESSAGES/volto.po +++ b/packages/volto/locales/ro/LC_MESSAGES/volto.po @@ -559,6 +559,7 @@ msgstr "Nu se poate edita aspectul pentru tipul de conținut {type}\n" "Language-Team: Plone i18n \n" "Content-Type: text/plain; charset=utf-8\n" @@ -555,6 +555,7 @@ msgstr "" #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1055,12 +1056,12 @@ msgid "Delete row" msgstr "" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "" @@ -1070,7 +1071,7 @@ msgid "Deleted" msgstr "" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "" @@ -2355,6 +2356,11 @@ msgstr "" msgid "Navigate back" msgstr "" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3242,6 +3248,11 @@ msgstr "" msgid "Select relation" msgstr "" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3439,12 +3450,12 @@ msgid "Small" msgstr "" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "" #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "" @@ -3812,6 +3823,11 @@ msgstr "" msgid "There were some errors." msgstr "" +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3833,7 +3849,7 @@ msgid "This is a working copy of {title}" msgstr "" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "" @@ -4242,7 +4258,7 @@ msgid "View changes" msgstr "" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "" @@ -4671,12 +4687,12 @@ msgid "intranet" msgstr "" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "" @@ -4695,6 +4711,21 @@ msgstr "" msgid "leadimage" msgstr "" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4820,15 +4851,20 @@ msgid "rebuild relations" msgstr "" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/locales/zh_CN/LC_MESSAGES/volto.po b/packages/volto/locales/zh_CN/LC_MESSAGES/volto.po index 2a7fce693f..8b3aa94303 100644 --- a/packages/volto/locales/zh_CN/LC_MESSAGES/volto.po +++ b/packages/volto/locales/zh_CN/LC_MESSAGES/volto.po @@ -559,6 +559,7 @@ msgstr "" #. Default: "Cancel" #: components/manage/Add/Add +#: components/manage/Contents/ContentsDeleteModal #: components/manage/Contents/ContentsUploadModal #: components/manage/Controlpanels/ContentType #: components/manage/Controlpanels/ContentTypeLayout @@ -1059,12 +1060,12 @@ msgid "Delete row" msgstr "删除条件" #. Default: "Delete selected items?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete selected items?" msgstr "" #. Default: "Delete this item?" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Delete this item?" msgstr "" @@ -1074,7 +1075,7 @@ msgid "Deleted" msgstr "已删除" #. Default: "Deleting this item breaks {brokenReferences} {variation}." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Deleting this item breaks {brokenReferences} {variation}." msgstr "" @@ -2359,6 +2360,11 @@ msgstr "" msgid "Navigate back" msgstr "导航返回" +#. Default: "Navigate to this item" +#: components/manage/Contents/ContentsDeleteModal +msgid "Navigate to this item" +msgstr "" + #. Default: "Navigation" #: components/theme/Navigation/ContextNavigation msgid "Navigation" @@ -3246,6 +3252,11 @@ msgstr "选择要显示的列" msgid "Select relation" msgstr "" +#. Default: "Select rule" +#: components/manage/Rules/Rules +msgid "Select rule" +msgstr "" + #. Default: "Select the transition to be used for modifying the items state." #: components/manage/Contents/ContentsWorkflowModal msgid "Select the transition to be used for modifying the items state." @@ -3443,12 +3454,12 @@ msgid "Small" msgstr "小" #. Default: "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are also a folder. By deleting them you will delete {containedItemsToDelete} {variation} inside the folders." msgstr "" #. Default: "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "Some items are referenced by other contents. By deleting them {brokenReferences} {variation} will be broken." msgstr "" @@ -3816,6 +3827,11 @@ msgstr "这里出现了一些错误" msgid "There were some errors." msgstr "这里出现了一些错误。" +#. Default: "These items will have broken links" +#: components/manage/Contents/ContentsDeleteModal +msgid "These items will have broken links" +msgstr "" + #. Default: "Third" #: components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField msgid "Third" @@ -3837,7 +3853,7 @@ msgid "This is a working copy of {title}" msgstr "这是{title}的一个工作副本" #. Default: "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "This item is also a folder. By deleting it you will delete {containedItemsToDelete} {variation} inside the folder." msgstr "" @@ -4246,7 +4262,7 @@ msgid "View changes" msgstr "" #. Default: "View links and references to this item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "View links and references to this item" msgstr "" @@ -4675,12 +4691,12 @@ msgid "intranet" msgstr "内部" #. Default: "item" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "item" msgstr "" #. Default: "items" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "items" msgstr "" @@ -4699,6 +4715,21 @@ msgstr "我的用户名是" msgid "leadimage" msgstr "" +#. Default: "Delete" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete" +msgstr "" + +#. Default: "Delete item and break links" +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: Delete item and break links" +msgstr "" + +#. Default: "Checking references..." +#: components/manage/Contents/ContentsDeleteModal +msgid "link-integrity: loading references" +msgstr "" + #. Default: "Enter a URL to an image" #: components/manage/Widgets/ImageWidget msgid "linkAnImage" @@ -4824,15 +4855,20 @@ msgid "rebuild relations" msgstr "" #. Default: "reference" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "reference" msgstr "" #. Default: "references" -#: components/manage/Contents/Contents +#: components/manage/Contents/ContentsDeleteModal msgid "references" msgstr "" +#. Default: "refers to" +#: components/manage/Contents/ContentsDeleteModal +msgid "refers to" +msgstr "" + #. Default: "results" #: components/theme/Search/Search msgid "results found" diff --git a/packages/volto/package.json b/packages/volto/package.json index afe541524b..2d90155dfc 100644 --- a/packages/volto/package.json +++ b/packages/volto/package.json @@ -9,7 +9,7 @@ } ], "license": "MIT", - "version": "18.2.3", + "version": "18.4.0", "repository": { "type": "git", "url": "git@github.com:plone/volto.git" diff --git a/packages/volto/src/components/manage/Blocks/Container/EditBlockWrapper.jsx b/packages/volto/src/components/manage/Blocks/Container/EditBlockWrapper.jsx index 20d22753a6..60a2c5c952 100644 --- a/packages/volto/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +++ b/packages/volto/src/components/manage/Blocks/Container/EditBlockWrapper.jsx @@ -4,7 +4,7 @@ import { defineMessages, useIntl } from 'react-intl'; import NewBlockAddButton from './NewBlockAddButton'; import cx from 'classnames'; import { isInteractiveElement } from '@plone/volto/helpers/Utils/Utils'; - +import { buildStyleObjectFromData } from '@plone/volto/helpers/Blocks/Blocks'; import clearSVG from '@plone/volto/icons/clear.svg'; const messages = defineMessages({ @@ -38,12 +38,15 @@ const EditBlockWrapper = (props) => { onChangeBlock(block, { '@type': 'empty' }); } + const style = buildStyleObjectFromData(data); + return (
0 - ) { - const linkintegrityInfo = await this.props.linkIntegrityCheck( - map(this.state.itemsToDelete, (item) => this.getFieldById(item, 'UID')), - ); - const containedItems = linkintegrityInfo - .map((result) => result.items_total ?? 0) - .reduce((acc, value) => acc + value, 0); - const breaches = linkintegrityInfo.flatMap((result) => - result.breaches.map((source) => ({ - source: source, - target: result, - })), - ); - const source_by_uid = breaches.reduce( - (acc, value) => acc.set(value.source.uid, value.source), - new Map(), - ); - const by_source = breaches.reduce((acc, value) => { - if (acc.get(value.source.uid) === undefined) { - acc.set(value.source.uid, new Set()); - } - acc.get(value.source.uid).add(value.target); - return acc; - }, new Map()); - - this.setState({ - containedItemsToDelete: containedItems, - brokenReferences: by_source.size, - linksAndReferencesViewLink: linkintegrityInfo.length - ? linkintegrityInfo[0]['@id'] + '/links-to-item' - : null, - breaches: Array.from(by_source, (entry) => ({ - source: source_by_uid.get(entry[0]), - targets: Array.from(entry[1]), - })), - showAllItemsToDelete: - this.state.itemsToDelete.length < this.deleteItemsToShowThreshold, - }); - } - } /** * Component will receive props @@ -1209,298 +1149,12 @@ class Contents extends Component { />
- - {this.state.itemsToDelete.length > 1 ? ( - this.state.containedItemsToDelete > 0 ? ( - <> - - {this.state.containedItemsToDelete} - - ), - variation: ( - - {this.state.containedItemsToDelete === - 1 ? ( - - ) : ( - - )} - - ), - }} - /> - {this.state.brokenReferences > 0 && ( - <> -
- - {this.state.brokenReferences} - - ), - variation: ( - - {this.state.brokenReferences === 1 ? ( - - ) : ( - - )} - - ), - }} - /> - - )} - - ) : ( - <> - {this.state.brokenReferences > 0 && ( - <> - - {this.state.brokenReferences} - - ), - variation: ( - - {this.state.brokenReferences === 1 ? ( - - ) : ( - - )} - - ), - }} - /> - - )} - - ) - ) : this.state.containedItemsToDelete > 0 ? ( - <> - - {this.state.containedItemsToDelete} - - ), - variation: ( - - {this.state.containedItemsToDelete === 1 ? ( - - ) : ( - - )} - - ), - }} - /> - {this.state.brokenReferences > 0 && ( - <> -
- {this.state.brokenReferences} - ), - variation: ( - - {this.state.brokenReferences === 1 ? ( - - ) : ( - - )} - - ), - }} - /> -
- -
    - {this.state.breaches.map((breach) => ( -
  • - - {breach.source.title} - {' '} - refers to{' '} - {breach.targets - .map((target) => ( - - {target.title} - - )) - .reduce((result, item) => ( - <> - {result}, {item} - - ))} -
  • - ))} -
- {this.state.linksAndReferencesViewLink && ( - - - - )} -
- - )} - - ) : this.state.brokenReferences > 0 ? ( - <> - {this.state.brokenReferences} - ), - variation: ( - - {this.state.brokenReferences === 1 ? ( - - ) : ( - - )} - - ), - }} - /> -
- -
    - {this.state.breaches.map((breach) => ( -
  • - - {breach.source.title} - {' '} - refers to{' '} - {breach.targets - .map((target) => ( - - {target.title} - - )) - .reduce((result, item) => ( - <> - {result}, {item} - - ))} -
  • - ))} -
- {this.state.linksAndReferencesViewLink && ( - - - - )} -
- - ) : null} -
- } onCancel={this.onDeleteCancel} - onConfirm={this.onDeleteOk} - size="medium" + onOk={this.onDeleteOk} + items={this.state.items} + itemsToDelete={this.state.itemsToDelete} /> { + const { itemsToDelete = [], open, onCancel, onOk, items } = props; + const intl = useIntl(); + const dispatch = useDispatch(); + const linkintegrityInfo = useSelector((state) => state.linkIntegrity?.result); + const loading = useSelector((state) => state.linkIntegrity?.loading); + + const [brokenReferences, setBrokenReferences] = useState(0); + const [containedItemsToDelete, setContainedItemsToDelete] = useState([]); + const [breaches, setBreaches] = useState([]); + + const [linksAndReferencesViewLink, setLinkAndReferencesViewLink] = + useState(null); + + useEffect(() => { + const getFieldById = (id, field) => { + const item = find(items, { '@id': id }); + return item ? item[field] : ''; + }; + + if (itemsToDelete.length > 0 && open) { + dispatch( + linkIntegrityCheck( + map(itemsToDelete, (item) => getFieldById(item, 'UID')), + ), + ); + } + }, [itemsToDelete, items, open, dispatch]); + + useEffect(() => { + if (linkintegrityInfo) { + const containedItems = linkintegrityInfo + .map((result) => result.items_total ?? 0) + .reduce((acc, value) => acc + value, 0); + const breaches = linkintegrityInfo.flatMap((result) => + result.breaches.map((source) => ({ + source: source, + target: result, + })), + ); + const source_by_uid = breaches.reduce( + (acc, value) => acc.set(value.source.uid, value.source), + new Map(), + ); + const by_source = breaches.reduce((acc, value) => { + if (acc.get(value.source.uid) === undefined) { + acc.set(value.source.uid, new Set()); + } + acc.get(value.source.uid).add(value.target); + return acc; + }, new Map()); + + setContainedItemsToDelete(containedItems); + setBrokenReferences(by_source.size); + setLinkAndReferencesViewLink( + linkintegrityInfo.length + ? linkintegrityInfo[0]['@id'] + '/links-to-item' + : null, + ); + setBreaches( + Array.from(by_source, (entry) => ({ + source: source_by_uid.get(entry[0]), + targets: Array.from(entry[1]), + })), + ); + } else { + setContainedItemsToDelete([]); + setBrokenReferences(0); + setLinkAndReferencesViewLink(null); + setBreaches([]); + } + }, [linkintegrityInfo]); + + return ( + open && ( + + + + {intl.formatMessage(messages.loading)} + + + + {itemsToDelete.length > 1 ? ( + containedItemsToDelete > 0 ? ( + <> + {containedItemsToDelete} + ), + variation: ( + + {containedItemsToDelete === 1 ? ( + + ) : ( + + )} + + ), + }} + /> + {brokenReferences > 0 && ( + <> +
+ {brokenReferences}, + variation: ( + + {brokenReferences === 1 ? ( + + ) : ( + + )} + + ), + }} + /> + + )} + + ) : ( + <> + {brokenReferences > 0 && ( + <> + {brokenReferences}, + variation: ( + + {brokenReferences === 1 ? ( + + ) : ( + + )} + + ), + }} + /> + + )} + + ) + ) : containedItemsToDelete > 0 ? ( + <> + {containedItemsToDelete} + ), + variation: ( + + {containedItemsToDelete === 1 ? ( + + ) : ( + + )} + + ), + }} + /> + {brokenReferences > 0 && ( + <> +
+ {brokenReferences}, + variation: ( + + {brokenReferences === 1 ? ( + + ) : ( + + )} + + ), + }} + /> + + + )} + + ) : brokenReferences > 0 ? ( + <> + {brokenReferences}, + variation: ( + + {brokenReferences === 1 ? ( + + ) : ( + + )} + + ), + }} + /> + + + ) : null} +
+ } + onCancel={onCancel} + onConfirm={onOk} + size="medium" + /> + ) + ); +}; + +const BrokenLinksList = ({ intl, breaches, linksAndReferencesViewLink }) => { + return ( +
+ + : + + + {breaches.map((breach) => ( + + + + {breach.source.title} + + + + : + + +
    + {breach.targets.map((target) => ( +
  • + + {target.title} + +
  • + ))} +
+
+
+ ))} +
+
+ {linksAndReferencesViewLink && ( + + + + )} +
+ ); +}; +ContentsDeleteModal.propTypes = { + itemsToDelete: PropTypes.arrayOf( + PropTypes.shape({ + UID: PropTypes.string, + }), + ).isRequired, + open: PropTypes.bool.isRequired, + onOk: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, +}; +export default ContentsDeleteModal; diff --git a/packages/volto/src/components/manage/Rules/Rules.jsx b/packages/volto/src/components/manage/Rules/Rules.jsx index e8b4837aa4..2a07bf0ca6 100644 --- a/packages/volto/src/components/manage/Rules/Rules.jsx +++ b/packages/volto/src/components/manage/Rules/Rules.jsx @@ -76,6 +76,10 @@ const messages = defineMessages({ id: 'Unassigned', defaultMessage: 'Unassigned', }, + select_rule: { + id: 'Select rule', + defaultMessage: 'Select rule', + }, }); /** @@ -366,7 +370,9 @@ class Rules extends Component { />