@verdaccio/ui-components 3.0.0-next-7.7 → 3.0.0-next-7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +1 -1
- package/CHANGELOG.md +6 -0
- package/build/Theme/theme.js +3 -3
- package/build/components/ActionBar/ActionBar.js +3 -1
- package/build/components/ActionBar/ActionBarAction.js +7 -6
- package/build/components/Author/Author.js +13 -42
- package/build/components/CopyClipboard/utils.js +3 -12
- package/build/components/Dependencies/Dependencies.js +12 -13
- package/build/components/Dependencies/DependencyBlock.js +5 -4
- package/build/components/Developers/DeveloperType.js +12 -0
- package/build/components/Developers/Developers.js +20 -22
- package/build/components/Developers/Title.js +5 -9
- package/build/components/Developers/index.js +4 -4
- package/build/components/Distribution/Dist.js +1 -1
- package/build/components/Distribution/styles.js +10 -23
- package/build/components/Engines/Engines.js +7 -1
- package/build/components/Engines/styles.js +6 -6
- package/build/components/FundButton/FundButton.js +7 -8
- package/build/components/HeaderInfoDialog/HeaderInfoDialog.js +2 -1
- package/build/components/Icons/DevsIcons/CommonJS.js +1 -12
- package/build/components/Icons/DevsIcons/ES6Module.js +2 -13
- package/build/components/Icons/DevsIcons/Git.js +1 -12
- package/build/components/Icons/DevsIcons/NodeJS.js +1 -12
- package/build/components/Icons/DevsIcons/TypeScript.js +1 -12
- package/build/components/Icons/FileBinary.js +11 -5
- package/build/components/Icons/Law.js +12 -6
- package/build/components/Icons/Managers/Npm.js +1 -12
- package/build/components/Icons/Managers/Pnpm.js +1 -12
- package/build/components/Icons/Managers/Yarn.js +1 -12
- package/build/components/Install/Install.js +23 -18
- package/build/components/Install/InstallListItem.js +19 -18
- package/build/components/Keywords/KeywordListItems.js +34 -0
- package/build/components/Keywords/Keywords.js +39 -0
- package/build/{sections/Header/RegistryInfoDialog → components/Keywords}/index.js +2 -2
- package/build/components/Link/Link.js +4 -16
- package/build/components/Link/index.js +1 -1
- package/build/components/LinkExternal/LinkExternal.js +32 -0
- package/build/components/LinkExternal/index.js +14 -0
- package/build/components/Loading/styles.js +3 -2
- package/build/components/LoginDialog/LoginDialog.js +12 -1
- package/build/components/LoginDialog/LoginDialogCloseButton.js +3 -2
- package/build/components/LoginDialog/LoginDialogForm.js +2 -14
- package/build/components/LoginDialog/LoginDialogFormError.js +3 -2
- package/build/components/Logo/Logo.js +13 -6
- package/build/components/Package/Package.js +43 -34
- package/build/components/Package/styles.js +46 -58
- package/build/components/Person/Person.js +48 -0
- package/build/components/Person/PersonTooltip.js +22 -0
- package/build/components/{Package/Tag → Person}/index.js +2 -2
- package/build/components/Person/utils.js +17 -0
- package/build/components/RawViewer/RawViewer.js +11 -5
- package/build/components/Readme/Readme.js +15 -6
- package/build/components/Readme/Readme.js.map +1 -1
- package/build/components/Readme/Readme.spec.js +19 -0
- package/build/components/Readme/Readme.spec.js.map +1 -1
- package/build/components/Readme/utils.js +2 -5
- package/build/components/RegistryInfoDialog/styles.js +9 -10
- package/build/components/Repository/Repository.js +19 -31
- package/build/components/Search/AutoComplete/styles.js +4 -41
- package/build/components/Search/Search.js +4 -2
- package/build/components/Search/SearchItem.js +51 -38
- package/build/components/Search/utils.js +23 -0
- package/build/components/SettingsMenu/SettingsMenu.js +35 -9
- package/build/components/SideBarTitle/SideBarTitle.js +16 -6
- package/build/components/UpLinks/UpLinks.js +35 -6
- package/build/components/UpLinks/UplinkLink.js +22 -0
- package/build/components/UpLinks/styles.js +5 -4
- package/build/components/Versions/HistoryList.js +8 -5
- package/build/components/Versions/TagList.js +8 -4
- package/build/components/Versions/Versions.js +30 -7
- package/build/index.js +27 -3
- package/build/providers/AppConfigurationProvider/AppConfigurationProvider.js +1 -0
- package/build/providers/PersistenceSettingProvider/PersistenceSettingProvider.js +1 -0
- package/build/sections/Detail/Detail.js +6 -2
- package/build/sections/Detail/Tabs.js +4 -3
- package/build/sections/Footer/Footer.js +17 -8
- package/build/sections/Footer/styles.js +13 -10
- package/build/sections/Header/HeaderLeft.js +14 -17
- package/build/sections/Header/HeaderMenu.js +1 -1
- package/build/sections/Header/HeaderRight.js +12 -3
- package/build/sections/Header/HeaderSettingsDialog.js +2 -2
- package/build/sections/Header/styles.js +43 -82
- package/build/sections/SideBar/Sidebar.js +10 -15
- package/build/src/Theme/ThemeProvider.test.d.ts +1 -0
- package/build/src/components/Author/Author.d.ts +0 -5
- package/build/src/components/CopyClipboard/CopyToClipBoard.test.d.ts +1 -0
- package/build/src/components/Dependencies/Dependencies.d.ts +0 -1
- package/build/src/components/Developers/DeveloperType.d.ts +4 -0
- package/build/src/components/Developers/Developers.d.ts +1 -4
- package/build/src/components/Developers/Title.d.ts +1 -4
- package/build/src/components/Developers/index.d.ts +2 -1
- package/build/src/components/Distribution/styles.d.ts +0 -1
- package/build/src/components/ErrorBoundary/ErrorBoundary.test.d.ts +1 -0
- package/build/src/components/HeaderInfoDialog/HeaderInfoDialog.test.d.ts +1 -0
- package/build/src/components/Heading/Heading.test.d.ts +1 -0
- package/build/src/components/Icons/Icons.test.d.ts +1 -0
- package/build/src/components/Install/InstallListItem.d.ts +1 -1
- package/build/src/components/Keywords/KeywordListItems.d.ts +5 -0
- package/build/src/components/Keywords/Keywords.d.ts +6 -0
- package/build/src/components/Keywords/Keywords.stories.d.ts +5 -0
- package/build/src/components/Keywords/Keywords.test.d.ts +1 -0
- package/build/src/components/Keywords/index.d.ts +1 -0
- package/build/src/components/Link/Link.d.ts +0 -3
- package/build/src/components/Link/Link.test.d.ts +1 -0
- package/build/src/components/Link/index.d.ts +1 -1
- package/build/src/components/LinkExternal/LinkExternal.d.ts +3 -0
- package/build/src/components/LinkExternal/LinkExternal.test.d.ts +1 -0
- package/build/src/components/LinkExternal/index.d.ts +1 -0
- package/build/src/components/Logo/Logo.d.ts +1 -0
- package/build/src/components/Logo/Logo.stories.d.ts +5 -0
- package/build/src/components/Package/Package.d.ts +1 -1
- package/build/src/components/Package/styles.d.ts +0 -8
- package/build/src/components/Person/Person.d.ts +9 -0
- package/build/src/components/Person/Person.test.d.ts +1 -0
- package/build/src/components/Person/PersonTooltip.d.ts +6 -0
- package/build/src/components/Person/index.d.ts +1 -0
- package/build/src/components/Person/utils.d.ts +3 -0
- package/build/src/components/Readme/Readme.d.ts +0 -1
- package/build/src/components/Search/AutoComplete/styles.d.ts +0 -8
- package/build/src/components/Search/utils.d.ts +1 -0
- package/build/src/components/SettingsMenu/SettingsMenu.d.ts +2 -2
- package/build/src/components/SettingsMenu/SettingsMenu.test.d.ts +1 -0
- package/build/src/components/UpLinks/UplinkLink.d.ts +6 -0
- package/build/src/components/Versions/Versions.d.ts +1 -0
- package/build/src/index.d.ts +4 -1
- package/build/src/sections/Detail/Tabs.d.ts +1 -0
- package/build/src/sections/Header/styles.d.ts +0 -7
- package/build/src/store/models/routes.d.ts +8 -0
- package/build/src/store/models/utils.d.ts +1 -0
- package/build/src/types/packageMeta.d.ts +7 -5
- package/build/src/utils/routes.d.ts +1 -0
- package/build/src/utils/utils.d.ts +1 -0
- package/build/store/models/configuration.js +2 -1
- package/build/store/models/login.js +4 -2
- package/build/store/models/manifest.js +5 -3
- package/build/store/models/packages.js +4 -2
- package/build/store/models/routes.js +18 -0
- package/build/store/models/search.js +4 -2
- package/build/store/models/utils.js +10 -0
- package/build/utils/routes.js +1 -0
- package/build/utils/utils.js +20 -1
- package/package.json +2 -2
- package/src/AppTest/AppRoute.test.tsx +65 -0
- package/src/Theme/ThemeProvider.test.tsx +27 -0
- package/src/Theme/theme.ts +3 -3
- package/src/components/ActionBar/ActionBar.test.tsx +36 -15
- package/src/components/ActionBar/ActionBar.tsx +1 -1
- package/src/components/ActionBar/ActionBarAction.tsx +8 -5
- package/src/components/Author/Author.test.tsx +7 -1
- package/src/components/Author/Author.tsx +3 -41
- package/src/components/CopyClipboard/CopyToClipBoard.test.tsx +23 -0
- package/src/components/CopyClipboard/utils.ts +2 -13
- package/src/components/Dependencies/Dependencies.tsx +9 -9
- package/src/components/Dependencies/DependencyBlock.tsx +2 -1
- package/src/components/Developers/DeveloperType.tsx +4 -0
- package/src/components/Developers/Developers.test.tsx +37 -10
- package/src/components/Developers/Developers.tsx +13 -13
- package/src/components/Developers/Title.tsx +1 -5
- package/src/components/Developers/index.ts +2 -1
- package/src/components/Distribution/Dist.test.tsx +1 -1
- package/src/components/Distribution/Dist.tsx +2 -4
- package/src/components/Distribution/styles.ts +0 -6
- package/src/components/Engines/Engines.tsx +6 -2
- package/src/components/Engines/styles.ts +1 -1
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +39 -0
- package/src/components/FundButton/FundButton.tsx +5 -5
- package/src/components/HeaderInfoDialog/HeaderInfoDialog.test.tsx +51 -0
- package/src/components/HeaderInfoDialog/HeaderInfoDialog.tsx +2 -2
- package/src/components/Heading/Heading.test.tsx +20 -0
- package/src/components/Icons/DevsIcons/CommonJS.tsx +1 -7
- package/src/components/Icons/DevsIcons/ES6Module.tsx +2 -8
- package/src/components/Icons/DevsIcons/Git.tsx +1 -7
- package/src/components/Icons/DevsIcons/NodeJS.tsx +1 -7
- package/src/components/Icons/DevsIcons/TypeScript.tsx +1 -7
- package/src/components/Icons/FileBinary.tsx +2 -1
- package/src/components/Icons/Icons.stories.tsx +21 -5
- package/src/components/Icons/Icons.test.tsx +70 -0
- package/src/components/Icons/Law.tsx +2 -1
- package/src/components/Icons/Managers/Npm.tsx +1 -7
- package/src/components/Icons/Managers/Pnpm.tsx +1 -7
- package/src/components/Icons/Managers/Yarn.tsx +1 -7
- package/src/components/Install/Install.test.tsx +54 -13
- package/src/components/Install/Install.tsx +12 -11
- package/src/components/Install/InstallListItem.tsx +12 -11
- package/src/components/Keywords/KeywordListItems.tsx +22 -0
- package/src/components/Keywords/Keywords.stories.tsx +19 -0
- package/src/components/Keywords/Keywords.test.tsx +57 -0
- package/src/components/Keywords/Keywords.tsx +35 -0
- package/src/components/Keywords/index.ts +1 -0
- package/src/components/Link/Link.test.tsx +25 -0
- package/src/components/Link/Link.tsx +4 -18
- package/src/components/Link/index.ts +1 -1
- package/src/components/LinkExternal/LinkExternal.test.tsx +18 -0
- package/src/components/LinkExternal/LinkExternal.tsx +22 -0
- package/src/components/LinkExternal/index.ts +1 -0
- package/src/components/Loading/Loading.test.tsx +8 -5
- package/src/components/Loading/styles.ts +1 -0
- package/src/components/LoginDialog/LoginDialog.test.tsx +1 -1
- package/src/components/LoginDialog/LoginDialog.tsx +10 -1
- package/src/components/LoginDialog/LoginDialogCloseButton.tsx +1 -0
- package/src/components/LoginDialog/LoginDialogForm.tsx +0 -2
- package/src/components/LoginDialog/LoginDialogFormError.tsx +1 -1
- package/src/components/Logo/Logo.stories.tsx +16 -0
- package/src/components/Logo/Logo.test.tsx +8 -1
- package/src/components/Logo/Logo.tsx +19 -3
- package/src/components/Package/Package.test.tsx +47 -14
- package/src/components/Package/Package.tsx +41 -44
- package/src/components/Package/styles.ts +7 -17
- package/src/components/PackageList/Packagelist.test.tsx +1 -0
- package/src/components/Person/Person.test.tsx +50 -0
- package/src/components/Person/Person.tsx +45 -0
- package/src/components/Person/PersonTooltip.tsx +26 -0
- package/src/components/Person/index.ts +1 -0
- package/src/components/Person/utils.ts +20 -0
- package/src/components/RawViewer/RawViewer.tsx +8 -4
- package/src/components/Readme/Readme.spec.tsx +17 -0
- package/src/components/Readme/Readme.tsx +10 -5
- package/src/components/Readme/utils.ts +2 -5
- package/src/components/RegistryInfoDialog/styles.ts +5 -4
- package/src/components/Repository/Repository.tsx +9 -14
- package/src/components/Search/AutoComplete/styles.ts +7 -0
- package/src/components/Search/Search.test.tsx +36 -9
- package/src/components/Search/Search.tsx +4 -2
- package/src/components/Search/SearchItem.tsx +19 -8
- package/src/components/Search/utils.ts +17 -0
- package/src/components/SettingsMenu/SettingsMenu.test.tsx +41 -0
- package/src/components/SettingsMenu/SettingsMenu.tsx +48 -10
- package/src/components/SideBarTitle/SideBarTitle.tsx +19 -3
- package/src/components/UpLinks/UpLinks.test.tsx +7 -0
- package/src/components/UpLinks/UpLinks.tsx +38 -15
- package/src/components/UpLinks/UplinkLink.tsx +20 -0
- package/src/components/UpLinks/styles.ts +1 -0
- package/src/components/Versions/HistoryList.tsx +9 -4
- package/src/components/Versions/TagList.tsx +4 -3
- package/src/components/Versions/Versions.test.tsx +2 -0
- package/src/components/Versions/Versions.tsx +57 -32
- package/src/index.ts +4 -1
- package/src/providers/AppConfigurationProvider/AppConfigurationProvider.tsx +1 -0
- package/src/providers/PersistenceSettingProvider/PersistenceSettingProvider.tsx +2 -0
- package/src/providers/VersionProvider/VersionProvider.test.tsx +3 -3
- package/src/sections/Detail/Detail.test.tsx +8 -1
- package/src/sections/Detail/Detail.tsx +11 -4
- package/src/sections/Detail/Tabs.tsx +5 -2
- package/src/sections/Footer/Footer.tsx +15 -4
- package/src/sections/Footer/styles.ts +4 -0
- package/src/sections/Header/Header.test.tsx +12 -10
- package/src/sections/Header/HeaderLeft.tsx +19 -11
- package/src/sections/Header/HeaderMenu.tsx +1 -1
- package/src/sections/Header/HeaderRight.tsx +14 -3
- package/src/sections/Header/HeaderSettingsDialog.tsx +1 -1
- package/src/sections/Header/RegistryInfoContent/RegistryInfoContent.test.tsx +1 -1
- package/src/sections/Header/styles.ts +4 -16
- package/src/sections/Home/Home.test.tsx +12 -4
- package/src/sections/SideBar/Sidebar.test.tsx +20 -13
- package/src/sections/SideBar/Sidebar.tsx +5 -9
- package/src/store/api.test.ts +16 -0
- package/src/store/models/configuration.ts +2 -1
- package/src/store/models/login.ts +10 -12
- package/src/store/models/manifest.ts +6 -5
- package/src/store/models/packages.ts +4 -5
- package/src/store/models/routes.ts +10 -0
- package/src/store/models/search.ts +4 -2
- package/src/store/models/utils.ts +3 -0
- package/src/types/packageMeta.ts +7 -5
- package/src/utils/routes.ts +1 -0
- package/src/utils/utils.test.ts +34 -0
- package/src/utils/utils.ts +20 -5
- package/tsconfig.json +1 -1
- package/build/components/Developers/styles.js +0 -65
- package/build/components/Distribution/utils.js +0 -25
- package/build/components/Distribution/utilts.spec.js +0 -18
- package/build/components/Package/Tag/Tag.js +0 -14
- package/build/components/Package/Tag/styles.js +0 -24
- package/build/sections/Header/RegistryInfoDialog/RegistryInfoDialog.js +0 -36
- package/build/sections/Header/RegistryInfoDialog/styles.js +0 -46
- package/build/sections/Header/RegistryInfoDialog/types.js +0 -6
- package/build/src/components/Developers/styles.d.ts +0 -11
- package/build/src/components/Distribution/utils.d.ts +0 -7
- package/build/src/components/Package/Tag/Tag.d.ts +0 -6
- package/build/src/components/Package/Tag/index.d.ts +0 -1
- package/build/src/components/Package/Tag/styles.d.ts +0 -5
- package/build/src/sections/Header/RegistryInfoDialog/RegistryInfoDialog.d.ts +0 -4
- package/build/src/sections/Header/RegistryInfoDialog/index.d.ts +0 -1
- package/build/src/sections/Header/RegistryInfoDialog/styles.d.ts +0 -13
- package/build/src/sections/Header/RegistryInfoDialog/types.d.ts +0 -7
- package/src/components/Developers/styles.ts +0 -31
- package/src/components/Distribution/utils.ts +0 -32
- package/src/components/Distribution/utilts.spec.ts +0 -17
- package/src/components/Package/Tag/Tag.test.tsx +0 -15
- package/src/components/Package/Tag/Tag.tsx +0 -11
- package/src/components/Package/Tag/index.ts +0 -1
- package/src/components/Package/Tag/styles.ts +0 -11
- package/src/components/Search/AutoComplete/styles.tsx +0 -42
- package/src/sections/Header/RegistryInfoDialog/RegistryInfoDialog.tsx +0 -31
- package/src/sections/Header/RegistryInfoDialog/index.ts +0 -1
- package/src/sections/Header/RegistryInfoDialog/styles.ts +0 -21
- package/src/sections/Header/RegistryInfoDialog/types.ts +0 -8
- /package/build/components/Icons/DevsIcons/{es6modules.svg → es6module.svg} +0 -0
- /package/build/src/{components/Package/Tag/Tag.test.d.ts → AppTest/AppRoute.test.d.ts} +0 -0
- /package/src/components/Icons/DevsIcons/{es6modules.svg → es6module.svg} +0 -0
|
@@ -3,20 +3,20 @@ import styled from '@emotion/styled';
|
|
|
3
3
|
import BugReport from '@mui/icons-material/BugReport';
|
|
4
4
|
import DownloadIcon from '@mui/icons-material/CloudDownload';
|
|
5
5
|
import HomeIcon from '@mui/icons-material/Home';
|
|
6
|
-
import { useTheme } from '@mui/material';
|
|
7
6
|
import CircularProgress from '@mui/material/CircularProgress';
|
|
8
7
|
import Grid from '@mui/material/Grid';
|
|
8
|
+
import List from '@mui/material/List';
|
|
9
9
|
import ListItem from '@mui/material/ListItem';
|
|
10
10
|
import Tooltip from '@mui/material/Tooltip';
|
|
11
11
|
import React, { useCallback } from 'react';
|
|
12
12
|
import { useTranslation } from 'react-i18next';
|
|
13
13
|
import { useDispatch, useSelector } from 'react-redux';
|
|
14
14
|
|
|
15
|
-
import { Dispatch, Link, RootState, Theme } from '../../';
|
|
15
|
+
import { Dispatch, Link, LinkExternal, RootState, Theme } from '../../';
|
|
16
16
|
import { FileBinary, Law, Time, Version } from '../../components/Icons';
|
|
17
17
|
import { Author as PackageAuthor, PackageMetaInterface } from '../../types/packageMeta';
|
|
18
|
-
import { url, utils } from '../../utils';
|
|
19
|
-
import
|
|
18
|
+
import { Route, url, utils } from '../../utils';
|
|
19
|
+
import KeywordListItems from '../Keywords/KeywordListItems';
|
|
20
20
|
import {
|
|
21
21
|
Author,
|
|
22
22
|
Avatar,
|
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
PackageListItemText,
|
|
29
29
|
PackageTitle,
|
|
30
30
|
Published,
|
|
31
|
-
TagContainer,
|
|
32
31
|
Wrapper,
|
|
33
32
|
WrapperLink,
|
|
34
33
|
} from './styles';
|
|
@@ -47,7 +46,7 @@ export interface PackageInterface {
|
|
|
47
46
|
time?: number | string;
|
|
48
47
|
author: PackageAuthor;
|
|
49
48
|
description?: string;
|
|
50
|
-
keywords?:
|
|
49
|
+
keywords?: PackageMetaInterface['latest']['keywords'];
|
|
51
50
|
license?: PackageMetaInterface['latest']['license'];
|
|
52
51
|
homepage?: string;
|
|
53
52
|
bugs?: Bugs;
|
|
@@ -61,7 +60,7 @@ const Package: React.FC<PackageInterface> = ({
|
|
|
61
60
|
description,
|
|
62
61
|
dist,
|
|
63
62
|
homepage,
|
|
64
|
-
keywords
|
|
63
|
+
keywords,
|
|
65
64
|
license,
|
|
66
65
|
name: packageName,
|
|
67
66
|
time,
|
|
@@ -71,7 +70,6 @@ const Package: React.FC<PackageInterface> = ({
|
|
|
71
70
|
const config = useSelector((state: RootState) => state.configuration.config);
|
|
72
71
|
const dispatch = useDispatch<Dispatch>();
|
|
73
72
|
const { t } = useTranslation();
|
|
74
|
-
const theme = useTheme();
|
|
75
73
|
const isLoading = useSelector((state: RootState) => state?.loading?.models.download);
|
|
76
74
|
|
|
77
75
|
const handleDownload = useCallback(
|
|
@@ -94,21 +92,12 @@ const Package: React.FC<PackageInterface> = ({
|
|
|
94
92
|
const renderAuthorInfo = (): React.ReactNode => {
|
|
95
93
|
const name = utils.getAuthorName(authorName);
|
|
96
94
|
return (
|
|
97
|
-
<
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
fontWeight: theme?.fontWeight.semiBold,
|
|
104
|
-
color:
|
|
105
|
-
theme?.palette.mode === 'light' ? theme?.palette.greyLight2 : theme?.palette.white,
|
|
106
|
-
}}
|
|
107
|
-
>
|
|
108
|
-
{name}
|
|
109
|
-
</div>
|
|
110
|
-
</Details>
|
|
111
|
-
</Author>
|
|
95
|
+
<OverviewItem>
|
|
96
|
+
<Author>
|
|
97
|
+
<Avatar alt={name} src={authorAvatar} />
|
|
98
|
+
<Details>{name}</Details>
|
|
99
|
+
</Author>
|
|
100
|
+
</OverviewItem>
|
|
112
101
|
);
|
|
113
102
|
};
|
|
114
103
|
|
|
@@ -132,33 +121,34 @@ const Package: React.FC<PackageInterface> = ({
|
|
|
132
121
|
time && (
|
|
133
122
|
<OverviewItem>
|
|
134
123
|
<StyledTime />
|
|
135
|
-
<Published
|
|
136
|
-
|
|
124
|
+
<Published title={utils.formatDate(time)}>
|
|
125
|
+
{t('package.published-on', { time: utils.formatDateDistance(time) })}
|
|
126
|
+
</Published>
|
|
137
127
|
</OverviewItem>
|
|
138
128
|
);
|
|
139
129
|
|
|
140
130
|
const renderHomePageLink = (): React.ReactNode =>
|
|
141
131
|
homepage &&
|
|
142
132
|
url.isURL(homepage) && (
|
|
143
|
-
<
|
|
133
|
+
<LinkExternal to={homepage}>
|
|
144
134
|
<Tooltip aria-label={t('package.homepage')} title={t('package.visit-home-page')}>
|
|
145
135
|
<IconButton aria-label={t('package.homepage')} size="large">
|
|
146
136
|
<HomeIcon />
|
|
147
137
|
</IconButton>
|
|
148
138
|
</Tooltip>
|
|
149
|
-
</
|
|
139
|
+
</LinkExternal>
|
|
150
140
|
);
|
|
151
141
|
|
|
152
142
|
const renderBugsLink = (): React.ReactNode =>
|
|
153
143
|
bugs?.url &&
|
|
154
144
|
url.isURL(bugs.url) && (
|
|
155
|
-
<
|
|
145
|
+
<LinkExternal to={bugs.url}>
|
|
156
146
|
<Tooltip aria-label={t('package.bugs')} title={t('package.open-an-issue')}>
|
|
157
147
|
<IconButton aria-label={t('package.bugs')} size="large">
|
|
158
148
|
<BugReport />
|
|
159
149
|
</IconButton>
|
|
160
150
|
</Tooltip>
|
|
161
|
-
</
|
|
151
|
+
</LinkExternal>
|
|
162
152
|
);
|
|
163
153
|
|
|
164
154
|
const renderDownloadLink = (): React.ReactNode =>
|
|
@@ -174,7 +164,11 @@ const Package: React.FC<PackageInterface> = ({
|
|
|
174
164
|
aria-label={t('package.download', { what: t('package.the-tar-file') })}
|
|
175
165
|
title={t('package.tarball')}
|
|
176
166
|
>
|
|
177
|
-
<IconButton
|
|
167
|
+
<IconButton
|
|
168
|
+
aria-label={t('package.download')}
|
|
169
|
+
data-testid="download-tarball"
|
|
170
|
+
size="large"
|
|
171
|
+
>
|
|
178
172
|
{isLoading ? (
|
|
179
173
|
<CircularProgress size={13}>
|
|
180
174
|
<DownloadIcon />
|
|
@@ -191,7 +185,7 @@ const Package: React.FC<PackageInterface> = ({
|
|
|
191
185
|
return (
|
|
192
186
|
<Grid container={true} item={true} xs={12}>
|
|
193
187
|
<Grid item={true} xs={11}>
|
|
194
|
-
<WrapperLink to={
|
|
188
|
+
<WrapperLink to={`${Route.DETAIL}${packageName}`}>
|
|
195
189
|
<PackageTitle className="package-title" data-testid="package-title">
|
|
196
190
|
{packageName}
|
|
197
191
|
</PackageTitle>
|
|
@@ -213,15 +207,7 @@ const Package: React.FC<PackageInterface> = ({
|
|
|
213
207
|
);
|
|
214
208
|
};
|
|
215
209
|
|
|
216
|
-
const renderSecondaryComponent = (): React.ReactNode => {
|
|
217
|
-
const tags = keywords.sort().map((keyword, index) => <Tag key={index}>{keyword}</Tag>);
|
|
218
|
-
return (
|
|
219
|
-
<>
|
|
220
|
-
<Description>{description}</Description>
|
|
221
|
-
{tags.length > 0 && <TagContainer>{tags}</TagContainer>}
|
|
222
|
-
</>
|
|
223
|
-
);
|
|
224
|
-
};
|
|
210
|
+
const renderSecondaryComponent = (): React.ReactNode => <Description>{description}</Description>;
|
|
225
211
|
|
|
226
212
|
const renderPackageListItemText = (): React.ReactNode => (
|
|
227
213
|
<PackageListItemText
|
|
@@ -231,10 +217,21 @@ const Package: React.FC<PackageInterface> = ({
|
|
|
231
217
|
/>
|
|
232
218
|
);
|
|
233
219
|
|
|
220
|
+
const renderKeywords = (): React.ReactNode => (
|
|
221
|
+
<ListItem alignItems={'flex-start'} sx={{ py: 0, my: 0 }}>
|
|
222
|
+
<List sx={{ p: 0, my: 0 }}>
|
|
223
|
+
<KeywordListItems keywords={keywords} />
|
|
224
|
+
</List>
|
|
225
|
+
</ListItem>
|
|
226
|
+
);
|
|
227
|
+
|
|
234
228
|
return (
|
|
235
229
|
<Wrapper className={'package'} data-testid="package-item-list">
|
|
236
|
-
<ListItem alignItems={'flex-start'}
|
|
237
|
-
|
|
230
|
+
<ListItem alignItems={'flex-start'} sx={{ mb: 0 }}>
|
|
231
|
+
{renderPackageListItemText()}
|
|
232
|
+
</ListItem>
|
|
233
|
+
{keywords && keywords?.length > 0 ? renderKeywords() : null}
|
|
234
|
+
<ListItem alignItems={'flex-start'} sx={{ mt: 0 }}>
|
|
238
235
|
{renderAuthorInfo()}
|
|
239
236
|
{renderVersionInfo()}
|
|
240
237
|
{renderPublishedInfo()}
|
|
@@ -248,8 +245,8 @@ const Package: React.FC<PackageInterface> = ({
|
|
|
248
245
|
export default Package;
|
|
249
246
|
|
|
250
247
|
const iconStyle = ({ theme }: { theme: Theme }) => css`
|
|
251
|
-
margin:
|
|
252
|
-
fill: ${theme?.palette.mode === 'light' ? theme?.palette.
|
|
248
|
+
margin: 0 10px 0 0;
|
|
249
|
+
fill: ${theme?.palette.mode === 'light' ? theme?.palette.greyDark : theme?.palette.white};
|
|
253
250
|
`;
|
|
254
251
|
|
|
255
252
|
const StyledVersion = styled(Version)`
|
|
@@ -11,8 +11,8 @@ import { Theme } from '../../';
|
|
|
11
11
|
export const OverviewItem = styled('span')<{ theme?: Theme }>(({ theme }) => ({
|
|
12
12
|
display: 'flex',
|
|
13
13
|
alignItems: 'center',
|
|
14
|
-
margin: '0 0 0
|
|
15
|
-
color: theme?.palette.mode === 'light' ? theme?.palette.
|
|
14
|
+
margin: '0 20px 0 0',
|
|
15
|
+
color: theme?.palette.mode === 'light' ? theme?.palette.greyDark2 : theme?.palette.white,
|
|
16
16
|
fontSize: 12,
|
|
17
17
|
[`@media (max-width: ${theme?.breakPoints.medium}px)`]: {
|
|
18
18
|
':nth-of-type(3)': {
|
|
@@ -26,10 +26,9 @@ export const OverviewItem = styled('span')<{ theme?: Theme }>(({ theme }) => ({
|
|
|
26
26
|
},
|
|
27
27
|
}));
|
|
28
28
|
|
|
29
|
-
export const Published = styled('span')
|
|
30
|
-
color: theme?.palette.mode === 'light' ? theme?.palette.greyLight2 : theme?.palette.white,
|
|
29
|
+
export const Published = styled('span')({
|
|
31
30
|
margin: '0 5px 0 0',
|
|
32
|
-
})
|
|
31
|
+
});
|
|
33
32
|
|
|
34
33
|
export const Details = styled('span')({
|
|
35
34
|
marginLeft: '5px',
|
|
@@ -59,6 +58,7 @@ export const PackageTitle = styled('span')<{ theme?: Theme }>(({ theme }) => ({
|
|
|
59
58
|
marginBottom: 12,
|
|
60
59
|
color: theme?.palette.mode == 'dark' ? theme?.palette.dodgerBlue : theme?.palette.eclipse,
|
|
61
60
|
cursor: 'pointer',
|
|
61
|
+
textDecoration: 'none',
|
|
62
62
|
[`@media (max-width: ${theme?.breakPoints.small}px)`]: {
|
|
63
63
|
fontSize: 14,
|
|
64
64
|
marginBottom: 8,
|
|
@@ -70,9 +70,9 @@ export const GridRightAligned = styled(Grid)({
|
|
|
70
70
|
});
|
|
71
71
|
|
|
72
72
|
export const Wrapper = styled(List)<{ theme?: Theme }>(({ theme }) => ({
|
|
73
|
-
'
|
|
73
|
+
'&:hover': {
|
|
74
74
|
backgroundColor:
|
|
75
|
-
theme?.palette?.type == 'dark' ? theme?.palette?.secondary.main : theme?.palette?.
|
|
75
|
+
theme?.palette?.type == 'dark' ? theme?.palette?.secondary.main : theme?.palette?.greyLight2,
|
|
76
76
|
},
|
|
77
77
|
}));
|
|
78
78
|
|
|
@@ -83,16 +83,6 @@ export const IconButton = styled(MuiIconButton)({
|
|
|
83
83
|
},
|
|
84
84
|
});
|
|
85
85
|
|
|
86
|
-
export const TagContainer = styled('span')<{ theme?: Theme }>(({ theme }) => ({
|
|
87
|
-
marginTop: 8,
|
|
88
|
-
marginBottom: 12,
|
|
89
|
-
display: 'flex',
|
|
90
|
-
flexWrap: 'wrap',
|
|
91
|
-
[`@media (max-width: ${theme?.breakPoints.medium}px)`]: {
|
|
92
|
-
display: 'none',
|
|
93
|
-
},
|
|
94
|
-
}));
|
|
95
|
-
|
|
96
86
|
export const PackageListItemText = styled(ListItemText)({
|
|
97
87
|
paddingRight: 0,
|
|
98
88
|
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { fireEvent, render, screen } from '../../test/test-react-testing-library';
|
|
4
|
+
import { Developer } from '../../types/packageMeta';
|
|
5
|
+
import Person from './Person';
|
|
6
|
+
|
|
7
|
+
const mockPerson: Developer = {
|
|
8
|
+
name: 'John Doe',
|
|
9
|
+
email: 'john.doe@example.com',
|
|
10
|
+
avatar: 'https://example.com/avatar.jpg',
|
|
11
|
+
url: 'https://example.com/~johndoe',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const mockPackageName = 'test-package';
|
|
15
|
+
const mockVersion = '1.0.0';
|
|
16
|
+
|
|
17
|
+
const ComponentToBeRendered: React.FC<{ withText?: boolean }> = ({ withText = false }) => {
|
|
18
|
+
return (
|
|
19
|
+
<Person
|
|
20
|
+
packageName={mockPackageName}
|
|
21
|
+
person={mockPerson}
|
|
22
|
+
version={mockVersion}
|
|
23
|
+
withText={withText}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
describe('Person component', () => {
|
|
29
|
+
test('should render avatar', () => {
|
|
30
|
+
render(<ComponentToBeRendered />);
|
|
31
|
+
const avatar = screen.getByAltText(mockPerson.name);
|
|
32
|
+
expect(avatar).toBeInTheDocument();
|
|
33
|
+
// but not include text
|
|
34
|
+
expect(screen.queryByText(mockPerson.name)).not.toBeInTheDocument();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('should render name when withText is true', () => {
|
|
38
|
+
render(<ComponentToBeRendered withText={true} />);
|
|
39
|
+
const name = screen.getByText(mockPerson.name);
|
|
40
|
+
expect(name).toBeInTheDocument();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('should not render name when withText is false', async () => {
|
|
44
|
+
render(<ComponentToBeRendered />);
|
|
45
|
+
// hover over the avatar
|
|
46
|
+
fireEvent.mouseEnter(screen.getByTestId(mockPerson.name));
|
|
47
|
+
// wait for the tooltip to appear
|
|
48
|
+
await screen.findByTestId(mockPerson.name + '-tooltip');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Typography } from '@mui/material';
|
|
2
|
+
import Avatar from '@mui/material/Avatar';
|
|
3
|
+
import Tooltip from '@mui/material/Tooltip';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
import { Developer } from '../../types/packageMeta';
|
|
7
|
+
import LinkExternal from '../LinkExternal';
|
|
8
|
+
import PersonTooltip from './PersonTooltip';
|
|
9
|
+
import { getLink, getName } from './utils';
|
|
10
|
+
|
|
11
|
+
const Person: React.FC<{
|
|
12
|
+
person: Developer;
|
|
13
|
+
packageName: string;
|
|
14
|
+
version: string;
|
|
15
|
+
withText?: boolean;
|
|
16
|
+
}> = ({ person, packageName, version, withText = false }) => {
|
|
17
|
+
const link = getLink(person, packageName, version);
|
|
18
|
+
|
|
19
|
+
const avatarComponent = (
|
|
20
|
+
<Avatar alt={person.name} src={person.avatar} sx={{ width: 40, height: 40, ml: 0, mr: 1 }} />
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<Tooltip
|
|
26
|
+
data-testid={person.name}
|
|
27
|
+
key={person.email}
|
|
28
|
+
title={<PersonTooltip person={person} />}
|
|
29
|
+
>
|
|
30
|
+
{link.length > 0 ? (
|
|
31
|
+
<LinkExternal to={link}>{avatarComponent}</LinkExternal>
|
|
32
|
+
) : (
|
|
33
|
+
avatarComponent
|
|
34
|
+
)}
|
|
35
|
+
</Tooltip>
|
|
36
|
+
{withText && (
|
|
37
|
+
<Typography sx={{ ml: 1 }} variant="subtitle2">
|
|
38
|
+
{getName(person.name)}
|
|
39
|
+
</Typography>
|
|
40
|
+
)}
|
|
41
|
+
</>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default Person;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Typography from '@mui/material/Typography';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { Developer } from '../../types/packageMeta';
|
|
5
|
+
import { url } from '../../utils';
|
|
6
|
+
import LinkExternal from '../LinkExternal';
|
|
7
|
+
|
|
8
|
+
const PersonTooltip: React.FC<{ person: Developer }> = ({ person }) => (
|
|
9
|
+
<Typography data-testid={person.name + '-tooltip'}>
|
|
10
|
+
{person.name}
|
|
11
|
+
{person.email && url.isEmail(person.email) && (
|
|
12
|
+
<LinkExternal to={`mailto:${person.email}`}>
|
|
13
|
+
<br />
|
|
14
|
+
{person.email}
|
|
15
|
+
</LinkExternal>
|
|
16
|
+
)}
|
|
17
|
+
{person.url && url.isURL(person.url) && (
|
|
18
|
+
<LinkExternal to={person.url}>
|
|
19
|
+
<br />
|
|
20
|
+
{person.url}
|
|
21
|
+
</LinkExternal>
|
|
22
|
+
)}
|
|
23
|
+
</Typography>
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
export default PersonTooltip;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './Person';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import i18next from 'i18next';
|
|
2
|
+
|
|
3
|
+
import { Developer } from '../../types/packageMeta';
|
|
4
|
+
import { url } from '../../utils';
|
|
5
|
+
|
|
6
|
+
export function getLink(person: Developer, packageName: string, version: string): string {
|
|
7
|
+
return person.email && url.isEmail(person.email)
|
|
8
|
+
? `mailto:${person.email}?subject=${packageName} v${version}`
|
|
9
|
+
: person.url && url.isURL(person.url)
|
|
10
|
+
? person.url
|
|
11
|
+
: '';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function getName(name?: string): string {
|
|
15
|
+
return !name
|
|
16
|
+
? i18next.t('author-unknown')
|
|
17
|
+
: name.toLowerCase() === 'anonymous'
|
|
18
|
+
? i18next.t('author-anonymous')
|
|
19
|
+
: name;
|
|
20
|
+
}
|
|
@@ -3,6 +3,7 @@ import Dialog from '@mui/material/Dialog';
|
|
|
3
3
|
import DialogContent from '@mui/material/DialogContent';
|
|
4
4
|
import DialogTitle from '@mui/material/DialogTitle';
|
|
5
5
|
import IconButton from '@mui/material/IconButton';
|
|
6
|
+
import { useTheme } from '@mui/styles';
|
|
6
7
|
import React from 'react';
|
|
7
8
|
import { useTranslation } from 'react-i18next';
|
|
8
9
|
import ReactJson from 'react-json-view';
|
|
@@ -22,6 +23,7 @@ const ViewerTitle = (props: ViewerTitleProps) => {
|
|
|
22
23
|
{onClose ? (
|
|
23
24
|
<IconButton
|
|
24
25
|
aria-label="close"
|
|
26
|
+
data-testid="close-raw-viewer"
|
|
25
27
|
onClick={onClose}
|
|
26
28
|
sx={{
|
|
27
29
|
position: 'absolute',
|
|
@@ -46,18 +48,20 @@ type Props = {
|
|
|
46
48
|
/* eslint-disable verdaccio/jsx-spread */
|
|
47
49
|
const RawViewer: React.FC<Props> = ({ isOpen = false, onClose, packageMeta }) => {
|
|
48
50
|
const { t } = useTranslation();
|
|
51
|
+
const theme = useTheme();
|
|
49
52
|
return (
|
|
50
53
|
<Dialog data-testid={'rawViewer--dialog'} fullScreen={true} open={isOpen}>
|
|
51
54
|
<ViewerTitle id="viewer-title" onClose={onClose}>
|
|
52
|
-
{t('action-bar-action.raw')}
|
|
55
|
+
{t('action-bar-action.raw-title', { package: packageMeta.latest.name })}
|
|
53
56
|
</ViewerTitle>
|
|
54
57
|
<DialogContent>
|
|
55
58
|
<ReactJson
|
|
56
|
-
collapseStringsAfterLength={
|
|
57
|
-
collapsed={
|
|
58
|
-
enableClipboard={
|
|
59
|
+
collapseStringsAfterLength={200}
|
|
60
|
+
collapsed={2}
|
|
61
|
+
enableClipboard={true}
|
|
59
62
|
groupArraysAfterLength={10}
|
|
60
63
|
src={packageMeta as any}
|
|
64
|
+
theme={theme?.palette.mode == 'light' ? 'bright:inverted' : 'bright'}
|
|
61
65
|
/>
|
|
62
66
|
</DialogContent>
|
|
63
67
|
</Dialog>
|
|
@@ -15,4 +15,21 @@ describe('<Readme /> component', () => {
|
|
|
15
15
|
const wrapper = render(<Readme description="<h1>This is a test string</h1>" />);
|
|
16
16
|
expect(wrapper.getByText('This is a test string')).toBeInTheDocument();
|
|
17
17
|
});
|
|
18
|
+
|
|
19
|
+
test('should sanitize html', () => {
|
|
20
|
+
const markdown = `<script>alert('test')</script>`;
|
|
21
|
+
const wrapper = render(<Readme description={markdown} />);
|
|
22
|
+
expect(wrapper.queryAllByText('test')).toHaveLength(0);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('should highlight code', () => {
|
|
26
|
+
const markdown = `\`\`\`js\nconst test = 1 + 2;\n\`\`\``;
|
|
27
|
+
const wrapper = render(<Readme description={markdown} />);
|
|
28
|
+
expect(wrapper.getByText('const')).toBeInTheDocument();
|
|
29
|
+
expect(wrapper.getByText('const')).toHaveClass('hljs-keyword');
|
|
30
|
+
expect(wrapper.getByText('1')).toBeInTheDocument();
|
|
31
|
+
expect(wrapper.getByText('1')).toHaveClass('hljs-number');
|
|
32
|
+
expect(wrapper.getByText('2')).toBeInTheDocument();
|
|
33
|
+
expect(wrapper.getByText('2')).toHaveClass('hljs-number');
|
|
34
|
+
});
|
|
18
35
|
});
|
|
@@ -2,8 +2,6 @@ import styled from '@emotion/styled';
|
|
|
2
2
|
import Box from '@mui/material/Box';
|
|
3
3
|
import Card from '@mui/material/Card';
|
|
4
4
|
import CardContent from '@mui/material/CardContent';
|
|
5
|
-
import { useTheme } from '@mui/styles';
|
|
6
|
-
import 'highlight.js/styles/default.css';
|
|
7
5
|
import React from 'react';
|
|
8
6
|
|
|
9
7
|
import { useCustomTheme } from '../../';
|
|
@@ -14,12 +12,19 @@ import { parseReadme } from './utils';
|
|
|
14
12
|
const Readme: React.FC<Props> = ({ description }) => {
|
|
15
13
|
// @ts-ignore
|
|
16
14
|
const { isDarkMode } = useCustomTheme();
|
|
17
|
-
|
|
15
|
+
|
|
16
|
+
// Stackoverflow theme fits well to Verdaccio dark colors
|
|
17
|
+
// https://highlightjs.org/examples
|
|
18
|
+
if (isDarkMode) {
|
|
19
|
+
require('highlight.js/styles/github-dark.css');
|
|
20
|
+
} else {
|
|
21
|
+
require('highlight.js/styles/github.css');
|
|
22
|
+
}
|
|
18
23
|
|
|
19
24
|
return (
|
|
20
|
-
<Card>
|
|
25
|
+
<Card sx={{ mb: 2 }}>
|
|
21
26
|
<CardContent>
|
|
22
|
-
<Box data-testid="readme" sx={{
|
|
27
|
+
<Box data-testid="readme" sx={{ m: 2 }}>
|
|
23
28
|
<Wrapper
|
|
24
29
|
className={`markdown-body ${isDarkMode ? 'markdown-dark' : 'markdown-light'}`}
|
|
25
30
|
dangerouslySetInnerHTML={{ __html: parseReadme(description) as string }}
|
|
@@ -21,9 +21,6 @@ marked.setOptions({
|
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
export function parseReadme(readme: string): string | void {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return DOMPurify.sanitize(html);
|
|
27
|
-
}
|
|
28
|
-
return '';
|
|
24
|
+
const html = marked.parse(readme);
|
|
25
|
+
return DOMPurify.sanitize(html);
|
|
29
26
|
}
|
|
@@ -4,10 +4,11 @@ import DialogTitle from '@mui/material/DialogTitle';
|
|
|
4
4
|
|
|
5
5
|
import { Theme } from '../../';
|
|
6
6
|
|
|
7
|
-
export const Title = styled(DialogTitle)<{ theme?: Theme }>((
|
|
8
|
-
backgroundColor:
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
export const Title = styled(DialogTitle)<{ theme?: Theme }>(({ theme }) => ({
|
|
8
|
+
backgroundColor:
|
|
9
|
+
theme?.palette.mode === 'light' ? theme?.palette.primary.main : theme?.palette.cyanBlue,
|
|
10
|
+
color: theme?.palette.white,
|
|
11
|
+
fontSize: theme?.fontSize.lg,
|
|
11
12
|
}));
|
|
12
13
|
|
|
13
14
|
export const Content = styled(DialogContent)<{ theme?: Theme }>(({ theme }) => ({
|
|
@@ -4,6 +4,7 @@ import List from '@mui/material/List';
|
|
|
4
4
|
import ListItem from '@mui/material/ListItem';
|
|
5
5
|
import ListItemText from '@mui/material/ListItemText';
|
|
6
6
|
import Typography from '@mui/material/Typography';
|
|
7
|
+
import { useTheme } from '@mui/styles';
|
|
7
8
|
import React from 'react';
|
|
8
9
|
import { useTranslation } from 'react-i18next';
|
|
9
10
|
|
|
@@ -11,20 +12,13 @@ import { Theme } from '../../Theme';
|
|
|
11
12
|
import { url as urlUtils } from '../../utils';
|
|
12
13
|
import CopyClipboard from '../CopyClipboard';
|
|
13
14
|
import { Git } from '../Icons';
|
|
14
|
-
import
|
|
15
|
+
import LinkExternal from '../LinkExternal';
|
|
15
16
|
|
|
16
17
|
const StyledText = styled(Typography)<{ theme?: Theme }>((props) => ({
|
|
17
18
|
fontWeight: props.theme?.fontWeight.bold,
|
|
18
19
|
textTransform: 'capitalize',
|
|
19
20
|
}));
|
|
20
21
|
|
|
21
|
-
const GithubLink = styled(Link)<{ theme?: Theme }>(({ theme }) => ({
|
|
22
|
-
color: theme?.palette.mode === 'light' ? theme?.palette.primary.main : theme?.palette.white,
|
|
23
|
-
':hover': {
|
|
24
|
-
color: theme?.palette.dodgerBlue,
|
|
25
|
-
},
|
|
26
|
-
}));
|
|
27
|
-
|
|
28
22
|
const RepositoryListItem = styled(ListItem)({
|
|
29
23
|
padding: 0,
|
|
30
24
|
':hover': {
|
|
@@ -33,18 +27,19 @@ const RepositoryListItem = styled(ListItem)({
|
|
|
33
27
|
});
|
|
34
28
|
|
|
35
29
|
const RepositoryListItemText = styled(ListItemText)({
|
|
36
|
-
padding: '0 10px',
|
|
30
|
+
padding: '0 0 0 10px',
|
|
37
31
|
margin: 0,
|
|
38
32
|
});
|
|
39
33
|
|
|
40
34
|
const RepositoryAvatar = styled(Avatar)({
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
padding: 0,
|
|
36
|
+
marginLeft: 0,
|
|
43
37
|
backgroundColor: 'transparent',
|
|
44
38
|
});
|
|
45
39
|
|
|
46
40
|
const Repository: React.FC<{ packageMeta: any }> = ({ packageMeta }) => {
|
|
47
41
|
const { t } = useTranslation();
|
|
42
|
+
const theme = useTheme();
|
|
48
43
|
const url = packageMeta?.latest?.repository?.url;
|
|
49
44
|
if (!url || !urlUtils.isURL(url)) {
|
|
50
45
|
return null;
|
|
@@ -66,15 +61,15 @@ const Repository: React.FC<{ packageMeta: any }> = ({ packageMeta }) => {
|
|
|
66
61
|
subheader={<StyledText variant="subtitle1">{t('sidebar.repository.title')}</StyledText>}
|
|
67
62
|
>
|
|
68
63
|
<RepositoryListItem>
|
|
69
|
-
<RepositoryAvatar sx={{
|
|
64
|
+
<RepositoryAvatar sx={{ bgcolor: theme.palette.white }}>
|
|
70
65
|
<Git />
|
|
71
66
|
</RepositoryAvatar>
|
|
72
67
|
<RepositoryListItemText
|
|
73
68
|
primary={
|
|
74
69
|
<CopyClipboard dataTestId="repositoryID" text={repositoryURL} title={repositoryURL}>
|
|
75
|
-
<
|
|
70
|
+
<LinkExternal to={repositoryURL} variant="outline">
|
|
76
71
|
{repositoryURL}
|
|
77
|
-
</
|
|
72
|
+
</LinkExternal>
|
|
78
73
|
</CopyClipboard>
|
|
79
74
|
}
|
|
80
75
|
/>
|