From b6a8dd37d0f1dea08ab58b4db120dd571cb62750 Mon Sep 17 00:00:00 2001 From: "Juan Picado @jotadeveloper" Date: Sun, 13 Jan 2019 19:34:52 +0100 Subject: [PATCH] chore: add sidebar experiment --- package.json | 3 +- src/webui/components/DetailContainer/index.js | 49 ++++++++++++ .../components/DetailContainer/styles.js | 12 +++ src/webui/components/DetailContainer/types.js | 12 +++ src/webui/components/DetailSidebar/index.js | 75 +++++++++++++++++++ src/webui/components/DetailSidebar/styles.js | 14 ++++ src/webui/components/DetailSidebar/types.js | 12 +++ src/webui/components/Layout/index.js | 2 +- src/webui/components/Package/index.js | 2 +- src/webui/pages/version/index.js | 47 ++++++++++-- src/webui/styles/global.scss | 2 +- src/webui/utils/sec-utils.js | 12 +++ src/webui/utils/styles/colors.js | 68 ++++++++--------- yarn.lock | 13 ++++ 14 files changed, 280 insertions(+), 43 deletions(-) create mode 100644 src/webui/components/DetailContainer/index.js create mode 100644 src/webui/components/DetailContainer/styles.js create mode 100644 src/webui/components/DetailContainer/types.js create mode 100644 src/webui/components/DetailSidebar/index.js create mode 100644 src/webui/components/DetailSidebar/styles.js create mode 100644 src/webui/components/DetailSidebar/types.js create mode 100644 src/webui/utils/sec-utils.js diff --git a/package.json b/package.json index 6ae43b0c6..71e0b91b2 100644 --- a/package.json +++ b/package.json @@ -160,7 +160,8 @@ "webpack-cli": "3.1.1", "webpack-dev-server": "3.1.14", "webpack-merge": "4.1.4", - "whatwg-fetch": "3.0.0" + "whatwg-fetch": "3.0.0", + "xss": "1.0.3" }, "keywords": [ "private", diff --git a/src/webui/components/DetailContainer/index.js b/src/webui/components/DetailContainer/index.js new file mode 100644 index 000000000..127bd15f9 --- /dev/null +++ b/src/webui/components/DetailContainer/index.js @@ -0,0 +1,49 @@ +import React, {Component} from 'react'; + +import { DetailContextConsumer } from '../../pages/version/index'; +import Readme from '../Readme'; +import {preventXSS} from '../../utils/sec-utils'; +import Tabs from '@material-ui/core/Tabs/index'; +import Tab from '@material-ui/core/Tab/index'; +import { Content } from './styles'; + +class DetailContainer extends Component { + state = { + tabPosition: 0, + }; + + render() { + return ( + + {(context) => { + return this.renderTabs(context); + }} + + ); + }; + + renderTabs = ({readMe}) => { + const { tabPosition } = this.state; + + return ( + + + + + + + + {tabPosition === 0 && this.renderReadme(readMe)} + + ); + } + + renderReadme = (readMe) => { + const encodedReadme = preventXSS(readMe); + + return (); + } +} + + +export default DetailContainer; diff --git a/src/webui/components/DetailContainer/styles.js b/src/webui/components/DetailContainer/styles.js new file mode 100644 index 000000000..52a3eeb65 --- /dev/null +++ b/src/webui/components/DetailContainer/styles.js @@ -0,0 +1,12 @@ +/** + * @prettier + * @flow + */ + +import styled from 'react-emotion'; + +export const Content = styled.div` + && { + padding: 20px; + } +`; diff --git a/src/webui/components/DetailContainer/types.js b/src/webui/components/DetailContainer/types.js new file mode 100644 index 000000000..ee2d6b387 --- /dev/null +++ b/src/webui/components/DetailContainer/types.js @@ -0,0 +1,12 @@ +/** + * @prettier + * @flow + */ + +import type { Node } from 'react'; + +export interface IProps { + children: Node; + open: boolean; + onClose: () => void; +} diff --git a/src/webui/components/DetailSidebar/index.js b/src/webui/components/DetailSidebar/index.js new file mode 100644 index 000000000..e7a0f17a4 --- /dev/null +++ b/src/webui/components/DetailSidebar/index.js @@ -0,0 +1,75 @@ +/* eslint react/jsx-max-depth: 0 */ + +import React, {Component} from 'react'; + +import { DetailContextConsumer } from '../../pages/version/index'; +// import Paper from '@material-ui/core/Paper/index'; +import Typography from '@material-ui/core/Typography/index'; +import Grid from '@material-ui/core/Grid/index'; +// import CardHeader from '@material-ui/core/CardHeader'; +import Card from '@material-ui/core/Card/index'; +import CardContent from '@material-ui/core/CardContent/index'; +import { Content } from './styles'; +import CopyToClipBoard from '../CopyToClipBoard'; +import Button from '@material-ui/core/Button'; +import CardActions from '@material-ui/core/CardActions'; +// import Paper from '@material-ui/core/Paper/index'; + +class DetailSidebar extends Component { + render() { + return ( + + {(context) => { + return this.renderSideBar(context); + }} + + ); + }; + + renderSideBar = ({packageMeta, packageName}) => { + return ( + + {this.renderDescription(packageMeta, packageName)} + + + + + {packageName} + + + {packageMeta.latest.description} + + + + + + + + + + + + + + + + + + ); + } + + renderDescription = (packageMeta) => { + console.log('packageMeta', packageMeta); + + return ( + + + + ); + } +} + + +export default DetailSidebar; diff --git a/src/webui/components/DetailSidebar/styles.js b/src/webui/components/DetailSidebar/styles.js new file mode 100644 index 000000000..0cdcde222 --- /dev/null +++ b/src/webui/components/DetailSidebar/styles.js @@ -0,0 +1,14 @@ +/** + * @prettier + * @flow + */ + +import styled from 'react-emotion'; +import colors from '../../utils/styles/colors'; + +export const Content = styled.div` + && { + padding: 10px; + background-color: ${colors.white}; + } +`; diff --git a/src/webui/components/DetailSidebar/types.js b/src/webui/components/DetailSidebar/types.js new file mode 100644 index 000000000..ee2d6b387 --- /dev/null +++ b/src/webui/components/DetailSidebar/types.js @@ -0,0 +1,12 @@ +/** + * @prettier + * @flow + */ + +import type { Node } from 'react'; + +export interface IProps { + children: Node; + open: boolean; + onClose: () => void; +} diff --git a/src/webui/components/Layout/index.js b/src/webui/components/Layout/index.js index 05f69a7fd..f33d8ea06 100644 --- a/src/webui/components/Layout/index.js +++ b/src/webui/components/Layout/index.js @@ -7,7 +7,7 @@ import styled, { css } from 'react-emotion'; export const Content = styled.div` && { - background-color: #fff; + background-color: #ffffff; flex: 1; position: relative; } diff --git a/src/webui/components/Package/index.js b/src/webui/components/Package/index.js index 31087a7e1..1cfd3916b 100644 --- a/src/webui/components/Package/index.js +++ b/src/webui/components/Package/index.js @@ -80,7 +80,7 @@ const Package = ({ name: label, version, time, author: { name, avatar }, descrip ); return ( - +
{renderMainInfo()} diff --git a/src/webui/pages/version/index.js b/src/webui/pages/version/index.js index c074585fb..bc0e4e0a6 100644 --- a/src/webui/pages/version/index.js +++ b/src/webui/pages/version/index.js @@ -1,9 +1,21 @@ +/** + * @prettier + * @flow + */ + import React, { Component } from 'react'; import API from '../../utils/api'; +import Grid from '@material-ui/core/Grid/index'; import Loading from '../../components/Loading'; +import DetailContainer from '../../components/DetailContainer'; +import DetailSidebar from '../../components/DetailSidebar'; + +export const DetailContext = React.createContext(); + +export const DetailContextProvider = DetailContext.Provider; +export const DetailContextConsumer = DetailContext.Consumer; class VersionPage extends Component { - state = { readMe: '', packageMeta: null, @@ -18,6 +30,8 @@ class VersionPage extends Component { async loadPackageInfo() { const { match } = this.props; const packageName = match.params.package; + // FIXME: use utility + document.title = `Verdaccio - ${packageName}`; this.setState({ readMe: '', @@ -41,11 +55,34 @@ class VersionPage extends Component { } render() { - const {isLoading} = this.state; + const { isLoading, packageMeta, readMe } = this.state; + const { match } = this.props; + const packageName = match.params.package; - return ( -
{isLoading && }
- ); + if (isLoading === false) { + return ( + + + + {this.renderDetail()} + + + {this.renderSidebar()} + + + + ); + } else { + return ; + } + } + + renderDetail() { + return ; + } + + renderSidebar() { + return ; } } diff --git a/src/webui/styles/global.scss b/src/webui/styles/global.scss index e33736172..1b8e4b16f 100644 --- a/src/webui/styles/global.scss +++ b/src/webui/styles/global.scss @@ -3,7 +3,7 @@ :global { .container { - padding: 15px; + padding: 0px 15px; flex: 1; @include container-size; diff --git a/src/webui/utils/sec-utils.js b/src/webui/utils/sec-utils.js new file mode 100644 index 000000000..fee761339 --- /dev/null +++ b/src/webui/utils/sec-utils.js @@ -0,0 +1,12 @@ +/** + * @prettier + * @flow + */ +// $FlowFixMe +import parseXSS from 'xss'; + +export function preventXSS(text: string) { + const encodedText = parseXSS(text); + + return encodedText; +} diff --git a/src/webui/utils/styles/colors.js b/src/webui/utils/styles/colors.js index 7c1a3ee66..4cd495f25 100644 --- a/src/webui/utils/styles/colors.js +++ b/src/webui/utils/styles/colors.js @@ -1,34 +1,34 @@ -// Verdaccio -// ------------------------- - -// Main colors -// ------------------------- -const colors = { - black: '#000', - white: '#fff', - red: '#d32f2f', - grey: '#808080', - - greyLight: '#d3d3d3', - greyDark: '#a9a9a9', - greyChateau: '#95989a', - greyGainsboro: '#e3e3e3', - greyAthens: '#d3dddd', - - eclipse: '#3c3c3c', - paleNavy: '#e4e8f1', - saltpan: '#f7f8f6', - snow: '#f9f9f9', - - nobel01: '#999999', - nobel02: '#9f9f9f', - - // Main colors - // ------------------------- - - primary: '#4b5e40', - secondary: '#20232a', - -}; - -export default colors; +// Verdaccio +// ------------------------- + +// Main colors +// ------------------------- +const colors = { + black: '#000', + white: '#fff', + red: '#d32f2f', + grey: '#808080', + greySuperLight: '#f5f5f5', + greyLight: '#d3d3d3', + greyDark: '#a9a9a9', + greyChateau: '#95989a', + greyGainsboro: '#e3e3e3', + greyAthens: '#d3dddd', + + eclipse: '#3c3c3c', + paleNavy: '#e4e8f1', + saltpan: '#f7f8f6', + snow: '#f9f9f9', + + nobel01: '#999999', + nobel02: '#9f9f9f', + + // Main colors + // ------------------------- + + primary: '#4b5e40', + secondary: '#20232a', + +}; + +export default colors; diff --git a/yarn.lock b/yarn.lock index 5f8a30794..6d3b519fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3594,6 +3594,11 @@ cssesc@^2.0.0: resolved "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== +cssfilter@0.0.10: + version "0.0.10" + resolved "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae" + integrity sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4= + cssnano-preset-default@^4.0.6: version "4.0.6" resolved "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.6.tgz#92379e2a6db4a91c0ea727f5f556eeac693eab6a" @@ -13417,6 +13422,14 @@ xregexp@4.0.0: resolved "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" integrity sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg== +xss@1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/xss/-/xss-1.0.3.tgz#d04bd2558fd6c29c46113824d5e8b2a910054e23" + integrity sha512-LTpz3jXPLUphMMmyufoZRSKnqMj41OVypZ8uYGzvjkMV9C1EdACrhQl/EM8Qfh5htSAuMIQFOejmKAZGkJfaCg== + dependencies: + commander "^2.9.0" + cssfilter "0.0.10" + xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"