mirror of
https://github.com/verdaccio/verdaccio.git
synced 2025-04-01 02:42:23 -05:00
Merge pull request #1178 from verdaccio/feat-registry-dialog
feat: register info selector
This commit is contained in:
commit
df755291e6
10 changed files with 161 additions and 30 deletions
|
@ -11,27 +11,12 @@ import type { Node } from 'react';
|
|||
import { IProps } from './types';
|
||||
|
||||
import { ClipBoardCopy, ClipBoardCopyText, CopyIcon } from './styles';
|
||||
|
||||
const copyToClipBoardUtility = (str: string) => (event: SyntheticEvent<HTMLElement>) => {
|
||||
event.preventDefault();
|
||||
const node = document.createElement('div');
|
||||
node.innerText = str;
|
||||
if (document.body) {
|
||||
document.body.appendChild(node);
|
||||
const range = document.createRange();
|
||||
const selection = window.getSelection();
|
||||
range.selectNodeContents(node);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
document.execCommand('copy');
|
||||
// $FlowFixMe
|
||||
document.body.removeChild(node);
|
||||
}
|
||||
};
|
||||
import { copyToClipBoardUtility } from '../../utils/cli-utils';
|
||||
import { TEXT } from '../../utils/constants';
|
||||
|
||||
const CopyToClipBoard = ({ text }: IProps): Node => {
|
||||
const renderToolTipFileCopy = () => (
|
||||
<Tooltip disableFocusListener={true} title={'Copy to Clipboard'}>
|
||||
<Tooltip disableFocusListener={true} title={TEXT.CLIPBOARD_COPY}>
|
||||
<CopyIcon onClick={copyToClipBoardUtility(text)}>
|
||||
<FileCopy />
|
||||
</CopyIcon>
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
import styled from 'react-emotion';
|
||||
import IconButton from '@material-ui/core/IconButton/index';
|
||||
|
||||
export const ClipBoardCopy = styled.p`
|
||||
export const ClipBoardCopy = styled.div`
|
||||
&& {
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
padding: 5px 0 5px 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
@ -26,4 +23,4 @@ export const CopyIcon = styled(IconButton)`
|
|||
&& {
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
`;
|
||||
`;
|
||||
|
|
|
@ -19,10 +19,10 @@ import { default as IconSearch } from '@material-ui/icons/Search';
|
|||
import { getRegistryURL } from '../../utils/url';
|
||||
import Link from '../Link';
|
||||
import Logo from '../Logo';
|
||||
import CopyToClipBoard from '../CopyToClipBoard/index';
|
||||
import RegistryInfoDialog from '../RegistryInfoDialog';
|
||||
import Label from '../Label';
|
||||
import Search from '../Search';
|
||||
import RegistryInfoContent from '../RegistryInfoContent';
|
||||
|
||||
import { IProps, IState } from './types';
|
||||
import type { ToolTipType } from './types';
|
||||
|
@ -222,10 +222,7 @@ class Header extends Component<IProps, IState> {
|
|||
const { openInfoDialog, registryUrl } = this.state;
|
||||
return (
|
||||
<RegistryInfoDialog onClose={this.handleCloseRegistryInfoDialog} open={openInfoDialog}>
|
||||
<div>
|
||||
<CopyToClipBoard text={`npm set ${scope} registry ${registryUrl}`} />
|
||||
<CopyToClipBoard text={`npm adduser --registry ${registryUrl}`} />
|
||||
</div>
|
||||
<RegistryInfoContent registryUrl={registryUrl} scope={scope} />
|
||||
</RegistryInfoDialog>
|
||||
);
|
||||
};
|
||||
|
|
90
src/webui/components/RegistryInfoContent/index.js
Normal file
90
src/webui/components/RegistryInfoContent/index.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* @prettier
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import type { IProps, IState } from './types';
|
||||
import { CommandContainer } from './styles';
|
||||
import CopyToClipBoard from '../CopyToClipBoard';
|
||||
import Tabs from '@material-ui/core/Tabs/index';
|
||||
import Tab from '@material-ui/core/Tab/index';
|
||||
import Typography from '@material-ui/core/Typography/index';
|
||||
|
||||
import { getCLISetRegistry, getCLIChangePassword, getCLISetConfigRegistry } from '../../utils/cli-utils';
|
||||
import { NODE_MANAGER } from '../../utils/constants';
|
||||
|
||||
/* eslint react/prop-types:0 */
|
||||
function TabContainer({ children }) {
|
||||
return (
|
||||
<CommandContainer>
|
||||
<Typography component={'div'} style={{ padding: 0, minHeight: 170 }}>
|
||||
{children}
|
||||
</Typography>
|
||||
</CommandContainer>
|
||||
);
|
||||
}
|
||||
|
||||
class RegistryInfoContent extends Component<IProps, IState> {
|
||||
state = {
|
||||
tabPosition: 0,
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.renderTabs()}</div>;
|
||||
}
|
||||
|
||||
renderTabs() {
|
||||
const { scope, registryUrl } = this.props;
|
||||
const { tabPosition } = this.state;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Tabs indicatorColor={'primary'} onChange={this.handleChange} textColor={'primary'} value={tabPosition} variant={'fullWidth'}>
|
||||
<Tab label={NODE_MANAGER.npm} />
|
||||
<Tab label={NODE_MANAGER.pnpm} />
|
||||
<Tab label={NODE_MANAGER.yarn} />
|
||||
</Tabs>
|
||||
{tabPosition === 0 && <TabContainer>{this.renderNpmTab(scope, registryUrl)}</TabContainer>}
|
||||
{tabPosition === 1 && <TabContainer>{this.renderPNpmTab(scope, registryUrl)}</TabContainer>}
|
||||
{tabPosition === 2 && <TabContainer>{this.renderYarnTab(scope, registryUrl)}</TabContainer>}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
renderNpmTab(scope: string, registryUrl: string) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<CopyToClipBoard text={getCLISetConfigRegistry(`${NODE_MANAGER.npm} set`, scope, registryUrl)} />
|
||||
<CopyToClipBoard text={getCLISetRegistry(`${NODE_MANAGER.npm} adduser`, registryUrl)} />
|
||||
<CopyToClipBoard text={getCLIChangePassword(NODE_MANAGER.npm, registryUrl)} />
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
renderPNpmTab(scope: string, registryUrl: string) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<CopyToClipBoard text={getCLISetConfigRegistry(`${NODE_MANAGER.pnpm} set`, scope, registryUrl)} />
|
||||
<CopyToClipBoard text={getCLISetRegistry(`${NODE_MANAGER.pnpm} adduser`, registryUrl)} />
|
||||
<CopyToClipBoard text={getCLIChangePassword(NODE_MANAGER.pnpm, registryUrl)} />
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
renderYarnTab(scope: string, registryUrl: string) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<CopyToClipBoard text={getCLISetConfigRegistry(`${NODE_MANAGER.yarn} config set`, scope, registryUrl)} />
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
handleChange = (event: any, tabPosition: number) => {
|
||||
event.preventDefault();
|
||||
this.setState({ tabPosition });
|
||||
};
|
||||
}
|
||||
|
||||
export default RegistryInfoContent;
|
7
src/webui/components/RegistryInfoContent/styles.js
Normal file
7
src/webui/components/RegistryInfoContent/styles.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import styled from 'react-emotion';
|
||||
|
||||
export const CommandContainer = styled.div`
|
||||
&& {
|
||||
padding-top: 20px;
|
||||
}
|
||||
`;
|
13
src/webui/components/RegistryInfoContent/types.js
Normal file
13
src/webui/components/RegistryInfoContent/types.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* @prettier
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export interface IProps {
|
||||
scope: string;
|
||||
registryUrl: string;
|
||||
}
|
||||
|
||||
export interface IState {
|
||||
tabPosition: number;
|
||||
}
|
33
src/webui/utils/cli-utils.js
Normal file
33
src/webui/utils/cli-utils.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* @prettier
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export const copyToClipBoardUtility = (str: string) => (event: SyntheticEvent<HTMLElement>) => {
|
||||
event.preventDefault();
|
||||
const node = document.createElement('div');
|
||||
node.innerText = str;
|
||||
if (document.body) {
|
||||
document.body.appendChild(node);
|
||||
const range = document.createRange();
|
||||
const selection = window.getSelection();
|
||||
range.selectNodeContents(node);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
document.execCommand('copy');
|
||||
// $FlowFixMe
|
||||
document.body.removeChild(node);
|
||||
}
|
||||
};
|
||||
|
||||
export function getCLISetConfigRegistry(command: string, scope: string, registryUrl: string): string {
|
||||
return `${command} ${scope} registry ${registryUrl}`;
|
||||
}
|
||||
|
||||
export function getCLISetRegistry(command: string, registryUrl: string): string {
|
||||
return `${command} --registry ${registryUrl}`;
|
||||
}
|
||||
|
||||
export function getCLIChangePassword(command: string, registryUrl: string): string {
|
||||
return `${command} profile set password --registry ${registryUrl}`;
|
||||
}
|
9
src/webui/utils/constants.js
Normal file
9
src/webui/utils/constants.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
export const TEXT = {
|
||||
CLIPBOARD_COPY: 'Copy to Clipboard',
|
||||
};
|
||||
|
||||
export const NODE_MANAGER = {
|
||||
npm: 'npm',
|
||||
yarn: 'yarn',
|
||||
pnpm: 'pnpm',
|
||||
};
|
|
@ -1,3 +1,3 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<CopyToClipBoard /> component render the component 1`] = `"<p class=\\"css-1a0lalv eduq2bv0\\"><span class=\\"css-1m8aenu eduq2bv1\\">copy text</span><button tabindex=\\"0\\" class=\\"MuiButtonBase-root-14 MuiIconButton-root-8 css-56v3u0 eduq2bv2\\" type=\\"button\\" title=\\"Copy to Clipboard\\"><span class=\\"MuiIconButton-label-13\\"><svg class=\\"MuiSvgIcon-root-17\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\" role=\\"presentation\\"><path fill=\\"none\\" d=\\"M0 0h24v24H0z\\"></path><path d=\\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z\\"></path></svg></span><span class=\\"MuiTouchRipple-root-26\\"></span></button></p>"`;
|
||||
exports[`<CopyToClipBoard /> component render the component 1`] = `"<div class=\\"css-1mta3t8 eduq2bv0\\"><span class=\\"css-1m8aenu eduq2bv1\\">copy text</span><button tabindex=\\"0\\" class=\\"MuiButtonBase-root-14 MuiIconButton-root-8 css-56v3u0 eduq2bv2\\" type=\\"button\\" title=\\"Copy to Clipboard\\"><span class=\\"MuiIconButton-label-13\\"><svg class=\\"MuiSvgIcon-root-17\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\" role=\\"presentation\\"><path fill=\\"none\\" d=\\"M0 0h24v24H0z\\"></path><path d=\\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z\\"></path></svg></span><span class=\\"MuiTouchRipple-root-26\\"></span></button></div>"`;
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Help /> component should render the component in default state 1`] = `"<div class=\\"MuiPaper-root-2 MuiPaper-elevation1-5 MuiPaper-rounded-3 MuiCard-root-1 css-ryznli e1vnhvvu0\\" id=\\"help-card\\"><div class=\\"MuiCardContent-root-29\\"><h2 class=\\"MuiTypography-root-30 MuiTypography-headline-35 MuiTypography-gutterBottom-48\\" id=\\"help-card__title\\">No Package Published Yet.</h2><p class=\\"MuiTypography-root-30 MuiTypography-body1-39 MuiTypography-colorTextSecondary-54 MuiTypography-gutterBottom-48 css-zg2fwz e1vnhvvu1\\">To publish your first package just:</p><aside class=\\"MuiTypography-root-30 MuiTypography-body2-38\\">1. Login</aside><p class=\\"css-1a0lalv eduq2bv0\\"><span class=\\"css-1m8aenu eduq2bv1\\">$ npm adduser --registry http://localhost</span><button tabindex=\\"0\\" class=\\"MuiButtonBase-root-69 MuiIconButton-root-63 css-56v3u0 eduq2bv2\\" type=\\"button\\" title=\\"Copy to Clipboard\\"><span class=\\"MuiIconButton-label-68\\"><svg class=\\"MuiSvgIcon-root-72\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\" role=\\"presentation\\"><path fill=\\"none\\" d=\\"M0 0h24v24H0z\\"></path><path d=\\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z\\"></path></svg></span><span class=\\"MuiTouchRipple-root-81\\"></span></button></p><aside class=\\"MuiTypography-root-30 MuiTypography-body2-38\\">2. Publish</aside><p class=\\"css-1a0lalv eduq2bv0\\"><span class=\\"css-1m8aenu eduq2bv1\\">$ npm publish --registry http://localhost</span><button tabindex=\\"0\\" class=\\"MuiButtonBase-root-69 MuiIconButton-root-63 css-56v3u0 eduq2bv2\\" type=\\"button\\" title=\\"Copy to Clipboard\\"><span class=\\"MuiIconButton-label-68\\"><svg class=\\"MuiSvgIcon-root-72\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\" role=\\"presentation\\"><path fill=\\"none\\" d=\\"M0 0h24v24H0z\\"></path><path d=\\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z\\"></path></svg></span><span class=\\"MuiTouchRipple-root-81\\"></span></button></p><aside class=\\"MuiTypography-root-30 MuiTypography-body2-38\\">3. Refresh this page.</aside></div><div class=\\"MuiCardActions-root-88\\"><a tabindex=\\"0\\" class=\\"MuiButtonBase-root-69 MuiButton-root-90 MuiButton-text-92 MuiButton-textPrimary-93 MuiButton-flat-95 MuiButton-flatPrimary-96 MuiButton-sizeSmall-113 MuiCardActions-action-89\\" role=\\"button\\" href=\\"https://verdaccio.org/docs/en/installation\\" target=\\"_blank\\"><span class=\\"MuiButton-label-91\\">Learn More</span><span class=\\"MuiTouchRipple-root-81\\"></span></a></div></div>"`;
|
||||
exports[`<Help /> component should render the component in default state 1`] = `"<div class=\\"MuiPaper-root-2 MuiPaper-elevation1-5 MuiPaper-rounded-3 MuiCard-root-1 css-ryznli e1vnhvvu0\\" id=\\"help-card\\"><div class=\\"MuiCardContent-root-29\\"><h2 class=\\"MuiTypography-root-30 MuiTypography-headline-35 MuiTypography-gutterBottom-48\\" id=\\"help-card__title\\">No Package Published Yet.</h2><p class=\\"MuiTypography-root-30 MuiTypography-body1-39 MuiTypography-colorTextSecondary-54 MuiTypography-gutterBottom-48 css-zg2fwz e1vnhvvu1\\">To publish your first package just:</p><aside class=\\"MuiTypography-root-30 MuiTypography-body2-38\\">1. Login</aside><div class=\\"css-1mta3t8 eduq2bv0\\"><span class=\\"css-1m8aenu eduq2bv1\\">$ npm adduser --registry http://localhost</span><button tabindex=\\"0\\" class=\\"MuiButtonBase-root-69 MuiIconButton-root-63 css-56v3u0 eduq2bv2\\" type=\\"button\\" title=\\"Copy to Clipboard\\"><span class=\\"MuiIconButton-label-68\\"><svg class=\\"MuiSvgIcon-root-72\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\" role=\\"presentation\\"><path fill=\\"none\\" d=\\"M0 0h24v24H0z\\"></path><path d=\\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z\\"></path></svg></span><span class=\\"MuiTouchRipple-root-81\\"></span></button></div><aside class=\\"MuiTypography-root-30 MuiTypography-body2-38\\">2. Publish</aside><div class=\\"css-1mta3t8 eduq2bv0\\"><span class=\\"css-1m8aenu eduq2bv1\\">$ npm publish --registry http://localhost</span><button tabindex=\\"0\\" class=\\"MuiButtonBase-root-69 MuiIconButton-root-63 css-56v3u0 eduq2bv2\\" type=\\"button\\" title=\\"Copy to Clipboard\\"><span class=\\"MuiIconButton-label-68\\"><svg class=\\"MuiSvgIcon-root-72\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\" role=\\"presentation\\"><path fill=\\"none\\" d=\\"M0 0h24v24H0z\\"></path><path d=\\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z\\"></path></svg></span><span class=\\"MuiTouchRipple-root-81\\"></span></button></div><aside class=\\"MuiTypography-root-30 MuiTypography-body2-38\\">3. Refresh this page.</aside></div><div class=\\"MuiCardActions-root-88\\"><a tabindex=\\"0\\" class=\\"MuiButtonBase-root-69 MuiButton-root-90 MuiButton-text-92 MuiButton-textPrimary-93 MuiButton-flat-95 MuiButton-flatPrimary-96 MuiButton-sizeSmall-113 MuiCardActions-action-89\\" role=\\"button\\" href=\\"https://verdaccio.org/docs/en/installation\\" target=\\"_blank\\"><span class=\\"MuiButton-label-91\\">Learn More</span><span class=\\"MuiTouchRipple-root-81\\"></span></a></div></div>"`;
|
||||
|
|
Loading…
Add table
Reference in a new issue