Docs modifications (#5804)

- Fixes #5504
- Fixes #5503
- Return 404 when the page does not exist
- Modified the footer in order to align it properly
- Removed "noticed something to change" in each table of content
- Fixed the URLs of the edit module 
- Added the edit module to Developers
- Fixed header style on the REST API page.
- Edited the README to point to Developers
- Fixed selected state when clicking on sidebar elements

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
Ady Beraud
2024-06-11 10:45:17 +03:00
committed by GitHub
parent 3c5a4ba692
commit ff1bca1816
261 changed files with 459 additions and 12184 deletions

View File

@ -0,0 +1,13 @@
import dynamic from 'next/dynamic';
type ClientOnlyProps = { children: any };
const ClientOnly = (props: ClientOnlyProps) => {
const { children } = props;
return children;
};
export default dynamic(() => Promise.resolve(ClientOnly), {
ssr: false,
});

View File

@ -1,6 +1,7 @@
'use client';
import React from 'react';
import React, { useState } from 'react';
import styled from '@emotion/styled';
import Image from 'next/image';
import { usePathname } from 'next/navigation';
import { ArticleContent } from '@/app/_components/ui/layout/articles/ArticleContent';
@ -15,7 +16,6 @@ const StyledContainer = styled('div')`
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
borderBottom: `1px solid ${Theme.background.transparent.medium}`,
fontFamily: `${Theme.font.family}`,
})};
width: 100%;
@ -37,8 +37,9 @@ const StyledWrapper = styled.div`
width: 440px;
}
@media (min-width: 801px) {
@media (min-width: 801px) and (max-width: 1500px) {
max-width: 720px;
min-width: calc(100% - 184px);
margin: ${Theme.spacing(10)} 92px ${Theme.spacing(20)};
}
@ -96,28 +97,30 @@ const StyledRectangle = styled.div`
background: ${Theme.background.transparent.medium};
`;
const StyledImageContainer = styled.div`
border: 2px solid ${Theme.text.color.primary};
display: flex;
justify-content: center;
align-items: center;
const StyledImageContainer = styled.div<{ loaded: string }>`
position: relative;
width: 100%;
padding-top: 46%;
overflow: hidden;
border-radius: 16px;
max-width: fit-content;
border: 2px solid rgba(20, 20, 20, 0.08);
background: #fafafa;
transition: border-color 150ms ease-in-out;
${({ loaded }) =>
loaded === 'true' &&
`border-color: ${Theme.text.color.primary};
`}
`;
img {
height: 100%;
max-width: 100%;
width: 100%;
@media (min-width: 1000px) {
width: 720px;
}
}
const StyledImage = styled(Image)<{ loaded: string }>`
opacity: ${({ loaded }) => (loaded === 'true' ? 1 : 0)};
transition: opacity 250ms ease-in-out;
`;
export default function DocsContent({ item }: { item: FileContent }) {
const pathname = usePathname();
const { uri, label } = getUriAndLabel(pathname);
const [imageLoaded, setImageLoaded] = useState(false);
const BREADCRUMB_ITEMS = [
{
@ -136,12 +139,16 @@ export default function DocsContent({ item }: { item: FileContent }) {
separator="/"
/>
<StyledHeading>{item.itemInfo.title}</StyledHeading>
<StyledImageContainer>
<StyledImageContainer loaded={imageLoaded.toString()}>
{item.itemInfo.image && (
<img
<StyledImage
id={`img-${item.itemInfo.title}`}
src={item.itemInfo.image}
alt={item.itemInfo.title}
fill
style={{ objectFit: 'cover' }}
onLoad={() => setImageLoaded(true)}
loaded={imageLoaded.toString()}
/>
)}
</StyledImageContainer>

View File

@ -19,7 +19,6 @@ const StyledContainer = styled.div`
flexDirection: 'column',
background: `${Theme.background.secondary}`,
borderRight: `1px solid ${Theme.background.transparent.medium}`,
borderBottom: `1px solid ${Theme.background.transparent.medium}`,
padding: `${Theme.spacing(10)} ${Theme.spacing(4)}`,
gap: `${Theme.spacing(6)}`,
})}

View File

@ -120,7 +120,7 @@ const DocsSidebarSection = ({
? '/user-guide/'
: pathname.includes('developers')
? '/developers/'
: '/twenty-ui';
: '/twenty-ui/';
const initializeUnfoldedState = () => {
const unfoldedState: TopicsState = {};
@ -171,11 +171,11 @@ const DocsSidebarSection = ({
{(unfolded[topic] || !hasMultipleFiles) &&
cards.map((card) => {
const isselected = pathname === `${path}${card.fileName}`;
const sectionName = card.topic
.toLowerCase()
.replace(/\s+/g, '-');
const routerPath = getCardPath(card, path, false, sectionName);
const isselected = pathname === routerPath;
return (
<StyledSubTopicItem
key={card.title}

View File

@ -1,8 +1,10 @@
'use client';
import { useEffect, useState } from 'react';
import styled from '@emotion/styled';
import { motion } from 'framer-motion';
import { usePathname } from 'next/navigation';
import ClientOnly from '@/app/_components/docs/ClientOnly';
import mq from '@/app/_components/ui/theme/mq';
import { Theme } from '@/app/_components/ui/theme/theme';
import { useHeadsObserver } from '@/app/user-guide/hooks/useHeadsObserver';
@ -13,7 +15,6 @@ const StyledContainer = styled.div`
flexDirection: 'column',
background: `${Theme.background.secondary}`,
borderLeft: `1px solid ${Theme.background.transparent.medium}`,
borderBottom: `1px solid ${Theme.background.transparent.medium}`,
padding: `0px ${Theme.spacing(6)}`,
})};
width: 300px;
@ -96,7 +97,8 @@ const DocsTableContents = () => {
useEffect(() => {
const nodes: HTMLElement[] = Array.from(
document.querySelectorAll('h2, h3, h4, h5'),
);
).filter((elem) => (elem as HTMLElement).id !== 'edit') as HTMLElement[];
const elements: HeadingType[] = nodes.map(
(elem): HeadingType => ({
id: elem.id,
@ -106,41 +108,52 @@ const DocsTableContents = () => {
level: Number(elem.nodeName.charAt(1)),
}),
);
setHeadings(elements);
}, [pathname]);
}, []);
return (
<StyledContainer>
<StyledNav>
<StyledHeadingText>Table of Content</StyledHeadingText>
<StyledUnorderedList>
{headings.map((heading) => (
<StyledList
key={heading.text}
style={getStyledHeading(heading.level)}
>
<StyledLink
href={`#${heading.text}`}
onClick={(e) => {
e.preventDefault();
const yOffset = -70;
const y =
heading.elem.getBoundingClientRect().top +
window.scrollY +
yOffset;
window.scrollTo({ top: y, behavior: 'smooth' });
}}
style={{
fontWeight: activeText === heading.text ? 'bold' : 'normal',
}}
>
{heading.text}
</StyledLink>
</StyledList>
))}
</StyledUnorderedList>
<ClientOnly>
{!!headings?.length && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.2 }}
>
<StyledUnorderedList>
{headings.map((heading) => (
<StyledList
key={heading.text}
style={getStyledHeading(heading.level)}
>
<StyledLink
href={`#${heading.text}`}
onClick={(e) => {
e.preventDefault();
const yOffset = -70;
const y =
heading.elem.getBoundingClientRect().top +
window.scrollY +
yOffset;
window.scrollTo({ top: y, behavior: 'smooth' });
}}
style={{
fontWeight:
activeText === heading.text ? 'bold' : 'normal',
}}
>
{heading.text}
</StyledLink>
</StyledList>
))}
</StyledUnorderedList>
</motion.div>
)}
</ClientOnly>
</StyledNav>
</StyledContainer>
);