Skip to content
This repository was archived by the owner on Jul 30, 2025. It is now read-only.

Commit f7ccdf1

Browse files
myan9starpit
authored andcommitted
feat(plugins/plugin-client-common): empty tables use PatternFly's "empty state" UI
Fixes #6867
1 parent 3a593b7 commit f7ccdf1

File tree

5 files changed

+49
-19
lines changed

5 files changed

+49
-19
lines changed

packages/test/src/api/selectors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ export const TABLE_AS_SEQUENCE = (N: number) => `${OUTPUT_N(N)} .kui--data-table
223223
export const TABLE_AS_SEQUENCE_BAR = (N: number) => `${TABLE_AS_SEQUENCE(N)} .kui--bar`
224224
export const TABLE_AS_SEQUENCE_BAR_WIDTH = (N: number, width: string) =>
225225
`${TABLE_AS_SEQUENCE(N)} .kui--bar[data-width="${width}]`
226+
export const _TABLE_EMPTY = `.kui--table-like-wrapper tbody td[data-is-empty="true"]`
226227

227228
const _TABLE_TITLE = `.kui--data-table-title`
228229
export const TABLE_TITLE = (N: number) => `${OUTPUT_N(N)} ${_TABLE_TITLE}`

plugins/plugin-client-common/i18n/resources_en_US.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"Try getting started": "Try getting started",
5959
"Settings": "Settings",
6060
"Switch theme": "Switch theme",
61+
"No results found": "No results found",
6162
"Show as table in terminal": "Show as table in terminal",
6263
"Pause watcher": "Pause this watcher",
6364
"Resume watcher": "Resume this watcher",

plugins/plugin-client-common/src/components/Content/Table/TableBody.tsx

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { Table, Tab, REPL } from '@kui-shell/core'
17+
import { i18n, Table, Tab, REPL } from '@kui-shell/core'
1818

1919
import React from 'react'
20-
import { Tbody, Tr } from '@patternfly/react-table'
20+
import { Tbody, Tr, Td } from '@patternfly/react-table'
21+
import { EmptyState, EmptyStateVariant, Bullseye, Title, EmptyStateIcon } from '@patternfly/react-core'
22+
import { SearchIcon } from '@patternfly/react-icons'
2123

2224
import renderCell from './TableCell'
2325

26+
const strings = i18n('plugin-client-common')
27+
2428
/**
2529
* Render the TableBody part
2630
*
@@ -34,24 +38,42 @@ export default function renderBody(
3438
repl: REPL,
3539
offset: number
3640
) {
41+
const emptyState = () => {
42+
return (
43+
<Tr>
44+
<Td data-is-empty={true} colSpan={kuiTable.header ? kuiTable.header.attributes.length + 1 : 0}>
45+
<Bullseye>
46+
<EmptyState variant={EmptyStateVariant.small}>
47+
<EmptyStateIcon icon={SearchIcon} />
48+
<Title headingLevel="h2" size="lg">
49+
{strings('No results found')}
50+
</Title>
51+
</EmptyState>
52+
</Bullseye>
53+
</Td>
54+
</Tr>
55+
)
56+
}
3757
return (
3858
<Tbody>
39-
{kuiTable.body.map((kuiRow, ridx) => {
40-
const updated = justUpdated[kuiRow.rowKey || kuiRow.name]
41-
const cell = renderCell(kuiTable, kuiRow, updated, tab, repl)
59+
{kuiTable.body.length === 0
60+
? emptyState()
61+
: kuiTable.body.map((kuiRow, ridx) => {
62+
const updated = justUpdated[kuiRow.rowKey || kuiRow.name]
63+
const cell = renderCell(kuiTable, kuiRow, updated, tab, repl)
4264

43-
const key = kuiRow.key || (kuiTable.header ? kuiTable.header.key || kuiTable.header.name : undefined)
65+
const key = kuiRow.key || (kuiTable.header ? kuiTable.header.key || kuiTable.header.name : undefined)
4466

45-
return (
46-
<Tr key={ridx} data-row-key={kuiRow.rowKey} data-name={kuiTable.body[offset + ridx].name}>
47-
{cell(key, kuiRow.name, undefined, kuiRow.outerCSS, kuiRow.css, kuiRow.onclick, 0)}
48-
{kuiRow.attributes &&
49-
kuiRow.attributes.map((attr, idx) =>
50-
cell(attr.key, attr.value, attr.tag, attr.outerCSS, attr.css, attr.onclick, idx + 1)
51-
)}
52-
</Tr>
53-
)
54-
})}
67+
return (
68+
<Tr key={ridx} data-row-key={kuiRow.rowKey} data-name={kuiTable.body[offset + ridx].name}>
69+
{cell(key, kuiRow.name, undefined, kuiRow.outerCSS, kuiRow.css, kuiRow.onclick, 0)}
70+
{kuiRow.attributes &&
71+
kuiRow.attributes.map((attr, idx) =>
72+
cell(attr.key, attr.value, attr.tag, attr.outerCSS, attr.css, attr.onclick, idx + 1)
73+
)}
74+
</Tr>
75+
)
76+
})}
5577
</Tbody>
5678
)
5779
}

plugins/plugin-client-common/web/scss/components/Table/tables.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,12 @@ body[kui-theme-style] .kui--data-table-wrapper {
232232
th {
233233
padding-left: var(--pf-c-card--child--PaddingLeft);
234234
}
235+
236+
td {
237+
h2 {
238+
margin: 0;
239+
}
240+
}
235241
}
236242

237243
.pf-m-wrap {

plugins/plugin-core-support/src/test/core-support2/history.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ describe('command history plain', function(this: Common.ISuite) {
106106

107107
it(`should list history with filter, expect nothing`, () =>
108108
CLI.command(`history gumbogumbo`, this.app)
109-
.then(ReplExpect.justOK) // some random string that won't be in the command history
109+
.then(ReplExpect.okWithCustom({ selector: Selectors._TABLE_EMPTY }))
110110
.catch(Common.oops(this, true)))
111111

112112
it(`should delete command history`, () =>
@@ -116,7 +116,7 @@ describe('command history plain', function(this: Common.ISuite) {
116116

117117
it(`should list history with no args after delete and expect nothing`, () =>
118118
CLI.command(`history`, this.app)
119-
.then(ReplExpect.justOK)
119+
.then(ReplExpect.okWithCustom({ selector: Selectors._TABLE_EMPTY }))
120120
.catch(Common.oops(this, true)))
121121

122122
it(`should list history with idx arg after delete and expect only the previous`, () =>
@@ -131,6 +131,6 @@ describe('command history plain', function(this: Common.ISuite) {
131131

132132
it(`should list history with idx and filter args after delete and expect nothing`, () =>
133133
CLI.command(`history 10 lls`, this.app)
134-
.then(ReplExpect.justOK) // some random string that won't be in the command history
134+
.then(ReplExpect.okWithCustom({ selector: Selectors._TABLE_EMPTY }))
135135
.catch(Common.oops(this, true)))
136136
})

0 commit comments

Comments
 (0)