Added Algolia Search (#5524)

-Added Algolia Search Box :

<img width="707" alt="Screenshot 2024-05-22 at 10 05 13"
src="https://github.com/twentyhq/twenty/assets/102751374/d26f9748-2a80-4690-88ca-16b078c52915">

-Added Algolia Search Bar:

<img width="294" alt="Screenshot 2024-05-22 at 10 05 56"
src="https://github.com/twentyhq/twenty/assets/102751374/ad503894-4ae1-41e4-bd4b-6241f7679142">

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
Ady Beraud 2024-05-22 13:06:00 +03:00 committed by GitHub
parent 2e79bcc70b
commit 40bd42efc4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 206 additions and 28 deletions

View File

@ -116,7 +116,7 @@ const config = {
algolia: {
appId: 'J2OX2P2QAO',
apiKey: 'e0a7a59c7862598a0cf87307c8ea97f2',
indexName: 'twenty',
indexName: 'twenty-developer-docs',
// Optional: see doc section below
contextualSearch: true,

View File

@ -1,2 +1,4 @@
GITHUB_TOKEN=your_github_token
DATABASE_PG_URL=postgres://website:website@localhost:5432/website # only if using postgres
NEXT_PUBLIC_ALGOLIA_APP_ID=twenty_appId
NEXT_PUBLIC_ALGOLIA_API_KEY=twenty_apiKey

View File

@ -12,7 +12,7 @@ const StyledContainer = styled.div`
display: flex;
flex-direction: row;
h1 {
h2 {
margin: 0px;
font-size: ${Theme.font.size.lg};
}
@ -75,10 +75,10 @@ export default function ArticleEditContent({
return (
<StyledContainer>
<div>
<h1>Noticed something to modify?</h1>
<h2>Noticed something to change?</h2>
<p>
As an open-source company, we welcome contributions to our GitHub user
guide. Help us keep it up-to-date, accurate, and easy to understand by
As an open-source company, we welcome contributions through Github.
Help us keep it up-to-date, accurate, and easy to understand by
getting involved and sharing your ideas!
</p>
<StyledButtonContainer>

View File

@ -0,0 +1,48 @@
import { DocSearch } from '@docsearch/react';
import { StoredDocSearchHit } from '@docsearch/react/dist/esm/types';
interface AlgoliaHit extends StoredDocSearchHit {
_snippetResult?: {
content: { value: string };
};
}
export const AlgoliaDocSearch = () => {
return (
<DocSearch
hitComponent={({ hit }: { hit: AlgoliaHit }) => (
<section className="DocSearch-Hits">
<a href={hit.url}>
<div className="DocSearch-Hit-Container">
<div className="DocSearch-Hit-icon">
<svg width="20" height="20" viewBox="0 0 20 20">
<path
d="M13 13h4-4V8H7v5h6v4-4H7V8H3h4V3v5h6V3v5h4-4v5zm-6 0v4-4H3h4z"
stroke="currentColor"
fill="none"
fillRule="evenodd"
strokeLinecap="round"
strokeLinejoin="round"
></path>
</svg>
</div>
<div className="DocSearch-Hit-action">
<h2>
{hit.hierarchy.lvl1 ? hit.hierarchy.lvl1 : hit.hierarchy.lvl0}
</h2>
<p
dangerouslySetInnerHTML={{
__html: hit?._snippetResult?.content?.value || '',
}}
></p>
</div>
</div>
</a>
</section>
)}
appId={process.env.NEXT_PUBLIC_ALGOLIA_APP_ID as string}
apiKey={process.env.NEXT_PUBLIC_ALGOLIA_API_KEY as string}
indexName="twenty-user-guide"
/>
);
};

View File

@ -6,9 +6,13 @@ import { useRouter } from 'next/navigation';
import { IconBook } from '@/app/_components/ui/icons';
import mq from '@/app/_components/ui/theme/mq';
import { Theme } from '@/app/_components/ui/theme/theme';
import { AlgoliaDocSearch } from '@/app/_components/user-guide/AlgoliaDocSearch';
import UserGuideSidebarSection from '@/app/_components/user-guide/UserGuideSidebarSection';
import { UserGuideArticlesProps } from '@/content/user-guide/constants/getUserGuideArticles';
import '@docsearch/css';
import '../../user-guide/algolia.css';
const StyledContainer = styled.div`
${mq({
display: ['none', 'flex', 'flex'],
@ -66,6 +70,7 @@ const UserGuideSidebar = ({
return (
<StyledContainer>
<AlgoliaDocSearch />
<StyledHeading>
<StyledIconContainer>
<IconBook size={Theme.icon.size.md} />

View File

@ -0,0 +1,122 @@
.DocSearch-Hit-source{
color: #1c1e21;
}
.DocSearch-Search-Icon {
color: #1c1e21;
}
.DocSearch-Logo {
display: none;
}
.DocSearch-Footer{
flex-direction: row;
box-shadow: none;
border: 1px solid #14141414;
}
.DocSearch-Form {
box-shadow: none;
border: 1px solid #141414;
border-radius: 8px;
}
.DocSearch-Modal {
background-color: white;
}
.DocSearch-Hits {
width: 100%;
margin-bottom: 2px !important;
}
.DocSearch-Hit[aria-selected=true] mark {
color: #1961ED !important;
text-decoration: none;
}
.DocSearch-Hit a {
box-shadow: none;
}
.DocSearch-Hits mark {
background-color: #E8EFFD;
color: #1961ED;
}
.DocSearch-Hit-action {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
margin: 0 8px;
}
.DocSearch-Hit-action h2{
font-size: .9em;
margin: 0 0 4px;
font-weight: 500;
}
.DocSearch-Hit-action p{
font-size: 12px;
margin: 0;
width: 90%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-family: var(--font-inter);
font-weight: 400;
}
.DocSearch-Button {
margin: 0px;
min-height: 36px;
background-color: white;
border-radius: 8px;
border: 1px solid #14141414;
}
.DocSearch-Button:hover {
color: #B3B3B3;
box-shadow: none;
}
.DocSearch-Button-Placeholder{
color: #B3B3B3;
}
.DocSearch-Search-Icon {
height: 12px;
width: 12px;
color: #B3B3B3 !important;
}
.DocSearch-Hit-source {
background: none;
font-weight: 600;
font-size: 12px;
font-family: var(--font-inter);
}
.DocSearch-Button-Placeholder {
font-weight: 500;
font-family: var(--font-gabarito);
}
.DocSearch-Button-Keys {
display: none
}
:root {
--docsearch-primary-color: #1c1e21;
--docsearch-highlight-color: #1414140F;
--docsearch-hit-active-color: var(--docsearch-muted-color);
}
.anchor {
scroll-margin-top: calc(80px);
}

View File

@ -26,7 +26,7 @@ Since your API key gives access to sensitive information, you shouldn't share it
<div style={{padding:'70.59% 0 0 0', position:'relative', margin: '32px 0px 0px' }}>
<iframe
src="https://player.vimeo.com/video/928786722?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',
@ -62,7 +62,7 @@ For instance, a webhook can alert your system in real-time when someone creates
<div style={{padding:'70.59% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/928786708?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -14,7 +14,7 @@ image: /images/user-guide/create-workspace/workspace-cover.png
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927066829?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -41,7 +41,7 @@ Your newly created field is now available within the application's fields. To di
<div style={{padding:'71.15% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927628219?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -26,7 +26,7 @@ To export data from an object:
<div style={{padding:'71.24% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/926226303?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -24,7 +24,7 @@ Sync Twenty with 3000+ apps using <ArticleLink href="https://zapier.com/apps/twe
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927913866?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -16,7 +16,7 @@ Kanban views visually map out process flows, where each column stands for a dist
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927888627?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',
@ -43,7 +43,7 @@ To add a stage, access the Select Field Settings by navigating to Settings > Dat
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927890428?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -32,7 +32,7 @@ You can also change the background color and text color of each block to highlig
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927896302?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -40,7 +40,7 @@ To create a new custom object:
<div style={{padding:'71.24% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/926288174?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',
@ -61,7 +61,7 @@ To create a new custom object:
<div style={{padding:'71.24% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/926293493?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -18,7 +18,7 @@ Enter the record name then press `Enter` to save. To edit a record name, click o
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927071691?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',
@ -45,7 +45,7 @@ Enter the record name then press `Enter` to save. To edit a record name, click o
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927073570?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -17,7 +17,7 @@ Creating tasks in Twenty is seamless. You can either:
<div style={{padding:'70.59% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/928786754?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',
@ -49,7 +49,7 @@ You can also see tasks for a given Record on its `Record page`.
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927908280?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',
@ -86,7 +86,7 @@ This procedure will help keep an updated record of your accomplishments.
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927910083?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -16,7 +16,7 @@ Workspace admins can edit its name and logo in settings.
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927915481?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',
@ -43,7 +43,7 @@ Select **Dark**. The system will automatically save your changes.
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927916570?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -36,7 +36,7 @@ The newly created view opens automatically.
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927639721?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',
@ -59,7 +59,7 @@ When you change the `Sorting` and `Filtering` of an existing view, a `Save as ne
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927643495?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',
@ -88,7 +88,7 @@ You will then be able to modify the view. To delete it, press the `Delete` butto
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927645774?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',
@ -124,7 +124,7 @@ To filter a view:
<div style={{padding:'71.24% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/926282262?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',
@ -148,7 +148,7 @@ Order your fields data in ascending or descending order:
<div style={{padding:'69.01% 0 0 0', position:'relative', margin: '32px 0px 0px'}}>
<iframe
src="https://player.vimeo.com/video/927885588?autoplay=1&loop=1&autopause=0&background=1&amp;app_id=58479"
frameborder="0"
frameBorder="0"
allow="autoplay; fullscreen; picture-in-picture; clipboard-write"
style={{
position:'absolute',

View File

@ -25,6 +25,7 @@ export const wrapHeadingsWithAnchor = (children: ReactNode): ReactNode => {
.toLowerCase();
return cloneElement(child as ReactElement<any>, {
id: id,
className: 'anchor',
children: <a href={`#${id}`}>{child.props.children}</a>,
});
}