mirror of
https://github.com/SomboChea/ui
synced 2026-01-19 01:25:51 +07:00
Compare commits
16 Commits
v0.3.11
...
feat-dark-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f761e36669 | ||
|
|
26dbf3d921 | ||
|
|
7cb20fa699 | ||
|
|
e6aad5370f | ||
|
|
d481f54948 | ||
|
|
e6e9cfb2b4 | ||
|
|
6570e3fba1 | ||
|
|
d4f2720994 | ||
|
|
1eca1f4079 | ||
|
|
164cea6c10 | ||
|
|
dad44c46c0 | ||
|
|
222ffed022 | ||
|
|
ee1c3f08eb | ||
|
|
1531cb6226 | ||
|
|
e514ec95a6 | ||
|
|
6b322ad553 |
11
.github/workflows/security.yml
vendored
Normal file
11
.github/workflows/security.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
name: Security Flow
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
security:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@master
|
||||||
|
- name: Run Snyk to check for vulnerabilities
|
||||||
|
uses: snyk/actions/node@0.1.0
|
||||||
|
env:
|
||||||
|
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||||
18
CHANGELOG.md
18
CHANGELOG.md
@@ -2,6 +2,24 @@
|
|||||||
|
|
||||||
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.13](https://github.com/verdaccio/ui/compare/v0.3.12...v0.3.13) (2020-02-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* do not capitalize heading - closes [#428](https://github.com/verdaccio/ui/issues/428) ([#431](https://github.com/verdaccio/ui/issues/431)) ([d481f54](https://github.com/verdaccio/ui/commit/d481f549484361c1d1bc011e0858e8f99b8a2528))
|
||||||
|
* package list refresh based on logged-in user ([#415](https://github.com/verdaccio/ui/issues/415)) ([222ffed](https://github.com/verdaccio/ui/commit/222ffed0226f5aaa62f2d5b91bb08717b2aa24ef)), closes [#414](https://github.com/verdaccio/ui/issues/414) [#414](https://github.com/verdaccio/ui/issues/414)
|
||||||
|
* reload packages on log in ([#421](https://github.com/verdaccio/ui/issues/421)) ([1eca1f4](https://github.com/verdaccio/ui/commit/1eca1f40797790e87d9592204ca061527d09c4ae))
|
||||||
|
* typo ([#423](https://github.com/verdaccio/ui/issues/423)) ([164cea6](https://github.com/verdaccio/ui/commit/164cea6c10804c1d2097c2a582eb3e1e51814d4a))
|
||||||
|
* update dependencies ([#420](https://github.com/verdaccio/ui/issues/420)) ([ee1c3f0](https://github.com/verdaccio/ui/commit/ee1c3f08eb16da2313d8841cfab18358d7f4ea10))
|
||||||
|
|
||||||
|
### [0.3.12](https://github.com/verdaccio/ui/compare/v0.3.11...v0.3.12) (2020-01-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* generate correct registry URL ([#413](https://github.com/verdaccio/ui/issues/413)) ([6b322ad](https://github.com/verdaccio/ui/commit/6b322ad553e9fb3ee65b2968dcfe856ba42a0bfb)), closes [#300](https://github.com/verdaccio/ui/issues/300) [#311](https://github.com/verdaccio/ui/issues/311)
|
||||||
|
|
||||||
### [0.3.11](https://github.com/verdaccio/ui/compare/v0.3.10...v0.3.11) (2020-01-08)
|
### [0.3.11](https://github.com/verdaccio/ui/compare/v0.3.10...v0.3.11) (2020-01-08)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
[](https://stackshare.io/verdaccio)
|
[](https://stackshare.io/verdaccio)
|
||||||
[](http://chat.verdaccio.org/)
|
[](http://chat.verdaccio.org/)
|
||||||
[](https://www.npmjs.com/package/@verdaccio/ui-theme)
|
[](https://www.npmjs.com/package/@verdaccio/ui-theme)
|
||||||

|
[](./LICENSE)
|
||||||
[](https://crowdin.com/project/verdaccio)
|
[](https://crowdin.com/project/verdaccio)
|
||||||
[](https://codecov.io/gh/verdaccio/ui)
|
[](https://codecov.io/gh/verdaccio/ui)
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
require.requireActual('babel/polyfill');
|
jest.requireActual('babel/polyfill');
|
||||||
|
|||||||
@@ -8,14 +8,13 @@ import Adapter from 'enzyme-adapter-react-16';
|
|||||||
import { GlobalWithFetchMock } from 'jest-fetch-mock';
|
import { GlobalWithFetchMock } from 'jest-fetch-mock';
|
||||||
import 'mutationobserver-shim';
|
import 'mutationobserver-shim';
|
||||||
|
|
||||||
// @ts-ignore : Only a void function can be called with the 'new' keyword
|
|
||||||
configure({ adapter: new Adapter() });
|
configure({ adapter: new Adapter() });
|
||||||
|
|
||||||
// @ts-ignore : Property '__APP_VERSION__' does not exist on type 'Global'.
|
// @ts-ignore : Property '__APP_VERSION__' does not exist on type 'Global'.
|
||||||
global.__APP_VERSION__ = '1.0.0';
|
global.__APP_VERSION__ = '1.0.0';
|
||||||
// @ts-ignore : Property '__VERDACCIO_BASENAME_UI_OPTIONS' does not exist on type 'Global'.
|
// @ts-ignore : Property '__VERDACCIO_BASENAME_UI_OPTIONS' does not exist on type 'Global'.
|
||||||
global.__VERDACCIO_BASENAME_UI_OPTIONS = {};
|
global.__VERDACCIO_BASENAME_UI_OPTIONS = { base: 'http://localhost' };
|
||||||
|
// @ts-ignore : Property 'VERDACCIO_API_URL' does not exist on type 'Global'.
|
||||||
global.VERDACCIO_API_URL = 'https://verdaccio.tld';
|
global.VERDACCIO_API_URL = 'https://verdaccio.tld';
|
||||||
|
|
||||||
const customGlobal: GlobalWithFetchMock = global as GlobalWithFetchMock;
|
const customGlobal: GlobalWithFetchMock = global as GlobalWithFetchMock;
|
||||||
|
|||||||
57
package.json
57
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@verdaccio/ui-theme",
|
"name": "@verdaccio/ui-theme",
|
||||||
"version": "0.3.11",
|
"version": "0.3.13",
|
||||||
"description": "Verdaccio User Interface",
|
"description": "Verdaccio User Interface",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Verdaccio Core Team",
|
"name": "Verdaccio Core Team",
|
||||||
@@ -13,10 +13,10 @@
|
|||||||
"homepage": "https://verdaccio.org",
|
"homepage": "https://verdaccio.org",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-nullish-coalescing-operator": "7.7.4",
|
"@babel/plugin-proposal-nullish-coalescing-operator": "7.8.0",
|
||||||
"@babel/plugin-proposal-optional-chaining": "7.7.5",
|
"@babel/plugin-proposal-optional-chaining": "7.8.0",
|
||||||
"@commitlint/cli": "8.2.0",
|
"@commitlint/cli": "8.3.4",
|
||||||
"@commitlint/config-conventional": "8.2.0",
|
"@commitlint/config-conventional": "8.3.4",
|
||||||
"@emotion/core": "10.0.22",
|
"@emotion/core": "10.0.22",
|
||||||
"@emotion/styled": "10.0.23",
|
"@emotion/styled": "10.0.23",
|
||||||
"@material-ui/core": "4.8.0",
|
"@material-ui/core": "4.8.0",
|
||||||
@@ -29,33 +29,33 @@
|
|||||||
"@types/jest": "24.0.24",
|
"@types/jest": "24.0.24",
|
||||||
"@types/js-base64": "2.3.1",
|
"@types/js-base64": "2.3.1",
|
||||||
"@types/lodash": "4.14.149",
|
"@types/lodash": "4.14.149",
|
||||||
"@types/node": "12.12.21",
|
"@types/node": "13.1.6",
|
||||||
"@types/react": "16.9.17",
|
"@types/react": "16.9.17",
|
||||||
"@types/react-autosuggest": "9.3.13",
|
"@types/react-autosuggest": "9.3.13",
|
||||||
"@types/react-dom": "16.9.4",
|
"@types/react-dom": "16.9.4",
|
||||||
"@types/react-router-dom": "5.1.3",
|
"@types/react-router-dom": "5.1.3",
|
||||||
"@types/request": "2.48.4",
|
"@types/request": "2.48.4",
|
||||||
"@types/validator": "12.0.1",
|
"@types/validator": "12.0.1",
|
||||||
"@types/webpack-env": "1.14.1",
|
"@types/webpack-env": "1.15.0",
|
||||||
"@typescript-eslint/parser": "2.12.0",
|
"@typescript-eslint/parser": "2.18.0",
|
||||||
"@verdaccio/babel-preset": "8.4.2",
|
"@verdaccio/babel-preset": "9.0.0",
|
||||||
"@verdaccio/commons-api": "8.4.2",
|
"@verdaccio/commons-api": "9.0.0",
|
||||||
"@verdaccio/eslint-config": "8.4.2",
|
"@verdaccio/eslint-config": "8.4.2",
|
||||||
"@verdaccio/types": "8.4.2",
|
"@verdaccio/types": "9.0.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.3.6",
|
"codeceptjs": "2.4.0",
|
||||||
"codecov": "3.6.1",
|
"codecov": "3.6.5",
|
||||||
"concurrently": "5.0.2",
|
"concurrently": "5.0.2",
|
||||||
"cross-env": "6.0.3",
|
"cross-env": "6.0.3",
|
||||||
"css-loader": "3.4.0",
|
"css-loader": "3.4.2",
|
||||||
"dayjs": "1.8.18",
|
"dayjs": "1.8.19",
|
||||||
"detect-secrets": "1.0.5",
|
"detect-secrets": "1.0.5",
|
||||||
"emotion": "10.0.23",
|
"emotion": "10.0.27",
|
||||||
"emotion-theming": "10.0.19",
|
"emotion-theming": "10.0.27",
|
||||||
"enzyme": "3.10.0",
|
"enzyme": "3.11.0",
|
||||||
"enzyme-adapter-react-16": "1.15.1",
|
"enzyme-adapter-react-16": "1.15.2",
|
||||||
"enzyme-to-json": "3.4.3",
|
"enzyme-to-json": "3.4.3",
|
||||||
"eslint": "6.7.2",
|
"eslint": "6.7.2",
|
||||||
"eslint-plugin-codeceptjs": "1.2.0",
|
"eslint-plugin-codeceptjs": "1.2.0",
|
||||||
@@ -74,16 +74,16 @@
|
|||||||
"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",
|
||||||
"jest-emotion": "10.0.26",
|
"jest-emotion": "10.0.27",
|
||||||
"jest-environment-jsdom": "24.9.0",
|
"jest-environment-jsdom": "24.9.0",
|
||||||
"jest-environment-jsdom-global": "1.2.0",
|
"jest-environment-jsdom-global": "1.2.0",
|
||||||
"jest-environment-node": "24.9.0",
|
"jest-environment-node": "25.1.0",
|
||||||
"jest-fetch-mock": "2.1.2",
|
"jest-fetch-mock": "3.0.1",
|
||||||
"js-base64": "2.5.1",
|
"js-base64": "2.5.1",
|
||||||
"js-yaml": "3.13.1",
|
"js-yaml": "3.13.1",
|
||||||
"lint-staged": "9.5.0",
|
"lint-staged": "9.5.0",
|
||||||
"localstorage-memory": "1.0.3",
|
"localstorage-memory": "1.0.3",
|
||||||
"lockfile-lint": "3.0.3",
|
"lockfile-lint": "3.0.5",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"mini-css-extract-plugin": "0.9.0",
|
"mini-css-extract-plugin": "0.9.0",
|
||||||
"mutationobserver-shim": "0.3.3",
|
"mutationobserver-shim": "0.3.3",
|
||||||
@@ -113,15 +113,15 @@
|
|||||||
"stylelint-webpack-plugin": "1.1.2",
|
"stylelint-webpack-plugin": "1.1.2",
|
||||||
"supertest": "4.0.2",
|
"supertest": "4.0.2",
|
||||||
"typeface-roboto": "0.0.75",
|
"typeface-roboto": "0.0.75",
|
||||||
"typescript": "3.7.3",
|
"typescript": "3.7.4",
|
||||||
"uglifyjs-webpack-plugin": "2.2.0",
|
"uglifyjs-webpack-plugin": "2.2.0",
|
||||||
"url-loader": "3.0.0",
|
"url-loader": "3.0.0",
|
||||||
"validator": "12.1.0",
|
"validator": "12.1.0",
|
||||||
"verdaccio": "4.4.0",
|
"verdaccio": "4.4.2",
|
||||||
"verdaccio-auth-memory": "8.4.2",
|
"verdaccio-auth-memory": "9.0.0",
|
||||||
"verdaccio-memory": "8.4.2",
|
"verdaccio-memory": "9.0.0",
|
||||||
"wait-on": "3.3.0",
|
"wait-on": "3.3.0",
|
||||||
"webpack": "4.41.4",
|
"webpack": "4.41.5",
|
||||||
"webpack-bundle-analyzer": "3.6.0",
|
"webpack-bundle-analyzer": "3.6.0",
|
||||||
"webpack-bundle-size-analyzer": "3.1.0",
|
"webpack-bundle-size-analyzer": "3.1.0",
|
||||||
"webpack-cli": "3.3.10",
|
"webpack-cli": "3.3.10",
|
||||||
@@ -171,6 +171,7 @@
|
|||||||
"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\"",
|
||||||
"test:e2e": "cross-env BABEL_ENV=test jest --config ./test/jest.config.e2e.js",
|
"test:e2e": "cross-env BABEL_ENV=test jest --config ./test/jest.config.e2e.js",
|
||||||
"test": "cross-env NODE_ENV=test BABEL_ENV=test TZ=UTC jest --config ./jest/jest.config.js --maxWorkers 2 --passWithNoTests",
|
"test": "cross-env NODE_ENV=test BABEL_ENV=test TZ=UTC jest --config ./jest/jest.config.js --maxWorkers 2 --passWithNoTests",
|
||||||
|
"test:update-snapshot": "npm run test -- -u",
|
||||||
"test:size": "bundlesize",
|
"test:size": "bundlesize",
|
||||||
"lint": "npm run lint:js && npm run lint:css && npm run lint:lockfile",
|
"lint": "npm run lint:js && npm run lint:css && npm run lint:lockfile",
|
||||||
"lint:js": "npm run type-check && eslint . --ext .js,.ts,.tsx",
|
"lint:js": "npm run type-check && eslint . --ext .js,.ts,.tsx",
|
||||||
|
|||||||
@@ -5,11 +5,9 @@ import { Router } from 'react-router-dom';
|
|||||||
|
|
||||||
import storage from '../utils/storage';
|
import storage from '../utils/storage';
|
||||||
import { isTokenExpire } from '../utils/login';
|
import { isTokenExpire } from '../utils/login';
|
||||||
import API from '../utils/api';
|
|
||||||
import Header from '../components/Header';
|
import Header from '../components/Header';
|
||||||
import Footer from '../components/Footer';
|
import Footer from '../components/Footer';
|
||||||
import Box from '../muiComponents/Box';
|
import Box from '../muiComponents/Box';
|
||||||
import Loading from '../components/Loading';
|
|
||||||
import StyleBaseline from '../design-tokens/StyleBaseline';
|
import StyleBaseline from '../design-tokens/StyleBaseline';
|
||||||
import { Theme } from '../design-tokens/theme';
|
import { Theme } from '../design-tokens/theme';
|
||||||
|
|
||||||
@@ -17,7 +15,7 @@ import AppContextProvider from './AppContextProvider';
|
|||||||
import AppRoute, { history } from './AppRoute';
|
import AppRoute, { history } from './AppRoute';
|
||||||
|
|
||||||
const StyledBox = styled(Box)<{ theme?: Theme }>(({ theme }) => ({
|
const StyledBox = styled(Box)<{ theme?: Theme }>(({ theme }) => ({
|
||||||
backgroundColor: theme && theme.palette.white,
|
backgroundColor: theme && theme.palette.backgroundBody,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledBoxContent = styled(Box)<{ theme?: Theme }>(({ theme }) => ({
|
const StyledBoxContent = styled(Box)<{ theme?: Theme }>(({ theme }) => ({
|
||||||
@@ -33,11 +31,9 @@ const StyledBoxContent = styled(Box)<{ theme?: Theme }>(({ theme }) => ({
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [user, setUser] = useState();
|
const [user, setUser] = useState();
|
||||||
const [packages, setPackages] = useState([]);
|
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logouts user
|
* Logout user
|
||||||
* Required by: <Header />
|
* Required by: <Header />
|
||||||
*/
|
*/
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
@@ -59,46 +55,26 @@ const App: React.FC = () => {
|
|||||||
setUser({ username });
|
setUser({ username });
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadOnHandler = async () => {
|
|
||||||
try {
|
|
||||||
const packages = await API.request('packages', 'GET');
|
|
||||||
// FIXME add correct type for package
|
|
||||||
setPackages(packages as never[]);
|
|
||||||
} catch (error) {
|
|
||||||
// FIXME: add dialog
|
|
||||||
console.error({
|
|
||||||
title: 'Warning',
|
|
||||||
message: `Unable to load package list: ${error.message}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsLoading(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
checkUserAlreadyLoggedIn();
|
checkUserAlreadyLoggedIn();
|
||||||
loadOnHandler();
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<StyleBaseline />
|
<StyleBaseline />
|
||||||
<StyledBox display="flex" flexDirection="column" height="100%">
|
<StyledBox display="flex" flexDirection="column" height="100%">
|
||||||
{isLoading ? (
|
<>
|
||||||
<Loading />
|
<Router history={history}>
|
||||||
) : (
|
<AppContextProvider user={user}>
|
||||||
<>
|
<Header />
|
||||||
<Router history={history}>
|
<StyledBoxContent flexGrow={1}>
|
||||||
<AppContextProvider packages={packages} user={user}>
|
{/* eslint-disable-next-line react/jsx-max-depth */}
|
||||||
<Header />
|
<AppRoute />
|
||||||
<StyledBoxContent flexGrow={1}>
|
</StyledBoxContent>
|
||||||
<AppRoute />
|
</AppContextProvider>
|
||||||
</StyledBoxContent>
|
</Router>
|
||||||
</AppContextProvider>
|
<Footer />
|
||||||
</Router>
|
</>
|
||||||
<Footer />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</StyledBox>
|
</StyledBox>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { createContext } from 'react';
|
|||||||
export interface AppProps {
|
export interface AppProps {
|
||||||
user?: User;
|
user?: User;
|
||||||
scope: string;
|
scope: string;
|
||||||
packages: any[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
|
|||||||
@@ -3,15 +3,13 @@ import React, { useState, useEffect } from 'react';
|
|||||||
import AppContext, { AppProps, User } from './AppContext';
|
import AppContext, { AppProps, User } from './AppContext';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
packages: any[];
|
|
||||||
user?: User;
|
user?: User;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
const AppContextProvider: React.FC<Props> = ({ children, packages, user }) => {
|
const AppContextProvider: React.FC<Props> = ({ children, user }) => {
|
||||||
const [state, setState] = useState<AppProps>({
|
const [state, setState] = useState<AppProps>({
|
||||||
scope: window.VERDACCIO_SCOPE || '',
|
scope: window.VERDACCIO_SCOPE || '',
|
||||||
packages,
|
|
||||||
user,
|
user,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -22,13 +20,6 @@ const AppContextProvider: React.FC<Props> = ({ children, packages, user }) => {
|
|||||||
});
|
});
|
||||||
}, [user]);
|
}, [user]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setState({
|
|
||||||
...state,
|
|
||||||
packages,
|
|
||||||
});
|
|
||||||
}, [packages]);
|
|
||||||
|
|
||||||
const setUser = (user?: User) => {
|
const setUser = (user?: User) => {
|
||||||
setState({
|
setState({
|
||||||
...state,
|
...state,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const AppRoute: React.FC = () => {
|
|||||||
throw Error('The app Context was not correct used');
|
throw Error('The app Context was not correct used');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { user, packages } = appContext;
|
const { user } = appContext;
|
||||||
|
|
||||||
const isUserLoggedIn = user && user.username;
|
const isUserLoggedIn = user && user.username;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ const AppRoute: React.FC = () => {
|
|||||||
<Suspense fallback={<Loading />}>
|
<Suspense fallback={<Loading />}>
|
||||||
<Switch>
|
<Switch>
|
||||||
<ReactRouterDomRoute exact={true} path={Route.ROOT}>
|
<ReactRouterDomRoute exact={true} path={Route.ROOT}>
|
||||||
<HomePage isUserLoggedIn={!!isUserLoggedIn} packages={packages || []} />
|
<HomePage isUserLoggedIn={!!isUserLoggedIn} />
|
||||||
</ReactRouterDomRoute>
|
</ReactRouterDomRoute>
|
||||||
<ReactRouterDomRoute exact={true} path={Route.PACKAGE}>
|
<ReactRouterDomRoute exact={true} path={Route.PACKAGE}>
|
||||||
<VersionContextProvider>
|
<VersionContextProvider>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@ import Box from '../../muiComponents/Box';
|
|||||||
import DetailContainerTabs from './DetailContainerTabs';
|
import DetailContainerTabs from './DetailContainerTabs';
|
||||||
import DetailContainerContent from './DetailContainerContent';
|
import DetailContainerContent from './DetailContainerContent';
|
||||||
import { TabPosition } from './tabs';
|
import { TabPosition } from './tabs';
|
||||||
|
import { DetailTheme } from './styles';
|
||||||
|
|
||||||
const DetailContainer: React.FC = () => {
|
const DetailContainer: React.FC = () => {
|
||||||
const [tabPosition, setTabPosition] = useState(TabPosition.README);
|
const [tabPosition, setTabPosition] = useState(TabPosition.README);
|
||||||
@@ -23,10 +24,12 @@ const DetailContainer: React.FC = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box component="div" display="flex" flexDirection="column" padding={2}>
|
<Box component="div" display="flex" flexDirection="column">
|
||||||
<DetailContainerTabs onChangeTabPosition={handleChangeTabPosition} tabPosition={tabPosition} />
|
<DetailContainerTabs onChangeTabPosition={handleChangeTabPosition} tabPosition={tabPosition} />
|
||||||
<DetailContainerContent readDescription={readMe} tabPosition={tabPosition} />
|
<DetailTheme>
|
||||||
</Box>
|
<DetailContainerContent readDescription={readMe} tabPosition={tabPosition} />
|
||||||
|
</DetailTheme>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,18 @@ import React from 'react';
|
|||||||
|
|
||||||
import { preventXSS } from '../../utils/sec-utils';
|
import { preventXSS } from '../../utils/sec-utils';
|
||||||
import Readme from '../Readme';
|
import Readme from '../Readme';
|
||||||
|
import { ReadmeSpacing } from './styles';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
description?: string;
|
description?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DetailContainerContentReadme: React.FC<Props> = ({ description }) => {
|
const DetailContainerContentReadme: React.FC<Props> = ({ description }) => {
|
||||||
if (!description) return null;
|
if (!description) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const encodedReadme = preventXSS(description);
|
const encodedReadme = preventXSS(description);
|
||||||
return <Readme description={encodedReadme} />;
|
return <ReadmeSpacing><Readme description={encodedReadme} /></ReadmeSpacing>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DetailContainerContentReadme;
|
export default DetailContainerContentReadme;
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ const DetailContainerTabs: React.FC<Props> = ({ tabPosition, onChangeTabPosition
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<Tabs
|
||||||
indicatorColor={'primary'}
|
indicatorColor={'secondary'}
|
||||||
onChange={onChangeTabPosition}
|
onChange={onChangeTabPosition}
|
||||||
textColor={'primary'}
|
textColor={'secondary'}
|
||||||
value={tabPositionIndex}
|
value={tabPositionIndex}
|
||||||
variant={'fullWidth'}>
|
variant={'fullWidth'}>
|
||||||
<Tab data-testid={'readme-tab'} id={'readme-tab'} label={TabPosition.README} />
|
<Tab data-testid={'readme-tab'} id={'readme-tab'} label={TabPosition.README} />
|
||||||
|
|||||||
11
src/components/DetailContainer/styles.ts
Normal file
11
src/components/DetailContainer/styles.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import { Theme } from '../../design-tokens/theme';
|
||||||
|
|
||||||
|
export const DetailTheme = styled('div')<{ theme?: Theme }>(props => ({
|
||||||
|
backgroundColor: props?.theme?.palette.readmeBackgroundColor,
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const ReadmeSpacing = styled('div')<{ theme?: Theme }>(props => ({
|
||||||
|
padding: '20px',
|
||||||
|
}));
|
||||||
@@ -15,7 +15,6 @@ interface Props {
|
|||||||
const StyledHeading = styled(Heading)({
|
const StyledHeading = styled(Heading)({
|
||||||
fontSize: '1rem',
|
fontSize: '1rem',
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
textTransform: 'capitalize',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const StyledBoxVersion = styled(Box)<{ theme?: Theme }>(({ theme }) => ({
|
const StyledBoxVersion = styled(Box)<{ theme?: Theme }>(({ theme }) => ({
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ describe('<Header /> component with logged in state', () => {
|
|||||||
test('should load the component in logged out state', () => {
|
test('should load the component in logged out state', () => {
|
||||||
const { container, queryByTestId, getByText } = render(
|
const { container, queryByTestId, getByText } = render(
|
||||||
<Router>
|
<Router>
|
||||||
<AppContextProvider packages={props.packages}>
|
<AppContextProvider>
|
||||||
<Header />
|
<Header />
|
||||||
</AppContextProvider>
|
</AppContextProvider>
|
||||||
</Router>
|
</Router>
|
||||||
@@ -32,7 +32,7 @@ describe('<Header /> component with logged in state', () => {
|
|||||||
test('should load the component in logged in state', () => {
|
test('should load the component in logged in state', () => {
|
||||||
const { container, getByTestId, queryByText } = render(
|
const { container, getByTestId, queryByText } = render(
|
||||||
<Router>
|
<Router>
|
||||||
<AppContextProvider packages={props.packages} user={props.user}>
|
<AppContextProvider user={props.user}>
|
||||||
<Header />
|
<Header />
|
||||||
</AppContextProvider>
|
</AppContextProvider>
|
||||||
</Router>
|
</Router>
|
||||||
@@ -46,7 +46,7 @@ describe('<Header /> component with logged in state', () => {
|
|||||||
test('should open login dialog', async () => {
|
test('should open login dialog', async () => {
|
||||||
const { getByText } = render(
|
const { getByText } = render(
|
||||||
<Router>
|
<Router>
|
||||||
<AppContextProvider packages={props.packages}>
|
<AppContextProvider>
|
||||||
<Header />
|
<Header />
|
||||||
</AppContextProvider>
|
</AppContextProvider>
|
||||||
</Router>
|
</Router>
|
||||||
@@ -61,7 +61,7 @@ describe('<Header /> component with logged in state', () => {
|
|||||||
test('should logout the user', async () => {
|
test('should logout the user', async () => {
|
||||||
const { getByText, getByTestId } = render(
|
const { getByText, getByTestId } = render(
|
||||||
<Router>
|
<Router>
|
||||||
<AppContextProvider packages={props.packages} user={props.user}>
|
<AppContextProvider user={props.user}>
|
||||||
<Header />
|
<Header />
|
||||||
</AppContextProvider>
|
</AppContextProvider>
|
||||||
</Router>
|
</Router>
|
||||||
@@ -79,7 +79,7 @@ describe('<Header /> component with logged in state', () => {
|
|||||||
test("The question icon should open a new tab of verdaccio's website - installation doc", () => {
|
test("The question icon should open a new tab of verdaccio's website - installation doc", () => {
|
||||||
const { getByTestId } = render(
|
const { getByTestId } = render(
|
||||||
<Router>
|
<Router>
|
||||||
<AppContextProvider packages={props.packages} user={props.user}>
|
<AppContextProvider user={props.user}>
|
||||||
<Header />
|
<Header />
|
||||||
</AppContextProvider>
|
</AppContextProvider>
|
||||||
</Router>
|
</Router>
|
||||||
@@ -92,7 +92,7 @@ describe('<Header /> component with logged in state', () => {
|
|||||||
test('should open the registrationInfo modal when clicking on the info icon', async () => {
|
test('should open the registrationInfo modal when clicking on the info icon', async () => {
|
||||||
const { getByTestId } = render(
|
const { getByTestId } = render(
|
||||||
<Router>
|
<Router>
|
||||||
<AppContextProvider packages={props.packages} user={props.user}>
|
<AppContextProvider user={props.user}>
|
||||||
<Header />
|
<Header />
|
||||||
</AppContextProvider>
|
</AppContextProvider>
|
||||||
</Router>
|
</Router>
|
||||||
@@ -109,7 +109,7 @@ describe('<Header /> component with logged in state', () => {
|
|||||||
test('should close the registrationInfo modal when clicking on the button close', async () => {
|
test('should close the registrationInfo modal when clicking on the button close', async () => {
|
||||||
const { getByTestId, getByText, queryByTestId } = render(
|
const { getByTestId, getByText, queryByTestId } = render(
|
||||||
<Router>
|
<Router>
|
||||||
<AppContextProvider packages={props.packages} user={props.user}>
|
<AppContextProvider user={props.user}>
|
||||||
<Header />
|
<Header />
|
||||||
</AppContextProvider>
|
</AppContextProvider>
|
||||||
</Router>
|
</Router>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import LoginDialog from './LoginDialog';
|
|||||||
|
|
||||||
const appContextValue: AppContextProps = {
|
const appContextValue: AppContextProps = {
|
||||||
scope: '',
|
scope: '',
|
||||||
packages: [],
|
|
||||||
setUser: jest.fn(),
|
setUser: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import logo from './img/logo.svg';
|
import logo from './img/verdaccio-blackwhite.svg';
|
||||||
|
|
||||||
export enum Size {
|
export enum Size {
|
||||||
|
Tiny = '20px',
|
||||||
Small = '40px',
|
Small = '40px',
|
||||||
Big = '90px',
|
Big = '90px',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="verdaccio"><Title>Verdaccio</Title><defs><path id="b" d="M48 17.6L32.8 48H24L.4.8h15.2l12.8 25.6 4.4-8.8H48z"/><filter x="-20%" y="-11.7%" width="139.9%" height="140.3%" filterUnits="objectBoundingBox" id="a"><feOffset dy="4" in="SourceAlpha" result="shadowOffsetOuter1"/><feGaussianBlur stdDeviation="2.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0906646286 0" in="shadowBlurOuter1"/></filter><path id="d" d="M50.8 12H35.6L41.2.8h15.2L50.8 12z"/><filter x="-45.7%" y="-49.1%" width="191.3%" height="269.6%" filterUnits="objectBoundingBox" id="c"><feOffset dy="4" in="SourceAlpha" result="shadowOffsetOuter1"/><feGaussianBlur stdDeviation="2.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0906646286 0" in="shadowBlurOuter1"/></filter></defs><g fill="none" fill-rule="evenodd"><rect fill="#F7F8F6" width="100" height="100" rx="37"/><g transform="translate(22 29)"><use fill="#000" filter="url(#a)" xlink:href="#b"/><path stroke="#405236" stroke-width="2.4" d="M46.058 18.8H33.542L28.4 29.083 14.858 2H2.342l22.4 44.8h7.316l14-28z" stroke-linejoin="square" fill="#405236"/></g><g transform="translate(22 29)"><use fill="#000" filter="url(#c)" xlink:href="#d"/><path stroke="#CD4000" stroke-width="2.4" d="M50.058 10.8l4.4-8.8H41.942l-4.4 8.8h12.516z" stroke-linejoin="square" fill="#CD4000"/></g><path d="M54.06 75.8l2.575-5.112L36.857 31H24.342l22.4 44.8h7.319z" stroke="#405236" stroke-width="2.4" fill="#4A5E3F"/><path d="M59.6 31h15.221M55.6 35h15.221M51.6 39.8h15.221" stroke="#CD4000" stroke-width="2.4" stroke-linecap="square"/></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.9 KiB |
31
src/components/Logo/img/verdaccio-blackwhite.svg
Normal file
31
src/components/Logo/img/verdaccio-blackwhite.svg
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg" id="verdaccio">
|
||||||
|
<Title>Verdaccio</Title>
|
||||||
|
<rect width="100" height="100" rx="37" fill="black" />
|
||||||
|
<g filter="url(#filter0_d)">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M70 46.7288L54.6723 77H45.7983L22 30L37.3277 30L50.2353 55.4915L54.6723 46.7288H70Z" fill="white" fill-opacity="0.6" />
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter1_d)">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M67.621 41H72.4L78 30H75.621H62.8H58V32.3571H61.6L60.8 33.9286H54V36.2857H59.6L58.4 38.6429H50V41H57.2H67.621Z" fill="white" />
|
||||||
|
</g>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M54.785 77H45.8804L22 30H37.3806L58 70.7175L54.785 77Z" fill="white" />
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d" x="17" y="29" width="58" height="57" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" />
|
||||||
|
<feOffset dy="4" />
|
||||||
|
<feGaussianBlur stdDeviation="2.5" />
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0906646 0" />
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow" />
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape" />
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d" x="45" y="29" width="38" height="21" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" />
|
||||||
|
<feOffset dy="4" />
|
||||||
|
<feGaussianBlur stdDeviation="2.5" />
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0906646 0" />
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow" />
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape" />
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
32
src/components/Logo/img/verdaccio.svg
Normal file
32
src/components/Logo/img/verdaccio.svg
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="verdaccio">
|
||||||
|
<Title>Verdaccio</Title>
|
||||||
|
<defs>
|
||||||
|
<path id="b" d="M48 17.6L32.8 48H24L.4.8h15.2l12.8 25.6 4.4-8.8H48z" />
|
||||||
|
<filter x="-20%" y="-11.7%" width="139.9%" height="140.3%" filterUnits="objectBoundingBox" id="a">
|
||||||
|
<feOffset dy="4" in="SourceAlpha" result="shadowOffsetOuter1" />
|
||||||
|
<feGaussianBlur stdDeviation="2.5" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||||
|
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||||
|
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0906646286 0" in="shadowBlurOuter1" />
|
||||||
|
</filter>
|
||||||
|
<path id="d" d="M50.8 12H35.6L41.2.8h15.2L50.8 12z" />
|
||||||
|
<filter x="-45.7%" y="-49.1%" width="191.3%" height="269.6%" filterUnits="objectBoundingBox" id="c">
|
||||||
|
<feOffset dy="4" in="SourceAlpha" result="shadowOffsetOuter1" />
|
||||||
|
<feGaussianBlur stdDeviation="2.5" in="shadowOffsetOuter1" result="shadowBlurOuter1" />
|
||||||
|
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1" />
|
||||||
|
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0906646286 0" in="shadowBlurOuter1" />
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<rect fill="#F7F8F6" width="100" height="100" rx="37" />
|
||||||
|
<g transform="translate(22 29)">
|
||||||
|
<use fill="#000" filter="url(#a)" xlink:href="#b" />
|
||||||
|
<path stroke="#405236" stroke-width="2.4" d="M46.058 18.8H33.542L28.4 29.083 14.858 2H2.342l22.4 44.8h7.316l14-28z" stroke-linejoin="square" fill="#405236" />
|
||||||
|
</g>
|
||||||
|
<g transform="translate(22 29)">
|
||||||
|
<use fill="#000" filter="url(#c)" xlink:href="#d" />
|
||||||
|
<path stroke="#CD4000" stroke-width="2.4" d="M50.058 10.8l4.4-8.8H41.942l-4.4 8.8h12.516z" stroke-linejoin="square" fill="#CD4000" />
|
||||||
|
</g>
|
||||||
|
<path d="M54.06 75.8l2.575-5.112L36.857 31H24.342l22.4 44.8h7.319z" stroke="#405236" stroke-width="2.4" fill="#4A5E3F" />
|
||||||
|
<path d="M59.6 31h15.221M55.6 35h15.221M51.6 39.8h15.221" stroke="#CD4000" stroke-width="2.4" stroke-linecap="square" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -71,7 +71,7 @@ export const PackageTitle = styled('span')<{ theme?: Theme }>(({ theme }) => ({
|
|||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
display: 'block',
|
display: 'block',
|
||||||
marginBottom: 12,
|
marginBottom: 12,
|
||||||
color: theme && theme.palette.eclipse,
|
color: theme?.palette?.eclipse,
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
':hover': {
|
':hover': {
|
||||||
color: theme && theme.palette.black,
|
color: theme && theme.palette.black,
|
||||||
@@ -117,7 +117,7 @@ export const PackageListItemText = styled(ListItemText)({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const Description = styled(Typography)<{ theme?: Theme }>(props => ({
|
export const Description = styled(Typography)<{ theme?: Theme }>(props => ({
|
||||||
color: props.theme && props.theme.palette.greyDark2,
|
color: props?.theme?.palette.greyDark2,
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
paddingRight: 0,
|
paddingRight: 0,
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,33 +1,24 @@
|
|||||||
import createMuiTheme from '@material-ui/core/styles/createMuiTheme';
|
import createMuiTheme from '@material-ui/core/styles/createMuiTheme';
|
||||||
|
|
||||||
// Main colors
|
import defaultTheme from './themes/default';
|
||||||
// -------------------------
|
import darkTheme from './themes/dark';
|
||||||
const colors = {
|
import { ColorsTheme } from './types';
|
||||||
black: '#000',
|
|
||||||
white: '#fff',
|
|
||||||
red: '#d32f2f',
|
|
||||||
orange: '#CD4000',
|
|
||||||
greySuperLight: '#f5f5f5',
|
|
||||||
greyLight: '#d3d3d3',
|
|
||||||
greyLight2: '#908ba1',
|
|
||||||
greyLight3: '#f3f4f240',
|
|
||||||
greyDark: '#a9a9a9',
|
|
||||||
greyDark2: '#586069',
|
|
||||||
greyChateau: '#95989a',
|
|
||||||
greyGainsboro: '#e3e3e3',
|
|
||||||
greyAthens: '#d3dddd',
|
|
||||||
eclipse: '#3c3c3c',
|
|
||||||
paleNavy: '#e4e8f1',
|
|
||||||
saltpan: '#f7f8f6',
|
|
||||||
snow: '#f9f9f9',
|
|
||||||
love: '#e25555',
|
|
||||||
nobel01: '#999999',
|
|
||||||
nobel02: '#9f9f9f',
|
|
||||||
primary: window.VERDACCIO_PRIMARY_COLOR || '#4b5e40',
|
|
||||||
secondary: '#20232a',
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Colors = keyof typeof colors;
|
function getThemeColors() {
|
||||||
|
// eslint-disable-next-line no-constant-condition
|
||||||
|
if (false) {
|
||||||
|
return defaultTheme;
|
||||||
|
} else {
|
||||||
|
return darkTheme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Colors = ColorsTheme;
|
||||||
|
|
||||||
|
const padding = {
|
||||||
|
light: '16px',
|
||||||
|
regular: '24px',
|
||||||
|
};
|
||||||
|
|
||||||
const fontSize = {
|
const fontSize = {
|
||||||
xxl: 26,
|
xxl: 26,
|
||||||
@@ -72,10 +63,10 @@ export const theme = createMuiTheme({
|
|||||||
fontFamily: 'inherit',
|
fontFamily: 'inherit',
|
||||||
},
|
},
|
||||||
palette: {
|
palette: {
|
||||||
...colors,
|
...getThemeColors(),
|
||||||
primary: { main: colors.primary },
|
primary: { main: getThemeColors().primary },
|
||||||
secondary: { main: colors.secondary },
|
secondary: { main: getThemeColors().secondary },
|
||||||
error: { main: colors.red },
|
error: { main: getThemeColors().red },
|
||||||
},
|
},
|
||||||
...customizedTheme,
|
...customizedTheme,
|
||||||
});
|
});
|
||||||
|
|||||||
30
src/design-tokens/themes/dark.ts
Normal file
30
src/design-tokens/themes/dark.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
const colors = {
|
||||||
|
black: '#000',
|
||||||
|
white: '#fff',
|
||||||
|
red: '#d32f2f',
|
||||||
|
orange: '#CD4000',
|
||||||
|
greySuperLight: '#f5f5f5',
|
||||||
|
greyLight: '#d3d3d3',
|
||||||
|
greyLight2: '#908ba1',
|
||||||
|
greyLight3: '#f3f4f240',
|
||||||
|
greyDark: '#a9a9a9',
|
||||||
|
greyDark2: '#fff',
|
||||||
|
greyChateau: '#95989a',
|
||||||
|
greyGainsboro: '#e3e3e3',
|
||||||
|
greyAthens: '#d3dddd',
|
||||||
|
eclipse: '#fff',
|
||||||
|
paleNavy: '#e4e8f1',
|
||||||
|
saltpan: '#f7f8f6',
|
||||||
|
snow: '#f9f9f9',
|
||||||
|
love: '#e25555',
|
||||||
|
nobel01: '#999999',
|
||||||
|
nobel02: '#9f9f9f',
|
||||||
|
primary: '#000000',
|
||||||
|
secondary: '#ffffff',
|
||||||
|
// colors based on features
|
||||||
|
backgroundBody: '#000',
|
||||||
|
lightBackgroundColor: '#fff',
|
||||||
|
readmeBackgroundColor: '#fff',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default colors;
|
||||||
28
src/design-tokens/themes/default.ts
Normal file
28
src/design-tokens/themes/default.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
const colors = {
|
||||||
|
black: '#000',
|
||||||
|
white: '#fff',
|
||||||
|
red: '#d32f2f',
|
||||||
|
orange: '#CD4000',
|
||||||
|
greySuperLight: '#f5f5f5',
|
||||||
|
greyLight: '#d3d3d3',
|
||||||
|
greyLight2: '#908ba1',
|
||||||
|
greyLight3: '#f3f4f240',
|
||||||
|
greyDark: '#a9a9a9',
|
||||||
|
greyDark2: '#586069',
|
||||||
|
greyChateau: '#95989a',
|
||||||
|
greyGainsboro: '#e3e3e3',
|
||||||
|
greyAthens: '#d3dddd',
|
||||||
|
eclipse: '#3c3c3c',
|
||||||
|
paleNavy: '#e4e8f1',
|
||||||
|
saltpan: '#f7f8f6',
|
||||||
|
snow: '#f9f9f9',
|
||||||
|
love: '#e25555',
|
||||||
|
nobel01: '#999999',
|
||||||
|
nobel02: '#9f9f9f',
|
||||||
|
primary: window.VERDACCIO_PRIMARY_COLOR || '#4b5e40',
|
||||||
|
secondary: '#20232a',
|
||||||
|
// colors based on features
|
||||||
|
backgroundBody: '#fff',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default colors;
|
||||||
3
src/design-tokens/types.ts
Normal file
3
src/design-tokens/types.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export interface ColorsTheme {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
@@ -1,13 +1,10 @@
|
|||||||
import React, { forwardRef } from 'react';
|
import React, { forwardRef } from 'react';
|
||||||
import { default as MaterialUITypography, TypographyProps } from '@material-ui/core/Typography';
|
import { default as MaterialUITypography } from '@material-ui/core/Typography';
|
||||||
|
|
||||||
|
import { TextProps } from './TextConfig';
|
||||||
|
|
||||||
type TextType = 'subtitle1' | 'subtitle2' | 'body1' | 'body2';
|
|
||||||
type TextRef = HTMLElementTagNameMap[keyof HTMLElementTagNameMap];
|
type TextRef = HTMLElementTagNameMap[keyof HTMLElementTagNameMap];
|
||||||
|
|
||||||
export interface TextProps extends Omit<TypographyProps, 'variant'> {
|
|
||||||
variant?: TextType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The reference is already from type of the Component, so the any below is not a problem
|
// The reference is already from type of the Component, so the any below is not a problem
|
||||||
const Text = forwardRef<TextRef, TextProps>(function Text(props, ref) {
|
const Text = forwardRef<TextRef, TextProps>(function Text(props, ref) {
|
||||||
return <MaterialUITypography {...props} ref={ref} />;
|
return <MaterialUITypography {...props} ref={ref} />;
|
||||||
|
|||||||
7
src/muiComponents/Text/TextConfig.ts
Normal file
7
src/muiComponents/Text/TextConfig.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { TypographyProps } from '@material-ui/core/Typography';
|
||||||
|
|
||||||
|
type TextType = 'subtitle1' | 'subtitle2' | 'body1' | 'body2';
|
||||||
|
|
||||||
|
export interface TextProps extends Omit<TypographyProps, 'variant'> {
|
||||||
|
variant?: TextType;
|
||||||
|
}
|
||||||
@@ -1 +1,2 @@
|
|||||||
export { default, TextProps } from './Text';
|
export { default } from './Text';
|
||||||
|
export { TextProps } from './TextConfig';
|
||||||
|
|||||||
@@ -1,24 +1,6 @@
|
|||||||
import { createContext, Consumer, Provider } from 'react';
|
import { createContext, Consumer, Provider } from 'react';
|
||||||
|
|
||||||
import { PackageMetaInterface } from '../../../types/packageMeta';
|
import { DetailContextProps, VersionPageConsumerProps } from './version-config';
|
||||||
export interface DetailContextProps {
|
|
||||||
packageMeta: PackageMetaInterface;
|
|
||||||
packageVersion?: string;
|
|
||||||
readMe: string;
|
|
||||||
packageName: string;
|
|
||||||
enableLoading: () => void;
|
|
||||||
isLoading: boolean;
|
|
||||||
hasNotBeenFound: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VersionPageConsumerProps {
|
|
||||||
packageMeta: PackageMetaInterface;
|
|
||||||
readMe: string;
|
|
||||||
packageName: string;
|
|
||||||
packageVersion?: string;
|
|
||||||
// FIXME: looking for the appropiated type here
|
|
||||||
enableLoading: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DetailContext = createContext<Partial<DetailContextProps>>({});
|
export const DetailContext = createContext<Partial<DetailContextProps>>({});
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
export {
|
export { DetailContext, DetailContextConsumer, DetailContextProvider } from './context';
|
||||||
DetailContext,
|
export { VersionPageConsumerProps, DetailContextProps } from './version-config';
|
||||||
DetailContextConsumer,
|
|
||||||
DetailContextProvider,
|
|
||||||
DetailContextProps,
|
|
||||||
VersionPageConsumerProps,
|
|
||||||
} from './context';
|
|
||||||
export { default } from './Version';
|
export { default } from './Version';
|
||||||
|
|||||||
19
src/pages/Version/version-config.ts
Normal file
19
src/pages/Version/version-config.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { PackageMetaInterface } from '../../../types/packageMeta';
|
||||||
|
|
||||||
|
export interface DetailContextProps {
|
||||||
|
enableLoading: () => void;
|
||||||
|
hasNotBeenFound: boolean;
|
||||||
|
isLoading: boolean;
|
||||||
|
packageMeta: PackageMetaInterface;
|
||||||
|
packageName: string;
|
||||||
|
packageVersion?: string;
|
||||||
|
readMe: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VersionPageConsumerProps {
|
||||||
|
enableLoading: () => void;
|
||||||
|
packageMeta: PackageMetaInterface;
|
||||||
|
packageName: string;
|
||||||
|
packageVersion?: string;
|
||||||
|
readMe: string;
|
||||||
|
}
|
||||||
@@ -1,17 +1,35 @@
|
|||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { PackageList } from '../../components/PackageList';
|
import { PackageList } from '../../components/PackageList';
|
||||||
import { PackageInterface } from '../../components/Package/Package';
|
import API from '../../utils/api';
|
||||||
|
import Loading from '../../components/Loading';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isUserLoggedIn: boolean;
|
isUserLoggedIn: boolean;
|
||||||
packages: PackageInterface[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Home: React.FC<Props> = ({ packages }) => (
|
const Home: React.FC<Props> = ({ isUserLoggedIn }) => {
|
||||||
<div className="container content">
|
const [packages, setPackages] = useState([]);
|
||||||
<PackageList packages={packages} />
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
</div>
|
const loadPackages = async () => {
|
||||||
);
|
try {
|
||||||
|
const packages = await API.request('packages', 'GET');
|
||||||
|
// FIXME add correct type for package
|
||||||
|
setPackages(packages as never[]);
|
||||||
|
} catch (error) {
|
||||||
|
// FIXME: add dialog
|
||||||
|
console.error({
|
||||||
|
title: 'Warning',
|
||||||
|
message: `Unable to load package list: ${error.message}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setIsLoading(false);
|
||||||
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
loadPackages().then();
|
||||||
|
}, [isUserLoggedIn]);
|
||||||
|
|
||||||
|
return <div className="container content">{isLoading ? <Loading /> : <PackageList packages={packages} />}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
export default Home;
|
export default Home;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export function handleResponseType(response: Response): Promise<[boolean, Blob |
|
|||||||
return Promise.all([response.ok, response.text()]);
|
return Promise.all([response.ok, response.text()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unfortunatelly on download files there is no header available
|
// unfortunately on download files there is no header available
|
||||||
if (response.url && response.url.endsWith('.tgz') === true) {
|
if (response.url && response.url.endsWith('.tgz') === true) {
|
||||||
return Promise.all([response.ok, response.blob()]);
|
return Promise.all([response.ok, response.blob()]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,18 @@ describe('utils', () => {
|
|||||||
expect(isEmail('')).toBeFalsy();
|
expect(isEmail('')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getRegistryURL() - should keep slash if location is a sub directory', () => {
|
test('getRegistryURL() - should not change when location change', () => {
|
||||||
|
expect(getRegistryURL()).toBe('http://localhost');
|
||||||
history.pushState({}, 'page title', '/-/web/detail');
|
history.pushState({}, 'page title', '/-/web/detail');
|
||||||
expect(getRegistryURL()).toBe('http://localhost/-/web/detail');
|
expect(getRegistryURL()).toBe('http://localhost');
|
||||||
history.pushState({}, 'page title', '/');
|
history.pushState({}, 'page title', '/');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getRegistryURL() - should not add slash if location is not a sub directory', () => {
|
test('getRegistryURL() - should change when UI options change', () => {
|
||||||
expect(getRegistryURL()).toBe('http://localhost');
|
expect(getRegistryURL()).toBe('http://localhost');
|
||||||
|
window.__VERDACCIO_BASENAME_UI_OPTIONS.base = 'http://localhost/test';
|
||||||
|
expect(getRegistryURL()).toBe('http://localhost/test');
|
||||||
|
window.__VERDACCIO_BASENAME_UI_OPTIONS.base = 'http://localhost';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import isURLValidator from 'validator/lib/isURL';
|
|||||||
import isEmailValidator from 'validator/lib/isEmail';
|
import isEmailValidator from 'validator/lib/isEmail';
|
||||||
import '../../types';
|
import '../../types';
|
||||||
|
|
||||||
|
const OCTET_STREAM_TYPE = 'application/octet-stream';
|
||||||
|
|
||||||
export function isURL(url: string): boolean {
|
export function isURL(url: string): boolean {
|
||||||
return isURLValidator(url || '', {
|
return isURLValidator(url || '', {
|
||||||
protocols: ['http', 'https', 'git+https'],
|
protocols: ['http', 'https', 'git+https'],
|
||||||
@@ -15,8 +17,7 @@ export function isEmail(email: string): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getRegistryURL(): string {
|
export function getRegistryURL(): string {
|
||||||
// Don't add slash if it's not a sub directory
|
return window.__VERDACCIO_BASENAME_UI_OPTIONS.base;
|
||||||
return `${location.origin}${location.pathname === '/' ? '' : location.pathname}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function extractFileName(url: string): string {
|
export function extractFileName(url: string): string {
|
||||||
@@ -38,9 +39,9 @@ export function downloadFile(fileStream: Blob, fileName: string): void {
|
|||||||
// @ts-ignore. Please see: https://github.com/microsoft/TypeScript/issues/33792
|
// @ts-ignore. Please see: https://github.com/microsoft/TypeScript/issues/33792
|
||||||
if (navigator.msSaveBlob) {
|
if (navigator.msSaveBlob) {
|
||||||
// Detect if Edge
|
// Detect if Edge
|
||||||
file = blobToFile(new Blob([fileStream], { type: 'application/octet-stream' }), fileName);
|
file = blobToFile(new Blob([fileStream], { type: OCTET_STREAM_TYPE }), fileName);
|
||||||
} else {
|
} else {
|
||||||
file = new File([fileStream], fileName, { type: 'application/octet-stream', lastModified: Date.now() });
|
file = new File([fileStream], fileName, { type: OCTET_STREAM_TYPE, lastModified: Date.now() });
|
||||||
}
|
}
|
||||||
|
|
||||||
const objectURL = URL.createObjectURL(file);
|
const objectURL = URL.createObjectURL(file);
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ auth:
|
|||||||
users:
|
users:
|
||||||
foo:
|
foo:
|
||||||
name: test
|
name: test
|
||||||
password: test
|
password: test #pragma: allowlist secret
|
||||||
bar:
|
bar:
|
||||||
name: bar
|
name: bar
|
||||||
password: test
|
password: test #pragma: allowlist secret
|
||||||
security:
|
security:
|
||||||
api:
|
api:
|
||||||
jwt:
|
jwt:
|
||||||
@@ -23,7 +23,7 @@ security:
|
|||||||
web:
|
web:
|
||||||
sign:
|
sign:
|
||||||
expiresIn: 100d
|
expiresIn: 100d
|
||||||
notBefore: 1
|
notBefore: 0
|
||||||
|
|
||||||
uplinks:
|
uplinks:
|
||||||
npmjs:
|
npmjs:
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export default {
|
|||||||
}),
|
}),
|
||||||
new HTMLWebpackPlugin({
|
new HTMLWebpackPlugin({
|
||||||
__UI_OPTIONS: JSON.stringify({
|
__UI_OPTIONS: JSON.stringify({
|
||||||
base: '/',
|
base: new URL('/', 'https://localhost:4872'),
|
||||||
}),
|
}),
|
||||||
title: 'Verdaccio Dev UI',
|
title: 'Verdaccio Dev UI',
|
||||||
scope: '',
|
scope: '',
|
||||||
|
|||||||
Reference in New Issue
Block a user