mirror of https://github.com/artifacthub/hub.git
Refresh design with some touches across the UI (#2690)
Signed-off-by: Cintia Sanchez Garcia <cynthiasg@icloud.com>
This commit is contained in:
parent
2c211d4b76
commit
f4ea916d06
|
|
@ -82,6 +82,18 @@ body {
|
|||
color: var(--color-font);
|
||||
}
|
||||
|
||||
.swagger-ui input[type=email], .swagger-ui input[type=file], .swagger-ui input[type=password], .swagger-ui input[type=search], .swagger-ui input[type=text], .swagger-ui textarea {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.swagger-ui .opblock, .swagger-ui .opblock-body pre.microlight, .swagger-ui select, .swagger-ui .opblock .opblock-summary-method, .swagger-ui .btn, .swagger-ui .copy-to-clipboard {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.swagger-ui .model-box-control:focus, .swagger-ui .models-control:focus, .swagger-ui .opblock-summary-control:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.swagger-ui .topbar .download-url-wrapper .select-label select {
|
||||
border-color: var(--color-1-500);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,15 +6,13 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<title>Artifact Hub Helm charts repository</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
html, body {
|
||||
background-color: #417598;
|
||||
color: #ffffff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Lato", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
font-size: 1rem;
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 1rem;
|
||||
font-weight: 300;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -79,4 +79,4 @@ oras push \
|
|||
artifacthub-repo.yml:application/vnd.cncf.artifacthub.repository-metadata.layer.v1.yaml
|
||||
```
|
||||
|
||||
*Please note that publishing an Artifact Hub repository metadata file requires that the registry supports [OCI artifacts](https://oras.land/implementors/).
|
||||
*Please note that publishing an Artifact Hub repository metadata file requires that the registry supports [OCI artifacts](https://oras.land/implementors/).*
|
||||
|
|
|
|||
|
|
@ -44,39 +44,6 @@
|
|||
--color-code: #a3a3a6;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Lato';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local('Lato Light'), local('Lato-Light'), url('/static/fonts/Lato/lato-300.woff2') format('woff2'),
|
||||
url('/static/fonts/Lato/lato-300.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Lato';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Lato Bold'), local('Lato-Bold'), url('/static/fonts/Lato/lato-700.woff2') format('woff2'),
|
||||
url('/static/fonts/Lato/lato-700.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Lato';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Lato Regular'), local('Lato-Regular'), url('/static/fonts/Lato/lato-regular.woff2') format('woff2'),
|
||||
url('/static/fonts/Lato/lato-regular.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto Mono';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Roboto Mono'), local('RobotoMono-Regular'),
|
||||
url('/static/fonts/Roboto_Mono/roboto-mono-regular.woff2') format('woff2'),
|
||||
url('/static/fonts/Roboto_Mono/roboto-mono-regular.woff') format('woff');
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--body-bg);
|
||||
color: var(--color-font);
|
||||
|
|
@ -86,11 +53,11 @@ body {
|
|||
}
|
||||
|
||||
body, .gdoc-mermaid, .gdoc-header {
|
||||
font-family: 'Lato', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: 'Roboto Mono', 'Courier New', monospace;
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
|
||||
.gdoc-header {
|
||||
|
|
@ -126,7 +93,6 @@ code {
|
|||
word-wrap: break-word;
|
||||
background-color: var(--mid-gray) !important;
|
||||
border: 1px solid rgba(28, 44, 53, 0.1) !important;
|
||||
border-radius: 3px;
|
||||
padding: 0 0.15rem;
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +104,6 @@ code {
|
|||
|
||||
.gdoc-markdown pre {
|
||||
overflow-x: auto;
|
||||
border-radius: 3px;
|
||||
padding: .5rem 1rem;
|
||||
tab-size: 4;
|
||||
background-color: var(--bg-code) !important;
|
||||
|
|
@ -172,7 +137,6 @@ code {
|
|||
}
|
||||
|
||||
.gdoc-nav--main {
|
||||
border-radius: .25rem;
|
||||
background-color: var(--ah-white);
|
||||
border: 1px solid var(--color-black-125);
|
||||
box-shadow: 0 .125rem .25rem var(--color-black-75);
|
||||
|
|
|
|||
|
|
@ -6,14 +6,13 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<title>Artifact Hub - maintenance page</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@300&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
html, body {
|
||||
background-color: #417598;
|
||||
color: #ffffff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Lato", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-size: 1rem;
|
||||
font-weight: 300;
|
||||
height: 100%;
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -3,7 +3,6 @@
|
|||
}
|
||||
|
||||
.templateWrapper {
|
||||
border-radius: 3px;
|
||||
border-color: var(--color-black-15) !important;
|
||||
background-color: var(--extra-light-gray);
|
||||
}
|
||||
|
|
@ -47,7 +46,6 @@
|
|||
line-height: 18px;
|
||||
padding: 0 5px;
|
||||
border-color: var(--gray) !important;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.searchIcon {
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ const ContentDefaultModal = (props: Props) => {
|
|||
<div className={styles.legend}>
|
||||
<small className="text-muted text-uppercase">Kind:</small>
|
||||
</div>
|
||||
<span className={`text-truncate border fw-bold ${styles.label}`}>
|
||||
<span className={`text-truncate border fw-semibold ${styles.label}`}>
|
||||
{resource.kind}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -360,20 +360,18 @@ const ContentDefaultModal = (props: Props) => {
|
|||
return (
|
||||
<div className={`p-3 border-bottom ${styles.extraInfo}`}>
|
||||
<div className="h6 fw-bold">{selectedItem.displayName || selectedItem.name}</div>
|
||||
<div className="d-flex flex-row align-items-baseline mb-1">
|
||||
<div className={styles.legend}>
|
||||
<small className="text-muted text-uppercase">Name:</small>
|
||||
</div>
|
||||
<div className={`text-truncate ${styles.btnItemContent}`}>{selectedItem.name}</div>
|
||||
<div className="mb-1">
|
||||
<small className="text-muted text-uppercase me-2">Name:</small>
|
||||
<span className={`text-truncate ${styles.btnItemContent}`}>
|
||||
{selectedItem.name}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-row align-items-baseline mb-1">
|
||||
<div className={styles.legend}>
|
||||
<small className="text-muted text-uppercase">Description:</small>
|
||||
</div>
|
||||
<div className={styles.btnItemContent}>
|
||||
<div className="mb-1">
|
||||
<small className="text-muted text-uppercase me-2">Description:</small>
|
||||
<span className={styles.btnItemContent}>
|
||||
{selectedItem.description.replace(/\n/g, ' ')}
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
min-width: 60px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-color: var(--bs-white) !important;
|
||||
box-shadow: 0px 0px 5px 0px var(--color-1-20);
|
||||
}
|
||||
|
||||
.imageAsBg {
|
||||
|
|
@ -31,5 +29,4 @@
|
|||
width: 60px;
|
||||
height: 60px;
|
||||
border-color: var(--bs-white) !important;
|
||||
box-shadow: 0px 0px 5px 0px var(--color-1-20);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,8 @@
|
|||
.labelText {
|
||||
background-color: var(--body-light-bg);
|
||||
line-height: 18px;
|
||||
padding: 0 5px 0 10px;
|
||||
padding: 0 5px;
|
||||
border-color: var(--color-black-15) !important;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.labelTextNoIcon {
|
||||
|
|
@ -19,10 +18,6 @@
|
|||
height: 20px;
|
||||
line-height: 1rem;
|
||||
color: var(--light-gray);
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
box-shadow: inset -1px 0 var(--color-black-25);
|
||||
margin-right: -3px;
|
||||
min-width: 20px;
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +26,6 @@
|
|||
}
|
||||
|
||||
.onlyIcon {
|
||||
border-radius: 3px !important;
|
||||
width: 21px;
|
||||
}
|
||||
|
||||
|
|
@ -39,54 +33,23 @@
|
|||
stroke: var(--light-gray);
|
||||
}
|
||||
|
||||
.iconWrapper:not(.onlyIcon)::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: -3px;
|
||||
top: calc(50% - 3px);
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
border-radius: 50%;
|
||||
box-shadow: inset -1px 0 var(--color-black-25);
|
||||
}
|
||||
|
||||
.default .iconWrapper {
|
||||
background-color: var(--light-gray);
|
||||
color: var(--bs-dark);
|
||||
}
|
||||
|
||||
.default .iconWrapper::before {
|
||||
background-color: var(--light-gray);
|
||||
}
|
||||
|
||||
.warning .iconWrapper {
|
||||
background-color: var(--bs-orange);
|
||||
}
|
||||
|
||||
.warning .iconWrapper::before {
|
||||
background-color: var(--bs-orange);
|
||||
}
|
||||
|
||||
.success .iconWrapper {
|
||||
background-color: var(--bs-success);
|
||||
}
|
||||
|
||||
.success .iconWrapper::before {
|
||||
background-color: var(--bs-success);
|
||||
}
|
||||
|
||||
.danger .iconWrapper {
|
||||
background-color: var(--bs-danger);
|
||||
}
|
||||
|
||||
.danger .iconWrapper::before {
|
||||
background-color: var(--bs-danger);
|
||||
}
|
||||
|
||||
.custom .iconWrapper {
|
||||
color: var(--light-gray);
|
||||
}
|
||||
|
||||
.custom .iconWrapper::before {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
}
|
||||
|
||||
.content {
|
||||
border-radius: 15px !important;
|
||||
border-radius: 0 !important;
|
||||
border-color: var(--color-1-500) !important;
|
||||
box-shadow: 0px 0px 5px 0px var(--color-1-20) !important;
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
.modal pre:not(:global(.customYAML)):not(:global(.diffTemplate)) {
|
||||
padding: 16px !important;
|
||||
border-radius: 3px;
|
||||
border-radius: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +71,5 @@
|
|||
padding: 0.25rem 0.5rem;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,14 +16,11 @@
|
|||
min-width: 30px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-color: var(--color-1-10) !important;
|
||||
|
||||
box-shadow: 0px 0px 5px 0px var(--color-1-20);
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: calc(100% - 2px);
|
||||
max-height: calc(100% - 2px);
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.description {
|
||||
|
|
@ -35,6 +32,10 @@
|
|||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.icon {
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 575.98px) {
|
||||
.dropdown {
|
||||
display: none !important;
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ const OrganizationInfo = (props: Props) => {
|
|||
<div className={styles.content}>
|
||||
<div className="d-flex flex-row align-items-center">
|
||||
<div
|
||||
className={`d-flex align-items-center justify-content-center overflow-hidden me-2 p-1 position-relative border border-2 rounded-circle bg-white ${styles.imageWrapper} imageWrapper`}
|
||||
className={`d-flex align-items-center justify-content-center overflow-hidden me-2 position-relative ${styles.imageWrapper}`}
|
||||
>
|
||||
{organization.logoImageId ? (
|
||||
<Image
|
||||
|
|
@ -137,15 +137,15 @@ const OrganizationInfo = (props: Props) => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-row align-items-start text-truncate">
|
||||
<div className="d-flex flex-row align-items-baseline text-truncate">
|
||||
{props.visibleLegend && (
|
||||
<div className="d-flex flex-row align-items-baseline me-1 text-muted text-uppercase">
|
||||
<small>Org:</small>
|
||||
<div className={`d-flex flex-row align-items-baseline me-1 text-dark position-relative ${styles.icon}`}>
|
||||
<MdBusiness />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<button
|
||||
className={`p-0 border-0 text-dark text-truncate flex-grow-1 bg-transparent position-relative ${styles.link} ${props.btnClassName}`}
|
||||
className={`p-0 border-0 text-muted text-truncate flex-grow-1 bg-transparent position-relative ${styles.link} ${props.btnClassName}`}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
history.push({
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
.card {
|
||||
box-shadow: 0px 0px 5px 0px var(--bs-light);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.card:hover {
|
||||
border-color: var(--color-black-50);
|
||||
box-shadow: 0px 0px 5px 0px var(--color-black-75);
|
||||
border-color: var(--color-black-25);
|
||||
box-shadow: 0 0 0 2px var(--color-black-25);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -21,15 +17,145 @@
|
|||
color: inherit;
|
||||
}
|
||||
|
||||
.imageWrapper {
|
||||
min-width: 70px;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: var(--gray-dark);
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.mx50 {
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.titleWrapper {
|
||||
background-color: var(--body-bg);
|
||||
padding: 0.6rem 1rem;
|
||||
height: 70px;
|
||||
margin-left: 0.75rem;
|
||||
}
|
||||
|
||||
.rightInfo {
|
||||
padding-left: 2.25rem;
|
||||
}
|
||||
|
||||
[data-theme='dark'] .titleWrapper {
|
||||
background-color: #2c2e31;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 0.85rem;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.subtitle span {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.kind {
|
||||
font-size: 0.9rem;
|
||||
color: var(--color-1-500);
|
||||
}
|
||||
|
||||
.truncateWrapper {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.version {
|
||||
font-size: 0.8rem;
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
.userInfo {
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.userIcon {
|
||||
font-size: 0.8rem;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.licenseBtn {
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.labelsWrapper > div:not(:last-child) {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 575.98px) {
|
||||
.lineClamp {
|
||||
overflow: hidden;
|
||||
text-overflow: unset;
|
||||
white-space: inherit;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
word-wrap: normal;
|
||||
max-height: 62px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767.98px) {
|
||||
.imageWrapper {
|
||||
min-width: 50px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 1rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
.card {
|
||||
min-height: 215px;
|
||||
@media only screen and (min-width: 576px) {
|
||||
.titleWrapper {
|
||||
width: 600px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 992px) {
|
||||
.labelsWrapper > div:not(:first-child) {
|
||||
margin-right: 0;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.labelsWrapper > div:first-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -44,3 +170,15 @@
|
|||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1920px) {
|
||||
.titleWrapper {
|
||||
width: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
.card {
|
||||
min-height: 215px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import { render, screen } from '@testing-library/react';
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
|
||||
import { Package } from '../../types';
|
||||
import calculateDiffInYears from '../../utils/calculateDiffInYears';
|
||||
import { prepareQueryString } from '../../utils/prepareQueryString';
|
||||
import PackageCard from './PackageCard';
|
||||
jest.mock('../../utils/calculateDiffInYears');
|
||||
|
||||
const getMockPackage = (fixtureId: string): Package => {
|
||||
return require(`./__fixtures__/PackageCard/${fixtureId}.json`) as Package;
|
||||
|
|
@ -19,14 +21,11 @@ jest.mock('react-router-dom', () => ({
|
|||
}),
|
||||
}));
|
||||
|
||||
const mockSaveScrollPosition = jest.fn();
|
||||
|
||||
const defaultProps = {
|
||||
saveScrollPosition: mockSaveScrollPosition,
|
||||
searchUrlReferer: undefined,
|
||||
};
|
||||
|
||||
describe('PackageCard', () => {
|
||||
beforeEach(() => {
|
||||
(calculateDiffInYears as jest.Mock).mockImplementation(() => 0.5);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
|
@ -35,7 +34,7 @@ describe('PackageCard', () => {
|
|||
const mockPackage = getMockPackage('1');
|
||||
const { asFragment } = render(
|
||||
<Router>
|
||||
<PackageCard {...defaultProps} package={mockPackage} />
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
|
|
@ -46,7 +45,7 @@ describe('PackageCard', () => {
|
|||
const mockPackage = getMockPackage('2');
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard {...defaultProps} package={mockPackage} />
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const image = screen.getByAltText(`Logo ${mockPackage.displayName}`);
|
||||
|
|
@ -58,7 +57,7 @@ describe('PackageCard', () => {
|
|||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard {...defaultProps} package={mockPackage} />
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const image = screen.getByAltText(`Logo ${mockPackage.displayName}`);
|
||||
|
|
@ -73,11 +72,10 @@ describe('PackageCard', () => {
|
|||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard {...defaultProps} package={mockPackage} />
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const title = screen.getByText(mockPackage.displayName!);
|
||||
expect(title).toBeInTheDocument();
|
||||
expect(screen.getByText(mockPackage.displayName!)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders name when display name is null', () => {
|
||||
|
|
@ -85,7 +83,7 @@ describe('PackageCard', () => {
|
|||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard {...defaultProps} package={mockPackage} />
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
expect(screen.getByText(mockPackage.name!)).toBeInTheDocument();
|
||||
|
|
@ -98,26 +96,28 @@ describe('PackageCard', () => {
|
|||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard {...defaultProps} package={mockPackage} />
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
|
||||
const buttons = screen.getAllByTestId('repoLink');
|
||||
expect(buttons).toHaveLength(2);
|
||||
const icons = screen.getAllByAltText('Icon');
|
||||
expect(icons).toHaveLength(16);
|
||||
expect(icons).toHaveLength(12);
|
||||
expect(icons[0]).toBeInTheDocument();
|
||||
expect((icons[0] as HTMLImageElement).src).toBe('http://localhost/static/media/helm-chart.svg');
|
||||
await userEvent.click(buttons[0]!);
|
||||
expect(mockHistoryPush).toHaveBeenCalledTimes(1);
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith({
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
pageNumber: 1,
|
||||
filters: {
|
||||
repo: [mockPackage.repository.name],
|
||||
},
|
||||
}),
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockHistoryPush).toHaveBeenCalledTimes(1);
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith({
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
pageNumber: 1,
|
||||
filters: {
|
||||
repo: [mockPackage.repository.name],
|
||||
},
|
||||
}),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -126,43 +126,105 @@ describe('PackageCard', () => {
|
|||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard {...defaultProps} package={mockPackage} />
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const button = screen.getByTestId('userLink');
|
||||
expect(button).toBeInTheDocument();
|
||||
await userEvent.click(button);
|
||||
expect(mockHistoryPush).toHaveBeenCalledTimes(1);
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith({
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
pageNumber: 1,
|
||||
filters: {
|
||||
user: [mockPackage.repository.userAlias!],
|
||||
},
|
||||
}),
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockHistoryPush).toHaveBeenCalledTimes(1);
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith({
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
pageNumber: 1,
|
||||
filters: {
|
||||
user: [mockPackage.repository.userAlias!],
|
||||
},
|
||||
}),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('renders repo kind link', async () => {
|
||||
const mockPackage = getMockPackage('8');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const buttons = screen.getAllByTestId('repoIconLabelLink');
|
||||
expect(buttons).toHaveLength(2);
|
||||
await userEvent.click(buttons[0]);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockHistoryPush).toHaveBeenCalledTimes(1);
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith({
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
pageNumber: 1,
|
||||
filters: {
|
||||
kind: ['1'],
|
||||
},
|
||||
}),
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Detail', () => {
|
||||
it('opens detail page', async () => {
|
||||
const mockPackage = getMockPackage('9');
|
||||
const urlReferer = {
|
||||
tsQueryWeb: 'test',
|
||||
filters: {},
|
||||
pageNumber: 1,
|
||||
};
|
||||
describe('Security Rating label', () => {
|
||||
it('renders label', () => {
|
||||
const mockPackage = getMockPackage('12');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard {...defaultProps} package={mockPackage} searchUrlReferer={urlReferer} />
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const link = screen.getByRole('link');
|
||||
expect(link).toBeInTheDocument();
|
||||
await userEvent.click(link!);
|
||||
expect(mockSaveScrollPosition).toHaveBeenCalledTimes(1);
|
||||
expect(window.location.pathname).toBe('/packages/helm/test/test');
|
||||
|
||||
expect(screen.getByText('Images Security Rating')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not render label when package is older than 1 year', () => {
|
||||
(calculateDiffInYears as jest.Mock).mockImplementation(() => 1.5);
|
||||
|
||||
const mockPackage = getMockPackage('12');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Images Security Rating')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when repository has a verified publisher', () => {
|
||||
it('renders correct label', () => {
|
||||
const mockPackage = getMockPackage('10');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
expect(screen.getAllByText('Verified Publisher')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when repository has repository scanner disabled', () => {
|
||||
it('renders correct label', () => {
|
||||
const mockPackage = getMockPackage('11');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
expect(screen.getAllByText('Security scanner disabled')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,40 +1,262 @@
|
|||
import isUndefined from 'lodash/isUndefined';
|
||||
import { Link } from 'react-router-dom';
|
||||
import moment from 'moment';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { AiOutlineStop } from 'react-icons/ai';
|
||||
import { FaUser } from 'react-icons/fa';
|
||||
import { Link, useHistory } from 'react-router-dom';
|
||||
|
||||
import { Package, SearchFiltersURL } from '../../types';
|
||||
import { Package, RepositoryKind, SearchFiltersURL } from '../../types';
|
||||
import buildPackageURL from '../../utils/buildPackageURL';
|
||||
import calculateDiffInYears from '../../utils/calculateDiffInYears';
|
||||
import cutString from '../../utils/cutString';
|
||||
import isFuture from '../../utils/isFuture';
|
||||
import isPackageOfficial from '../../utils/isPackageOfficial';
|
||||
import { prepareQueryString } from '../../utils/prepareQueryString';
|
||||
import Image from '../common/Image';
|
||||
import Label from '../common/Label';
|
||||
import OfficialBadge from '../common/OfficialBadge';
|
||||
import OrganizationInfo from '../common/OrganizationInfo';
|
||||
import ProductionBadge from '../common/ProductionBadge';
|
||||
import RepositoryIconLabel from '../common/RepositoryIconLabel';
|
||||
import RepositoryInfo from '../common/RepositoryInfo';
|
||||
import ScannerDisabledRepositoryBadge from '../common/ScannerDisabledRepositoryBadge';
|
||||
import SecurityRating from '../common/SecurityRating';
|
||||
import SignedBadge from '../common/SignedBadge';
|
||||
import StarBadge from '../common/StarBadge';
|
||||
import VerifiedPublisherBadge from '../common/VerifiedPublisherBadge';
|
||||
import styles from './PackageCard.module.css';
|
||||
import PackageInfo from './PackageInfo';
|
||||
|
||||
interface Props {
|
||||
package: Package;
|
||||
cardWrapperClassName?: string;
|
||||
className?: string;
|
||||
saveScrollPosition?: () => void;
|
||||
noBadges?: boolean;
|
||||
searchUrlReferer?: SearchFiltersURL;
|
||||
fromStarredPage?: boolean;
|
||||
}
|
||||
|
||||
const PackageCard = (props: Props) => (
|
||||
<div className={`col-12 col-xxl-6 py-sm-3 py-2 ${styles.cardWrapper}`} role="listitem">
|
||||
<div className={`card cardWithHover h-100 mw-100 bg-white ${styles.card} ${props.className}`}>
|
||||
<Link
|
||||
className={`text-decoration-none text-reset h-100 bg-transparent ${styles.link}`}
|
||||
onClick={() => {
|
||||
if (!isUndefined(props.saveScrollPosition)) {
|
||||
props.saveScrollPosition();
|
||||
}
|
||||
}}
|
||||
to={{
|
||||
pathname: buildPackageURL(props.package.normalizedName, props.package.repository, props.package.version!),
|
||||
state: { searchUrlReferer: props.searchUrlReferer, fromStarredPage: props.fromStarredPage },
|
||||
}}
|
||||
>
|
||||
<div className={`card-body d-flex flex-column h-100 ${styles.body}`}>
|
||||
<PackageInfo package={props.package} breakpointForInfoSection="lg" />
|
||||
</div>
|
||||
</Link>
|
||||
const PackageCard = (props: Props) => {
|
||||
const history = useHistory();
|
||||
const [isVersionOlderThanOneYear, setIsVersionOlderThanOneYear] = useState<boolean>(false);
|
||||
|
||||
const pkgTS = (
|
||||
<>
|
||||
{!isFuture(props.package.ts) && (
|
||||
<small className={`text-muted text-nowrap ${styles.date}`}>
|
||||
Updated {moment.unix(props.package.ts).fromNow()}
|
||||
</small>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
const starsAndKindInfo = (
|
||||
<div className={`align-self-start d-flex align-items-center text-uppercase ms-auto ${styles.kind}`}>
|
||||
<StarBadge className="me-2" starsNumber={props.package.stars} />
|
||||
<RepositoryIconLabel
|
||||
btnClassName={`position-relative ${styles.repoLabel}`}
|
||||
kind={props.package.repository.kind}
|
||||
deprecated={props.package.deprecated}
|
||||
clickable
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const diffInYears = calculateDiffInYears(props.package.ts);
|
||||
setIsVersionOlderThanOneYear(diffInYears > 1);
|
||||
}, [props.package]);
|
||||
|
||||
return (
|
||||
<div className={`py-sm-3 py-2 ${styles.cardWrapper} ${props.cardWrapperClassName}`} role="listitem">
|
||||
<div className={`card cardWithHover h-100 mw-100 bg-white ${styles.card} ${props.className}`}>
|
||||
<Link
|
||||
className={`text-decoration-none text-reset h-100 bg-transparent ${styles.link}`}
|
||||
onClick={() => {
|
||||
if (!isUndefined(props.saveScrollPosition)) {
|
||||
props.saveScrollPosition();
|
||||
}
|
||||
}}
|
||||
to={{
|
||||
pathname: buildPackageURL(props.package.normalizedName, props.package.repository, props.package.version!),
|
||||
state: { searchUrlReferer: props.searchUrlReferer, fromStarredPage: props.fromStarredPage },
|
||||
}}
|
||||
>
|
||||
<div className={`card-body d-flex flex-column h-100 ${styles.body}`}>
|
||||
<div className="d-flex align-items-start justify-content-between mw-100">
|
||||
<div className={`d-flex align-items-stretch flex-grow-1 h-100 ${styles.truncateWrapper}`}>
|
||||
<div
|
||||
className={`my-2 my-md-0 d-flex align-items-center justify-content-center overflow-hidden position-relative ${styles.imageWrapper}`}
|
||||
>
|
||||
<Image
|
||||
imageId={props.package.logoImageId}
|
||||
alt={`Logo ${props.package.displayName || props.package.name}`}
|
||||
className={styles.image}
|
||||
kind={props.package.repository.kind}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`d-flex flex-column flex-grow-1 flex-sm-grow-0 justify-content-between ${styles.truncateWrapper} ${styles.titleWrapper}`}
|
||||
>
|
||||
<div className="text-truncate card-title mb-0">
|
||||
<div className="d-flex flex-row align-items-center justify-content-between">
|
||||
<div className={`text-truncate ${styles.title}`}>
|
||||
{props.package.displayName || props.package.name}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="d-block d-md-none">
|
||||
<div className={`card-subtitle align-items-baseline ${styles.subtitle}`}>
|
||||
<RepositoryInfo
|
||||
repository={props.package.repository}
|
||||
deprecated={props.package.deprecated}
|
||||
className="d-inline d-md-none text-truncate w-100"
|
||||
repoLabelClassName="d-none"
|
||||
withLabels={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={`d-none d-md-block card-subtitle align-items-center ${styles.subtitle}`}>
|
||||
<div className="d-flex flex-row align-items-center">
|
||||
{props.package.repository.organizationName && (
|
||||
<OrganizationInfo
|
||||
className={`me-0 d-flex flex-row align-items-baseline text-left w-auto ${styles.mx50} `}
|
||||
btnClassName="text-truncate mw-100"
|
||||
organizationName={props.package.repository.organizationName}
|
||||
organizationDisplayName={props.package.repository.organizationDisplayName}
|
||||
deprecated={props.package.deprecated}
|
||||
visibleLegend
|
||||
/>
|
||||
)}
|
||||
|
||||
{props.package.repository.userAlias && (
|
||||
<div className={`d-flex flex-row align-items-baseline ${styles.userInfo}`}>
|
||||
<div className={`text-dark me-1 position-relative ${styles.userIcon}`}>
|
||||
<FaUser />
|
||||
</div>
|
||||
<span className="visually-hidden">{props.package.repository.userAlias}</span>
|
||||
|
||||
<button
|
||||
data-testid="userLink"
|
||||
className={`p-0 border-0 text-truncate text-muted mw-100 bg-transparent ${styles.link} ${styles.mx50}`}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
history.push({
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
pageNumber: 1,
|
||||
filters: {
|
||||
user: [props.package.repository.userAlias!],
|
||||
},
|
||||
deprecated: props.package.deprecated,
|
||||
}),
|
||||
});
|
||||
}}
|
||||
aria-label={`Filter by ${props.package.repository.userAlias}`}
|
||||
aria-hidden="true"
|
||||
tabIndex={-1}
|
||||
>
|
||||
<div className="text-truncate">{props.package.repository.userAlias}</div>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={styles.mx50}>
|
||||
<RepositoryInfo
|
||||
repository={props.package.repository}
|
||||
deprecated={props.package.deprecated}
|
||||
className={`d-flex flex-row align-items-baseline ms-3 ${styles.truncateWrapper}`}
|
||||
repoLabelClassName="d-none d-lg-inline"
|
||||
withLabels={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={`d-none d-lg-flex flex-column align-items-end mb-auto ms-auto ${styles.rightInfo}`}>
|
||||
{starsAndKindInfo}
|
||||
<div className="mt-1">{pkgTS}</div>
|
||||
<div className={`mt-1 text-truncate align-items-baseline position-relative ${styles.version}`}>
|
||||
<div className="d-flex flex-row align-items-baseline text-truncate">
|
||||
<span className="text-muted me-1">
|
||||
{props.package.repository.kind === RepositoryKind.Container ? 'Tag' : 'Version'}{' '}
|
||||
</span>
|
||||
{cutString(props.package.version || '-', 16)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!isUndefined(props.package.description) && (
|
||||
<div className={`mb-0 mb-md-1 mt-3 text-muted text-truncate ${styles.description} ${styles.lineClamp} `}>
|
||||
{props.package.description}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className={`d-flex d-lg-none flex-row flex-wrap justify-content-between align-items-center mt-auto pt-3 pt-lg-0 mt-1 mt-lg-0 mt-xxl-1 mt-xxxl-0`}
|
||||
>
|
||||
{pkgTS}
|
||||
<span>{starsAndKindInfo}</span>
|
||||
</div>
|
||||
|
||||
{(isUndefined(props.noBadges) || !props.noBadges) && (
|
||||
<div
|
||||
className={`d-none d-sm-flex flex-wrap justify-content-lg-end mt-0 mt-md-auto ${styles.labelsWrapper}`}
|
||||
>
|
||||
<OfficialBadge official={isPackageOfficial(props.package)} className="d-inline mt-3" type="package" />
|
||||
<ProductionBadge
|
||||
productionOrganizationsCount={props.package.productionOrganizationsCount}
|
||||
className="d-inline mt-3"
|
||||
/>
|
||||
<VerifiedPublisherBadge
|
||||
verifiedPublisher={props.package.repository.verifiedPublisher}
|
||||
className="d-inline mt-3"
|
||||
/>
|
||||
{props.package.deprecated && (
|
||||
<Label text="Deprecated" icon={<AiOutlineStop />} labelStyle="danger" className="d-inline mt-3" />
|
||||
)}
|
||||
{props.package.signed && (
|
||||
<SignedBadge
|
||||
signed={props.package.signed}
|
||||
signatures={props.package.signatures}
|
||||
repositoryKind={props.package.repository.kind}
|
||||
className="d-inline mt-3"
|
||||
/>
|
||||
)}
|
||||
{/* Do not display security rating badge when version is older than 1 year */}
|
||||
{!isVersionOlderThanOneYear && (
|
||||
<SecurityRating
|
||||
summary={props.package.securityReportSummary}
|
||||
className="d-inline mt-3"
|
||||
onlyBadge={false}
|
||||
withLink={buildPackageURL(
|
||||
props.package.normalizedName,
|
||||
props.package.repository,
|
||||
props.package.version!
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{(props.package.repository.scannerDisabled || props.package.allContainersImagesWhitelisted) && (
|
||||
<ScannerDisabledRepositoryBadge
|
||||
className="d-inline mt-3"
|
||||
scannerDisabled={props.package.repository.scannerDisabled || false}
|
||||
allContainersImagesWhitelisted={props.package.allContainersImagesWhitelisted || false}
|
||||
withTooltip
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PackageCard;
|
||||
|
|
|
|||
|
|
@ -1,128 +0,0 @@
|
|||
.imageWrapper {
|
||||
min-width: 80px;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-color: var(--color-1-10) !important;
|
||||
box-shadow: 0px 0px 5px 0px var(--color-1-20);
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: calc(100% - 10px);
|
||||
max-height: calc(100% - 10px);
|
||||
}
|
||||
|
||||
.link {
|
||||
color: var(--gray-dark);
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.mx50 {
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
.titleWrapper {
|
||||
margin-top: -3px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 0.9rem;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.subtitle span {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.kind {
|
||||
font-size: 0.9rem;
|
||||
color: var(--color-1-500);
|
||||
}
|
||||
|
||||
.truncateWrapper {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
.lineClamp {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.lastLine {
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
.licenseBtn {
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.labelsWrapper > div:not(:last-child) {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 575.98px) {
|
||||
.lineClamp {
|
||||
-webkit-line-clamp: 2;
|
||||
word-wrap: normal;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767.98px) {
|
||||
.imageWrapper {
|
||||
min-width: 60px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: calc(100% - 9px);
|
||||
max-height: calc(100% - 9px);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 992px) {
|
||||
.labelsWrapper > div:not(:first-child) {
|
||||
margin-right: 0;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.labelsWrapper > div:first-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1400px) and (max-width: 1991.98px) {
|
||||
.title {
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.imageWrapper {
|
||||
margin: 0.25rem 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,223 +0,0 @@
|
|||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
|
||||
import { Package } from '../../types';
|
||||
import calculateDiffInYears from '../../utils/calculateDiffInYears';
|
||||
import { prepareQueryString } from '../../utils/prepareQueryString';
|
||||
import PackageInfo from './PackageInfo';
|
||||
jest.mock('../../utils/calculateDiffInYears');
|
||||
|
||||
const getMockPackage = (fixtureId: string): Package => {
|
||||
return require(`./__fixtures__/PackageInfo/${fixtureId}.json`) as Package;
|
||||
};
|
||||
|
||||
const mockHistoryPush = jest.fn();
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...(jest.requireActual('react-router-dom') as {}),
|
||||
useHistory: () => ({
|
||||
push: mockHistoryPush,
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('PackageInfo', () => {
|
||||
beforeEach(() => {
|
||||
(calculateDiffInYears as jest.Mock).mockImplementation(() => 0.5);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('creates snapshot', () => {
|
||||
const mockPackage = getMockPackage('1');
|
||||
const { asFragment } = render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('Image', () => {
|
||||
it('renders package logo', () => {
|
||||
const mockPackage = getMockPackage('2');
|
||||
render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const image = screen.getByAltText(`Logo ${mockPackage.displayName}`);
|
||||
expect(image).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders placeholder when imageId is null', () => {
|
||||
const mockPackage = getMockPackage('3');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const image = screen.getByAltText(`Logo ${mockPackage.displayName}`);
|
||||
expect(image).toBeInTheDocument();
|
||||
expect((image as HTMLImageElement).src).toBe('http://localhost/static/media/placeholder_pkg_helm.png');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Title', () => {
|
||||
it('renders display name', () => {
|
||||
const mockPackage = getMockPackage('4');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
expect(screen.getByText(mockPackage.displayName!)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders name when display name is null', () => {
|
||||
const mockPackage = getMockPackage('5');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
expect(screen.getByText(mockPackage.name!)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Repository button', () => {
|
||||
it('renders repository link', async () => {
|
||||
const mockPackage = getMockPackage('6');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const buttons = screen.getAllByTestId('repoLink');
|
||||
expect(buttons).toHaveLength(2);
|
||||
const icons = screen.getAllByAltText('Icon');
|
||||
expect(icons).toHaveLength(16);
|
||||
expect(icons[0]).toBeInTheDocument();
|
||||
expect((icons[0] as HTMLImageElement).src).toBe('http://localhost/static/media/helm-chart.svg');
|
||||
await userEvent.click(buttons[0]!);
|
||||
expect(mockHistoryPush).toHaveBeenCalledTimes(1);
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith({
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
pageNumber: 1,
|
||||
filters: {
|
||||
repo: [mockPackage.repository.name],
|
||||
},
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
it('renders user link', async () => {
|
||||
const mockPackage = getMockPackage('7');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const button = screen.getByTestId('userLink');
|
||||
expect(button).toBeInTheDocument();
|
||||
await userEvent.click(button);
|
||||
expect(mockHistoryPush).toHaveBeenCalledTimes(1);
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith({
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
pageNumber: 1,
|
||||
filters: {
|
||||
user: [mockPackage.repository.userAlias!],
|
||||
},
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
it('renders repo kind link', async () => {
|
||||
const mockPackage = getMockPackage('8');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const buttons = screen.getAllByTestId('repoIconLabelLink');
|
||||
expect(buttons).toHaveLength(3);
|
||||
await userEvent.click(buttons[0]);
|
||||
expect(mockHistoryPush).toHaveBeenCalledTimes(1);
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith({
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
pageNumber: 1,
|
||||
filters: {
|
||||
kind: ['1'],
|
||||
},
|
||||
}),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Security Rating label', () => {
|
||||
it('renders label', () => {
|
||||
const mockPackage = getMockPackage('12');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
|
||||
expect(screen.getByText('Images Security Rating')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not render label when package is older than 1 year', () => {
|
||||
(calculateDiffInYears as jest.Mock).mockImplementation(() => 1.5);
|
||||
|
||||
const mockPackage = getMockPackage('12');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Images Security Rating')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when repository has a verified publisher', () => {
|
||||
it('renders correct label', () => {
|
||||
const mockPackage = getMockPackage('10');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
|
||||
expect(screen.getAllByText('Verified Publisher')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when repository has repository scanner disabled', () => {
|
||||
it('renders correct label', () => {
|
||||
const mockPackage = getMockPackage('11');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageInfo package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
|
||||
expect(screen.getAllByText('Security scanner disabled')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,270 +0,0 @@
|
|||
import moment from 'moment';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { AiOutlineStop } from 'react-icons/ai';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { Package, RepositoryKind } from '../../types';
|
||||
import buildPackageURL from '../../utils/buildPackageURL';
|
||||
import calculateDiffInYears from '../../utils/calculateDiffInYears';
|
||||
import cutString from '../../utils/cutString';
|
||||
import isFuture from '../../utils/isFuture';
|
||||
import isPackageOfficial from '../../utils/isPackageOfficial';
|
||||
import { prepareQueryString } from '../../utils/prepareQueryString';
|
||||
import License from '../package/License';
|
||||
import Image from './Image';
|
||||
import Label from './Label';
|
||||
import OfficialBadge from './OfficialBadge';
|
||||
import OrganizationInfo from './OrganizationInfo';
|
||||
import styles from './PackageInfo.module.css';
|
||||
import ProductionBadge from './ProductionBadge';
|
||||
import RepositoryIconLabel from './RepositoryIconLabel';
|
||||
import RepositoryInfo from './RepositoryInfo';
|
||||
import ScannerDisabledRepositoryBadge from './ScannerDisabledRepositoryBadge';
|
||||
import SecurityRating from './SecurityRating';
|
||||
import SignedBadge from './SignedBadge';
|
||||
import StarBadge from './StarBadge';
|
||||
import VerifiedPublisherBadge from './VerifiedPublisherBadge';
|
||||
|
||||
interface Props {
|
||||
package: Package;
|
||||
breakpointForInfoSection?: string;
|
||||
}
|
||||
|
||||
const PackageInfo = (props: Props) => {
|
||||
const history = useHistory();
|
||||
const [isVersionOlderThanOneYear, setIsVersionOlderThanOneYear] = useState<boolean>(false);
|
||||
|
||||
const pkgTS = (
|
||||
<>
|
||||
{!isFuture(props.package.ts) && (
|
||||
<small className={`text-muted text-nowrap ${styles.date}`}>
|
||||
Updated {moment.unix(props.package.ts).fromNow()}
|
||||
</small>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
const starsAndKindInfo = (
|
||||
<div className={`align-self-start d-flex align-items-center text-uppercase ms-auto ${styles.kind}`}>
|
||||
<StarBadge className="me-2" starsNumber={props.package.stars} />
|
||||
<RepositoryIconLabel kind={props.package.repository.kind} deprecated={props.package.deprecated} clickable />
|
||||
</div>
|
||||
);
|
||||
|
||||
const packageImage = (
|
||||
<div
|
||||
className={`d-flex align-items-center justify-content-center overflow-hidden rounded-circle p-1 p-md-2 border position-relative bg-white ${styles.imageWrapper} imageWrapper`}
|
||||
>
|
||||
<Image
|
||||
imageId={props.package.logoImageId}
|
||||
alt={`Logo ${props.package.displayName || props.package.name}`}
|
||||
className={styles.image}
|
||||
kind={props.package.repository.kind}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const diffInYears = calculateDiffInYears(props.package.ts);
|
||||
setIsVersionOlderThanOneYear(diffInYears > 1);
|
||||
}, [props.package]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="d-flex align-items-start justify-content-between mw-100">
|
||||
<div className={`d-flex align-items-stretch flex-grow-1 h-100 ${styles.truncateWrapper}`}>
|
||||
{packageImage}
|
||||
|
||||
<div
|
||||
className={`d-flex flex-column justify-content-between ms-3 my-1 my-md-0 flex-grow-1 ${styles.truncateWrapper} ${styles.titleWrapper}`}
|
||||
>
|
||||
<div className="text-truncate card-title mb-0">
|
||||
<div className="d-flex flex-row align-items-center justify-content-between">
|
||||
<div className={`text-truncate ${styles.title}`}>{props.package.displayName || props.package.name}</div>
|
||||
<div className="d-none d-xxl-flex d-xxxl-none flex-column ms-2">{starsAndKindInfo}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="d-block d-md-none">
|
||||
<div className={`card-subtitle align-items-baseline ${styles.subtitle}`}>
|
||||
<RepositoryInfo
|
||||
repository={props.package.repository}
|
||||
deprecated={props.package.deprecated}
|
||||
className="d-inline d-md-none text-truncate w-100"
|
||||
repoLabelClassName="d-none"
|
||||
withLabels={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={`d-none d-md-block card-subtitle align-items-baseline ${styles.subtitle}`}>
|
||||
<div className="d-flex flex-row align-items-baseline">
|
||||
{props.package.repository.organizationName && (
|
||||
<OrganizationInfo
|
||||
className={`me-0 d-flex flex-row align-items-baseline text-left w-auto ${styles.mx50} `}
|
||||
btnClassName="text-truncate mw-100"
|
||||
organizationName={props.package.repository.organizationName}
|
||||
organizationDisplayName={props.package.repository.organizationDisplayName}
|
||||
deprecated={props.package.deprecated}
|
||||
visibleLegend
|
||||
/>
|
||||
)}
|
||||
|
||||
{props.package.repository.userAlias && (
|
||||
<>
|
||||
<span className="text-muted text-uppercase me-1">User: </span>
|
||||
<span className="visually-hidden">{props.package.repository.userAlias}</span>
|
||||
|
||||
<button
|
||||
data-testid="userLink"
|
||||
className={`p-0 border-0 text-truncate text-dark mw-100 bg-transparent ${styles.link} ${styles.mx50}`}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
history.push({
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
pageNumber: 1,
|
||||
filters: {
|
||||
user: [props.package.repository.userAlias!],
|
||||
},
|
||||
deprecated: props.package.deprecated,
|
||||
}),
|
||||
});
|
||||
}}
|
||||
aria-label={`Filter by ${props.package.repository.userAlias}`}
|
||||
aria-hidden="true"
|
||||
tabIndex={-1}
|
||||
>
|
||||
<div className="text-truncate">{props.package.repository.userAlias}</div>
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className={styles.mx50}>
|
||||
<RepositoryInfo
|
||||
repository={props.package.repository}
|
||||
deprecated={props.package.deprecated}
|
||||
className={`d-flex flex-row align-items-baseline ms-3 ${styles.truncateWrapper}`}
|
||||
repoLabelClassName="d-none d-lg-inline"
|
||||
withLabels={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`d-none d-md-block card-subtitle text-truncate align-items-baseline position-relative ${styles.subtitle} ${styles.lastLine}`}
|
||||
>
|
||||
<div className="d-flex flex-row align-items-baseline text-truncate">
|
||||
<span className="text-muted text-uppercase me-1">
|
||||
{props.package.repository.kind === RepositoryKind.Container ? 'Tag' : 'Version'}:{' '}
|
||||
</span>
|
||||
{cutString(props.package.version || '-')}
|
||||
|
||||
{(() => {
|
||||
switch (props.package.repository.kind) {
|
||||
case RepositoryKind.Helm:
|
||||
case RepositoryKind.Container:
|
||||
return (
|
||||
<>
|
||||
{props.package.appVersion && (
|
||||
<>
|
||||
<span className="text-muted text-uppercase me-1 ms-3">App Version: </span>
|
||||
{cutString(props.package.appVersion)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})()}
|
||||
|
||||
{props.package.license && (
|
||||
<div className={`d-none d-lg-flex d-xxl-none d-xxxl-flex flex-row text-truncate ${styles.mx50}`}>
|
||||
<span className="text-muted text-uppercase me-1 ms-3">License:</span>
|
||||
<License
|
||||
license={props.package.license}
|
||||
className="text-truncate"
|
||||
linkClassName={`${styles.link} ${styles.subtitle} ${styles.licenseBtn} position-relative text-truncate mw-100`}
|
||||
visibleIcon={false}
|
||||
btnType
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`d-none d-${
|
||||
props.breakpointForInfoSection || 'md'
|
||||
}-flex d-xxl-none d-xxxl-flex flex-column align-items-end mb-auto ms-2`}
|
||||
>
|
||||
{starsAndKindInfo}
|
||||
<div className="mt-1">{pkgTS}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`mb-0 mb-md-1 mt-3 overflow-hidden ${styles.description} text-truncate`}>
|
||||
{props.package.description}
|
||||
</div>
|
||||
|
||||
<div className="d-none d-xxl-block d-xxxl-none text-end mt-2">{pkgTS}</div>
|
||||
|
||||
<div
|
||||
className={`d-flex d-${
|
||||
props.breakpointForInfoSection || 'md'
|
||||
}-none d-xxl-none flex-row flex-wrap justify-content-between align-items-center mt-auto pt-2 pt-${
|
||||
props.breakpointForInfoSection || 'md'
|
||||
}-0 mt-1 mt-${props.breakpointForInfoSection || 'md'}-0 mt-xxl-1 mt-xxxl-0`}
|
||||
>
|
||||
{pkgTS}
|
||||
<span>{starsAndKindInfo}</span>
|
||||
</div>
|
||||
|
||||
<div className={`d-flex flex-wrap justify-content-lg-end mt-0 mt-md-auto ${styles.labelsWrapper}`}>
|
||||
<OfficialBadge official={isPackageOfficial(props.package)} className="d-inline mt-3" type="package" />
|
||||
<ProductionBadge
|
||||
productionOrganizationsCount={props.package.productionOrganizationsCount}
|
||||
className="d-inline mt-3"
|
||||
/>
|
||||
<VerifiedPublisherBadge
|
||||
verifiedPublisher={props.package.repository.verifiedPublisher}
|
||||
className="d-inline mt-3"
|
||||
/>
|
||||
{props.package.deprecated && (
|
||||
<Label text="Deprecated" icon={<AiOutlineStop />} labelStyle="danger" className="d-inline mt-3" />
|
||||
)}
|
||||
{props.package.signed && (
|
||||
<SignedBadge
|
||||
signed={props.package.signed}
|
||||
signatures={props.package.signatures}
|
||||
repositoryKind={props.package.repository.kind}
|
||||
className="d-inline mt-3"
|
||||
/>
|
||||
)}
|
||||
{/* Do not display security rating badge when version is older than 1 year */}
|
||||
{!isVersionOlderThanOneYear && (
|
||||
<SecurityRating
|
||||
summary={props.package.securityReportSummary}
|
||||
className="d-inline mt-3"
|
||||
onlyBadge={false}
|
||||
withLink={buildPackageURL(props.package.normalizedName, props.package.repository, props.package.version!)}
|
||||
/>
|
||||
)}
|
||||
{(props.package.repository.scannerDisabled || props.package.allContainersImagesWhitelisted) && (
|
||||
<ScannerDisabledRepositoryBadge
|
||||
className="d-inline mt-3"
|
||||
scannerDisabled={props.package.repository.scannerDisabled || false}
|
||||
allContainersImagesWhitelisted={props.package.allContainersImagesWhitelisted || false}
|
||||
withTooltip
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default PackageInfo;
|
||||
|
|
@ -18,7 +18,7 @@ const RSSLinkTitle = (props: Props) => (
|
|||
|
||||
<small>
|
||||
<a
|
||||
className="badge rounded-pill bg-secondary rssBadge ms-3"
|
||||
className="badge bg-secondary rssBadge ms-3"
|
||||
rel="alternate noopener noreferrer"
|
||||
role="button"
|
||||
target="_blank"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
.btn {
|
||||
line-height: normal !important;
|
||||
}
|
||||
|
||||
.badge {
|
||||
font-size: 75%;
|
||||
text-transform: none;
|
||||
|
|
@ -14,3 +18,7 @@
|
|||
width: 12px;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.text {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ interface Props {
|
|||
kind: RepositoryKind;
|
||||
isPlural?: boolean;
|
||||
className?: string;
|
||||
btnClassName?: string;
|
||||
iconClassName?: string;
|
||||
noBackground?: boolean;
|
||||
clickable?: boolean;
|
||||
|
|
@ -27,8 +28,7 @@ const RepositoryIconLabel = (props: Props) => {
|
|||
<span
|
||||
className={classnames(
|
||||
{
|
||||
[`badge bg-light text-dark rounded-pill border ${styles.bg}`]:
|
||||
isUndefined(props.noBackground) || !props.noBackground,
|
||||
[`badge bg-light text-dark border ${styles.bg}`]: isUndefined(props.noBackground) || !props.noBackground,
|
||||
},
|
||||
styles.badge,
|
||||
props.className
|
||||
|
|
@ -38,7 +38,7 @@ const RepositoryIconLabel = (props: Props) => {
|
|||
<div className={`position-relative ${styles.icon} ${props.iconClassName}`} aria-hidden="true">
|
||||
{repo.icon}
|
||||
</div>
|
||||
<div className="ms-1">{props.isPlural ? repo.plural : repo.singular}</div>
|
||||
<div className={`ms-1 ${styles.text}`}>{props.isPlural ? repo.plural : repo.singular}</div>
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
|
|
@ -52,7 +52,7 @@ const RepositoryIconLabel = (props: Props) => {
|
|||
|
||||
<button
|
||||
data-testid="repoIconLabelLink"
|
||||
className="btn btn-link m-0 p-0"
|
||||
className={`btn btn-link m-0 p-0 border-0 ${styles.btn} ${props.btnClassName}`}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
history.push({
|
||||
|
|
|
|||
|
|
@ -2,10 +2,6 @@
|
|||
top: -1px;
|
||||
}
|
||||
|
||||
.moreMarginTop {
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
width: 350px;
|
||||
font-size: 0.85rem;
|
||||
|
|
@ -45,8 +41,12 @@
|
|||
border-bottom-color: var(--color-1-900) !important;
|
||||
}
|
||||
|
||||
.icon {
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.repoLabel {
|
||||
top: -1px;
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 575.98px) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import classnames from 'classnames';
|
||||
import isUndefined from 'lodash/isUndefined';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { MdInfoOutline } from 'react-icons/md';
|
||||
import { FiPackage } from 'react-icons/fi';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import useOutsideClick from '../../hooks/useOutsideClick';
|
||||
|
|
@ -10,7 +10,6 @@ import { prepareQueryString } from '../../utils/prepareQueryString';
|
|||
import AttachedIconToText from './AttachedIconToText';
|
||||
import ButtonCopyToClipboard from './ButtonCopyToClipboard';
|
||||
import RepositoryIcon from './RepositoryIcon';
|
||||
import RepositoryIconLabel from './RepositoryIconLabel';
|
||||
import styles from './RepositoryInfo.module.css';
|
||||
import VerifiedPublisherBadge from './VerifiedPublisherBadge';
|
||||
|
||||
|
|
@ -19,8 +18,6 @@ interface Props {
|
|||
deprecated?: boolean | null;
|
||||
className?: string;
|
||||
repoLabelClassName?: string;
|
||||
visibleInfoIcon?: boolean;
|
||||
visibleIcon?: boolean;
|
||||
withLabels: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -101,28 +98,19 @@ const RepositoryInfo = (props: Props) => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-row text-truncate">
|
||||
<div className="d-flex flex-row align-items-baseline me-1 text-muted text-uppercase">
|
||||
<small>Repo:</small>
|
||||
{props.visibleIcon && (
|
||||
<RepositoryIconLabel
|
||||
kind={props.repository.kind}
|
||||
deprecated={props.deprecated}
|
||||
className="ms-1"
|
||||
clickable
|
||||
/>
|
||||
)}
|
||||
<div className="d-flex flex-row align-items-baseline text-truncate">
|
||||
<div className="d-flex flex-row align-items-baseline me-1 text-dark text-uppercase">
|
||||
<div className={`position-relative ${styles.icon}`}>
|
||||
<FiPackage />
|
||||
</div>
|
||||
</div>
|
||||
<span className="visually-hidden">{props.repository.name}</span>
|
||||
|
||||
<button
|
||||
data-testid="repoLink"
|
||||
className={classnames(
|
||||
'd-flex flex-row p-0 border-0 text-dark text-truncate bg-transparent position-relative',
|
||||
styles.link,
|
||||
{
|
||||
[styles.moreMarginTop]: props.visibleIcon,
|
||||
}
|
||||
'd-flex flex-row p-0 border-0 text-muted text-truncate bg-transparent position-relative',
|
||||
styles.link
|
||||
)}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
|
|
@ -151,10 +139,6 @@ const RepositoryInfo = (props: Props) => {
|
|||
>
|
||||
<>
|
||||
<div className="text-truncate">{props.repository.displayName || props.repository.name}</div>
|
||||
|
||||
{props.repository.url && props.visibleInfoIcon && (
|
||||
<MdInfoOutline className={`d-none d-sm-inline-block ms-1 position-relative ${styles.infoIcon}`} />
|
||||
)}
|
||||
</>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
[data-theme='dark'] .sampleQuery {
|
||||
color: var(--font-color-light) !important;
|
||||
border-color: var(--border-solid) !important;
|
||||
background-color: #1a1d21 !important;
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ import { Fragment, memo } from 'react';
|
|||
import { Link } from 'react-router-dom';
|
||||
|
||||
import getSampleQueries from '../../utils/getSampleQueries';
|
||||
import styles from './SampleQueries.module.css';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
|
|
@ -28,7 +29,7 @@ const SampleQueries = (props: Props) => {
|
|||
{queries.map((query: SampleQuery, index: number) => (
|
||||
<Fragment key={`sampleQuery_${index}`}>
|
||||
<Link
|
||||
className={`badge rounded-pill border fw-normal mx-2 mt-3 ${props.className}`}
|
||||
className={`badge border fw-normal mx-2 mt-3 ${styles.sampleQuery} ${props.className}`}
|
||||
to={{
|
||||
pathname: '/packages/search',
|
||||
search: `?${query.querystring}`,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
.searchBar {
|
||||
height: 36px;
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 0 0 0.3rem var(--color-black-15);
|
||||
}
|
||||
|
||||
.big {
|
||||
height: 50px;
|
||||
border-radius: 25px;
|
||||
}
|
||||
|
||||
.iconWrapper {
|
||||
|
|
@ -47,14 +45,11 @@
|
|||
min-width: 50px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-color: var(--color-1-10) !important;
|
||||
|
||||
box-shadow: 0px 0px 3px 0px var(--color-1-20);
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: calc(100% - 7px);
|
||||
max-height: calc(100% - 7px);
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.activeDropdownItem {
|
||||
|
|
@ -95,7 +90,6 @@
|
|||
@media only screen and (max-width: 767.98px) {
|
||||
.searchBar {
|
||||
height: 30px;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.loading {
|
||||
|
|
@ -104,7 +98,6 @@
|
|||
|
||||
.big {
|
||||
height: 40px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.big + .loading {
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ const SearchBar = (props: Props) => {
|
|||
></button>
|
||||
|
||||
<div
|
||||
className={classnames('position-absolute text-dark', styles.tipIcon, {
|
||||
className={classnames('d-none d-sm-block position-absolute text-dark', styles.tipIcon, {
|
||||
[styles.bigTipIcon]: props.size === 'big',
|
||||
})}
|
||||
>
|
||||
|
|
@ -327,7 +327,7 @@ const SearchBar = (props: Props) => {
|
|||
id={`sl-opt${index}`}
|
||||
>
|
||||
<div
|
||||
className={`d-none d-md-flex align-items-center justify-content-center overflow-hidden rounded-circle p-1 border border-2 bg-white position-relative ${styles.imageWrapper} imageWrapper`}
|
||||
className={`d-none d-md-flex align-items-center justify-content-center overflow-hidden position-relative ${styles.imageWrapper}`}
|
||||
>
|
||||
<Image
|
||||
imageId={pkg.logoImageId}
|
||||
|
|
@ -339,7 +339,9 @@ const SearchBar = (props: Props) => {
|
|||
|
||||
<div className={`ms-0 ms-md-3 flex-grow-1 ${styles.truncateWrapper}`}>
|
||||
<div className="d-flex flex-row align-items-center">
|
||||
<div className={`text-truncate fw-bold ${styles.title}`}>{pkg.displayName || pkg.name}</div>
|
||||
<div className={`text-truncate fw-bold mt-1 ${styles.title}`}>
|
||||
{pkg.displayName || pkg.name}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`align-self-start d-flex align-items-center text-uppercase ms-auto ps-2 ${styles.midText}`}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.inputWrapper {
|
||||
height: 36px;
|
||||
border-radius: 18px;
|
||||
margin: 0 0.3rem;
|
||||
box-shadow: 0 0 0 0.3rem var(--color-black-15);
|
||||
}
|
||||
|
||||
|
|
@ -60,14 +60,11 @@
|
|||
min-width: 30px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-color: var(--color-1-10) !important;
|
||||
|
||||
box-shadow: 0px 0px 2px 0px var(--color-1-20);
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: calc(100% - 2px);
|
||||
max-height: calc(100% - 2px);
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.tableWrapper {
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ const SearchPackages = (props: Props) => {
|
|||
<td className="align-middle">
|
||||
<div className="d-flex flex-row align-items-center">
|
||||
<div
|
||||
className={`d-none d-sm-flex align-items-center justify-content-center overflow-hidden p-1 border border-2 bg-white rounded-circle ${styles.imageWrapper} imageWrapper`}
|
||||
className={`d-none d-sm-flex align-items-center justify-content-center overflow-hidden ${styles.imageWrapper}`}
|
||||
>
|
||||
<Image
|
||||
imageId={item.logoImageId}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
.inputWrapper {
|
||||
height: 36px;
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 0 0 0.3rem var(--color-black-15);
|
||||
margin: 0 0.3rem;
|
||||
}
|
||||
|
||||
.iconWrapper {
|
||||
|
|
@ -55,6 +55,7 @@
|
|||
|
||||
.icon {
|
||||
height: 17px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.tinyIcon {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
.badge {
|
||||
top: -2px;
|
||||
width: 22px;
|
||||
box-shadow: inset 0px 0px 2px 1px var(--color-black-25);
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ const SecurityRating = (props: Props) => {
|
|||
props.onlyBadge ? (
|
||||
<small>
|
||||
<div
|
||||
className={`badge rounded-pill text-light fw-bold ${styles.badge} ${className}`}
|
||||
className={`badge text-light fw-bold ${styles.badge} ${className}`}
|
||||
style={{
|
||||
backgroundColor: severity.color,
|
||||
}}
|
||||
|
|
@ -66,13 +66,13 @@ const SecurityRating = (props: Props) => {
|
|||
/>
|
||||
)
|
||||
}
|
||||
tooltipWidth={285}
|
||||
tooltipWidth={300}
|
||||
tooltipClassName={`${styles.tooltip} ${props.tooltipClassName} ${props.onlyBadge ? styles.onlyBadgeTooltip : ''}`}
|
||||
tooltipMessage={
|
||||
<div className="d-flex flex-column">
|
||||
<div className="d-flex flex-row align-items-center my-1">
|
||||
<span
|
||||
className={`badge rounded-pill text-light fw-bold me-2 ${styles.badge}`}
|
||||
className={`badge text-light fw-semibold me-2 ${styles.badge}`}
|
||||
style={{
|
||||
backgroundColor: SEVERITY_RATING.default!.color,
|
||||
}}
|
||||
|
|
@ -83,7 +83,7 @@ const SecurityRating = (props: Props) => {
|
|||
</div>
|
||||
<div className="d-flex flex-row align-items-center my-1">
|
||||
<span
|
||||
className={`badge rounded-pill text-light fw-bold me-2 ${styles.badge}`}
|
||||
className={`badge text-light fw-semibold me-2 ${styles.badge}`}
|
||||
style={{
|
||||
backgroundColor: SEVERITY_RATING[VulnerabilitySeverity.Low]!.color,
|
||||
}}
|
||||
|
|
@ -96,7 +96,7 @@ const SecurityRating = (props: Props) => {
|
|||
</div>
|
||||
<div className="d-flex flex-row align-items-center my-1">
|
||||
<span
|
||||
className={`badge rounded-pill text-light fw-bold me-2 ${styles.badge}`}
|
||||
className={`badge text-light fw-semibold me-2 ${styles.badge}`}
|
||||
style={{
|
||||
backgroundColor: SEVERITY_RATING[VulnerabilitySeverity.Medium]!.color,
|
||||
}}
|
||||
|
|
@ -109,7 +109,7 @@ const SecurityRating = (props: Props) => {
|
|||
</div>
|
||||
<div className="d-flex flex-row align-items-center my-1">
|
||||
<span
|
||||
className={`badge rounded-pill text-light fw-bold me-2 ${styles.badge}`}
|
||||
className={`badge text-light fw-semibold me-2 ${styles.badge}`}
|
||||
style={{
|
||||
backgroundColor: SEVERITY_RATING[VulnerabilitySeverity.High]!.color,
|
||||
}}
|
||||
|
|
@ -122,7 +122,7 @@ const SecurityRating = (props: Props) => {
|
|||
</div>
|
||||
<div className="d-flex flex-row align-items-center my-1">
|
||||
<span
|
||||
className={`badge rounded-pill text-light fw-bold me-2 ${styles.badge}`}
|
||||
className={`badge text-light fw-semibold me-2 ${styles.badge}`}
|
||||
style={{
|
||||
backgroundColor: SEVERITY_RATING[VulnerabilitySeverity.Critical]!.color,
|
||||
}}
|
||||
|
|
@ -135,7 +135,7 @@ const SecurityRating = (props: Props) => {
|
|||
</div>
|
||||
<div className="d-flex flex-row align-items-center my-1">
|
||||
<span
|
||||
className={`badge rounded-pill text-light fw-bold me-2 ${styles.badge}`}
|
||||
className={`badge text-light fw-semibold me-2 ${styles.badge}`}
|
||||
style={{
|
||||
backgroundColor: SEVERITY_RATING[VulnerabilitySeverity.UnKnown]!.color,
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
background-color: var(--badge-bg);
|
||||
border-color: var(--gray) !important;
|
||||
height: 19px;
|
||||
line-height: 0.8rem;
|
||||
}
|
||||
|
||||
.size-xs {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ const StarBadge = (props: Props) => {
|
|||
return (
|
||||
<div
|
||||
data-testid="starBadge"
|
||||
className={classnames('badge rounded-pill bg-light text-dark border', styles.badge, props.className, {
|
||||
className={classnames('badge bg-light text-dark border', styles.badge, props.className, {
|
||||
[styles[`size-${props.size}`]]: !isUndefined(props.size),
|
||||
})}
|
||||
aria-label={`${props.starsNumber} stars`}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
.list {
|
||||
border-color: var(--color-black-15) !important;
|
||||
border-radius: 3px;
|
||||
z-index: 100;
|
||||
top: 31px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@
|
|||
"description": "desc",
|
||||
"logoImageId": "imageId",
|
||||
"appVersion": "1.0.0",
|
||||
"securityReportSummary": {
|
||||
"low": 0,
|
||||
"high": 7,
|
||||
"medium": 1,
|
||||
"unknown": 0,
|
||||
"critical": 1
|
||||
},
|
||||
"repository": {
|
||||
"repositoryId": "0acb228c-17ab-4e50-85e9-ffc7102ea423",
|
||||
"kind": 0,
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ exports[`OrganizationInfo creates snapshot 1`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-row align-items-start text-truncate"
|
||||
class="d-flex flex-row align-items-baseline text-truncate"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-hidden="true"
|
||||
aria-label="Organization info"
|
||||
class="p-0 border-0 text-dark text-truncate flex-grow-1 bg-transparent position-relative link undefined"
|
||||
class="p-0 border-0 text-muted text-truncate flex-grow-1 bg-transparent position-relative link undefined"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
exports[`PackageCard creates snapshot 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="col-12 col-xxl-6 py-sm-3 py-2 cardWrapper"
|
||||
class="py-sm-3 py-2 cardWrapper undefined"
|
||||
role="listitem"
|
||||
>
|
||||
<div
|
||||
|
|
@ -23,7 +23,7 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
class="d-flex align-items-stretch flex-grow-1 h-100 truncateWrapper"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden rounded-circle p-1 p-md-2 border position-relative bg-white imageWrapper imageWrapper"
|
||||
class="my-2 my-md-0 d-flex align-items-center justify-content-center overflow-hidden position-relative imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="Logo Pretty name"
|
||||
|
|
@ -34,7 +34,7 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-column justify-content-between ms-3 my-1 my-md-0 flex-grow-1 truncateWrapper titleWrapper"
|
||||
class="d-flex flex-column flex-grow-1 flex-sm-grow-0 justify-content-between truncateWrapper titleWrapper"
|
||||
>
|
||||
<div
|
||||
class="text-truncate card-title mb-0"
|
||||
|
|
@ -47,91 +47,6 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
>
|
||||
Pretty name
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-xxl-flex d-xxxl-none flex-column ms-2"
|
||||
>
|
||||
<div
|
||||
class="align-self-start d-flex align-items-center text-uppercase ms-auto kind"
|
||||
>
|
||||
<div
|
||||
class="d-none d-md-inline-block"
|
||||
>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
Helm chart
|
||||
</span>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by Helm chart repository kind"
|
||||
class="btn btn-link m-0 p-0"
|
||||
data-testid="repoIconLabelLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex d-md-none fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
|
@ -282,14 +197,45 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-row text-truncate"
|
||||
class="d-flex flex-row align-items-baseline text-truncate"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline me-1 text-muted text-uppercase"
|
||||
class="d-flex flex-row align-items-baseline me-1 text-dark text-uppercase"
|
||||
>
|
||||
<small>
|
||||
Repo:
|
||||
</small>
|
||||
<div
|
||||
class="position-relative icon"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<line
|
||||
x1="16.5"
|
||||
x2="7.5"
|
||||
y1="9.4"
|
||||
y2="4.21"
|
||||
/>
|
||||
<path
|
||||
d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"
|
||||
/>
|
||||
<polyline
|
||||
points="3.27 6.96 12 12.01 20.73 6.96"
|
||||
/>
|
||||
<line
|
||||
x1="12"
|
||||
x2="12"
|
||||
y1="22.08"
|
||||
y2="12"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
|
|
@ -300,7 +246,7 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
aria-expanded="false"
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by repo stable"
|
||||
class="d-flex flex-row p-0 border-0 text-dark text-truncate bg-transparent position-relative link"
|
||||
class="d-flex flex-row p-0 border-0 text-muted text-truncate bg-transparent position-relative link"
|
||||
data-testid="repoLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
|
|
@ -315,34 +261,50 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-md-block card-subtitle align-items-baseline subtitle"
|
||||
class="d-none d-md-block card-subtitle align-items-center subtitle"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline"
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<span
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
User:
|
||||
</span>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
user
|
||||
</span>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by user"
|
||||
class="p-0 border-0 text-truncate text-dark mw-100 bg-transparent link mx50"
|
||||
data-testid="userLink"
|
||||
tabindex="-1"
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline userInfo"
|
||||
>
|
||||
<div
|
||||
class="text-truncate"
|
||||
class="text-dark me-1 position-relative userIcon"
|
||||
>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
stroke="currentColor"
|
||||
stroke-width="0"
|
||||
viewBox="0 0 448 512"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
user
|
||||
</div>
|
||||
</button>
|
||||
</span>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by user"
|
||||
class="p-0 border-0 text-truncate text-muted mw-100 bg-transparent link mx50"
|
||||
data-testid="userLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="text-truncate"
|
||||
>
|
||||
user
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="mx50"
|
||||
>
|
||||
|
|
@ -488,14 +450,45 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-row text-truncate"
|
||||
class="d-flex flex-row align-items-baseline text-truncate"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline me-1 text-muted text-uppercase"
|
||||
class="d-flex flex-row align-items-baseline me-1 text-dark text-uppercase"
|
||||
>
|
||||
<small>
|
||||
Repo:
|
||||
</small>
|
||||
<div
|
||||
class="position-relative icon"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<line
|
||||
x1="16.5"
|
||||
x2="7.5"
|
||||
y1="9.4"
|
||||
y2="4.21"
|
||||
/>
|
||||
<path
|
||||
d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"
|
||||
/>
|
||||
<polyline
|
||||
points="3.27 6.96 12 12.01 20.73 6.96"
|
||||
/>
|
||||
<line
|
||||
x1="12"
|
||||
x2="12"
|
||||
y1="22.08"
|
||||
y2="12"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
|
|
@ -506,7 +499,7 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
aria-expanded="false"
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by repo stable"
|
||||
class="d-flex flex-row p-0 border-0 text-dark text-truncate bg-transparent position-relative link"
|
||||
class="d-flex flex-row p-0 border-0 text-muted text-truncate bg-transparent position-relative link"
|
||||
data-testid="repoLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
|
|
@ -521,29 +514,9 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-md-block card-subtitle text-truncate align-items-baseline position-relative subtitle lastLine"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline text-truncate"
|
||||
>
|
||||
<span
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
Version:
|
||||
</span>
|
||||
-
|
||||
<span
|
||||
class="text-muted text-uppercase me-1 ms-3"
|
||||
>
|
||||
App Version:
|
||||
</span>
|
||||
1.0.0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-lg-flex d-xxl-none d-xxxl-flex flex-column align-items-end mb-auto ms-2"
|
||||
class="d-none d-lg-flex flex-column align-items-end mb-auto ms-auto rightInfo"
|
||||
>
|
||||
<div
|
||||
class="align-self-start d-flex align-items-center text-uppercase ms-auto kind"
|
||||
|
|
@ -559,12 +532,12 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by Helm chart repository kind"
|
||||
class="btn btn-link m-0 p-0"
|
||||
class="btn btn-link m-0 p-0 border-0 btn position-relative repoLabel"
|
||||
data-testid="repoIconLabelLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
class="badge bg-light text-dark border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
|
|
@ -585,7 +558,7 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
class="ms-1 text"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
|
|
@ -597,7 +570,7 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
class="d-flex d-md-none fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
class="badge bg-light text-dark border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
|
|
@ -618,7 +591,7 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
class="ms-1 text"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
|
|
@ -635,25 +608,30 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
Updated Invalid date
|
||||
</small>
|
||||
</div>
|
||||
<div
|
||||
class="mt-1 text-truncate align-items-baseline position-relative version"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline text-truncate"
|
||||
>
|
||||
<span
|
||||
class="text-muted me-1"
|
||||
>
|
||||
Version
|
||||
</span>
|
||||
-
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mb-0 mb-md-1 mt-3 overflow-hidden description text-truncate"
|
||||
class="mb-0 mb-md-1 mt-3 text-muted text-truncate description lineClamp "
|
||||
>
|
||||
desc
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-xxl-block d-xxxl-none text-end mt-2"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-nowrap date"
|
||||
>
|
||||
Updated Invalid date
|
||||
</small>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex d-lg-none d-xxl-none flex-row flex-wrap justify-content-between align-items-center mt-auto pt-2 pt-lg-0 mt-1 mt-lg-0 mt-xxl-1 mt-xxxl-0"
|
||||
class="d-flex d-lg-none flex-row flex-wrap justify-content-between align-items-center mt-auto pt-3 pt-lg-0 mt-1 mt-lg-0 mt-xxl-1 mt-xxxl-0"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-nowrap date"
|
||||
|
|
@ -675,12 +653,12 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by Helm chart repository kind"
|
||||
class="btn btn-link m-0 p-0"
|
||||
class="btn btn-link m-0 p-0 border-0 btn position-relative repoLabel"
|
||||
data-testid="repoIconLabelLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
class="badge bg-light text-dark border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
|
|
@ -701,7 +679,7 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
class="ms-1 text"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
|
|
@ -713,7 +691,7 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
class="d-flex d-md-none fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
class="badge bg-light text-dark border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
|
|
@ -734,7 +712,7 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
class="ms-1 text"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
|
|
@ -745,8 +723,65 @@ exports[`PackageCard creates snapshot 1`] = `
|
|||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-wrap justify-content-lg-end mt-0 mt-md-auto labelsWrapper"
|
||||
/>
|
||||
class="d-none d-sm-flex flex-wrap justify-content-lg-end mt-0 mt-md-auto labelsWrapper"
|
||||
>
|
||||
<div
|
||||
class="d-inline mt-3"
|
||||
>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Open security report"
|
||||
class="btn btn-link text-reset p-0 position-relative link"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="position-relative undefined"
|
||||
>
|
||||
<div
|
||||
data-testid="elementWithTooltip"
|
||||
>
|
||||
<div
|
||||
class="fw-bold undefined"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center overflow-hidden labelWrapper custom"
|
||||
>
|
||||
<div
|
||||
class="text-center border border-end-0 position-relative labelIconWrapper iconWrapper"
|
||||
data-testid="label-wrapper"
|
||||
style="background-color: rgb(150, 0, 3);"
|
||||
>
|
||||
<span
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="position-relative ratingLetter"
|
||||
>
|
||||
F
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="text-nowrap border fw-bold labelText"
|
||||
>
|
||||
<span
|
||||
class="d-none d-sm-inline"
|
||||
>
|
||||
Images Security Rating
|
||||
</span>
|
||||
<span
|
||||
class="d-inline d-sm-none"
|
||||
>
|
||||
Security Rating
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,794 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PackageInfo creates snapshot 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="d-flex align-items-start justify-content-between mw-100"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-stretch flex-grow-1 h-100 truncateWrapper"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden rounded-circle p-1 p-md-2 border position-relative bg-white imageWrapper imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="Logo Pretty name"
|
||||
aria-hidden="true"
|
||||
class="image"
|
||||
src="/image/imageId"
|
||||
srcset="/image/imageId@1x 1x, /image/imageId@2x 2x, /image/imageId@3x 3x, /image/imageId@4x 4x"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-column justify-content-between ms-3 my-1 my-md-0 flex-grow-1 truncateWrapper titleWrapper"
|
||||
>
|
||||
<div
|
||||
class="text-truncate card-title mb-0"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center justify-content-between"
|
||||
>
|
||||
<div
|
||||
class="text-truncate title"
|
||||
>
|
||||
Pretty name
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-xxl-flex d-xxxl-none flex-column ms-2"
|
||||
>
|
||||
<div
|
||||
class="align-self-start d-flex align-items-center text-uppercase ms-auto kind"
|
||||
>
|
||||
<div
|
||||
class="d-none d-md-inline-block"
|
||||
>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
Helm chart
|
||||
</span>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by Helm chart repository kind"
|
||||
class="btn btn-link m-0 p-0"
|
||||
data-testid="repoIconLabelLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex d-md-none fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-block d-md-none"
|
||||
>
|
||||
<div
|
||||
class="card-subtitle align-items-baseline subtitle"
|
||||
>
|
||||
<div
|
||||
class="d-inline d-md-none text-truncate w-100"
|
||||
>
|
||||
<div
|
||||
class="position-absolute"
|
||||
>
|
||||
<div
|
||||
class="dropdown-menu dropdown-menu-left text-wrap dropdown"
|
||||
role="complementary"
|
||||
>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-column"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
Repo:
|
||||
</small>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="me-1 w-auto repoIconMini iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="me-1 w-auto repoIconMini iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
<div
|
||||
class="text-reset text-truncate labelContent"
|
||||
>
|
||||
stable
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-2 d-flex flex-row align-items-baseline"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
Url:
|
||||
</small>
|
||||
<div
|
||||
class="text-reset text-break labelContent"
|
||||
data-testid="repoUrl"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row flex-wrap undefined"
|
||||
data-testid="attachedIconToTextWrapper"
|
||||
style="line-height: 21px;"
|
||||
>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
r
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
e
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
p
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
o
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
U
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
r
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
l
|
||||
</div>
|
||||
<div
|
||||
class="d-inline-block"
|
||||
>
|
||||
<div
|
||||
class="position-relative d-inline"
|
||||
>
|
||||
<button
|
||||
aria-label="Copy repository url to clipboard"
|
||||
class="btn btn-sm bg-transparent"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect
|
||||
height="13"
|
||||
rx="2"
|
||||
ry="2"
|
||||
width="13"
|
||||
x="9"
|
||||
y="9"
|
||||
/>
|
||||
<path
|
||||
d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-row text-truncate"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline me-1 text-muted text-uppercase"
|
||||
>
|
||||
<small>
|
||||
Repo:
|
||||
</small>
|
||||
</div>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
stable
|
||||
</span>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by repo stable"
|
||||
class="d-flex flex-row p-0 border-0 text-dark text-truncate bg-transparent position-relative link"
|
||||
data-testid="repoLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="text-truncate"
|
||||
>
|
||||
stable
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-md-block card-subtitle align-items-baseline subtitle"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline"
|
||||
>
|
||||
<span
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
User:
|
||||
</span>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
user
|
||||
</span>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by user"
|
||||
class="p-0 border-0 text-truncate text-dark mw-100 bg-transparent link mx50"
|
||||
data-testid="userLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="text-truncate"
|
||||
>
|
||||
user
|
||||
</div>
|
||||
</button>
|
||||
<div
|
||||
class="mx50"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline ms-3 truncateWrapper"
|
||||
>
|
||||
<div
|
||||
class="position-absolute"
|
||||
>
|
||||
<div
|
||||
class="dropdown-menu dropdown-menu-left text-wrap dropdown"
|
||||
role="complementary"
|
||||
>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-column"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
Repo:
|
||||
</small>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="me-1 w-auto repoIconMini iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="me-1 w-auto repoIconMini iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
<div
|
||||
class="text-reset text-truncate labelContent"
|
||||
>
|
||||
stable
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-2 d-flex flex-row align-items-baseline"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
Url:
|
||||
</small>
|
||||
<div
|
||||
class="text-reset text-break labelContent"
|
||||
data-testid="repoUrl"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row flex-wrap undefined"
|
||||
data-testid="attachedIconToTextWrapper"
|
||||
style="line-height: 21px;"
|
||||
>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
r
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
e
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
p
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
o
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
U
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
r
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
l
|
||||
</div>
|
||||
<div
|
||||
class="d-inline-block"
|
||||
>
|
||||
<div
|
||||
class="position-relative d-inline"
|
||||
>
|
||||
<button
|
||||
aria-label="Copy repository url to clipboard"
|
||||
class="btn btn-sm bg-transparent"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect
|
||||
height="13"
|
||||
rx="2"
|
||||
ry="2"
|
||||
width="13"
|
||||
x="9"
|
||||
y="9"
|
||||
/>
|
||||
<path
|
||||
d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-row text-truncate"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline me-1 text-muted text-uppercase"
|
||||
>
|
||||
<small>
|
||||
Repo:
|
||||
</small>
|
||||
</div>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
stable
|
||||
</span>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by repo stable"
|
||||
class="d-flex flex-row p-0 border-0 text-dark text-truncate bg-transparent position-relative link"
|
||||
data-testid="repoLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="text-truncate"
|
||||
>
|
||||
stable
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-md-block card-subtitle text-truncate align-items-baseline position-relative subtitle lastLine"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline text-truncate"
|
||||
>
|
||||
<span
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
Version:
|
||||
</span>
|
||||
-
|
||||
<span
|
||||
class="text-muted text-uppercase me-1 ms-3"
|
||||
>
|
||||
App Version:
|
||||
</span>
|
||||
1.0.0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-md-flex d-xxl-none d-xxxl-flex flex-column align-items-end mb-auto ms-2"
|
||||
>
|
||||
<div
|
||||
class="align-self-start d-flex align-items-center text-uppercase ms-auto kind"
|
||||
>
|
||||
<div
|
||||
class="d-none d-md-inline-block"
|
||||
>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
Helm chart
|
||||
</span>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by Helm chart repository kind"
|
||||
class="btn btn-link m-0 p-0"
|
||||
data-testid="repoIconLabelLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex d-md-none fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-1"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-nowrap date"
|
||||
>
|
||||
Updated Invalid date
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mb-0 mb-md-1 mt-3 overflow-hidden description text-truncate"
|
||||
>
|
||||
desc
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-xxl-block d-xxxl-none text-end mt-2"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-nowrap date"
|
||||
>
|
||||
Updated Invalid date
|
||||
</small>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex d-md-none d-xxl-none flex-row flex-wrap justify-content-between align-items-center mt-auto pt-2 pt-md-0 mt-1 mt-md-0 mt-xxl-1 mt-xxxl-0"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-nowrap date"
|
||||
>
|
||||
Updated Invalid date
|
||||
</small>
|
||||
<span>
|
||||
<div
|
||||
class="align-self-start d-flex align-items-center text-uppercase ms-auto kind"
|
||||
>
|
||||
<div
|
||||
class="d-none d-md-inline-block"
|
||||
>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
Helm chart
|
||||
</span>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by Helm chart repository kind"
|
||||
class="btn btn-link m-0 p-0"
|
||||
data-testid="repoIconLabelLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex d-md-none fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-wrap justify-content-lg-end mt-0 mt-md-auto labelsWrapper"
|
||||
>
|
||||
<div
|
||||
class="d-inline mt-3"
|
||||
>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Open security report"
|
||||
class="btn btn-link text-reset p-0 position-relative link"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="position-relative undefined"
|
||||
>
|
||||
<div
|
||||
data-testid="elementWithTooltip"
|
||||
>
|
||||
<div
|
||||
class="fw-bold undefined"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center overflow-hidden labelWrapper custom"
|
||||
>
|
||||
<div
|
||||
class="text-center border border-end-0 position-relative labelIconWrapper iconWrapper"
|
||||
data-testid="label-wrapper"
|
||||
style="background-color: rgb(150, 0, 3);"
|
||||
>
|
||||
<span
|
||||
class=""
|
||||
>
|
||||
<span
|
||||
class="position-relative ratingLetter"
|
||||
>
|
||||
F
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="text-nowrap border fw-bold labelText"
|
||||
>
|
||||
<span
|
||||
class="d-none d-sm-inline"
|
||||
>
|
||||
Images Security Rating
|
||||
</span>
|
||||
<span
|
||||
class="d-inline d-sm-none"
|
||||
>
|
||||
Security Rating
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
|
|
@ -16,7 +16,7 @@ exports[`RSSLinkTitle creates snapshot 1`] = `
|
|||
</div>
|
||||
<small>
|
||||
<a
|
||||
class="badge rounded-pill bg-secondary rssBadge ms-3"
|
||||
class="badge bg-secondary rssBadge ms-3"
|
||||
href="/api/v1/packages/helm/stable/test/feed/rss"
|
||||
rel="alternate noopener noreferrer"
|
||||
role="button"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ exports[`RepositoryIconLabel creates snapshot 1`] = `
|
|||
class="d-flex fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
class="badge bg-light text-dark border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
|
|
@ -30,7 +30,7 @@ exports[`RepositoryIconLabel creates snapshot 1`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
class="ms-1 text"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
|
|
@ -42,7 +42,7 @@ exports[`RepositoryIconLabel creates snapshot 1`] = `
|
|||
class="d-flex d-md-none fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
class="badge bg-light text-dark border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
|
|
@ -63,7 +63,7 @@ exports[`RepositoryIconLabel creates snapshot 1`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
class="ms-1 text"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -197,14 +197,45 @@ exports[`RepositoryInfo creates snapshot 1`] = `
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-row text-truncate"
|
||||
class="d-flex flex-row align-items-baseline text-truncate"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline me-1 text-muted text-uppercase"
|
||||
class="d-flex flex-row align-items-baseline me-1 text-dark text-uppercase"
|
||||
>
|
||||
<small>
|
||||
Repo:
|
||||
</small>
|
||||
<div
|
||||
class="position-relative icon"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<line
|
||||
x1="16.5"
|
||||
x2="7.5"
|
||||
y1="9.4"
|
||||
y2="4.21"
|
||||
/>
|
||||
<path
|
||||
d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"
|
||||
/>
|
||||
<polyline
|
||||
points="3.27 6.96 12 12.01 20.73 6.96"
|
||||
/>
|
||||
<line
|
||||
x1="12"
|
||||
x2="12"
|
||||
y1="22.08"
|
||||
y2="12"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
|
|
@ -215,7 +246,7 @@ exports[`RepositoryInfo creates snapshot 1`] = `
|
|||
aria-expanded="false"
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by repo Stable"
|
||||
class="d-flex flex-row p-0 border-0 text-dark text-truncate bg-transparent position-relative link"
|
||||
class="d-flex flex-row p-0 border-0 text-muted text-truncate bg-transparent position-relative link"
|
||||
data-testid="repoLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -4,35 +4,35 @@ exports[`SampleQueries creates snapshot 1`] = `
|
|||
<DocumentFragment>
|
||||
<a
|
||||
aria-label="Filter by OLM operators for databases"
|
||||
class="badge rounded-pill border fw-normal mx-2 mt-3 undefined"
|
||||
class="badge border fw-normal mx-2 mt-3 sampleQuery undefined"
|
||||
href="/packages/search?kind=3&ts_query_web=database"
|
||||
>
|
||||
OLM operators for databases
|
||||
</a>
|
||||
<a
|
||||
aria-label="Filter by Helm Charts provided by Bitnami"
|
||||
class="badge rounded-pill border fw-normal mx-2 mt-3 undefined"
|
||||
class="badge border fw-normal mx-2 mt-3 sampleQuery undefined"
|
||||
href="/packages/search?kind=0&org=bitnami"
|
||||
>
|
||||
Helm Charts provided by Bitnami
|
||||
</a>
|
||||
<a
|
||||
aria-label="Filter by Packages of any kind related to etcd"
|
||||
class="badge rounded-pill border fw-normal mx-2 mt-3 undefined"
|
||||
class="badge border fw-normal mx-2 mt-3 sampleQuery undefined"
|
||||
href="/packages/search?ts_query_web=etcd"
|
||||
>
|
||||
Packages of any kind related to etcd
|
||||
</a>
|
||||
<a
|
||||
aria-label="Filter by Falco rules for CVE"
|
||||
class="badge rounded-pill border fw-normal mx-2 mt-3 undefined"
|
||||
class="badge border fw-normal mx-2 mt-3 sampleQuery undefined"
|
||||
href="/packages/search?kind=1&ts_query_web=cve"
|
||||
>
|
||||
Falco rules for CVE
|
||||
</a>
|
||||
<a
|
||||
aria-label="Filter by OLM operators in the monitoring category"
|
||||
class="badge rounded-pill border fw-normal mx-2 mt-3 undefined"
|
||||
class="badge border fw-normal mx-2 mt-3 sampleQuery undefined"
|
||||
href="/packages/search?kind=3&ts_query=monitoring"
|
||||
>
|
||||
OLM operators in the monitoring category
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ exports[`SearchBar creates snapshot 1`] = `
|
|||
type="button"
|
||||
/>
|
||||
<div
|
||||
class="position-absolute text-dark tipIcon bigTipIcon"
|
||||
class="d-none d-sm-block position-absolute text-dark tipIcon bigTipIcon"
|
||||
>
|
||||
<button
|
||||
aria-label="Open search tips modal"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ exports[`StarBadge creates snapshot 1`] = `
|
|||
<DocumentFragment>
|
||||
<div
|
||||
aria-label="1 stars"
|
||||
class="badge rounded-pill bg-light text-dark border badge"
|
||||
class="badge bg-light text-dark border badge"
|
||||
data-testid="starBadge"
|
||||
>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
width: 700px;
|
||||
max-width: 80%;
|
||||
border-color: var(--color-1-500) !important;
|
||||
border-radius: 15px;
|
||||
z-index: 1100;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
.section {
|
||||
border-color: transparent !important;
|
||||
border-top-left-radius: 0.25rem !important;
|
||||
border-top-right-radius: 0.25rem !important;
|
||||
}
|
||||
|
||||
.section:hover {
|
||||
|
|
@ -25,7 +23,11 @@
|
|||
.activeSection {
|
||||
border-color: var(--color-1-20) !important;
|
||||
border-bottom-color: transparent !important;
|
||||
background-color: var(--body-bg) !important;
|
||||
background-color: #2c2e31 !important;
|
||||
}
|
||||
|
||||
[data-theme='light'] .activeSection {
|
||||
background-color: var(--extra-light-gray) !important;
|
||||
}
|
||||
|
||||
.activeSection::before {
|
||||
|
|
@ -33,11 +35,9 @@
|
|||
position: absolute;
|
||||
top: -1px;
|
||||
height: 4px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
background-color: var(--color-1-700);
|
||||
border-top-left-radius: 0.25rem;
|
||||
border-top-right-radius: 0.25rem;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767.98px) {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ const UserContext = () => {
|
|||
<small className={`text-uppercase text-muted ${styles.legendCtx}`}>Control panel context</small>
|
||||
<div className="d-flex flex-row align-items-center">
|
||||
<button
|
||||
className={`btn btn-primary rounded-pill btn-sm pe-3 position-relative lh-1 ${styles.ctxBtn}`}
|
||||
className={`btn btn-primary btn-sm pe-3 position-relative lh-1 ${styles.ctxBtn}`}
|
||||
type="button"
|
||||
onClick={() => {
|
||||
fetchOrganizations();
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ exports[`UserContext creates snapshot 1`] = `
|
|||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Open context"
|
||||
class="btn btn-primary rounded-pill btn-sm pe-3 position-relative lh-1 ctxBtn"
|
||||
class="btn btn-primary btn-sm pe-3 position-relative lh-1 ctxBtn"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -37,17 +37,33 @@ exports[`ControlPanelView renders correctly 1`] = `
|
|||
class="icon"
|
||||
>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
fill="none"
|
||||
height="1em"
|
||||
stroke="currentColor"
|
||||
stroke-width="0"
|
||||
viewBox="0 0 16 16"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<line
|
||||
x1="16.5"
|
||||
x2="7.5"
|
||||
y1="9.4"
|
||||
y2="4.21"
|
||||
/>
|
||||
<path
|
||||
d="M1 4.27v7.47c0 .45.3.84.75.97l6.5 1.73c.16.05.34.05.5 0l6.5-1.73c.45-.13.75-.52.75-.97V4.27c0-.45-.3-.84-.75-.97l-6.5-1.74a1.4 1.4 0 0 0-.5 0L1.75 3.3c-.45.13-.75.52-.75.97zm7 9.09l-6-1.59V5l6 1.61v6.75zM2 4l2.5-.67L11 5.06l-2.5.67L2 4zm13 7.77l-6 1.59V6.61l2-.55V8.5l2-.53V5.53L15 5v6.77zm-2-7.24L6.5 2.8l2-.53L15 4l-2 .53z"
|
||||
fill-rule="evenodd"
|
||||
d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"
|
||||
/>
|
||||
<polyline
|
||||
points="3.27 6.96 12 12.01 20.73 6.96"
|
||||
/>
|
||||
<line
|
||||
x1="12"
|
||||
x2="12"
|
||||
y1="22.08"
|
||||
y2="12"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
|
|
@ -159,7 +175,7 @@ exports[`ControlPanelView renders correctly 1`] = `
|
|||
<button
|
||||
aria-expanded="false"
|
||||
aria-label="Open context"
|
||||
class="btn btn-primary rounded-pill btn-sm pe-3 position-relative lh-1 ctxBtn"
|
||||
class="btn btn-primary btn-sm pe-3 position-relative lh-1 ctxBtn"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -17,14 +17,11 @@
|
|||
min-width: 40px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-color: var(--color-1-10) !important;
|
||||
|
||||
box-shadow: 0px 0px 5px 0px var(--color-1-20);
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: calc(100% - 2px);
|
||||
max-height: calc(100% - 2px);
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767.98px) {
|
||||
|
|
|
|||
|
|
@ -13,17 +13,10 @@
|
|||
right: 4px;
|
||||
}
|
||||
|
||||
.imageWrapper {
|
||||
.image {
|
||||
min-width: 40px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-color: var(--color-1-10) !important;
|
||||
box-shadow: 0px 0px 5px 0px var(--color-1-20);
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: calc(100% - 2px);
|
||||
max-height: calc(100% - 2px);
|
||||
}
|
||||
|
||||
.link {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
.code {
|
||||
background-color: var(--code-bg-md);
|
||||
border: 1px solid var(--color-1-20);
|
||||
border-radius: 3px;
|
||||
padding: 0 0.15rem;
|
||||
color: var(--color-font);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ exports[`Repository Card - packages section creates snapshot 1`] = `
|
|||
class="d-flex fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
class="badge bg-light text-dark border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
|
|
@ -51,7 +51,7 @@ exports[`Repository Card - packages section creates snapshot 1`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
class="ms-1 text"
|
||||
>
|
||||
Helm charts
|
||||
</div>
|
||||
|
|
@ -63,7 +63,7 @@ exports[`Repository Card - packages section creates snapshot 1`] = `
|
|||
class="d-flex d-md-none fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
class="badge bg-light text-dark border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
|
|
@ -84,7 +84,7 @@ exports[`Repository Card - packages section creates snapshot 1`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
class="ms-1 text"
|
||||
>
|
||||
Helm charts
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ const EnableTwoFactorAuthenticationModal = (props: Props) => {
|
|||
be used once.{' '}
|
||||
<span className="fw-bold">Please treat them as passwords and store them safely</span>.
|
||||
</div>
|
||||
<div className={`border rounded position-relative p-2 p-sm-4 ${styles.codesWrapper}`}>
|
||||
<div className={`border position-relative p-2 p-sm-4 ${styles.codesWrapper}`}>
|
||||
<BlockCodeButtons
|
||||
filename="artifacthub-recovery-codes.txt"
|
||||
content={setUp.recoveryCodes.join('\n')}
|
||||
|
|
@ -229,7 +229,7 @@ const EnableTwoFactorAuthenticationModal = (props: Props) => {
|
|||
</div>
|
||||
|
||||
<div className="text-center mb-4">
|
||||
<div className="border rounded d-inline-block p-1 my-1">
|
||||
<div className="border d-inline-block p-1 my-1">
|
||||
<img className={styles.qrCode} src={setUp.qrCode} alt="QR code" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -25,13 +25,11 @@
|
|||
min-width: 25px;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-color: var(--color-1-10) !important;
|
||||
box-shadow: 0px 0px 2px 0px var(--color-1-20);
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: calc(100% - 2px);
|
||||
max-height: calc(100% - 2px);
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.icon {
|
||||
|
|
|
|||
|
|
@ -14,14 +14,11 @@
|
|||
min-width: 30px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-color: var(--color-1-10) !important;
|
||||
|
||||
box-shadow: 0px 0px 2px 0px var(--color-1-20);
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: calc(100% - 2px);
|
||||
max-height: calc(100% - 2px);
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.closeButton {
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ const SubscriptionModal = (props: Props) => {
|
|||
{!isNull(packageItem) ? (
|
||||
<div
|
||||
data-testid="activePackageItem"
|
||||
className={`border border-secondary w-100 rounded mt-1 ${styles.packageWrapper}`}
|
||||
className={`border border-secondary w-100 mt-1 ${styles.packageWrapper}`}
|
||||
>
|
||||
<div className="d-flex flex-row flex-nowrap align-items-stretch justify-content-between">
|
||||
<div className="flex-grow-1 text-truncate py-2">
|
||||
|
|
@ -184,7 +184,7 @@ const SubscriptionModal = (props: Props) => {
|
|||
</div>
|
||||
|
||||
<div
|
||||
className={`d-flex align-items-center justify-content-center overflow-hidden p-1 ms-2 ms-md-0 rounded-circle border border-2 bg-white ${styles.imageWrapper} imageWrapper`}
|
||||
className={`d-flex align-items-center justify-content-center overflow-hidden ms-2 ms-md-0 ${styles.imageWrapper}`}
|
||||
>
|
||||
<Image
|
||||
alt={packageItem.displayName || packageItem.name}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
.card {
|
||||
box-shadow: 0px 0px 5px 0px var(--bs-light);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.card:hover {
|
||||
border-color: var(--color-black-50);
|
||||
box-shadow: 0px 0px 5px 0px var(--color-black-75);
|
||||
border-color: var(--color-black-25);
|
||||
box-shadow: 0 0 0 2px var(--color-black-25);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -22,14 +18,11 @@
|
|||
min-width: 60px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-color: var(--color-1-10) !important;
|
||||
|
||||
box-shadow: 0px 0px 5px 0px var(--color-1-20);
|
||||
}
|
||||
|
||||
.image {
|
||||
max-width: calc(100% - 8px);
|
||||
max-height: calc(100% - 8px);
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.link {
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ exports[`PackagesSection creates snapshot 1`] = `
|
|||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden p-1 rounded-circle border bg-white imageWrapper imageWrapper"
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="airflow"
|
||||
|
|
@ -330,7 +330,7 @@ exports[`PackagesSection creates snapshot 1`] = `
|
|||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden p-1 rounded-circle border bg-white imageWrapper imageWrapper"
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="cerebro"
|
||||
|
|
@ -445,7 +445,7 @@ exports[`PackagesSection creates snapshot 1`] = `
|
|||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden p-1 rounded-circle border bg-white imageWrapper imageWrapper"
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="elastic-stack"
|
||||
|
|
@ -560,7 +560,7 @@ exports[`PackagesSection creates snapshot 1`] = `
|
|||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden p-1 rounded-circle border bg-white imageWrapper imageWrapper"
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="ibm-redis"
|
||||
|
|
@ -675,7 +675,7 @@ exports[`PackagesSection creates snapshot 1`] = `
|
|||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden p-1 rounded-circle border bg-white imageWrapper imageWrapper"
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="SSH connections"
|
||||
|
|
@ -790,7 +790,7 @@ exports[`PackagesSection creates snapshot 1`] = `
|
|||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden p-1 rounded-circle border bg-white imageWrapper imageWrapper"
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="Traefik"
|
||||
|
|
@ -905,7 +905,7 @@ exports[`PackagesSection creates snapshot 1`] = `
|
|||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden p-1 rounded-circle border bg-white imageWrapper imageWrapper"
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="Trusted Registry Images"
|
||||
|
|
@ -1020,7 +1020,7 @@ exports[`PackagesSection creates snapshot 1`] = `
|
|||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden p-1 rounded-circle border bg-white imageWrapper imageWrapper"
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="zookeeper"
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ const PackagesSection = (props: Props) => {
|
|||
<td className="align-middle">
|
||||
<div className="d-flex flex-row align-items-center">
|
||||
<div
|
||||
className={`d-flex align-items-center justify-content-center overflow-hidden p-1 rounded-circle border bg-white ${styles.imageWrapper} imageWrapper`}
|
||||
className={`d-flex align-items-center justify-content-center overflow-hidden ${styles.imageWrapper}`}
|
||||
>
|
||||
<Image
|
||||
alt={item.displayName || item.name}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
.card {
|
||||
box-shadow: 0px 0px 5px 0px var(--bs-light);
|
||||
}
|
||||
|
||||
.badge {
|
||||
font-size: 0.5rem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,13 +23,10 @@
|
|||
background-color: var(--bs-white);
|
||||
}
|
||||
|
||||
.imageWrapper {
|
||||
.image {
|
||||
min-width: 25px;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-color: var(--color-1-10) !important;
|
||||
|
||||
box-shadow: 0px 0px 2px 0px var(--color-1-20);
|
||||
}
|
||||
|
||||
.cellWrapper {
|
||||
|
|
@ -54,6 +51,7 @@
|
|||
|
||||
.codeWrapper {
|
||||
overflow-x: auto;
|
||||
background-color: var(--color-black-5);
|
||||
}
|
||||
|
||||
.variablesTable {
|
||||
|
|
|
|||
|
|
@ -473,16 +473,12 @@ const WebhookForm = (props: Props) => {
|
|||
</td>
|
||||
<td className="align-middle">
|
||||
<div className="d-flex flex-row align-items-center">
|
||||
<div
|
||||
className={`d-flex align-items-center justify-content-center overflow-hidden p-1 rounded-circle border border-2 bg-white ${styles.imageWrapper} imageWrapper`}
|
||||
>
|
||||
<Image
|
||||
alt={item.displayName || item.name}
|
||||
imageId={item.logoImageId}
|
||||
className="mw-100 mh-100 fs-4"
|
||||
kind={item.repository.kind}
|
||||
/>
|
||||
</div>
|
||||
<Image
|
||||
alt={item.displayName || item.name}
|
||||
imageId={item.logoImageId}
|
||||
className={`fs-4 ${styles.image}`}
|
||||
kind={item.repository.kind}
|
||||
/>
|
||||
|
||||
<div className={`ms-2 text-dark ${styles.cellWrapper}`}>
|
||||
<div className="text-truncate">
|
||||
|
|
|
|||
|
|
@ -442,17 +442,13 @@ exports[`WebhookForm creates snapshot 1`] = `
|
|||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden p-1 rounded-circle border border-2 bg-white imageWrapper imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="envoy"
|
||||
aria-hidden="true"
|
||||
class="mw-100 mh-100 fs-4"
|
||||
src="/image/c5cfce82-9b0c-4a26-9a8d-c9d0fd5aa2cc"
|
||||
srcset="/image/c5cfce82-9b0c-4a26-9a8d-c9d0fd5aa2cc@1x 1x, /image/c5cfce82-9b0c-4a26-9a8d-c9d0fd5aa2cc@2x 2x, /image/c5cfce82-9b0c-4a26-9a8d-c9d0fd5aa2cc@3x 3x, /image/c5cfce82-9b0c-4a26-9a8d-c9d0fd5aa2cc@4x 4x"
|
||||
/>
|
||||
</div>
|
||||
<img
|
||||
alt="envoy"
|
||||
aria-hidden="true"
|
||||
class="fs-4 image"
|
||||
src="/image/c5cfce82-9b0c-4a26-9a8d-c9d0fd5aa2cc"
|
||||
srcset="/image/c5cfce82-9b0c-4a26-9a8d-c9d0fd5aa2cc@1x 1x, /image/c5cfce82-9b0c-4a26-9a8d-c9d0fd5aa2cc@2x 2x, /image/c5cfce82-9b0c-4a26-9a8d-c9d0fd5aa2cc@3x 3x, /image/c5cfce82-9b0c-4a26-9a8d-c9d0fd5aa2cc@4x 4x"
|
||||
/>
|
||||
<div
|
||||
class="ms-2 text-dark cellWrapper"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@
|
|||
padding-top: 7rem !important;
|
||||
}
|
||||
|
||||
.mainTitle {
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.search {
|
||||
min-width: 250px;
|
||||
max-width: 500px;
|
||||
|
|
@ -32,6 +36,10 @@
|
|||
width: 75px;
|
||||
}
|
||||
|
||||
.legend {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.legendIcon {
|
||||
font-size: 70%;
|
||||
line-height: 1rem;
|
||||
|
|
@ -97,6 +105,10 @@
|
|||
font-size: 85%;
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
.banner {
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1400px) {
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
.card {
|
||||
margin: 0 auto;
|
||||
max-width: 750px;
|
||||
box-shadow: 0px 0px 5px 0px var(--bs-light);
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 1.75rem !important;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767.98px) {
|
||||
.body {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
.card {
|
||||
min-height: 198px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.card:hover {
|
||||
border-color: var(--color-black-50);
|
||||
box-shadow: 0px 0px 5px 0px var(--color-black-75);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
|
||||
import { Package } from '../../types';
|
||||
import { prepareQueryString } from '../../utils/prepareQueryString';
|
||||
import PackageCard from './PackageCard';
|
||||
|
||||
const getMockPackage = (fixtureId: string): Package => {
|
||||
return require(`./__fixtures__/PackageCard/${fixtureId}.json`) as Package;
|
||||
};
|
||||
|
||||
const mockHistoryPush = jest.fn();
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...(jest.requireActual('react-router-dom') as {}),
|
||||
useHistory: () => ({
|
||||
push: mockHistoryPush,
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('PackageCard', () => {
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('renders correctly', () => {
|
||||
const mockPackage = getMockPackage('1');
|
||||
const { asFragment } = render(
|
||||
<Router>
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('Image', () => {
|
||||
it('renders package logo', () => {
|
||||
const mockPackage = getMockPackage('2');
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const image = screen.getByAltText(`Logo ${mockPackage.displayName}`);
|
||||
expect(image).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders placeholder when imageId is null', () => {
|
||||
const mockPackage = getMockPackage('3');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const image = screen.getByAltText(`Logo ${mockPackage.displayName}`);
|
||||
expect(image).toBeInTheDocument();
|
||||
expect((image as HTMLImageElement).src).toBe('http://localhost/static/media/placeholder_pkg_helm.png');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Title', () => {
|
||||
it('renders display name', () => {
|
||||
const mockPackage = getMockPackage('4');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const title = screen.queryByText(mockPackage.displayName!);
|
||||
expect(title).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders name when display name is null', () => {
|
||||
const mockPackage = getMockPackage('5');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const title = screen.queryByText(mockPackage.name!);
|
||||
expect(title).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Repository button', () => {
|
||||
it('renders repository link', async () => {
|
||||
const mockPackage = getMockPackage('7');
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const buttons = screen.queryAllByTestId('repoLink');
|
||||
expect(buttons).toHaveLength(2);
|
||||
const icons = screen.queryAllByAltText('Icon');
|
||||
expect(icons).toHaveLength(16);
|
||||
expect(icons[0]).toBeInTheDocument();
|
||||
expect((icons[0] as HTMLImageElement).src).toBe('http://localhost/static/media/helm-chart.svg');
|
||||
await userEvent.click(buttons[0]!);
|
||||
|
||||
expect(mockHistoryPush).toHaveBeenCalledTimes(1);
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith({
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
pageNumber: 1,
|
||||
filters: {
|
||||
repo: [mockPackage.repository.name],
|
||||
},
|
||||
}),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Detail', () => {
|
||||
it('opens detail page', async () => {
|
||||
const mockPackage = getMockPackage('9');
|
||||
render(
|
||||
<Router>
|
||||
<PackageCard package={mockPackage} />
|
||||
</Router>
|
||||
);
|
||||
const link = screen.getByRole('link');
|
||||
expect(link).toBeInTheDocument();
|
||||
await userEvent.click(link);
|
||||
expect(window.location.pathname).toBe('/packages/helm/stable/test');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { Package } from '../../types';
|
||||
import buildPackageURL from '../../utils/buildPackageURL';
|
||||
import PackageInfo from '../common/PackageInfo';
|
||||
import styles from './PackageCard.module.css';
|
||||
|
||||
interface Props {
|
||||
package: Package;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const PackageCard = (props: Props) => (
|
||||
<div
|
||||
className={`col-12 col-xxl-6 col-xxxl-5 py-sm-3 py-2 px-0 px-xxl-3 position-relative ${props.className}`}
|
||||
role="listitem"
|
||||
>
|
||||
<div className={`card cardWithHover h-100 ${styles.card}`}>
|
||||
<Link
|
||||
className="text-decoration-none text-reset h-100"
|
||||
to={{
|
||||
pathname: buildPackageURL(props.package.normalizedName, props.package.repository, props.package.version!),
|
||||
}}
|
||||
>
|
||||
<div className={`card-body d-flex flex-column h-100 ${styles.body}`}>
|
||||
<PackageInfo package={props.package} />
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default PackageCard;
|
||||
|
|
@ -2,3 +2,14 @@
|
|||
min-height: 500px;
|
||||
background-color: var(--body-bg);
|
||||
}
|
||||
|
||||
.card {
|
||||
max-width: 750px !important;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
.card {
|
||||
min-height: 172px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import API from '../../api';
|
|||
import { Package } from '../../types';
|
||||
import Loading from '../common/Loading';
|
||||
import NoData from '../common/NoData';
|
||||
import PackageCard from './PackageCard';
|
||||
import PackageCard from '../common/PackageCard';
|
||||
import styles from './RandomPackages.module.css';
|
||||
|
||||
const RandomPackages = () => {
|
||||
|
|
@ -45,7 +45,11 @@ const RandomPackages = () => {
|
|||
<PackageCard
|
||||
key={`rp_${item.packageId}`}
|
||||
package={item}
|
||||
className={classnames({ 'd-none d-xxl-block': index > 4 })}
|
||||
className={styles.card}
|
||||
cardWrapperClassName={classnames('col-12 col-xxl-6 col-xxxl-5', {
|
||||
'd-none d-xxl-block': index > 4,
|
||||
})}
|
||||
noBadges
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const SearchTip = () => {
|
|||
<span className="fw-semibold me-1">Tip:</span>
|
||||
{activeTip.content} Example:{' '}
|
||||
<Link
|
||||
className="fw-bold textLighter p-0"
|
||||
className="fw-semibold textLighter p-0"
|
||||
to={{
|
||||
pathname: '/packages/search',
|
||||
search: prepareQueryString({
|
||||
|
|
|
|||
|
|
@ -1,755 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PackageCard renders correctly 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
class="col-12 col-xxl-6 col-xxxl-5 py-sm-3 py-2 px-0 px-xxl-3 position-relative undefined"
|
||||
role="listitem"
|
||||
>
|
||||
<div
|
||||
class="card cardWithHover h-100 card"
|
||||
>
|
||||
<a
|
||||
class="text-decoration-none text-reset h-100"
|
||||
href="/packages/helm/stable/test"
|
||||
>
|
||||
<div
|
||||
class="card-body d-flex flex-column h-100 body"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-start justify-content-between mw-100"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-stretch flex-grow-1 h-100 truncateWrapper"
|
||||
>
|
||||
<div
|
||||
class="d-flex align-items-center justify-content-center overflow-hidden rounded-circle p-1 p-md-2 border position-relative bg-white imageWrapper imageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="Logo Pretty name"
|
||||
aria-hidden="true"
|
||||
class="image"
|
||||
src="/image/imageId"
|
||||
srcset="/image/imageId@1x 1x, /image/imageId@2x 2x, /image/imageId@3x 3x, /image/imageId@4x 4x"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-column justify-content-between ms-3 my-1 my-md-0 flex-grow-1 truncateWrapper titleWrapper"
|
||||
>
|
||||
<div
|
||||
class="text-truncate card-title mb-0"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center justify-content-between"
|
||||
>
|
||||
<div
|
||||
class="text-truncate title"
|
||||
>
|
||||
Pretty name
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-xxl-flex d-xxxl-none flex-column ms-2"
|
||||
>
|
||||
<div
|
||||
class="align-self-start d-flex align-items-center text-uppercase ms-auto kind"
|
||||
>
|
||||
<div
|
||||
class="d-none d-md-inline-block"
|
||||
>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
Helm chart
|
||||
</span>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by Helm chart repository kind"
|
||||
class="btn btn-link m-0 p-0"
|
||||
data-testid="repoIconLabelLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex d-md-none fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-block d-md-none"
|
||||
>
|
||||
<div
|
||||
class="card-subtitle align-items-baseline subtitle"
|
||||
>
|
||||
<div
|
||||
class="d-inline d-md-none text-truncate w-100"
|
||||
>
|
||||
<div
|
||||
class="position-absolute"
|
||||
>
|
||||
<div
|
||||
class="dropdown-menu dropdown-menu-left text-wrap dropdown"
|
||||
role="complementary"
|
||||
>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-column"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
Repo:
|
||||
</small>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="me-1 w-auto repoIconMini iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="me-1 w-auto repoIconMini iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
<div
|
||||
class="text-reset text-truncate labelContent"
|
||||
>
|
||||
stable
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-2 d-flex flex-row align-items-baseline"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
Url:
|
||||
</small>
|
||||
<div
|
||||
class="text-reset text-break labelContent"
|
||||
data-testid="repoUrl"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row flex-wrap undefined"
|
||||
data-testid="attachedIconToTextWrapper"
|
||||
style="line-height: 21px;"
|
||||
>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
r
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
e
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
p
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
o
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
U
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
r
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
l
|
||||
</div>
|
||||
<div
|
||||
class="d-inline-block"
|
||||
>
|
||||
<div
|
||||
class="position-relative d-inline"
|
||||
>
|
||||
<button
|
||||
aria-label="Copy repository url to clipboard"
|
||||
class="btn btn-sm bg-transparent"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect
|
||||
height="13"
|
||||
rx="2"
|
||||
ry="2"
|
||||
width="13"
|
||||
x="9"
|
||||
y="9"
|
||||
/>
|
||||
<path
|
||||
d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-row text-truncate"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline me-1 text-muted text-uppercase"
|
||||
>
|
||||
<small>
|
||||
Repo:
|
||||
</small>
|
||||
</div>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
stable
|
||||
</span>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by repo stable"
|
||||
class="d-flex flex-row p-0 border-0 text-dark text-truncate bg-transparent position-relative link"
|
||||
data-testid="repoLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="text-truncate"
|
||||
>
|
||||
stable
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-md-block card-subtitle align-items-baseline subtitle"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline"
|
||||
>
|
||||
<span
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
User:
|
||||
</span>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
user
|
||||
</span>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by user"
|
||||
class="p-0 border-0 text-truncate text-dark mw-100 bg-transparent link mx50"
|
||||
data-testid="userLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="text-truncate"
|
||||
>
|
||||
user
|
||||
</div>
|
||||
</button>
|
||||
<div
|
||||
class="mx50"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline ms-3 truncateWrapper"
|
||||
>
|
||||
<div
|
||||
class="position-absolute"
|
||||
>
|
||||
<div
|
||||
class="dropdown-menu dropdown-menu-left text-wrap dropdown"
|
||||
role="complementary"
|
||||
>
|
||||
<div
|
||||
class="content"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-column"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
Repo:
|
||||
</small>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="me-1 w-auto repoIconMini iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="me-1 w-auto repoIconMini iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
<div
|
||||
class="text-reset text-truncate labelContent"
|
||||
>
|
||||
stable
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-2 d-flex flex-row align-items-baseline"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
Url:
|
||||
</small>
|
||||
<div
|
||||
class="text-reset text-break labelContent"
|
||||
data-testid="repoUrl"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row flex-wrap undefined"
|
||||
data-testid="attachedIconToTextWrapper"
|
||||
style="line-height: 21px;"
|
||||
>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
r
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
e
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
p
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
o
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
U
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
r
|
||||
</div>
|
||||
<div
|
||||
class="d-inline"
|
||||
>
|
||||
l
|
||||
</div>
|
||||
<div
|
||||
class="d-inline-block"
|
||||
>
|
||||
<div
|
||||
class="position-relative d-inline"
|
||||
>
|
||||
<button
|
||||
aria-label="Copy repository url to clipboard"
|
||||
class="btn btn-sm bg-transparent"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect
|
||||
height="13"
|
||||
rx="2"
|
||||
ry="2"
|
||||
width="13"
|
||||
x="9"
|
||||
y="9"
|
||||
/>
|
||||
<path
|
||||
d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-row text-truncate"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline me-1 text-muted text-uppercase"
|
||||
>
|
||||
<small>
|
||||
Repo:
|
||||
</small>
|
||||
</div>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
stable
|
||||
</span>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by repo stable"
|
||||
class="d-flex flex-row p-0 border-0 text-dark text-truncate bg-transparent position-relative link"
|
||||
data-testid="repoLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="text-truncate"
|
||||
>
|
||||
stable
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-md-block card-subtitle text-truncate align-items-baseline position-relative subtitle lastLine"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-baseline text-truncate"
|
||||
>
|
||||
<span
|
||||
class="text-muted text-uppercase me-1"
|
||||
>
|
||||
Version:
|
||||
</span>
|
||||
-
|
||||
<span
|
||||
class="text-muted text-uppercase me-1 ms-3"
|
||||
>
|
||||
App Version:
|
||||
</span>
|
||||
1.0.0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-md-flex d-xxl-none d-xxxl-flex flex-column align-items-end mb-auto ms-2"
|
||||
>
|
||||
<div
|
||||
class="align-self-start d-flex align-items-center text-uppercase ms-auto kind"
|
||||
>
|
||||
<div
|
||||
class="d-none d-md-inline-block"
|
||||
>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
Helm chart
|
||||
</span>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by Helm chart repository kind"
|
||||
class="btn btn-link m-0 p-0"
|
||||
data-testid="repoIconLabelLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex d-md-none fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-1"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-nowrap date"
|
||||
>
|
||||
Updated Invalid date
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mb-0 mb-md-1 mt-3 overflow-hidden description text-truncate"
|
||||
>
|
||||
desc
|
||||
</div>
|
||||
<div
|
||||
class="d-none d-xxl-block d-xxxl-none text-end mt-2"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-nowrap date"
|
||||
>
|
||||
Updated Invalid date
|
||||
</small>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex d-md-none d-xxl-none flex-row flex-wrap justify-content-between align-items-center mt-auto pt-2 pt-md-0 mt-1 mt-md-0 mt-xxl-1 mt-xxxl-0"
|
||||
>
|
||||
<small
|
||||
class="text-muted text-nowrap date"
|
||||
>
|
||||
Updated Invalid date
|
||||
</small>
|
||||
<span>
|
||||
<div
|
||||
class="align-self-start d-flex align-items-center text-uppercase ms-auto kind"
|
||||
>
|
||||
<div
|
||||
class="d-none d-md-inline-block"
|
||||
>
|
||||
<span
|
||||
class="visually-hidden"
|
||||
>
|
||||
Helm chart
|
||||
</span>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
aria-label="Filter by Helm chart repository kind"
|
||||
class="btn btn-link m-0 p-0"
|
||||
data-testid="repoIconLabelLink"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex d-md-none fs-6"
|
||||
>
|
||||
<span
|
||||
class="badge bg-light text-dark rounded-pill border bg badge"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row align-items-center"
|
||||
>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="position-relative icon undefined"
|
||||
>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconLight"
|
||||
src="/static/media/helm-chart.svg"
|
||||
/>
|
||||
<img
|
||||
alt="Icon"
|
||||
class="mw-100 mh-100 iconDark"
|
||||
src="/static/media/helm-chart-light.svg"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ms-1"
|
||||
>
|
||||
Helm chart
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="d-flex flex-wrap justify-content-lg-end mt-0 mt-md-auto labelsWrapper"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -36,7 +36,7 @@ exports[`SearchTip creates snapshot 1`] = `
|
|||
</span>
|
||||
to refine your search. Example:
|
||||
<a
|
||||
class="fw-bold textLighter p-0"
|
||||
class="fw-semibold textLighter p-0"
|
||||
href="/packages/search?ts_query_web=kafka+operator&sort=relevance&page=1"
|
||||
>
|
||||
kafka operator
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ exports[`Home index creates snapshot 1`] = `
|
|||
>
|
||||
<div
|
||||
aria-label="Find, install and publisher Kubernetes packages"
|
||||
class="display-4 text-center fw-light d-block d-xxl-flex justify-content-center noFocus mainTitle"
|
||||
class="display-4 text-center d-block d-xxl-flex justify-content-center noFocus mainTitle"
|
||||
id="content"
|
||||
role="banner"
|
||||
tabindex="-1"
|
||||
|
|
@ -106,7 +106,7 @@ exports[`Home index creates snapshot 1`] = `
|
|||
type="button"
|
||||
/>
|
||||
<div
|
||||
class="position-absolute text-dark tipIcon bigTipIcon"
|
||||
class="d-none d-sm-block position-absolute text-dark tipIcon bigTipIcon"
|
||||
>
|
||||
<button
|
||||
aria-label="Open search tips modal"
|
||||
|
|
@ -136,7 +136,7 @@ exports[`Home index creates snapshot 1`] = `
|
|||
- or -
|
||||
<a
|
||||
aria-label="Browse all packages"
|
||||
class="btn btn-link textLighter fw-bold py-0 pb-1 ps-1 allPkgBtn"
|
||||
class="btn btn-link textLighter fw-semibold py-0 pb-1 ps-1 allPkgBtn"
|
||||
href="/packages/search"
|
||||
>
|
||||
browse all packages
|
||||
|
|
@ -148,7 +148,7 @@ exports[`Home index creates snapshot 1`] = `
|
|||
Or you can also
|
||||
<a
|
||||
aria-label="Browse all packages"
|
||||
class="btn btn-link textLighter fw-bold py-0 pb-1 ps-1 pe-0"
|
||||
class="btn btn-link textLighter fw-semibold py-0 pb-1 ps-1 pe-0"
|
||||
href="/packages/search"
|
||||
>
|
||||
browse all packages
|
||||
|
|
@ -206,9 +206,11 @@ exports[`Home index creates snapshot 1`] = `
|
|||
class="text-center h5 my-4 mt-md-5 legend"
|
||||
>
|
||||
Artifact Hub is an
|
||||
<b>
|
||||
<span
|
||||
class="fw-semibold"
|
||||
>
|
||||
Open Source
|
||||
</b>
|
||||
</span>
|
||||
project
|
||||
</div>
|
||||
<div
|
||||
|
|
@ -308,7 +310,7 @@ exports[`Home index creates snapshot 1`] = `
|
|||
Please see the
|
||||
<a
|
||||
aria-label="Open documentation"
|
||||
class="link btn btn-link text-light fw-bold textLight p-0 align-baseline inlineLink"
|
||||
class="link btn btn-link text-light fw-semibold textLight p-0 align-baseline inlineLink"
|
||||
href="/docs/topics/repositories"
|
||||
rel="noopener noreferrer"
|
||||
role="button"
|
||||
|
|
@ -604,6 +606,9 @@ exports[`Home index creates snapshot 1`] = `
|
|||
<div
|
||||
class="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around"
|
||||
>
|
||||
<div
|
||||
class="col"
|
||||
/>
|
||||
<a
|
||||
aria-label="Open Container Initiative site"
|
||||
class="link col iconLink"
|
||||
|
|
@ -682,6 +687,9 @@ exports[`Home index creates snapshot 1`] = `
|
|||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div
|
||||
class="col"
|
||||
/>
|
||||
</div>
|
||||
Discovering artifacts to use with CNCF projects can be difficult. If every CNCF project that needs to share artifacts creates its own Hub this creates a fair amount of repeat work for each project and a fractured experience for those trying to find the artifacts to consume. The Artifact Hub attempts to solve that by providing a single experience for consumers that any CNCF project can leverage.
|
||||
</div>
|
||||
|
|
@ -707,7 +715,7 @@ exports[`Home index creates snapshot 1`] = `
|
|||
Artifact Hub is a
|
||||
<a
|
||||
aria-label="Open CNCF sandbox projects site"
|
||||
class="link fw-bold text-dark"
|
||||
class="link fw-semibold text-dark"
|
||||
href="https://www.cncf.io/sandbox-projects/"
|
||||
rel="noopener noreferrer"
|
||||
role="button"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { FaGithub, FaSlack, FaTwitter } from 'react-icons/fa';
|
|||
import { Link, useHistory } from 'react-router-dom';
|
||||
|
||||
import API from '../../api';
|
||||
import useBreakpointDetect from '../../hooks/useBreakpointDetect';
|
||||
import { Banner as IBanner, RepositoryKind, Stats } from '../../types';
|
||||
import alertDispatcher from '../../utils/alertDispatcher';
|
||||
import bannerDispatcher from '../../utils/bannerDispatcher';
|
||||
|
|
@ -34,6 +35,7 @@ interface Props {
|
|||
}
|
||||
|
||||
const HomeView = (props: Props) => {
|
||||
const point = useBreakpointDetect();
|
||||
const history = useHistory();
|
||||
const sampleQueries = getSampleQueries();
|
||||
const [isLoadingStats, setIsLoadingStats] = useState(false);
|
||||
|
|
@ -88,7 +90,7 @@ const HomeView = (props: Props) => {
|
|||
<div
|
||||
role="banner"
|
||||
aria-label="Find, install and publisher Kubernetes packages"
|
||||
className={`display-4 text-center fw-light d-block d-xxl-flex justify-content-center noFocus ${styles.mainTitle}`}
|
||||
className={`display-4 text-center d-block d-xxl-flex justify-content-center noFocus ${styles.mainTitle}`}
|
||||
id="content"
|
||||
tabIndex={-1}
|
||||
>
|
||||
|
|
@ -111,7 +113,7 @@ const HomeView = (props: Props) => {
|
|||
<div className="d-inline-block d-md-none text-center mt-3">
|
||||
- or -
|
||||
<Link
|
||||
className={`btn btn-link textLighter fw-bold py-0 pb-1 ps-1 ${styles.allPkgBtn}`}
|
||||
className={`btn btn-link textLighter fw-semibold py-0 pb-1 ps-1 ${styles.allPkgBtn}`}
|
||||
to={{
|
||||
pathname: '/packages/search',
|
||||
}}
|
||||
|
|
@ -124,7 +126,7 @@ const HomeView = (props: Props) => {
|
|||
<div className="d-none d-md-inline-block text-center mt-5">
|
||||
{sampleQueries.length > 0 ? <>You can also </> : <>Or you can also </>}
|
||||
<Link
|
||||
className="btn btn-link textLighter fw-bold py-0 pb-1 ps-1 pe-0"
|
||||
className="btn btn-link textLighter fw-semibold py-0 pb-1 ps-1 pe-0"
|
||||
to={{
|
||||
pathname: '/packages/search',
|
||||
}}
|
||||
|
|
@ -142,7 +144,7 @@ const HomeView = (props: Props) => {
|
|||
</div>
|
||||
|
||||
<div className="d-none d-md-flex flex-row align-items-end justify-content-center flex-wrap">
|
||||
<SampleQueries lineBreakIn={3} className="bg-secondary border-light" />
|
||||
<SampleQueries lineBreakIn={3} className="bg-secondary" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -158,14 +160,14 @@ const HomeView = (props: Props) => {
|
|||
wrapperClassName="d-inline-block position-relative mt-4 mt-md-5"
|
||||
banner={banner}
|
||||
removeBanner={() => setBanner(null)}
|
||||
maxEqualRatio
|
||||
maxEqualRatio={point !== 'xs'}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!whiteLabel && (
|
||||
<>
|
||||
<div className={`text-center h5 my-4 mt-md-5 ${styles.legend}`}>
|
||||
Artifact Hub is an <b>Open Source</b> project
|
||||
Artifact Hub is an <span className="fw-semibold">Open Source</span> project
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-row align-items-center justify-content-center flex-wrap">
|
||||
|
|
@ -206,7 +208,7 @@ const HomeView = (props: Props) => {
|
|||
<div className={`text-center mx-3 mt-md-4 mb-4 fw-light ${styles.repoGuideText}`}>
|
||||
Please see the{' '}
|
||||
<ExternalLink
|
||||
className={`btn btn-link text-light fw-bold textLight p-0 align-baseline ${styles.inlineLink}`}
|
||||
className={`btn btn-link text-light fw-semibold textLight p-0 align-baseline ${styles.inlineLink}`}
|
||||
href="/docs/topics/repositories"
|
||||
label="Open documentation"
|
||||
>
|
||||
|
|
@ -335,6 +337,7 @@ const HomeView = (props: Props) => {
|
|||
</ExternalLink>
|
||||
</div>
|
||||
<div className="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around">
|
||||
<div className="col" />
|
||||
<ExternalLink
|
||||
href="https://opencontainers.org"
|
||||
className={`col ${styles.iconLink}`}
|
||||
|
|
@ -371,6 +374,7 @@ const HomeView = (props: Props) => {
|
|||
</div>
|
||||
</div>
|
||||
</ExternalLink>
|
||||
<div className="col" />
|
||||
</div>
|
||||
Discovering artifacts to use with CNCF projects can be difficult. If every CNCF project that needs to
|
||||
share artifacts creates its own Hub this creates a fair amount of repeat work for each project and a
|
||||
|
|
@ -392,7 +396,7 @@ const HomeView = (props: Props) => {
|
|||
Artifact Hub is a{' '}
|
||||
<ExternalLink
|
||||
href="https://www.cncf.io/sandbox-projects/"
|
||||
className="fw-bold text-dark"
|
||||
className="fw-semibold text-dark"
|
||||
label="Open CNCF sandbox projects site"
|
||||
>
|
||||
Cloud Native Computing Foundation
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ const Footer = (props: Props) => {
|
|||
className={`d-flex flex-row flex-wrap align-items-stretch justify-content-between ${styles.footerContent}`}
|
||||
>
|
||||
<div>
|
||||
<div className="h6 fw-bold text-uppercase">Project</div>
|
||||
<div className="h6 fw-semibold text-uppercase">Project</div>
|
||||
<div className="d-flex flex-column text-start">
|
||||
<ExternalLink
|
||||
className={`mb-1 ${styles.link}`}
|
||||
|
|
@ -58,7 +58,7 @@ const Footer = (props: Props) => {
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<div className="h6 fw-bold text-uppercase">Community</div>
|
||||
<div className="h6 fw-semibold text-uppercase">Community</div>
|
||||
<div className="d-flex flex-column text-start">
|
||||
<ExternalLink
|
||||
className={`mb-1 ${styles.link}`}
|
||||
|
|
@ -94,7 +94,7 @@ const Footer = (props: Props) => {
|
|||
</div>
|
||||
|
||||
<div className={styles.fullMobileSection}>
|
||||
<div className="h6 fw-bold text-uppercase">About</div>
|
||||
<div className="h6 fw-semibold text-uppercase">About</div>
|
||||
<div className={styles.copyrightContent}>
|
||||
Artifact Hub is an <b className="d-inline-block">Open Source</b> project licensed under the{' '}
|
||||
<ExternalLink
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
.iconWrapper {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border-width: 2px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
.profileImage {
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ const MobileSettings = (props: Props) => {
|
|||
buttonIcon={
|
||||
<div
|
||||
className={classnames(
|
||||
'rounded-circle d-flex align-items-center justify-content-center lh-1 fs-3 bg-white',
|
||||
'rounded-circle d-flex align-items-center justify-content-center lh-1 bg-white',
|
||||
styles.iconWrapper
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -66,3 +66,10 @@
|
|||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767.98px) {
|
||||
.search {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,12 +45,12 @@ const Navbar = (props: Props) => {
|
|||
return (
|
||||
<>
|
||||
<nav
|
||||
className={classnames('navbar navbar-top navbar-expand-lg navbar-dark border-top-0 p-3', styles.navbar, {
|
||||
className={classnames('navbar navbar-top navbar-expand-lg navbar-dark border-top-0 p-2 p-sm-3', styles.navbar, {
|
||||
[`bg-transparent w-100 position-absolute ${styles.homeNavbar}`]: props.fromHome,
|
||||
})}
|
||||
>
|
||||
<div className="container-lg px-sm-4 px-lg-0">
|
||||
<div className={`d-flex flex-row ${styles.mobileWrapper}`}>
|
||||
<div className="container-lg px-0 px-sm-4 px-lg-0">
|
||||
<div className={`d-flex flex-row px-1 ${styles.mobileWrapper}`}>
|
||||
<Link data-testid="brandLink" className="navbar-brand d-flex align-items-center" to="/">
|
||||
<div className="d-flex align-items-start">
|
||||
<img className={`w-auto ${styles.logo}`} src={logo} alt={`Logo ${siteName}`} />
|
||||
|
|
@ -67,7 +67,7 @@ const Navbar = (props: Props) => {
|
|||
{isUndefined(props.fromHome) && (
|
||||
<SearchBar
|
||||
size="normal"
|
||||
formClassName={`mx-2 me-md-auto my-3 my-md-0 flex-grow-1 pe-4 ${styles.search}`}
|
||||
formClassName={`mx-2 me-md-auto my-3 my-md-0 flex-grow-1 pe-0 pe-sm-4 ${styles.search}`}
|
||||
isSearching={props.isSearching}
|
||||
tsQueryWeb={props.searchText}
|
||||
openTips={openTips}
|
||||
|
|
|
|||
|
|
@ -3,3 +3,7 @@
|
|||
background-color: var(--color-2-500);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.navbar label {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ interface Props {
|
|||
|
||||
const SubNavbar = (props: Props) => (
|
||||
<nav className={`navbar navbar-expand-sm ${styles.navbar} ${props.className}`} role="navigation">
|
||||
<div className="container-lg px-sm-4 px-lg-0 d-flex align-items-center justify-content-between flex-nowrap">
|
||||
<div className="container-lg px-1 px-sm-4 px-lg-0 d-flex align-items-center justify-content-between flex-nowrap">
|
||||
{props.children}
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ exports[`Footer creates snapshot 1`] = `
|
|||
>
|
||||
<div>
|
||||
<div
|
||||
class="h6 fw-bold text-uppercase"
|
||||
class="h6 fw-semibold text-uppercase"
|
||||
>
|
||||
Project
|
||||
</div>
|
||||
|
|
@ -56,7 +56,7 @@ exports[`Footer creates snapshot 1`] = `
|
|||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="h6 fw-bold text-uppercase"
|
||||
class="h6 fw-semibold text-uppercase"
|
||||
>
|
||||
Community
|
||||
</div>
|
||||
|
|
@ -156,7 +156,7 @@ exports[`Footer creates snapshot 1`] = `
|
|||
class="fullMobileSection"
|
||||
>
|
||||
<div
|
||||
class="h6 fw-bold text-uppercase"
|
||||
class="h6 fw-semibold text-uppercase"
|
||||
>
|
||||
About
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ exports[`MobileSettings creates snapshot 1`] = `
|
|||
class="d-flex align-items-center justify-content-center"
|
||||
>
|
||||
<div
|
||||
class="rounded-circle d-flex align-items-center justify-content-center lh-1 fs-3 bg-white iconWrapper"
|
||||
class="rounded-circle d-flex align-items-center justify-content-center lh-1 bg-white iconWrapper"
|
||||
>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
exports[`Navbar creates snapshot 1`] = `
|
||||
<DocumentFragment>
|
||||
<nav
|
||||
class="navbar navbar-top navbar-expand-lg navbar-dark border-top-0 p-3 navbar bg-transparent w-100 position-absolute homeNavbar"
|
||||
class="navbar navbar-top navbar-expand-lg navbar-dark border-top-0 p-2 p-sm-3 navbar bg-transparent w-100 position-absolute homeNavbar"
|
||||
>
|
||||
<div
|
||||
class="container-lg px-sm-4 px-lg-0"
|
||||
class="container-lg px-0 px-sm-4 px-lg-0"
|
||||
>
|
||||
<div
|
||||
class="d-flex flex-row mobileWrapper"
|
||||
class="d-flex flex-row px-1 mobileWrapper"
|
||||
>
|
||||
<a
|
||||
class="navbar-brand d-flex align-items-center"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ exports[`SubNavbar creates snapshot 1`] = `
|
|||
role="navigation"
|
||||
>
|
||||
<div
|
||||
class="container-lg px-sm-4 px-lg-0 d-flex align-items-center justify-content-between flex-nowrap"
|
||||
class="container-lg px-1 px-sm-4 px-lg-0 d-flex align-items-center justify-content-between flex-nowrap"
|
||||
>
|
||||
<div
|
||||
data-testid="children"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
.content {
|
||||
background-color: var(--bs-light);
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 4rem;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue