Skip to content
This repository was archived by the owner on Oct 3, 2025. It is now read-only.
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
1 change: 0 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache: 'pip' # harmless even though we'll use uv
- name: "Install uv"
uses: astral-sh/setup-uv@v6
with:
Expand Down
137 changes: 79 additions & 58 deletions frontend/bun.lock

Large diffs are not rendered by default.

40 changes: 23 additions & 17 deletions frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
{
"name": "frontend",
"version": "0.1.0",
"type": "module",
"private": true,
"proxy": "http://0.0.0.0:8000",
"dependencies": {
"@radix-ui/react-tooltip": "^1.0.7",
"@radix-ui/react-tooltip": "^1.2.8",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^20.12.5",
"@types/react": "^18.2.18",
"@types/react-dom": "^18.2.18",
"ajv": "^7",
"postcss": "^8.4.38",
"react": "^18.2.0",
"react-code-blocks": "^0.1.5",
"react-dom": "^18.2.0",
"@types/node": "^20.19.19",
"@types/react": "^18.3.25",
"@types/react-dom": "^18.3.7",
"ajv": "^7.2.4",
"postcss": "^8.5.6",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-inject-env": "^2.1.0",
"react-router-dom": "^6.21.2",
"react-refractor": "^4.0.0",
"react-router-dom": "^6.30.1",
"react-scripts": "^5.0.1",
"react-syntax-highlighter": "^15.5.0",
"react-syntax-highlighter": "^15.6.6",
"refractor": "^5.0.0",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
Expand Down Expand Up @@ -53,17 +55,21 @@
},
"jest": {
"transform": {
"^.+\\.svg$": "./src/tests/transformers/svg.js"
"^.+\\.svg$": "<rootDir>/src/tests/transformers/svg.js"
},
"moduleNameMapper": {
"^react-refractor$": "<rootDir>/__mocks__/react-refractor.js",
"^refractor/yaml$": "<rootDir>/__mocks__/refractor/yaml.js"
}
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@svgr/webpack": "^8.1.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-testing-library": "^6.0.1",
"prettier": "^3.0.3",
"tailwindcss": "^3.3.3"
"eslint-config-prettier": "^9.1.2",
"eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-testing-library": "^6.5.0",
"prettier": "^3.6.2",
"tailwindcss": "^3.4.17"
},
"overrides": {
"@svgr/webpack": "$@svgr/webpack"
Expand Down
9 changes: 0 additions & 9 deletions frontend/src/__mocks__/react-code-blocks.js

This file was deleted.

9 changes: 9 additions & 0 deletions frontend/src/__mocks__/react-refractor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react";

export const Refractor = () => {
return <div data-testid="mocked-code-block">RefractorMock</div>;
};

export const registerLanguage = () => {};

export default Refractor;
2 changes: 2 additions & 0 deletions frontend/src/__mocks__/refractor/yaml.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const yaml = {};
export default yaml;
57 changes: 57 additions & 0 deletions frontend/src/components/CodeBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { useMemo } from "react";
import { Refractor, registerLanguage } from "react-refractor";
import yaml from "refractor/yaml";

registerLanguage(yaml);

interface CodeBlockProps {
text: string;
language?: "yaml" | "javascript";
showLineNumbers?: boolean;
startingLineNumber?: number;
className?: string;
}

export default function CodeBlock({
text,
language = "yaml",
showLineNumbers = true,
startingLineNumber = 1,
className,
}: CodeBlockProps) {
const lines = useMemo(() => text.split("\n"), [text]);

const numbers = lines
.map((_, i) => String(startingLineNumber + i))
.join("\n");

return (
<pre
className={`flex ${className || ""} overflow-x-auto`}
data-starting-line-number={startingLineNumber}
data-testid="code-block"
>
{showLineNumbers && (
<div
className="text-right text-gray-400 select-none"
data-starting-line-number={startingLineNumber}
>
<Refractor
language="text"
value={numbers}
inline={false}
className="!rounded-r-none !pr-0"
/>
</div>
)}
<div className="flex-1" data-starting-line-number={startingLineNumber}>
<Refractor
language={language}
value={text}
inline={false}
className="!rounded-l-none"
/>
</div>
</pre>
);
}
43 changes: 43 additions & 0 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,46 @@
/*@apply border-b-[40px] border-l-[50px] border-b-upsun-violet-600 border-l-transparent;*/
}
}

@layer components {
code[class*="language-"] {
@apply block;
}

:not(.gutter) > code[class*="language-"] {
@apply text-gray-400;
}

pre[class*="language-"] {
@apply text-white bg-black p-4 m-0 overflow-auto rounded-md;
}

code[class*="language-"] .token.comment {
@apply text-white italic;
}

code[class*="language-"] .token.key {
@apply text-upsun-yellow-400;
}

code[class*="language-"] .token.string,
code[class*="language-"] .token.char {
@apply text-[#34E2E2];
}

code[class*="language-"] .token.punctuation {
@apply text-[#ccc];
}

code[class*="language-"] .token.function {
@apply text-[#FFD700];
}

code[class*="language-"] .token.variable {
@apply text-[#F0E68C];
}

code[class*="language-"] .token.number {
@apply text-[#FFA500];
}
}
40 changes: 36 additions & 4 deletions frontend/src/steps/StepRedis.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import fs from "fs";
import path from "path";
import { render, screen } from "@testing-library/react";
import StepRedis from "./StepRedis";

function getSnippetStartLine(filePath: string, marker: string) {
const contents = fs.readFileSync(filePath, "utf-8").split("\n");
const idx = contents.findIndex((line) => line.includes(marker));
if (idx === -1) throw new Error(`Marker "${marker}" not found`);
return idx + 1;
}

describe("<StepRedis />", () => {
it("renders with correct title", async () => {
render(
Expand All @@ -10,7 +19,6 @@ describe("<StepRedis />", () => {
environment="staging"
/>,
);

expect(
await screen.findByText("3. Add Redis to staging"),
).toBeInTheDocument();
Expand All @@ -20,11 +28,30 @@ describe("<StepRedis />", () => {
render(
<StepRedis isDisabled={true} hideContent={false} environment="staging" />,
);

expect(await screen.findByTestId("step-redis")).toHaveClass("is-disabled");
});

it("renders the mocked code block instead of the real one", async () => {
it("renders one mocked code block for gutter and one for code", async () => {
render(
<StepRedis
isDisabled={false}
hideContent={false}
environment="staging"
/>,
);

const block = screen.getByTestId("code-block");

expect(block).toBeInTheDocument();
});

it("uses the correct startingLineNumber based on config.yaml", () => {
const filePath = path.resolve(process.cwd(), "../.upsun/config.yaml");
const expectedLineNumber = getSnippetStartLine(
filePath,
"#add_service_start",
);

render(
<StepRedis
isDisabled={false}
Expand All @@ -33,6 +60,11 @@ describe("<StepRedis />", () => {
/>,
);

expect(await screen.findByTestId("mocked-code-block")).toBeInTheDocument();
const block = screen.getByTestId("code-block");

expect(block).toHaveAttribute(
"data-starting-line-number",
String(expectedLineNumber),
);
});
});
6 changes: 2 additions & 4 deletions frontend/src/steps/StepRedis.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React from "react";
import FeatureStep from "../components/FeatureStep";
import { ReactComponent as RedisIcon } from "../assets/utility/service_redis.svg";
import { CodeBlock } from "react-code-blocks";
import UpsunCodeTheme from "../theme/code";
import CodeBlock from "../components/CodeBlock";
import CopyButton from "../components/CopyButton";
import commands from "../commands.json";
import CodeExample from "../components/CodeExample";
Expand Down Expand Up @@ -70,8 +69,7 @@ services:
text={servicesText}
language="yaml"
showLineNumbers
theme={UpsunCodeTheme}
startingLineNumber={67}
startingLineNumber={79}
/>
</div>
</li>
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/tests/transformers/svg.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const path = require("path");
import path from "path";

/**
* This function build module.
Expand Down Expand Up @@ -78,4 +78,5 @@ const processSvg = (contents, filename) => {
// return { code: contents };
};

module.exports = { process: processSvg };
const output = { process: processSvg };
export default output;
10 changes: 0 additions & 10 deletions frontend/src/theme/code.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion frontend/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
content: ["./src/**/*.{js,jsx,ts,tsx}", "./node_modules/refractor/**/*.js"],
theme: {
extend: {
fontSize: {
Expand Down
2 changes: 1 addition & 1 deletion frontend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
Expand Down
Loading