Skip to content

Commit

Permalink
flesh out chart view/details
Browse files Browse the repository at this point in the history
  • Loading branch information
Adnan Abdulhussein committed Jan 22, 2018
1 parent 28ffc43 commit cb2f42c
Show file tree
Hide file tree
Showing 22 changed files with 476 additions and 62 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"raf": "^3.4.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-markdown": "^3.1.4",
"react-modal": "^3.1.11",
"react-redux": "^5.0.6",
"react-router-dom": "^4.2.2",
Expand Down
44 changes: 41 additions & 3 deletions src/actions/charts.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
import { Dispatch } from "redux";
import { createAction, getReturnOfExpression } from "typesafe-actions";

import { IChart, IStoreState } from "../shared/types";
import { IChart, IChartVersion, IStoreState } from "../shared/types";
import * as url from "../shared/url";

export const requestCharts = createAction("REQUEST_CHARTS");
export const receiveCharts = createAction("RECEIVE_CHARTS", (charts: IChart[]) => ({
charts,
type: "RECEIVE_CHARTS",
}));
export const receiveChartVersions = createAction(
"RECEIVE_CHART_VERSIONS",
(versions: IChartVersion[]) => ({
type: "RECEIVE_CHART_VERSIONS",
versions,
}),
);
export const selectChart = createAction("SELECT_CHART", (chart: IChart) => ({
chart,
type: "SELECT_CHART",
}));
export const selectReadme = createAction("SELECT_README", (readme: string) => ({
readme,
type: "SELECT_README",
}));

const allActions = [requestCharts, receiveCharts, selectChart].map(getReturnOfExpression);
const allActions = [
requestCharts,
receiveCharts,
receiveChartVersions,
selectChart,
selectReadme,
].map(getReturnOfExpression);
export type ChartsAction = typeof allActions[number];

export function fetchCharts(repo: string) {
Expand All @@ -31,7 +48,28 @@ export function getChart(id: string) {
dispatch(requestCharts());
return fetch(url.api.charts.get(id))
.then(response => response.json())
.then(json => dispatch(selectChart(json.data)));
.then(json => {
const c: IChart = json.data;
dispatch(listChartVersions(c.id));
dispatch(getChartReadme(c.id, c.relationships.latestChartVersion.data.version));
return dispatch(selectChart(json.data));
});
};
}

export function listChartVersions(id: string) {
return (dispatch: Dispatch<IStoreState>): Promise<{}> => {
return fetch(url.api.charts.listVersions(id))
.then(response => response.json())
.then(json => dispatch(receiveChartVersions(json.data)));
};
}

export function getChartReadme(id: string, version: string) {
return (dispatch: Dispatch<IStoreState>): Promise<{}> => {
return fetch(url.api.charts.getReadme(id, version))
.then(response => response.text())
.then(text => dispatch(selectReadme(text)));
};
}

Expand Down
6 changes: 6 additions & 0 deletions src/components/ChartIcon/ChartIcon.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.ChartIcon {
height: 64px;
}
.ChartIcon__img {
max-height: 64px;
}
6 changes: 4 additions & 2 deletions src/components/ChartIcon/ChartIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as React from "react";

import placeholder from "../../placeholder.png";
import "./ChartIcon.css";

interface IChartIconProps {
icon?: string;
Expand All @@ -11,8 +13,8 @@ class ChartIcon extends React.Component<IChartIconProps> {
const iconSrc = icon ? `/api/chartsvc/${icon}` : placeholder;

return (
<div className="ChartListItem__icon">
<img className="ChartListItem__icon" src={iconSrc} />
<div className="ChartIcon">
<img className="ChartIcon__img" src={iconSrc} />
</div>
);
}
Expand Down
4 changes: 0 additions & 4 deletions src/components/ChartList/ChartListItem.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.ChartListItem {
width: 250px;
}

.ChartListItem__icon {
max-height: 64px;
}
2 changes: 1 addition & 1 deletion src/components/ChartView/ChartDeployButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ChartDeployButton extends React.Component<IChartDeployButtonProps, IChartD
onClick={this.openModel}
disabled={this.state.isDeploying}
>
Deploy
Deploy using Helm
</button>
<Modal
isOpen={this.state.modalIsOpen}
Expand Down
36 changes: 36 additions & 0 deletions src/components/ChartView/ChartHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as React from "react";
import { Link } from "react-router-dom";

import ChartIcon from "../ChartIcon";

interface IChartHeaderProps {
appVersion?: string;
id: string;
icon: string;
repo: string;
description: string;
}

class ChartHeader extends React.Component<IChartHeaderProps> {
public render() {
const { appVersion, id, icon, repo, description } = this.props;
return (
<header>
<div className="ChartView__heading margin-normal">
<ChartIcon icon={icon} />
<div className="title margin-l-small">
<h1 className="margin-t-reset">{id}</h1>
<h5 className="subtitle margin-b-normal">
{appVersion && <span>{appVersion} - </span>}
<Link to={`/charts/${repo}`}>{repo}</Link>
</h5>
<h5 className="subtitle margin-b-reset">{description}</h5>
</div>
</div>
<hr />
</header>
);
}
}

export default ChartHeader;
4 changes: 4 additions & 0 deletions src/components/ChartView/ChartReadme.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.ChartReadme pre {
overflow: scroll;
background: #f1f1f1;
}
21 changes: 21 additions & 0 deletions src/components/ChartView/ChartReadme.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as React from "react";
import * as ReactMarkdown from "react-markdown";

import "./ChartReadme.css";

interface IChartReadmeProps {
markdown?: string;
}

class ChartReadme extends React.Component<IChartReadmeProps> {
public render() {
const { markdown } = this.props;
return (
<div className="ChartReadme">
{markdown ? <ReactMarkdown source={markdown} /> : "Loading"}
</div>
);
}
}

export default ChartReadme;
30 changes: 30 additions & 0 deletions src/components/ChartView/ChartVersionsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as React from "react";

import { IChartVersion } from "../../shared/types";

interface IChartVersionsListProps {
versions: IChartVersion[];
}

class ChartVersionsList extends React.Component<IChartVersionsListProps> {
public render() {
const items = this.props.versions.slice(0, 5).map(v => (
<li key={v.id}>
{v.attributes.version} - {this.formatDate(v.attributes.created)}
</li>
));
return (
<div className="ChartVersionsList">
<ul className="remove-style padding-l-reset margin-b-reset">{items}</ul>
<span className="type-small">Show all...</span>
</div>
);
}

public formatDate(dateStr: string) {
const d = new Date(dateStr);
return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
}
}

export default ChartVersionsList;
17 changes: 17 additions & 0 deletions src/components/ChartView/ChartView.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.ChartView__heading {
display: flex;
}

.ChartView__readme-container {
/* for col-8 class */
width: 66.66%;
}

.ChartViewSidebar__section {
/* hack to make h2 margin work... */
padding-top: 0.1px;
}

.ChartViewSidebar__section > div {
margin-left: 1em;
}
65 changes: 54 additions & 11 deletions src/components/ChartView/ChartView.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import * as React from "react";
import { RouterAction } from "react-router-redux";
import { IChart, IChartVersion } from "../../shared/types";

import { IChart, IChartState } from "../../shared/types";
import ChartDeployButton from "./ChartDeployButton";
import ChartHeader from "./ChartHeader";
import ChartReadme from "./ChartReadme";
import ChartVersionsList from "./ChartVersionsList";
import "./ChartView.css";

interface IChartViewProps {
chartID: string;
getChart: (id: string) => Promise<{}>;
deployChart: (chart: IChart, releaseName: string, namespace: string) => Promise<{}>;
push: (location: string) => RouterAction;
isFetching: boolean;
chart: IChart;
version: IChartVersion;
selected: IChartState["selected"];
}

class ChartView extends React.Component<IChartViewProps> {
Expand All @@ -20,18 +24,57 @@ class ChartView extends React.Component<IChartViewProps> {
}

public render() {
const { isFetching, chart, deployChart, push } = this.props;
const { isFetching, deployChart, push } = this.props;
const { chart, readme, versions } = this.props.selected;
if (isFetching || !chart) {
return <div>Loading</div>;
}
return (
<section className="ChartListView">
<header className="ChartListView__header">
<h1>{chart.id}</h1>
<hr />
</header>
<main className="text-c">
<ChartDeployButton push={push} chart={chart} deployChart={deployChart} />
<section className="ChartView">
<ChartHeader
id={chart.id}
description={chart.attributes.description}
icon={chart.attributes.icon}
repo={chart.attributes.repo.name}
appVersion={chart.relationships.latestChartVersion.data.app_version}
/>
<main>
<div className="container">
<div className="row">
<div className="col-8 ChartView__readme-container">
<ChartReadme markdown={readme} />
</div>
{/* TODO: fix when upgrading to bitnami-ui v3 - col-4 does not fit correctly in v2 */}
<div className="col-3">
<aside className="ChartViewSidebar bg-light margin-v-big padding-h-normal">
<div className="ChartViewSidebar__section">
<h2>Usage</h2>
<ChartDeployButton push={push} chart={chart} deployChart={deployChart} />
</div>
<div className="ChartViewSidebar__section">
<h2>Chart Versions</h2>
<ChartVersionsList versions={versions} />
</div>
<div className="ChartViewSidebar__section">
<h2>App Version</h2>
<div>{chart.relationships.latestChartVersion.data.app_version}</div>
</div>
<div className="ChartViewSidebar__section">
<h2>Home</h2>
<div>{chart.attributes.home}</div>
</div>
<div className="ChartViewSidebar__section">
<h2>Maintainers</h2>
{chart.attributes.maintainers.map((m, i) => <div key={i}>{m.name}</div>)}
</div>
<div className="ChartViewSidebar__section">
<h2>Related</h2>
{chart.attributes.sources.map((s, i) => <div key={i}>{s}</div>)}
</div>
</aside>
</div>
</div>
</div>
</main>
</section>
);
Expand Down
21 changes: 21 additions & 0 deletions src/components/Layout/Layout.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.Layout {
display: flex;
min-height: 100vh;
width: 100%;
flex-direction: column;
}

.Layout > main {
flex: 1;
display: flex;
flex-direction: row;
}

.Layout > main > .container {
width: 100%;
}

.Layout > main > .container > .row {
height: 100%;
width: 100%;
}
1 change: 1 addition & 0 deletions src/components/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as React from "react";
import Footer from "../Footer";
import Header from "../Header";
import Sidebar from "../Sidebar";
import "./Layout.css";

class Layout extends React.Component {
public render() {
Expand Down
3 changes: 3 additions & 0 deletions src/components/Sidebar/Sidebar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.Sidebar {
height: 100%;
}
4 changes: 3 additions & 1 deletion src/components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import * as React from "react";

import placeholder from "../../placeholder.png";
import "./Sidebar.css";

class Sidebar extends React.Component {
public render() {
return (
<aside className="bg-dark type-color-reverse-anchor-reset">
<aside className="Sidebar bg-dark type-color-reverse-anchor-reset">
<ul className="remove-style margin-reset padding-h-normal text-c">
<li className="padding-v-normal">
<img src={placeholder} height="48" />
Expand Down
3 changes: 1 addition & 2 deletions src/containers/ChartViewContainer/ChartViewContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ interface IRouteProps {

function mapStateToProps({ charts }: IStoreState, { match: { params } }: IRouteProps) {
return {
chart: charts.selectedChart,
chartID: `${params.repo}/${params.id}`,
isFetching: charts.isFetching,
version: charts.selectedVersion,
selected: charts.selected,
};
}

Expand Down
Loading

0 comments on commit cb2f42c

Please sign in to comment.