Skip to content

Commit

Permalink
Adds readme and yaml on details page
Browse files Browse the repository at this point in the history
  - This patch adds:
       - Implementation of readme and yaml on details page by making
         api calls to github using raw url of the resource
       - Renders readme and yaml using `react-markdown` and `syantax-highlighter`

Signed-off-by: Puneet Punamiya <[email protected]>
  • Loading branch information
PuneetPunamiya committed Dec 21, 2020
1 parent 26f214c commit f213b78
Show file tree
Hide file tree
Showing 22 changed files with 2,311 additions and 320 deletions.
458 changes: 458 additions & 0 deletions ui/package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@types/node": "^12.12.54",
"@types/react-dom": "^16.9.8",
"@types/react-router-dom": "^5.1.6",
"@types/react-syntax-highlighter": "^13.5.0",
"@types/react-test-renderer": "^16.9.3",
"axios": "^0.19.2",
"fuzzysort": "^1.1.4",
Expand All @@ -25,8 +26,10 @@
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-github-login": "^1.0.3",
"react-markdown": "^5.0.3",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.3",
"react-syntax-highlighter": "^15.3.1",
"typescript": "^3.7.5"
},
"scripts": {
Expand Down
20 changes: 20 additions & 0 deletions ui/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export interface Api {
resourceVersion(resourceId: number): Promise<IVersion>;
versionUpdate(versionId: number): Promise<IVersion>;
authentication(authCode: string): Promise<AuthResponse>;
readme(rawURL: string): Promise<string>;
yaml(rawURL: string): Promise<string>;
}

export class Hub implements Api {
Expand Down Expand Up @@ -70,4 +72,22 @@ export class Hub implements Api {
return err.response;
}
}

async readme(rawURL: string) {
try {
const URL = rawURL.substring(0, rawURL.lastIndexOf('/') + 1);
return axios.get(`${URL}/README.md`).then((response) => response.data);
} catch (err) {
return err.response;
}
}

async yaml(rawURL: string) {
try {
const newLine = '\n';
return axios.get(`${rawURL}`).then((response) => '```yaml' + newLine + response.data);
} catch (err) {
return err.response;
}
}
}
22 changes: 22 additions & 0 deletions ui/src/api/testutil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,26 @@ export class FakeHub implements Api {
setTimeout(() => resolve(ret()), 1000);
});
}

async readme(rawURL: string) {
const splitRawUrl = rawURL.split('/');
const resourceName = splitRawUrl[splitRawUrl.length - 3];
const data = `${this.dataDir}/${resourceName}-Readme.md`;

const ret = () => fs.readFileSync(data).toString();
return new Promise<string>((resolve) => {
setTimeout(() => resolve(ret()), 1000);
});
}

async yaml(rawURL: string) {
const splitRawUrl = rawURL.split('/');
const resourceName = splitRawUrl[splitRawUrl.length - 3];
const data = `${this.dataDir}/${resourceName}.yaml`;

const ret = () => fs.readFileSync(data).toString();
return new Promise<string>((resolve) => {
setTimeout(() => resolve(ret()), 1000);
});
}
}
79 changes: 79 additions & 0 deletions ui/src/components/Description/Description.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
.hub-description {
max-width: 90em;
margin: auto;
margin-top: 2em;
}

.hub-description-header {
padding-top: 2em;
}

.hub-tabs {
width: 90em;
background: white;
}

.hub-horizontal-line {
background-color: #ededed;
margin-bottom: 1em;
}

.hub-readme > h2:first-child,
.hub-readme > h1:first-child {
font-weight: bold;
font-size: 1.3em;
padding-bottom: 0.5em;
}

.hub-readme > h2,
h3 {
font-weight: bold;
padding-top: 1em;
padding-bottom: 0.5em;
}

.hub-readme > h2:first-child {
padding-top: 0em;
padding-bottom: 0.5em;
}
.hub-readme > ul {
list-style-type: disc;
padding-left: 2em;
}
.hub-readme > ol {
padding-left: 2em;
font-family: Helvetica;
padding-bottom: 0.5em;
}
.hub-readme > ul > li {
padding-bottom: 0.5em;
}
.hub-readme > p {
padding-bottom: 0.5em;
}
.hub-readme {
font-family: Helvetica;
}

code {
font-family: Consolas, 'courier new';
font-weight: bold;
color: crimson;
padding: 2px;
font-size: 100%;
}

.a > code {
background-color: #f1f1f1;
padding: 2px;
font-size: 90%;
}

.hub-details-spinner {
position: fixed;
left: 0;
right: 0;
top: 2em;
bottom: 0;
margin: auto;
}
45 changes: 45 additions & 0 deletions ui/src/components/Description/Description.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import { mount } from 'enzyme';
import { when } from 'mobx';
import ReactMarkDown from 'react-markdown';
import { FakeHub } from '../../api/testutil';
import { createProviderAndStore } from '../../store/root';
import Description from '.';

const TESTDATA_DIR = `src/store/testdata`;
const api = new FakeHub(TESTDATA_DIR);
const { Provider, root } = createProviderAndStore(api);

describe('Resource Readme and Yaml', () => {
it('render readme and yaml', (done) => {
const { resources } = root;
when(
() => {
return !resources.isLoading;
},
() => {
resources.loadReadme('buildah');
resources.loadYaml('buildah');
when(
() => {
return !resources.isLoading;
},
() => {
setTimeout(() => {
const component = mount(
<Provider>
<Description name="buildah" />
</Provider>
);
component.update();

expect(component.find(ReactMarkDown).length).toBe(2);

done();
}, 1000);
}
);
}
);
});
});
65 changes: 65 additions & 0 deletions ui/src/components/Description/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React, { ReactText } from 'react';
import { useObserver } from 'mobx-react';
import ReactMarkDown from 'react-markdown';
import { Grid, Card, Tabs, Tab, GridItem, CardHeader, Spinner } from '@patternfly/react-core';
import { useMst } from '../../store/root';
import Readme from '../Readme';
import Yaml from '../Yaml';
import './Description.css';

interface Props {
name: string;
}

const Description: React.FC<Props> = (props) => {
const { resources } = useMst();

const [activeTabKey, setActiveTabKey] = React.useState(0);
const handleTabClick = (_: React.MouseEvent<HTMLElement, MouseEvent>, tabIndex: ReactText) => {
setActiveTabKey(Number(tabIndex));
};

const resource = resources.resources.get(props.name);

return useObserver(() =>
resource.readme === '' || resource.yaml === '' ? (
<Spinner className="hub-details-spinner" />
) : (
<React.Fragment>
<Grid className="hub-description">
<GridItem span={12}>
<Card>
<CardHeader className="hub-description-header">
<Grid className="hub-tabs">
<GridItem span={12}>
<Tabs activeKey={activeTabKey} isSecondary onSelect={handleTabClick}>
<Tab eventKey={0} title="Description" id={props.name}>
<hr className="hub-horizontal-line"></hr>
<ReactMarkDown
source={resource.readme}
escapeHtml={true}
renderers={{ code: Readme }}
className="hub-readme"
/>
</Tab>
<Tab eventKey={1} title="YAML" id={props.name}>
<hr className="hub-horizontal-line"></hr>
<ReactMarkDown
source={resource.yaml}
escapeHtml={true}
renderers={{ code: Yaml }}
/>
</Tab>
</Tabs>
</GridItem>
</Grid>
</CardHeader>
</Card>
</GridItem>
</Grid>
</React.Fragment>
)
);
};

export default Description;
37 changes: 37 additions & 0 deletions ui/src/components/Readme/Readme.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { mount } from 'enzyme';
import Readme from '.';

const readme = `
# \`az\`
This task performs operations on Microsoft Azure resources using \`az\`.
## Install the Task
\`\`\`
kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/azure-cli/azure_cli.yaml
\`\`\`
## Parameters
* **az-image**: \`az\` CLI container image to run this task.
_default_: \`mcr.microsoft.com/azure-cli:2.0.77\`
You can use a specific version of the \`az\` CLI by specifying the \`az-image\` param with the \`mcr.microsoft.com/azure-cli\` image tagged with the specific version of the CLI you would like to use (i.e. version 2.0.70 = \`mcr.microsoft.com/azure-cli:2.0.70\`). A full list of available version tags can be found under the [Full Tag Listing](https://hub.docker.com/_/microsoft-azure-cli) section of the \`az\` Docker Hub.
* **ARGS**: The arguments to pass to \`az\` CLI. This parameter is required to run this task.
## Usage
### Running the Task
After creating the task, you should now be able to execute \`az\` commands by specifying the command you would like to run as the \`ARGS\` param. The \`ARGS\` param takes an array of \`az\` subcommands that will be executed as part of this task.
### Examples
Run \`az ad --help\` using \`az\`. Start the task using the Tekton CLI (\`tkn\`):
\`\`\`shell
tkn task start az -p ARGS=ad,--help
\`\`\`
Specify a different \`az-image\` to use with the \`az\` task:
\`\`\`shell
tkn task start az -p az-image=mcr.microsoft.com/azure-cli:2.0.70
\`\`\`
`;

it('should render the readme file', () => {
const component = mount(<Readme value={readme} />);

expect(component.find('SyntaxHighlighter').length).toBe(1);

expect(component.debug()).toMatchSnapshot();
});
Loading

0 comments on commit f213b78

Please sign in to comment.