1
0
mirror of https://github.com/SomboChea/ui synced 2026-01-17 16:45:49 +07:00

Compare commits

...

15 Commits

Author SHA1 Message Date
Juan Picado @jotadeveloper
3779caa4e3 chore(release): 0.3.1 2019-09-29 20:03:29 +02:00
Juan Picado @jotadeveloper
7e6702c34b chore: update dependencies (#138)
* chore: update dependencies

dependencies maintenance

* chore: restore date-fns@1.30.1
2019-09-29 18:26:04 +02:00
Filip Messa
2e50981514 fix(ui): fix the hover effect on the packageItem's author area (#137) 2019-09-29 16:44:10 +02:00
Daniel Ruf
f61913c2d3 fix: correctly load font files - closes #128 (#134)
* fix: correctly load font files - closes #128

* Resolve issue with the moduleNameWrapper in Jest
2019-09-29 16:36:38 +02:00
Priscila Oliveira
ffc97c373c chore: pumped mui version (#131)
* chore: updated mui libs

* fix: updated snap
2019-09-28 00:31:01 +02:00
Sergio Hg
3a889b67ee Merge pull request #127 from verdaccio/refactor-ci
chore: refactor ci
2019-09-11 22:55:04 +02:00
Sergio Herrera Guzmán
de0f91a6d2 test: skip non-deterministic test 2019-09-11 22:47:45 +02:00
Sergio Herrera Guzmán
195a79a809 ci: drop Node 8 support 2019-09-11 22:35:29 +02:00
Sergio Herrera Guzmán
0a7428edab chore: fix Prettier and Stylelint glob expansion for Windows 2019-09-11 15:53:57 +02:00
Sergio Herrera Guzmán
9ad506d569 test: fix one failing snapshot 2019-09-11 15:53:07 +02:00
Sergio Herrera Guzmán
3b52a17623 chore: update lockfile 2019-09-11 15:53:07 +02:00
Sergio Herrera Guzmán
3309e449d1 ci(circleci): improve workflow and add linting 2019-09-11 15:53:07 +02:00
Sergio Herrera Guzmán
7853ec2acb ci(github): remove workflow before deprecation and improve current 2019-09-11 15:53:07 +02:00
Juan Picado @jotadeveloper
2890e5a27e chore(release): 0.3.0 2019-09-01 13:16:44 +02:00
Juan Picado @jotadeveloper
1904179af3 feat: add browser features to browse by version (#125)
* feat: add browser features to browse by version

* chore: verify whether version exist

* chore: add link on versions

* chore: udpate imports

* chore: use mui links

* test: add unit test

* chore: Add todo list

* chore: remove imports
2019-09-01 04:09:23 -07:00
23 changed files with 9033 additions and 3611 deletions

View File

@@ -1,31 +1,25 @@
version: 2 version: 2
aliases: aliases:
- &repo_path
~/ui-theme
- &defaults - &defaults
working_directory: ~/ui-theme working_directory: *repo_path
- &node11_executor - &node_latest_executor
docker: docker:
- image: circleci/node:11.10.1 - image: circleci/node:latest
- &node8_executor - &node_lts_executor
docker: docker:
- image: circleci/node:8 - image: circleci/node:lts
- &node10_executor
docker:
- image: circleci/node:10
- &default_executor - &default_executor
<<: *node10_executor <<: *node_latest_executor
- &repo_key
repo-{{ .Branch }}-{{ .Revision }}
- &coverage_key
coverage-{{ .Branch }}-{{ .Revision }}
- &base_config_key
base-config-{{ .Branch }}-{{ .Revision }}
- &yarn_cache_key - &yarn_cache_key
yarn-sha-{{ checksum "yarn.lock" }} yarn-sha-{{ checksum "yarn.lock" }}
- &coverage_key
coverage-{{ .Branch }}-{{ .Revision }}
- &restore_repo - &restore_repo
restore_cache: attach_workspace:
keys: at: *repo_path
- *repo_key
- &ignore_non_dev_branches - &ignore_non_dev_branches
filters: filters:
tags: tags:
@@ -36,7 +30,7 @@ aliases:
- &execute_on_release - &execute_on_release
filters: filters:
tags: tags:
only: /(v)?[0-9]+(\.[0-9]+)*/ only: /v?[0-9]+(\.[0-9]+)*([-+\.][a-zA-Z0-9]+)*/
branches: branches:
ignore: ignore:
- /.*/ - /.*/
@@ -48,21 +42,11 @@ jobs:
steps: steps:
- *restore_repo - *restore_repo
- checkout - checkout
- restore_cache:
key: *base_config_key
- run:
name: 'Base environment setup'
command: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
- save_cache:
key: *base_config_key
paths:
- ~/.npmrc
- ~/.gitconfig
- restore_cache: - restore_cache:
key: *yarn_cache_key key: *yarn_cache_key
- run: - run:
name: Install Js dependencies name: Install dependencies
command: yarn install --no-progress --registry https://registry.verdaccio.org --no-lockfile command: yarn install --frozen-lockfile
- run: - run:
name: Build project name: Build project
command: yarn run build command: yarn run build
@@ -72,10 +56,20 @@ jobs:
- ~/.yarn - ~/.yarn
- ~/.cache/yarn - ~/.cache/yarn
- node_modules - node_modules
- save_cache: - persist_to_workspace:
key: *repo_key root: *repo_path
paths: paths:
- ~/ui-theme - ./*
lint:
<<: *defaults
<<: *default_executor
steps:
- *restore_repo
- run:
name: Lint code
command: yarn lint
test_bundlesize: test_bundlesize:
<<: *defaults <<: *defaults
<<: *default_executor <<: *default_executor
@@ -85,37 +79,28 @@ jobs:
name: Test BundleSize name: Test BundleSize
command: yarn test:size command: yarn test:size
test_node11: test_node_latest:
<<: *defaults <<: *defaults
<<: *node11_executor <<: *node_latest_executor
steps: steps:
- *restore_repo - *restore_repo
- run: - run:
name: Test with Node 11 name: Test with Node (Latest)
command: yarn test command: yarn test
test_node8:
<<: *defaults
<<: *node8_executor
steps:
- *restore_repo
- run:
name: Test with Node 8
command: yarn test
test_node10:
<<: *defaults
<<: *node10_executor
steps:
- *restore_repo
- run:
name: Test with Node 10
command: yarn run test
- save_cache: - save_cache:
key: *coverage_key key: *coverage_key
paths: paths:
- coverage - coverage
test_node_lts:
<<: *defaults
<<: *node_lts_executor
steps:
- *restore_repo
- run:
name: Test with Node (LTS)
command: yarn test
coverage: coverage:
<<: *defaults <<: *defaults
<<: *default_executor <<: *default_executor
@@ -140,8 +125,9 @@ jobs:
<<: *default_executor <<: *default_executor
steps: steps:
- *restore_repo - *restore_repo
- restore_cache: - run:
key: *base_config_key name: 'Setup publish credentials'
command: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
- run: - run:
name: Publish name: Publish
command: yarn publish command: yarn publish
@@ -152,29 +138,31 @@ workflows:
jobs: jobs:
- prepare: - prepare:
<<: *ignore_non_dev_branches <<: *ignore_non_dev_branches
- test_node11: - lint:
requires:
- prepare
<<: *ignore_non_dev_branches
- test_node8:
requires:
- prepare
<<: *ignore_non_dev_branches
- test_node10:
requires: requires:
- prepare - prepare
<<: *ignore_non_dev_branches <<: *ignore_non_dev_branches
- test_bundlesize: - test_bundlesize:
requires: requires:
- test_node11 - prepare
- test_node8 <<: *ignore_non_dev_branches
- test_node10 - test_node_latest:
requires:
- prepare
<<: *ignore_non_dev_branches
- test_node_lts:
requires:
- prepare
<<: *ignore_non_dev_branches <<: *ignore_non_dev_branches
- coverage: - coverage:
requires: requires:
- test_bundlesize - test_node_latest
<<: *ignore_non_dev_branches <<: *ignore_non_dev_branches
- publish_package: - publish_package:
requires: requires:
- lint
- test_bundlesize
- test_node_latest
- test_node_lts
- coverage - coverage
<<: *execute_on_release <<: *execute_on_release

67
.github/main.workflow vendored
View File

@@ -1,67 +0,0 @@
################################################
# Workflow for a github release when a tag is
# pushed
################################################
workflow "github release" {
resolves = [
"release.github",
"release.lint",
]
on = "push"
}
action "release.filter" {
uses = "actions/bin/filter@master"
args = "tag v*"
}
action "release.install" {
uses = "docker://node:10"
needs = ["release.filter"]
args = "yarn install"
}
action "release.build" {
uses = "docker://node:10"
needs = ["release.install"]
args = "yarn run build"
}
action "release.lint" {
uses = "docker://node:10"
needs = ["release.install"]
args = "yarn run lint"
}
action "release.test" {
uses = "docker://node:10"
needs = ["release.build"]
args = "yarn run test"
}
action "release.auth" {
needs = ["release.test"]
uses = "actions/bin/filter@master"
args = ["actor", "octocat", "torvalds"]
}
action "release.npm.publish" {
needs = ["release.auth"]
uses = "docker://node:10"
args = "sh scripts/publish.sh"
secrets = [
"REGISTRY_AUTH_TOKEN",
]
env = {
REGISTRY_URL = "registry.npmjs.org"
}
}
action "release.github" {
needs = ["release.npm.publish"]
uses = "docker://node:10"
args = "sh scripts/github-release.sh"
secrets = [
"GITHUB_TOKEN",
]
}

View File

@@ -1,28 +1,28 @@
name: Node CI name: CI
on: [push] on: push
jobs: jobs:
ci: build_test_lint:
name: Test on node ${{ matrix.node_version }} and ${{ matrix.os }} name: Node ${{ matrix.node_version }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false
matrix: matrix:
node_version: [8, 10, 12] node_version: [10, 12]
os: [ubuntu-latest, windows-latest, macOS-latest] os: [ubuntu-latest, windows-latest, macOS-latest]
runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node_version }} - name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
version: ${{ matrix.node_version }} version: ${{ matrix.node_version }}
- name: Install
- name: Use Yarn 1.17.2 run: yarn install --frozen-lockfile
run: | - name: Build
npm install -g yarn@1.17.2 run: yarn build
- name: yarn build - name: Lint
run: | run: yarn lint
yarn install
yarn lint
yarn build

View File

@@ -1,4 +1,5 @@
{ {
"endOfLine": "auto",
"useTabs": false, "useTabs": false,
"printWidth": 160, "printWidth": 160,
"tabWidth": 2, "tabWidth": 2,

View File

@@ -2,6 +2,21 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [0.3.1](https://github.com/verdaccio/ui/compare/v0.3.0...v0.3.1) (2019-09-29)
### Bug Fixes
* **ui:** fix the hover effect on the packageItem's author area ([#137](https://github.com/verdaccio/ui/issues/137)) ([2e50981](https://github.com/verdaccio/ui/commit/2e50981))
* correctly load font files - closes [#128](https://github.com/verdaccio/ui/issues/128) ([#134](https://github.com/verdaccio/ui/issues/134)) ([f61913c](https://github.com/verdaccio/ui/commit/f61913c))
## [0.3.0](https://github.com/verdaccio/ui/compare/v0.2.4...v0.3.0) (2019-09-01)
### Features
* add browser features to browse by version ([#125](https://github.com/verdaccio/ui/issues/125)) ([1904179](https://github.com/verdaccio/ui/commit/1904179))
### [0.2.4](https://github.com/verdaccio/ui/compare/v0.2.3...v0.2.4) (2019-08-31) ### [0.2.4](https://github.com/verdaccio/ui/compare/v0.2.3...v0.2.4) (2019-08-31)

View File

@@ -1,6 +1,6 @@
{ {
"name": "@verdaccio/ui-theme", "name": "@verdaccio/ui-theme",
"version": "0.2.4", "version": "0.3.1",
"description": "Verdaccio User Interface", "description": "Verdaccio User Interface",
"author": { "author": {
"name": "Verdaccio Core Team" "name": "Verdaccio Core Team"
@@ -11,31 +11,30 @@
}, },
"main": "index.js", "main": "index.js",
"devDependencies": { "devDependencies": {
"@commitlint/cli": "8.1.0", "@commitlint/cli": "8.2.0",
"@commitlint/config-conventional": "8.1.0", "@commitlint/config-conventional": "8.2.0",
"@material-ui/core": "4.3.3", "@material-ui/core": "4.4.3",
"@material-ui/icons": "4.2.1", "@material-ui/icons": "4.4.3",
"@material-ui/styles": "4.3.3",
"@octokit/rest": "16.28.7", "@octokit/rest": "16.28.7",
"@testing-library/react": "9.1.3", "@testing-library/react": "9.2.0",
"@types/enzyme": "3.10.3", "@types/enzyme": "3.10.3",
"@types/jest": "24.0.18", "@types/jest": "24.0.18",
"@types/lodash": "4.14.138", "@types/lodash": "4.14.141",
"@types/node": "12.7.3", "@types/node": "12.7.8",
"@types/react": "16.9.2", "@types/react": "16.9.2",
"@types/react-dom": "16.9.0", "@types/react-dom": "16.9.0",
"@types/react-router-dom": "4.3.5", "@types/react-router-dom": "4.3.5",
"@types/validator": "10.11.3", "@types/validator": "10.11.3",
"@verdaccio/babel-preset": "2.0.0", "@verdaccio/babel-preset": "2.0.0",
"@verdaccio/eslint-config": "2.0.0", "@verdaccio/eslint-config": "2.0.0",
"@verdaccio/types": "8.0.0", "@verdaccio/types": "8.1.0",
"autosuggest-highlight": "3.1.1", "autosuggest-highlight": "3.1.1",
"babel-loader": "8.0.6", "babel-loader": "8.0.6",
"bundlesize": "0.18.0", "bundlesize": "0.18.0",
"codeceptjs": "2.2.1", "codeceptjs": "2.3.2",
"codecov": "3.5.0", "codecov": "3.6.1",
"concurrently": "4.1.2", "concurrently": "4.1.2",
"cross-env": "5.2.0", "cross-env": "6.0.0",
"css-loader": "3.2.0", "css-loader": "3.2.0",
"date-fns": "1.30.1", "date-fns": "1.30.1",
"emotion": "9.2.12", "emotion": "9.2.12",
@@ -54,7 +53,7 @@
"get-stdin": "6.0.0", "get-stdin": "6.0.0",
"github-markdown-css": "3.0.1", "github-markdown-css": "3.0.1",
"html-webpack-plugin": "3.2.0", "html-webpack-plugin": "3.2.0",
"husky": "3.0.4", "husky": "3.0.7",
"identity-obj-proxy": "3.0.0", "identity-obj-proxy": "3.0.0",
"in-publish": "2.0.0", "in-publish": "2.0.0",
"jest": "24.9.0", "jest": "24.9.0",
@@ -68,7 +67,7 @@
"lint-staged": "8.2.1", "lint-staged": "8.2.1",
"localstorage-memory": "1.0.3", "localstorage-memory": "1.0.3",
"mini-css-extract-plugin": "0.8.0", "mini-css-extract-plugin": "0.8.0",
"node-mocks-http": "1.7.6", "node-mocks-http": "1.8.0",
"normalize.css": "8.0.1", "normalize.css": "8.0.1",
"optimize-css-assets-webpack-plugin": "5.0.3", "optimize-css-assets-webpack-plugin": "5.0.3",
"ora": "3.4.0", "ora": "3.4.0",
@@ -83,7 +82,7 @@
"react-router": "5.0.1", "react-router": "5.0.1",
"react-router-dom": "5.0.1", "react-router-dom": "5.0.1",
"resolve-url-loader": "3.1.0", "resolve-url-loader": "3.1.0",
"rimraf": "2.6.3", "rimraf": "3.0.0",
"source-map-loader": "0.2.4", "source-map-loader": "0.2.4",
"standard-version": "7.0.0", "standard-version": "7.0.0",
"style-loader": "1.0.0", "style-loader": "1.0.0",
@@ -99,13 +98,13 @@
"url-loader": "2.1.0", "url-loader": "2.1.0",
"validator": "11.1.0", "validator": "11.1.0",
"verdaccio": "4.2.2", "verdaccio": "4.2.2",
"verdaccio-auth-memory": "8.0.0", "verdaccio-auth-memory": "8.1.1",
"verdaccio-memory": "8.0.0", "verdaccio-memory": "8.1.1",
"webpack": "4.39.3", "webpack": "4.41.0",
"webpack-bundle-analyzer": "3.4.1", "webpack-bundle-analyzer": "3.5.2",
"webpack-bundle-size-analyzer": "3.0.0", "webpack-bundle-size-analyzer": "3.1.0",
"webpack-cli": "3.3.7", "webpack-cli": "3.3.9",
"webpack-dev-server": "3.8.0", "webpack-dev-server": "3.8.1",
"webpack-merge": "4.2.2", "webpack-merge": "4.2.2",
"whatwg-fetch": "3.0.0", "whatwg-fetch": "3.0.0",
"xss": "1.0.6" "xss": "1.0.6"
@@ -144,7 +143,7 @@
"scripts": { "scripts": {
"type-check": "tsc --noEmit", "type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch", "type-check:watch": "npm run type-check -- --watch",
"release": "standard-version -a -s", "release": "standard-version -a",
"test:clean": "npx jest --clearCache", "test:clean": "npx jest --clearCache",
"test:acceptance": "codeceptjs run --steps", "test:acceptance": "codeceptjs run --steps",
"test:acceptance:server": "concurrently --kill-others \"npm run verdaccio:server\" \"npm run test:acceptance\"", "test:acceptance:server": "concurrently --kill-others \"npm run verdaccio:server\" \"npm run test:acceptance\"",
@@ -152,7 +151,7 @@
"test:size": "bundlesize", "test:size": "bundlesize",
"lint": "npm run lint:js && npm run lint:css", "lint": "npm run lint:js && npm run lint:css",
"lint:js": "npm run type-check && eslint . --ext .js,.ts,.tsx", "lint:js": "npm run type-check && eslint . --ext .js,.ts,.tsx",
"lint:css": "stylelint 'src/**/styles.ts'", "lint:css": "stylelint \"src/**/styles.ts\"",
"coverage:publish": "codecov", "coverage:publish": "codecov",
"pre:webpack": "rimraf static/*", "pre:webpack": "rimraf static/*",
"prepublish": "in-publish && npm run build || not-in-publish", "prepublish": "in-publish && npm run build || not-in-publish",

View File

@@ -10,7 +10,7 @@ import Header from '../components/Header';
import { Container, Content } from '../components/Layout'; import { Container, Content } from '../components/Layout';
import RouterApp from '../router'; import RouterApp from '../router';
import API from '../utils/api'; import API from '../utils/api';
import '../styles/typeface-roboto.css'; import 'typeface-roboto/index.css';
import '../utils/styles/global'; import '../utils/styles/global';
import 'normalize.css'; import 'normalize.css';
import Footer from '../components/Footer'; import Footer from '../components/Footer';

View File

@@ -16,6 +16,15 @@ import { DetailContext } from '../../pages/Version';
import { TitleListItem, TitleListItemText } from './styles'; import { TitleListItem, TitleListItemText } from './styles';
const renderLatestDescription = (description, version, isLatest: boolean = true) => {
return (
<span>
<div>{description}</div>
{version ? <small>{`${isLatest ? 'Latest v' : 'v'}${version}`}</small> : null}
</span>
);
};
const renderCopyCLI = () => <Install />; const renderCopyCLI = () => <Install />;
const renderMaintainers = () => <Developers type="maintainers" />; const renderMaintainers = () => <Developers type="maintainers" />;
const renderContributors = () => <Developers type="contributors" />; const renderContributors = () => <Developers type="contributors" />;
@@ -24,22 +33,25 @@ const renderAuthor = () => <Author />;
const renderEngine = () => <Engine />; const renderEngine = () => <Engine />;
const renderDist = () => <Dist />; const renderDist = () => <Dist />;
const renderActionBar = () => <ActionBar />; const renderActionBar = () => <ActionBar />;
const renderTitle = (packageName, packageMeta) => { const renderTitle = (packageName, packageVersion, packageMeta) => {
const version = packageVersion ? packageVersion : packageMeta.latest.version;
const isLatest = typeof packageVersion === 'undefined';
return ( return (
<List className="detail-info"> <List className="detail-info">
<TitleListItem alignItems="flex-start" button={true}> <TitleListItem alignItems="flex-start" button={true}>
<TitleListItemText primary={<b>{packageName}</b>} secondary={packageMeta.latest.description} /> <TitleListItemText primary={<b>{packageName}</b>} secondary={renderLatestDescription(packageMeta.latest.description, version, isLatest)} />
</TitleListItem> </TitleListItem>
</List> </List>
); );
}; };
function renderSideBar(packageName, packageMeta): ReactElement<HTMLElement> { function renderSideBar(packageName, packageVersion, packageMeta): ReactElement<HTMLElement> {
return ( return (
<div className={'sidebar-info'}> <div className={'sidebar-info'}>
<Card> <Card>
<CardContent> <CardContent>
{renderTitle(packageName, packageMeta)} {renderTitle(packageName, packageVersion, packageMeta)}
{renderActionBar()} {renderActionBar()}
{renderCopyCLI()} {renderCopyCLI()}
{renderRepository()} {renderRepository()}
@@ -55,9 +67,9 @@ function renderSideBar(packageName, packageMeta): ReactElement<HTMLElement> {
} }
const DetailSidebar = () => { const DetailSidebar = () => {
const { packageName, packageMeta } = React.useContext(DetailContext); const { packageName, packageMeta, packageVersion } = React.useContext(DetailContext);
return renderSideBar(packageName, packageMeta); return renderSideBar(packageName, packageVersion, packageMeta);
}; };
export default DetailSidebar; export default DetailSidebar;

View File

@@ -72,10 +72,10 @@ exports[`test Developers should render the component for contributors with items
name="dmethvin" name="dmethvin"
version="1.0.0" version="1.0.0"
> >
<WithStyles(Tooltip) <WithStyles(ForwardRef(Tooltip))
title="dmethvin" title="dmethvin"
> >
<Tooltip <ForwardRef(Tooltip)
classes={ classes={
Object { Object {
"popper": "MuiTooltip-popper", "popper": "MuiTooltip-popper",
@@ -143,8 +143,8 @@ exports[`test Developers should render the component for contributors with items
placement="bottom" placement="bottom"
transition={true} transition={true}
/> />
</Tooltip> </ForwardRef(Tooltip)>
</WithStyles(Tooltip)> </WithStyles(ForwardRef(Tooltip))>
</AvatarTooltip> </AvatarTooltip>
</span> </span>
</Styled(span)> </Styled(span)>
@@ -159,10 +159,10 @@ exports[`test Developers should render the component for contributors with items
name="mgol" name="mgol"
version="1.0.0" version="1.0.0"
> >
<WithStyles(Tooltip) <WithStyles(ForwardRef(Tooltip))
title="mgol" title="mgol"
> >
<Tooltip <ForwardRef(Tooltip)
classes={ classes={
Object { Object {
"popper": "MuiTooltip-popper", "popper": "MuiTooltip-popper",
@@ -230,8 +230,8 @@ exports[`test Developers should render the component for contributors with items
placement="bottom" placement="bottom"
transition={true} transition={true}
/> />
</Tooltip> </ForwardRef(Tooltip)>
</WithStyles(Tooltip)> </WithStyles(ForwardRef(Tooltip))>
</AvatarTooltip> </AvatarTooltip>
</span> </span>
</Styled(span)> </Styled(span)>
@@ -312,10 +312,10 @@ exports[`test Developers should render the component for maintainers with items
name="dmethvin" name="dmethvin"
version="1.0.0" version="1.0.0"
> >
<WithStyles(Tooltip) <WithStyles(ForwardRef(Tooltip))
title="dmethvin" title="dmethvin"
> >
<Tooltip <ForwardRef(Tooltip)
classes={ classes={
Object { Object {
"popper": "MuiTooltip-popper", "popper": "MuiTooltip-popper",
@@ -383,8 +383,8 @@ exports[`test Developers should render the component for maintainers with items
placement="bottom" placement="bottom"
transition={true} transition={true}
/> />
</Tooltip> </ForwardRef(Tooltip)>
</WithStyles(Tooltip)> </WithStyles(ForwardRef(Tooltip))>
</AvatarTooltip> </AvatarTooltip>
</span> </span>
</Styled(span)> </Styled(span)>
@@ -399,10 +399,10 @@ exports[`test Developers should render the component for maintainers with items
name="mgol" name="mgol"
version="1.0.0" version="1.0.0"
> >
<WithStyles(Tooltip) <WithStyles(ForwardRef(Tooltip))
title="mgol" title="mgol"
> >
<Tooltip <ForwardRef(Tooltip)
classes={ classes={
Object { Object {
"popper": "MuiTooltip-popper", "popper": "MuiTooltip-popper",
@@ -470,8 +470,8 @@ exports[`test Developers should render the component for maintainers with items
placement="bottom" placement="bottom"
transition={true} transition={true}
/> />
</Tooltip> </ForwardRef(Tooltip)>
</WithStyles(Tooltip)> </WithStyles(ForwardRef(Tooltip))>
</AvatarTooltip> </AvatarTooltip>
</span> </span>
</Styled(span)> </Styled(span)>

View File

@@ -20,7 +20,6 @@ import {
IconButton, IconButton,
OverviewItem, OverviewItem,
PackageList, PackageList,
PackageListItem,
PackageListItemText, PackageListItemText,
PackageTitle, PackageTitle,
Published, Published,
@@ -174,13 +173,13 @@ const Package: React.FC<PackageInterface> = ({
return ( return (
<PackageList className={'package'}> <PackageList className={'package'}>
<ListItem alignItems={'flex-start'}>{renderPackageListItemText()}</ListItem> <ListItem alignItems={'flex-start'}>{renderPackageListItemText()}</ListItem>
<PackageListItem alignItems={'flex-start'} button={true}> <ListItem alignItems={'flex-start'}>
{renderAuthorInfo()} {renderAuthorInfo()}
{renderVersionInfo()} {renderVersionInfo()}
{renderPublishedInfo()} {renderPublishedInfo()}
{renderFileSize()} {renderFileSize()}
{renderLicenseInfo()} {renderLicenseInfo()}
</PackageListItem> </ListItem>
</PackageList> </PackageList>
); );
}; };

View File

@@ -3,7 +3,6 @@ import { Link } from 'react-router-dom';
import Grid from '@material-ui/core/Grid'; import Grid from '@material-ui/core/Grid';
import List from '@material-ui/core/List'; import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText'; import ListItemText from '@material-ui/core/ListItemText';
import MuiIconButton from '@material-ui/core/IconButton'; import MuiIconButton from '@material-ui/core/IconButton';
import Photo from '@material-ui/core/Avatar'; import Photo from '@material-ui/core/Avatar';
@@ -120,6 +119,10 @@ export const PackageList = styled(List)({
'&:hover': { '&:hover': {
backgroundColor: colors.greyLight3, backgroundColor: colors.greyLight3,
}, },
'> :last-child': {
paddingTop: 0,
},
}, },
}); });
@@ -144,12 +147,6 @@ export const TagContainer = styled('span')`
} }
`; `;
export const PackageListItem = styled(ListItem)({
'&&': {
paddingTop: 0,
},
});
export const PackageListItemText = styled(ListItemText)({ export const PackageListItemText = styled(ListItemText)({
'&&': { '&&': {
paddingRight: 0, paddingRight: 0,

View File

@@ -1,35 +1,20 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import { MemoryRouter } from 'react-router';
import Versions from './Versions'; import Versions, { LABEL_CURRENT_TAGS, LABEL_VERSION_HISTORY } from './Versions';
import data from './__partials__/data.json';
import { render, cleanup } from '@testing-library/react';
const mockPackageMeta = jest.fn(() => ({ const mockPackageMeta = jest.fn(() => ({
latest: { packageName: 'foo',
versions: { packageMeta: data,
'1.0.0': {
version: '1.0.0',
},
'2.0.0': {
version: '2.0.0',
},
'3.0.0': {
version: '3.0.0',
},
},
time: {
'1.0.0': '2016-08-26T22:36:41.762Z',
'2.0.0': '2017-08-26T22:36:41.762Z',
'3.0.0': '2018-02-07T06:43:22.801Z',
},
'dist-tags': {
latest: '3.0.0',
},
},
})); }));
jest.mock('../../pages/Version', () => ({ jest.mock('../../pages/Version', () => ({
DetailContextConsumer: component => { DetailContextConsumer: component => {
return component.children({ packageMeta: mockPackageMeta() }); return component.children({ ...mockPackageMeta() });
}, },
})); }));
@@ -38,8 +23,52 @@ describe('<Version /> component', () => {
jest.resetModules(); jest.resetModules();
}); });
test('should render the component in default state', () => { afterEach(() => {
const wrapper = mount(<Versions />); cleanup();
});
// FIXME: this test is not deterministic (writes `N days ago` in the snapshot, where N is random number)
test.skip('should render the component in default state', () => {
const wrapper = mount(
<MemoryRouter>
<Versions />
</MemoryRouter>
);
expect(wrapper.html()).toMatchSnapshot(); expect(wrapper.html()).toMatchSnapshot();
}); });
test('should render versions', () => {
const { getByText } = render(
<MemoryRouter>
<Versions />
</MemoryRouter>
);
expect(getByText(LABEL_VERSION_HISTORY)).toBeTruthy();
expect(getByText(LABEL_CURRENT_TAGS)).toBeTruthy();
// pick some versions
expect(getByText('2.3.0')).toBeTruthy();
expect(getByText('canary')).toBeTruthy();
});
test('should not render versions', () => {
const request = {
packageName: 'foo',
};
// @ts-ignore
mockPackageMeta.mockImplementation(() => request);
const { queryByText } = render(
<MemoryRouter>
<Versions />
</MemoryRouter>
);
expect(queryByText(LABEL_VERSION_HISTORY)).toBeFalsy();
expect(queryByText(LABEL_CURRENT_TAGS)).toBeFalsy();
});
test.todo('should click on version link');
}); });

View File

@@ -1,57 +1,85 @@
import React, { ReactElement } from 'react'; import React, { ReactElement } from 'react';
import List from '@material-ui/core/List'; import List from '@material-ui/core/List';
import { Link as RouterLink } from 'react-router-dom';
import Link from '@material-ui/core/Link';
import ListItem from '@material-ui/core/ListItem'; import ListItem from '@material-ui/core/ListItem';
import { DetailContextConsumer } from '../../pages/Version'; import { DetailContextConsumer } from '../../pages/Version';
import { formatDateDistance } from '../../utils/package'; import { formatDateDistance } from '../../utils/package';
import { DIST_TAGS } from '../../../lib/constants'; import { DIST_TAGS } from '../../../lib/constants';
import { Heading, Spacer, ListItemText } from './styles'; import { Heading, Spacer, ListItemText } from './styles';
const NOT_AVAILABLE = 'Not available'; export const NOT_AVAILABLE = 'Not available';
export const LABEL_CURRENT_TAGS = 'Current Tags';
export const LABEL_VERSION_HISTORY = 'Version History';
class Versions extends React.PureComponent { class Versions extends React.PureComponent {
public render(): ReactElement<HTMLDivElement> { public render(): ReactElement<HTMLDivElement> {
return ( return (
<DetailContextConsumer> <DetailContextConsumer>
{context => { {context => {
return context && context.packageMeta && this.renderContent(context.packageMeta); const { packageMeta, packageName } = context;
if (!packageMeta) {
return null;
}
return this.renderContent(packageMeta, packageName);
}} }}
</DetailContextConsumer> </DetailContextConsumer>
); );
} }
public renderPackageList = (packages: {}, isVersion: boolean = false, timeMap: Record<string, {}> = {}): ReactElement<HTMLDivElement> => { public renderPackageList = (packages: {}, timeMap: Record<string, {}>, packageName): ReactElement<HTMLDivElement> => {
return ( return (
<List> <List dense={true}>
{Object.keys(packages) {Object.keys(packages)
.reverse() .reverse()
.map(version => ( .map(version => (
<ListItem className="version-item" key={version}> <ListItem className="version-item" key={version}>
<ListItemText>{version}</ListItemText> <Link component={RouterLink} to={`/-/web/detail/${packageName}/v/${version}`}>
<ListItemText>{version}</ListItemText>
</Link>
<Spacer /> <Spacer />
{isVersion && <ListItemText>{timeMap[version] ? `${formatDateDistance(timeMap[version])} ago` : NOT_AVAILABLE}</ListItemText>} <ListItemText>{timeMap[version] ? `${formatDateDistance(timeMap[version])} ago` : NOT_AVAILABLE}</ListItemText>
{isVersion === false && <ListItemText>{packages[version]}</ListItemText>}
</ListItem> </ListItem>
))} ))}
</List> </List>
); );
}; };
public renderContent(packageMeta): ReactElement<HTMLDivElement> { public renderTagList = (packages: {}): ReactElement<HTMLDivElement> => {
return (
<List dense={true}>
{Object.keys(packages)
.reverse()
.map(tag => (
<ListItem className="version-item" key={tag}>
<ListItemText>{tag}</ListItemText>
<Spacer />
<ListItemText>{packages[tag]}</ListItemText>
</ListItem>
))}
</List>
);
};
public renderContent(packageMeta, packageName): ReactElement<HTMLDivElement> {
const { versions = {}, time: timeMap = {}, [DIST_TAGS]: distTags = {} } = packageMeta; const { versions = {}, time: timeMap = {}, [DIST_TAGS]: distTags = {} } = packageMeta;
return ( return (
<> <>
{distTags && ( {distTags && (
<> <>
<Heading variant="subtitle1">{'Current Tags'}</Heading> <Heading variant="subtitle1">{LABEL_CURRENT_TAGS}</Heading>
{this.renderPackageList(distTags, false, timeMap)} {this.renderTagList(distTags)}
</> </>
)} )}
{versions && ( {versions && (
<> <>
<Heading variant="subtitle1">{'Version History'}</Heading> <Heading variant="subtitle1">{LABEL_VERSION_HISTORY}</Heading>
{this.renderPackageList(versions, true, timeMap)} {this.renderPackageList(versions, timeMap, packageName)}
</> </>
)} )}
</> </>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -19,10 +19,27 @@ export function getRouterPackageName(params): string {
return packageName; return packageName;
} }
function fillTitle(text) {
return `Verdaccio - ${text}`;
}
function isVersionValid(packageMeta, packageVersion): boolean {
const hasVersion = typeof packageVersion !== 'undefined';
if (!hasVersion) {
// if is undefined, that means versions does not exist, we continue
return true;
}
const hasMatchVersion = Object.keys(packageMeta.versions).includes(packageVersion);
return hasMatchVersion;
}
const Version = ({ match: { params } }) => { const Version = ({ match: { params } }) => {
const pkgName = getRouterPackageName(params); const pkgName = getRouterPackageName(params);
const [readMe, setReadme] = useState(); const [readMe, setReadme] = useState();
const [packageName, setPackageName] = useState(pkgName); const [packageName, setPackageName] = useState(pkgName);
// eslint-disable-next-line no-unused-vars
const [packageVersion, setPackageVersion] = useState(params.version);
const [packageMeta, setPackageMeta] = useState(); const [packageMeta, setPackageMeta] = useState();
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [notFound, setNotFound] = useState(false); const [notFound, setNotFound] = useState(false);
@@ -30,27 +47,37 @@ const Version = ({ match: { params } }) => {
useEffect(() => { useEffect(() => {
(async () => { (async () => {
try { try {
const packageMeta = (await callDetailPage(packageName)) as Partial<StateInterface>; const packageMeta = (await callDetailPage(packageName, packageVersion)) as Partial<StateInterface>;
const readMe = (await callReadme(packageName)) as Partial<StateInterface>; const readMe = (await callReadme(packageName, packageVersion)) as Partial<StateInterface>;
setReadme(readMe); if (isVersionValid(packageMeta, packageVersion)) {
setPackageMeta(packageMeta); setReadme(readMe);
setIsLoading(false); setPackageMeta(packageMeta);
setIsLoading(false);
} else {
setIsLoading(false);
setNotFound(true);
}
} catch (error) { } catch (error) {
setNotFound(true); setNotFound(true);
setIsLoading(false); setIsLoading(false);
} }
})(); })();
}, [packageName]); }, [packageName, packageVersion]);
useEffect(() => { useEffect(() => {
document.title = `Verdaccio - ${packageName}`; if (!packageVersion) {
}, [packageName]); document.title = fillTitle(packageName);
} else {
document.title = fillTitle(`${packageName}@${packageVersion}`);
}
}, [packageName, packageVersion]);
useEffect(() => { useEffect(() => {
const pkgName = getRouterPackageName(params); const pkgName = getRouterPackageName(params);
setPackageName(pkgName); setPackageName(pkgName);
}, [params]); setPackageVersion(params.version);
}, [params, setPackageName, setPackageVersion]);
const isNotFound = notFound || typeof packageMeta === 'undefined' || typeof packageName === 'undefined' || typeof readMe === 'undefined'; const isNotFound = notFound || typeof packageMeta === 'undefined' || typeof packageName === 'undefined' || typeof readMe === 'undefined';
const renderContent = (): React.ReactElement<HTMLElement> => { const renderContent = (): React.ReactElement<HTMLElement> => {
@@ -63,7 +90,9 @@ const Version = ({ match: { params } }) => {
} }
}; };
return <DetailContextProvider value={{ packageMeta, readMe, packageName, enableLoading: setIsLoading }}>{renderContent()}</DetailContextProvider>; return (
<DetailContextProvider value={{ packageMeta, packageVersion, readMe, packageName, enableLoading: setIsLoading }}>{renderContent()}</DetailContextProvider>
);
}; };
export default Version; export default Version;

View File

@@ -2,6 +2,7 @@ import { PackageMetaInterface } from '../../../types/packageMeta';
export interface DetailContextProps { export interface DetailContextProps {
packageMeta: PackageMetaInterface; packageMeta: PackageMetaInterface;
packageVersion?: string;
readMe: string; readMe: string;
packageName: string; packageName: string;
enableLoading: () => void; enableLoading: () => void;
@@ -11,6 +12,7 @@ export interface VersionPageConsumerProps {
packageMeta: PackageMetaInterface; packageMeta: PackageMetaInterface;
readMe: string; readMe: string;
packageName: string; packageName: string;
packageVersion?: string;
// FIXME: looking for the appropiated type here // FIXME: looking for the appropiated type here
enableLoading: any; enableLoading: any;
} }

View File

@@ -31,6 +31,8 @@ class RouterApp extends Component<RouterAppProps> {
<Route exact={true} path={'/'} render={this.renderHomePage} /> <Route exact={true} path={'/'} render={this.renderHomePage} />
<Route exact={true} path={'/-/web/detail/@:scope/:package'} render={this.renderVersionPage} /> <Route exact={true} path={'/-/web/detail/@:scope/:package'} render={this.renderVersionPage} />
<Route exact={true} path={'/-/web/detail/:package'} render={this.renderVersionPage} /> <Route exact={true} path={'/-/web/detail/:package'} render={this.renderVersionPage} />
<Route exact={true} path={'/-/web/detail/:package/v/:version'} render={this.renderVersionPage} />
<Route exact={true} path={'/-/web/detail/@:scope/:package/v/:version'} render={this.renderVersionPage} />
<Route component={NotFound} /> <Route component={NotFound} />
</Switch> </Switch>
</> </>

View File

@@ -1 +0,0 @@
@import '~typeface-roboto';

View File

@@ -1,12 +1,12 @@
import API from './api'; import API from './api';
import { PackageMetaInterface } from 'types/packageMeta'; import { PackageMetaInterface } from 'types/packageMeta';
export async function callReadme(packageName): Promise<string | {}> { export async function callReadme(packageName, packageVersion?: string): Promise<string | {}> {
return await API.request<string | {}>(`package/readme/${packageName}`, 'GET'); return await API.request<string | {}>(`package/readme/${packageName}${packageVersion ? `?v=${packageVersion}` : ''}`, 'GET');
} }
export async function callDetailPage(packageName): Promise<PackageMetaInterface | {}> { export async function callDetailPage(packageName: string, packageVersion?: string): Promise<PackageMetaInterface | {}> {
const packageMeta = await API.request<PackageMetaInterface | {}>(`sidebar/${packageName}`, 'GET'); const packageMeta = await API.request<PackageMetaInterface | {}>(`sidebar/${packageName}${packageVersion ? `?v=${packageVersion}` : ''}`, 'GET');
return packageMeta; return packageMeta;
} }

View File

@@ -18,7 +18,9 @@ new WebpackDevServer(compiler, {
contentBase: `${env.DIST_PATH}`, contentBase: `${env.DIST_PATH}`,
publicPath: config.output.publicPath, publicPath: config.output.publicPath,
hot: true, hot: true,
historyApiFallback: true, historyApiFallback: {
disableDotRule: true,
},
quiet: true, quiet: true,
noInfo: false, noInfo: false,
stats: { stats: {

View File

@@ -66,7 +66,7 @@ module.exports = {
test: /\.(woff|woff2|eot|ttf|otf)$/, test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: 'url-loader', loader: 'url-loader',
options: { options: {
name: 'fonts/[name].[ext]', name: '/fonts/[name].[ext]',
limit: 50, limit: 50,
}, },
}, },

5673
yarn.lock

File diff suppressed because it is too large Load Diff