Add new breakpoint to UI (#827)

Closes #778

Signed-off-by: Cintia Sanchez Garcia <cynthiasg@icloud.com>
This commit is contained in:
Cynthia S. Garcia 2020-11-06 09:39:23 +01:00 committed by GitHub
parent af136556cc
commit 309660d154
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
132 changed files with 4761 additions and 4467 deletions

View File

@ -11,7 +11,7 @@ returns setof json as $$
and p.logo_image_id is not null
and s.readme is not null
and s.created_at between current_timestamp - '6 months'::interval and current_timestamp
order by random() limit 5
order by random() limit 10
) rp
cross join get_package_summary(rp.package_id) as pkgJSON;
$$ language sql;

View File

@ -65,7 +65,7 @@
]
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -190,13 +190,13 @@ describe('index API', () => {
org: ['org1', 'org2'],
},
deprecated: false,
limit: 15,
limit: 20,
offset: 0,
});
expect(fetchMock.mock.calls.length).toEqual(1);
expect(fetchMock.mock.calls[0][0]).toEqual(
'/api/v1/packages/search?facets=true&limit=15&offset=0&kind=0&repo=repo1&repo=repo2&org=org1&org=org2&ts_query_web=database'
'/api/v1/packages/search?facets=true&limit=20&offset=0&kind=0&repo=repo1&repo=repo2&org=org1&org=org2&ts_query_web=database'
);
expect(response).toEqual(methods.toCamelCase(search));
});

View File

@ -58,7 +58,7 @@ const ElementWithTooltip = (props: Props) => {
{props.visibleTooltip && visibleTooltipStatus && (
<div
className={classnames('position-absolute', {
className={classnames('position-absolute d-none d-md-block', {
[styles.rightAligned]: !isUndefined(props.alignmentTooltip) && props.alignmentTooltip === 'right',
})}
>

View File

@ -8,7 +8,6 @@
.dropdown {
top: 40px;
width: 220px;
overflow-x: auto;
}

View File

@ -160,7 +160,7 @@ const InputTypeahead = (props: Props) => {
<div
ref={dropdownRef}
data-testid="typeaheadDropdown"
className={`dropdown-menu p-0 shadow-sm show ${styles.dropdown}`}
className={`dropdown-menu p-0 shadow-sm w-100 show ${styles.dropdown}`}
>
<div className={`form-group input-group-sm p-1 mb-0 border-bottom ${styles.inputWrapper}`}>
<input
@ -182,8 +182,8 @@ const InputTypeahead = (props: Props) => {
data-testid="typeaheadClearBtn"
className="btn btn-sm btn-block"
onClick={() => {
props.onResetSomeFilters(Object.keys(props.selected));
collapseDropdown();
props.onResetSomeFilters(Object.keys(props.selected));
}}
>
<div className="d-flex flex-row align-items-center text-muted">

View File

@ -102,6 +102,12 @@
}
}
@media only screen and (min-width: 768px) {
.card {
min-height: 215px;
}
}
@media (hover: hover) {
.link:hover {
text-decoration: underline;

View File

@ -9,6 +9,7 @@ import PackageInfo from './PackageInfo';
interface Props {
package: Package;
className?: string;
saveScrollPosition?: () => void;
searchUrlReferer?: SearchFiltersURL;
fromStarredPage?: boolean;
@ -16,11 +17,11 @@ interface Props {
}
const PackageCard = (props: Props) => (
<div className="col-12 py-sm-3 py-2" role="listitem">
<div className={`card cardWithHover h-100 ${styles.card}`}>
<div className="col-12 col-xxl-6 py-sm-3 py-2" role="listitem">
<div className={`card cardWithHover h-100 ${styles.card} ${props.className}`}>
<Link
data-testid="link"
className={`text-decoration-none text-reset ${styles.link}`}
className={`text-decoration-none text-reset h-100 ${styles.link}`}
onClick={() => {
if (!isUndefined(props.saveScrollPosition)) {
props.saveScrollPosition();
@ -31,7 +32,7 @@ const PackageCard = (props: Props) => (
state: { searchUrlReferer: props.searchUrlReferer, fromStarredPage: props.fromStarredPage },
}}
>
<div className={`card-body d-flex flex-column ${styles.body}`}>
<div className={`card-body d-flex flex-column h-100 ${styles.body}`}>
<PackageInfo
package={props.package}
visibleSignedBadge={props.visibleSignedBadge}

View File

@ -76,7 +76,7 @@
.lineClamp {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
@ -94,12 +94,22 @@
margin-right: 1rem;
}
.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;
}
}
@media only screen and (max-width: 767.98px) {
.imageWrapper {
min-width: 60px;
@ -109,7 +119,7 @@
}
.description {
font-size: 0.9rem;
font-size: 0.85rem;
}
.image {

View File

@ -67,7 +67,7 @@ const PackageInfo = (props: Props) => {
return (
<>
<div className="d-flex align-items-start justify-content-between flex-grow-1 mw-100">
<div className="d-flex align-items-start justify-content-between mw-100">
<div className={`d-flex align-items-strecht flex-grow-1 h-100 ${styles.truncateWrapper}`}>
{props.withPackageLinks ? (
<Link
@ -229,7 +229,7 @@ const PackageInfo = (props: Props) => {
<div
className={`d-flex d-${
props.breakpointForInfoSection || 'md'
}-none flex-row justify-content-between align-items-center mt-2 mb-3 mt-${
}-none flex-row justify-content-between align-items-center mt-auto pt-2 pt-${
props.breakpointForInfoSection || 'md'
}-0`}
>
@ -237,7 +237,7 @@ const PackageInfo = (props: Props) => {
{starsAndKindInfo}
</div>
<div className={`d-flex flex-wrap justify-content-md-end ${styles.labelsWrapper}`}>
<div className={`d-flex flex-wrap justify-content-md-end mt-0 mt-md-auto ${styles.labelsWrapper}`}>
<OfficialBadge official={props.package.repository.official} className="d-inline mt-3" />
<VerifiedPublisherBadge
verifiedPublisher={props.package.repository.verifiedPublisher}

View File

@ -31,7 +31,7 @@ const SearchPackages = (props: Props) => {
{
tsQueryWeb: tsQueryWeb,
filters: {},
limit: 15,
limit: 20,
offset: 0,
},
false

View File

@ -45,7 +45,7 @@ const SectionPanel = (props: Props) => {
return (
<main role="main" className="container d-flex flex-column flex-md-row justify-content-between my-md-4 p-0">
<nav className={`mb-3 ${styles.sidebar}`}>
<nav className={`mb-4 ${styles.sidebar}`}>
<div className={`list-group my-4 my-md-0 mr-md-5 ${styles.listGroup}`}>
{props.sections.map((section: Section) => {
const className = classnames(

View File

@ -55,7 +55,7 @@ const SecurityRating = (props: Props) => {
)
}
alignmentTooltip="right"
tooltipClassName={`d-none d-md-block ${styles.tooltip}`}
tooltipClassName={styles.tooltip}
tooltipArrowClassName={styles.tooltipArrow}
tooltipMessage={
<div className="d-flex flex-column">

View File

@ -33,7 +33,7 @@
"facets": null
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -33,7 +33,7 @@
"facets": null
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -33,7 +33,7 @@
"facets": null
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -33,7 +33,7 @@
"facets": null
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -26,7 +26,7 @@ const mockCtx = {
user: { alias: 'test', email: 'test@test.com' },
prefs: {
controlPanel: { selectedOrg: 'orgTest' },
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -17,7 +17,7 @@ const mockCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -31,7 +31,7 @@ const mockOrgCtx = {
controlPanel: {
selectedOrg: 'test',
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -45,7 +45,7 @@ const mockOrgCtx1 = {
controlPanel: {
selectedOrg: 'org',
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -24,7 +24,7 @@ const mockCtx = {
user: { alias: 'test', email: 'test@test.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -36,7 +36,7 @@ const mockCtxOrgSelected = {
user: { alias: 'test', email: 'test@test.com' },
prefs: {
controlPanel: { selectedOrg: 'orgTest' },
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -1,8 +1,3 @@
.listItem {
border-width: 2px;
padding: 1.25rem;
}
.btnIcon {
font-size: 0.65rem;
}

View File

@ -26,7 +26,7 @@ const mockCtx = {
controlPanel: {
selectedOrg: 'orgTest',
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -76,146 +76,152 @@ const MemberCard = (props: Props) => {
};
return (
<li className={`list-group-item ${styles.listItem}`} data-testid="memberCard">
<div className="d-flex flex-row w-100 justify-content-between align-items-start">
<div
className={`d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 ${styles.imageWrapper} imageWrapper`}
>
<FaUser className={styles.image} />
</div>
<div className="flex-grow-1">
<div className="d-flex flex-row align-items-start">
<div className="h5 mb-1">
{!isNull(props.member.firstName) || !isNull(props.member.lastName) ? getFullName() : props.member.alias}
<div className="col-12 col-xxl-6 py-sm-3 py-2" data-testid="memberCard">
<div className="card h-100">
<div className="card-body d-flex flex-column h-100">
<div className="d-flex flex-row w-100 justify-content-between align-items-start">
<div
className={`d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 ${styles.imageWrapper} imageWrapper`}
>
<FaUser className={styles.image} />
</div>
{!isUndefined(props.member.confirmed) && !props.member.confirmed && (
<div className={classnames('ml-3', { 'mr-3': props.membersNumber > 1 })}>
<small>
<span className="badge badge-warning">Invitation not accepted yet</span>
</small>
</div>
)}
</div>
<div className="h6 text-muted mr-1 font-italic">{props.member.alias}</div>
</div>
{props.membersNumber > 1 && (
<>
{modalStatus && (
<Modal
className={`d-inline-block ${styles.modal}`}
closeButton={
<>
<button
className={`btn btn-sm btn-light text-uppercase ${styles.btnLight}`}
onClick={() => setModalStatus(false)}
>
<div className="d-flex flex-row align-items-center">
<IoMdCloseCircle className="mr-2" />
<span>Cancel</span>
</div>
</button>
<button
data-testid="leaveOrRemoveBtn"
className="btn btn-sm btn-danger ml-3"
onClick={(e) => {
e.preventDefault();
deleteMember();
}}
disabled={isDeletingMember}
>
<div className="d-flex flex-row align-items-center text-uppercase">
{isDeletingMember ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="ml-2">{isUser ? 'Leaving...' : 'Removing...'}</span>
</>
) : (
<>
{isUser ? (
<FaSignOutAlt className={`mr-2 ${styles.btnIcon}`} />
) : (
<FaUserMinus className={`mr-2 ${styles.btnIcon}`} />
)}
<span>{isUser ? 'Leave' : 'Remove'}</span>
</>
)}
</div>
</button>
</>
}
header={
<div className={`h3 m-2 ${styles.title}`}>{isUser ? 'Leave ' : 'Remove from '} organization</div>
}
onClose={() => setModalStatus(false)}
open
>
<div className="mt-3 mw-100 text-center">
<p>
{isUser
? 'Are you sure you want to leave this organization?'
: 'Are you sure you want to remove this member from this organization?'}
</p>
<div className="flex-grow-1">
<div className="d-flex flex-row align-items-start">
<div className="h5 mb-1">
{!isNull(props.member.firstName) || !isNull(props.member.lastName)
? getFullName()
: props.member.alias}
</div>
</Modal>
)}
<div className="ml-auto">
<div
ref={dropdownMenu}
className={classnames('dropdown-menu dropdown-menu-right p-0', styles.dropdownMenu, {
show: dropdownMenuStatus,
})}
>
<div className={`arrow ${styles.arrow}`} />
{isUser ? (
<button
data-testid="leaveOrRemoveModalBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setModalStatus(true);
}}
>
<div className="d-flex flex-row align-items-center">
<FaSignOutAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Leave</span>
</div>
</button>
) : (
<ActionBtn
testId="leaveOrRemoveModalBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setModalStatus(true);
}}
action={AuthorizerAction.DeleteOrganizationMember}
>
<>
<FaUserMinus className={`mr-2 ${styles.btnIcon}`} />
<span>Remove</span>
</>
</ActionBtn>
{!isUndefined(props.member.confirmed) && !props.member.confirmed && (
<div className={classnames('ml-3', { 'mr-3': props.membersNumber > 1 })}>
<small>
<span className="badge badge-warning">Invitation not accepted yet</span>
</small>
</div>
)}
</div>
<button
className={`btn btn-light p-0 text-secondary text-center ${styles.btnDropdown}`}
onClick={() => setDropdownMenuStatus(true)}
>
<BsThreeDotsVertical />
</button>
<div className="h6 text-muted mr-1 font-italic">{props.member.alias}</div>
</div>
</>
)}
{props.membersNumber > 1 && (
<>
{modalStatus && (
<Modal
className={`d-inline-block ${styles.modal}`}
closeButton={
<>
<button
className={`btn btn-sm btn-light text-uppercase ${styles.btnLight}`}
onClick={() => setModalStatus(false)}
>
<div className="d-flex flex-row align-items-center">
<IoMdCloseCircle className="mr-2" />
<span>Cancel</span>
</div>
</button>
<button
data-testid="leaveOrRemoveBtn"
className="btn btn-sm btn-danger ml-3"
onClick={(e) => {
e.preventDefault();
deleteMember();
}}
disabled={isDeletingMember}
>
<div className="d-flex flex-row align-items-center text-uppercase">
{isDeletingMember ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="ml-2">{isUser ? 'Leaving...' : 'Removing...'}</span>
</>
) : (
<>
{isUser ? (
<FaSignOutAlt className={`mr-2 ${styles.btnIcon}`} />
) : (
<FaUserMinus className={`mr-2 ${styles.btnIcon}`} />
)}
<span>{isUser ? 'Leave' : 'Remove'}</span>
</>
)}
</div>
</button>
</>
}
header={
<div className={`h3 m-2 ${styles.title}`}>{isUser ? 'Leave ' : 'Remove from '} organization</div>
}
onClose={() => setModalStatus(false)}
open
>
<div className="mt-3 mw-100 text-center">
<p>
{isUser
? 'Are you sure you want to leave this organization?'
: 'Are you sure you want to remove this member from this organization?'}
</p>
</div>
</Modal>
)}
<div className="ml-auto">
<div
ref={dropdownMenu}
className={classnames('dropdown-menu dropdown-menu-right p-0', styles.dropdownMenu, {
show: dropdownMenuStatus,
})}
>
<div className={`arrow ${styles.arrow}`} />
{isUser ? (
<button
data-testid="leaveOrRemoveModalBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setModalStatus(true);
}}
>
<div className="d-flex flex-row align-items-center">
<FaSignOutAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Leave</span>
</div>
</button>
) : (
<ActionBtn
testId="leaveOrRemoveModalBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setModalStatus(true);
}}
action={AuthorizerAction.DeleteOrganizationMember}
>
<>
<FaUserMinus className={`mr-2 ${styles.btnIcon}`} />
<span>Remove</span>
</>
</ActionBtn>
)}
</div>
<button
className={`btn btn-light p-0 text-secondary text-center ${styles.btnDropdown}`}
onClick={() => setDropdownMenuStatus(true)}
>
<BsThreeDotsVertical />
</button>
</div>
</>
)}
</div>
</div>
</div>
</li>
</div>
);
};

View File

@ -28,7 +28,7 @@ const mockCtx = {
controlPanel: {
selectedOrg: 'orgTest',
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -2,111 +2,119 @@
exports[`Member Card - members section creates snapshot 1`] = `
<DocumentFragment>
<li
class="list-group-item listItem"
<div
class="col-12 col-xxl-6 py-sm-3 py-2"
data-testid="memberCard"
>
<div
class="d-flex flex-row w-100 justify-content-between align-items-start"
class="card h-100"
>
<div
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
<svg
class="image"
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>
<div
class="flex-grow-1"
class="card-body d-flex flex-column h-100"
>
<div
class="d-flex flex-row align-items-start"
class="d-flex flex-row w-100 justify-content-between align-items-start"
>
<div
class="h5 mb-1"
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
first last
<svg
class="image"
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>
</div>
<div
class="h6 text-muted mr-1 font-italic"
>
test
</div>
</div>
<div
class="ml-auto"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<span
class="position-relative"
class="flex-grow-1"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="leaveOrRemoveModalBtn"
type="button"
<div
class="d-flex flex-row align-items-start"
>
<div
class="d-flex flex-row align-items-center undefined"
class="h5 mb-1"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 640 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M624 208H432c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h192c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm-400 48c70.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>
<span>
Remove
</span>
first last
</div>
</button>
</span>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
</div>
<div
class="h6 text-muted mr-1 font-italic"
>
test
</div>
</div>
<div
class="ml-auto"
>
<path
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
</button>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="leaveOrRemoveModalBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 640 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M624 208H432c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h192c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm-400 48c70.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>
<span>
Remove
</span>
</div>
</button>
</span>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
</button>
</div>
</div>
</div>
</div>
</li>
</div>
</DocumentFragment>
`;

View File

@ -88,7 +88,7 @@ exports[`Members section index creates snapshot 1`] = `
</div>
</div>
<div
class="mt-4"
class="mt-5"
/>
</div>
</main>
@ -165,218 +165,234 @@ exports[`Members section index creates snapshot 2`] = `
</div>
</div>
<div
class="mt-4"
class="mt-5"
>
<div
class="list-group mt-4 mt-md-5"
class="row mt-4 mt-md-5"
>
<li
class="list-group-item listItem"
<div
class="col-12 col-xxl-6 py-sm-3 py-2"
data-testid="memberCard"
>
<div
class="d-flex flex-row w-100 justify-content-between align-items-start"
class="card h-100"
>
<div
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
<svg
class="image"
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>
<div
class="flex-grow-1"
class="card-body d-flex flex-column h-100"
>
<div
class="d-flex flex-row align-items-start"
class="d-flex flex-row w-100 justify-content-between align-items-start"
>
<div
class="h5 mb-1"
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
Test 1
<svg
class="image"
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>
</div>
<div
class="h6 text-muted mr-1 font-italic"
>
test
</div>
</div>
<div
class="ml-auto"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="leaveOrRemoveModalBtn"
class="flex-grow-1"
>
<div
class="d-flex flex-row align-items-center"
class="d-flex flex-row align-items-start"
>
<div
class="h5 mb-1"
>
Test 1
</div>
</div>
<div
class="h6 text-muted mr-1 font-italic"
>
test
</div>
</div>
<div
class="ml-auto"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="leaveOrRemoveModalBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z"
/>
</svg>
<span>
Leave
</span>
</div>
</button>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z"
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
<span>
Leave
</span>
</div>
</button>
</button>
</div>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
</button>
</div>
</div>
</li>
<li
class="list-group-item listItem"
</div>
<div
class="col-12 col-xxl-6 py-sm-3 py-2"
data-testid="memberCard"
>
<div
class="d-flex flex-row w-100 justify-content-between align-items-start"
class="card h-100"
>
<div
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
<svg
class="image"
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>
<div
class="flex-grow-1"
class="card-body d-flex flex-column h-100"
>
<div
class="d-flex flex-row align-items-start"
class="d-flex flex-row w-100 justify-content-between align-items-start"
>
<div
class="h5 mb-1"
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
Test 2
<svg
class="image"
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>
</div>
<div
class="h6 text-muted mr-1 font-italic"
>
test1
</div>
</div>
<div
class="ml-auto"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<span
class="position-relative"
class="flex-grow-1"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="leaveOrRemoveModalBtn"
type="button"
<div
class="d-flex flex-row align-items-start"
>
<div
class="d-flex flex-row align-items-center undefined"
class="h5 mb-1"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 640 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M624 208H432c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h192c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm-400 48c70.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>
<span>
Remove
</span>
Test 2
</div>
</button>
</span>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
</div>
<div
class="h6 text-muted mr-1 font-italic"
>
test1
</div>
</div>
<div
class="ml-auto"
>
<path
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
</button>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="leaveOrRemoveModalBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 640 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M624 208H432c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h192c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm-400 48c70.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>
<span>
Remove
</span>
</div>
</button>
</span>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
</button>
</div>
</div>
</div>
</div>
</li>
</div>
</div>
</div>
</div>

View File

@ -31,7 +31,7 @@ const mockCtx = {
controlPanel: {
selectedOrg: 'orgTest',
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -84,7 +84,7 @@ const MembersSection = (props: Props) => {
{(isGettingMembers || isUndefined(members)) && <Loading />}
<div className="mt-4">
<div className="mt-5">
{!isUndefined(members) && (
<>
{members.length === 0 ? (
@ -110,7 +110,7 @@ const MembersSection = (props: Props) => {
)}
</NoData>
) : (
<div className="list-group mt-4 mt-md-5">
<div className="row mt-4 mt-md-5">
{members.map((member: Member) => (
<MemberCard
key={`member_${member.alias}`}

View File

@ -1,8 +1,3 @@
.listItem {
border-width: 2px;
padding: 1.25rem;
}
.btnIcon {
font-size: 0.65rem;
}

View File

@ -23,7 +23,7 @@ const mockCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -92,173 +92,177 @@ const OrganizationCard = (props: Props) => {
props.organization.membersCount > 1));
return (
<li className={`list-group-item ${styles.listItem}`} data-testid="organizationCard">
<div className="d-flex flex-row w-100 justify-content-between align-items-start">
<div className="d-flex flex-row align-items-center w-100">
<div
className={`d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 ${styles.imageWrapper} imageWrapper`}
>
{!isUndefined(props.organization.logoImageId) ? (
<Image
alt={props.organization.displayName || props.organization.name}
imageId={props.organization.logoImageId}
className={styles.image}
placeholderIcon={<MdBusiness />}
/>
) : (
<MdBusiness className={styles.image} />
<div className="col-12 col-xxl-6 py-sm-3 py-2" data-testid="organizationCard">
<div className="card h-100">
<div className="card-body d-flex flex-column h-100">
<div className="d-flex flex-row w-100 justify-content-between align-items-start">
<div className="d-flex flex-row align-items-center w-100">
<div
className={`d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 ${styles.imageWrapper} imageWrapper`}
>
{!isUndefined(props.organization.logoImageId) ? (
<Image
alt={props.organization.displayName || props.organization.name}
imageId={props.organization.logoImageId}
className={styles.image}
placeholderIcon={<MdBusiness />}
/>
) : (
<MdBusiness className={styles.image} />
)}
</div>
<div className="flex-grow-1 text-truncate">
<div className={`h5 mb-0 text-truncate ${styles.title}`}>
{props.organization.displayName || props.organization.name}
</div>
</div>
{!isMember && (
<div className="ml-3">
<span className="badge badge-warning">Invitation not accepted yet</span>
</div>
)}
<div className="ml-auto">
<div
ref={dropdownMenu}
className={classnames('dropdown-menu dropdown-menu-right p-0', styles.dropdownMenu, {
show: dropdownMenuStatus,
})}
>
<div className={`arrow ${styles.arrow}`} />
{!isUndefined(props.organization.confirmed) &&
!isNull(props.organization.confirmed) &&
props.organization.confirmed ? (
<>
{isMember && props.organization.membersCount && props.organization.membersCount > 1 && (
<button
data-testid="leaveOrgModalBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setLeaveModalStatus(true);
}}
>
<div className="d-flex flex-row align-items-center">
<FaSignOutAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Leave</span>
</div>
</button>
)}
</>
) : (
<div>
<button
data-testid="acceptInvitationBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
confirmOrganizationMembership();
closeDropdown();
}}
disabled={isAccepting}
>
<div className="d-flex flex-row align-items-center">
{isAccepting ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="ml-2">Accepting invitation...</span>
</>
) : (
<>
<FaEnvelopeOpenText className={`mr-2 ${styles.btnIcon}`} />
<span>Accept invitation</span>
</>
)}
</div>
</button>
</div>
)}
</div>
{hasDropdownContent && (
<button
className={`ml-3 btn btn-light p-0 text-secondary text-center ${styles.btnDropdown}`}
onClick={() => setDropdownMenuStatus(true)}
>
<BsThreeDotsVertical />
</button>
)}
</div>
</div>
{leaveModalStatus && (
<Modal
className={`d-inline-block ${styles.modal}`}
closeButton={
<>
<button
className={`btn btn-sm btn-light text-uppercase ${styles.btnLight}`}
onClick={() => setLeaveModalStatus(false)}
>
<div className="d-flex flex-row align-items-center">
<IoMdCloseCircle className="mr-2" />
<span>Cancel</span>
</div>
</button>
<button
data-testid="leaveOrgBtn"
className="btn btn-sm btn-danger ml-3"
onClick={(e) => {
e.preventDefault();
leaveOrganization();
}}
disabled={isLeaving}
>
<div className="d-flex flex-row align-items-center text-uppercase">
{isLeaving ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="ml-2">Leaving...</span>
</>
) : (
<>
<FaSignOutAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Leave</span>
</>
)}
</div>
</button>
</>
}
header={<div className={`h3 m-2 ${styles.title}`}>Leave organization</div>}
onClose={() => setLeaveModalStatus(false)}
open
>
<div className="mt-3 mw-100 text-center">
<p>Are you sure you want to leave this organization?</p>
</div>
</Modal>
)}
</div>
<div className="flex-grow-1 text-truncate">
<div className={`h5 mb-0 text-truncate ${styles.title}`}>
{props.organization.displayName || props.organization.name}
</div>
</div>
{!isMember && (
<div className="ml-3">
<span className="badge badge-warning">Invitation not accepted yet</span>
{!isUndefined(props.organization.homeUrl) && !isNull(props.organization.homeUrl) && (
<div className="mt-3 text-truncate">
<small className="text-muted text-uppercase mr-1">Homepage: </small>
<ExternalLink href={props.organization.homeUrl} className={`text-reset ${styles.link}`}>
{props.organization.homeUrl}
</ExternalLink>
</div>
)}
<div className="ml-auto">
<div
ref={dropdownMenu}
className={classnames('dropdown-menu dropdown-menu-right p-0', styles.dropdownMenu, {
show: dropdownMenuStatus,
})}
>
<div className={`arrow ${styles.arrow}`} />
{!isUndefined(props.organization.confirmed) &&
!isNull(props.organization.confirmed) &&
props.organization.confirmed ? (
<>
{isMember && props.organization.membersCount && props.organization.membersCount > 1 && (
<button
data-testid="leaveOrgModalBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setLeaveModalStatus(true);
}}
>
<div className="d-flex flex-row align-items-center">
<FaSignOutAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Leave</span>
</div>
</button>
)}
</>
) : (
<div>
<button
data-testid="acceptInvitationBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
confirmOrganizationMembership();
closeDropdown();
}}
disabled={isAccepting}
>
<div className="d-flex flex-row align-items-center">
{isAccepting ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="ml-2">Accepting invitation...</span>
</>
) : (
<>
<FaEnvelopeOpenText className={`mr-2 ${styles.btnIcon}`} />
<span>Accept invitation</span>
</>
)}
</div>
</button>
</div>
)}
{!isUndefined(props.organization.description) && !isNull(props.organization.description) && (
<div className="mt-2">
<p className="mb-0">{props.organization.description}</p>
</div>
{hasDropdownContent && (
<button
className={`ml-3 btn btn-light p-0 text-secondary text-center ${styles.btnDropdown}`}
onClick={() => setDropdownMenuStatus(true)}
>
<BsThreeDotsVertical />
</button>
)}
</div>
)}
</div>
{leaveModalStatus && (
<Modal
className={`d-inline-block ${styles.modal}`}
closeButton={
<>
<button
className={`btn btn-sm btn-light text-uppercase ${styles.btnLight}`}
onClick={() => setLeaveModalStatus(false)}
>
<div className="d-flex flex-row align-items-center">
<IoMdCloseCircle className="mr-2" />
<span>Cancel</span>
</div>
</button>
<button
data-testid="leaveOrgBtn"
className="btn btn-sm btn-danger ml-3"
onClick={(e) => {
e.preventDefault();
leaveOrganization();
}}
disabled={isLeaving}
>
<div className="d-flex flex-row align-items-center text-uppercase">
{isLeaving ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="ml-2">Leaving...</span>
</>
) : (
<>
<FaSignOutAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Leave</span>
</>
)}
</div>
</button>
</>
}
header={<div className={`h3 m-2 ${styles.title}`}>Leave organization</div>}
onClose={() => setLeaveModalStatus(false)}
open
>
<div className="mt-3 mw-100 text-center">
<p>Are you sure you want to leave this organization?</p>
</div>
</Modal>
)}
</div>
{!isUndefined(props.organization.homeUrl) && !isNull(props.organization.homeUrl) && (
<div className="mt-3 text-truncate">
<small className="text-muted text-uppercase mr-1">Homepage: </small>
<ExternalLink href={props.organization.homeUrl} className={`text-reset ${styles.link}`}>
{props.organization.homeUrl}
</ExternalLink>
</div>
)}
{!isUndefined(props.organization.description) && !isNull(props.organization.description) && (
<div className="mt-2">
<p className="mb-0">{props.organization.description}</p>
</div>
)}
</li>
</div>
);
};

View File

@ -36,7 +36,7 @@ const mockCtx = {
controlPanel: {
selectedOrg: 'orgTest',
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -2,128 +2,136 @@
exports[`Organization Card - organization section creates snapshot 1`] = `
<DocumentFragment>
<li
class="list-group-item listItem"
<div
class="col-12 col-xxl-6 py-sm-3 py-2"
data-testid="organizationCard"
>
<div
class="d-flex flex-row w-100 justify-content-between align-items-start"
class="card h-100"
>
<div
class="d-flex flex-row align-items-center w-100"
class="card-body d-flex flex-column h-100"
>
<div
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
<svg
class="image"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"
/>
</svg>
</div>
<div
class="flex-grow-1 text-truncate"
class="d-flex flex-row w-100 justify-content-between align-items-start"
>
<div
class="h5 mb-0 text-truncate title"
>
Test
</div>
</div>
<div
class="ml-auto"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
class="d-flex flex-row align-items-center w-100"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="leaveOrgModalBtn"
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
<svg
class="image"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"
/>
</svg>
</div>
<div
class="flex-grow-1 text-truncate"
>
<div
class="d-flex flex-row align-items-center"
class="h5 mb-0 text-truncate title"
>
Test
</div>
</div>
<div
class="ml-auto"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="leaveOrgModalBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z"
/>
</svg>
<span>
Leave
</span>
</div>
</button>
</div>
<button
class="ml-3 btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497 273L329 441c-15 15-41 4.5-41-17v-96H152c-13.3 0-24-10.7-24-24v-96c0-13.3 10.7-24 24-24h136V88c0-21.4 25.9-32 41-17l168 168c9.3 9.4 9.3 24.6 0 34zM192 436v-40c0-6.6-5.4-12-12-12H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h84c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12H96c-53 0-96 43-96 96v192c0 53 43 96 96 96h84c6.6 0 12-5.4 12-12z"
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
<span>
Leave
</span>
</div>
</button>
</button>
</div>
</div>
<button
class="ml-3 btn btn-light p-0 text-secondary text-center btnDropdown"
</div>
<div
class="mt-3 text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
</button>
Homepage:
</small>
<a
class="link text-reset link"
href="https://test.org"
rel="noopener noreferrer"
role="button"
target="_blank"
>
https://test.org
</a>
</div>
<div
class="mt-2"
>
<p
class="mb-0"
>
Lorem ipsum...
</p>
</div>
</div>
</div>
<div
class="mt-3 text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
Homepage:
</small>
<a
class="link text-reset link"
href="https://test.org"
rel="noopener noreferrer"
role="button"
target="_blank"
>
https://test.org
</a>
</div>
<div
class="mt-2"
>
<p
class="mb-0"
>
Lorem ipsum...
</p>
</div>
</li>
</div>
</DocumentFragment>
`;

View File

@ -224,164 +224,180 @@ exports[`Organizations section index creates snapshot 2`] = `
</div>
</div>
<div
class="list-group mt-4 mt-md-5"
class="row mt-4 mt-md-5"
>
<li
class="list-group-item listItem"
<div
class="col-12 col-xxl-6 py-sm-3 py-2"
data-testid="organizationCard"
>
<div
class="d-flex flex-row w-100 justify-content-between align-items-start"
class="card h-100"
>
<div
class="d-flex flex-row align-items-center w-100"
class="card-body d-flex flex-column h-100"
>
<div
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
<svg
class="image"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"
/>
</svg>
</div>
<div
class="flex-grow-1 text-truncate"
class="d-flex flex-row w-100 justify-content-between align-items-start"
>
<div
class="h5 mb-0 text-truncate title"
>
Test
</div>
</div>
<div
class="ml-auto"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
class="d-flex flex-row align-items-center w-100"
>
<div
class="arrow arrow"
/>
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
<svg
class="image"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"
/>
</svg>
</div>
<div
class="flex-grow-1 text-truncate"
>
<div
class="h5 mb-0 text-truncate title"
>
Test
</div>
</div>
<div
class="ml-auto"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
</div>
</div>
</div>
</div>
<div
class="mt-3 text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
Homepage:
</small>
<a
class="link text-reset link"
href="https://test.org"
rel="noopener noreferrer"
role="button"
target="_blank"
>
https://test.org
</a>
</div>
<div
class="mt-2"
>
<p
class="mb-0"
>
Lorem ipsum...
</p>
</div>
</div>
</div>
<div
class="mt-3 text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
Homepage:
</small>
<a
class="link text-reset link"
href="https://test.org"
rel="noopener noreferrer"
role="button"
target="_blank"
>
https://test.org
</a>
</div>
<div
class="mt-2"
>
<p
class="mb-0"
>
Lorem ipsum...
</p>
</div>
</li>
<li
class="list-group-item listItem"
</div>
<div
class="col-12 col-xxl-6 py-sm-3 py-2"
data-testid="organizationCard"
>
<div
class="d-flex flex-row w-100 justify-content-between align-items-start"
class="card h-100"
>
<div
class="d-flex flex-row align-items-center w-100"
class="card-body d-flex flex-column h-100"
>
<div
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
<svg
class="image"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"
/>
</svg>
</div>
<div
class="flex-grow-1 text-truncate"
class="d-flex flex-row w-100 justify-content-between align-items-start"
>
<div
class="h5 mb-0 text-truncate title"
>
Helm
</div>
</div>
<div
class="ml-auto"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
class="d-flex flex-row align-items-center w-100"
>
<div
class="arrow arrow"
/>
class="d-flex align-items-center justify-content-center p-1 overflow-hidden mr-2 imageWrapper imageWrapper"
>
<svg
class="image"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"
/>
</svg>
</div>
<div
class="flex-grow-1 text-truncate"
>
<div
class="h5 mb-0 text-truncate title"
>
Helm
</div>
</div>
<div
class="ml-auto"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
</div>
</div>
</div>
</div>
<div
class="mt-3 text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
Homepage:
</small>
<a
class="link text-reset link"
href="https://helm.sh"
rel="noopener noreferrer"
role="button"
target="_blank"
>
https://helm.sh
</a>
</div>
<div
class="mt-2"
>
<p
class="mb-0"
>
The package manager for Kubernetes
</p>
</div>
</div>
</div>
<div
class="mt-3 text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
Homepage:
</small>
<a
class="link text-reset link"
href="https://helm.sh"
rel="noopener noreferrer"
role="button"
target="_blank"
>
https://helm.sh
</a>
</div>
<div
class="mt-2"
>
<p
class="mb-0"
>
The package manager for Kubernetes
</p>
</div>
</li>
</div>
</div>
</div>
</div>

View File

@ -23,7 +23,7 @@ const mockCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -98,7 +98,7 @@ const OrganizationsSection = (props: Props) => {
)}
</NoData>
) : (
<div className="list-group mt-4 mt-md-5">
<div className="row mt-4 mt-md-5">
{organizations.map((org: Organization) => (
<OrganizationCard
key={`org_${org.name}`}

View File

@ -1,8 +1,3 @@
.listItem {
border-width: 2px;
padding: 1.25rem;
}
.labelWrapper {
margin-top: 4px;
}

View File

@ -48,7 +48,7 @@ const mockCtx = {
user: { alias: 'test', email: 'test@test.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -177,217 +177,222 @@ const RepositoryCard = (props: Props) => {
}
return (
<li className={`list-group-item ${styles.listItem}`} data-testid="repoCard">
<div className="d-flex flex-row w-100 justify-content-between">
<div className="d-flex flex-row align-items-center mb-1 text-truncate">
<div className={`h5 mb-0 mr-3 text-truncate ${styles.titleCard}`}>
{props.repository.displayName || props.repository.name}
</div>
<OfficialBadge
official={props.repository.official}
className={`ml-3 d-none d-md-inline ${styles.labelWrapper}`}
/>
<VerifiedPublisherBadge
verifiedPublisher={props.repository.verifiedPublisher}
className={`ml-3 d-none d-md-inline ${styles.labelWrapper}`}
/>
</div>
{transferModalStatus && (
<TransferRepositoryModal
open={true}
repository={props.repository}
onSuccess={props.onSuccess}
onAuthError={props.onAuthError}
onClose={() => setTransferModalStatus(false)}
/>
)}
{deletionModalStatus && (
<Modal
className={`d-inline-block ${styles.modal}`}
closeButton={
<>
<button
className={`btn btn-sm btn-light text-uppercase ${styles.btnLight}`}
onClick={() => setDeletionModalStatus(false)}
>
<div className="d-flex flex-row align-items-center">
<IoMdCloseCircle className="mr-2" />
<span>Cancel</span>
</div>
</button>
<button
data-testid="deleteRepoBtn"
className="btn btn-sm btn-danger ml-3"
onClick={(e) => {
e.preventDefault();
deleteRepository();
}}
disabled={isDeleting}
>
<div className="d-flex flex-row align-items-center text-uppercase">
{isDeleting ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="ml-2">Deleting...</span>
</>
) : (
<>
<FaTrashAlt className={`mr-2 ${styles.Icon}`} />
<span>Delete</span>
</>
)}
</div>
</button>
</>
}
header={<div className={`h3 m-2 ${styles.title}`}>Delete repository</div>}
onClose={() => setDeletionModalStatus(false)}
open
>
<div className="mt-3 mw-100 text-center">
<p>If you delete this repository all packages belonging to it will be deleted.</p>
<p>
Please note that some other items which depend on your repository, like users subscriptions to packages,
will be deleted as well. <span className="font-weight-bold">This operation cannot be undone</span>.
</p>
</div>
</Modal>
)}
{badgeModalStatus && (
<BadgeModal
repository={props.repository}
onClose={() => setBadgeModalStatus(false)}
open={badgeModalStatus}
/>
)}
<div className="ml-auto">
<RepositoryIcon kind={props.repository.kind} className={styles.kindIcon} />
</div>
<div className="ml-3">
<div
ref={dropdownMenu}
className={classnames('dropdown-menu dropdown-menu-right p-0', styles.dropdownMenu, {
show: dropdownMenuStatus,
})}
>
<div className={`arrow ${styles.arrow}`} />
<button
data-testid="getBadgeBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setBadgeModalStatus(true);
}}
>
<div className="d-flex flex-row align-items-center">
<MdLabel className={`mr-2 ${styles.btnIcon}`} />
<span>Get badge</span>
<div className="col-12 col-xxl-6 py-sm-3 py-2" data-testid="repoCard">
<div className="card h-100">
<div className="card-body d-flex flex-column h-100">
<div className="d-flex flex-row w-100 justify-content-between">
<div className="d-flex flex-row align-items-center mb-1 text-truncate">
<div className={`h5 mb-0 mr-3 text-truncate ${styles.titleCard}`}>
{props.repository.displayName || props.repository.name}
</div>
</button>
<ActionBtn
testId="transferRepoBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setTransferModalStatus(true);
}}
action={AuthorizerAction.TransferOrganizationRepository}
>
<>
<RiArrowLeftRightLine className={`mr-2 ${styles.btnIcon}`} />
<span>Transfer</span>
</>
</ActionBtn>
<OfficialBadge
official={props.repository.official}
className={`ml-3 d-none d-md-inline ${styles.labelWrapper}`}
/>
<ActionBtn
testId="updateRepoBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
props.setModalStatus({
open: true,
repository: props.repository,
});
}}
action={AuthorizerAction.UpdateOrganizationRepository}
>
<>
<FaPencilAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Edit</span>
</>
</ActionBtn>
<ActionBtn
testId="deleteRepoDropdownBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setDeletionModalStatus(true);
}}
action={AuthorizerAction.DeleteOrganizationRepository}
>
<>
<FaTrashAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Delete</span>
</>
</ActionBtn>
</div>
<button
className={`btn btn-light p-0 text-secondary text-center ${styles.btnDropdown}`}
onClick={() => setDropdownMenuStatus(true)}
>
<BsThreeDotsVertical />
</button>
</div>
</div>
{!isUndefined(props.repository.repositoryId) && (
<div className="mt-2 d-flex flex-row align-items-baseline">
<div className="text-truncate">
<small className="text-muted text-uppercase mr-1">ID: </small>
<small>{props.repository.repositoryId}</small>
</div>
<div className={`ml-1 ${styles.copyBtn}`}>
<div className={`position-absolute ${styles.copyBtnWrapper}`}>
<ButtonCopyToClipboard
text={props.repository.repositoryId}
className="btn-link border-0 text-secondary font-weight-bold"
<VerifiedPublisherBadge
verifiedPublisher={props.repository.verifiedPublisher}
className={`ml-3 d-none d-md-inline ${styles.labelWrapper}`}
/>
</div>
{transferModalStatus && (
<TransferRepositoryModal
open={true}
repository={props.repository}
onSuccess={props.onSuccess}
onAuthError={props.onAuthError}
onClose={() => setTransferModalStatus(false)}
/>
)}
{deletionModalStatus && (
<Modal
className={`d-inline-block ${styles.modal}`}
closeButton={
<>
<button
className={`btn btn-sm btn-light text-uppercase ${styles.btnLight}`}
onClick={() => setDeletionModalStatus(false)}
>
<div className="d-flex flex-row align-items-center">
<IoMdCloseCircle className="mr-2" />
<span>Cancel</span>
</div>
</button>
<button
data-testid="deleteRepoBtn"
className="btn btn-sm btn-danger ml-3"
onClick={(e) => {
e.preventDefault();
deleteRepository();
}}
disabled={isDeleting}
>
<div className="d-flex flex-row align-items-center text-uppercase">
{isDeleting ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="ml-2">Deleting...</span>
</>
) : (
<>
<FaTrashAlt className={`mr-2 ${styles.Icon}`} />
<span>Delete</span>
</>
)}
</div>
</button>
</>
}
header={<div className={`h3 m-2 ${styles.title}`}>Delete repository</div>}
onClose={() => setDeletionModalStatus(false)}
open
>
<div className="mt-3 mw-100 text-center">
<p>If you delete this repository all packages belonging to it will be deleted.</p>
<p>
Please note that some other items which depend on your repository, like users subscriptions to
packages, will be deleted as well.{' '}
<span className="font-weight-bold">This operation cannot be undone</span>.
</p>
</div>
</Modal>
)}
{badgeModalStatus && (
<BadgeModal
repository={props.repository}
onClose={() => setBadgeModalStatus(false)}
open={badgeModalStatus}
/>
)}
<div className="ml-auto">
<RepositoryIcon kind={props.repository.kind} className={styles.kindIcon} />
</div>
<div className="ml-3">
<div
ref={dropdownMenu}
className={classnames('dropdown-menu dropdown-menu-right p-0', styles.dropdownMenu, {
show: dropdownMenuStatus,
})}
>
<div className={`arrow ${styles.arrow}`} />
<button
data-testid="getBadgeBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setBadgeModalStatus(true);
}}
>
<div className="d-flex flex-row align-items-center">
<MdLabel className={`mr-2 ${styles.btnIcon}`} />
<span>Get badge</span>
</div>
</button>
<ActionBtn
testId="transferRepoBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setTransferModalStatus(true);
}}
action={AuthorizerAction.TransferOrganizationRepository}
>
<>
<RiArrowLeftRightLine className={`mr-2 ${styles.btnIcon}`} />
<span>Transfer</span>
</>
</ActionBtn>
<ActionBtn
testId="updateRepoBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
props.setModalStatus({
open: true,
repository: props.repository,
});
}}
action={AuthorizerAction.UpdateOrganizationRepository}
>
<>
<FaPencilAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Edit</span>
</>
</ActionBtn>
<ActionBtn
testId="deleteRepoDropdownBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setDeletionModalStatus(true);
}}
action={AuthorizerAction.DeleteOrganizationRepository}
>
<>
<FaTrashAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Delete</span>
</>
</ActionBtn>
</div>
<button
className={`btn btn-light p-0 text-secondary text-center ${styles.btnDropdown}`}
onClick={() => setDropdownMenuStatus(true)}
>
<BsThreeDotsVertical />
</button>
</div>
</div>
{!isUndefined(props.repository.repositoryId) && (
<div className="mt-2 d-flex flex-row align-items-baseline">
<div className="text-truncate">
<small className="text-muted text-uppercase mr-1">ID: </small>
<small>{props.repository.repositoryId}</small>
</div>
<div className={`ml-1 ${styles.copyBtn}`}>
<div className={`position-absolute ${styles.copyBtnWrapper}`}>
<ButtonCopyToClipboard
text={props.repository.repositoryId}
className="btn-link border-0 text-secondary font-weight-bold"
/>
</div>
</div>
</div>
)}
<div className="text-truncate">
<small className="text-muted text-uppercase mr-1">Url: </small>
<small>{props.repository.url}</small>
</div>
{!isUndefined(props.repository.lastTrackingTs) && (
<div>
<small className="text-muted text-uppercase mr-1">Last processed: </small>
<small>{getLastTracking()}</small>
</div>
)}
<div className="mt-3 m-md-0 d-flex flex-row d-md-none">
<OfficialBadge official={props.repository.official} className="mr-3" />
<VerifiedPublisherBadge verifiedPublisher={props.repository.verifiedPublisher} />
</div>
</div>
)}
<div className="text-truncate">
<small className="text-muted text-uppercase mr-1">Url: </small>
<small>{props.repository.url}</small>
</div>
{!isUndefined(props.repository.lastTrackingTs) && (
<div>
<small className="text-muted text-uppercase mr-1">Last processed: </small>
<small>{getLastTracking()}</small>
</div>
)}
<div className="mt-3 m-md-0 d-flex flex-row d-md-none">
<OfficialBadge official={props.repository.official} className="mr-3" />
<VerifiedPublisherBadge verifiedPublisher={props.repository.verifiedPublisher} />
</div>
</li>
</div>
);
};

View File

@ -27,7 +27,7 @@ const mockWithoutSelectedOrgCtx = {
controlPanel: {
selectedOrg: undefined,
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -41,7 +41,7 @@ const mockWithSelectedOrgCtx = {
controlPanel: {
selectedOrg: 'orgTest',
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -36,7 +36,7 @@ const mockCtx = {
controlPanel: {
selectedOrg: 'orgTest',
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -36,7 +36,7 @@ const mockWithoutSelectedOrgCtx = {
controlPanel: {
selectedOrg: undefined,
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -50,7 +50,7 @@ const mockWithSelectedOrgCtx = {
controlPanel: {
selectedOrg: 'orgTest',
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -2,212 +2,220 @@
exports[`Repository Card - packages section creates snapshot 1`] = `
<DocumentFragment>
<li
class="list-group-item listItem"
<div
class="col-12 col-xxl-6 py-sm-3 py-2"
data-testid="repoCard"
>
<div
class="d-flex flex-row w-100 justify-content-between"
class="card h-100"
>
<div
class="d-flex flex-row align-items-center mb-1 text-truncate"
class="card-body d-flex flex-column h-100"
>
<div
class="h5 mb-0 mr-3 text-truncate titleCard"
>
Repo test
</div>
</div>
<div
class="ml-auto"
>
<img
alt="Icon"
class="kindIcon repoIcon"
src="/static/media/helm-chart.svg"
/>
</div>
<div
class="ml-3"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
class="d-flex flex-row w-100 justify-content-between"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="getBadgeBtn"
class="d-flex flex-row align-items-center mb-1 text-truncate"
>
<div
class="d-flex flex-row align-items-center"
class="h5 mb-0 mr-3 text-truncate titleCard"
>
Repo test
</div>
</div>
<div
class="ml-auto"
>
<img
alt="Icon"
class="kindIcon repoIcon"
src="/static/media/helm-chart.svg"
/>
</div>
<div
class="ml-3"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="getBadgeBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z"
/>
</svg>
<span>
Get badge
</span>
</div>
</button>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="transferRepoBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M0 0h24v24H0z"
fill="none"
/>
<path
d="M16.05 12.05L21 17l-4.95 4.95-1.414-1.414 2.536-2.537L4 18v-2h13.172l-2.536-2.536 1.414-1.414zm-8.1-10l1.414 1.414L6.828 6 20 6v2H6.828l2.536 2.536L7.95 11.95 3 7l4.95-4.95z"
/>
</g>
</svg>
<span>
Transfer
</span>
</div>
</button>
</span>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="updateRepoBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
/>
</svg>
<span>
Edit
</span>
</div>
</button>
</span>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="deleteRepoDropdownBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
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="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"
/>
</svg>
<span>
Delete
</span>
</div>
</button>
</span>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z"
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
<span>
Get badge
</span>
</div>
</button>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="transferRepoBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M0 0h24v24H0z"
fill="none"
/>
<path
d="M16.05 12.05L21 17l-4.95 4.95-1.414-1.414 2.536-2.537L4 18v-2h13.172l-2.536-2.536 1.414-1.414zm-8.1-10l1.414 1.414L6.828 6 20 6v2H6.828l2.536 2.536L7.95 11.95 3 7l4.95-4.95z"
/>
</g>
</svg>
<span>
Transfer
</span>
</div>
</button>
</span>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="updateRepoBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
/>
</svg>
<span>
Edit
</span>
</div>
</button>
</span>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="deleteRepoDropdownBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
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="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"
/>
</svg>
<span>
Delete
</span>
</div>
</button>
</span>
</div>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
<div
class="text-truncate"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
<small
class="text-muted text-uppercase mr-1"
>
<path
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
</button>
Url:
</small>
<small>
http://test.repo
</small>
</div>
<div>
<small
class="text-muted text-uppercase mr-1"
>
Last processed:
</small>
<small>
Not processed yet, it will be processed automatically in ~ 3 minutes
</small>
</div>
<div
class="mt-3 m-md-0 d-flex flex-row d-md-none"
/>
</div>
</div>
<div
class="text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
Url:
</small>
<small>
http://test.repo
</small>
</div>
<div>
<small
class="text-muted text-uppercase mr-1"
>
Last processed:
</small>
<small>
Not processed yet, it will be processed automatically in ~ 3 minutes
</small>
</div>
<div
class="mt-3 m-md-0 d-flex flex-row d-md-none"
/>
</li>
</div>
</DocumentFragment>
`;

View File

@ -360,277 +360,285 @@ exports[`Repository index creates snapshot 2`] = `
to each of them including the repository ID provided below. This label will let users know that you own or have control over the repository. The repository metadata file must be located at the path used in the repository URL.
</p>
<div
class="list-group mt-4 mt-md-5"
class="row mt-3 mt-md-4"
data-testid="repoList"
>
<li
class="list-group-item listItem"
<div
class="col-12 col-xxl-6 py-sm-3 py-2"
data-testid="repoCard"
>
<div
class="d-flex flex-row w-100 justify-content-between"
class="card h-100"
>
<div
class="d-flex flex-row align-items-center mb-1 text-truncate"
class="card-body d-flex flex-column h-100"
>
<div
class="h5 mb-0 mr-3 text-truncate titleCard"
>
test
</div>
</div>
<div
class="ml-auto"
>
<img
alt="Icon"
class="kindIcon repoIcon"
src="/static/media/helm-chart.svg"
/>
</div>
<div
class="ml-3"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
class="d-flex flex-row w-100 justify-content-between"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="getBadgeBtn"
class="d-flex flex-row align-items-center mb-1 text-truncate"
>
<div
class="d-flex flex-row align-items-center"
class="h5 mb-0 mr-3 text-truncate titleCard"
>
test
</div>
</div>
<div
class="ml-auto"
>
<img
alt="Icon"
class="kindIcon repoIcon"
src="/static/media/helm-chart.svg"
/>
</div>
<div
class="ml-3"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="getBadgeBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z"
/>
</svg>
<span>
Get badge
</span>
</div>
</button>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="transferRepoBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M0 0h24v24H0z"
fill="none"
/>
<path
d="M16.05 12.05L21 17l-4.95 4.95-1.414-1.414 2.536-2.537L4 18v-2h13.172l-2.536-2.536 1.414-1.414zm-8.1-10l1.414 1.414L6.828 6 20 6v2H6.828l2.536 2.536L7.95 11.95 3 7l4.95-4.95z"
/>
</g>
</svg>
<span>
Transfer
</span>
</div>
</button>
</span>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="updateRepoBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
/>
</svg>
<span>
Edit
</span>
</div>
</button>
</span>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="deleteRepoDropdownBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
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="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"
/>
</svg>
<span>
Delete
</span>
</div>
</button>
</span>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.63 5.84C17.27 5.33 16.67 5 16 5L5 5.01C3.9 5.01 3 5.9 3 7v10c0 1.1.9 1.99 2 1.99L16 19c.67 0 1.27-.33 1.63-.84L22 12l-4.37-6.16z"
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
<span>
Get badge
</span>
</div>
</button>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="transferRepoBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M0 0h24v24H0z"
fill="none"
/>
<path
d="M16.05 12.05L21 17l-4.95 4.95-1.414-1.414 2.536-2.537L4 18v-2h13.172l-2.536-2.536 1.414-1.414zm-8.1-10l1.414 1.414L6.828 6 20 6v2H6.828l2.536 2.536L7.95 11.95 3 7l4.95-4.95z"
/>
</g>
</svg>
<span>
Transfer
</span>
</div>
</button>
</span>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="updateRepoBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
/>
</svg>
<span>
Edit
</span>
</div>
</button>
</span>
<span
class="position-relative"
>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="deleteRepoDropdownBtn"
type="button"
>
<div
class="d-flex flex-row align-items-center undefined"
>
<svg
class="mr-2 btnIcon"
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="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"
/>
</svg>
<span>
Delete
</span>
</div>
</button>
</span>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
</button>
</div>
</div>
<div
class="mt-2 d-flex flex-row align-items-baseline"
>
<div
class="text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
ID:
</small>
<small>
test
</small>
</div>
<div
class="ml-1 copyBtn"
>
<div
class="position-absolute copyBtnWrapper"
>
<div
class="position-relative undefined"
>
<button
class="btn btn-sm btn-link border-0 text-secondary font-weight-bold"
data-testid="ctcBtn"
type="button"
>
<div
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
class="mt-2 d-flex flex-row align-items-baseline"
>
<div
class="text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
ID:
</small>
<small>
test
</small>
</div>
<div
class="ml-1 copyBtn"
>
<div
class="position-absolute copyBtnWrapper"
>
<div
class="position-relative undefined"
>
<button
class="btn btn-sm btn-link border-0 text-secondary font-weight-bold"
data-testid="ctcBtn"
type="button"
>
<div
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
class="text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
Url:
</small>
<small>
http://test.com
</small>
</div>
<div>
<small
class="text-muted text-uppercase mr-1"
>
Last processed:
</small>
<small>
Not processed yet, it will be processed automatically in ~ 3 minutes
</small>
</div>
<div
class="mt-3 m-md-0 d-flex flex-row d-md-none"
/>
</div>
</div>
<div
class="text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
Url:
</small>
<small>
http://test.com
</small>
</div>
<div>
<small
class="text-muted text-uppercase mr-1"
>
Last processed:
</small>
<small>
Not processed yet, it will be processed automatically in ~ 3 minutes
</small>
</div>
<div
class="mt-3 m-md-0 d-flex flex-row d-md-none"
/>
</li>
</div>
</div>
</div>
</main>

View File

@ -33,7 +33,7 @@ const mockCtx = {
user: { alias: 'test', email: 'test@test.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -191,7 +191,7 @@ const RepositoriesSection = (props: Props) => {
)}
</NoData>
) : (
<div className="list-group mt-4 mt-md-5" data-testid="repoList">
<div className="row mt-3 mt-md-4" data-testid="repoList">
{repositories.map((repo: Repo) => (
<RepositoryCard
key={repo.name}

View File

@ -56,7 +56,7 @@ const mockCtx = {
controlPanel: {
selectedOrg: 'orgTest',
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -70,7 +70,7 @@ const mockNotSelectedOrgCtx = {
controlPanel: {
selectedOrg: undefined,
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -31,7 +31,7 @@ const mockCtx = {
controlPanel: {
selectedOrg: 'orgTest',
},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -1,8 +1,3 @@
.listItem {
border-width: 2px;
padding: 1.25rem;
}
.titleCard {
word-break: break-word;
}

View File

@ -56,116 +56,120 @@ const APIKeyCard = (props: Props) => {
}
return (
<li className={`list-group-item ${styles.listItem}`} data-testid="APIKeyCard">
<div className="d-flex flex-row w-100 justify-content-between">
<div className={`h5 mb-1 mr-2 ${styles.titleCard}`}>{props.apiKey.name}</div>
{deletionModalStatus && (
<Modal
className={`d-inline-block ${styles.modal}`}
closeButton={
<>
<button
className={`btn btn-sm btn-light text-uppercase ${styles.btnLight}`}
onClick={() => setDeletionModalStatus(false)}
>
<div className="d-flex flex-row align-items-center">
<IoMdCloseCircle className="mr-2" />
<span>Cancel</span>
</div>
</button>
<div className="col-12 col-xxl-6 py-sm-3 py-2" data-testid="APIKeyCard">
<div className="card h-100">
<div className="card-body d-flex flex-column h-100">
<div className="d-flex flex-row w-100 justify-content-between">
<div className={`h5 mb-1 mr-2 ${styles.titleCard}`}>{props.apiKey.name}</div>
{deletionModalStatus && (
<Modal
className={`d-inline-block ${styles.modal}`}
closeButton={
<>
<button
className={`btn btn-sm btn-light text-uppercase ${styles.btnLight}`}
onClick={() => setDeletionModalStatus(false)}
>
<div className="d-flex flex-row align-items-center">
<IoMdCloseCircle className="mr-2" />
<span>Cancel</span>
</div>
</button>
<button
data-testid="deleteAPIKeyBtn"
className="btn btn-sm btn-danger ml-3"
onClick={(e) => {
e.preventDefault();
closeDropdown();
deleteAPIKey();
}}
disabled={isDeleting}
>
<div className="d-flex flex-row align-items-center text-uppercase">
{isDeleting ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="ml-2">Deleting...</span>
</>
) : (
<>
<FaTrashAlt className={`mr-2 ${styles.btnDeleteIcon}`} />
<span>Delete</span>
</>
)}
</div>
</button>
</>
}
header={<div className={`h3 m-2 ${styles.title}`}>Delete API key</div>}
onClose={() => setDeletionModalStatus(false)}
open
>
<div className="mt-3 mw-100 text-center">
<p>Are you sure you want to remove this API key?</p>
</div>
</Modal>
)}
<div className="ml-auto">
<div
ref={dropdownMenu}
className={classnames('dropdown-menu dropdown-menu-right p-0', styles.dropdownMenu, {
show: dropdownMenuStatus,
})}
>
<div className={`arrow ${styles.arrow}`} />
<button
data-testid="deleteAPIKeyBtn"
className="btn btn-sm btn-danger ml-3"
onClick={(e) => {
data-testid="updateAPIKeyBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
deleteAPIKey();
props.setModalStatus({
open: true,
apiKey: props.apiKey,
});
}}
disabled={isDeleting}
>
<div className="d-flex flex-row align-items-center text-uppercase">
{isDeleting ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="ml-2">Deleting...</span>
</>
) : (
<>
<FaTrashAlt className={`mr-2 ${styles.btnDeleteIcon}`} />
<span>Delete</span>
</>
)}
<div className="d-flex flex-row align-items-center">
<FaPencilAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Edit</span>
</div>
</button>
</>
}
header={<div className={`h3 m-2 ${styles.title}`}>Delete API key</div>}
onClose={() => setDeletionModalStatus(false)}
open
>
<div className="mt-3 mw-100 text-center">
<p>Are you sure you want to remove this API key?</p>
<button
data-testid="deleteAPIKeyModalBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setDeletionModalStatus(true);
}}
>
<div className="d-flex flex-row align-items-center">
<FaTrashAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Delete</span>
</div>
</button>
</div>
<button
className={`btn btn-light p-0 text-secondary text-center ${styles.btnDropdown}`}
onClick={() => setDropdownMenuStatus(true)}
>
<BsThreeDotsVertical />
</button>
</div>
</Modal>
)}
<div className="ml-auto">
<div
ref={dropdownMenu}
className={classnames('dropdown-menu dropdown-menu-right p-0', styles.dropdownMenu, {
show: dropdownMenuStatus,
})}
>
<div className={`arrow ${styles.arrow}`} />
<button
data-testid="updateAPIKeyBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
props.setModalStatus({
open: true,
apiKey: props.apiKey,
});
}}
>
<div className="d-flex flex-row align-items-center">
<FaPencilAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Edit</span>
</div>
</button>
<button
data-testid="deleteAPIKeyModalBtn"
className="dropdown-item btn btn-sm rounded-0 text-secondary"
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
closeDropdown();
setDeletionModalStatus(true);
}}
>
<div className="d-flex flex-row align-items-center">
<FaTrashAlt className={`mr-2 ${styles.btnIcon}`} />
<span>Delete</span>
</div>
</button>
</div>
<button
className={`btn btn-light p-0 text-secondary text-center ${styles.btnDropdown}`}
onClick={() => setDropdownMenuStatus(true)}
>
<BsThreeDotsVertical />
</button>
<div className="mt-2 text-truncate">
<small className="text-muted text-uppercase mr-1">Created at: </small>
<small>{moment(props.apiKey.createdAt! * 1000).format('YYYY/MM/DD HH:mm:ss (Z)')}</small>
</div>
</div>
</div>
<div className="mt-2 text-truncate">
<small className="text-muted text-uppercase mr-1">Created at: </small>
<small>{moment(props.apiKey.createdAt! * 1000).format('YYYY/MM/DD HH:mm:ss (Z)')}</small>
</div>
</li>
</div>
);
};

View File

@ -2,113 +2,121 @@
exports[`API key Card - API keys section creates snapshot 1`] = `
<DocumentFragment>
<li
class="list-group-item listItem"
<div
class="col-12 col-xxl-6 py-sm-3 py-2"
data-testid="APIKeyCard"
>
<div
class="d-flex flex-row w-100 justify-content-between"
class="card h-100"
>
<div
class="h5 mb-1 mr-2 titleCard"
>
key1
</div>
<div
class="ml-auto"
class="card-body d-flex flex-column h-100"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
class="d-flex flex-row w-100 justify-content-between"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="updateAPIKeyBtn"
class="h5 mb-1 mr-2 titleCard"
>
key1
</div>
<div
class="ml-auto"
>
<div
class="d-flex flex-row align-items-center"
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="updateAPIKeyBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
/>
</svg>
<span>
Edit
</span>
</div>
</button>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="deleteAPIKeyModalBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
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="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"
/>
</svg>
<span>
Delete
</span>
</div>
</button>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
<span>
Edit
</span>
</div>
</button>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="deleteAPIKeyModalBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
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="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"
/>
</svg>
<span>
Delete
</span>
</div>
</button>
</button>
</div>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
<div
class="mt-2 text-truncate"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
<small
class="text-muted text-uppercase mr-1"
>
<path
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
</button>
Created at:
</small>
<small>
2020/06/18 16:35:39 (+00:00)
</small>
</div>
</div>
</div>
<div
class="mt-2 text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
Created at:
</small>
<small>
2020/06/18 16:35:39 (+00:00)
</small>
</div>
</li>
</div>
</DocumentFragment>
`;

View File

@ -84,7 +84,7 @@ exports[`API keys section index creates snapshot 1`] = `
</div>
</div>
<div
class="mx-auto mt-4 mt-md-5 wrapper"
class="mt-4"
/>
<div>
<div
@ -232,231 +232,247 @@ exports[`API keys section index creates snapshot 2`] = `
</div>
</div>
<div
class="mx-auto mt-4 mt-md-5 wrapper"
class="mt-4"
>
<div
class="mt-4 mt-md-5"
>
<div
class="list-group mt-4 mt-md-5"
class="row mt-4 mt-md-5"
data-testid="apiKeysList"
>
<li
class="list-group-item listItem"
<div
class="col-12 col-xxl-6 py-sm-3 py-2"
data-testid="APIKeyCard"
>
<div
class="d-flex flex-row w-100 justify-content-between"
class="card h-100"
>
<div
class="h5 mb-1 mr-2 titleCard"
>
key1
</div>
<div
class="ml-auto"
class="card-body d-flex flex-column h-100"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
class="d-flex flex-row w-100 justify-content-between"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="updateAPIKeyBtn"
class="h5 mb-1 mr-2 titleCard"
>
key1
</div>
<div
class="ml-auto"
>
<div
class="d-flex flex-row align-items-center"
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="updateAPIKeyBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
/>
</svg>
<span>
Edit
</span>
</div>
</button>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="deleteAPIKeyModalBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
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="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"
/>
</svg>
<span>
Delete
</span>
</div>
</button>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
<span>
Edit
</span>
</div>
</button>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="deleteAPIKeyModalBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
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="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"
/>
</svg>
<span>
Delete
</span>
</div>
</button>
</button>
</div>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
<div
class="mt-2 text-truncate"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
<small
class="text-muted text-uppercase mr-1"
>
<path
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
</button>
Created at:
</small>
<small>
2020/06/18 16:35:39 (+00:00)
</small>
</div>
</div>
</div>
<div
class="mt-2 text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
Created at:
</small>
<small>
2020/06/18 16:35:39 (+00:00)
</small>
</div>
</li>
<li
class="list-group-item listItem"
</div>
<div
class="col-12 col-xxl-6 py-sm-3 py-2"
data-testid="APIKeyCard"
>
<div
class="d-flex flex-row w-100 justify-content-between"
class="card h-100"
>
<div
class="h5 mb-1 mr-2 titleCard"
>
key2
</div>
<div
class="ml-auto"
class="card-body d-flex flex-column h-100"
>
<div
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
class="d-flex flex-row w-100 justify-content-between"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="updateAPIKeyBtn"
class="h5 mb-1 mr-2 titleCard"
>
key2
</div>
<div
class="ml-auto"
>
<div
class="d-flex flex-row align-items-center"
class="dropdown-menu dropdown-menu-right p-0 dropdownMenu"
>
<div
class="arrow arrow"
/>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="updateAPIKeyBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
/>
</svg>
<span>
Edit
</span>
</div>
</button>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="deleteAPIKeyModalBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
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="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"
/>
</svg>
<span>
Delete
</span>
</div>
</button>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
>
<svg
class="mr-2 btnIcon"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 512 512"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z"
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
<span>
Edit
</span>
</div>
</button>
<button
class="dropdown-item btn btn-sm rounded-0 text-secondary"
data-testid="deleteAPIKeyModalBtn"
>
<div
class="d-flex flex-row align-items-center"
>
<svg
class="mr-2 btnIcon"
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="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"
/>
</svg>
<span>
Delete
</span>
</div>
</button>
</button>
</div>
</div>
<button
class="btn btn-light p-0 text-secondary text-center btnDropdown"
<div
class="mt-2 text-truncate"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 16 16"
width="1em"
xmlns="http://www.w3.org/2000/svg"
<small
class="text-muted text-uppercase mr-1"
>
<path
clip-rule="evenodd"
d="M9.5 13a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm0-5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z"
fill-rule="evenodd"
/>
</svg>
</button>
Created at:
</small>
<small>
2020/06/18 16:35:39 (+00:00)
</small>
</div>
</div>
</div>
<div
class="mt-2 text-truncate"
>
<small
class="text-muted text-uppercase mr-1"
>
Created at:
</small>
<small>
2020/06/18 16:35:39 (+00:00)
</small>
</div>
</li>
</div>
</div>
</div>
</div>

View File

@ -72,7 +72,7 @@ const APIKeysSection = (props: Props) => {
</div>
</div>
<div className={`mx-auto mt-4 mt-md-5 ${styles.wrapper}`}>
<div className="mt-4">
{!isUndefined(apiKeysList) && (
<div className="mt-4 mt-md-5">
{apiKeysList.length === 0 ? (
@ -98,7 +98,7 @@ const APIKeysSection = (props: Props) => {
)}
</NoData>
) : (
<div className="list-group mt-4 mt-md-5" data-testid="apiKeysList">
<div className="row mt-4 mt-md-5" data-testid="apiKeysList">
{apiKeysList.map((apiKey: APIKey) => (
<APIKeyCard
key={apiKey.apiKeyId!}

View File

@ -23,7 +23,7 @@ const mockCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -177,7 +177,7 @@
]
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -37,7 +37,7 @@
"facets": []
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -37,7 +37,7 @@
"facets": []
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -37,7 +37,7 @@
"facets": []
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -37,7 +37,7 @@
"facets": []
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -37,7 +37,7 @@
"facets": []
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -134,153 +134,160 @@ const PackagesSection = (props: Props) => {
{!isUndefined(packages) && packages.length > 0 && (
<>
<div className="d-none d-sm-inline" data-testid="packagesList">
<table className={`table table-bordered table-hover ${styles.table}`}>
<thead>
<tr className={`table-primary ${styles.tableTitle}`}>
<th scope="col" className={`align-middle text-center d-none d-sm-table-cell ${styles.fitCell}`}>
Kind
</th>
<th scope="col" className="align-middle text-center w-50">
Package
</th>
<th scope="col" className="align-middle text-center w-50">
Publisher
</th>
{PACKAGE_SUBSCRIPTIONS_LIST.map((subs: SubscriptionItem) => (
<th
scope="col"
className={`align-middle text-nowrap ${styles.fitCell}`}
key={`title_${subs.kind}`}
>
<div className="d-flex flex-row align-items-center justify-content-center">
{subs.icon}
<span className="d-none d-lg-inline ml-2">{subs.title}</span>
</div>
</th>
))}
</tr>
</thead>
<tbody>
{packages.map((item: Package) => (
<tr key={`subs_${item.packageId}`} data-testid="subsTableCell">
<td className="align-middle text-center d-none d-sm-table-cell">
<RepositoryIcon kind={item.repository.kind} className={styles.icon} />
</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 ${styles.imageWrapper} imageWrapper`}
<div className="row">
<div className="col-12 col-xxl-10">
<table className={`table table-bordered table-hover ${styles.table}`}>
<thead>
<tr className={`table-primary ${styles.tableTitle}`}>
<th
scope="col"
className={`align-middle text-center d-none d-sm-table-cell ${styles.fitCell}`}
>
Kind
</th>
<th scope="col" className="align-middle w-50">
Package
</th>
<th scope="col" className="align-middle w-50">
Publisher
</th>
{PACKAGE_SUBSCRIPTIONS_LIST.map((subs: SubscriptionItem) => (
<th
scope="col"
className={`align-middle text-nowrap ${styles.fitCell}`}
key={`title_${subs.kind}`}
>
<Image
alt={item.displayName || item.name}
imageId={item.logoImageId}
className={styles.image}
kind={item.repository.kind}
/>
</div>
<div className="d-flex flex-row align-items-center justify-content-center">
{subs.icon}
<span className="d-none d-lg-inline ml-2">{subs.title}</span>
</div>
</th>
))}
</tr>
</thead>
<tbody>
{packages.map((item: Package) => (
<tr key={`subs_${item.packageId}`} data-testid="subsTableCell">
<td className="align-middle text-center d-none d-sm-table-cell">
<RepositoryIcon kind={item.repository.kind} className={styles.icon} />
</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 ${styles.imageWrapper} imageWrapper`}
>
<Image
alt={item.displayName || item.name}
imageId={item.logoImageId}
className={styles.image}
kind={item.repository.kind}
/>
</div>
<Link
data-testid="packageLink"
className="ml-2 text-dark"
to={{
pathname: buildPackageURL(item),
}}
>
{item.displayName || item.name}
</Link>
</div>
</td>
<td className="align-middle position-relative">
{!isNull(item.repository.userAlias) ? (
<Link
data-testid="userLink"
className="text-dark"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
user: [item.repository.userAlias!],
},
}),
}}
>
{item.repository.userAlias}
</Link>
) : (
<Link
data-testid="orgLink"
className="text-dark"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
org: [item.repository.organizationName!],
},
}),
}}
>
{item.repository.organizationDisplayName || item.repository.organizationName}
</Link>
)}
<small className="ml-2">
(<span className={`text-uppercase text-muted ${styles.legend}`}>Repo: </span>
<Link
data-testid="repoLink"
className="text-dark"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
repo: [item.repository.name],
},
}),
}}
>
{item.repository.displayName || item.repository.name}
</Link>
)
</small>
</td>
{PACKAGE_SUBSCRIPTIONS_LIST.map((subs: SubscriptionItem) => {
const isActive = !isUndefined(item.eventKinds) && item.eventKinds.includes(subs.kind);
const id = `subs_${item.packageId}_${subs.kind}`;
return (
<td className="align-middle text-center" key={`td_${item.normalizedName}_${subs.kind}`}>
<div className="custom-control custom-switch ml-2">
<input
data-testid={`${item.name}_${subs.name}_input`}
id={id}
type="checkbox"
className={`custom-control-input ${styles.checkbox}`}
disabled={!subs.enabled}
onChange={() =>
changeSubscription(
item.packageId,
subs.kind,
isActive,
item.displayName || item.name
)
}
checked={isActive}
/>
<label
data-testid={`${item.name}_${subs.name}_label`}
className="custom-control-label"
htmlFor={id}
/>
<Link
data-testid="packageLink"
className="ml-2 text-dark"
to={{
pathname: buildPackageURL(item),
}}
>
{item.displayName || item.name}
</Link>
</div>
</td>
);
})}
</tr>
))}
</tbody>
</table>
<td className="align-middle position-relative">
{!isNull(item.repository.userAlias) ? (
<Link
data-testid="userLink"
className="text-dark"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
user: [item.repository.userAlias!],
},
}),
}}
>
{item.repository.userAlias}
</Link>
) : (
<Link
data-testid="orgLink"
className="text-dark"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
org: [item.repository.organizationName!],
},
}),
}}
>
{item.repository.organizationDisplayName || item.repository.organizationName}
</Link>
)}
<small className="ml-2">
(<span className={`text-uppercase text-muted ${styles.legend}`}>Repo: </span>
<Link
data-testid="repoLink"
className="text-dark"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
repo: [item.repository.name],
},
}),
}}
>
{item.repository.displayName || item.repository.name}
</Link>
)
</small>
</td>
{PACKAGE_SUBSCRIPTIONS_LIST.map((subs: SubscriptionItem) => {
const isActive = !isUndefined(item.eventKinds) && item.eventKinds.includes(subs.kind);
const id = `subs_${item.packageId}_${subs.kind}`;
return (
<td className="align-middle text-center" key={`td_${item.normalizedName}_${subs.kind}`}>
<div className="custom-control custom-switch ml-2">
<input
data-testid={`${item.name}_${subs.name}_input`}
id={id}
type="checkbox"
className={`custom-control-input ${styles.checkbox}`}
disabled={!subs.enabled}
onChange={() =>
changeSubscription(
item.packageId,
subs.kind,
isActive,
item.displayName || item.name
)
}
checked={isActive}
/>
<label
data-testid={`${item.name}_${subs.name}_label`}
className="custom-control-label"
htmlFor={id}
/>
</div>
</td>
);
})}
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
<div className="d-inline d-sm-none">

View File

@ -56,7 +56,7 @@ const mockCtx = {
user: { alias: 'test', email: 'test@test.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -163,297 +163,305 @@ exports[`RepositoriesSection renders correctly 2`] = `
<div
class="mt-4 mt-md-5"
>
<table
class="table table-bordered table-hover table"
data-testid="repositoriesList"
<div
class="row"
>
<thead>
<tr
class="table-primary tableTitle"
<div
class="col-12 col-xxl-10"
>
<table
class="table table-bordered table-hover table"
data-testid="repositoriesList"
>
<th
class="align-middle text-center d-none d-sm-table-cell fitCell"
scope="col"
>
Kind
</th>
<th
class="align-middle text-center w-50"
scope="col"
>
Repository
</th>
<th
class="align-middle text-center w-50 d-none d-sm-table-cell"
scope="col"
>
Publisher
</th>
<th
class="align-middle text-nowrap fitCell"
scope="col"
>
<div
class="d-flex flex-row align-items-center justify-content-center"
<thead>
<tr
class="table-primary tableTitle"
>
<svg
baseProfile="tiny"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
version="1.2"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
<th
class="align-middle text-center d-none d-sm-table-cell fitCell"
scope="col"
>
<path
d="M21.171 15.398l-5.912-9.854c-.776-1.293-1.963-2.033-3.259-2.033s-2.483.74-3.259 2.031l-5.912 9.856c-.786 1.309-.872 2.705-.235 3.83.636 1.126 1.878 1.772 3.406 1.772h12c1.528 0 2.77-.646 3.406-1.771.637-1.125.551-2.521-.235-3.831zm-9.171 2.151c-.854 0-1.55-.695-1.55-1.549 0-.855.695-1.551 1.55-1.551s1.55.696 1.55 1.551c0 .854-.696 1.549-1.55 1.549zm1.633-7.424c-.011.031-1.401 3.468-1.401 3.468-.038.094-.13.156-.231.156s-.193-.062-.231-.156l-1.391-3.438c-.09-.233-.129-.443-.129-.655 0-.965.785-1.75 1.75-1.75s1.75.785 1.75 1.75c0 .212-.039.422-.117.625z"
Kind
</th>
<th
class="align-middle w-50"
scope="col"
>
Repository
</th>
<th
class="align-middle w-50 d-none d-sm-table-cell"
scope="col"
>
Publisher
</th>
<th
class="align-middle text-nowrap fitCell"
scope="col"
>
<div
class="d-flex flex-row align-items-center justify-content-center"
>
<svg
baseProfile="tiny"
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
version="1.2"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M21.171 15.398l-5.912-9.854c-.776-1.293-1.963-2.033-3.259-2.033s-2.483.74-3.259 2.031l-5.912 9.856c-.786 1.309-.872 2.705-.235 3.83.636 1.126 1.878 1.772 3.406 1.772h12c1.528 0 2.77-.646 3.406-1.771.637-1.125.551-2.521-.235-3.831zm-9.171 2.151c-.854 0-1.55-.695-1.55-1.549 0-.855.695-1.551 1.55-1.551s1.55.696 1.55 1.551c0 .854-.696 1.549-1.55 1.549zm1.633-7.424c-.011.031-1.401 3.468-1.401 3.468-.038.094-.13.156-.231.156s-.193-.062-.231-.156l-1.391-3.438c-.09-.233-.129-.443-.129-.655 0-.965.785-1.75 1.75-1.75s1.75.785 1.75 1.75c0 .212-.039.422-.117.625z"
/>
</svg>
<span
class="d-none d-lg-inline ml-2"
>
Tracking errors
</span>
</div>
</th>
</tr>
</thead>
<tbody>
<tr
data-testid="optOutRow"
>
<td
class="align-middle text-center d-none d-sm-table-cell"
>
<img
alt="Icon"
class="icon repoIcon"
src="/static/media/helm-chart.svg"
/>
</svg>
<span
class="d-none d-lg-inline ml-2"
</td>
<td
class="align-middle"
>
Tracking errors
</span>
</div>
</th>
</tr>
</thead>
<tbody>
<tr
data-testid="optOutRow"
>
<td
class="align-middle text-center d-none d-sm-table-cell"
>
<img
alt="Icon"
class="icon repoIcon"
src="/static/media/helm-chart.svg"
/>
</td>
<td
class="align-middle"
>
<div
class="d-flex flex-row align-items-center"
<div
class="d-flex flex-row align-items-center"
>
<a
class="text-dark text-capitalize"
data-testid="repoLink"
href="/packages/search?page=1&repo=adfinis"
>
adfinis
</a>
</div>
</td>
<td
class="align-middle position-relative d-none d-sm-table-cell"
>
<span
class="mx-1 mb-1 tinyIcon"
>
<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>
</span>
<a
class="text-dark"
data-testid="userLink"
href="/packages/search?page=1&user=alias"
>
alias
</a>
</td>
<td
class="align-middle text-center"
>
<div
class="custom-control custom-switch ml-2"
>
<input
checked=""
class="custom-control-input checkbox"
data-testid="87234sf-dfgdfgfe5-tyreh7i68_trackingErrors_input"
id="subs_8cf4ae9a-d43c-4abf-86d0-615bb3864db2_2"
type="checkbox"
/>
<label
class="custom-control-label"
data-testid="87234sf-dfgdfgfe5-tyreh7i68_trackingErrors_label"
for="subs_8cf4ae9a-d43c-4abf-86d0-615bb3864db2_2"
/>
</div>
</td>
</tr>
<tr
data-testid="optOutRow"
>
<a
class="text-dark text-capitalize"
data-testid="repoLink"
href="/packages/search?page=1&repo=adfinis"
<td
class="align-middle text-center d-none d-sm-table-cell"
>
adfinis
</a>
</div>
</td>
<td
class="align-middle position-relative d-none d-sm-table-cell"
>
<span
class="mx-1 mb-1 tinyIcon"
>
<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"
<img
alt="Icon"
class="icon repoIcon"
src="/static/media/helm-chart.svg"
/>
</svg>
</span>
<a
class="text-dark"
data-testid="userLink"
href="/packages/search?page=1&user=alias"
>
alias
</a>
</td>
<td
class="align-middle text-center"
>
<div
class="custom-control custom-switch ml-2"
>
<input
checked=""
class="custom-control-input checkbox"
data-testid="87234sf-dfgdfgfe5-tyreh7i68_trackingErrors_input"
id="subs_8cf4ae9a-d43c-4abf-86d0-615bb3864db2_2"
type="checkbox"
/>
<label
class="custom-control-label"
data-testid="87234sf-dfgdfgfe5-tyreh7i68_trackingErrors_label"
for="subs_8cf4ae9a-d43c-4abf-86d0-615bb3864db2_2"
/>
</div>
</td>
</tr>
<tr
data-testid="optOutRow"
>
<td
class="align-middle text-center d-none d-sm-table-cell"
>
<img
alt="Icon"
class="icon repoIcon"
src="/static/media/helm-chart.svg"
/>
</td>
<td
class="align-middle"
>
<div
class="d-flex flex-row align-items-center"
>
<a
class="text-dark text-capitalize"
data-testid="repoLink"
href="/packages/search?page=1&repo=apache-pulsar-helm-chart-repo"
</td>
<td
class="align-middle"
>
apache-pulsar-helm-chart-repo
</a>
</div>
</td>
<td
class="align-middle position-relative d-none d-sm-table-cell"
>
<span
class="mx-1 mb-1 tinyIcon"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 448 512"
width="1em"
xmlns="http://www.w3.org/2000/svg"
<div
class="d-flex flex-row align-items-center"
>
<a
class="text-dark text-capitalize"
data-testid="repoLink"
href="/packages/search?page=1&repo=apache-pulsar-helm-chart-repo"
>
apache-pulsar-helm-chart-repo
</a>
</div>
</td>
<td
class="align-middle position-relative d-none d-sm-table-cell"
>
<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"
<span
class="mx-1 mb-1 tinyIcon"
>
<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>
</span>
<a
class="text-dark"
data-testid="userLink"
href="/packages/search?page=1&user=alias"
>
alias
</a>
</td>
<td
class="align-middle text-center"
>
<div
class="custom-control custom-switch ml-2"
>
<input
checked=""
class="custom-control-input checkbox"
data-testid="43543trger-gvnmbvf5u6-kjfg-utyiu8_trackingErrors_input"
id="subs_68edcb58-ed11-42e1-953b-e52e3bfac3e5_2"
type="checkbox"
/>
<label
class="custom-control-label"
data-testid="43543trger-gvnmbvf5u6-kjfg-utyiu8_trackingErrors_label"
for="subs_68edcb58-ed11-42e1-953b-e52e3bfac3e5_2"
/>
</div>
</td>
</tr>
<tr
data-testid="optOutRow"
>
<td
class="align-middle text-center d-none d-sm-table-cell"
>
<img
alt="Icon"
class="icon repoIcon"
src="/static/media/helm-chart.svg"
/>
</svg>
</span>
<a
class="text-dark"
data-testid="userLink"
href="/packages/search?page=1&user=alias"
>
alias
</a>
</td>
<td
class="align-middle text-center"
>
<div
class="custom-control custom-switch ml-2"
>
<input
checked=""
class="custom-control-input checkbox"
data-testid="43543trger-gvnmbvf5u6-kjfg-utyiu8_trackingErrors_input"
id="subs_68edcb58-ed11-42e1-953b-e52e3bfac3e5_2"
type="checkbox"
/>
<label
class="custom-control-label"
data-testid="43543trger-gvnmbvf5u6-kjfg-utyiu8_trackingErrors_label"
for="subs_68edcb58-ed11-42e1-953b-e52e3bfac3e5_2"
/>
</div>
</td>
</tr>
<tr
data-testid="optOutRow"
>
<td
class="align-middle text-center d-none d-sm-table-cell"
>
<img
alt="Icon"
class="icon repoIcon"
src="/static/media/helm-chart.svg"
/>
</td>
<td
class="align-middle"
>
<div
class="d-flex flex-row align-items-center"
>
<a
class="text-dark text-capitalize"
data-testid="repoLink"
href="/packages/search?page=1&repo=artifact-hub"
</td>
<td
class="align-middle"
>
artifact-hub
</a>
</div>
</td>
<td
class="align-middle position-relative d-none d-sm-table-cell"
>
<span
class="mx-1 mb-1 tinyIcon"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
<div
class="d-flex flex-row align-items-center"
>
<a
class="text-dark text-capitalize"
data-testid="repoLink"
href="/packages/search?page=1&repo=artifact-hub"
>
artifact-hub
</a>
</div>
</td>
<td
class="align-middle position-relative d-none d-sm-table-cell"
>
<path
d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"
/>
</svg>
</span>
<a
class="text-dark"
data-testid="orgLink"
href="/packages/search?page=1&org=artifactHub"
>
artifactHub
</a>
</td>
<td
class="align-middle text-center"
>
<div
class="custom-control custom-switch ml-2"
>
<input
checked=""
class="custom-control-input checkbox"
data-testid="5trurt4sf-drtyrygfe5-po09rikjtr_trackingErrors_input"
id="subs_a032a436-3568-4970-804a-2780f5e9d231_2"
type="checkbox"
/>
<label
class="custom-control-label"
data-testid="5trurt4sf-drtyrygfe5-po09rikjtr_trackingErrors_label"
for="subs_a032a436-3568-4970-804a-2780f5e9d231_2"
/>
</div>
</td>
</tr>
</tbody>
</table>
<span
class="mx-1 mb-1 tinyIcon"
>
<svg
fill="currentColor"
height="1em"
stroke="currentColor"
stroke-width="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"
/>
</svg>
</span>
<a
class="text-dark"
data-testid="orgLink"
href="/packages/search?page=1&org=artifactHub"
>
artifactHub
</a>
</td>
<td
class="align-middle text-center"
>
<div
class="custom-control custom-switch ml-2"
>
<input
checked=""
class="custom-control-input checkbox"
data-testid="5trurt4sf-drtyrygfe5-po09rikjtr_trackingErrors_input"
id="subs_a032a436-3568-4970-804a-2780f5e9d231_2"
type="checkbox"
/>
<label
class="custom-control-label"
data-testid="5trurt4sf-drtyrygfe5-po09rikjtr_trackingErrors_label"
for="subs_a032a436-3568-4970-804a-2780f5e9d231_2"
/>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -131,128 +131,136 @@ const RepositoriesSection = (props: Props) => {
<div className="mt-4 mt-md-5">
{!isUndefined(optOutList) && optOutList.length > 0 && (
<table className={`table table-bordered table-hover ${styles.table}`} data-testid="repositoriesList">
<thead>
<tr className={`table-primary ${styles.tableTitle}`}>
<th scope="col" className={`align-middle text-center d-none d-sm-table-cell ${styles.fitCell}`}>
Kind
</th>
<th scope="col" className="align-middle text-center w-50">
Repository
</th>
<th scope="col" className="align-middle text-center w-50 d-none d-sm-table-cell">
Publisher
</th>
{REPOSITORY_SUBSCRIPTIONS_LIST.map((subs: SubscriptionItem) => (
<th scope="col" className={`align-middle text-nowrap ${styles.fitCell}`} key={`title_${subs.kind}`}>
<div className="d-flex flex-row align-items-center justify-content-center">
{subs.icon}
<span className="d-none d-lg-inline ml-2">{subs.title}</span>
</div>
</th>
))}
</tr>
</thead>
<tbody>
{optOutList.map((item: OptOutItem) => (
<tr key={`subs_${item.optOutId}`} data-testid="optOutRow">
<td className="align-middle text-center d-none d-sm-table-cell">
<RepositoryIcon kind={item.repository.kind} className={styles.icon} />
</td>
<td className="align-middle">
<div className="d-flex flex-row align-items-center">
<Link
data-testid="repoLink"
className="text-dark text-capitalize"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
repo: [item.repository.name],
},
}),
}}
<div className="row">
<div className="col-12 col-xxl-10">
<table className={`table table-bordered table-hover ${styles.table}`} data-testid="repositoriesList">
<thead>
<tr className={`table-primary ${styles.tableTitle}`}>
<th scope="col" className={`align-middle text-center d-none d-sm-table-cell ${styles.fitCell}`}>
Kind
</th>
<th scope="col" className="align-middle w-50">
Repository
</th>
<th scope="col" className="align-middle w-50 d-none d-sm-table-cell">
Publisher
</th>
{REPOSITORY_SUBSCRIPTIONS_LIST.map((subs: SubscriptionItem) => (
<th
scope="col"
className={`align-middle text-nowrap ${styles.fitCell}`}
key={`title_${subs.kind}`}
>
{item.repository.name}
</Link>
</div>
</td>
<td className="align-middle position-relative d-none d-sm-table-cell">
<span className={`mx-1 mb-1 ${styles.tinyIcon}`}>
{item.repository.userAlias ? <FaUser /> : <MdBusiness />}
</span>{' '}
{!isNull(item.repository.userAlias) ? (
<Link
data-testid="userLink"
className="text-dark"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
user: [item.repository.userAlias!],
},
}),
}}
>
{item.repository.userAlias}
</Link>
) : (
<Link
data-testid="orgLink"
className="text-dark"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
org: [item.repository.organizationName!],
},
}),
}}
>
{item.repository.organizationDisplayName || item.repository.organizationName}
</Link>
)}
</td>
{REPOSITORY_SUBSCRIPTIONS_LIST.map((subs: SubscriptionItem) => {
const isActive = subs.kind === item.eventKind;
const id = `subs_${item.repository.repositoryId!}_${subs.kind}`;
return (
<td className="align-middle text-center" key={`td_${item.repository.name}_${subs.kind}`}>
<div className="custom-control custom-switch ml-2">
<input
data-testid={`${item.optOutId}_${subs.name}_input`}
id={id}
type="checkbox"
className={`custom-control-input ${styles.checkbox}`}
disabled={!subs.enabled}
onChange={() =>
changeSubscription(
item.repository.repositoryId!,
subs.kind,
isActive,
item.repository.name,
item.optOutId
)
}
checked={isActive}
/>
<label
data-testid={`${item.optOutId}_${subs.name}_label`}
className="custom-control-label"
htmlFor={id}
/>
<div className="d-flex flex-row align-items-center justify-content-center">
{subs.icon}
<span className="d-none d-lg-inline ml-2">{subs.title}</span>
</div>
</th>
))}
</tr>
</thead>
<tbody>
{optOutList.map((item: OptOutItem) => (
<tr key={`subs_${item.optOutId}`} data-testid="optOutRow">
<td className="align-middle text-center d-none d-sm-table-cell">
<RepositoryIcon kind={item.repository.kind} className={styles.icon} />
</td>
<td className="align-middle">
<div className="d-flex flex-row align-items-center">
<Link
data-testid="repoLink"
className="text-dark text-capitalize"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
repo: [item.repository.name],
},
}),
}}
>
{item.repository.name}
</Link>
</div>
</td>
);
})}
</tr>
))}
</tbody>
</table>
<td className="align-middle position-relative d-none d-sm-table-cell">
<span className={`mx-1 mb-1 ${styles.tinyIcon}`}>
{item.repository.userAlias ? <FaUser /> : <MdBusiness />}
</span>{' '}
{!isNull(item.repository.userAlias) ? (
<Link
data-testid="userLink"
className="text-dark"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
user: [item.repository.userAlias!],
},
}),
}}
>
{item.repository.userAlias}
</Link>
) : (
<Link
data-testid="orgLink"
className="text-dark"
to={{
pathname: '/packages/search',
search: prepareQueryString({
pageNumber: 1,
filters: {
org: [item.repository.organizationName!],
},
}),
}}
>
{item.repository.organizationDisplayName || item.repository.organizationName}
</Link>
)}
</td>
{REPOSITORY_SUBSCRIPTIONS_LIST.map((subs: SubscriptionItem) => {
const isActive = subs.kind === item.eventKind;
const id = `subs_${item.repository.repositoryId!}_${subs.kind}`;
return (
<td className="align-middle text-center" key={`td_${item.repository.name}_${subs.kind}`}>
<div className="custom-control custom-switch ml-2">
<input
data-testid={`${item.optOutId}_${subs.name}_input`}
id={id}
type="checkbox"
className={`custom-control-input ${styles.checkbox}`}
disabled={!subs.enabled}
onChange={() =>
changeSubscription(
item.repository.repositoryId!,
subs.kind,
isActive,
item.repository.name,
item.optOutId
)
}
checked={isActive}
/>
<label
data-testid={`${item.optOutId}_${subs.name}_label`}
className="custom-control-label"
htmlFor={id}
/>
</div>
</td>
);
})}
</tr>
))}
</tbody>
</table>
</div>
</div>
)}
</div>
</div>

View File

@ -29,7 +29,7 @@ const mockUserCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -41,7 +41,7 @@ const mockOrgCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: { selectedOrg: 'test' },
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -55,7 +55,7 @@ const WebhookCard = (props: Props) => {
}
return (
<div className="mb-3" role="listitem">
<div className="col-12 col-xxl-6 py-sm-3 py-2" role="listitem">
<div className={`card cardWithHover w-100 ${styles.card}`}>
<div className={`card-body p-0 position-relative ${styles.body}`}>
<div className="d-flex flex-row">

View File

@ -34,7 +34,7 @@ const mockUserCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -46,7 +46,7 @@ const mockOrgCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: { selectedOrg: 'test' },
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -426,8 +426,10 @@ const WebhookForm = (props: Props) => {
and the configured url will be called. At least one package must be selected.
</small>
</div>
<div className="mb-3">
<SearchPackages disabledPackages={getPackagesIds()} onSelection={addPackage} />
<div className="mb-3 row">
<div className="col-12 col-xxl-8">
<SearchPackages disabledPackages={getPackagesIds()} onSelection={addPackage} />
</div>
</div>
{isValidated && selectedPackages.length === 0 && (
@ -435,72 +437,76 @@ const WebhookForm = (props: Props) => {
)}
{selectedPackages.length > 0 && (
<table className={`table table-hover table-sm ${styles.table}`}>
<thead>
<tr className={`table-primary ${styles.tableTitle}`}>
<th scope="col" className={`align-middle d-none d-sm-table-cell ${styles.fitCell}`}></th>
<th scope="col" className="align-middle w-50">
Package
</th>
<th scope="col" className="align-middle w-50">
Publisher
</th>
<th scope="col" className={`align-middle ${styles.fitCell}`}></th>
</tr>
</thead>
<tbody>
{selectedPackages.map((item: Package) => (
<tr key={`subs_${item.packageId}`} data-testid="packageTableCell">
<td className="align-middle text-center d-none d-sm-table-cell">
<RepositoryIcon kind={item.repository.kind} className={`${styles.icon} mx-2`} />
</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 ${styles.imageWrapper} imageWrapper`}
>
<Image
alt={item.displayName || item.name}
imageId={item.logoImageId}
className={styles.image}
/>
</div>
<div className="row">
<div className="col-12 col-xxl-8">
<table className={`table table-hover table-sm ${styles.table}`}>
<thead>
<tr className={`table-primary ${styles.tableTitle}`}>
<th scope="col" className={`align-middle d-none d-sm-table-cell ${styles.fitCell}`}></th>
<th scope="col" className="align-middle w-50">
Package
</th>
<th scope="col" className="align-middle w-50">
Publisher
</th>
<th scope="col" className={`align-middle ${styles.fitCell}`}></th>
</tr>
</thead>
<tbody>
{selectedPackages.map((item: Package) => (
<tr key={`subs_${item.packageId}`} data-testid="packageTableCell">
<td className="align-middle text-center d-none d-sm-table-cell">
<RepositoryIcon kind={item.repository.kind} className={`${styles.icon} mx-2`} />
</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 ${styles.imageWrapper} imageWrapper`}
>
<Image
alt={item.displayName || item.name}
imageId={item.logoImageId}
className={styles.image}
/>
</div>
<div className="ml-2 text-dark">{item.displayName || item.name}</div>
</div>
</td>
<td className="align-middle position-relative text-dark">
{item.repository.userAlias ||
item.repository.organizationDisplayName ||
item.repository.organizationName}
<div className="ml-2 text-dark">{item.displayName || item.name}</div>
</div>
</td>
<td className="align-middle position-relative text-dark">
{item.repository.userAlias ||
item.repository.organizationDisplayName ||
item.repository.organizationName}
<small className="ml-2">
(
<span className={`text-uppercase text-muted d-none d-sm-inline ${styles.legend}`}>
Repo:{' '}
</span>
<span className="text-dark">{item.repository.displayName || item.repository.name}</span>)
</small>
</td>
<small className="ml-2">
(
<span className={`text-uppercase text-muted d-none d-sm-inline ${styles.legend}`}>
Repo:{' '}
</span>
<span className="text-dark">{item.repository.displayName || item.repository.name}</span>)
</small>
</td>
<td className="align-middle">
<button
data-testid="deletePackageButton"
className={`close text-danger mx-2 ${styles.closeBtn}`}
type="button"
onClick={(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
event.preventDefault();
event.stopPropagation();
deletePackage(item.packageId);
}}
>
<span aria-hidden="true">&times;</span>
</button>
</td>
</tr>
))}
</tbody>
</table>
<td className="align-middle">
<button
data-testid="deletePackageButton"
className={`close text-danger mx-2 ${styles.closeBtn}`}
type="button"
onClick={(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
event.preventDefault();
event.stopPropagation();
deletePackage(item.packageId);
}}
>
<span aria-hidden="true">&times;</span>
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)}
</div>
@ -599,86 +605,94 @@ const WebhookForm = (props: Props) => {
</div>
)}
<AutoresizeTextarea
name="template"
value={template}
disabled={payloadKind === PayloadKind.default}
required={payloadKind !== PayloadKind.default}
invalidText="This field is required"
minRows={6}
onChange={checkTestAvailability}
/>
<div className="form-row">
<div className="col-xxl-8">
<AutoresizeTextarea
name="template"
value={template}
disabled={payloadKind === PayloadKind.default}
required={payloadKind !== PayloadKind.default}
invalidText="This field is required"
minRows={6}
onChange={checkTestAvailability}
/>
</div>
</div>
</div>
<div className="mb-3">
<label className={`font-weight-bold ${styles.label}`} htmlFor="template">
Variables reference
</label>
<small className="form-text text-muted">
<table className={`table table-sm ${styles.variablesTable}`}>
<tbody>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Event.id }}`}</span>
</th>
<td>Id of the event triggering the notification.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Event.kind }}`}</span>
</th>
<td>
Kind of the event triggering notification. At the moment the only possible value is{' '}
<span className="font-weight-bold">package.new-release</span>.
</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.name }}`}</span>
</th>
<td>Name of the package.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.version }}`}</span>
</th>
<td>Version of the new release.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.url }}`}</span>
</th>
<td>ArtifactHub URL of the package.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.repository.kind }}`}</span>
</th>
<td>
Kind of the repository associated with the notification. Possible values are{' '}
<span className="font-weight-bold">helm-chart</span>,{' '}
<span className="font-weight-bold">falco-rules</span> and{' '}
<span className="font-weight-bold">opa-policies</span>.
</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.repository.name }}`}</span>
</th>
<td>Name of the repository.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.repository.publisher }}`}</span>
</th>
<td>
Publisher of the repository. If the owner is a user it'll be the user alias. If it's an
organization, it'll be the organization name.
</td>
</tr>
</tbody>
</table>
</small>
<div className="form-row">
<div className="col-xxl-8">
<small className="form-text text-muted">
<table className={`table table-sm ${styles.variablesTable}`}>
<tbody>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Event.id }}`}</span>
</th>
<td>Id of the event triggering the notification.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Event.kind }}`}</span>
</th>
<td>
Kind of the event triggering notification. At the moment the only possible value is{' '}
<span className="font-weight-bold">package.new-release</span>.
</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.name }}`}</span>
</th>
<td>Name of the package.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.version }}`}</span>
</th>
<td>Version of the new release.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.url }}`}</span>
</th>
<td>ArtifactHub URL of the package.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.repository.kind }}`}</span>
</th>
<td>
Kind of the repository associated with the notification. Possible values are{' '}
<span className="font-weight-bold">helm-chart</span>,{' '}
<span className="font-weight-bold">falco-rules</span> and{' '}
<span className="font-weight-bold">opa-policies</span>.
</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.repository.name }}`}</span>
</th>
<td>Name of the repository.</td>
</tr>
<tr>
<th scope="row">
<span className="text-nowrap">{`{{ .Package.repository.publisher }}`}</span>
</th>
<td>
Publisher of the repository. If the owner is a user it'll be the user alias. If it's an
organization, it'll be the organization name.
</td>
</tr>
</tbody>
</table>
</small>
</div>
</div>
</div>
<div className="mt-4 mt-md-5">

View File

@ -67,7 +67,7 @@
]
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -176,10 +176,10 @@ exports[`WebhooksSection renders correctly 2`] = `
Webhooks notify external services when certain events happen.
</p>
<div
class="list-group mt-4 mt-md-5"
class="row mt-3 mt-md-4"
>
<div
class="mb-3"
class="col-12 col-xxl-6 py-sm-3 py-2"
role="listitem"
>
<div
@ -319,7 +319,7 @@ exports[`WebhooksSection renders correctly 2`] = `
</div>
</div>
<div
class="mb-3"
class="col-12 col-xxl-6 py-sm-3 py-2"
role="listitem"
>
<div
@ -459,7 +459,7 @@ exports[`WebhooksSection renders correctly 2`] = `
</div>
</div>
<div
class="mb-3"
class="col-12 col-xxl-6 py-sm-3 py-2"
role="listitem"
>
<div
@ -597,7 +597,7 @@ exports[`WebhooksSection renders correctly 2`] = `
</div>
</div>
<div
class="mb-3"
class="col-12 col-xxl-6 py-sm-3 py-2"
role="listitem"
>
<div
@ -737,7 +737,7 @@ exports[`WebhooksSection renders correctly 2`] = `
</div>
</div>
<div
class="mb-3"
class="col-12 col-xxl-6 py-sm-3 py-2"
role="listitem"
>
<div

View File

@ -23,7 +23,7 @@ const mockUserCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -35,7 +35,7 @@ const mockOrgCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: { selectedOrg: 'test' },
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -115,7 +115,7 @@ const WebhooksSection = (props: Props) => {
)}
</NoData>
) : (
<div className="list-group mt-4 mt-md-5">
<div className="row mt-3 mt-md-4">
{webhooks.map((webhook: Webhook) => (
<WebhookCard
key={`member_${webhook.name}`}

View File

@ -87,3 +87,13 @@
width: 90px;
}
}
@media only screen and (min-width: 1920px) {
.secondLine::before {
content: '\00a0 ';
}
.search {
max-width: 750px;
}
}

View File

@ -1,12 +1,11 @@
.card {
width: 750px;
background-color: transparent !important;
margin: 0 auto;
max-width: 750px;
box-shadow: 0px 0px 5px 0px var(--light);
}
.card:not(:last-child) {
border-bottom: 1px solid var(--color-black-15);
margin-bottom: 1rem;
padding-bottom: 1rem;
.body {
padding: 1.75rem !important;
}
@media only screen and (max-width: 767.98px) {
@ -14,3 +13,16 @@
padding: 0.75rem;
}
}
@media only screen and (min-width: 768px) {
.card {
min-height: 198px;
}
}
@media (hover: hover) {
.card:hover {
border-color: var(--color-1-700);
box-shadow: 0px 0px 5px 0px var(--color-1-900);
}
}

View File

@ -124,7 +124,7 @@ describe('PackageCard', () => {
<PackageCard package={mockPackage} />
</Router>
);
const link = getByTestId('packageLink');
const link = getByTestId('link');
expect(link).toBeInTheDocument();
fireEvent.click(link);
expect(window.location.pathname).toBe(buildPackageURL(mockPackage));

View File

@ -1,17 +1,30 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Package } from '../../types';
import PackageHeader from '../common/PackageInfo';
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={`position-relative mw-100 homeCard ${styles.card}`}>
<div className={`card-body d-flex flex-column ${styles.body}`}>
<PackageHeader package={props.package} withPackageLinks />
<div className={`col-12 col-xxl-5 py-sm-3 py-2 px-0 px-xxl-3 position-relative ${props.className}`}>
<div className={`card cardWithHover h-100 ${styles.card}`}>
<Link
data-testid="link"
className={`text-decoration-none text-reset h-100 ${styles.link}`}
to={{
pathname: buildPackageURL(props.package),
}}
>
<div className={`card-body d-flex flex-column h-100 ${styles.body}`}>
<PackageInfo package={props.package} withPackageLinks={false} />
</div>
</Link>
</div>
</div>
);

View File

@ -1,3 +1,4 @@
.wrapper {
min-height: 500px;
background-color: var(--body-bg);
}

View File

@ -1,3 +1,4 @@
import classnames from 'classnames';
import isUndefined from 'lodash/isUndefined';
import React, { useEffect, useState } from 'react';
@ -39,9 +40,15 @@ const RandomPackages = () => {
<div data-testid="randomPackagesList" className="mw-100 my-2">
<div className="h4 text-center text-secondary mt-3 mt-md-2 mb-4">Explore and discover packages</div>
<div className="pt-2">
{packages.map((item: Package) => {
return <PackageCard key={`rp_${item.packageId}`} package={item} />;
<div className="pt-2 row no-gutters justify-content-center">
{packages.map((item: Package, index: number) => {
return (
<PackageCard
key={`rp_${item.packageId}`}
package={item}
className={classnames({ 'd-none d-xxl-block': index > 4 })}
/>
);
})}
</div>
</div>

View File

@ -2,3 +2,9 @@
font-size: 80%;
font-weight: 300;
}
@media only screen and (min-width: 1920px) {
.tipText {
font-size: 90%;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -9,12 +9,17 @@ exports[`Home index creates snapshot 1`] = `
class="jumbotron mb-0 text-center jumbotron"
>
<div
class="display-4 text-center font-weight-light mainTitle"
class="display-4 text-center font-weight-light d-block d-xxl-flex justify-content-center mainTitle"
role="heading"
>
Find, install and publish
<br />
Kubernetes packages
<div>
Find, install and publish
</div>
<div
class="secondLine"
>
Kubernetes packages
</div>
</div>
<div
class="mt-5 text-center"

View File

@ -95,7 +95,7 @@ describe('Home index', () => {
const mockStats = getMockStats('5');
mocked(API).getStats.mockResolvedValue(mockStats);
const { getByRole } = render(
const { getByRole, getByText } = render(
<Router>
<HomeView {...defaultProps} />
</Router>
@ -104,7 +104,8 @@ describe('Home index', () => {
const heading = await waitFor(() => getByRole('heading'));
expect(heading).toBeInTheDocument();
expect(heading.innerHTML).toBe('Find, install and publish<br>Kubernetes packages');
expect(getByText('Find, install and publish')).toBeInTheDocument();
expect(getByText('Kubernetes packages')).toBeInTheDocument();
await waitFor(() => {});
});
});

View File

@ -60,10 +60,12 @@ const HomeView = (props: Props) => {
return (
<div className={`d-flex flex-column flex-grow-1 ${styles.home} home`}>
<div className={`jumbotron mb-0 text-center ${styles.jumbotron}`}>
<div role="heading" className={`display-4 text-center font-weight-light ${styles.mainTitle}`}>
Find, install and publish
<br />
Kubernetes packages
<div
role="heading"
className={`display-4 text-center font-weight-light d-block d-xxl-flex justify-content-center ${styles.mainTitle}`}
>
<div>Find, install and publish</div>
<div className={styles.secondLine}>Kubernetes packages</div>
</div>
<div className="mt-5 text-center">

View File

@ -18,7 +18,7 @@ const mockCtxLoggedIn = {
user: { alias: 'test', email: 'test@test.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -30,7 +30,7 @@ const mockCtxNotLoggedIn = {
user: null,
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -42,7 +42,7 @@ const mockUndefinedUser = {
user: undefined,
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -50,6 +50,12 @@
}
}
@media only screen and (min-width: 1920px) {
.search {
max-width: 500px;
}
}
@media (hover: hover) {
.button:hover::before {
content: '';

View File

@ -15,7 +15,7 @@ const mockCtxLoggedIn = {
user: { alias: 'test', email: 'test@test.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -27,7 +27,7 @@ const mockCtxNotLoggedIn = {
user: null,
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -39,7 +39,7 @@ const mockUndefinedUser = {
user: undefined,
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -9,7 +9,7 @@ const mockCtx = {
user: { alias: 'test', email: 'test@test.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -9,7 +9,7 @@ const mockCtxLoggedIn = {
user: { alias: 'test', email: 'test@test.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -39,7 +39,7 @@ const CustomResourceDefinition = (props: Props) => {
<div className="row mt-4">
{props.resources.map((resourceDefinition: CustomResourcesDefinition) => {
return (
<div className="col-12 col-lg-6 mb-4" key={`resourceDef_${resourceDefinition.kind}`}>
<div className="col-12 col-lg-6 col-xxl-4 mb-4" key={`resourceDef_${resourceDefinition.kind}`}>
<div className="card h-100" data-testid="resourceDefinition">
<div className="card-body d-flex flex-column">
<h6 className="card-title mb-3">{resourceDefinition.displayName || resourceDefinition.name}</h6>

View File

@ -23,7 +23,7 @@ const OPAPoliciesList = (props: Props) => {
const fileName = pathFile.pop();
const path = pathFile.join('/');
return (
<div className="col-12 col-lg-6 mb-4" key={`policy_${index}`}>
<div className="col-12 col-lg-6 col-xxl-4 mb-4" key={`policy_${index}`}>
<div className={`card h-100 ${styles.card}`} data-testid="policyCard">
<div className="card-body d-flex flex-column">
<div className="d-flex flex-row align-items-baseline">

View File

@ -192,3 +192,18 @@
margin-top: -3px;
}
}
@media only screen and (min-width: 1920px) {
.mainContent {
flex: 0 0 calc(100% - 380px);
max-width: calc(100% - 380px);
}
.info {
width: 310px;
}
.relatedPackagesWrapper {
max-width: 310px;
}
}

View File

@ -52,6 +52,7 @@
}
.md table {
min-width: 100%;
margin-bottom: 16px;
font-size: 0.9rem;
}
@ -79,6 +80,10 @@
margin-top: -3px;
}
.md table .btnLink {
font-size: inherit;
}
@media only screen and (max-width: 575.98px) {
.md {
margin-left: 15px;

View File

@ -1,5 +1,6 @@
import classnames from 'classnames';
import isNull from 'lodash/isNull';
import React, { useLayoutEffect } from 'react';
import React, { useLayoutEffect, useState } from 'react';
import ReactMarkdown from 'react-markdown';
import SyntaxHighlighter from 'react-syntax-highlighter';
import { docco } from 'react-syntax-highlighter/dist/cjs/styles/hljs';
@ -48,7 +49,11 @@ const Readme = (props: Props) => {
};
const Image: React.ElementType = (data: ImageProps) => {
return /^https?:/.test(data.src) ? <img src={data.src} alt={data.alt} /> : null;
const [error, setError] = useState<boolean>(false);
return /^https?:/.test(data.src) ? (
<img src={data.src} alt={data.alt} className={classnames({ 'd-none': error })} onError={() => setError(true)} />
) : null;
};
// Only for external links and anchors
@ -97,7 +102,7 @@ const Readme = (props: Props) => {
let readme = props.markdownContent;
if (!props.markdownContent.startsWith('#')) {
readme = `# ${props.packageName}\n${props.markdownContent}`;
readme = `# ${props.packageName}\n${readme}`;
}
return (
@ -105,7 +110,7 @@ const Readme = (props: Props) => {
<span data-testid="readme">
<ReactMarkdown
className={`mt-3 mb-5 ${styles.md}`}
source={readme}
children={readme}
linkTarget="_blank"
skipHtml
renderers={{
@ -121,4 +126,4 @@ const Readme = (props: Props) => {
);
};
export default Readme;
export default React.memo(Readme);

View File

@ -18,7 +18,7 @@ const mockCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -18,7 +18,7 @@ const mockCtx = {
user: { alias: 'userAlias', email: 'jsmith@email.com' },
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -30,7 +30,7 @@ const mockNotSignedInCtx = {
user: null,
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,
@ -42,7 +42,7 @@ const mockUndefinedUserCtx = {
user: undefined,
prefs: {
controlPanel: {},
search: { limit: 25 },
search: { limit: 60 },
theme: {
configured: 'light',
automatic: false,

View File

@ -117,7 +117,7 @@
"facets": null
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -117,7 +117,7 @@
"facets": null
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -117,7 +117,7 @@
"facets": null
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

View File

@ -477,7 +477,7 @@
"facets": null
},
"metadata": {
"limit": 50,
"limit": 60,
"offset": 0,
"total": 7
}

Some files were not shown because too many files have changed in this diff Show More