mirror of
https://github.com/quay/quay.git
synced 2025-04-16 23:03:13 +03:00
ui: render modelcard markdown tables (PROJQUAY-8680) (#3708)
* ui: render modelcard markdown tables (PROJQUAY-8680) * ui: oembed to render embeded video in markdown (PROJQUAY-8679) * ui: render tables and embeded links in markdown (PROJQUAY-8673) * Github linked videos and Patternfly code block * Limit img source to github and huggingface
This commit is contained in:
parent
a6713a669d
commit
1af42c0b5a
3437
web/package-lock.json
generated
3437
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -27,12 +27,15 @@
|
||||
"null-loader": "^4.0.1",
|
||||
"process": "^0.11.10",
|
||||
"react": "^17.0.2",
|
||||
"react-remark": "^2.1.0",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-router-dom": "^6.15.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"recoil": "^0.7.7",
|
||||
"recoil-persist": "^4.2.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"rehype-video": "^2.3.0",
|
||||
"remark-gemoji": "^8.0.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"ts-jest": "^29.1.1",
|
||||
"typescript": "^4.6.3",
|
||||
"use-react-router-breadcrumbs": "^4.0.1",
|
||||
|
@ -1,14 +1,110 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
CodeBlock,
|
||||
CodeBlockAction,
|
||||
CodeBlockCode,
|
||||
ClipboardCopyButton,
|
||||
} from '@patternfly/react-core';
|
||||
import {PageSection, Divider, TextContent} from '@patternfly/react-core';
|
||||
import {Table, Caption, Th, Td} from '@patternfly/react-table';
|
||||
|
||||
import {Remark} from 'react-remark';
|
||||
import Markdown from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import rehypeRaw from 'rehype-raw';
|
||||
import rehypeVideo from 'rehype-video';
|
||||
|
||||
export const MarkdownCodeBlock: React.FunctionComponent = (props) => {
|
||||
const [copied, setCopied] = React.useState(false);
|
||||
|
||||
const clipboardCopyFunc = (event, text) => {
|
||||
navigator.clipboard.writeText(text.toString());
|
||||
};
|
||||
|
||||
const onClick = (event, text) => {
|
||||
clipboardCopyFunc(event, text);
|
||||
setCopied(true);
|
||||
};
|
||||
|
||||
const actions = (
|
||||
<React.Fragment>
|
||||
<CodeBlockAction>
|
||||
<ClipboardCopyButton
|
||||
id="basic-copy-button"
|
||||
textId="code-content"
|
||||
aria-label="Copy to clipboard"
|
||||
onClick={(e) => onClick(e, props.code)}
|
||||
exitDelay={copied ? 1500 : 600}
|
||||
maxWidth="110px"
|
||||
variant="plain"
|
||||
onTooltipHidden={() => setCopied(false)}
|
||||
>
|
||||
{copied ? 'Successfully copied to clipboard!' : 'Copy to clipboard'}
|
||||
</ClipboardCopyButton>
|
||||
</CodeBlockAction>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
return (
|
||||
<CodeBlock actions={actions}>
|
||||
<CodeBlockCode id="code-content">{props.code}</CodeBlockCode>
|
||||
</CodeBlock>
|
||||
);
|
||||
};
|
||||
|
||||
export function ModelCard(props: ModelCardProps) {
|
||||
const modelcard = props.modelCard;
|
||||
const isValidImgSrc = (src) =>
|
||||
src &&
|
||||
(src.startsWith('https://github.com/') ||
|
||||
src.startsWith('https://huggingface.co/'));
|
||||
|
||||
return (
|
||||
<>
|
||||
<Divider />
|
||||
<PageSection>
|
||||
<TextContent>
|
||||
<Remark>{props.modelCard}</Remark>
|
||||
<Markdown
|
||||
remarkPlugins={[remarkGfm]}
|
||||
rehypePlugins={[
|
||||
[rehypeRaw],
|
||||
[
|
||||
rehypeVideo,
|
||||
{
|
||||
test: new RegExp(
|
||||
'(.*)(githubusercontent.com|github.com|huggingface.co)(.*)(.mp4|.mov)$',
|
||||
),
|
||||
},
|
||||
],
|
||||
]}
|
||||
components={{
|
||||
code({node, inline, className, children, ...props}) {
|
||||
return <MarkdownCodeBlock code={children} />;
|
||||
},
|
||||
table: ({children}) => (
|
||||
<Table borders={true} variant={'compact'}>
|
||||
{children}
|
||||
</Table>
|
||||
),
|
||||
caption: 'Caption',
|
||||
th: ({children}) => (
|
||||
<Th style={{border: '1px solid black', padding: '8px'}}>
|
||||
{children}
|
||||
</Th>
|
||||
),
|
||||
td: ({children}) => (
|
||||
<Td style={{border: '1px solid black', padding: '8px'}}>
|
||||
{children}
|
||||
</Td>
|
||||
),
|
||||
img: ({src, alt}) =>
|
||||
isValidImgSrc(src) ? (
|
||||
<img src={src} alt={alt} style={{maxWidth: '100%'}} />
|
||||
) : null,
|
||||
iframe: () => null,
|
||||
}}
|
||||
>
|
||||
{modelcard}
|
||||
</Markdown>
|
||||
</TextContent>
|
||||
</PageSection>
|
||||
</>
|
||||
|
@ -160,6 +160,10 @@ module.exports = (env) => {
|
||||
],
|
||||
symlinks: false,
|
||||
cacheWithContext: false,
|
||||
alias: {
|
||||
'react/jsx-dev-runtime': 'react/jsx-dev-runtime.js',
|
||||
'react/jsx-runtime': 'react/jsx-runtime.js',
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user