Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion cypress/fixtures/flows/dashboard-tables.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,30 @@
]
]
},
{
"id": "dashboard-ui-table-fixed-height",
"type": "ui-table",
"z": "node-red-tab-tables",
"group": "dashboard-ui-group",
"name": "Fixed Height",
"label": "fixed height",
"action": "replace",
"order": 7,
"width": 6,
"height": 8,
"maxrows": 0,
"passthru": false,
"autocols": true,
"selectionType": "none",
"columns": [],
"x": 320,
"y": 320,
"wires": [
[
"test-helper"
]
]
},
{
"id": "1ad285ca06fd711f",
"type": "inject",
Expand All @@ -67,7 +91,8 @@
"dashboard-ui-table-single-row-click",
"dashboard-ui-table-multi-select",
"dashboard-ui-table-table-buttons-string-value",
"dashboard-ui-table-buttons-text-from-payload"
"dashboard-ui-table-buttons-text-from-payload",
"dashboard-ui-table-fixed-height"
]
]
},
Expand Down
10 changes: 10 additions & 0 deletions cypress/tests/widgets/table.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ describe('Node-RED Dashboard 2.0 - Tables', () => {
cy.get('#nrdb-ui-widget-dashboard-ui-table-default').find('.v-data-table-footer').should('not.exist')
})

it('renders the provided data when a fixed widget size (not auto) is configured', () => {
// with a fixed size the table was clamped to a single grid row, hiding all but the first row
const widget = '#nrdb-ui-widget-dashboard-ui-table-fixed-height'
cy.get(widget).find('tbody tr').should('have.length', 5)
// a row beyond the first should be visible - i.e. not clipped into a single-row-high table
cy.get(widget).find('tbody tr').eq(3).should('be.visible')
// the table should fill the widget's fixed height rather than collapse to a single row
cy.get(widget).find('.nrdb-table').invoke('outerHeight').should('be.greaterThan', 150)
})

it('render the provided data, with a pagination limit if defined', () => {
cy.get('#nrdb-ui-widget-dashboard-ui-table-max-rows').find('tbody tr').should('have.length', 2)
cy.get('#nrdb-ui-widget-dashboard-ui-table-max-rows').find('tbody .v-selection-control').should('have.length', 0)
Expand Down
98 changes: 54 additions & 44 deletions ui/src/widgets/ui-table/UITable.vue
Original file line number Diff line number Diff line change
@@ -1,46 +1,48 @@
<template>
<label v-if="props.label" ref="title" class="nrdb-ui-table-title">{{ props.label }}</label>
<v-text-field
v-if="props.showSearch"
v-model="search"
label="Search"
prepend-inner-icon="mdi-magnify"
variant="outlined"
hide-details
single-line
/>
<v-data-table
ref="table"
v-model="selected"
class="nrdb-table"
:mobile="isMobile"
:class="{'nrdb-table--mobile': isMobile}"
:items="payload || []" :return-object="true"
:items-per-page="itemsPerPage"
:headers="headers" :show-select="props.selectionType === 'checkbox'"
:search="search"
@update:model-value="onMultiSelect"
>
<template v-if="itemsPerPage === 0" #bottom />
<template #item="{ item, index, internalItem, isSelected, toggleSelect }">
<tr
:class="{'nrdb-table-row-selectable': props.selectionType === 'click', 'nrdb-table-row-selected': selected === item, 'v-data-table__tr--mobile': isMobile}"
@click="props.selectionType === 'click' ? onRowClick(item) : {}"
>
<td v-if="props.selectionType === 'checkbox'" class="v-data-table__td v-data-table-column--no-padding v-data-table-column--align-start">
<v-checkbox-btn :modelValue="isSelected(internalItem)" @click="toggleSelect(internalItem)" />
</td>
<td v-for="col in headers" :key="col.key" :data-column-key="col.key">
<div v-if="isMobile">
{{ col.title }}
</div>
<div class="nrdb-table-cell-align" :style="{'justify-content': isMobile ? 'end' : (col.align || 'start')}">
<UITableCell :row="index + 1" :item="item" :property="col.key" :propertyType="col.keyType" :type="col.type" @action-click="onCellClick" />
</div>
</td>
</tr>
</template>
</v-data-table>
<div class="nrdb-ui-table-wrapper">
<label v-if="props.label" ref="title" class="nrdb-ui-table-title">{{ props.label }}</label>
<v-text-field
v-if="props.showSearch"
v-model="search"
label="Search"
prepend-inner-icon="mdi-magnify"
variant="outlined"
hide-details
single-line
/>
<v-data-table
ref="table"
v-model="selected"
class="nrdb-table"
:mobile="isMobile"
:class="{'nrdb-table--mobile': isMobile}"
:items="payload || []" :return-object="true"
:items-per-page="itemsPerPage"
:headers="headers" :show-select="props.selectionType === 'checkbox'"
:search="search"
@update:model-value="onMultiSelect"
>
<template v-if="itemsPerPage === 0" #bottom />
<template #item="{ item, index, internalItem, isSelected, toggleSelect }">
<tr
:class="{'nrdb-table-row-selectable': props.selectionType === 'click', 'nrdb-table-row-selected': selected === item, 'v-data-table__tr--mobile': isMobile}"
@click="props.selectionType === 'click' ? onRowClick(item) : {}"
>
<td v-if="props.selectionType === 'checkbox'" class="v-data-table__td v-data-table-column--no-padding v-data-table-column--align-start">
<v-checkbox-btn :modelValue="isSelected(internalItem)" @click="toggleSelect(internalItem)" />
</td>
<td v-for="col in headers" :key="col.key" :data-column-key="col.key">
<div v-if="isMobile">
{{ col.title }}
</div>
<div class="nrdb-table-cell-align" :style="{'justify-content': isMobile ? 'end' : (col.align || 'start')}">
<UITableCell :row="index + 1" :item="item" :property="col.key" :propertyType="col.keyType" :type="col.type" @action-click="onCellClick" />
</div>
</td>
</tr>
</template>
</v-data-table>
</div>
</template>

<script>
Expand Down Expand Up @@ -268,8 +270,16 @@ export default {
</script>

<style>
.nrdb-ui-table {
overflow-y: auto;
.nrdb-ui-table-wrapper {
display: flex;
flex-direction: column;
min-height: 0;
height: 100%;
overflow: hidden;
}
.nrdb-ui-table-wrapper > .nrdb-table.v-table {
flex: 1 1 auto;
min-height: 0;
}

.nrdb-table.v-table {
Expand Down
Loading