I've been playing with v-data-table and have gotten as far as can at the moment.
I've used the CSV file upload example and most the work has been on CCS styling of the table.
I used the headers option to pass up custom headers as I wanted to shorten column names.
This is done in a function node and reference as msg?.headers.
I've been able to reduce a "security key" col and use the expand option to view it. However every row expands at the moment where as it should only be the clicked row. The CCS below reduces the row hight to make a more compact search/table/footer.
The flow below might be of help to others that want a customised table.
// CSS
<style>
// define any styles here - supports raw CSS
.v-field__field {padding: 0 0px 0 6px !important; height:35px; min-height: 35px;}
.v-field__input{padding: 0 0px 0 6px !important; height:35px; min-height: 35px;}
.v-data-table { width: 1755px; }
.v-data-table-column--no-padding {padding: 0 0px 0 6px !important;}
.v-data-table-column--align-start {padding: 0 0px 0 6px !important;}
.v-data-table-header__content {color: black; font-weight: bold; height:40px; min-height: 40px; }
.v-data-table-header__content:hover {color: black; font-weight: bold;}
.v-data-table__th {background-color: #B3C1C6; white-space: nowrap;}
.v-data-table .v-data-table__td {white-space: nowrap; height: 40px !important; min-height: 40px !important;}
.v-table__wrapper tr:nth-child(even){background-color: #f2f2f2;}
.v-table__wrapper tr:hover {background-color: #ddd; color: black;}
.v-data-table-footer { background-color: #B3C1C6; color: black; height: 43px !important; min-height: 43px !important; padding:0;}
.v-data-table-footer .v-input__control {height: 35px !important; min-height: 30px !important; padding:0}
</style>
// Flow
[
{
"id": "3b1c8b1a52f7af8e",
"type": "ui-template",
"z": "ccbf14926ab59f7f",
"group": "8a94c465ccc99808",
"page": "",
"ui": "",
"name": "UPLOAD",
"order": 0,
"width": "3",
"height": "2",
"head": "",
"format": "<v-file-input show-size multiple chips :rules=\"rules\" accept=\".csv\"\n variant=\"underlined\" label=\"\" v-on:change=\"uploadFile\" v-model=\"value\"\n active-color=\"primary\" @update:modelValue=\"send({payload: value})\" prepend-icon=\"mdi-text-box-outline\" />\n",
"storeOutMessages": true,
"passthru": true,
"resendOnRefresh": true,
"templateScope": "local",
"className": "",
"x": 160,
"y": 120,
"wires": [
[
"c16c52e40cce67e4"
]
]
},
{
"id": "c16c52e40cce67e4",
"type": "change",
"z": "ccbf14926ab59f7f",
"name": "",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "payload[0]",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 255,
"y": 120,
"wires": [
[
"fe397451602922bf"
]
],
"l": false
},
{
"id": "fe397451602922bf",
"type": "function",
"z": "ccbf14926ab59f7f",
"name": "Convert Hex to String",
"func": "const hexBuffer = msg.payload;\n\n// Convert the hex buffer to a Buffer object\nconst buffer = Buffer.from(hexBuffer, 'hex');\n\n// Convert the Buffer to a string\nconst string = buffer.toString();\n\n// Assign the string to msg.payload for further processing\nmsg.payload = string;\n\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 315,
"y": 120,
"wires": [
[
"fd9e67b2a0e7d8fd"
]
],
"l": false
},
{
"id": "fd9e67b2a0e7d8fd",
"type": "csv",
"z": "ccbf14926ab59f7f",
"name": "",
"sep": ",",
"hdrin": true,
"hdrout": "none",
"multi": "mult",
"ret": "\\n",
"temp": "",
"skip": "0",
"strings": true,
"include_empty_strings": "",
"include_null_values": "",
"x": 375,
"y": 120,
"wires": [
[
"0198aa546d9f0815"
]
],
"l": false
},
{
"id": "0198aa546d9f0815",
"type": "change",
"z": "ccbf14926ab59f7f",
"name": "",
"rules": [
{
"t": "set",
"p": "CSV",
"pt": "flow",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 435,
"y": 120,
"wires": [
[
"953a43666f537f44",
"9a140742e675322c",
"c93eb9884699e05a"
]
],
"l": false
},
{
"id": "953a43666f537f44",
"type": "function",
"z": "ccbf14926ab59f7f",
"name": "headers",
"func": "msg.headers = [\n {title: \"customer\", key:\"customer\"},\n {title: \"project\", key: \"project\"},\n {title: \"ver\", key: \"version\"},\n {title: \"Gateway\", key:\"gateway_name\"},\n {title: \"manf\", key:\"manufacturer\"},\n {title: \"model\", key:\"model\"},\n {title: \"devEUI\", key:\"devEUI\"},\n {title: \"appEUI\", key:\"appEUI\"},\n {title: \"appKey\", key:\"appkey\"},\n {title: \"HW ver\", key:\"hardware\"},\n {title: \"FW ver\", key:\"firmware\"},\n {title: \"name\", key:\"device_name\"},\n {title: \"tag\", key:\"tagging\"},\n { title: '', key: 'data-table-expand' }\n]\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 535,
"y": 120,
"wires": [
[
"5ea7c9b33f60bd6e"
]
],
"l": false
},
{
"id": "5ea7c9b33f60bd6e",
"type": "ui-template",
"z": "ccbf14926ab59f7f",
"group": "760f720c21457605",
"page": "",
"ui": "",
"name": "Expandable Custom table",
"order": 2,
"width": "5",
"height": "1",
"head": "",
"format": "<template>\n <v-card\n flat\n width=1555\n >\n <!-- Provide an input text box to search the content -->\n <v-text-field v-model=\"search\" label=\"Search\" prepend-inner-icon=\"mdi-magnify\" single-line variant=\"outlined\" hide-details ></v-text-field>\n <v-data-table v-model:search=\"search\" :items=\"msg?.payload\" :headers=\"msg?.headers\" v-model:custom-filter=\"customSearch\" show-expand >\n <template v-slot:header.current>\n <div class=\"text-center\">Center-Aligned</div>\n </template>\n <template v-slot:item.appKey=\"{ item }\">\n <div style=\"width: 40px; height:20px; overflow: hidden;\">{{item.appKey}} </div>\n </template>\n <template v-slot:expanded-row=\"{ columns, item }\">\n <td :colspan=\"3\" style=\"text-align: left; height:50px; background-color:#F4F9FC;\">\n <div style=\"padding-left:15px;\"> {{item.appKey }}</div>\n </td>\n </template>\n </v-data-table>\n </v-card>\n \n</template>\n\n<script>\n export default {\n data () {\n return {\n search: ''\n }\n }\n }\n</script>\n\n<style>\n// define any styles here - supports raw CSS\n.v-field__field {padding: 0 0px 0 6px !important; height:35px; min-height: 35px;}\n.v-field__input{padding: 0 0px 0 6px !important; height:35px; min-height: 35px;}\n.v-data-table { width: 1755px; }\n.v-data-table-column--no-padding {padding: 0 0px 0 6px !important;}\n.v-data-table-column--align-start {padding: 0 0px 0 6px !important;}\n.v-data-table-header__content {color: black; font-weight: bold; height:40px; min-height: 40px; }\n.v-data-table-header__content:hover {color: black; font-weight: bold;}\n.v-data-table__th {background-color: #B3C1C6; white-space: nowrap;}\n.v-data-table .v-data-table__td {white-space: nowrap; height: 40px !important; min-height: 40px !important;}\n.v-table__wrapper tr:nth-child(even){background-color: #f2f2f2;}\n.v-table__wrapper tr:hover {background-color: #ddd; color: black;}\n.v-data-table-footer { background-color: #B3C1C6; color: black; height: 43px !important; min-height: 43px !important; padding:0;}\n.v-data-table-footer .v-input__control {height: 35px !important; min-height: 30px !important; padding:0}\n</style>\n",
"storeOutMessages": true,
"passthru": false,
"resendOnRefresh": true,
"templateScope": "local",
"className": "",
"x": 600,
"y": 144,
"wires": [
[]
],
"l": false
},
{
"id": "8a94c465ccc99808",
"type": "ui-group",
"name": "CSV upload",
"page": "76f6b77509a74a17",
"width": "3",
"height": "2",
"order": -1,
"showTitle": true,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "760f720c21457605",
"type": "ui-group",
"name": "Devices",
"page": "76f6b77509a74a17",
"width": "9",
"height": "1",
"order": -1,
"showTitle": true,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "76f6b77509a74a17",
"type": "ui-page",
"name": "Device CSV Upload",
"ui": "42751b5153d87eac",
"path": "/",
"icon": "tray-arrow-up",
"layout": "grid",
"theme": "0d92c765bfad87e6",
"order": 1,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "42751b5153d87eac",
"type": "ui-base",
"name": "baseNode",
"path": "/dashboard",
"includeClientData": true,
"acceptsClientConfig": [
"ui-notification",
"ui-control"
],
"showPathInSidebar": false,
"navigationStyle": "icon"
},
{
"id": "0d92c765bfad87e6",
"type": "ui-theme",
"name": "Basic Blue Theme",
"colors": {
"surface": "#506f86",
"primary": "#b3c1c6",
"bgPage": "#ffffff",
"groupBg": "#ffffff",
"groupOutline": "#f0f0f0"
},
"sizes": {
"pagePadding": "12px",
"groupGap": "12px",
"groupBorderRadius": "4px",
"widgetGap": "12px"
}
}
]