diff --git a/gatsby-config.js b/gatsby-config.js
index e3ab5a15..5ca940f8 100644
--- a/gatsby-config.js
+++ b/gatsby-config.js
@@ -3,8 +3,17 @@ module.exports = {
siteUrl: 'https://stories.jenkins.io',
description: 'Jenkins is the way',
twitter: '@jenkinsci',
+ githubRepo: 'jenkins-infra/stories',
},
plugins: [
+ {
+ resolve: '@jenkinsci/gatsby-plugin-jenkins-layout',
+ options: {
+ siteUrl: 'https://stories.jenkins.io',
+ headerUrl: 'https://deploy-preview-5668--jenkins-io-site-pr.netlify.app/template/index.html',
+ githubBranch: 'main'
+ },
+ },
{
resolve: 'gatsby-plugin-netlify-cms',
options: {
diff --git a/gatsby-node.js b/gatsby-node.js
index 28d1a6a6..ee9a972a 100644
--- a/gatsby-node.js
+++ b/gatsby-node.js
@@ -1,11 +1,6 @@
-const {makeReactLayout, saveReactLayout} = require('./makeLayout');
const YAML = require('yaml');
const path = require('path');
-exports.onPreBootstrap = async () => {
- await makeReactLayout('https://stories.jenkins.io').then(saveReactLayout);
-};
-
async function createUserStoryPages({graphql, createPage, createRedirect}) {
const userStory = path.resolve('src/pages/_user_story.jsx');
const result = await graphql(`{
diff --git a/makeLayout.js b/makeLayout.js
deleted file mode 100644
index 9dcc4f8b..00000000
--- a/makeLayout.js
+++ /dev/null
@@ -1,213 +0,0 @@
-/* eslint-env node */
-/* eslint-disable no-console */
-const axios = require('axios');
-const cheerio = require('cheerio');
-const fs = require('fs/promises');
-
-async function makeReactLayout(siteUrl) {
- const headerUrl = process.env.HEADER_FILE || 'https://www.jenkins.io/template/index.html';
- const manifestUrl = new URL('/site.webmanifest', headerUrl).toString();
-
- if (!headerUrl) {
- return null;
- }
-
- const jsxLines = [
- 'import React from \'react\';',
- 'import { Helmet } from \'react-helmet\';',
- 'import \'./layout.css\';',
- ];
-
- const cssLines = [
- //'@import \'./styles/ubuntu-fonts.css\';',
- //'@import \'./styles/lato-fonts.css\';',
- //'@import \'./styles/roboto-fonts.css\';',
- //'@import \'./styles/base.css\';',
- //'@import \'./styles/font-icons.css\';',
- //'@import \'github-syntax-light/lib/github-light.css\';'
- ];
-
- console.info(`Downloading header file from '${headerUrl}'`);
- const parsedHeaderUrl = new URL(headerUrl);
- const baseUrl = `${parsedHeaderUrl.protocol}//${parsedHeaderUrl.hostname}${parsedHeaderUrl.port ? `:${parsedHeaderUrl.port}` : ''}`;
- const content = await axios
- .get(headerUrl)
- .then((results) => {
- if (results.status !== 200) {
- throw results.data;
- }
- return results.data;
- });
-
- const $ = cheerio.load(content, {decodeEntities: false});
- $('title').text('Title must not be empty');
- $('nav .active.nav-item').removeClass('active'); // remove highlighted link
- if (siteUrl) {
- $(`.nav-item a[href*="${ siteUrl }"]`).parent('.nav-item').addClass('active');
- $(`.nav-link[href*="${siteUrl}"]`).attr('href', '/');
- }
- $('img, script').each(function () {
- const src = $(this).attr('src');
- if (!src) {return;}
- if (src.startsWith('/')) {
- $(this).attr('src', `${baseUrl}${src}`);
- } else {
- $(this).attr('src', src.replace('https://jenkins.io', baseUrl).replace('https://www.jenkins.io', baseUrl));
- }
- });
- $('a, link').each(function () {
- const href = $(this).attr('href');
- if (!href) {return;}
- if (href.startsWith('/')) {
- $(this).attr('href', `${baseUrl}${href}`);
- } else {
- $(this).attr('href', href.replace('https://jenkins.io', baseUrl).replace('https://www.jenkins.io', baseUrl));
- }
- });
- // remove canonical as we add our own
- $('link[rel="canonical"]').remove();
- // Even though we're supplying our own this one still causes a conflict.
- $('link[href$="/css/font-icons.css"]').remove();
- // Prevents: Access to resource at 'https://jenkins.io/site.webmanifest' from origin 'https://plugins.jenkins.io' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
- $('link[href$="site.webmanifest"]').attr('href', '/site.webmanifest');
- // lets get rid of all the head tags since we are populating them with the SEO component
- $('meta[content*="{{"]').remove();
- //
- // padd as per https://stackoverflow.com/questions/11124777/twitter-bootstrap-navbar-fixed-top-overlapping-site
- $('head').append('');
- $('head').append('');
-
- $('#grid-box').empty();
- $('#grid-box').append('{children}');
- if (process.env.NETLIFY) {
- $('#footer .col-md-4').prepend('

');
- }
- $('link[rel="stylesheet"]').each((_, elm) => {
- elm = $(elm);
- cssLines.push(`@import url('${elm.attr('href')}');`);
- elm.remove();
- });
- $('.searchbox').remove();
- $('script[src*="docsearch"]').remove();
- $('script:contains("docsearch")').remove();
- $('script:contains("google-analytics.com")').remove();
-
- const keyConversion = {
- class: 'className',
- 'charSet': 'charset',
- 'http-equiv': 'httpEquiv',
- 'stop-color': 'stopColor',
- 'crossorigin': 'crossOrigin',
- 'lineargradient': 'linearGradient',
- 'gradienttransform': 'gradientTransform',
- 'gradientunits': 'gradientUnits',
- 'viewbox': 'viewBox',
- 'xlink:href': 'xlinkHref',
- 'xmlns:xlink': 'xmlnsXlink',
- };
-
- const nodeConversions = {
- 'lineargradient': 'linearGradient',
- 'gradienttransform': 'gradientTransform',
- };
-
- const handleNode = (node, indent = 0) => {
- const prefix = ''.padStart(6 + indent);
-
- if (node.name) {
- node.name = nodeConversions[node.name] || node.name;
- }
-
- if (node.name === 'link' && node.attribs && node.attribs.rel === 'stylesheet') {
- delete node.attribs.crossorigin;
- node.attribs.type = 'text/css';
- node.attribs.media = 'all';
- }
- const attrs = Object.entries(node.attribs || {}).map(([key, val]) => {
- key = keyConversion[key] || key;
- return `${key}=${JSON.stringify(val)}`;
- }).join(' ');
- if (node.name === 'script') {
- // FIXME - handle me
- const text = node.children.map(child => {
- if (child.type === 'text') {
- return child.data;
- }
- throw new Error(`not sure how to handle ${child.type}`);
- });
- jsxLines.push(`${prefix}<${node.name} ${attrs} dangerouslySetInnerHTML={{__html: ${JSON.stringify(text)}}} />`);
- return;
- } else if (node.type === 'comment') {
- return;
- } else if (node.type === 'text') {
- const text = node.data.replace('\u00A0', ' ');
- jsxLines.push(`${prefix}${text}`);
- } else if (node.children && node.children.length) {
- jsxLines.push(`${prefix}<${node.name} ${attrs}>`);
- node.children.forEach(child => handleNode(child, indent + 2));
- jsxLines.push(`${prefix}${node.name}>`);
- } else {
- const tempAttrs = attrs;
-
- if (!node.name) {
- console.log(node);
- }
- jsxLines.push(`${prefix}<${node.name} ${tempAttrs} />`);
- }
- };
-
- jsxLines.push('export default function Layout({ children, id}) {');
- jsxLines.push(' return (');
- jsxLines.push(' ');
- jsxLines.push(' ');
- $('head').children(':not(link[rel="stylesheet"])').each((_, child) => handleNode(child, 2));
- $('head').children('link[rel="stylesheet"]').each((_, child) => handleNode(child, 2));
- jsxLines.push(' ');
- $('body').children().each((_, child) => handleNode(child, 0));
- jsxLines.push('
');
- jsxLines.push(' );');
-
-
- jsxLines.push('}');
-
-
- console.info(`Downloading site manifest file from '${manifestUrl}'`);
- const manifest = await axios
- .get(manifestUrl)
- .then((results) => {
- if (results.status !== 200) {
- throw results.data;
- }
- results.data.icons.forEach(icon => {
- icon.src = new URL(icon.src, manifestUrl).toString();
- });
- results.data.start_url = siteUrl || 'https://www.jenkins.io';
- return JSON.stringify(results.data);
- });
-
- return {
- manifest: manifest,
- jsxLines: jsxLines.map(str => str.trimEnd()).filter(Boolean).join('\n'),
- cssLines: cssLines.map(str => str.trimEnd()).filter(Boolean).join('\n')
- };
-}
-
-async function saveReactLayout({jsxLines, cssLines, manifest}) {
- if (manifest) {
- await fs.mkdir('static', {recursive: true});
- await fs.writeFile('./static/site.webmanifest', manifest);
- }
- if (jsxLines) {
- await fs.writeFile('./src/layout.jsx', jsxLines);
- }
- if (cssLines) {
- await fs.writeFile('./src/layout.css', cssLines);
- }
-}
-
-exports.makeReactLayout = makeReactLayout;
-exports.saveReactLayout = saveReactLayout;
-
-if (require.main === module) {
- makeReactLayout().then(saveReactLayout).catch(console.error);
-}
diff --git a/package-lock.json b/package-lock.json
index 3c807851..77e93b19 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -36,6 +36,9 @@
"remark-html": "^13.0.1",
"truncate": "^3.0.0",
"yaml": "^1.10.2"
+ },
+ "devDependencies": {
+ "@jenkinsci/gatsby-plugin-jenkins-layout": "^1.2.3"
}
},
"node_modules/@ampproject/remapping": {
@@ -2869,6 +2872,34 @@
"react": "*"
}
},
+ "node_modules/@jenkinsci/gatsby-plugin-jenkins-layout": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@jenkinsci/gatsby-plugin-jenkins-layout/-/gatsby-plugin-jenkins-layout-1.2.3.tgz",
+ "integrity": "sha512-t3nrQ/bfhZo0z5DXjurE7H7RdHw6YMM0uVcu1lFCcO9pVWYSJyPBmYyNzaFL4f4qbUj7RNkyW1DlAnNfe5sblg==",
+ "dev": true,
+ "dependencies": {
+ "axios": "^0.27.2",
+ "cheerio": "^1.0.0-rc.12",
+ "dedent-js": "^1.0.1",
+ "prop-types": "^15.8.1",
+ "react-timeago": "^7.1.0",
+ "style-to-object": "^0.3.0"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/@jenkinsci/gatsby-plugin-jenkins-layout/node_modules/axios": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
+ "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+ "dev": true,
+ "dependencies": {
+ "follow-redirects": "^1.14.9",
+ "form-data": "^4.0.0"
+ }
+ },
"node_modules/@jimp/bmp": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.14.0.tgz",
@@ -6853,17 +6884,17 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
},
"node_modules/cheerio": {
- "version": "1.0.0-rc.10",
- "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
- "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
+ "version": "1.0.0-rc.12",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
+ "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
"dependencies": {
- "cheerio-select": "^1.5.0",
- "dom-serializer": "^1.3.2",
- "domhandler": "^4.2.0",
- "htmlparser2": "^6.1.0",
- "parse5": "^6.0.1",
- "parse5-htmlparser2-tree-adapter": "^6.0.1",
- "tslib": "^2.2.0"
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1",
+ "htmlparser2": "^8.0.1",
+ "parse5": "^7.0.0",
+ "parse5-htmlparser2-tree-adapter": "^7.0.0"
},
"engines": {
"node": ">= 6"
@@ -6873,24 +6904,177 @@
}
},
"node_modules/cheerio-select": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz",
- "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
"dependencies": {
- "css-select": "^4.1.3",
- "css-what": "^5.0.1",
- "domelementtype": "^2.2.0",
- "domhandler": "^4.2.0",
- "domutils": "^2.7.0"
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
- "node_modules/cheerio/node_modules/tslib": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
- "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
+ "node_modules/cheerio-select/node_modules/css-select": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+ "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/domutils": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
+ "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/entities": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
+ "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/domutils": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
+ "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/entities": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
+ "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/htmlparser2": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
+ "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "entities": "^4.3.0"
+ }
+ },
+ "node_modules/cheerio/node_modules/parse5": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
+ "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+ "dependencies": {
+ "entities": "^4.4.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
},
"node_modules/chokidar": {
"version": "3.5.3",
@@ -8170,6 +8354,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/dedent-js": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz",
+ "integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==",
+ "dev": true
+ },
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -8526,9 +8716,9 @@
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
"node_modules/domelementtype": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
- "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
@@ -17997,11 +18187,51 @@
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
},
"node_modules/parse5-htmlparser2-tree-adapter": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
- "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
+ "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
+ "dependencies": {
+ "domhandler": "^5.0.2",
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
- "parse5": "^6.0.1"
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/entities": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
+ "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
+ "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+ "dependencies": {
+ "entities": "^4.4.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/parseqs": {
@@ -19880,6 +20110,15 @@
"react": "^16.8.0 || ^17.0.0"
}
},
+ "node_modules/react-timeago": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/react-timeago/-/react-timeago-7.1.0.tgz",
+ "integrity": "sha512-rouF7MiEm55fH791Y8cg+VobIJgx8gtNJ+gjr86R4ZqO1WKPkXiXjdT/lRzrvEkUzsxT1exHqV2V+Zdi114H3A==",
+ "dev": true,
+ "peerDependencies": {
+ "react": "^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-toggled": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/react-toggled/-/react-toggled-1.2.7.tgz",
@@ -26328,6 +26567,32 @@
"integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==",
"requires": {}
},
+ "@jenkinsci/gatsby-plugin-jenkins-layout": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@jenkinsci/gatsby-plugin-jenkins-layout/-/gatsby-plugin-jenkins-layout-1.2.3.tgz",
+ "integrity": "sha512-t3nrQ/bfhZo0z5DXjurE7H7RdHw6YMM0uVcu1lFCcO9pVWYSJyPBmYyNzaFL4f4qbUj7RNkyW1DlAnNfe5sblg==",
+ "dev": true,
+ "requires": {
+ "axios": "^0.27.2",
+ "cheerio": "^1.0.0-rc.12",
+ "dedent-js": "^1.0.1",
+ "prop-types": "^15.8.1",
+ "react-timeago": "^7.1.0",
+ "style-to-object": "^0.3.0"
+ },
+ "dependencies": {
+ "axios": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
+ "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+ "dev": true,
+ "requires": {
+ "follow-redirects": "^1.14.9",
+ "form-data": "^4.0.0"
+ }
+ }
+ }
+ },
"@jimp/bmp": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.14.0.tgz",
@@ -29244,36 +29509,136 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
},
"cheerio": {
- "version": "1.0.0-rc.10",
- "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
- "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
+ "version": "1.0.0-rc.12",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
+ "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
"requires": {
- "cheerio-select": "^1.5.0",
- "dom-serializer": "^1.3.2",
- "domhandler": "^4.2.0",
- "htmlparser2": "^6.1.0",
- "parse5": "^6.0.1",
- "parse5-htmlparser2-tree-adapter": "^6.0.1",
- "tslib": "^2.2.0"
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1",
+ "htmlparser2": "^8.0.1",
+ "parse5": "^7.0.0",
+ "parse5-htmlparser2-tree-adapter": "^7.0.0"
},
"dependencies": {
- "tslib": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
- "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
+ "dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "requires": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ }
+ },
+ "domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "requires": {
+ "domelementtype": "^2.3.0"
+ }
+ },
+ "domutils": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
+ "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "requires": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.1"
+ }
+ },
+ "entities": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
+ "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA=="
+ },
+ "htmlparser2": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
+ "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
+ "requires": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "entities": "^4.3.0"
+ }
+ },
+ "parse5": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
+ "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+ "requires": {
+ "entities": "^4.4.0"
+ }
}
}
},
"cheerio-select": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz",
- "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
"requires": {
- "css-select": "^4.1.3",
- "css-what": "^5.0.1",
- "domelementtype": "^2.2.0",
- "domhandler": "^4.2.0",
- "domutils": "^2.7.0"
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
+ },
+ "dependencies": {
+ "css-select": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+ "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+ "requires": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ }
+ },
+ "css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
+ },
+ "dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "requires": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ }
+ },
+ "domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "requires": {
+ "domelementtype": "^2.3.0"
+ }
+ },
+ "domutils": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
+ "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+ "requires": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.1"
+ }
+ },
+ "entities": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
+ "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA=="
+ }
}
},
"chokidar": {
@@ -30228,6 +30593,12 @@
}
}
},
+ "dedent-js": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz",
+ "integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==",
+ "dev": true
+ },
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -30518,9 +30889,9 @@
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
"domelementtype": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
- "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
},
"domhandler": {
"version": "4.3.0",
@@ -37548,11 +37919,35 @@
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
},
"parse5-htmlparser2-tree-adapter": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
- "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
+ "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
"requires": {
- "parse5": "^6.0.1"
+ "domhandler": "^5.0.2",
+ "parse5": "^7.0.0"
+ },
+ "dependencies": {
+ "domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "requires": {
+ "domelementtype": "^2.3.0"
+ }
+ },
+ "entities": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
+ "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA=="
+ },
+ "parse5": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
+ "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+ "requires": {
+ "entities": "^4.4.0"
+ }
+ }
}
},
"parseqs": {
@@ -38885,6 +39280,13 @@
"use-latest": "^1.0.0"
}
},
+ "react-timeago": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/react-timeago/-/react-timeago-7.1.0.tgz",
+ "integrity": "sha512-rouF7MiEm55fH791Y8cg+VobIJgx8gtNJ+gjr86R4ZqO1WKPkXiXjdT/lRzrvEkUzsxT1exHqV2V+Zdi114H3A==",
+ "dev": true,
+ "requires": {}
+ },
"react-toggled": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/react-toggled/-/react-toggled-1.2.7.tgz",
diff --git a/package.json b/package.json
index a4b0119d..58d29f91 100644
--- a/package.json
+++ b/package.json
@@ -44,5 +44,8 @@
"remark-html": "^13.0.1",
"truncate": "^3.0.0",
"yaml": "^1.10.2"
+ },
+ "devDependencies": {
+ "@jenkinsci/gatsby-plugin-jenkins-layout": "^1.2.3"
}
}
diff --git a/src/pages/_user_story.jsx b/src/pages/_user_story.jsx
index f1a13b60..64c3da05 100644
--- a/src/pages/_user_story.jsx
+++ b/src/pages/_user_story.jsx
@@ -10,7 +10,7 @@ import UserStory from '../components/UserStory';
const UserStoryPage = ({data: {userStory: page}, pageContext}) => {
const title = page.title;
return (
-
+
@@ -61,6 +61,11 @@ export default UserStoryPage;
export const pageQuery = graphql`
query UserStoryBySlug($id: String!) {
userStory(id: {eq: $id}) {
+ parent {
+ ... on File {
+ relativePath
+ }
+ }
slug
date
post_name