refactor: Export pages directly from index file
Signed-off-by: Carlos Esteban Lopez <lcarlosesteb@vmware.com>
This commit is contained in:
@@ -1,268 +0,0 @@
|
||||
import Link from '@docusaurus/Link';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import { BannerSection } from '@site/src/components/banner-section/banner-section';
|
||||
import { BannerSectionGrid } from '@site/src/components/banner-section/banner-section-grid';
|
||||
import Layout from '@theme/Layout';
|
||||
import { clsx } from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
import communityStyles from './community.module.scss';
|
||||
import { ContentBlock } from '../../components/content-block/content-block';
|
||||
|
||||
interface ICollectionItem {
|
||||
title?: string;
|
||||
content: React.ReactNode;
|
||||
label: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
export function Community() {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
|
||||
//#region Collection Data
|
||||
const communityListItems: ICollectionItem[] = [
|
||||
{
|
||||
content: 'Chat and get support on our',
|
||||
label: 'Discord',
|
||||
link: 'https://discord.gg/MUpMjP2',
|
||||
},
|
||||
{
|
||||
content: 'Get into contributing with the',
|
||||
label: 'Good First Issues',
|
||||
link: 'https://github.com/backstage/backstage/contribute',
|
||||
},
|
||||
{
|
||||
content: 'Subscribe to the',
|
||||
label: 'Community newsletter',
|
||||
link: 'https://info.backstage.spotify.com/newsletter_subscribe',
|
||||
},
|
||||
{
|
||||
content: 'Join the',
|
||||
label: 'Twitter community',
|
||||
link: 'https://twitter.com/i/communities/1494019781716062215',
|
||||
},
|
||||
];
|
||||
|
||||
const officialInitiatives: ICollectionItem[] = [
|
||||
{
|
||||
title: 'Community sessions',
|
||||
content:
|
||||
'Maintainers and adopters meet monthly to share updates, demos, and ideas. Yep, all sessions are recorded!',
|
||||
link: '/on-demand',
|
||||
label: 'Join a session',
|
||||
},
|
||||
{
|
||||
title: 'Newsletter',
|
||||
content:
|
||||
"The official monthly Backstage newsletter. Don't miss the latest news from your favorite project!",
|
||||
link: 'https://info.backstage.spotify.com/newsletter_subscribe',
|
||||
label: 'Subscribe',
|
||||
},
|
||||
{
|
||||
title: 'Contributor Spotlight',
|
||||
content:
|
||||
"A recognition for valuable community work. Nominate contributing members for their efforts! We'll put them in the spotlight ❤️",
|
||||
link: '/nominate',
|
||||
label: 'Nominate now',
|
||||
},
|
||||
];
|
||||
|
||||
const communityInitiatives: ICollectionItem[] = [
|
||||
{
|
||||
title: 'Open Mic Meetup',
|
||||
content: (
|
||||
<>
|
||||
A casual get together of Backstage users sharing their experiences and
|
||||
helping each other. Hosted by{' '}
|
||||
<Link to="https://roadie.io/">Roadie.io</Link> and{' '}
|
||||
<Link to="https://frontside.com/">Frontside Software</Link>.
|
||||
</>
|
||||
),
|
||||
link: 'https://backstage-openmic.com/',
|
||||
label: 'Learn more',
|
||||
},
|
||||
{
|
||||
title: 'Backstage Weekly Newsletter',
|
||||
content: (
|
||||
<>
|
||||
A weekly newsletter with news, updates and things community from your
|
||||
friends at <Link to="https://roadie.io/">Roadie.io</Link>.
|
||||
</>
|
||||
),
|
||||
link: 'https://roadie.io/backstage-weekly/',
|
||||
label: 'Learn more',
|
||||
},
|
||||
];
|
||||
|
||||
const trainingNCertifications: ICollectionItem[] = [
|
||||
{
|
||||
title: 'Open Mic Meetup',
|
||||
content:
|
||||
'This is a course produced and curated by the Linux Foundation. This course introduces you to Backstage and how to get started with the project.',
|
||||
link: 'https://training.linuxfoundation.org/training/introduction-to-backstage-developer-portals-made-easy-lfs142x/',
|
||||
label: 'Learn more',
|
||||
},
|
||||
];
|
||||
|
||||
const partners: { name: string; url: string; logo: string }[] = [
|
||||
{
|
||||
name: 'Frontside Software',
|
||||
url: 'https://frontside.com/backstage/',
|
||||
logo: 'img/partner-logo-frontside.png',
|
||||
},
|
||||
{
|
||||
name: 'Roadie',
|
||||
url: 'https://roadie.io/',
|
||||
logo: 'img/partner-logo-roadie.png',
|
||||
},
|
||||
{
|
||||
name: 'ThoughtWorks',
|
||||
url: 'https://www.thoughtworks.com',
|
||||
logo: 'img/partner-logo-thoughtworks.png',
|
||||
},
|
||||
{
|
||||
name: 'VMWare',
|
||||
url: 'https://www.vmware.com',
|
||||
logo: 'img/partner-logo-vmware.png',
|
||||
},
|
||||
];
|
||||
//#endregion
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className={clsx(communityStyles.communityPage)}>
|
||||
<BannerSection greyBackground>
|
||||
<BannerSectionGrid>
|
||||
<ContentBlock
|
||||
className="padding-right--xl"
|
||||
title={<h1>Backstage Community</h1>}
|
||||
>
|
||||
Join the vibrant community around Backstage through social media
|
||||
and different meetups. To ensure that you have a welcoming
|
||||
environment, we follow the
|
||||
<Link to="https://github.com/cncf/foundation/blob/master/code-of-conduct.md">
|
||||
{' '}
|
||||
CNCF Code of Conduct{' '}
|
||||
</Link>
|
||||
in everything we do.
|
||||
</ContentBlock>
|
||||
|
||||
<ContentBlock
|
||||
className={clsx(
|
||||
'padding-left--xl',
|
||||
communityStyles.listContainer,
|
||||
)}
|
||||
title="Get started in our community!"
|
||||
>
|
||||
<ul>
|
||||
{communityListItems.map(
|
||||
({ content: text, link, label }, index) => (
|
||||
<li key={index}>
|
||||
<p className="margin-bottom--none">
|
||||
{text} <Link to={link}>{label}</Link>
|
||||
</p>
|
||||
</li>
|
||||
),
|
||||
)}
|
||||
</ul>
|
||||
</ContentBlock>
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
|
||||
<BannerSection greenBottomGradientBackground>
|
||||
<BannerSectionGrid
|
||||
header={
|
||||
<>
|
||||
<h2 className="text--primary">Offical Backstage initiatives</h2>
|
||||
|
||||
<h1>Stay tuned to the latest developments</h1>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{officialInitiatives.map(
|
||||
({ title, content, link, label }, index) => (
|
||||
<ContentBlock
|
||||
key={index}
|
||||
title={title}
|
||||
hasBulletLine
|
||||
actionButtons={[
|
||||
{
|
||||
link,
|
||||
label,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{content}
|
||||
</ContentBlock>
|
||||
),
|
||||
)}
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
|
||||
<BannerSection greyBackground>
|
||||
<BannerSectionGrid
|
||||
header={<h2 className="text--primary">Community initiatives</h2>}
|
||||
>
|
||||
{communityInitiatives.map(
|
||||
({ title, content, link, label }, index) => (
|
||||
<ContentBlock
|
||||
key={index}
|
||||
title={title}
|
||||
hasBulletLine
|
||||
actionButtons={[
|
||||
{
|
||||
link,
|
||||
label,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<p>{content}</p>
|
||||
</ContentBlock>
|
||||
),
|
||||
)}
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
|
||||
<BannerSection>
|
||||
<BannerSectionGrid
|
||||
header={
|
||||
<h2 className="text--primary">Trainings and Certifications</h2>
|
||||
}
|
||||
>
|
||||
{trainingNCertifications.map(
|
||||
({ title, content, link, label }, index) => (
|
||||
<ContentBlock
|
||||
key={index}
|
||||
title={title}
|
||||
hasBulletLine
|
||||
actionButtons={[
|
||||
{
|
||||
link,
|
||||
label,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<p>{content}</p>
|
||||
</ContentBlock>
|
||||
),
|
||||
)}
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
|
||||
<BannerSection greyBackground>
|
||||
<BannerSectionGrid
|
||||
header={<h2 className="text--primary">Commercial Partners</h2>}
|
||||
>
|
||||
{partners.map(({ name, url, logo }, index) => (
|
||||
<div key={index}>
|
||||
<Link to={url}>
|
||||
<img src={`${siteConfig.baseUrl}${logo}`} alt={name} />
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,270 @@
|
||||
import { Community } from './_community';
|
||||
import Link from '@docusaurus/Link';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import { BannerSection } from '@site/src/components/banner-section/banner-section';
|
||||
import { BannerSectionGrid } from '@site/src/components/banner-section/banner-section-grid';
|
||||
import Layout from '@theme/Layout';
|
||||
import { clsx } from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
import { ContentBlock } from '../../components/content-block/content-block';
|
||||
import communityStyles from './community.module.scss';
|
||||
|
||||
interface ICollectionItem {
|
||||
title?: string;
|
||||
content: React.ReactNode;
|
||||
label: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
const Community = () => {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
|
||||
//#region Collection Data
|
||||
const communityListItems: ICollectionItem[] = [
|
||||
{
|
||||
content: 'Chat and get support on our',
|
||||
label: 'Discord',
|
||||
link: 'https://discord.gg/MUpMjP2',
|
||||
},
|
||||
{
|
||||
content: 'Get into contributing with the',
|
||||
label: 'Good First Issues',
|
||||
link: 'https://github.com/backstage/backstage/contribute',
|
||||
},
|
||||
{
|
||||
content: 'Subscribe to the',
|
||||
label: 'Community newsletter',
|
||||
link: 'https://info.backstage.spotify.com/newsletter_subscribe',
|
||||
},
|
||||
{
|
||||
content: 'Join the',
|
||||
label: 'Twitter community',
|
||||
link: 'https://twitter.com/i/communities/1494019781716062215',
|
||||
},
|
||||
];
|
||||
|
||||
const officialInitiatives: ICollectionItem[] = [
|
||||
{
|
||||
title: 'Community sessions',
|
||||
content:
|
||||
'Maintainers and adopters meet monthly to share updates, demos, and ideas. Yep, all sessions are recorded!',
|
||||
link: '/on-demand',
|
||||
label: 'Join a session',
|
||||
},
|
||||
{
|
||||
title: 'Newsletter',
|
||||
content:
|
||||
"The official monthly Backstage newsletter. Don't miss the latest news from your favorite project!",
|
||||
link: 'https://info.backstage.spotify.com/newsletter_subscribe',
|
||||
label: 'Subscribe',
|
||||
},
|
||||
{
|
||||
title: 'Contributor Spotlight',
|
||||
content:
|
||||
"A recognition for valuable community work. Nominate contributing members for their efforts! We'll put them in the spotlight ❤️",
|
||||
link: '/nominate',
|
||||
label: 'Nominate now',
|
||||
},
|
||||
];
|
||||
|
||||
const communityInitiatives: ICollectionItem[] = [
|
||||
{
|
||||
title: 'Open Mic Meetup',
|
||||
content: (
|
||||
<>
|
||||
A casual get together of Backstage users sharing their experiences and
|
||||
helping each other. Hosted by{' '}
|
||||
<Link to="https://roadie.io/">Roadie.io</Link> and{' '}
|
||||
<Link to="https://frontside.com/">Frontside Software</Link>.
|
||||
</>
|
||||
),
|
||||
link: 'https://backstage-openmic.com/',
|
||||
label: 'Learn more',
|
||||
},
|
||||
{
|
||||
title: 'Backstage Weekly Newsletter',
|
||||
content: (
|
||||
<>
|
||||
A weekly newsletter with news, updates and things community from your
|
||||
friends at <Link to="https://roadie.io/">Roadie.io</Link>.
|
||||
</>
|
||||
),
|
||||
link: 'https://roadie.io/backstage-weekly/',
|
||||
label: 'Learn more',
|
||||
},
|
||||
];
|
||||
|
||||
const trainingNCertifications: ICollectionItem[] = [
|
||||
{
|
||||
title: 'Open Mic Meetup',
|
||||
content:
|
||||
'This is a course produced and curated by the Linux Foundation. This course introduces you to Backstage and how to get started with the project.',
|
||||
link: 'https://training.linuxfoundation.org/training/introduction-to-backstage-developer-portals-made-easy-lfs142x/',
|
||||
label: 'Learn more',
|
||||
},
|
||||
];
|
||||
|
||||
const partners: { name: string; url: string; logo: string }[] = [
|
||||
{
|
||||
name: 'Frontside Software',
|
||||
url: 'https://frontside.com/backstage/',
|
||||
logo: 'img/partner-logo-frontside.png',
|
||||
},
|
||||
{
|
||||
name: 'Roadie',
|
||||
url: 'https://roadie.io/',
|
||||
logo: 'img/partner-logo-roadie.png',
|
||||
},
|
||||
{
|
||||
name: 'ThoughtWorks',
|
||||
url: 'https://www.thoughtworks.com',
|
||||
logo: 'img/partner-logo-thoughtworks.png',
|
||||
},
|
||||
{
|
||||
name: 'VMWare',
|
||||
url: 'https://www.vmware.com',
|
||||
logo: 'img/partner-logo-vmware.png',
|
||||
},
|
||||
];
|
||||
//#endregion
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className={clsx(communityStyles.communityPage)}>
|
||||
<BannerSection greyBackground>
|
||||
<BannerSectionGrid>
|
||||
<ContentBlock
|
||||
className="padding-right--xl"
|
||||
title={<h1>Backstage Community</h1>}
|
||||
>
|
||||
Join the vibrant community around Backstage through social media
|
||||
and different meetups. To ensure that you have a welcoming
|
||||
environment, we follow the
|
||||
<Link to="https://github.com/cncf/foundation/blob/master/code-of-conduct.md">
|
||||
{' '}
|
||||
CNCF Code of Conduct{' '}
|
||||
</Link>
|
||||
in everything we do.
|
||||
</ContentBlock>
|
||||
|
||||
<ContentBlock
|
||||
className={clsx(
|
||||
'padding-left--xl',
|
||||
communityStyles.listContainer,
|
||||
)}
|
||||
title="Get started in our community!"
|
||||
>
|
||||
<ul>
|
||||
{communityListItems.map(
|
||||
({ content: text, link, label }, index) => (
|
||||
<li key={index}>
|
||||
<p className="margin-bottom--none">
|
||||
{text} <Link to={link}>{label}</Link>
|
||||
</p>
|
||||
</li>
|
||||
),
|
||||
)}
|
||||
</ul>
|
||||
</ContentBlock>
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
|
||||
<BannerSection greenBottomGradientBackground>
|
||||
<BannerSectionGrid
|
||||
header={
|
||||
<>
|
||||
<h2 className="text--primary">Offical Backstage initiatives</h2>
|
||||
|
||||
<h1>Stay tuned to the latest developments</h1>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{officialInitiatives.map(
|
||||
({ title, content, link, label }, index) => (
|
||||
<ContentBlock
|
||||
key={index}
|
||||
title={title}
|
||||
hasBulletLine
|
||||
actionButtons={[
|
||||
{
|
||||
link,
|
||||
label,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{content}
|
||||
</ContentBlock>
|
||||
),
|
||||
)}
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
|
||||
<BannerSection greyBackground>
|
||||
<BannerSectionGrid
|
||||
header={<h2 className="text--primary">Community initiatives</h2>}
|
||||
>
|
||||
{communityInitiatives.map(
|
||||
({ title, content, link, label }, index) => (
|
||||
<ContentBlock
|
||||
key={index}
|
||||
title={title}
|
||||
hasBulletLine
|
||||
actionButtons={[
|
||||
{
|
||||
link,
|
||||
label,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<p>{content}</p>
|
||||
</ContentBlock>
|
||||
),
|
||||
)}
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
|
||||
<BannerSection>
|
||||
<BannerSectionGrid
|
||||
header={
|
||||
<h2 className="text--primary">Trainings and Certifications</h2>
|
||||
}
|
||||
>
|
||||
{trainingNCertifications.map(
|
||||
({ title, content, link, label }, index) => (
|
||||
<ContentBlock
|
||||
key={index}
|
||||
title={title}
|
||||
hasBulletLine
|
||||
actionButtons={[
|
||||
{
|
||||
link,
|
||||
label,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<p>{content}</p>
|
||||
</ContentBlock>
|
||||
),
|
||||
)}
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
|
||||
<BannerSection greyBackground>
|
||||
<BannerSectionGrid
|
||||
header={<h2 className="text--primary">Commercial Partners</h2>}
|
||||
>
|
||||
{partners.map(({ name, url, logo }, index) => (
|
||||
<div key={index}>
|
||||
<Link to={url}>
|
||||
<img src={`${siteConfig.baseUrl}${logo}`} alt={name} />
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default Community;
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
import Link from '@docusaurus/Link';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import { BannerSection } from '@site/src/components/banner-section/banner-section';
|
||||
import { BannerSectionGrid } from '@site/src/components/banner-section/banner-section-grid';
|
||||
import { ContentBlock } from '@site/src/components/content-block/content-block';
|
||||
import Layout from '@theme/Layout';
|
||||
import { clsx } from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
import demosStyles from './demos.module.scss';
|
||||
|
||||
interface IDemoItem {
|
||||
title: string;
|
||||
content: React.ReactNode;
|
||||
actionItemLink?: string;
|
||||
media: {
|
||||
type: 'image' | 'video';
|
||||
link: string;
|
||||
};
|
||||
}
|
||||
|
||||
export function Demos() {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
|
||||
//#region Collection Data
|
||||
const demoItems: IDemoItem[] = [
|
||||
{
|
||||
title: 'See us in action',
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Watch the videos below to get an introduction to Backstage and to
|
||||
see how we use different plugins to customize{' '}
|
||||
<Link to="https://engineering.atspotify.com/2020/04/21/how-we-use-backstage-at-spotify/">
|
||||
our internal version of Backstage at Spotify
|
||||
</Link>
|
||||
</p>
|
||||
<p>
|
||||
To see how other companies have already started using Backstage,
|
||||
watch these presentations from{' '}
|
||||
<Link to="https://youtu.be/rRphwXeq33Q?t=1508">Expedia</Link>,{' '}
|
||||
<Link to="https://youtu.be/6sg5uMCLxTA?t=153">Zalando</Link>, and{' '}
|
||||
<Link to="https://youtu.be/UZTVjv-AvZA?t=188">TELUS</Link>. For
|
||||
more, join our{' '}
|
||||
<Link to="https://github.com/backstage/community">
|
||||
Community Sessions
|
||||
</Link>
|
||||
</p>
|
||||
<p>
|
||||
To explore the UI and basic features of Backstage firsthand, go to:{' '}
|
||||
<Link to="https://demo.backstage.io">demo.backstage.io</Link>. (Tip:{' '}
|
||||
click “All” to view all the example components in the software
|
||||
catalog.)
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
media: {
|
||||
type: 'image',
|
||||
link: `${siteConfig.baseUrl}img/demo-screen.png`,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Introduction to Backstage',
|
||||
content:
|
||||
'Backstage is an open source platform for building developer portals. We’ve been using our homegrown version at Spotify for years — so it’s already packed with features. (We have over 120 internal plugins, built by 60 different teams.) In this live demo recording, Stefan Ålund, product manager for Backstage, tells the origin story of Backstage and gives you a tour of how we use it here at Spotify.',
|
||||
actionItemLink: 'https://www.youtube.com/watch?v=1XtJ5FAOjPk',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/1XtJ5FAOjPk',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Control cloud costs',
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
How do you control cloud costs while maintaining the speed and
|
||||
independence of your development teams? With the{' '}
|
||||
<Link to="https://backstage.io/plugins">Cost Insights plugin</Link>{' '}
|
||||
for Backstage, managing cloud costs becomes just another part of an
|
||||
engineer’s daily development process. They get a clear view of their
|
||||
spending — and can decide for themselves how they want to optimize
|
||||
it. Learn more about the{' '}
|
||||
<Link to="https://backstage.io/blog/2020/10/22/cost-insights-plugin">
|
||||
Cost Insights plugin
|
||||
</Link>
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
actionItemLink: 'https://youtu.be/YLAd5hdXR_Q',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/YLAd5hdXR_Q',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Make documentation easy',
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Documentation! Everyone needs it, no one wants to create it, and no
|
||||
one can ever find it. Backstage follows a “docs like code” approach:
|
||||
you write documentation in Markdown files right alongside your code.
|
||||
This makes documentation easier to create, maintain, find — and, you
|
||||
know, actually use. This demo video showcases Spotify’s internal
|
||||
version of TechDocs. Learn more about{' '}
|
||||
<Link to="https://backstage.io/blog/2020/09/08/announcing-tech-docs">
|
||||
TechDocs
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
actionItemLink: 'https://youtu.be/mOLCgdPw1iA',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/mOLCgdPw1iA',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Manage your tech health',
|
||||
content:
|
||||
'Instead of manually updating a spreadsheet, what if you had a beautiful dashboard that could give you an instant, interactive picture of your entire org’s tech stack? That’s how we do it at Spotify. With our Tech Insights plugin for Backstage, anyone at Spotify can see which version of which software anyone else at Spotify is using — and a whole a lot more. From managing migrations to fighting tech entropy, Backstage makes managing our tech health actually kind of pleasant.',
|
||||
actionItemLink:
|
||||
'https://www.youtube.com/watch?v=K3xz6VAbgH8&list=PLf1KFlSkDLIBtMGwRDfaVlKMqTMrjD2yO&index=6',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/K3xz6VAbgH8',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Create a microservice',
|
||||
content:
|
||||
'You’re a Spotify engineer about to build a new microservice (or any component) using Spring Boot. Where do you start? Search for a quick start guide online? Create an empty repo on GitHub? Copy and paste an old project? Nope. Just go to Backstage, and you’ll be up and running in two minutes — with a “Hello World” app, CI, and documentation all automatically set up and configured in a standardized way.',
|
||||
actionItemLink: 'https://www.youtube.com/watch?v=U1iwe3L5pzc',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/U1iwe3L5pzc',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Search all your services',
|
||||
content:
|
||||
'All of Spotify’s services are automatically indexed in Backstage. So our engineers can stop playing detective — no more spamming Slack channels asking if anyone knows who owns a particular service and where you can find its API, only to discover that the owner went on sabbatical three months ago and you have to hunt them down on a mountain in Tibet where they’re on a 12-day silent meditation retreat. At Spotify, anyone can always find anyone else’s service, inspect its APIs, and contact its current owner — all with one search.',
|
||||
actionItemLink: 'https://www.youtube.com/watch?v=vcDL9tOv7Eo',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/vcDL9tOv7Eo',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Manage data pipelines',
|
||||
content:
|
||||
'We manage a lot of data pipelines (also known as workflows) here at Spotify. So, of course, we made a great workflows plugin for our version of Backstage. All our workflow tools — including a scheduler, log inspector, data lineage graph, and configurable alerts — are integrated into one simple interface.',
|
||||
actionItemLink: 'https://www.youtube.com/watch?v=rH46MLNZIPM',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/rH46MLNZIPM',
|
||||
},
|
||||
},
|
||||
];
|
||||
//#endregion
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className={clsx(demosStyles.communityPage)}>
|
||||
{demoItems.map((demoItem, index) => (
|
||||
<BannerSection
|
||||
key={index}
|
||||
greyBackground={index % 2 === 0}
|
||||
className={demosStyles.banner}
|
||||
>
|
||||
<BannerSectionGrid>
|
||||
<ContentBlock
|
||||
title={<h1>{demoItem.title}</h1>}
|
||||
actionButtons={[
|
||||
{
|
||||
link: demoItem.actionItemLink,
|
||||
label: 'WATCH NOW',
|
||||
},
|
||||
]}
|
||||
>
|
||||
{demoItem.content}
|
||||
</ContentBlock>
|
||||
|
||||
<div className={clsx()}>
|
||||
{demoItem.media.type === 'image' ? (
|
||||
<img src={demoItem.media.link} alt={demoItem.title} />
|
||||
) : (
|
||||
<iframe
|
||||
src={demoItem.media.link}
|
||||
title={demoItem.title}
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
)}
|
||||
</div>
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
))}
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,206 @@
|
||||
import { Demos } from './_demos';
|
||||
import Link from '@docusaurus/Link';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import { BannerSection } from '@site/src/components/banner-section/banner-section';
|
||||
import { BannerSectionGrid } from '@site/src/components/banner-section/banner-section-grid';
|
||||
import { ContentBlock } from '@site/src/components/content-block/content-block';
|
||||
import Layout from '@theme/Layout';
|
||||
import { clsx } from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
import demosStyles from './demos.module.scss';
|
||||
|
||||
interface IDemoItem {
|
||||
title: string;
|
||||
content: React.ReactNode;
|
||||
actionItemLink?: string;
|
||||
media: {
|
||||
type: 'image' | 'video';
|
||||
link: string;
|
||||
};
|
||||
}
|
||||
|
||||
const Demos = () => {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
|
||||
//#region Collection Data
|
||||
const demoItems: IDemoItem[] = [
|
||||
{
|
||||
title: 'See us in action',
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Watch the videos below to get an introduction to Backstage and to
|
||||
see how we use different plugins to customize{' '}
|
||||
<Link to="https://engineering.atspotify.com/2020/04/21/how-we-use-backstage-at-spotify/">
|
||||
our internal version of Backstage at Spotify
|
||||
</Link>
|
||||
</p>
|
||||
<p>
|
||||
To see how other companies have already started using Backstage,
|
||||
watch these presentations from{' '}
|
||||
<Link to="https://youtu.be/rRphwXeq33Q?t=1508">Expedia</Link>,{' '}
|
||||
<Link to="https://youtu.be/6sg5uMCLxTA?t=153">Zalando</Link>, and{' '}
|
||||
<Link to="https://youtu.be/UZTVjv-AvZA?t=188">TELUS</Link>. For
|
||||
more, join our{' '}
|
||||
<Link to="https://github.com/backstage/community">
|
||||
Community Sessions
|
||||
</Link>
|
||||
</p>
|
||||
<p>
|
||||
To explore the UI and basic features of Backstage firsthand, go to:{' '}
|
||||
<Link to="https://demo.backstage.io">demo.backstage.io</Link>. (Tip:{' '}
|
||||
click “All” to view all the example components in the software
|
||||
catalog.)
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
media: {
|
||||
type: 'image',
|
||||
link: `${siteConfig.baseUrl}img/demo-screen.png`,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Introduction to Backstage',
|
||||
content:
|
||||
'Backstage is an open source platform for building developer portals. We’ve been using our homegrown version at Spotify for years — so it’s already packed with features. (We have over 120 internal plugins, built by 60 different teams.) In this live demo recording, Stefan Ålund, product manager for Backstage, tells the origin story of Backstage and gives you a tour of how we use it here at Spotify.',
|
||||
actionItemLink: 'https://www.youtube.com/watch?v=1XtJ5FAOjPk',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/1XtJ5FAOjPk',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Control cloud costs',
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
How do you control cloud costs while maintaining the speed and
|
||||
independence of your development teams? With the{' '}
|
||||
<Link to="https://backstage.io/plugins">Cost Insights plugin</Link>{' '}
|
||||
for Backstage, managing cloud costs becomes just another part of an
|
||||
engineer’s daily development process. They get a clear view of their
|
||||
spending — and can decide for themselves how they want to optimize
|
||||
it. Learn more about the{' '}
|
||||
<Link to="https://backstage.io/blog/2020/10/22/cost-insights-plugin">
|
||||
Cost Insights plugin
|
||||
</Link>
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
actionItemLink: 'https://youtu.be/YLAd5hdXR_Q',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/YLAd5hdXR_Q',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Make documentation easy',
|
||||
content: (
|
||||
<>
|
||||
<p>
|
||||
Documentation! Everyone needs it, no one wants to create it, and no
|
||||
one can ever find it. Backstage follows a “docs like code” approach:
|
||||
you write documentation in Markdown files right alongside your code.
|
||||
This makes documentation easier to create, maintain, find — and, you
|
||||
know, actually use. This demo video showcases Spotify’s internal
|
||||
version of TechDocs. Learn more about{' '}
|
||||
<Link to="https://backstage.io/blog/2020/09/08/announcing-tech-docs">
|
||||
TechDocs
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
actionItemLink: 'https://youtu.be/mOLCgdPw1iA',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/mOLCgdPw1iA',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Manage your tech health',
|
||||
content:
|
||||
'Instead of manually updating a spreadsheet, what if you had a beautiful dashboard that could give you an instant, interactive picture of your entire org’s tech stack? That’s how we do it at Spotify. With our Tech Insights plugin for Backstage, anyone at Spotify can see which version of which software anyone else at Spotify is using — and a whole a lot more. From managing migrations to fighting tech entropy, Backstage makes managing our tech health actually kind of pleasant.',
|
||||
actionItemLink:
|
||||
'https://www.youtube.com/watch?v=K3xz6VAbgH8&list=PLf1KFlSkDLIBtMGwRDfaVlKMqTMrjD2yO&index=6',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/K3xz6VAbgH8',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Create a microservice',
|
||||
content:
|
||||
'You’re a Spotify engineer about to build a new microservice (or any component) using Spring Boot. Where do you start? Search for a quick start guide online? Create an empty repo on GitHub? Copy and paste an old project? Nope. Just go to Backstage, and you’ll be up and running in two minutes — with a “Hello World” app, CI, and documentation all automatically set up and configured in a standardized way.',
|
||||
actionItemLink: 'https://www.youtube.com/watch?v=U1iwe3L5pzc',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/U1iwe3L5pzc',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Search all your services',
|
||||
content:
|
||||
'All of Spotify’s services are automatically indexed in Backstage. So our engineers can stop playing detective — no more spamming Slack channels asking if anyone knows who owns a particular service and where you can find its API, only to discover that the owner went on sabbatical three months ago and you have to hunt them down on a mountain in Tibet where they’re on a 12-day silent meditation retreat. At Spotify, anyone can always find anyone else’s service, inspect its APIs, and contact its current owner — all with one search.',
|
||||
actionItemLink: 'https://www.youtube.com/watch?v=vcDL9tOv7Eo',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/vcDL9tOv7Eo',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Manage data pipelines',
|
||||
content:
|
||||
'We manage a lot of data pipelines (also known as workflows) here at Spotify. So, of course, we made a great workflows plugin for our version of Backstage. All our workflow tools — including a scheduler, log inspector, data lineage graph, and configurable alerts — are integrated into one simple interface.',
|
||||
actionItemLink: 'https://www.youtube.com/watch?v=rH46MLNZIPM',
|
||||
media: {
|
||||
type: 'video',
|
||||
link: 'https://www.youtube.com/embed/rH46MLNZIPM',
|
||||
},
|
||||
},
|
||||
];
|
||||
//#endregion
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className={clsx(demosStyles.communityPage)}>
|
||||
{demoItems.map((demoItem, index) => (
|
||||
<BannerSection
|
||||
key={index}
|
||||
greyBackground={index % 2 === 0}
|
||||
className={demosStyles.banner}
|
||||
>
|
||||
<BannerSectionGrid>
|
||||
<ContentBlock
|
||||
title={<h1>{demoItem.title}</h1>}
|
||||
actionButtons={[
|
||||
{
|
||||
link: demoItem.actionItemLink,
|
||||
label: 'WATCH NOW',
|
||||
},
|
||||
]}
|
||||
>
|
||||
{demoItem.content}
|
||||
</ContentBlock>
|
||||
|
||||
<div className={clsx()}>
|
||||
{demoItem.media.type === 'image' ? (
|
||||
<img src={demoItem.media.link} alt={demoItem.title} />
|
||||
) : (
|
||||
<iframe
|
||||
src={demoItem.media.link}
|
||||
title={demoItem.title}
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
)}
|
||||
</div>
|
||||
</BannerSectionGrid>
|
||||
</BannerSection>
|
||||
))}
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default Demos;
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
import Link from '@docusaurus/Link';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import Layout from '@theme/Layout';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
import { IPluginData, PluginCard } from './_plugin-card';
|
||||
import pluginsStyles from './plugins.module.scss';
|
||||
|
||||
//#region Plugin data import
|
||||
const maxDescLength = 160;
|
||||
|
||||
const truncatePluginDescription = (pluginData: IPluginData) =>
|
||||
pluginData.description.length > maxDescLength
|
||||
? {
|
||||
...pluginData,
|
||||
description: pluginData.description.slice(0, maxDescLength) + '...',
|
||||
}
|
||||
: pluginData;
|
||||
|
||||
const pluginsContext = require.context(
|
||||
'../../../../microsite/data/plugins',
|
||||
false,
|
||||
/\.ya?ml/,
|
||||
);
|
||||
|
||||
const plugins = pluginsContext.keys().reduce(
|
||||
(acum, id) => {
|
||||
const pluginData: IPluginData = pluginsContext(id).default;
|
||||
|
||||
acum[
|
||||
pluginData.category === 'Core Feature' ? 'corePlugins' : 'otherPlugins'
|
||||
].push(truncatePluginDescription(pluginData));
|
||||
|
||||
return acum;
|
||||
},
|
||||
{ corePlugins: [] as IPluginData[], otherPlugins: [] as IPluginData[] },
|
||||
);
|
||||
|
||||
plugins.corePlugins.sort((a, b) => a.order - b.order);
|
||||
plugins.otherPlugins.sort((a, b) => a.order - b.order);
|
||||
//#endregion
|
||||
|
||||
export function Plugins() {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div
|
||||
className={clsx('container', 'padding--lg', pluginsStyles.pluginsPage)}
|
||||
>
|
||||
<div className="marketplaceBanner">
|
||||
<div className="marketplaceContent">
|
||||
<h2>Plugin Marketplace</h2>
|
||||
|
||||
<p>
|
||||
Open source plugins that you can add to your Backstage deployment.
|
||||
Learn how to build a <Link to="/docs/plugins">plugin</Link>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Link
|
||||
to="/docs/plugins/add-to-marketplace"
|
||||
className="button button--outline button--primary"
|
||||
>
|
||||
Add to Marketplace
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="bulletLine margin-bottom--lg"></div>
|
||||
|
||||
<h2>Core Features</h2>
|
||||
|
||||
<div className="pluginsContainer margin-bottom--lg">
|
||||
{plugins.corePlugins.map(pluginData => (
|
||||
<PluginCard key={pluginData.title} {...pluginData}></PluginCard>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h2>All Plugins</h2>
|
||||
|
||||
<div className="pluginsContainer margin-bottom--lg">
|
||||
{plugins.otherPlugins.map(pluginData => (
|
||||
<PluginCard key={pluginData.title} {...pluginData}></PluginCard>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
@@ -1,3 +1,87 @@
|
||||
import { Plugins } from './_plugins';
|
||||
import Link from '@docusaurus/Link';
|
||||
import Layout from '@theme/Layout';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
import { IPluginData, PluginCard } from './_plugin-card';
|
||||
import pluginsStyles from './plugins.module.scss';
|
||||
|
||||
//#region Plugin data import
|
||||
const maxDescLength = 160;
|
||||
|
||||
const truncatePluginDescription = (pluginData: IPluginData) =>
|
||||
pluginData.description.length > maxDescLength
|
||||
? {
|
||||
...pluginData,
|
||||
description: pluginData.description.slice(0, maxDescLength) + '...',
|
||||
}
|
||||
: pluginData;
|
||||
|
||||
const pluginsContext = require.context(
|
||||
'../../../../microsite/data/plugins',
|
||||
false,
|
||||
/\.ya?ml/,
|
||||
);
|
||||
|
||||
const plugins = pluginsContext.keys().reduce(
|
||||
(acum, id) => {
|
||||
const pluginData: IPluginData = pluginsContext(id).default;
|
||||
|
||||
acum[
|
||||
pluginData.category === 'Core Feature' ? 'corePlugins' : 'otherPlugins'
|
||||
].push(truncatePluginDescription(pluginData));
|
||||
|
||||
return acum;
|
||||
},
|
||||
{ corePlugins: [] as IPluginData[], otherPlugins: [] as IPluginData[] },
|
||||
);
|
||||
|
||||
plugins.corePlugins.sort((a, b) => a.order - b.order);
|
||||
plugins.otherPlugins.sort((a, b) => a.order - b.order);
|
||||
//#endregion
|
||||
|
||||
const Plugins = () => (
|
||||
<Layout>
|
||||
<div
|
||||
className={clsx('container', 'padding--lg', pluginsStyles.pluginsPage)}
|
||||
>
|
||||
<div className="marketplaceBanner">
|
||||
<div className="marketplaceContent">
|
||||
<h2>Plugin Marketplace</h2>
|
||||
|
||||
<p>
|
||||
Open source plugins that you can add to your Backstage deployment.
|
||||
Learn how to build a <Link to="/docs/plugins">plugin</Link>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Link
|
||||
to="/docs/plugins/add-to-marketplace"
|
||||
className="button button--outline button--primary"
|
||||
>
|
||||
Add to Marketplace
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="bulletLine margin-bottom--lg"></div>
|
||||
|
||||
<h2>Core Features</h2>
|
||||
|
||||
<div className="pluginsContainer margin-bottom--lg">
|
||||
{plugins.corePlugins.map(pluginData => (
|
||||
<PluginCard key={pluginData.title} {...pluginData}></PluginCard>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h2>All Plugins</h2>
|
||||
|
||||
<div className="pluginsContainer margin-bottom--lg">
|
||||
{plugins.otherPlugins.map(pluginData => (
|
||||
<PluginCard key={pluginData.title} {...pluginData}></PluginCard>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
export default Plugins;
|
||||
|
||||
Reference in New Issue
Block a user