* add /p/ segment to share urls

* minore fixes
This commit is contained in:
Philipinho
2025-04-22 20:24:55 +01:00
parent 7cd2c18b12
commit 6cfddead24
7 changed files with 33 additions and 38 deletions

View File

@ -56,7 +56,7 @@ export default function App() {
)} )}
<Route element={<ShareLayout />}> <Route element={<ShareLayout />}>
<Route path={"/share/:shareId/:pageSlug"} element={<SharedPage />} /> <Route path={"/share/:shareId/p/:pageSlug"} element={<SharedPage />} />
<Route path={"/share/p/:pageSlug"} element={<SharedPage />} /> <Route path={"/share/p/:pageSlug"} element={<SharedPage />} />
</Route> </Route>

View File

@ -81,7 +81,7 @@ export default function Breadcrumb() {
const renderAnchor = useCallback( const renderAnchor = useCallback(
(node: SpaceTreeNode) => ( (node: SpaceTreeNode) => (
<Tooltip label={node.name}> <Tooltip label={node.name} key={node.id}>
<Anchor <Anchor
component={Link} component={Link}
to={buildPageUrl(spaceSlug, node.slugId, node.name)} to={buildPageUrl(spaceSlug, node.slugId, node.name)}
@ -141,7 +141,7 @@ export default function Breadcrumb() {
position="bottom" position="bottom"
withArrow withArrow
shadow="xl" shadow="xl"
key="hidden-nodes" key="mobile-hidden-nodes"
> >
<Popover.Target> <Popover.Target>
<Tooltip label="Breadcrumbs"> <Tooltip label="Breadcrumbs">

View File

@ -32,5 +32,5 @@ export const buildSharedPageUrl = (opts: {
return `/share/p/${buildPageSlug(pageSlugId, pageTitle)}`; return `/share/p/${buildPageSlug(pageSlugId, pageTitle)}`;
} }
return `/share/${shareId}/${buildPageSlug(pageSlugId, pageTitle)}`; return `/share/${shareId}/p/${buildPageSlug(pageSlugId, pageTitle)}`;
}; };

View File

@ -11,7 +11,7 @@ import {
Tooltip, Tooltip,
} from "@mantine/core"; } from "@mantine/core";
import { IconExternalLink, IconWorld } from "@tabler/icons-react"; import { IconExternalLink, IconWorld } from "@tabler/icons-react";
import React, { useEffect, useState } from "react"; import React, { useEffect, useMemo, useState } from "react";
import { import {
useCreateShareMutation, useCreateShareMutation,
useDeleteShareMutation, useDeleteShareMutation,
@ -43,7 +43,7 @@ export default function ShareModal({ readOnly }: ShareModalProps) {
// if level is greater than zero, then it is a descendant page from a shared page // if level is greater than zero, then it is a descendant page from a shared page
const isDescendantShared = share && share.level > 0; const isDescendantShared = share && share.level > 0;
const publicLink = `${getAppUrl()}/share/${share?.key}/${pageSlug}`; const publicLink = `${getAppUrl()}/share/${share?.key}/p/${pageSlug}`;
const [isPagePublic, setIsPagePublic] = useState<boolean>(false); const [isPagePublic, setIsPagePublic] = useState<boolean>(false);
useEffect(() => { useEffect(() => {
@ -92,6 +92,27 @@ export default function ShareModal({ readOnly }: ShareModalProps) {
}); });
}; };
const shareLink = useMemo(() => (
<Group my="sm" gap={4} wrap="nowrap">
<TextInput
variant="filled"
value={publicLink}
readOnly
rightSection={<CopyTextButton text={publicLink} />}
style={{ width: "100%" }}
/>
<ActionIcon
component="a"
variant="default"
target="_blank"
href={publicLink}
size="sm"
>
<IconExternalLink size={16} />
</ActionIcon>
</Group>
), [publicLink]);
return ( return (
<Popover width={350} position="bottom" withArrow shadow="md"> <Popover width={350} position="bottom" withArrow shadow="md">
<Popover.Target> <Popover.Target>
@ -110,7 +131,7 @@ export default function ShareModal({ readOnly }: ShareModalProps) {
} }
variant="default" variant="default"
> >
Share {t("Share")}
</Button> </Button>
</Popover.Target> </Popover.Target>
<Popover.Dropdown style={{ userSelect: "none" }}> <Popover.Dropdown style={{ userSelect: "none" }}>
@ -141,14 +162,7 @@ export default function ShareModal({ readOnly }: ShareModalProps) {
</Group> </Group>
</Anchor> </Anchor>
<Group my="sm" grow> {shareLink}
<TextInput
variant="filled"
value={publicLink}
readOnly
rightSection={<CopyTextButton text={publicLink} />}
/>
</Group>
</> </>
) : ( ) : (
<> <>
@ -173,25 +187,7 @@ export default function ShareModal({ readOnly }: ShareModalProps) {
{pageIsShared && ( {pageIsShared && (
<> <>
<Group my="sm" gap={4} wrap="nowrap"> {shareLink}
<TextInput
variant="filled"
value={publicLink}
readOnly
rightSection={<CopyTextButton text={publicLink} />}
style={{ width: "100%" }}
/>
<ActionIcon
component="a"
variant="default"
target="_blank"
href={publicLink}
size="sm"
>
<IconExternalLink size={16} />
</ActionIcon>
</Group>
<Group justify="space-between" wrap="nowrap" gap="xl"> <Group justify="space-between" wrap="nowrap" gap="xl">
<div> <div>
<Text size="sm">{t("Include sub-pages")}</Text> <Text size="sm">{t("Include sub-pages")}</Text>
@ -207,7 +203,6 @@ export default function ShareModal({ readOnly }: ShareModalProps) {
disabled={readOnly} disabled={readOnly}
/> />
</Group> </Group>
<Group justify="space-between" wrap="nowrap" gap="xl" mt="sm"> <Group justify="space-between" wrap="nowrap" gap="xl" mt="sm">
<div> <div>
<Text size="sm">{t("Search engine indexing")}</Text> <Text size="sm">{t("Search engine indexing")}</Text>

View File

@ -21,7 +21,7 @@ export default function SingleSharedPage() {
useEffect(() => { useEffect(() => {
if (shareId && data) { if (shareId && data) {
if (data.share.key !== shareId) { if (data.share.key !== shareId) {
navigate(`/share/${data.share.key}/${pageSlug}`, { replace: true }); navigate(`/share/${data.share.key}/p/${pageSlug}`, { replace: true });
} }
} }
}, [shareId, data]); }, [shareId, data]);

View File

@ -19,7 +19,7 @@ export class ShareSeoController {
/* /*
* add meta tags to publicly shared pages * add meta tags to publicly shared pages
*/ */
@Get([':shareId/:pageSlug', 'p/:pageSlug']) @Get([':shareId/p/:pageSlug', 'p/:pageSlug'])
async getShare( async getShare(
@Res({ passthrough: false }) res: FastifyReply, @Res({ passthrough: false }) res: FastifyReply,
@Req() req: FastifyRequest, @Req() req: FastifyRequest,

View File

@ -32,7 +32,7 @@ async function bootstrap() {
); );
app.setGlobalPrefix('api', { app.setGlobalPrefix('api', {
exclude: ['robots.txt', 'share/:shareId/:pageSlug'], exclude: ['robots.txt', 'share/:shareId/p/:pageSlug'],
}); });
const reflector = app.get(Reflector); const reflector = app.get(Reflector);