jpmorganchase / mosaic Goto Github PK
View Code? Open in Web Editor NEWhttps://mosaic-mosaic-dev-team.vercel.app
Home Page: https://mosaic-mosaic-dev-team.vercel.app
License: Apache License 2.0
https://mosaic-mosaic-dev-team.vercel.app
Home Page: https://mosaic-mosaic-dev-team.vercel.app
License: Apache License 2.0
Document how each of the 3 existing Mosaic Sources can be configured and used.
Show how the Mosaic CLI can be used to add a source to the mosaic config
Examples
The Sidebar and TOC are scrolled when the page scrolls. On long pages this results in them being off screen and unusable e.g. this page --> https://mosaic-mosaic-dev-team.vercel.app/mosaic/quick-start/publish-site-to-aws
Another consequence of this is the TOC highlight to indicate what section you are on is broken.
If you click on a tab in the app header, and then click on a child page in the sidebar, the tab in the header is no longer highlighted.
With plugin errors no longer closing sources it would be good to find a way to surface plugin errors to the site somehow.
Perhaps a mosaic dev tools à la https://tanstack.com/query/v4/docs/react/devtools
Perhaps a new middleware
Perhaps we write a plugins-report.json
file into the Mosaic global filesystem.
Right now, the plugin errors are grouped by source. But this isn't something a regular user would know about. It would be more intuitive to show all plugin errors for a namespace (which may contain multiple sources). The SourceManager
should be able to handle this.
At present, when there is an error thrown by a source, the source is closed.
Now that schedules have been implemented we can add in source retries.
Extend the schedule schema to introduce retry config:
A few accessibility issues with the TOC component:
<p>
when the should be <a>
When you give a page an alias, the alias works fine and the page content etc is visible. However, the app header content is removed so it looks empty.
I think it might be related to the shared config being lost somehow
At present, frontmatter in pages can be referenced using a ref or tag.
It would be good if you could also reference content on pages.
getSection('heading-name')
, getContentBlock('name')
When generating a snapshot or serving certain sets of docs, the following error is sometimes thrown:
"TypeError: Cannot read properties of undefined (reading 'childNodes')".
We are beginning to add code examples to the mosaic docs now and these examples would be much clearer if the markdown and rendered preview were accessible on the page.
The new React doc use sandpack for this so that might be a good starting point.
Errors generated by plugins result in sources being closed.
This presents a problem whereby an issue on 1 page will destroy the source and therefore all pages that are OK are unavailable. To the user of a mosaic site you will see the 404 page everywhere.
We should attempt to handle this better so that broken pages are 404s (or show the error) but good pages are still available.
Given 2 index pages with shared config, 1 of which is in a parent directory of the other, then the child shared config should be merged with the parent.
This is best illustrated by the fact that most pages define a sharedConfig for header/footer info on the site root index file. Without merging, any other index page that specifies a shared config will override the root shared config. This removes heading links etc which is not great.
A workflow should execute in it's own worker thread to prevent any issues serving pages
If 2 or more sources use the same repo then there is an error thrown when cloning:
[Mosaic] Source Error: Command 'git clone <repo url> --no-checkout --origin=origin' failed: 128. fatal: destination path '<repo project-name>' already exists and is not an empty directory.
Basically, this is a timing issue at heart.
We have logic that checks for a previous clone but it does not work across sources. A git source is only aware of what it has done.
Schedule the sources to start with different delays. Delayed sources won't attempt a clone and will re-use the earlier cloned repo.
Refs and Aliases are powerful features of mosaic that can be used by content authors. The ref and alias plugins are always included in the mosaic config due to the key role they play.
Document and provide examples on how a content author can make use of them.
The Mosaic packages require a more thorough test plan in order to have confidence in the tool.
As part of this issue it would be good to begin the process (ordered by priority)
Document each of the Mosaic Plugins and describe the role of plugins in Mosaic architecture.
Overview
Per Plugin
How to configure them?
What features to they provide?
What frontmatter is used/added/updated by the plugin
Currently, font loading is working via a custom Document with link
elements being injected into the head https://github.com/jpmorganchase/mosaic/blob/main/packages/site-components/src/Document.tsx
This affects the initial paint time and slows down the site loading. Ideally, Mosaic should rely on next/font here, e.g. jpmorganchase/salt-ds#1509
When using the Fragment or PropsTable Plugins, a \
is being added to the beginning of lines that have components on them. This causes an MDX compilation failure and the page doesn't load.
Issue first observed in this PR --> jpmorganchase/salt-ds#1889
Both of these plugins make use of remark to process the page content so that could be the source...
After this commit: 6511d7c generating snapshots doesn't work with mosaic and failed with:
@jpmorganchase/mosaic-site:serve: 8080 Error resolving ref(s) for page '/mosaic/author/aliases.mdx'. Error reading file "d:/mosaic/author/" in 'd:/mosaic/author/'
@jpmorganchase/mosaic-site:serve: 8080 Error: Error: Error: Plugin 'D:\Work\mosaic\packages\plugins\dist\$RefPlugin.js' threw an exception running `$beforeSend`. See below:
@jpmorganchase/mosaic-site:serve: 8080 JSONParserError: Error reading file "d:/mosaic/author/"
@jpmorganchase/mosaic-site:serve: 8080 at D:\Work\mosaic\node_modules\@apidevtools\json-schema-ref-parser\dist\lib\parse.js:109:23
@jpmorganchase/mosaic-site:serve: 8080 at Generator.throw (<anonymous>)
@jpmorganchase/mosaic-site:serve: 8080 at rejected (D:\Work\mosaic\node_modules\@apidevtools\json-schema-ref-parser\dist\lib\parse.js:29:65)
@jpmorganchase/mosaic-site:serve: 8080 at runNextTicks (node:internal/process/task_queues:60:5)
@jpmorganchase/mosaic-site:serve: 8080 at process.processImmediate (node:internal/timers:447:9)
@jpmorganchase/mosaic-site:serve: 8080 at Object.$beforeSend (file:///D:/Work/mosaic/packages/core/dist/plugin/index.js:66:23)
@jpmorganchase/mosaic-site:serve: 8080 at runNextTicks (node:internal/process/task_queues:60:5)
@jpmorganchase/mosaic-site:serve: 8080 at process.processImmediate (node:internal/timers:447:9)
@jpmorganchase/mosaic-site:serve: 8080 at async file:///D:/Work/mosaic/packages/core/dist/worker/Source.worker.js:38:9
@jpmorganchase/mosaic-site:serve: 8080 Error: [Mosaic] Source 'site#c05241dc' threw an exception. See below:
@jpmorganchase/mosaic-site:serve: 8080 at EventEmitter.<anonymous> (file:///D:/Work/mosaic/packages/core/dist/PullDocs.js:81:27)
@jpmorganchase/mosaic-site:serve: 8080 at Object.onceWrapper (node:events:629:26)
@jpmorganchase/mosaic-site:serve: 8080 at EventEmitter.emit (node:events:526:35)
@jpmorganchase/mosaic-site:serve: 8080 at file:///D:/Work/mosaic/packages/core/dist/Source.js:124:57
@jpmorganchase/mosaic-site:serve: 8080 at EventEmitter.autoUnsubscribeHandler (file:///D:/Work/mosaic/packages/core/dist/WorkerSubscription.js:34:13)
@jpmorganchase/mosaic-site:serve: 8080 at EventEmitter.emit (node:events:514:28)
@jpmorganchase/mosaic-site:serve: 8080 at #onError [as error] (file:///D:/Work/mosaic/packages/core/dist/WorkerSubscription.js:61:23)
@jpmorganchase/mosaic-site:serve: 8080 at ConsumerObserver.error (D:\Work\mosaic\node_modules\rxjs\dist\cjs\internal\Subscriber.js:124:33)
@jpmorganchase/mosaic-site:serve: 8080 at Subscriber._error (D:\Work\mosaic\node_modules\rxjs\dist\cjs\internal\Subscriber.js:84:30)
@jpmorganchase/mosaic-site:serve: 8080 at Subscriber.error (D:\Work\mosaic\node_modules\rxjs\dist\cjs\internal\Subscriber.js:60:18)
@jpmorganchase/mosaic-site:serve: 8080 [Mosaic] Source 'site#c05241dc' closed
Some content may need to be protected or differ depending on the role of the logged in user.
TODO: add more detail
Create a source that can pull in data generated by typedoc
Markdown plugin -- https://github.com/tgreyuk/typedoc-plugin-markdown/tree/master/packages/typedoc-plugin-markdown#readme
Currently if you use the FragmentPlugin and the fragment page has references to metadata, such as {meta.data.title}
it will show the host page's title. This should be changed so that it references the metadata from the fragment page. Currently we would just advise that fragments do not contain such references.
Example:
If you edit have a host page referencing a content-fragment.mdx
page that looks like:
---
title: Content Fragment
---
#### {meta.title}
You should see the title of that section on the host page be Content Fragment
but what you get is the host page's title.
One for a follow up
Originally posted by @DavieReid in #354 (comment)
Currently, where a directory contains an index.mdx
file, Mosaic will ensure that the corresponding URL ends in index
. For example:
foo/bar/index.mdx
https://example.com/foo/bar/index
Requests to the URL https://example.com/foo/bar
will be redirected to the corresponding https://example.com/foo/bar/index
URL.
It would be nice if there was an option to change the behaviour so that it becomes:
foo/bar/index.mdx
https://example.com/foo/bar
https://example.com/foo/bar/index
would be a permanent redirect to https://example.com/foo/bar
This is the behaviour we would like for the Salt site as:
index.md|html|whatever
files tend to be served up at URLs whose path omits the index
part.I suggest that this becomes an opt-in option though (perhaps via mosaic.config.js
?), so that other Mosaic-based sites don't suddenly have all their URLs change upon upgrading.
Note that the non-index-suffixed URLs would also need to be reflected in any auto-generated links for site navigation, breadcrumbs, etc.
Given this source:
{
// disabled: process.env.NODE_ENV !== 'development',
modulePath: '@jpmorganchase/mosaic-source-local-folder',
namespace: 'mosaic', // each site has it's own namespace, think of this as your content's uid
options: {
rootDir: '../../docs', // relative path to content
prefixDir: 'mosaic', // root path used for namespace
extensions: ['.mdx'] // extensions of content which should be pulled
}
}
it should work without the prefixDir
option.
When using the InsertLink functionality of the content editor plugin, the Dialog closes when clicking into the link edit form
Mosaic uses MDX2 to create documents and has support for github flavoured markdown.
Provide a detailed example of how to author a page using MDX and showcase what mosaic components can be used.
Full component documentation will follow at a later date so for now it is sufficient to document the most commonly used components e.g. callout, tile
When deploying a mosaic site and snapshot to vercel, the snapshot directory is not included in the code deployed to serverless functions.
This results in the site showing the 404 page for all content and the following is displayed in the vercel logs
ENOENT: no such file or directory, realpath '/var/task/<site-name>/public/snapshots/latest/<page-name>.mdx'
After investigation, it appears that unless a file is somehow included in the source code, as described here then vercel will not include those files in the build output.
The site middleware package includes code that resolves the files when using snapshot mode.
Breadcrumbs are a feature that need to have a holistic view of the site pages in order for the breadcrumbs to be generated successfully.
Consider:
/home/products
The breadcrumbs of Source B correctly have breadcrumbs home > products > product
The breadcrumbs of Source B only have product
Breadcrumbs are created in the $afterSource
lifecycle event at which point the plugin does not have visibility of the global filesystem.
The frame can be thought of the components that side around the main page content. The furniture so to speak. For Mosaic this includes:
It is set in the frontmatter of a page using the layout
field. If no layout is provided then the FullWidth
layout is used by default.
The table below details he existing layouts and what frame components they use.
Layout Name | Header | Footer | Sidebar | TOC | Breadcrumbs | Doc Paginator | Full Width Content (max width is 1440px) |
---|---|---|---|---|---|---|---|
DetailContentOnly | ✅ | ✅ | 🚫 | 🚫 | ✅ | 🚫 | ✅ |
DetailHighlight | ✅ | ✅ | 🚫 | ✅ | ✅ | 🚫 | 🚫 |
DetailOverview | ✅ | ✅ | ✅ | 🚫 | ✅ | ✅ | 🚫 |
DetailTechnical | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 🚫 |
Edit | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ✅ |
FullWidth | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | ✅ |
Landing | ✅ | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | ✅ |
Newsletter | ✅ | ✅ | ✅ | 🚫 | 🚫 | ✅ | 🚫 |
ProductDiscover | ✅ | ✅ | 🚫 | 🚫 | ✅ | 🚫 | ✅ |
ProductPreview | ✅ | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | ✅ |
DetailContentOnly
layout.Edit
/FulllWidth
/Landing
are very similar.ProductDiscover
and DetailContentOnly
are identical.ProductPreview
and Landing
are identical.Build in the Header component into the Base Layout. It is always needed and I can't see a design that wouldn't have the header in it. This simplifies the logic for all layouts.
Instead of stating the name of the layout in the frontmatter, you can choose to enable/disable frame components. This gives users flexibility to show/hide the frame components at will.
---
title: A Title
description: A description
frame:
footer: true
sidebar: true
toc: true
breadcrumbs: true
paginator: true
---
If you choose to have sidebar:false
and toc:false
then the page content is full width.
There is no option to disable a header.
ProductDiscover
and ProductPreview
layout.This is likely to be a massive refactor.
We would want to do this to take advantage of the speed improvements associated with React Server Components. The app dir is also the general direction next js is moving and we should look to align. See the roadmap.
Off the top of my head the areas this is likely to touch are:
Create a new Quick Start Guide for creating a new mosaic site.
Probably best to create a new generator that does not add mosaic specific sources but instead adds some sample docs.
yarn v1
Node v 16+
yarn init
- to create a package.jsonyarn add @jpmorganchase/mosaic-create-site
-Wyarn mosaic-create-site init
yarn mosaic-create-site create -i -o site
cd site
yarn build
yarn serve
When adding to an existing monorepo as a new site package, had to run prettier on the generated site.
When using a git repo source, the repo is cloned and a worktree created for the branch specified by the source in the mosaic config file.
Now lets say you create a new branch in git and update the mosaic config file so that the source uses this new branch. When you spin up mosaic, it will attempt to reuse the previous clone and create a worktree for the new branch.
But the previous clone has no knowledge of the new branch as we did not do a fetch. This breaks the source as the worktree creation fails.
This may only be an issue that manifests when developing locally and using git repos as sources.
The workaround is to remove the .tmp
directory so that the clone is removed and the repo cloned again on next start-up.
We should do a fetch even when reusing a cloned repo so that we have the latest info about the repo.
We currently use Prism for code highlighting. It doesn't seem to work very well and I have heard a lot about Shiki recently that is supposed to be better.
I think this rehype plugin would do the job rehype-pretty-code
There are a few instances when you may want to flag a source as disabled, to prevent mosaic from loading docs from that source. You can do this with a namespace but it's a little unintuitive and may have routing implications.
When you navigate to a section on a page and that page is using the Table of Contents (TOC) component the following happens:
Mosaic generates a sitemap.xml plugin using the SiteMapPlugin.
However, when you try to access the sitemap you get an error saying Unsupported file type
The width of the content, vertical nav and TOC changes between pages.
As part of moving DP Mosaic design language to Salt DS, I'm categorising components that currently being used on DP Mosaic into 3parts.
1. Using Salt component : The component replaced to Salt component. Ex) Button, layout, icon, link, Tooltip
2. Mosaic specific component: The component designed for DP Mosaic using Salt DS.(Currently based on Mosaic Design language but will update it to Salt DS) Ex) Audio, video player, Accordion, callout, card, feature.. and so on
3. To be replaced to salt component: The component building in progress in Salt team. Currently using Mosaic component on the site, to be replaced to Salt component once it’s built. Ex) App header, Nav item, Tabs, List…
Our goal would be replace the DP Mosaic components to Salt DS components and keep Salt DS foundation styles include typography, color, and shadow.
For the components that designed only specific for DP Mosaic, also will be based on Salt DS, there won’t be DP Mosaic specific styles or specs.
All the related information will be documented on this Figma file
Currently Type ramp update and component categorising in progress.
ACTUAL RESULTS
When creating a 1 page (or more) file-system containing just an index.mdx
, you have to specify
frameOverrides:
header:
(or equivalent) to ensure a sharedConfig
file exists.
Without this entry, then you get 404
errors.
EXPECTED RESULTS
A 404 error is not thrown.
If no sharedConfig
is defined then it's not an error.
As part of fixing this error we should understand what the minimum frontmatter for a page is.
In theory it could be
---
---
Use https://arethetypeswrong.github.io/ to verify that we are shipping the correct package.json
config to ensure types are configured correctly.
We only support node 18 and ESM so any result for CJS or older node versions is irrelevant.
On initial page load, images and icons on the page are huge and take up a significant portion of the page.
It appears Salt styling is not applied to the SSR'd page and so when it first loads, prior to salt styles loading on the client, we have giant images/icons.
The table of contents should indent headings depending on the level to make the page hierarchy clear to users.
A request to an unknown targetDir causes `mosaic serve` to exit with `Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client`.
We should probably log the error out like [PULLDOCS] ${targetDir} not found...etc
Originally posted by @tambo in #33 (comment)
We noticed on the Salt site, that the sitemap.xml
files generated by Mosaic are incorrect (jpmorganchase/salt-ds#1559):
The sitemap.xml
files generated by Mosaic are incorrect. The contents of <loc>
needs to be the full URL to the page (see https://www.sitemaps.org/protocol.html), but instead seems to have the path to the source MDX file.
Check the sitemap.xml
file being generated by Mosaic. For example, visit https://www.saltdesignsystem.com/sitemap.xml
The contents of sitemap.xml
should conform to the specification.
Remote sources that pull content need to do so on a schedule. It would be good to:
The git source has onCommitChange
function has a default sync but no real way to override this from the plugin options.
The http source has a checkInterval option https://github.com/jpmorganchase/mosaic/blob/main/packages/source-http/src/index.ts#L9
The OpenApiComponent renders the react-swagger component without any styling.
I suspect the root cause is the fact that esbuild is told to exclude node_modules when bundling the open API component
https://github.com/jpmorganchase/mosaic/blob/main/scripts/bundle.js#L36
The package.json
file also mentions a dist/index.css
file which is incorrect. Should be dist/styles.css
.
Adding the following CSS import to _app.tsx
will apply swagger styling
import '@jpmorganchase/mosaic-open-api-component/index.css';
Add the following CSS import to _app.tsx
import 'swagger-ui-react/swagger-ui.css';
It is important for content authors to have an understanding of:
When viewing a page with a Table of Contents visible in the right sidebar, clicking on an item should highlight that item.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.