diff --git a/Makefile b/Makefile index 1400327daa..51cffa92c3 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,9 @@ api: ## Generate API docs npm run clean-api-docs npm run generate-api-docs +test: ## Run Jest tests + npm test + ##@ Git Targets commit: ## Add a Git commit. Usage: make commit MESSAGE="" diff --git a/README.md b/README.md index 4e06357ce0..037fd2a1cb 100644 --- a/README.md +++ b/README.md @@ -498,6 +498,36 @@ To add a video, use the following syntax. Ensure you capitalize the letter "V": ``` +### Simple Card Grid + +This is a custom component that creates a grid of simple text cards with two columns, styled according to our color +scheme. The rows of cards are dynamically created according to the list of specified cards. + +```js + +``` + ## Netlify Previews By default Netlify previews are enabled for pull requests. However, some branches do not require Netlify previews. In diff --git a/docs/docs-content/getting-started/dashboard.md b/docs/docs-content/getting-started/dashboard.md index 1804c05530..6922602457 100644 --- a/docs/docs-content/getting-started/dashboard.md +++ b/docs/docs-content/getting-started/dashboard.md @@ -1,7 +1,7 @@ --- sidebar_label: "Palette Dashboard" title: "Palette Dashboard" -description: "Spectro Cloud Palette Dashboard" +description: "Explore the Spectro Cloud Palette Dashboard." icon: "" hide_table_of_contents: false sidebar_position: 20 diff --git a/docs/docs-content/getting-started/getting-started.md b/docs/docs-content/getting-started/getting-started.md index 273d1cf752..0413c8f9f6 100644 --- a/docs/docs-content/getting-started/getting-started.md +++ b/docs/docs-content/getting-started/getting-started.md @@ -2,35 +2,96 @@ sidebar_label: "Getting Started" title: "Getting Started" description: "Spectro Cloud Getting Started" -hide_table_of_contents: false +hide_table_of_contents: true sidebar_custom_props: icon: "overview" tags: ["getting-started"] --- -This page gives an overview of how to get started with Spectro Cloud Palette and begin leveraging its Kubernetes +This page gives you an overview of how to get started with Spectro Cloud Palette and begin leveraging its Kubernetes full-stack management at scale. Palette's unique capabilities provide end-to-end declarative cluster management, cluster -monitoring and reconciliation, as well as adherence to the highest security standards. It provides support for public -cloud providers, data centers, bare metal and edge, so you can use Palette no matter the complexity of your production -environments. +monitoring and reconciliation, as well as enterprise-grade security. + +Palette provides developers and platform engineers with complete control of their Kubernetes clusters. The platform +provides support for public cloud providers, data centers, bare metal, and edge so that you can deploy and use +Kubernetes no matter the complexity or location of your production environments. Check out the following short video for +a quick overview of Palette's key functionalities. + + + +
+ +## Deploy Kubernetes Clusters with Palette The first step towards adopting Palette in your organization is to [create a login](https://www.spectrocloud.com/get-started). The [Palette Free Tier](https://www.spectrocloud.com/free-tier) allows you to experience the benefits of Palette first-hand. -The Getting Started section introduces you to the concepts and workflows you need to begin using Palette. Explore more -through the following pages. +We have curated the pages in the Getting Started section to give you a gradual introduction to the fundamental concepts +and workflows you need to deploy and manage Kubernetes clusters through Palette. -- [Introduction to Palette](./introduction.md) +
-- [Palette Dashboard](./dashboard.md) +![Overview of the getting started journey rocket](/getting-started/getting-started_getting-started_journey-overview.png) -- [Cluster Profiles](./cluster-profiles.md) +
-- [Create a Cluster Profile](./create-cluster-profile.md) +
-- [Deploy a Cluster](./deploy-k8s-cluster.md) +First, you will learn how to create cluster profiles, which are the blueprints for your Kubernetes stacks. Then, you +will deploy your first cluster using your cluster profile. Once you have deployed your first cluster, you update it +using Palette's cluster management functionality. The Getting Started section also includes other topics that you can +explore further, such as cluster deployment with Terraform, Palette's edge capabilities, and virtual machine +orchestration. -- [Deploy Cluster Profile Updates](./update-k8s-cluster.md) +Explore more through the following pages. -- [Deploy a Cluster with Terraform](./terraform.md) + diff --git a/docs/docs-content/getting-started/introduction.md b/docs/docs-content/getting-started/introduction.md index 92822f5596..3af92c1a74 100644 --- a/docs/docs-content/getting-started/introduction.md +++ b/docs/docs-content/getting-started/introduction.md @@ -1,7 +1,7 @@ --- sidebar_label: "Introduction to Palette" title: "Introduction to Palette" -description: "Learn what Spectro Cloud's Palette platform is." +description: "Learn about Spectro Cloud Palette." icon: "" hide_table_of_contents: false sidebar_position: 10 diff --git a/src/components/SimpleCardGrid/SimpleCardFooterArrow.tsx b/src/components/SimpleCardGrid/SimpleCardFooterArrow.tsx new file mode 100644 index 0000000000..2c2a90434c --- /dev/null +++ b/src/components/SimpleCardGrid/SimpleCardFooterArrow.tsx @@ -0,0 +1,10 @@ +import RightArrow from "/static/assets/icons/arrow-right-long.svg"; +import styles from "./SimpleCardGrid.module.scss"; +import React from "react"; + +interface FooterArrowProps { + index?: number; +} +export default function SimpleCardFooterArrow({ index }: FooterArrowProps) { + return ; +} diff --git a/src/components/SimpleCardGrid/SimpleCardGrid.module.scss b/src/components/SimpleCardGrid/SimpleCardGrid.module.scss new file mode 100644 index 0000000000..80cc970536 --- /dev/null +++ b/src/components/SimpleCardGrid/SimpleCardGrid.module.scss @@ -0,0 +1,99 @@ +.simpleCardGrid { + display: grid; + grid-gap: 32px; + grid-template-columns: 1fr 1fr; + grid-template-rows: 2fr; +} + +.simpleCard { + min-width: 360px; + padding: 12px 16px; + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 10px; + border: 1px solid var(--simpleCardBorder); + border-radius: 12px; + color: var(--ifm-font-color-base); + box-shadow: -10px 10px var(--simpleCardSecondary); + word-wrap: break-word; +} + +.simpleCardDescription { + font-size: 14px; + font-weight: 400; + line-height: 20px; + color: var(--simpleCardSubtle); +} + +.simpleCardHeader { + display: flex; + justify-content: flex-start; + align-items: center; + gap: 12px; + font-size: 20px; + font-weight: 500; + line-height: 24px; +} + +.simpleCardFooter { + display: flex; + justify-content: flex-end; + align-items: center; +} + +.simpleCardFooterBtn { + display: flex; + align-items: center; + gap: 10px; + background-color: var(--simpleCardSecondary); + border-radius: 4px; + color: var(--ifm-font-color-base); + font-size: 14px; + font-weight: var(--ifm-button-font-weight); + padding: 10px 16px; + border: none; + outline: none; + height: 32px; + width: 136px; + cursor: pointer; +} + +.simpleCardFooterArrow { + height: 1em; + fill: var(--ifm-font-color-base); +} + +.simpleCardIndex { + width: 32px; + height: 32px; + display: flex; + justify-content: center; + align-items: center; + background-color: var(--simpleCardPrimary); + color: var(--ifm-background-color); + border-radius: 4px; +} + +.simpleCard:hover { + box-shadow: -10px 10px var(--simpleCardSecondaryHover); +} + +.simpleCard:hover .simpleCardFooter button { + background-color: var(--simpleCardSecondaryHover); +} + +.simpleCard:hover .simpleCardIndex { + background-color: var(--simpleCardPrimaryHover); +} + +@media (max-width: 1120px) { + .simpleCardGrid { + grid-template-columns: 1fr; + } + + .simpleCard { + min-width: 280px; + } +} diff --git a/src/components/SimpleCardGrid/SimpleCardGrid.test.tsx b/src/components/SimpleCardGrid/SimpleCardGrid.test.tsx new file mode 100644 index 0000000000..3de9a9eb61 --- /dev/null +++ b/src/components/SimpleCardGrid/SimpleCardGrid.test.tsx @@ -0,0 +1,91 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import SimpleCardGrid from "./SimpleCardGrid"; + +jest.mock("./SimpleCardFooterArrow", () => { + return jest.fn(() => { + return
; + }); +}); + +describe("Display SimpleCardGrid", () => { + interface testCard { + title: string; + description: string; + buttonText: string; + relativeURL: string; + } + + interface testCase { + name: string; + cards: testCard[]; + } + + const testCards: testCard[] = [ + { + title: "First Card", + description: "Card 1", + buttonText: "Learn more 1", + relativeURL: "./getting-started-1", + }, + { + title: "Second Card", + description: "Card 2", + buttonText: "Learn more 2", + relativeURL: "./getting-started-2", + }, + { + title: "Third Card", + description: "Card 3", + buttonText: "Learn more 3", + relativeURL: "./getting-started-3", + }, + ]; + + const testCases: testCase[] = [ + { + name: "multiple row cards", + cards: testCards.slice(), + }, + { + name: "single row cards", + cards: testCards.slice(2), + }, + { + name: "less cards than a single row", + cards: testCards.slice(1), + }, + { + name: "empty cards", + cards: [], + }, + ]; + + function assert(testCards: testCard[]) { + render(); + if (testCards.length == 0) { + expect(screen.queryAllByRole("button")).toHaveLength(0); + return; + } + + testCards.forEach((tc, index) => { + expect(screen.getByText(tc.title)).toBeInTheDocument(); + expect(screen.getByText(tc.description)).toBeInTheDocument(); + expect(screen.getByText(tc.buttonText, { selector: "button" })).toBeInTheDocument(); + expect( + screen.getAllByRole("link").filter((value) => { + return value.getAttribute("href") == tc.relativeURL; + }) + ).not.toBeNull(); + }); + + expect(screen.getAllByTestId("mock-arrow")).toHaveLength(testCards.length); + expect(screen.getAllByRole("button")).toHaveLength(testCards.length); + } + + testCases.forEach((tc) => { + it(tc.name, () => { + assert(tc.cards); + }); + }); +}); diff --git a/src/components/SimpleCardGrid/SimpleCardGrid.tsx b/src/components/SimpleCardGrid/SimpleCardGrid.tsx new file mode 100644 index 0000000000..34d63f19e9 --- /dev/null +++ b/src/components/SimpleCardGrid/SimpleCardGrid.tsx @@ -0,0 +1,54 @@ +import React from "react"; +import styles from "./SimpleCardGrid.module.scss"; +import SimpleCardFooterArrow from "./SimpleCardFooterArrow"; + +interface SimpleCardProps { + cards?: SimpleCard[]; +} + +interface SimpleCard { + title: string; + index?: number; + description: string; + buttonText: string; + relativeURL: string; +} + +export default function SimpleCardGrid({ cards = [] }: SimpleCardProps) { + return ( +
+ {cards.map((card, index) => ( + + ))} +
+ ); +} + +function SimpleCard({ title, index, description, buttonText, relativeURL }: SimpleCard) { + return ( + +
+
+
{index}
+
{title}
+
+
+

{description}

+
+
+ +
+
+
+ ); +} diff --git a/src/components/SimpleCardGrid/index.ts b/src/components/SimpleCardGrid/index.ts new file mode 100644 index 0000000000..55f7d00d72 --- /dev/null +++ b/src/components/SimpleCardGrid/index.ts @@ -0,0 +1,3 @@ +import SimpleCardGrid from "./SimpleCardGrid"; + +export default SimpleCardGrid; diff --git a/src/css/custom.scss b/src/css/custom.scss index 6c537a6e9c..1218462710 100644 --- a/src/css/custom.scss +++ b/src/css/custom.scss @@ -208,3 +208,14 @@ p img.markdown-image { margin-right: auto; border-radius: 1vw; } + +.admonition-tech-preview { + border: 1px solid var(--custom-purple-important-color); + background-color: var(--custom-purple-alert-bg-color); +} + +.desktop-only-display { + @media (max-width: 768px) { + display: none; + } +} diff --git a/src/css/dark-mode.scss b/src/css/dark-mode.scss index 0cc8386a59..730dedb86e 100644 --- a/src/css/dark-mode.scss +++ b/src/css/dark-mode.scss @@ -29,6 +29,15 @@ html[data-theme="dark"] { --ifm-color-warning-dark: #ffc832; --ifm-alert-padding-horizontal: 1.5rem; --custom-table-header-color: #1c202b; + --custom-purple-important-color: #7d77ca; + --custom-purple-alert-bg-color: #1a173b; + --simpleCardPrimary: #72a8f5; + --simpleCardPrimaryHover: #9cc2f8; + --simpleCardSecondary: #192c47; + --simpleCardSecondaryHover: #213e67; + --simpleCardSubtle: #b5bdd4; + --simpleCardButtonIcon: #818ba9; + --simpleCardBorder: #1f263c; .theme-last-updated { color: var(--ifm-font-color-base); diff --git a/src/css/light-mode.scss b/src/css/light-mode.scss index 3ecae66d93..528d73711d 100644 --- a/src/css/light-mode.scss +++ b/src/css/light-mode.scss @@ -26,6 +26,15 @@ html[data-theme="light"] { --ifm-color-warning-dark: #a8882f; --ifm-alert-padding-horizontal: 1.5rem; --custom-table-header-color: #f7f7f7; + --custom-purple-important-color: #7d77ca; + --custom-purple-alert-bg-color: #dcdaf9; + --simpleCardPrimary: #4a8ff1; + --simpleCardPrimaryHover: #3f74be; + --simpleCardSecondary: #dbecff; + --simpleCardSecondaryHover: #c3e0ff; + --simpleCardSubtle: #545f7e; + --simpleCardButtonIcon: #545f7e; + --simpleCardBorder: #dee1ea; .theme-doc-sidebar-item-category-level-1 .menu__list-item { .menu__link:hover { diff --git a/src/theme/MDXComponents/MDXComponents.ts b/src/theme/MDXComponents/MDXComponents.ts index ff87200699..6323974fac 100644 --- a/src/theme/MDXComponents/MDXComponents.ts +++ b/src/theme/MDXComponents/MDXComponents.ts @@ -9,6 +9,7 @@ import Packs from "@site/src/components/Integrations/Packs/Packs"; import AppTiers from "@site/src/components/Integrations/AppTiers/AppTiers"; import PacksTable from "@site/src/components/PacksTable/PacksTable"; import TOCInline from "@theme/TOCInline"; +import SimpleCardGrid from "@site/src/components/SimpleCardGrid/index"; export default { ...MDXComponents, @@ -22,4 +23,5 @@ export default { AppTiers, PacksTable, TOCInline, + SimpleCardGrid, }; diff --git a/static/assets/docs/images/getting-started/getting-started_getting-started_journey-overview.png b/static/assets/docs/images/getting-started/getting-started_getting-started_journey-overview.png new file mode 100644 index 0000000000..ca0cfa53d0 Binary files /dev/null and b/static/assets/docs/images/getting-started/getting-started_getting-started_journey-overview.png differ diff --git a/static/assets/icons/arrow-right-long.svg b/static/assets/icons/arrow-right-long.svg new file mode 100644 index 0000000000..642b79e67e --- /dev/null +++ b/static/assets/icons/arrow-right-long.svg @@ -0,0 +1 @@ + \ No newline at end of file