Skip to content

Commit

Permalink
Start using Cards as we do in cockpit
Browse files Browse the repository at this point in the history
Otherwise paddings and other styles will look different than cockpit
cards.
  • Loading branch information
KKoukiou authored and marusak committed Nov 27, 2020
1 parent 4349b67 commit bfdb3ba
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 85 deletions.
30 changes: 30 additions & 0 deletions lib/ct-card.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* Rely on the margin from the Card for spacing */
.ct-card.pf-c-card .table {
margin-bottom: 0;
}

.ct-card.pf-c-card .pf-c-card__body.contains-list {
padding-left: 0;
padding-right: 0;
padding-bottom: 0;
}

.ct-card.pf-c-card .pf-c-card__body.contains-list > .pf-c-table > :last-child > tr:last-child {
border-bottom: none;
}

.ct-card.pf-c-card .pf-c-card__header > .pf-c-card__title {
padding: 0;
}

.ct-card.pf-c-card .pf-c-card__title {
font-weight: normal;
}

.ct-card.pf-c-card .pf-c-card__title > h2 {
font-size: var(--pf-global--FontSize--2xl);
}

.ct-card.pf-c-card .pf-c-card__header {
padding: var(--pf-global--spacer--md) var(--pf-global--spacer--md) var(--pf-global--spacer--sm) var(--pf-global--spacer--lg);
}
125 changes: 65 additions & 60 deletions src/Containers.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import React from 'react';
import ReactDOM from "react-dom";
import { Button, Badge, Card, CardBody, CardHeader, CardTitle, CardActions } from '@patternfly/react-core';
import {
Button, Badge,
Card, CardBody, CardHeader, CardTitle, CardActions,
Text, TextVariants
} from '@patternfly/react-core';
import { TrashIcon } from '@patternfly/react-icons';

import cockpit from 'cockpit';
Expand Down Expand Up @@ -442,71 +446,72 @@ class Containers extends React.Component {
</>;

return (
(this.props.containers === null || this.props.pods === null)
? <ListingTable caption={_("Containers")}
variant='compact'
emptyCaption={emptyCaption}
columns={columnTitles}
actions={filterRunning}
rows={[]} />
: <>
<header className='ct-table-header'>
<h3 className='ct-table-heading'> {_("Containers")} </h3>
<div className='ct-table-actions'> {filterRunning} </div>
</header>
{Object.keys(partitionedContainers)
.sort((a, b) => {
if (a == "no-pod") return -1;
else if (b == "no-pod") return 1;

// User pods are in front of system ones
if (this.props.pods[a].isSystem !== this.props.pods[b].isSystem)
return this.props.pods[a].isSystem ? 1 : -1;
return this.props.pods[a].Name > this.props.pods[b].Name ? 1 : -1;
})
.map(section => {
const tableProps = {};
const rows = partitionedContainers[section].map(container => {
return this.renderRow(this.props.containersStats, container,
this.props.containersDetails[container.Id + container.isSystem.toString()]);
});
let caption;
if (section !== 'no-pod') {
tableProps['aria-label'] = cockpit.format("Containers of Pod $0", this.props.pods[section].Name);
caption = this.props.pods[section].Name;
} else {
tableProps['aria-label'] = _("Containers");
}
return (
<Card key={'table-' + section}
<Card id="containers-containers" className="containers-containers">
<CardHeader>
<CardTitle><Text component={TextVariants.h2}>{_("Containers")}</Text></CardTitle>
<CardActions>{filterRunning}</CardActions>
</CardHeader>
<CardBody className="contains-list">
{(this.props.containers === null || this.props.pods === null)
? <ListingTable variant='compact'
aria-label={_("Containers")}
emptyCaption={emptyCaption}
columns={columnTitles}
rows={[]} />
: Object.keys(partitionedContainers)
.sort((a, b) => {
if (a == "no-pod") return -1;
else if (b == "no-pod") return 1;

// User pods are in front of system ones
if (this.props.pods[a].isSystem !== this.props.pods[b].isSystem)
return this.props.pods[a].isSystem ? 1 : -1;
return this.props.pods[a].Name > this.props.pods[b].Name ? 1 : -1;
})
.map(section => {
const tableProps = {};
const rows = partitionedContainers[section].map(container => {
return this.renderRow(this.props.containersStats, container,
this.props.containersDetails[container.Id + container.isSystem.toString()]);
});
let caption;
if (section !== 'no-pod') {
tableProps['aria-label'] = cockpit.format("Containers of Pod $0", this.props.pods[section].Name);
caption = this.props.pods[section].Name;
} else {
tableProps['aria-label'] = _("Containers");
}
return (
<Card key={'table-' + section}
id={'table-' + (section == "no-pod" ? section : this.props.pods[section].Name)}
className={"container-section" + (section != "no-pod" ? " pod-card" : "")}>
{caption && <CardHeader>
<CardTitle>
<span className='pod-name'>{caption}</span>
<span>{_("pod group")}</span>
</CardTitle>
<CardActions className='panel-actions'>
<Badge isRead>{_(this.props.pods[section].Status)}</Badge>
<PodActions onAddNotification={this.props.onAddNotification} pod={this.props.pods[section]} />
</CardActions>
</CardHeader>}
<CardBody>
<ListingTable variant='compact'
{caption && <CardHeader>
<CardTitle>
<span className='pod-name'>{caption}</span>
<span>{_("pod group")}</span>
</CardTitle>
<CardActions className='panel-actions'>
<Badge isRead>{_(this.props.pods[section].Status)}</Badge>
<PodActions onAddNotification={this.props.onAddNotification} pod={this.props.pods[section]} />
</CardActions>
</CardHeader>}
<CardBody>
<ListingTable variant='compact'
emptyCaption={section == "no-pod" ? emptyCaption : emptyCaptionPod}
columns={columnTitles}
rows={rows}
{...tableProps} />
</CardBody>
</Card>
);
})}
{containerDeleteModal}
{containerCheckpointModal}
{containerRestoreModal}
{containerRemoveErrorModal}
{this.state.showCommitModal && containerCommitModal}
</>
</CardBody>
</Card>
);
})}
</CardBody>
{containerDeleteModal}
{containerCheckpointModal}
{containerRestoreModal}
{containerRemoveErrorModal}
{this.state.showCommitModal && containerCommitModal}
</Card>
);
}
}
Expand Down
30 changes: 19 additions & 11 deletions src/Images.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import React from 'react';
import { Button } from '@patternfly/react-core';
import {
Button,
Card, CardBody, CardHeader, CardTitle, CardActions,
Text, TextVariants
} from '@patternfly/react-core';
import { PlayIcon, PlusIcon, TrashIcon } from '@patternfly/react-icons';

import cockpit from 'cockpit';
Expand Down Expand Up @@ -244,15 +248,19 @@ class Images extends React.Component {
/>;

return (
<>
<ListingTable caption={_("Images")}
variant='compact'
emptyCaption={emptyCaption}
columns={columnTitles}
rows={imageRows}
actions={getNewImageAction}
/>
{toggleIntermediate}
<Card id="containers-images" key="images" className="containers-images">
<CardHeader>
<CardTitle><Text component={TextVariants.h2}>{_("Images")}</Text></CardTitle>
<CardActions>{getNewImageAction}</CardActions>
</CardHeader>
<CardBody className="contains-list">
<ListingTable aria-label={_("Images")}
variant='compact'
emptyCaption={emptyCaption}
columns={columnTitles}
rows={imageRows} />
{toggleIntermediate}
</CardBody>
{imageRemoveErrorModal}
{this.state.selectImageDeleteModal &&
<ImageDeleteModal
Expand All @@ -273,7 +281,7 @@ class Images extends React.Component {
userServiceAvailable={this.props.userServiceAvailable}
systemServiceAvailable={this.props.systemServiceAvailable} /> }
{this.state.imageDownloadInProgress && <div className='download-in-progress'> {_("Pulling")} {this.state.imageDownloadInProgress}... </div>}
</>
</Card>
);
}
}
Expand Down
10 changes: 3 additions & 7 deletions src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import React from 'react';
import {
Page, PageSection, PageSectionVariants, Card, Gallery,
Page, PageSection, PageSectionVariants, Gallery,
Alert, AlertActionLink, AlertActionCloseButton, AlertGroup,
Button, Checkbox, Title,
EmptyState, EmptyStateVariant, EmptyStateIcon, EmptyStateSecondaryActions
Expand Down Expand Up @@ -682,12 +682,8 @@ class Application extends React.Component {
<PageSection>
<Gallery hasGutter>
{ this.state.showStartService ? startService : null }
<Card id="containers-containers" className="containers-containers">
{containerList}
</Card>
<Card id="containers-images" key="images" className="containers-images">
{imageList}
</Card>
{containerList}
{imageList}
</Gallery>
</PageSection>
</Page>
Expand Down
4 changes: 3 additions & 1 deletion src/podman.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
@import '../lib/ct-card.scss';

#app .pf-l-gallery {
--pf-l-gallery--GridTemplateColumns: 1fr;
}
#app .pf-c-card.containers-containers, #app .pf-c-card.containers-images {
padding: 1rem;
@extend .ct-card;
}

// Stretch body to fill the page
Expand Down
12 changes: 6 additions & 6 deletions test/check-application
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ registries = ['localhost:5000', 'localhost:6000']
"""

def checkImage(browser, name, owner):
browser.wait_present("#containers-images > table")
browser.wait_present("#containers-images table")
browser.wait_js_func("""(function (first, last) {
let items = ph_select("#containers-images > table tbody");
let items = ph_select("#containers-images table tbody");
for (i = 0; i < items.length; i++)
if (items[i].innerText.trim().startsWith(first) && items[i].innerText.trim().endsWith(last))
return true;
Expand Down Expand Up @@ -199,7 +199,7 @@ class TestApplication(testlib.MachineCase):
b.wait_not_present("#containers-containers-owner")

# Also user selection in image download should not be visible
b.click("header button:contains(Get new image)")
b.click("button:contains(Get new image)")
b.wait_present('div.pf-c-modal-box header:contains("Search for an image")')
b.wait_present("div.pf-c-modal-box footer button:contains(Download):disabled")
b.wait_not_present("#as-user")
Expand Down Expand Up @@ -232,7 +232,7 @@ class TestApplication(testlib.MachineCase):
b.wait_present("#containers-containers-owner")

# Also user selection in image download should be visible
b.click("header button:contains(Get new image)")
b.click("button:contains(Get new image)")
b.wait_present('div.pf-c-modal-box header:contains("Search for an image")')
b.wait_present("div.pf-c-modal-box footer button:contains(Download):disabled")
b.wait_present("#as-user")
Expand Down Expand Up @@ -629,7 +629,7 @@ class TestApplication(testlib.MachineCase):

def openDialog(self):
# Open get new image modal
b.click("header button:contains(Get new image)")
b.click("button:contains(Get new image)")
b.wait_present('div.pf-c-modal-box header:contains("Search for an image")')
b.wait_present("div.pf-c-modal-box footer button:contains(Download):disabled")

Expand Down Expand Up @@ -713,7 +713,7 @@ class TestApplication(testlib.MachineCase):
b.wait_present("#app")

# Test registries
b.click("header button:contains(Get new image)")
b.click("button:contains(Get new image)")
b.wait_present('div.pf-c-modal-box header:contains("Search for an image")')
# HACK: Sometimes the value is not shown fully. FIXME
b.set_input_text("#search-image-dialog-name", "my-busybox", value_check=False)
Expand Down

0 comments on commit bfdb3ba

Please sign in to comment.