add static generation

This commit is contained in:
dennis.ludwig
2021-06-11 11:48:05 +02:00
parent 02c81de12e
commit e2aec44ad7
8 changed files with 132 additions and 116 deletions

2
.env
View File

@@ -1 +1 @@
PUBLIC_URL=techradar/ PUBLIC_URL=/techradar

View File

@@ -1,42 +1,39 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.assetUrl = exports.isMobileViewport = exports.translate = exports.showEmptyRings = exports.getItemPageNames = exports.rings = exports.quadrants = exports.radarNameShort = exports.radarName = void 0; exports.assetUrl = exports.isMobileViewport = exports.translate = exports.showEmptyRings = exports.getItemPageNames = exports.rings = exports.quadrants = exports.radarNameShort = exports.radarName = void 0;
exports.radarName = process.env.RADAR_NAME || 'AOE Technology Radar'; exports.radarName = process.env.RADAR_NAME || "AOE Technology Radar";
exports.radarNameShort = exports.radarName; exports.radarNameShort = exports.radarName;
exports.quadrants = [ exports.quadrants = [
'languages-and-frameworks', "languages-and-frameworks",
'methods-and-patterns', "methods-and-patterns",
'platforms-and-aoe-services', "platforms-and-aoe-services",
'tools', "tools",
]; ];
exports.rings = [ exports.rings = ["all", "adopt", "trial", "assess", "hold"];
'all', var getItemPageNames = function (items) {
'adopt', return items.map(function (item) { return item.quadrant + "/" + item.name; });
'trial', };
'assess',
'hold'
];
var getItemPageNames = function (items) { return items.map(function (item) { return item.quadrant + "/" + item.name; }); };
exports.getItemPageNames = getItemPageNames; exports.getItemPageNames = getItemPageNames;
exports.showEmptyRings = false; exports.showEmptyRings = false;
var messages = { var messages = {
'languages-and-frameworks': 'Languages & Frameworks', "languages-and-frameworks": "Languages & Frameworks",
'methods-and-patterns': 'Methods & Patterns', "methods-and-patterns": "Methods & Patterns",
'platforms-and-aoe-services': 'Platforms and Operations', "platforms-and-aoe-services": "Platforms and Operations",
'tools': 'Tools', tools: "Tools",
}; };
var translate = function (key) { return (messages[key] || '-'); }; var translate = function (key) { return messages[key] || "-"; };
exports.translate = translate; exports.translate = translate;
function isMobileViewport() { function isMobileViewport() {
// return false for server side rendering // return false for server side rendering
if (typeof window == 'undefined') if (typeof window == "undefined")
return false; return false;
var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; var width = window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
return width < 1200; return width < 1200;
} }
exports.isMobileViewport = isMobileViewport; exports.isMobileViewport = isMobileViewport;
function assetUrl(file) { function assetUrl(file) {
return process.env.PUBLIC_URL + '/' + file; return process.env.PUBLIC_URL + "/" + file;
// return `/techradar/assets/${file}`
} }
exports.assetUrl = assetUrl; exports.assetUrl = assetUrl;

View File

@@ -46,24 +46,27 @@ var config_1 = require("../src/config");
switch (_a.label) { switch (_a.label) {
case 0: case 0:
_a.trys.push([0, 2, , 3]); _a.trys.push([0, 2, , 3]);
console.log('starting static'); console.log("starting static");
return [4 /*yield*/, radar_1.createRadar()]; return [4 /*yield*/, radar_1.createRadar()];
case 1: case 1:
radar = _a.sent(); radar = _a.sent();
fs_1.copyFileSync('build/index.html', 'build/overview.html'); fs_1.copyFileSync("build/index.html", "build/overview.html");
fs_1.copyFileSync('build/index.html', 'build/help-and-about-tech-radar.html'); fs_1.copyFileSync("build/index.html", "build/help-and-about-tech-radar.html");
config_1.quadrants.forEach(function (quadrant) { config_1.quadrants.forEach(function (quadrant) {
fs_1.copyFileSync('build/index.html', 'build/' + quadrant + '.html'); var destFolder = "build/" + quadrant;
fs_1.mkdirSync('build/' + quadrant); fs_1.copyFileSync("build/index.html", destFolder + ".html");
if (!fs_1.existsSync(destFolder)) {
fs_1.mkdirSync(destFolder);
}
}); });
radar.items.forEach(function (item) { radar.items.forEach(function (item) {
fs_1.copyFileSync('build/index.html', 'build/' + item.quadrant + '/' + item.name + '.html'); fs_1.copyFileSync("build/index.html", "build/" + item.quadrant + "/" + item.name + ".html");
}); });
console.log('created static'); console.log("created static");
return [3 /*break*/, 3]; return [3 /*break*/, 3];
case 2: case 2:
e_1 = _a.sent(); e_1 = _a.sent();
console.error('error:', e_1); console.error("error:", e_1);
return [3 /*break*/, 3]; return [3 /*break*/, 3];
case 3: return [2 /*return*/]; case 3: return [2 /*return*/];
} }

View File

@@ -61,7 +61,7 @@ interface Data {
export default function App() { export default function App() {
const [data, setData] = React.useState<Data>(); const [data, setData] = React.useState<Data>();
React.useEffect(() => { React.useEffect(() => {
fetch("rd.json") fetch(`${process.env.PUBLIC_URL}/rd.json`)
.then((response) => response.json()) .then((response) => response.json())
.then((data: Data) => { .then((data: Data) => {
setData(data); setData(data);
@@ -74,9 +74,9 @@ export default function App() {
if (data) { if (data) {
const { items, releases } = data; const { items, releases } = data;
return ( return (
<BrowserRouter> <BrowserRouter basename={`${process.env.PUBLIC_URL}`}>
<Switch> <Switch>
<Route path={"/techradar/:page(.+).html"}> <Route path={"/:page(.+).html"}>
<div> <div>
<div className="page"> <div className="page">
<div className="page__header"> <div className="page__header">
@@ -92,7 +92,7 @@ export default function App() {
</div> </div>
</Route> </Route>
<Route path={"/"}> <Route path={"/"}>
<Redirect to={"/techradar/index.html"} /> <Redirect to={"/index.html"} />
</Route> </Route>
</Switch> </Switch>
</BrowserRouter> </BrowserRouter>

View File

@@ -1,16 +1,16 @@
import React, { useState, useRef } from 'react'; import React, { useState, useRef } from "react";
import classNames from 'classnames'; import classNames from "classnames";
import Branding from '../Branding/Branding'; import Branding from "../Branding/Branding";
import Link from '../Link/Link'; import Link from "../Link/Link";
import LogoLink from '../LogoLink/LogoLink'; import LogoLink from "../LogoLink/LogoLink";
import Search from '../Search/Search'; import Search from "../Search/Search";
import { radarNameShort } from '../../config'; import { radarNameShort } from "../../config";
import { useHistory } from 'react-router-dom'; import { useHistory } from "react-router-dom";
import qs from 'query-string'; import qs from "query-string";
export default function Header({ pageName }: { pageName: string }) { export default function Header({ pageName }: { pageName: string }) {
const [searchOpen, setSearchOpen] = useState(false); const [searchOpen, setSearchOpen] = useState(false);
const [search, setSearch] = useState(''); const [search, setSearch] = useState("");
const history = useHistory(); const history = useHistory();
const searchRef = useRef<HTMLInputElement>(null); const searchRef = useRef<HTMLInputElement>(null);
@@ -23,17 +23,17 @@ export default function Header({ pageName }: { pageName: string }) {
}; };
const handleSearchChange = (value: string) => { const handleSearchChange = (value: string) => {
setSearch(value) setSearch(value);
}; };
const handleSearchSubmit = () => { const handleSearchSubmit = () => {
history.push({ history.push({
pathname: '/techradar/overview.html', pathname: "/overview.html",
search: qs.stringify({search: search}), search: qs.stringify({ search: search }),
}) });
setSearchOpen(false); setSearchOpen(false);
setSearch(''); setSearch("");
}; };
const handleOpenClick = (e: React.MouseEvent<HTMLButtonElement>) => { const handleOpenClick = (e: React.MouseEvent<HTMLButtonElement>) => {
@@ -44,27 +44,37 @@ export default function Header({ pageName }: { pageName: string }) {
}, 0); }, 0);
}; };
const smallLogo = pageName !== 'index'; const smallLogo = pageName !== "index";
return ( return (
<Branding logoContent={<LogoLink small={smallLogo} />}> <Branding logoContent={<LogoLink small={smallLogo} />}>
<div className='nav'> <div className="nav">
<div className='nav__item'> <div className="nav__item">
<Link pageName='help-and-about-tech-radar' className='icon-link'> <Link pageName="help-and-about-tech-radar" className="icon-link">
<span className='icon icon--question icon-link__icon'/>How to Use {radarNameShort}? <span className="icon icon--question icon-link__icon" />
How to Use {radarNameShort}?
</Link> </Link>
</div> </div>
<div className='nav__item'> <div className="nav__item">
<Link pageName='overview' className='icon-link'> <Link pageName="overview" className="icon-link">
<span className='icon icon--overview icon-link__icon'/>Technologies Overview <span className="icon icon--overview icon-link__icon" />
Technologies Overview
</Link> </Link>
</div> </div>
<div className='nav__item'> <div className="nav__item">
<button className='icon-link' onClick={handleOpenClick}> <button className="icon-link" onClick={handleOpenClick}>
<span className='icon icon--search icon-link__icon'/>Search <span className="icon icon--search icon-link__icon" />
Search
</button> </button>
<div className={classNames('nav__search', { 'is-open': searchOpen })}> <div className={classNames("nav__search", { "is-open": searchOpen })}>
<Search value={search} onClose={closeSearch} onSubmit={handleSearchSubmit} onChange={handleSearchChange} open={searchOpen} ref={searchRef} /> <Search
value={search}
onClose={closeSearch}
onSubmit={handleSearchSubmit}
onChange={handleSearchChange}
open={searchOpen}
ref={searchRef}
/>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,15 +1,20 @@
import React from 'react'; import React from "react";
import { Link as RLink } from 'react-router-dom'; import { Link as RLink } from "react-router-dom";
import './link.scss'; import "./link.scss";
type LinkProps = { type LinkProps = {
pageName: string; pageName: string;
style?: React.CSSProperties; style?: React.CSSProperties;
className?: string; className?: string;
}; };
function Link({ pageName, children, className, style = {} }: React.PropsWithChildren<LinkProps>) { function Link({
pageName,
children,
className,
style = {},
}: React.PropsWithChildren<LinkProps>) {
return ( return (
<RLink to={`/techradar/${pageName}.html`} style={style} {...{ className }}> <RLink to={`/${pageName}.html`} style={style} {...{ className }}>
{children} {children}
</RLink> </RLink>
); );

View File

@@ -1,47 +1,44 @@
import {Item} from './model'; import { Item } from "./model";
export const radarName = process.env.RADAR_NAME || 'AOE Technology Radar' export const radarName = process.env.RADAR_NAME || "AOE Technology Radar";
export const radarNameShort = radarName; export const radarNameShort = radarName;
export const quadrants = [ export const quadrants = [
'languages-and-frameworks', "languages-and-frameworks",
'methods-and-patterns', "methods-and-patterns",
'platforms-and-aoe-services', "platforms-and-aoe-services",
'tools', "tools",
]; ];
export const rings = [ export const rings = ["all", "adopt", "trial", "assess", "hold"] as const;
'all',
'adopt',
'trial',
'assess',
'hold'
] as const;
export type Ring = typeof rings[number] export type Ring = typeof rings[number];
export const getItemPageNames = (items: Item[]) => items.map(item => `${item.quadrant}/${item.name}`); export const getItemPageNames = (items: Item[]) =>
items.map((item) => `${item.quadrant}/${item.name}`);
export const showEmptyRings = false; export const showEmptyRings = false;
const messages: { [k: string]: string } = { const messages: { [k: string]: string } = {
'languages-and-frameworks': 'Languages & Frameworks', "languages-and-frameworks": "Languages & Frameworks",
'methods-and-patterns': 'Methods & Patterns', "methods-and-patterns": "Methods & Patterns",
'platforms-and-aoe-services': 'Platforms and Operations', "platforms-and-aoe-services": "Platforms and Operations",
'tools': 'Tools', tools: "Tools",
}; };
export const translate = (key: string) => (messages[key] || '-'); export const translate = (key: string) => messages[key] || "-";
export function isMobileViewport() { export function isMobileViewport() {
// return false for server side rendering // return false for server side rendering
if (typeof window == 'undefined') return false; if (typeof window == "undefined") return false;
const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; const width =
return width < 1200; window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
return width < 1200;
} }
export function assetUrl(file: string) { export function assetUrl(file: string) {
return process.env.PUBLIC_URL + '/' + file; return process.env.PUBLIC_URL + "/" + file;
// return `/techradar/assets/${file}`
} }

View File

@@ -1,29 +1,33 @@
#!/usr/bin/env node #!/usr/bin/env node
import {createRadar} from "./radar"; import { createRadar } from "./radar";
import {save} from "./file"; import { copyFileSync, mkdirSync, existsSync } from "fs";
import {copyFileSync, mkdir, mkdirSync} from "fs"; import { quadrants } from "../src/config";
import {quadrants} from "../src/config";
(async () => { (async () => {
try { try {
console.log('starting static') console.log("starting static");
const radar = await createRadar(); const radar = await createRadar();
copyFileSync('build/index.html', 'build/overview.html') copyFileSync("build/index.html", "build/overview.html");
copyFileSync('build/index.html', 'build/help-and-about-tech-radar.html') copyFileSync("build/index.html", "build/help-and-about-tech-radar.html");
quadrants.forEach(quadrant => { quadrants.forEach((quadrant) => {
copyFileSync('build/index.html', 'build/' + quadrant + '.html') const destFolder = `build/${quadrant}`;
mkdirSync('build/' + quadrant) copyFileSync("build/index.html", `${destFolder}.html`);
}) if (!existsSync(destFolder)) {
radar.items.forEach(item => { mkdirSync(destFolder);
copyFileSync('build/index.html', 'build/' + item.quadrant + '/' + item.name + '.html') }
}) });
radar.items.forEach((item) => {
copyFileSync(
"build/index.html",
`build/${item.quadrant}/${item.name}.html`
);
});
console.log('created static'); console.log("created static");
} catch (e) { } catch (e) {
console.error('error:', e); console.error("error:", e);
} }
})() })();