Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Website: markdown to release #4146

Merged
merged 6 commits into from
Feb 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions packages/twenty-website/src/app/_components/releases/Line.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use client';

import styled from '@emotion/styled';

const StyledLineContainer = styled.div`
width: 810px;
margin: 0 auto;
display: flex;

@media (max-width: 810px) {
width: auto;
margin: 24px 0;
display: block;
}
`;

const StyledLine = styled.div`
height: 1px;
background-color: #d9d9d9;
margin-bottom: 48px;
margin-left: 148px;
margin-top: 48px;
width: 100%;

@media (max-width: 810px) {
margin: 0;
}
`;

export const Line = () => {
return (
<StyledLineContainer>
<StyledLine />
</StyledLineContainer>
);
};
110 changes: 110 additions & 0 deletions packages/twenty-website/src/app/_components/releases/Release.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
'use client';

import styled from '@emotion/styled';
import { Gabarito } from 'next/font/google';
import { compileMDX } from 'next-mdx-remote/rsc';
import remarkBehead from 'remark-behead';
import gfm from 'remark-gfm';

import { ReleaseNote } from '@/app/get-releases';

const StyledContainer = styled.div`
width: 810px;
margin: 0 auto;
display: flex;
font-weight: 400;

@media (max-width: 810px) {
width: auto;
margin: 24px 0;
display: block;
}
`;

const StyledVersion = styled.div`
text-align: center;
width: 148px;
font-size: 24px;
display: flex;
flex-flow: column;
align-items: start;
font-weight: 500;

@media (max-width: 810px) {
width: 100%;
font-size: 20px;
flex-flow: row;
justify-content: space-between;
}
`;

const StyledRelease = styled.span`
color: #b3b3b3;
`;

const StyledDate = styled.span`
color: #474747;
font-size: 16px;
`;

const StlyedContent = styled.div`
flex: 1;

h3 {
color: #141414;
font-size: 40px;
margin: 0;
}

p {
color: #474747;
font-size: 16px;
line-height: 28.8px;
color: #818181;
font-weight: 400;
}

img {
max-width: 100%;
}
`;

const gabarito = Gabarito({
weight: ['400', '500'],
subsets: ['latin'],
display: 'swap',
adjustFontFallback: false,
});

export const Release = async ({ release }: { release: ReleaseNote }) => {
let mdxSource;
try {
mdxSource = await compileMDX({
source: release.content,
options: {
mdxOptions: {
remarkPlugins: [gfm, [remarkBehead, { depth: 2 }]],
},
},
});
mdxSource = mdxSource.content;
} catch (error) {
console.error('An error occurred during MDX rendering:', error);
mdxSource = `<p>Oops! Something went wrong.</p> ${error}`;
}

return (
<StyledContainer className={gabarito.className}>
<StyledVersion>
<StyledRelease>{release.release}</StyledRelease>
<StyledDate>
{release.date.endsWith(new Date().getFullYear().toString())
? release.date.slice(0, -5)
: release.date}
</StyledDate>
</StyledVersion>

<StlyedContent>{mdxSource}</StlyedContent>
</StyledContainer>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use client';

import styled from '@emotion/styled';

const StyledTitle = styled.div`
margin: 64px auto;
text-align: center;
font-size: 1.8em;

@media (max-width: 810px) {
font-size: 1em;
margin: 16px auto;
}
`;
const StyledHeader = styled.h1`
color: #b3b3b3;
margin: 0;
`;
const StyledSubHeader = styled.h1`
margin: 0;
`;

export const Title = () => {
return (
<StyledTitle>
<StyledHeader>Latest</StyledHeader>
<StyledSubHeader>Releases</StyledSubHeader>
</StyledTitle>
);
};
49 changes: 49 additions & 0 deletions packages/twenty-website/src/app/get-releases.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import fs from 'fs';
import matter from 'gray-matter';

export interface ReleaseNote {
slug: string;
date: string;
release: string;
content: string;
}

function compareSemanticVersions(a: string, b: string) {
const a1 = a.split('.');
const b1 = b.split('.');

const len = Math.min(a1.length, b1.length);

for (let i = 0; i < len; i++) {
const a2 = +a1[i] || 0;
const b2 = +b1[i] || 0;

if (a2 !== b2) {
return a2 > b2 ? 1 : -1;
}
}
return b1.length - a1.length;
}

export async function getReleases(): Promise<ReleaseNote[]> {
const files = fs.readdirSync('src/content/releases');
const releasenotes: ReleaseNote[] = [];

for (const fileName of files) {
if (!fileName.endsWith('.md') && !fileName.endsWith('.mdx')) {
continue;
}
const file = fs.readFileSync(`src/content/releases/${fileName}`, 'utf-8');
const { data: frontmatter, content } = matter(file);
releasenotes.push({
slug: fileName.slice(0, -4),
date: frontmatter.Date,
release: frontmatter.release,
content: content,
});
}

releasenotes.sort((a, b) => compareSemanticVersions(b.release, a.release));

return releasenotes;
}
32 changes: 32 additions & 0 deletions packages/twenty-website/src/app/releases/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { Metadata } from 'next';

import { Line } from '@/app/_components/releases/Line';
import { Release } from '@/app/_components/releases/Release';
import { Title } from '@/app/_components/releases/StyledTitle';
import { ContentContainer } from '@/app/_components/ui/layout/ContentContainer';
import { getReleases } from '@/app/get-releases';

export const metadata: Metadata = {
title: 'Twenty - Releases',
description: 'Latest releases of Twenty',
};

const Home = async () => {
const releases = await getReleases();

return (
<ContentContainer>
<Title />

{releases.map((note, index) => (
<React.Fragment key={note.slug}>
<Release release={note} />
{index != releases.length - 1 && <Line />}
</React.Fragment>
))}
</ContentContainer>
);
};

export default Home;
11 changes: 11 additions & 0 deletions packages/twenty-website/src/content/releases/CompactView.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
release: 0.3.2
Date: May 6th 2024
---

# Compact view


Standard objects are in-built objects with a set of attributes available for all users. All workspaces come with three standard objects by default: People, Companies, and Opportunities. Standard objects have standard fields that are also available for all Twenty users, like Account Owner and URL.

![](/images/user-guide/view-all-objects-light.png)
10 changes: 10 additions & 0 deletions packages/twenty-website/src/content/releases/Inbox.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
release: 0.4.3
Date: February 24th 2024
---

# Inbox



An inbox gathering task in a CRM system is an automated process that collects and organizes various types of communications such as notes, emails, and notifications. Notes are often summaries or details related to customer interactions that can be recorded and tracked. This system also archives and prioritizes emails and notifications, making it easier to manage customer relationships and ensure all communication is accounted for and responded to in a timely manner.
Loading