From bfdb3ba2fe2d8a81c331edf8eed4fd8b708b399c Mon Sep 17 00:00:00 2001 From: Katerina Koukiou Date: Tue, 17 Nov 2020 16:30:59 +0100 Subject: [PATCH] Start using Cards as we do in cockpit Otherwise paddings and other styles will look different than cockpit cards. --- lib/ct-card.scss | 30 ++++++++++ src/Containers.jsx | 125 +++++++++++++++++++++-------------------- src/Images.jsx | 30 ++++++---- src/app.jsx | 10 +--- src/podman.scss | 4 +- test/check-application | 12 ++-- 6 files changed, 126 insertions(+), 85 deletions(-) create mode 100644 lib/ct-card.scss diff --git a/lib/ct-card.scss b/lib/ct-card.scss new file mode 100644 index 000000000..db8f287fb --- /dev/null +++ b/lib/ct-card.scss @@ -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); +} diff --git a/src/Containers.jsx b/src/Containers.jsx index ff7b25695..ac6a34df5 100644 --- a/src/Containers.jsx +++ b/src/Containers.jsx @@ -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'; @@ -442,71 +446,72 @@ class Containers extends React.Component { ; return ( - (this.props.containers === null || this.props.pods === null) - ? - : <> -
-

{_("Containers")}

-
{filterRunning}
-
- {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 ( - + + {_("Containers")} + {filterRunning} + + + {(this.props.containers === null || this.props.pods === null) + ? + : 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 ( + - {caption && - - {caption} - {_("pod group")} - - - {_(this.props.pods[section].Status)} - - - } - - + + {caption} + {_("pod group")} + + + {_(this.props.pods[section].Status)} + + + } + + - - - ); - })} - {containerDeleteModal} - {containerCheckpointModal} - {containerRestoreModal} - {containerRemoveErrorModal} - {this.state.showCommitModal && containerCommitModal} - + + + ); + })} + + {containerDeleteModal} + {containerCheckpointModal} + {containerRestoreModal} + {containerRemoveErrorModal} + {this.state.showCommitModal && containerCommitModal} + ); } } diff --git a/src/Images.jsx b/src/Images.jsx index 54c5cfa6f..a39e5213d 100644 --- a/src/Images.jsx +++ b/src/Images.jsx @@ -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'; @@ -244,15 +248,19 @@ class Images extends React.Component { />; return ( - <> - - {toggleIntermediate} + + + {_("Images")} + {getNewImageAction} + + + + {toggleIntermediate} + {imageRemoveErrorModal} {this.state.selectImageDeleteModal && } {this.state.imageDownloadInProgress &&
{_("Pulling")} {this.state.imageDownloadInProgress}...
} - +
); } } diff --git a/src/app.jsx b/src/app.jsx index 8f776a41b..678f36d12 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -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 @@ -682,12 +682,8 @@ class Application extends React.Component { { this.state.showStartService ? startService : null } - - {containerList} - - - {imageList} - + {containerList} + {imageList} diff --git a/src/podman.scss b/src/podman.scss index 93172babd..856a1a9c6 100644 --- a/src/podman.scss +++ b/src/podman.scss @@ -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 diff --git a/test/check-application b/test/check-application index d8e6b288c..a543d41eb 100755 --- a/test/check-application +++ b/test/check-application @@ -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; @@ -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") @@ -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") @@ -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") @@ -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)