Skip to content

Commit

Permalink
Merge branch 'main' into fix-links
Browse files Browse the repository at this point in the history
  • Loading branch information
Shyam-Raghuwanshi authored Jan 16, 2025
2 parents 93f89c7 + 5dc98e1 commit eb88e97
Show file tree
Hide file tree
Showing 14 changed files with 205 additions and 160 deletions.
75 changes: 25 additions & 50 deletions apps/rr7/app/content.tsx
Original file line number Diff line number Diff line change
@@ -1,82 +1,57 @@
import type { LoaderArgs } from './routes/+types.home';
import {
dehydrate,
QueryClient,
HydrationBoundary,
useQuery,
useQueryClient,
} from '@tanstack/react-query';
import { useLoaderData, useLocation } from 'react-router';
import type { MetaFunction } from 'react-router';
import { usePloneClient } from '@plone/providers';
import type { Route } from './+types/content';
import { data, useLoaderData, useLocation } from 'react-router';
import PloneClient from '@plone/client';
import App from '@plone/slots/components/App';
import { flattenToAppURL } from './utils';
import config from '@plone/registry';

export const meta: MetaFunction = () => {
export const meta: Route.MetaFunction = ({ data }) => {
return [
{ title: 'Plone on React Router 7' },
{ name: 'description', content: 'Welcome to Plone!' },
{ title: data?.title },
{ name: 'description', content: data?.description },
];
};

const expand = ['navroot', 'breadcrumbs', 'navigation'];

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function loader({ params, request }: LoaderArgs) {
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,
},
},
});

export async function loader({ params, request }: Route.LoaderArgs) {
const ploneClient = config
.getUtility({
name: 'ploneClient',
type: 'client',
})
.method();

const { getContentQuery } = ploneClient as PloneClient;
const { getContent } = ploneClient as PloneClient;

const path = new URL(request.url).pathname;

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)
/\/@@images\//.test(path) ||
/\/@@download\//.test(path) ||
/^\/assets/.test(path) ||
/\.(css|css\.map)$/.test(path)
)
) {
await queryClient.prefetchQuery(getContentQuery({ path, expand }));
console.log('prefetching', path);
try {
return await getContent({ path, expand });
} catch (error) {
throw data('Content Not Found', { status: 404 });
}
} else {
console.log('path not prefetched', path);
throw data('Content Not Found', { status: 404 });
}

return { dehydratedState: dehydrate(queryClient) };
}

function Page() {
const { getContentQuery } = usePloneClient();
const pathname = useLocation().pathname;
const { data } = useQuery(getContentQuery({ path: pathname, expand }));

if (!data) return 'Loading...';
return <App content={data} location={{ pathname: '/' }} />;
}

export default function Content() {
const { dehydratedState } = useLoaderData<typeof loader>();
const queryClient = useQueryClient();
const data = useLoaderData<typeof loader>();
const pathname = useLocation().pathname;

return (
<HydrationBoundary state={dehydratedState} queryClient={queryClient}>
<Page />
</HydrationBoundary>
);
return <App content={data} location={{ pathname }} />;
}
38 changes: 35 additions & 3 deletions apps/rr7/app/root.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { LinksFunction } from 'react-router';
import type { Route } from './+types/root';
import { useState } from 'react';
import {
Links,
Expand All @@ -10,8 +12,8 @@ import {
useNavigate as useRRNavigate,
useParams,
useLoaderData,
isRouteErrorResponse,
} from 'react-router';
import type { LinksFunction } from 'react-router';

import { QueryClient } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
Expand All @@ -24,8 +26,8 @@ import installSSR from './config.server';

install();

import '@plone/theming/styles/main.css';
import '@plone/slots/main.css';
import themingMain from '@plone/theming/styles/main.css?url';
import slotsMain from '@plone/slots/main.css?url';

function useNavigate() {
const navigate = useRRNavigate();
Expand All @@ -37,6 +39,8 @@ function useHrefLocal(to: string) {
}

export const links: LinksFunction = () => [
{ rel: 'stylesheet', href: themingMain },
{ rel: 'stylesheet', href: slotsMain },
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
{
rel: 'preconnect',
Expand Down Expand Up @@ -85,6 +89,34 @@ export function Layout({ children }: { children: React.ReactNode }) {
);
}

export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
let message = 'Oops!';
let details = 'An unexpected error occurred.';
let stack: string | undefined;
if (isRouteErrorResponse(error)) {
message = error.status === 404 ? '404' : 'Error';
details =
error.status === 404
? 'The requested page could not be found.'
: error.statusText || details;
} else if (import.meta.env.DEV && error && error instanceof Error) {
details = error.message;
stack = error.stack;
}

return (
<main className="pt-16 p-4 container mx-auto">
<h1>{message}</h1>
<p>{details}</p>
{stack && (
<pre className="w-full p-4 overflow-x-auto">
<code>{stack}</code>
</pre>
)}
</main>
);
}

export default function App() {
if (!import.meta.env.SSR) {
config.settings.apiPath = window.env.PLONE_API_PATH;
Expand Down
6 changes: 4 additions & 2 deletions apps/rr7/app/routes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { RouteConfig } from '@react-router/dev/routes';
import { index, route } from '@react-router/dev/routes';

export const routes: RouteConfig = [
const routes: RouteConfig = [
index('content.tsx', { id: 'index' }),
route('ok', 'okroute.tsx', { id: 'ok' }),
route('*', 'content.tsx', { id: 'splat' }),
route('*', 'content.tsx', { id: 'content' }),
];

export default routes;
22 changes: 11 additions & 11 deletions apps/rr7/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,24 @@
"typegen": "react-router typegen"
},
"dependencies": {
"@react-router/node": "7.0.0-pre.4",
"@react-router/serve": "7.0.0-pre.4",
"@tanstack/react-query": "^5.59.0",
"@tanstack/react-query-devtools": "^5.59.0",
"isbot": "^5.1.17",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router": "7.0.0-pre.4"
},
"devDependencies": {
"@plone/blocks": "workspace:*",
"@plone/client": "workspace:*",
"@plone/components": "workspace:*",
"@plone/providers": "workspace:*",
"@plone/registry": "workspace:*",
"@plone/slots": "workspace:*",
"@plone/theming": "workspace:*",
"@react-router/dev": "7.0.0-pre.4",
"@react-router/node": "7.1.1",
"@react-router/serve": "7.1.1",
"@tanstack/react-query": "^5.59.0",
"@tanstack/react-query-devtools": "^5.59.0",
"isbot": "^5.1.17",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router": "7.1.1"
},
"devDependencies": {
"@react-router/dev": "7.1.1",
"@types/react": "^18.3.9",
"@types/react-dom": "^18.3.0",
"typescript": "^5.6.3",
Expand Down
7 changes: 7 additions & 0 deletions apps/rr7/react-router.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Config } from '@react-router/dev/config';

export default {
// Config options...
// Server-side render by default, to enable SPA mode set this to `false`
ssr: true,
} satisfies Config;
11 changes: 2 additions & 9 deletions apps/rr7/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,7 @@ const prodServerName =
: '';

export default defineConfig({
plugins: [
reactRouter({
// Server-side render by default, to enable SPA mode set this to `false`
ssr: true,
}),
tsconfigPaths(),
PloneRegistryVitePlugin(),
],
plugins: [PloneRegistryVitePlugin(), reactRouter(), tsconfigPaths()],
server: {
port: 3000,
proxy: {
Expand All @@ -29,7 +22,7 @@ export default defineConfig({
secure: false,
}),
rewrite: (path) => {
console.log(path);
console.log('rewritten path', path);
return path.replace('/++api++', '');
},
},
Expand Down
6 changes: 6 additions & 0 deletions packages/client/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@

<!-- towncrier release notes start -->

## 1.0.0-alpha.21 (2025-01-15)

### Feature

- Import `getContent` bare fetcher. @sneridagh [#6594](https://github.com/plone/volto/pull/6594)

## 1.0.0-alpha.20 (2024-11-05)

### Internal
Expand Down
2 changes: 1 addition & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
}
],
"license": "MIT",
"version": "1.0.0-alpha.20",
"version": "1.0.0-alpha.21",
"repository": {
"type": "git",
"url": "[email protected]:plone/volto.git"
Expand Down
2 changes: 2 additions & 0 deletions packages/client/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
} from './restapi/login/post';
import type { LoginArgs } from './restapi/login/post';

import { getContent as _getContent } from './restapi/content/get';
import { getContentQuery as _getContentQuery } from './restapi/content/get';
import { createContentMutation as _createContentMutation } from './restapi/content/add';
import { updateContentMutation as _updateContentMutation } from './restapi/content/update';
Expand Down Expand Up @@ -150,6 +151,7 @@ export default class PloneClient {
/*
Content queries
*/
getContent = queryWithConfig(_getContent, this.getConfig);
getContentQuery = queryWithConfig(_getContentQuery, this.getConfig);
createContentMutation = mutationWithConfig(
_createContentMutation,
Expand Down
1 change: 1 addition & 0 deletions packages/slots/components/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const Logo = (props: SlotComponentProps) => {
name: 'translation',
type: 'factory',
}).method;

const navRootPath = content['@components'].navroot?.navroot?.['@id'] || '/';
const site = content['@components'].site;
const siteTitle = site?.['plone.site_title'] || '';
Expand Down
2 changes: 2 additions & 0 deletions packages/volto/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,5 @@ docs/_build/
/.python-version
/.tool-versions
docs/source/news

.registry.loader.js
1 change: 1 addition & 0 deletions packages/volto/news/6585.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fix(useClipboard): Do not have a pending promise in a boolean state @nileshgulia1
10 changes: 7 additions & 3 deletions packages/volto/src/hooks/clipboard/useClipboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ export default function useClipboard(clipboardText = '') {
}
};

const copyAction = useCallback(() => {
const copiedString = copyToClipboard(stringToCopy.current);
setCopied(copiedString);
const copyAction = useCallback(async () => {
try {
await copyToClipboard(stringToCopy.current);
setCopied(true);
} catch (error) {
setCopied(false);
}
}, [stringToCopy]);

useEffect(() => {
Expand Down
Loading

0 comments on commit eb88e97

Please sign in to comment.