- Modified CSS: font-size, colors, margins... - Added an ArticleContent Component that will be used for the changelog and user guide articles, which contains the styles for each titles, paragraphs, images etc. - Added link to User Guide in footer - Added a UserGuideWarning Component: <img width="332" alt="Screenshot 2024-04-17 at 18 14 48" src="https://github.com/twentyhq/twenty/assets/102751374/0f5c601b-a2c0-4c63-baeb-1990d65fc332"> - Added a UserGuideEditContent Component: <img width="394" alt="Screenshot 2024-04-17 at 18 16 24" src="https://github.com/twentyhq/twenty/assets/102751374/6c7c3bd4-c5bb-4d02-8f93-bd99bc30ce7b"> - Added a UserGuideLink Component (for usage in MDX to allow links to open in new tab) - Fixed table of content - Made responsive --------- Co-authored-by: Ady Beraud <a.beraud96@gmail.com> Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
71 lines
2.2 KiB
TypeScript
71 lines
2.2 KiB
TypeScript
import { JSXElementConstructor, ReactElement } from 'react';
|
|
import fs from 'fs';
|
|
import matter from 'gray-matter';
|
|
import { compileMDX } from 'next-mdx-remote/rsc';
|
|
import gfm from 'remark-gfm';
|
|
|
|
import { ReleaseNote } from '@/app/releases/api/route';
|
|
import { compareSemanticVersions } from '@/shared-utils/compareSemanticVersions';
|
|
|
|
// WARNING: This API is used by twenty-front, not just by twenty-website
|
|
// Make sure you don't change it without updating twenty-front at the same time
|
|
export async function getReleases(baseUrl?: string): 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);
|
|
|
|
let updatedContent;
|
|
if (baseUrl) {
|
|
updatedContent = content.replace(
|
|
/!\[(.*?)\]\((?!http)(.*?)\)/g,
|
|
(match: string, alt: string, src: string) => {
|
|
// Check if src is a relative path (not starting with http:// or https://)
|
|
if (!src.startsWith('/')) {
|
|
src = `${baseUrl}/${src}`;
|
|
} else {
|
|
src = `${baseUrl}${src}`;
|
|
}
|
|
return ``;
|
|
},
|
|
);
|
|
}
|
|
|
|
releasenotes.push({
|
|
slug: fileName.slice(0, -4),
|
|
date: frontmatter.Date,
|
|
release: frontmatter.release,
|
|
content: updatedContent ?? content,
|
|
});
|
|
}
|
|
|
|
releasenotes.sort((a, b) => compareSemanticVersions(b.release, a.release));
|
|
|
|
return releasenotes;
|
|
}
|
|
|
|
export async function getMdxReleasesContent(
|
|
releases: ReleaseNote[],
|
|
): Promise<ReactElement<any, string | JSXElementConstructor<any>>[]> {
|
|
const mdxSourcesPromises = releases.map(async (release) => {
|
|
const mdxSource = await compileMDX<{ title: string; position?: number }>({
|
|
source: release.content,
|
|
options: {
|
|
parseFrontmatter: true,
|
|
mdxOptions: {
|
|
development: process.env.NODE_ENV === 'development',
|
|
remarkPlugins: [gfm],
|
|
},
|
|
},
|
|
});
|
|
return mdxSource.content;
|
|
});
|
|
|
|
return await Promise.all(mdxSourcesPromises);
|
|
}
|