From dc04f1350da9da384af637f28d6d82353b246e6c Mon Sep 17 00:00:00 2001 From: Aidan McPhelim Date: Fri, 12 Apr 2024 13:24:08 +0100 Subject: [PATCH 1/4] created github pages directory --- .github/workflows/site-deploy.yml | 35 ++ .github/workflows/site-pr-build.yml | 25 + site/.gitignore | 69 +++ site/.prettierignore | 4 + site/.prettierrc | 7 + site/.vscode/extensions.json | 12 + site/.vscode/settings.json | 15 + site/content/alternatives.mdx | 12 + site/content/background.mdx | 7 + site/content/documentation-hero.mdx | 11 + site/content/documentation/intro-doc.mdx | 51 ++ .../documentation/message-replaying.mdx | 18 + site/content/documentation/rsvp.mdx | 67 +++ site/content/getting-started.mdx | 32 ++ site/content/hero.mdx | 9 + site/content/news-hero.mdx | 6 + site/content/news/hello-world.mdx | 71 +++ site/content/use-cases.mdx | 22 + site/gatsby-browser.js | 8 + site/gatsby-config.js | 13 + site/gatsby-node.js | 90 +++ site/package.json | 49 ++ site/src/README.md | 40 ++ site/src/components/article.js | 10 + site/src/components/button-link.js | 11 + site/src/components/card-collection.js | 21 + site/src/components/cards/business-details.js | 7 + site/src/components/cards/card.js | 38 ++ site/src/components/cards/index.js | 15 + site/src/components/cards/person.js | 11 + site/src/components/cards/program.js | 11 + site/src/components/cards/story.js | 7 + site/src/components/cards/theme.js | 7 + site/src/components/example-box.js | 5 + site/src/components/footer.js | 33 ++ site/src/components/header.js | 38 ++ site/src/components/hero.js | 14 + site/src/components/layout.js | 32 ++ site/src/components/page-nav.js | 27 + site/src/components/section.js | 15 + site/src/components/seo.js | 71 +++ site/src/config/base-gatsby-plugins.js | 87 +++ site/src/constants/header-links.js | 6 + site/src/constants/mdx-shortcodes.js | 17 + site/src/images/icon.png | Bin 0 -> 28092 bytes site/src/images/logo-black.png | Bin 0 -> 10729 bytes site/src/pages/404.js | 31 + site/src/pages/documentation/index.js | 72 +++ site/src/pages/index.js | 48 ++ site/src/pages/news/index.js | 64 +++ site/src/styles/card.css | 169 ++++++ site/src/styles/fonts.css | 20 + site/src/styles/footer.css | 18 + site/src/styles/global.css | 184 ++++++ site/src/styles/header.css | 49 ++ site/src/styles/hero.css | 55 ++ site/src/styles/prismjs.css | 535 ++++++++++++++++++ site/src/styles/style.css | 145 +++++ site/src/templates/documentation.js | 91 +++ site/src/templates/news.js | 44 ++ site/src/templates/page.js | 38 ++ ...Q2ArtRev_GettyImages-1266548614_2285px.jpg | Bin 0 -> 151385 bytes ...2Q2ArtRev_GettyImages-184873183_2285px.jpg | Bin 0 -> 258368 bytes ...Q4ArtRev_GettyImages-1329571403_2285px.jpg | Bin 0 -> 423198 bytes ...Q4ArtRev_GettyImages-1329807910_2285px.jpg | Bin 0 -> 409678 bytes ...Q4ArtRev_GettyImages-1329808542_2285px.jpg | Bin 0 -> 452037 bytes site/static/images/logo-black.png | Bin 0 -> 10729 bytes site/static/robots.txt | 2 + 68 files changed, 2721 insertions(+) create mode 100644 .github/workflows/site-deploy.yml create mode 100644 .github/workflows/site-pr-build.yml create mode 100644 site/.gitignore create mode 100644 site/.prettierignore create mode 100644 site/.prettierrc create mode 100644 site/.vscode/extensions.json create mode 100644 site/.vscode/settings.json create mode 100644 site/content/alternatives.mdx create mode 100644 site/content/background.mdx create mode 100644 site/content/documentation-hero.mdx create mode 100644 site/content/documentation/intro-doc.mdx create mode 100644 site/content/documentation/message-replaying.mdx create mode 100644 site/content/documentation/rsvp.mdx create mode 100644 site/content/getting-started.mdx create mode 100644 site/content/hero.mdx create mode 100644 site/content/news-hero.mdx create mode 100644 site/content/news/hello-world.mdx create mode 100644 site/content/use-cases.mdx create mode 100644 site/gatsby-browser.js create mode 100644 site/gatsby-config.js create mode 100644 site/gatsby-node.js create mode 100644 site/package.json create mode 100644 site/src/README.md create mode 100644 site/src/components/article.js create mode 100644 site/src/components/button-link.js create mode 100644 site/src/components/card-collection.js create mode 100644 site/src/components/cards/business-details.js create mode 100644 site/src/components/cards/card.js create mode 100644 site/src/components/cards/index.js create mode 100644 site/src/components/cards/person.js create mode 100644 site/src/components/cards/program.js create mode 100644 site/src/components/cards/story.js create mode 100644 site/src/components/cards/theme.js create mode 100644 site/src/components/example-box.js create mode 100644 site/src/components/footer.js create mode 100644 site/src/components/header.js create mode 100644 site/src/components/hero.js create mode 100644 site/src/components/layout.js create mode 100644 site/src/components/page-nav.js create mode 100644 site/src/components/section.js create mode 100644 site/src/components/seo.js create mode 100644 site/src/config/base-gatsby-plugins.js create mode 100644 site/src/constants/header-links.js create mode 100644 site/src/constants/mdx-shortcodes.js create mode 100644 site/src/images/icon.png create mode 100644 site/src/images/logo-black.png create mode 100644 site/src/pages/404.js create mode 100644 site/src/pages/documentation/index.js create mode 100644 site/src/pages/index.js create mode 100644 site/src/pages/news/index.js create mode 100644 site/src/styles/card.css create mode 100644 site/src/styles/fonts.css create mode 100644 site/src/styles/footer.css create mode 100644 site/src/styles/global.css create mode 100644 site/src/styles/header.css create mode 100644 site/src/styles/hero.css create mode 100644 site/src/styles/prismjs.css create mode 100644 site/src/styles/style.css create mode 100644 site/src/templates/documentation.js create mode 100644 site/src/templates/news.js create mode 100644 site/src/templates/page.js create mode 100644 site/static/images/02354_2022Q2ArtRev_GettyImages-1266548614_2285px.jpg create mode 100644 site/static/images/02393_2022Q2ArtRev_GettyImages-184873183_2285px.jpg create mode 100644 site/static/images/02455_2022Q4ArtRev_GettyImages-1329571403_2285px.jpg create mode 100644 site/static/images/02458_2022Q4ArtRev_GettyImages-1329807910_2285px.jpg create mode 100644 site/static/images/02463_2022Q4ArtRev_GettyImages-1329808542_2285px.jpg create mode 100644 site/static/images/logo-black.png create mode 100644 site/static/robots.txt diff --git a/.github/workflows/site-deploy.yml b/.github/workflows/site-deploy.yml new file mode 100644 index 0000000..0efc8e5 --- /dev/null +++ b/.github/workflows/site-deploy.yml @@ -0,0 +1,35 @@ +name: GH Page Deploy + +on: + push: + branches: + - main + +defaults: + run: + working-directory: ./site + +permissions: + contents: write + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + cache-dependency-path: "./site/package-lock.json" + - run: npm ci + - run: npm run build + - name: Deploy + uses: crazy-max/ghaction-github-pages@v4 + with: + target_branch: gh-pages + build_dir: docs + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/site-pr-build.yml b/.github/workflows/site-pr-build.yml new file mode 100644 index 0000000..d5fe8fe --- /dev/null +++ b/.github/workflows/site-pr-build.yml @@ -0,0 +1,25 @@ +name: GH Page PR Build + +on: + pull_request: + branches: + - main + +defaults: + run: + working-directory: ./site + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + cache-dependency-path: "./site/package-lock.json" + - run: npm ci + - run: npm run build \ No newline at end of file diff --git a/site/.gitignore b/site/.gitignore new file mode 100644 index 0000000..f813275 --- /dev/null +++ b/site/.gitignore @@ -0,0 +1,69 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# dotenv environment variable files +.env* + +# gatsby files +.cache/ +public + +# Mac files +.DS_Store + +# Yarn +yarn-error.log +.pnp/ +.pnp.js +# Yarn Integrity file +.yarn-integrity diff --git a/site/.prettierignore b/site/.prettierignore new file mode 100644 index 0000000..58d06c3 --- /dev/null +++ b/site/.prettierignore @@ -0,0 +1,4 @@ +.cache +package.json +package-lock.json +public diff --git a/site/.prettierrc b/site/.prettierrc new file mode 100644 index 0000000..3613635 --- /dev/null +++ b/site/.prettierrc @@ -0,0 +1,7 @@ +{ + "endOfLine": "lf", + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5" +} diff --git a/site/.vscode/extensions.json b/site/.vscode/extensions.json new file mode 100644 index 0000000..abb0d2d --- /dev/null +++ b/site/.vscode/extensions.json @@ -0,0 +1,12 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. + // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp + // List of extensions which should be recommended for users of this workspace. + "recommendations": [ + "dbaeumer.vscode-eslint", + "mquandalle.graphql", + "ecmel.vscode-html-css" + ], + // List of extensions recommended by VS Code that should not be recommended for users of this workspace. + "unwantedRecommendations": [] +} diff --git a/site/.vscode/settings.json b/site/.vscode/settings.json new file mode 100644 index 0000000..2ee7048 --- /dev/null +++ b/site/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "diffEditor.codeLens": true, + "files.trimTrailingWhitespace": true, + "html.format.indentInnerHtml": true, + "html.format.wrapAttributes": "force-aligned", + "eslint.format.enable": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "eslint.validate": ["javascript"], + "editor.formatOnSave": true, + "search.exclude": { + "**/node_modules": true + } +} diff --git a/site/content/alternatives.mdx b/site/content/alternatives.mdx new file mode 100644 index 0000000..9912f73 --- /dev/null +++ b/site/content/alternatives.mdx @@ -0,0 +1,12 @@ +--- +description: List of alternatives and how they differ from this project +title: Alternatives +--- + +List of alternatives to the Message Broker. + +- [BullMQ](https://docs.bullmq.io) + - Relies on Redis +- [@node-ts/bus](https://bus.node-ts.com) + +Both of these alternatives lack the same level of type safety that the Message Broker provides. diff --git a/site/content/background.mdx b/site/content/background.mdx new file mode 100644 index 0000000..ae05a19 --- /dev/null +++ b/site/content/background.mdx @@ -0,0 +1,7 @@ +--- +description: Background and origin story of the Message Broker +title: Background +--- + +This project was written at Morgan Stanley to provide an internal messaging system for large scale UI systems. +The project was later Open Sourced so others could benefit from it. \ No newline at end of file diff --git a/site/content/documentation-hero.mdx b/site/content/documentation-hero.mdx new file mode 100644 index 0000000..c132377 --- /dev/null +++ b/site/content/documentation-hero.mdx @@ -0,0 +1,11 @@ +--- +description: Contribute content hero +title: Hero +--- + + + Open source is more than just code. There is planning before code is written, + the process on how to contribute or release that code, and fostering an + inclusive environment and community. Please review the guidelines below to + learn how to best contribute. + diff --git a/site/content/documentation/intro-doc.mdx b/site/content/documentation/intro-doc.mdx new file mode 100644 index 0000000..dc135a8 --- /dev/null +++ b/site/content/documentation/intro-doc.mdx @@ -0,0 +1,51 @@ +--- +order: 1 +title: Development +--- + +## Prerequisites + +You must use Typescript version: >3.4 + +The library depends on TypeScript's support for decorators. +Therefore you must enable `experimentalDecorators` and `emitDecoratorMetadata`. + +```typescript +{ + "compilerOptions": { + "experimentalDecorators": true, + "emitDecoratorMetadata": true + } +} +``` + +### Polyfills + +This library will work with modern browsers and JavaScript run-times without the need for polyfills, however if targeting older browsers you will need to provide a polyfill for the following types: + +- Map. Read about the Map type [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map). + +This library also makes use of the `reflect-metadata` API for performing runtime introspection. +Most browsers will not support this therefore you must install this yourself. + +```bash +npm install reflect-metadata +``` + +And you should import this module at the root of your application. + +```typescript +import "reflect-metadata"; +``` + +## Quick Start + +import GettingStarted from '../getting-started.mdx'; + + + +## Dependency Injection + +The MessageBroker class is decorated with @Injectable from @morgan-stanley/needle. +This means that it can be constructed by different DI frameworks. +For more information please refer to the [documentation for the Needle framework](https://github.com/morganstanley/needle). \ No newline at end of file diff --git a/site/content/documentation/message-replaying.mdx b/site/content/documentation/message-replaying.mdx new file mode 100644 index 0000000..3d18596 --- /dev/null +++ b/site/content/documentation/message-replaying.mdx @@ -0,0 +1,18 @@ +--- +order: 3 +title: Message Replaying +--- + +Replaying will allow new subscriptions to receive the latest "n" number of messages. Using the messagebroker config the user can configure how many messages they want to be cached when subscriptions are made. Configs can only be provided when the messagebroker channels are created. + +```typescript +import { messagebroker } from "@morgan-stanley/message-broker"; + +messagebroker() + .create('myCachedChannel', { replayCacheSize: 2 }) + .publish({ + payload: 'a message to all new Subscribers!' + }); +``` + +It is important to note that creating a channel with the same name but with different configurations will throw an error. \ No newline at end of file diff --git a/site/content/documentation/rsvp.mdx b/site/content/documentation/rsvp.mdx new file mode 100644 index 0000000..fa4c3a4 --- /dev/null +++ b/site/content/documentation/rsvp.mdx @@ -0,0 +1,67 @@ +--- +order: 4 +title: RSVP +--- + +The RSVP methods allow developers to define a request/response model using the messagebroker. +Unlike a normal publish, publishing on an RSVP channel is a synchronous call that will ask all subscribers to respond with some value. + +An RSVP message must be sent on a special RSVP channel. +In order to create on of those, you should extend the IRSVPConfig interface in your Contract interface, which will require you to specify an `rsvp` section. +In this section, you can provide a channel name as usual, and it must have a `payload` and `response` section in it. + +```typescript +interface IContract extends IRSVPConfig { + nonRSVPChannel : string; + rsvp: { + myRSVPChannel: { + payload: { data: string }; + response: number; + }; + }; +} +``` + +### Publish + +With your contract defined, you can now publish a message. + +Remember, this call will be *synchronous*, so it will block until all the subscribers have completed their work and returned a value. + +When all return values have been gathered, they will be returned by the rsvp method. + +```typescript +const results: number[] = messagebroker() + .rsvp('myRSVPChannel', { data: 'abcde'}); +``` + +### Respond + +Subscribing to an RSVP channel looks much the same as publishing, with the key difference being that the second parameter is a **function** rather than an object. +This function must take a parameter of the type that matches the `payload` type in your contract. +It must then return a value which is of the same type as the `response` type in your contract. + +```typescript +messagebroker() + .rsvp('myRSVPChannel', payload => { + // Perform some work on payload + return len(payload.data); + } +); +``` + +### Respond with manual disconnect + +If for some reason you would like to stop responding to RSVP messages on a certain channel, the `rsvp` function returns a responder handler which has a `disconnect` method on it. +Calling this method will prevent any further messages being received. + +```typescript +const responder = messagebroker() + .rsvp('myRSVPChannel', payload => { + return len(payload.data); + }); + +// Manually disconnect the responder to +// avoid handling further rsvp requests. +responder.disconnect(); +``` diff --git a/site/content/getting-started.mdx b/site/content/getting-started.mdx new file mode 100644 index 0000000..f00ecab --- /dev/null +++ b/site/content/getting-started.mdx @@ -0,0 +1,32 @@ +--- +description: Quick start guide +title: Getting Started +--- + +```bash +npm install @morganstanley/message-broker +``` + +```Typescript +import { + messagebroker, + TypedMessageBroker +} from '@morganstanley/message-broker' + +interface IContracts { + myChannel: { + payload: string + } +} + +const messagebroker: TypedMessageBroker + = messagebroker(); + +messagebroker.get('myChannel').subscribe(message => { + console.log(message.payload) +}); + +messagebroker.create('myChannel').publish({ + payload: 'My first message using the MessageBroker!' +}); +``` diff --git a/site/content/hero.mdx b/site/content/hero.mdx new file mode 100644 index 0000000..faa9bfa --- /dev/null +++ b/site/content/hero.mdx @@ -0,0 +1,9 @@ +--- +description: Featured content hero +title: Hero +--- + + + The Message Broker is a Typescript library which aims to provide asynchronous communication between typescript components. + It leverages the RxJS library to facilitate a pub/sub pattern and accepts user-defined contracts to ensure type safety across messages. + diff --git a/site/content/news-hero.mdx b/site/content/news-hero.mdx new file mode 100644 index 0000000..f5c21a1 --- /dev/null +++ b/site/content/news-hero.mdx @@ -0,0 +1,6 @@ +--- +description: News content hero +title: Hero +--- + +Projects updates and changelogs diff --git a/site/content/news/hello-world.mdx b/site/content/news/hello-world.mdx new file mode 100644 index 0000000..583b8c4 --- /dev/null +++ b/site/content/news/hello-world.mdx @@ -0,0 +1,71 @@ +--- +date: 2023-07-13 +title: A wild branded website template appears! +--- + +hello world + +> this is a blockquote + +```javascript{numberLines: true} +if (node.internal.type === `allMdx`) { + const value = createFilePath({ node, getNode }); + createNodeField({ + name: `slug`, + node, + value, + }); +} +``` + +```jsx +import React from 'react'; + +import Header from './header'; +import Seo from './seo'; + +function Layout({ location, title, children }) { + return ( + <> + +
+
+
+
{children}
+
+
+ Please feel free to contribute via{' '} + + Github + + . +
+
+ + ); +} + +export default Layout; +``` + +```python +import json +from datetime import datetime +from datetime import timedelta +import pandas as pd +import numpy as np +import matplotlib.pyplot as plt +plt.close('all') +plt.xkcd() + +states = pd.read_csv('https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-states.csv') + +us = pd.read_csv('https://raw.githubusercontent.com/nytimes/covid-19-data/master/us.csv') + +us.plot(x='date', y='cases', kind='bar', title='United States Confirmed Cases', figsize=(30,10)) +us.plot(x='date', y='deaths', kind='bar', title='United States Deaths', figsize=(30,10)) +``` diff --git a/site/content/use-cases.mdx b/site/content/use-cases.mdx new file mode 100644 index 0000000..1b9f560 --- /dev/null +++ b/site/content/use-cases.mdx @@ -0,0 +1,22 @@ +--- +description: Description of a simple but comprehensive use case for the + project +title: Use cases +--- + +Here is an example of a usecase in which the Message Broker could be useful. + +#### Notification system + +Let's say you have some document uploading functionality in your UI. +The uploading may take up to a minute and you don't want the user to have to wait, so once the upload is complete you want to have a pop-up notification appear which tells the user that their upload was successful. + +The code for your pop-up notification can live anywhere in your codebase, and can "listen" for a "document_uploaded" message using the MessageBroker. +Now all that needs to happen is for the document upload service to publish that message when the upload completes. + +**Note:** that with this model, our document uploading service doesn't even have to know about the existence of the notification service, so everything is nice and decoupled. + +#### Mediator Pattern + +More generically, the Message Broker essentially acts as a [Mediator](https://refactoring.guru/design-patterns/mediator) for your components. +Any time you would apply the Mediator pattern, the Message Broker is the perfect solution to avoid you some boilerplate coding. diff --git a/site/gatsby-browser.js b/site/gatsby-browser.js new file mode 100644 index 0000000..4ddc826 --- /dev/null +++ b/site/gatsby-browser.js @@ -0,0 +1,8 @@ +import './src/styles/fonts.css'; +import './src/styles/global.css'; +import './src/styles/prismjs.css'; +import './src/styles/style.css'; +import './src/styles/header.css'; +import './src/styles/footer.css'; +import './src/styles/hero.css'; +import './src/styles/card.css'; diff --git a/site/gatsby-config.js b/site/gatsby-config.js new file mode 100644 index 0000000..18fe076 --- /dev/null +++ b/site/gatsby-config.js @@ -0,0 +1,13 @@ +const { plugins } = require('./src/config/base-gatsby-plugins'); + +module.exports = { + siteMetadata: { + title: `Morgan Stanley Open Source Software`, + description: `Morgan Stanley Open Source Software`, + siteUrl: 'http://opensource.morganstanley.com', + documentationUrl: false, + // documentationUrl: url-of.documentation.site, + }, + pathPrefix: `/`, // include subdirectory + plugins, +}; diff --git a/site/gatsby-node.js b/site/gatsby-node.js new file mode 100644 index 0000000..913da4c --- /dev/null +++ b/site/gatsby-node.js @@ -0,0 +1,90 @@ +const path = require(`path`); +const { createFilePath } = require(`gatsby-source-filesystem`); + +exports.createPages = async ({ graphql, actions }) => { + const { createPage } = actions; + + const result = await graphql( + ` + { + allMdx { + nodes { + id + tableOfContents + frontmatter { + date + title + } + internal { + contentFilePath + } + fields { + slug + } + } + } + } + ` + ); + + if (result.errors) { + throw result.errors; + } + + // Create pages. + const pages = result.data.allMdx.nodes; + const newsTemplate = path.resolve(`./src/templates/news.js`); + const documentationTemplate = path.resolve( + `./src/templates/documentation.js` + ); + const pageTemplate = path.resolve(`./src/templates/page.js`); + + function getCategory(page) { + const path = page.internal.contentFilePath; + + return path + ? path.includes('news') + ? 'news' + : path.includes('documentation') + ? 'documentation' + : '' + : ''; + } + + function getTemplate(category) { + return category + ? category.includes('news') + ? newsTemplate + : category.includes('documentation') + ? documentationTemplate + : pageTemplate + : pageTemplate; + } + + pages.forEach((page, index) => { + const category = getCategory(page); + createPage({ + path: page.fields.slug, + component: `${getTemplate(category)}?__contentFilePath=${ + page.internal.contentFilePath + }`, + context: { + id: page.id, + category, + }, + }); + }); +}; + +exports.onCreateNode = ({ node, actions, getNode }) => { + const { createNodeField } = actions; + + if (node.internal.type === `Mdx`) { + const value = createFilePath({ node, getNode }); + createNodeField({ + name: `slug`, + node, + value, + }); + } +}; diff --git a/site/package.json b/site/package.json new file mode 100644 index 0000000..195c5bf --- /dev/null +++ b/site/package.json @@ -0,0 +1,49 @@ +{ + "name": "ms-gh-pages", + "version": "1.0.0", + "private": true, + "description": "ms-gh-pages", + "author": "Morgan Stanley", + "keywords": [ + "gatsby" + ], + "engines": { + "node": "^20.11.0", + "npm": "^10.3.0" + }, + "dependencies": { + "@mdx-js/react": "^2.3.0", + "gatsby": "^5.13.3", + "gatsby-plugin-image": "^3.13.1", + "gatsby-plugin-manifest": "^5.13.1", + "gatsby-plugin-mdx": "^5.13.1", + "gatsby-plugin-react-helmet": "^6.13.1", + "gatsby-plugin-sharp": "^5.13.1", + "gatsby-plugin-sitemap": "^6.13.1", + "gatsby-plugin-webfonts": "^2.3.2", + "gatsby-remark-autolink-headers": "^6.13.1", + "gatsby-remark-copy-linked-files": "^6.13.1", + "gatsby-remark-images": "^7.13.1", + "gatsby-remark-prismjs": "^7.13.1", + "gatsby-remark-responsive-iframe": "^6.13.1", + "gatsby-remark-smartypants": "^6.13.1", + "gatsby-source-filesystem": "^5.13.1", + "gatsby-transformer-sharp": "^5.13.1", + "prismjs": "^1.29.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-helmet": "^6.1.0", + "style-to-object": "^1.0.5" + }, + "scripts": { + "develop": "gatsby develop -H 0.0.0.0", + "start": "gatsby develop -H 0.0.0.0", + "build": "gatsby clean && gatsby build --prefix-paths && npm run pub", + "serve": "gatsby serve", + "pub": "rm -rf ../docs && mv public ../docs", + "clean": "gatsby clean" + }, + "devDependencies": { + "prettier": "^3.2.5" + } + } \ No newline at end of file diff --git a/site/src/README.md b/site/src/README.md new file mode 100644 index 0000000..2228ed0 --- /dev/null +++ b/site/src/README.md @@ -0,0 +1,40 @@ +# Morgan Stanley GitHub Pages Project Template + +## Local Development + +```shell +cd site +npm install +npm run start +``` + +Go to http://localhost:8000 for the development preview of the website and http://localhost:8000/\_\_\_graphql for the Graphql query tool. + +Sample Query to see all Markdown files: + +```graphql +{ + allMdx { + edges { + node { + fields { + slug + } + frontmatter { + description + title + } + } + } + } +} +``` + +## References + +- [Documentation](https://www.gatsbyjs.com/docs/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter-ts) +- [Tutorials](https://www.gatsbyjs.com/docs/tutorial/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter-ts) +- [Guides](https://www.gatsbyjs.com/docs/how-to/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter-ts) +- [API Reference](https://www.gatsbyjs.com/docs/api-reference/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter-ts) +- [Plugin Library](https://www.gatsbyjs.com/plugins?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter-ts) +- [Cheat Sheet](https://www.gatsbyjs.com/docs/cheat-sheet/?utm_source=starter&utm_medium=readme&utm_campaign=minimal-starter-ts) diff --git a/site/src/components/article.js b/site/src/components/article.js new file mode 100644 index 0000000..8f8cf54 --- /dev/null +++ b/site/src/components/article.js @@ -0,0 +1,10 @@ +import React from 'react'; + +export default function Article({ title, children }) { + return ( +
+

{title}

+ {children} +
+ ); +} diff --git a/site/src/components/button-link.js b/site/src/components/button-link.js new file mode 100644 index 0000000..a160b3e --- /dev/null +++ b/site/src/components/button-link.js @@ -0,0 +1,11 @@ +import React from 'react'; + +export default function ButtonLink({ href, text, align, variant = '' }) { + let classnames = align === 'right' ? `button align-right` : `button`; + classnames = variant === 'outlined' ? `${classnames} outlined` : classnames; + return ( + + {text} + + ); +} diff --git a/site/src/components/card-collection.js b/site/src/components/card-collection.js new file mode 100644 index 0000000..8d195db --- /dev/null +++ b/site/src/components/card-collection.js @@ -0,0 +1,21 @@ +import React from 'react'; +import Section from './section'; + +export default function CardCollection({ + title, + description, + color = 'primary', + children, + cols = 1, +}) { + const colorClassnames = `card-collection-container ${color}`; + const classnames = `card-collection card-collection-cols-${cols}`; + return ( +
+ {description || title ? ( +
{description}
+ ) : null} +
{children}
+
+ ); +} diff --git a/site/src/components/cards/business-details.js b/site/src/components/cards/business-details.js new file mode 100644 index 0000000..8793cc4 --- /dev/null +++ b/site/src/components/cards/business-details.js @@ -0,0 +1,7 @@ +import React from 'react'; + +import Card from './card'; + +export default function CardBusinessDetails(props) { + return ; +} diff --git a/site/src/components/cards/card.js b/site/src/components/cards/card.js new file mode 100644 index 0000000..698b9c1 --- /dev/null +++ b/site/src/components/cards/card.js @@ -0,0 +1,38 @@ +import React from 'react'; + +export default function Card({ + category, + title, + image, + color, + children, + link, + type = 'card-base', +}) { + const cardClassNames = `card ${type}`; + const eyebrowClassNames = `eyebrow ${color ? color : ''}`; + return ( +
+
+ {image ? ( +
+ {link ? ( + + {title} + + ) : ( + {title} + )} +
+ ) : ( + '' + )} +
+
{category}
+
+

{link ? {title} : title}

+ {children} +
+
+ ); +} diff --git a/site/src/components/cards/index.js b/site/src/components/cards/index.js new file mode 100644 index 0000000..52a0313 --- /dev/null +++ b/site/src/components/cards/index.js @@ -0,0 +1,15 @@ +import Card from './card'; +import CardBusinessDetails from './business-details'; +import CardPerson from './person'; +import CardProgram from './program'; +import CardStory from './story'; +import CardTheme from './theme'; + +export { + Card, + CardBusinessDetails, + CardPerson, + CardProgram, + CardStory, + CardTheme, +}; diff --git a/site/src/components/cards/person.js b/site/src/components/cards/person.js new file mode 100644 index 0000000..bf8300f --- /dev/null +++ b/site/src/components/cards/person.js @@ -0,0 +1,11 @@ +import React from 'react'; + +import Card from './card'; + +export default function Person({ children, ...rest }) { + return ( + +
{children}
+
+ ); +} diff --git a/site/src/components/cards/program.js b/site/src/components/cards/program.js new file mode 100644 index 0000000..32a8ffe --- /dev/null +++ b/site/src/components/cards/program.js @@ -0,0 +1,11 @@ +import React from 'react'; + +import Card from './card'; + +export default function CardProgram({ image, children, ...rest }) { + return ( + +
{children}
+
+ ); +} diff --git a/site/src/components/cards/story.js b/site/src/components/cards/story.js new file mode 100644 index 0000000..874bcee --- /dev/null +++ b/site/src/components/cards/story.js @@ -0,0 +1,7 @@ +import React from 'react'; + +import Card from './card'; + +export default function CardStory({ children, ...rest }) { + return ; +} diff --git a/site/src/components/cards/theme.js b/site/src/components/cards/theme.js new file mode 100644 index 0000000..386f698 --- /dev/null +++ b/site/src/components/cards/theme.js @@ -0,0 +1,7 @@ +import React from 'react'; + +import Card from './card'; + +export default function CardTheme({ children, ...rest }) { + return ; +} diff --git a/site/src/components/example-box.js b/site/src/components/example-box.js new file mode 100644 index 0000000..4def06a --- /dev/null +++ b/site/src/components/example-box.js @@ -0,0 +1,5 @@ +import React from 'react'; + +export default function Example({ children }) { + return
{children}
; +} diff --git a/site/src/components/footer.js b/site/src/components/footer.js new file mode 100644 index 0000000..6de98e2 --- /dev/null +++ b/site/src/components/footer.js @@ -0,0 +1,33 @@ +import React from 'react'; + +export default function Footer() { + const date = new Date(); + return ( + + ); +} diff --git a/site/src/components/header.js b/site/src/components/header.js new file mode 100644 index 0000000..4809e6c --- /dev/null +++ b/site/src/components/header.js @@ -0,0 +1,38 @@ +import React from 'react'; +import { Link } from 'gatsby'; +import { StaticImage } from 'gatsby-plugin-image'; + +const Header = ({ location, links }) => { + function menuLink(text) { + const path = links[text]; + const classname = location.pathname?.includes(path) + ? 'nav-link-current' + : 'nav-link'; + + return ( +
  • + {text} +
  • + ); + } + + return ( +
    +

    + + + +

    +
    +
      {Object.keys(links).map(menuLink)}
    +
    +
    + ); +}; + +export default Header; diff --git a/site/src/components/hero.js b/site/src/components/hero.js new file mode 100644 index 0000000..222dd96 --- /dev/null +++ b/site/src/components/hero.js @@ -0,0 +1,14 @@ +import React from 'react'; + +function Hero({ title, children }) { + return ( +
    +

    {title}

    +
    +
    {children}
    +
    +
    + ); +} + +export default Hero; diff --git a/site/src/components/layout.js b/site/src/components/layout.js new file mode 100644 index 0000000..95db17c --- /dev/null +++ b/site/src/components/layout.js @@ -0,0 +1,32 @@ +import React from 'react'; +import { MDXProvider } from '@mdx-js/react'; + +import { HeaderLinks } from '../constants/header-links'; +import { ShortCodes } from '../constants/mdx-shortcodes'; + +import Header from './header'; +import Footer from './footer'; +import Seo from './seo'; + +function Layout({ data, location, children }) { + const { documentationUrl, title } = data.site.siteMetadata; + + if (documentationUrl) { + HeaderLinks.Documentation = documentationUrl; + } + + return ( + <> + +
    +
    +
    +
    + {children} +
    +