diff --git a/.betterer.eslint.config.js b/.betterer.eslint.config.js index c1a38731291..ae8b600826f 100644 --- a/.betterer.eslint.config.js +++ b/.betterer.eslint.config.js @@ -157,4 +157,23 @@ module.exports = [ 'no-barrel-files/no-barrel-files': 'error', }, }, + { + // custom rule for Table to avoid performance regressions + files: ['packages/grafana-ui/src/components/Table/TableNG/Cells/**/*.{ts,tsx}'], + rules: { + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['**/themes/ThemeContext'], + importNames: ['useStyles2', 'useTheme2'], + message: + 'Do not use "useStyles2" or "useTheme2" in a cell directly. Instead, provide styles to cells via `getDefaultCellStyles` or `getCellSpecificStyles`.', + }, + ], + }, + ], + }, + }, ]; diff --git a/devenv/dev-dashboards/panel-table/table_kitchen_sink.json b/devenv/dev-dashboards/panel-table/table_kitchen_sink.json index 9c05634b066..77ba090a0df 100644 --- a/devenv/dev-dashboards/panel-table/table_kitchen_sink.json +++ b/devenv/dev-dashboards/panel-table/table_kitchen_sink.json @@ -18,7 +18,7 @@ "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, - "id": 138, + "id": 21409, "links": [], "panels": [ { @@ -78,6 +78,10 @@ { "id": "max", "value": 100 + }, + { + "id": "custom.inspect", + "value": true } ] }, @@ -140,14 +144,14 @@ }, { "matcher": { - "id": "byName", - "options": "Image" + "id": "byRegexp", + "options": "/Image/" }, "properties": [ { "id": "custom.cellOptions", "value": { - "alt": "${__value}", + "alt": "Grafana icon", "type": "image" } } @@ -278,7 +282,7 @@ }, { "id": "custom.width", - "value": 300 + "value": 255 } ] }, @@ -291,7 +295,8 @@ { "id": "custom.cellOptions", "value": { - "type": "pill" + "type": "pill", + "wrapText": true } }, { @@ -309,7 +314,8 @@ { "id": "custom.cellOptions", "value": { - "type": "data-links" + "type": "data-links", + "wrapText": true } }, { @@ -329,7 +335,7 @@ }, { "id": "custom.width", - "value": 180 + "value": 139 } ] }, @@ -339,12 +345,65 @@ "options": "Gauge" }, "properties": [] + }, + { + "matcher": { + "id": "byName", + "options": "Action" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "actions" + } + }, + { + "id": "actions", + "value": [ + { + "confirmation": "", + "fetch": { + "body": "{}", + "headers": [["Content-Type", "application/json"]], + "method": "GET", + "queryParams": [], + "url": "/api/health" + }, + "title": "Get instance health", + "type": "fetch" + } + ] + }, + { + "id": "custom.width", + "value": 142 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Image w/ Link" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Grafana Cloud Products", + "url": "https://grafana.com/products/cloud/" + } + ] + } + ] } ] }, "gridPos": { - "h": 15, - "w": 24, + "h": 12, + "w": 16, "x": 0, "y": 0 }, @@ -360,9 +419,14 @@ }, "frameIndex": 0, "showHeader": true, - "sortBy": [] + "sortBy": [ + { + "desc": false, + "displayName": "Long Text" + } + ] }, - "pluginVersion": "12.1.0-pre", + "pluginVersion": "12.2.0-pre", "targets": [ { "datasource": { @@ -372,7 +436,7 @@ "scenarioId": "random_walk_table" }, { - "csvContent": "Info,Image,Pills,Data Link,Long Text\ndown,https://placecats.com/millie/200/400,hello,https://grafana.com,\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse tempus et augue et lacinia. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec eu pretium tortor. Cras venenatis sapien sed mauris gravida, ut scelerisque est fringilla. Cras lorem diam, facilisis nec malesuada in, vulputate vel enim. Etiam fringilla nisi quis felis blandit tincidunt. Cras id lacus ornare, ullamcorper nisl eget, bibendum odio. Pellentesque imperdiet, leo a imperdiet venenatis, ligula risus venenatis quam, vel euismod magna nisi sit amet leo.\"\nup,https://placecats.com/neo/200/400,\"[1,2,3,\"\"foo\"\",\"\"bar\"\"]\",https://grafana.com/solutions/kubernetes/,\"Sed imperdiet eget diam sit amet fringilla. Curabitur quis lacus blandit, mollis diam non, accumsan tortor. Aliquam ac tellus eget dui facilisis tempor eu id nulla. Maecenas ultrices turpis eu elementum imperdiet. Fusce eget rhoncus mi, et egestas lectus. Mauris facilisis auctor enim sed malesuada. Maecenas placerat ultricies metus vitae viverra. In hac habitasse platea dictumst. Mauris ipsum nisl, dictum eu aliquam eleifend, rutrum id orci. Nullam eget dui et odio eleifend porttitor.\"\nup fast,https://placecats.com/bella/200/400,\"foo,1,4,beep\",https://k6.io/,\"Proin ac libero vulputate ex vulputate pharetra ut vel lacus. Phasellus quis dolor sed leo finibus scelerisque. Ut vel finibus leo, sed viverra ipsum. Suspendisse vitae rutrum arcu. Donec sed tellus vel lectus bibendum vestibulum. Sed eu felis non velit dictum pulvinar eu et leo. Aenean et dignissim arcu. Nam luctus at neque quis efficitur. Fusce tempus at nibh a imperdiet. Nullam malesuada ac magna at facilisis. Duis pretium aliquam eros. Donec pharetra dignissim dolor non bibendum. Ut gravida mi id urna tempus, at ullamcorper felis vulputate. Duis congue augue ex, sed finibus leo ornare ut. Mauris non quam sodales, dignissim lorem eget, tincidunt mauris. Aliquam ut velit auctor, vestibulum metus sed, mollis massa.\"\ndown fast,https://placecats.com/neo_2/200/400,\"foo,bar,baz,a longer one,bim\",https://grafana.com/products/cloud/,\"Nullam in pulvinar justo. Nunc dictum arcu ac pellentesque bibendum. Sed in erat turpis. Vestibulum eu orci ac ligula lobortis tempus. Fusce consectetur feugiat magna, eu tempor nibh vestibulum ac. Aliquam erat volutpat. Vivamus sit amet viverra enim. Quisque mollis odio nulla, nec vulputate sem placerat in. Etiam dolor sapien, pulvinar in accumsan at, consequat eget nisi. Nunc condimentum neque magna, congue consectetur dui efficitur interdum. Nam lobortis fringilla maximus. Vestibulum eu dui a velit condimentum eleifend consequat nec lectus.\"", + "csvContent": "Info,Image,Image w/ Link,Pills,Data Link,Long Text\ndown,https://grafana.com/media/menus/products/grafana-menu-icon.svg,https://grafana.com/media/menus/products/grafana-menu-icon.svg,hello,https://grafana.com,\"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse tempus et augue et lacinia. Interdum et malesuada fames ac ante ipsum primis in faucibus.\"\nup,https://grafana.com/media/menus/products/grafana-menu-icon-logs.svg,https://grafana.com/media/menus/products/grafana-menu-icon-logs.svg,\"[1,2,3,\"\"foo\"\",\"\"bar\"\"]\",https://grafana.com/solutions/kubernetes/,\"Sed imperdiet eget diam sit amet fringilla. Curabitur quis lacus blandit, mollis diam non, accumsan tortor.\"\nup fast,https://grafana.com/media/menus/products/grafana-menu-icon-traces.svg,https://grafana.com/media/menus/products/grafana-menu-icon-traces.svg,\"foo,1,4,beep\",https://k6.io/,\"Proin ac libero vulputate ex vulputate pharetra ut vel lacus. Phasellus quis dolor sed leo finibus scelerisque. Ut vel finibus leo, sed viverra ipsum.\"\ndown fast,https://grafana.com/media/menus/products/grafana-menu-icon-metrics.svg,https://grafana.com/media/menus/products/grafana-menu-icon-metrics.svg,\"foo,bar,baz,a longer one,bim\",https://grafana.com/products/cloud/,\"Nullam in pulvinar justo. Nunc dictum arcu ac pellentesque bibendum. Sed in erat turpis. Vestibulum eu orci ac ligula lobortis tempus.\"", "datasource": { "type": "grafana-testdata-datasource" }, @@ -389,6 +453,30 @@ "mode": "outerTabular" } }, + { + "id": "calculateField", + "options": { + "alias": "Action", + "binary": { + "left": { + "matcher": { + "id": "byName", + "options": "Image" + } + }, + "right": { + "matcher": { + "id": "byName", + "options": "$Filters" + } + } + }, + "mode": "index", + "reduce": { + "reducer": "sum" + } + } + }, { "id": "organize", "options": { @@ -397,14 +485,16 @@ }, "includeByName": {}, "indexByName": { - "A": 9, - "Data Link": 8, + "A": 11, + "Action": 7, + "Data Link": 10, "Image": 5, + "Image w/ Link": 6, "Info": 1, - "Long Text": 7, + "Long Text": 9, "Max A": 3, "Min A": 2, - "Pills": 6, + "Pills": 8, "State A": 4, "Time A": 0 }, @@ -426,17 +516,1082 @@ "type": "table" }, { - "id": 2, - "type": "table", - "title": "Empty Table Panel", - "gridPos": { - "x": 0, - "y": 0, - "h": 6, - "w": 24 + "datasource": { + "type": "grafana-testdata-datasource" }, "fieldConfig": { "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "color-background" + }, + "filterable": true, + "inspect": true, + "wrapHeaderText": false + }, + "fieldMinMax": true, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 8, + "x": 16, + "y": 0 + }, + "id": 4, + "maxDataPoints": 100, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": false, + "fields": "", + "reducer": ["max"], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "State" + } + ] + }, + "pluginVersion": "12.2.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "random_walk_table" + } + ], + "title": "Nested tables", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "A": false + }, + "includeByName": {}, + "indexByName": { + "A": 5, + "Info": 2, + "Max": 4, + "Min": 3, + "State": 1, + "Time": 0 + }, + "renameByName": {} + } + }, + { + "id": "groupToNestedTable", + "options": { + "fields": { + "State": { + "aggregations": [], + "operation": "groupby" + } + }, + "showSubframeHeaders": true + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false, + "minWidth": 50, + "wrapHeaderText": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 3 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/\\b(bg|color)\\b/" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "a": { + "color": "dark-red", + "index": 0 + }, + "b": { + "color": "super-light-orange", + "index": 1 + }, + "c": { + "color": "green", + "index": 2 + }, + "d": { + "color": "super-light-blue", + "index": 3 + } + }, + "type": "value" + } + ] + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/\\bcolor\\b/" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "color-text" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/\\bbg\\b/" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "color-background" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/\\blink\\b/" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "goto foo", + "url": "https://foo" + } + ] + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/\\blinks\\b/" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "goto foo", + "url": "https://foo" + }, + { + "targetBlank": true, + "title": "goto bar", + "url": "https://bar" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "links-cellType" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "data-links" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 12 + }, + "id": 2, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": ["sum"], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "12.2.0-pre", + "targets": [ + { + "csvContent": "auto,link,links,bg,bg-link,bg-links,color,color-link,color-links,bg-row,bg-row-link,bg-row-links,color-row,color-row-link,color-row-links,links-cellType\na,a,a,a,a,a,a,a,a,1,1,1,1,1,1,1\nb,b,b,b,b,b,b,b,b,2,2,2,2,2,2,2\nc,c,c,c,c,c,c,c,c,3,3,3,3,3,3,3\nd,d,d,d,d,d,d,d,d,4,4,4,4,4,4,4", + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "csv_content" + } + ], + "title": "Colors and Links", + "type": "table" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false, + "wrapHeaderText": false + }, + "fieldMinMax": true, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "applyToRow": true, + "mode": "basic", + "type": "color-background" + } + }, + { + "id": "color", + "value": { + "mode": "continuous-greens" + } + }, + { + "id": "custom.width", + "value": 50 + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/(Min|Max)/" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Info" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Google this term", + "url": "https://google.com/search?q=${__value.raw}" + } + ] + }, + { + "id": "custom.width", + "value": 79 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 156 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "State" + }, + "properties": [ + { + "id": "custom.width", + "value": 99 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 0, + "y": 19 + }, + "id": 6, + "maxDataPoints": 10, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": ["sum"], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "12.2.0-pre", + "targets": [ + { + "rawFrameContent": "[\n {\n \"schema\": {\n \"refId\": \"A\",\n \"name\": \"A\",\n \"fields\": [\n {\n \"name\": \"Time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Min\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Max\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Info\",\n \"type\": \"string\",\n \"typeInfo\": {\n \"frame\": \"string\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"State\",\n \"type\": \"enum\",\n \"typeInfo\": {\n \"frame\": \"enum\"\n },\n \"config\": {\n \"type\": {\n \"enum\": {\n \"text\": [\n \"Unknown\",\n \"Up\",\n \"Down\"\n ]\n }\n }\n }\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1754578636810,\n 1754580436810,\n 1754582236810,\n 1754584036810,\n 1754585836810,\n 1754587636810,\n 1754589436810,\n 1754591236810,\n 1754593036810,\n 1754594836810\n ],\n [\n 68.67815082171406,\n 68.21038738705283,\n 67.85748579518524,\n 67.48088827530566,\n 67.36362085363314,\n 67.75399477824531,\n 67.9006935145112,\n 68.2893033558627,\n 68.20547872017494,\n 67.96251158324088\n ],\n [\n 67.52655915076163,\n 68.03367017865995,\n 65.44308825471086,\n 66.94142900198796,\n 66.33531057489242,\n 66.97007154625013,\n 67.88134129373145,\n 65.92102089546943,\n 65.7896781452792,\n 67.77680599320166\n ],\n [\n 68.78026730954913,\n 68.46495903270079,\n 68.29118217530531,\n 67.90561937677037,\n 68.05316512901861,\n 70.26033810424696,\n 68.05691975265877,\n 68.76874724839202,\n 70.02772232081647,\n 70.38628221361253\n ],\n [\n \"up\",\n \"down fast\",\n \"down\",\n \"down\",\n \"down\",\n \"up\",\n \"up\",\n \"up\",\n \"down\",\n \"down\"\n ],\n [\n 1,\n 2,\n 2,\n 2,\n 2,\n 1,\n 1,\n 1,\n 2,\n 2\n ]\n ]\n }\n }\n]", + "refId": "A", + "scenarioId": "raw_frame" + } + ], + "title": "Apply to row - basic", + "type": "table" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false, + "wrapHeaderText": false + }, + "fieldMinMax": true, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "applyToRow": true, + "type": "color-background" + } + }, + { + "id": "color", + "value": { + "mode": "continuous-blues" + } + }, + { + "id": "custom.width", + "value": 50 + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/(Min|Max)/" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Info" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Google this term", + "url": "https://google.com/search?q=${__value.raw}" + } + ] + }, + { + "id": "custom.width", + "value": 59 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 161 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "State" + }, + "properties": [ + { + "id": "custom.width", + "value": 114 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 4, + "y": 19 + }, + "id": 5, + "maxDataPoints": 10, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": ["sum"], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "12.2.0-pre", + "targets": [ + { + "rawFrameContent": "[\n {\n \"schema\": {\n \"refId\": \"A\",\n \"name\": \"A\",\n \"fields\": [\n {\n \"name\": \"Time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Min\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Max\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Info\",\n \"type\": \"string\",\n \"typeInfo\": {\n \"frame\": \"string\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"State\",\n \"type\": \"enum\",\n \"typeInfo\": {\n \"frame\": \"enum\"\n },\n \"config\": {\n \"type\": {\n \"enum\": {\n \"text\": [\n \"Unknown\",\n \"Up\",\n \"Down\"\n ]\n }\n }\n }\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1754579008785,\n 1754580808785,\n 1754582608785,\n 1754584408785,\n 1754586208785,\n 1754588008785,\n 1754589808785,\n 1754591608785,\n 1754593408785,\n 1754595208785\n ],\n [\n 89.82213040422468,\n 89.53763263564208,\n 90.03103064454615,\n 90.51535567776907,\n 90.88960652895187,\n 91.30921636258488,\n 91.12427953645643,\n 91.1507153149385,\n 90.81021008780039,\n 91.11327042147582\n ],\n [\n 87.33191559754641,\n 88.46410173314496,\n 88.06920794235972,\n 88.98473401700574,\n 90.60349141857057,\n 90.5858441719162,\n 90.42154517148411,\n 90.32413455176213,\n 90.72055904641739,\n 88.74774424339796\n ],\n [\n 90.58845140604446,\n 90.08173133413374,\n 90.58230197880795,\n 92.55531809442493,\n 93.09165646181742,\n 93.38354884838586,\n 92.68544239576967,\n 92.15770413350477,\n 92.77335012158814,\n 92.52115072193222\n ],\n [\n \"down\",\n \"down\",\n \"up fast\",\n \"up fast\",\n \"up\",\n \"up fast\",\n \"down\",\n \"up\",\n \"down\",\n \"up\"\n ],\n [\n 2,\n 2,\n 1,\n 1,\n 1,\n 1,\n 2,\n 1,\n 2,\n 1\n ]\n ]\n }\n }\n]", + "refId": "A", + "scenarioId": "raw_frame" + } + ], + "title": "Apply to row - gradient", + "type": "table" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false, + "wrapHeaderText": false + }, + "fieldMinMax": true, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "applyToRow": true, + "type": "color-background" + } + }, + { + "id": "color", + "value": { + "mode": "thresholds" + } + }, + { + "id": "custom.width", + "value": 50 + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/(Min|Max)/" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Info" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Google this term", + "url": "https://google.com/search?q=${__value.raw}" + } + ] + }, + { + "id": "custom.width", + "value": 79 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 158 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "State" + }, + "properties": [ + { + "id": "custom.width", + "value": 97 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 8, + "y": 19 + }, + "id": 7, + "maxDataPoints": 10, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": ["sum"], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "12.2.0-pre", + "targets": [ + { + "rawFrameContent": "[\n {\n \"schema\": {\n \"refId\": \"A\",\n \"name\": \"A\",\n \"fields\": [\n {\n \"name\": \"Time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Min\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Max\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Info\",\n \"type\": \"string\",\n \"typeInfo\": {\n \"frame\": \"string\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"State\",\n \"type\": \"enum\",\n \"typeInfo\": {\n \"frame\": \"enum\"\n },\n \"config\": {\n \"type\": {\n \"enum\": {\n \"text\": [\n \"Unknown\",\n \"Up\",\n \"Down\"\n ]\n }\n }\n }\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1754579078813,\n 1754580878813,\n 1754582678813,\n 1754584478813,\n 1754586278813,\n 1754588078813,\n 1754589878813,\n 1754591678813,\n 1754593478813,\n 1754595278813\n ],\n [\n 77.30289281564126,\n 87.14357945690202,\n 76.67466266903213,\n 76.27969352662608,\n 95.80292639037513,\n 75.68396049965999,\n 75.76117912054544,\n 76.05073308839697,\n 75.93744737071192,\n 75.82930696129104\n ],\n [\n 76.58900057075734,\n 76.01493865596112,\n 75.25501274661029,\n 75.52871130918913,\n 73.53324017648568,\n 74.74670600818675,\n 73.4627470190636,\n 75.38455781635166,\n 74.04318166296315,\n 74.79620005730261\n ],\n [\n 77.58417866514938,\n 77.9390885538468,\n 78.37258492198521,\n 76.82242506518101,\n 75.81423643776408,\n 75.86349731305505,\n 76.79031910137064,\n 77.71934637974913,\n 76.11981207380533,\n 77.29746416618009\n ],\n [\n \"down fast\",\n \"down\",\n \"down fast\",\n \"down\",\n \"down fast\",\n \"down\",\n \"up\",\n \"up\",\n \"down\",\n \"down\"\n ],\n [\n 2,\n 2,\n 2,\n 2,\n 2,\n 2,\n 1,\n 1,\n 2,\n 2\n ]\n ]\n }\n }\n]", + "refId": "A", + "scenarioId": "raw_frame" + } + ], + "title": "Apply to row - thresholds", + "type": "table" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false, + "wrapHeaderText": false + }, + "fieldMinMax": true, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "custom.width", + "value": 50 + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/(Min|Max)/" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Info" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Google this term", + "url": "https://google.com/search?q=${__value.raw}" + } + ] + }, + { + "id": "custom.width", + "value": 79 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 158 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "State" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "applyToRow": true, + "type": "color-background" + } + }, + { + "id": "custom.width", + "value": 97 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 12, + "y": 19 + }, + "id": 8, + "maxDataPoints": 10, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": ["sum"], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": false, + "displayName": "A" + } + ] + }, + "pluginVersion": "12.2.0-pre", + "targets": [ + { + "rawFrameContent": "[\n {\n \"schema\": {\n \"refId\": \"A\",\n \"name\": \"A\",\n \"fields\": [\n {\n \"name\": \"Time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Min\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Max\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Info\",\n \"type\": \"string\",\n \"typeInfo\": {\n \"frame\": \"string\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"State\",\n \"type\": \"enum\",\n \"typeInfo\": {\n \"frame\": \"enum\"\n },\n \"config\": {\n \"type\": {\n \"enum\": {\n \"text\": [\n \"Unknown\",\n \"Up\",\n \"Down\"\n ]\n }\n }\n }\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1754579078813,\n 1754580878813,\n 1754582678813,\n 1754584478813,\n 1754586278813,\n 1754588078813,\n 1754589878813,\n 1754591678813,\n 1754593478813,\n 1754595278813\n ],\n [\n 77.30289281564126,\n 87.14357945690202,\n 76.67466266903213,\n 76.27969352662608,\n 95.80292639037513,\n 75.68396049965999,\n 75.76117912054544,\n 76.05073308839697,\n 75.93744737071192,\n 75.82930696129104\n ],\n [\n 76.58900057075734,\n 76.01493865596112,\n 75.25501274661029,\n 75.52871130918913,\n 73.53324017648568,\n 74.74670600818675,\n 73.4627470190636,\n 75.38455781635166,\n 74.04318166296315,\n 74.79620005730261\n ],\n [\n 77.58417866514938,\n 77.9390885538468,\n 78.37258492198521,\n 76.82242506518101,\n 75.81423643776408,\n 75.86349731305505,\n 76.79031910137064,\n 77.71934637974913,\n 76.11981207380533,\n 77.29746416618009\n ],\n [\n \"down fast\",\n \"down\",\n \"down fast\",\n \"down\",\n \"down fast\",\n \"down\",\n \"up\",\n \"up\",\n \"down\",\n \"down\"\n ],\n [\n 2,\n 2,\n 2,\n 2,\n 2,\n 2,\n 1,\n 1,\n 2,\n 2\n ]\n ]\n }\n }\n]", + "refId": "A", + "scenarioId": "raw_frame" + } + ], + "title": "Apply to row - enum", + "type": "table" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false, + "wrapHeaderText": false + }, + "fieldMinMax": true, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "color", + "value": { + "mode": "palette-classic" + } + }, + { + "id": "custom.width", + "value": 50 + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/(Min|Max)/" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Info" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Google this term", + "url": "https://google.com/search?q=${__value.raw}" + } + ] + }, + { + "id": "custom.width", + "value": 79 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 158 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "from": 0, + "result": { + "color": "purple", + "index": 0 + }, + "to": 76.999 + }, + "type": "range" + }, + { + "options": { + "from": 77, + "result": { + "color": "orange", + "index": 1 + } + }, + "type": "range" + } + ] + }, + { + "id": "custom.cellOptions", + "value": { + "applyToRow": true, + "type": "color-background" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "State" + }, + "properties": [ + { + "id": "custom.width", + "value": 97 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 16, + "y": 19 + }, + "id": 9, + "maxDataPoints": 10, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": ["sum"], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "12.2.0-pre", + "targets": [ + { + "rawFrameContent": "[\n {\n \"schema\": {\n \"refId\": \"A\",\n \"name\": \"A\",\n \"fields\": [\n {\n \"name\": \"Time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Min\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Max\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"Info\",\n \"type\": \"string\",\n \"typeInfo\": {\n \"frame\": \"string\",\n \"nullable\": true\n },\n \"config\": {}\n },\n {\n \"name\": \"State\",\n \"type\": \"enum\",\n \"typeInfo\": {\n \"frame\": \"enum\"\n },\n \"config\": {\n \"type\": {\n \"enum\": {\n \"text\": [\n \"Unknown\",\n \"Up\",\n \"Down\"\n ]\n }\n }\n }\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1754579078813,\n 1754580878813,\n 1754582678813,\n 1754584478813,\n 1754586278813,\n 1754588078813,\n 1754589878813,\n 1754591678813,\n 1754593478813,\n 1754595278813\n ],\n [\n 77.30289281564126,\n 87.14357945690202,\n 76.67466266903213,\n 76.27969352662608,\n 95.80292639037513,\n 75.68396049965999,\n 75.76117912054544,\n 76.05073308839697,\n 75.93744737071192,\n 75.82930696129104\n ],\n [\n 76.58900057075734,\n 76.01493865596112,\n 75.25501274661029,\n 75.52871130918913,\n 73.53324017648568,\n 74.74670600818675,\n 73.4627470190636,\n 75.38455781635166,\n 74.04318166296315,\n 74.79620005730261\n ],\n [\n 77.58417866514938,\n 77.9390885538468,\n 78.37258492198521,\n 76.82242506518101,\n 75.81423643776408,\n 75.86349731305505,\n 76.79031910137064,\n 77.71934637974913,\n 76.11981207380533,\n 77.29746416618009\n ],\n [\n \"down fast\",\n \"down\",\n \"down fast\",\n \"down\",\n \"down fast\",\n \"down\",\n \"up\",\n \"up\",\n \"down\",\n \"down\"\n ],\n [\n 2,\n 2,\n 2,\n 2,\n 2,\n 2,\n 1,\n 1,\n 2,\n 2\n ]\n ]\n }\n }\n]", + "refId": "A", + "scenarioId": "raw_frame" + } + ], + "title": "Apply to row - mappings", + "type": "table" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, "custom": { "align": "auto", "cellOptions": { @@ -450,42 +1605,45 @@ "mode": "absolute", "steps": [ { - "value": null, - "color": "green" + "color": "green", + "value": 0 }, { - "value": 80, - "color": "red" + "color": "red", + "value": 80 } ] - }, - "color": { - "mode": "thresholds" } }, "overrides": [] }, - "pluginVersion": "12.1.0-pre", - "targets": [ - { - "scenarioId": "csv_content", - "refId": "A", - "csvContent": "a,b,c" - } - ], - "datasource": { - "type": "grafana-testdata-datasource" + "gridPos": { + "h": 7, + "w": 4, + "x": 20, + "y": 19 }, + "id": 3, "options": { - "showHeader": true, "cellHeight": "sm", "footer": { - "show": false, - "reducer": ["sum"], "countRows": false, - "fields": "" + "fields": "", + "reducer": ["sum"], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "12.2.0-pre", + "targets": [ + { + "csvContent": "a,b,c", + "refId": "A", + "scenarioId": "csv_content" } - } + ], + "title": "Empty Table Panel", + "type": "table" } ], "preload": false, @@ -512,5 +1670,5 @@ "timezone": "", "title": "Panel Tests - Table - Kitchen Sink", "uid": "dcb9f5e9-8066-4397-889e-864b99555dbb", - "version": 2 + "version": 7 } diff --git a/devenv/dev-dashboards/panel-table/table_markdown.json b/devenv/dev-dashboards/panel-table/table_markdown.json index 863edd09fed..06f3d7c310c 100644 --- a/devenv/dev-dashboards/panel-table/table_markdown.json +++ b/devenv/dev-dashboards/panel-table/table_markdown.json @@ -93,7 +93,7 @@ "pluginVersion": "12.1.0-pre", "targets": [ { - "csvContent": "id,markdown\n1,\"
\"\n6,\"[Link](https://grafana.com), or HTML link\"\n7,\"1. foo\n1. bar\n - baz\n * bim\n3. bip\"\n8,\"# heading 1\n## heading 2\n### heading 3\n#### heading 4\n##### heading 5\n###### heading 6\"\n9,\"Emphasis, aka italics, with *asterisks* or _underscores_.\n\nStrong emphasis, aka bold, with **asterisks** or __underscores__.\n\nCombined emphasis with **asterisks and _underscores_**.\n\nStrikethrough uses two tildes. ~~Scratch this.~~\n\nunderline does require an HTML element tho.\"\n10,\"```javascript\nvar s = 'JavaScript syntax highlighting';\nalert(s);\n```\"\n11,\"\n| Month | Savings |\n| -------- | ------- |\n| I heard | $250 |\n| you like | $80 |\n| tables | $365 |\"\n",
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "gdev-testdata"
diff --git a/e2e-playwright/panels-suite/table-kitchenSink.spec.ts b/e2e-playwright/panels-suite/table-kitchenSink.spec.ts
index 8ac43ceebb1..5ddb7c4d4e4 100644
--- a/e2e-playwright/panels-suite/table-kitchenSink.spec.ts
+++ b/e2e-playwright/panels-suite/table-kitchenSink.spec.ts
@@ -1,6 +1,6 @@
import { Page, Locator } from '@playwright/test';
-import { test, expect } from '@grafana/plugin-e2e';
+import { test, expect, E2ESelectorGroups } from '@grafana/plugin-e2e';
const DASHBOARD_UID = 'dcb9f5e9-8066-4397-889e-864b99555dbb';
@@ -41,6 +41,21 @@ const getColumnIdx = async (loc: Page | Locator, columnName: string) => {
return result;
};
+const disableAllTextWrap = async (loc: Page | Locator, selectors: E2ESelectorGroups) => {
+ // disable text wrapping for all of the columns, since long text with links in them can push the links off the screen.
+ const wrapTextToggle = loc.locator(
+ `[aria-label="${selectors.components.PanelEditor.OptionsPane.fieldLabel('Wrap text')}"]`
+ );
+ const count = await wrapTextToggle.count();
+
+ for (let i = 0; i < count; i++) {
+ const toggle = wrapTextToggle.nth(i);
+ if ((await toggle.locator('//preceding-sibling::input').getAttribute('checked')) !== null) {
+ await toggle.click();
+ }
+ }
+};
+
test.describe('Panels test: Table - Kitchen Sink', { tag: ['@panels', '@table'] }, () => {
test('Tests word wrap, hover overflow, and cell inspect', async ({ gotoDashboardPage, selectors, page }) => {
const dashboardPage = await gotoDashboardPage({
@@ -214,11 +229,7 @@ test.describe('Panels test: Table - Kitchen Sink', { tag: ['@panels', '@table']
// because of text wrapping, we're guaranteed to only be showing a single row when we enable pagination.
await expect(page.getByText(/([\d]+) - ([\d]+) of ([\d]+) rows/)).toBeVisible();
- // FIXME horrible selector for the "Wrap text" toggle for the "Long text" column.
- await page
- .locator('[id="Override 13"]')
- .locator(`[aria-label="${selectors.components.PanelEditor.OptionsPane.fieldLabel('Wrap text')}"]`)
- .click();
+ await disableAllTextWrap(page, selectors);
// any number of rows that is not "1" is allowed here, we don't want to police the exact number of rows that
// are rendered since there are tons of factors which could effect this. we do want to grab this number for comparison
@@ -281,13 +292,7 @@ test.describe('Panels test: Table - Kitchen Sink', { tag: ['@panels', '@table']
dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('Table - Kitchen Sink'))
).toBeVisible();
- // disable text wrapping for this test to make it easier to click the links, the long lorem ipsum
- // can push the links off the screen.
- // FIXME very bad selector to get the correct "wrap text" toggle here.
- await page
- .locator('[id="Override 13"]')
- .locator(`[aria-label="${selectors.components.PanelEditor.OptionsPane.fieldLabel('Wrap text')}"]`)
- .click();
+ await disableAllTextWrap(page, selectors);
const infoColumnIdx = await getColumnIdx(page, 'Info');
const pillColIdx = await getColumnIdx(page, 'Pills');
@@ -351,7 +356,7 @@ test.describe('Panels test: Table - Kitchen Sink', { tag: ['@panels', '@table']
test('Empty Table panel', async ({ gotoDashboardPage, selectors }) => {
const dashboardPage = await gotoDashboardPage({
uid: DASHBOARD_UID,
- queryParams: new URLSearchParams({ editPanel: '2' }),
+ queryParams: new URLSearchParams({ editPanel: '3' }),
});
await expect(
diff --git a/packages/grafana-schema/src/common/common.gen.ts b/packages/grafana-schema/src/common/common.gen.ts
index c256e8ed6bd..62346b070f6 100644
--- a/packages/grafana-schema/src/common/common.gen.ts
+++ b/packages/grafana-schema/src/common/common.gen.ts
@@ -704,6 +704,7 @@ export enum TableCellDisplayMode {
Custom = 'custom',
DataLinks = 'data-links',
Gauge = 'gauge',
+ Geo = 'geo',
GradientGauge = 'gradient-gauge',
Image = 'image',
JSONView = 'json-view',
@@ -837,27 +838,6 @@ export interface TablePillCellOptions extends TableWrapTextOptions {
type: TableCellDisplayMode.Pill;
}
-export interface TableMarkdownCellOptions {
- dynamicHeight?: boolean;
- type: TableCellDisplayMode.Markdown;
-}
-
-/**
- * Height of a table cell
- */
-export enum TableCellHeight {
- Auto = 'auto',
- Lg = 'lg',
- Md = 'md',
- Sm = 'sm',
-}
-
-/**
- * Table cell options. Each cell has a display mode
- * and other potential options for that display.
- */
-export type TableCellOptions = (TableAutoCellOptions | TableSparklineCellOptions | TableBarGaugeCellOptions | TableColoredBackgroundCellOptions | TableColorTextCellOptions | TableImageCellOptions | TablePillCellOptions | TableDataLinksCellOptions | TableActionsCellOptions | TableJsonViewCellOptions | TableMarkdownCellOptions);
-
/**
* Use UTC/GMT timezone
*/
@@ -973,6 +953,29 @@ export enum ComparisonOperation {
NEQ = 'neq',
}
+export interface TableMarkdownCellOptions {
+ dynamicHeight?: boolean;
+ type: TableCellDisplayMode.Markdown;
+}
+
+/**
+ * Height of a table cell
+ */
+export enum TableCellHeight {
+ Auto = 'auto',
+ Lg = 'lg',
+ Md = 'md',
+ Sm = 'sm',
+}
+
+/**
+ * Table cell options. Each cell has a display mode
+ * and other potential options for that display.
+ */
+export type TableCellOptions = (TableAutoCellOptions | TableSparklineCellOptions | TableBarGaugeCellOptions | TableColoredBackgroundCellOptions | TableColorTextCellOptions | TableImageCellOptions | TablePillCellOptions | TableDataLinksCellOptions | TableActionsCellOptions | TableJsonViewCellOptions | TableMarkdownCellOptions | {
+ type: TableCellDisplayMode.Geo
+ });
+
/**
* Field options for each field within a table (e.g 10, "The String", 64.20, etc.)
* Generally defines alignment, filtering capabilties, display options, etc.
diff --git a/packages/grafana-schema/src/common/table.cue b/packages/grafana-schema/src/common/table.cue
index 57b7b56dc44..9fe71322a31 100644
--- a/packages/grafana-schema/src/common/table.cue
+++ b/packages/grafana-schema/src/common/table.cue
@@ -4,7 +4,7 @@ package common
// in the table such as colored text, JSON, gauge, etc.
// The color-background-solid, gradient-gauge, and lcd-gauge
// modes are deprecated in favor of new cell subOptions
-TableCellDisplayMode: "auto" | "color-text" | "color-background" | "color-background-solid" | "gradient-gauge" | "lcd-gauge" | "json-view" | "basic" | "image" | "gauge" | "sparkline" | "data-links" | "custom" | "actions" | "pill" | "markdown" @cuetsy(kind="enum",memberNames="Auto|ColorText|ColorBackground|ColorBackgroundSolid|GradientGauge|LcdGauge|JSONView|BasicGauge|Image|Gauge|Sparkline|DataLinks|Custom|Actions|Pill|Markdown")
+TableCellDisplayMode: "auto" | "color-text" | "color-background" | "color-background-solid" | "gradient-gauge" | "lcd-gauge" | "json-view" | "basic" | "image" | "gauge" | "sparkline" | "data-links" | "custom" | "actions" | "pill" | "markdown" | "geo" @cuetsy(kind="enum",memberNames="Auto|ColorText|ColorBackground|ColorBackgroundSolid|GradientGauge|LcdGauge|JSONView|BasicGauge|Image|Gauge|Sparkline|DataLinks|Custom|Actions|Pill|Markdown|Geo")
// Display mode to the "Colored Background" display
// mode for table cells. Either displays a solid color (basic mode)
@@ -96,12 +96,20 @@ TableMarkdownCellOptions: {
dynamicHeight?: bool
} @cuetsy(kind="interface")
+TableMarkdownCellOptions: {
+ type: TableCellDisplayMode & "markdown"
+} @cuetsy(kind="interface")
+
+TableGeoCellOptions: {
+ type: TableCellDisplayMode & "geo"
+}
+
// Height of a table cell
TableCellHeight: "sm" | "md" | "lg" | "auto" @cuetsy(kind="enum")
// Table cell options. Each cell has a display mode
// and other potential options for that display.
-TableCellOptions: TableAutoCellOptions | TableSparklineCellOptions | TableBarGaugeCellOptions | TableColoredBackgroundCellOptions | TableColorTextCellOptions | TableImageCellOptions | TablePillCellOptions | TableDataLinksCellOptions | TableActionsCellOptions | TableJsonViewCellOptions | TableMarkdownCellOptions @cuetsy(kind="type")
+TableCellOptions: TableAutoCellOptions | TableSparklineCellOptions | TableBarGaugeCellOptions | TableColoredBackgroundCellOptions | TableColorTextCellOptions | TableImageCellOptions | TablePillCellOptions | TableDataLinksCellOptions | TableActionsCellOptions | TableJsonViewCellOptions | TableMarkdownCellOptions | TableGeoCellOptions @cuetsy(kind="type")
// Field options for each field within a table (e.g 10, "The String", 64.20, etc.)
// Generally defines alignment, filtering capabilties, display options, etc.
diff --git a/packages/grafana-ui/src/components/Table/TableNG/Cells/ActionsCell.tsx b/packages/grafana-ui/src/components/Table/TableNG/Cells/ActionsCell.tsx
index 087efa47ecc..c8c2465a07a 100644
--- a/packages/grafana-ui/src/components/Table/TableNG/Cells/ActionsCell.tsx
+++ b/packages/grafana-ui/src/components/Table/TableNG/Cells/ActionsCell.tsx
@@ -1,29 +1,16 @@
import { css } from '@emotion/css';
-import { useMemo } from 'react';
-import { GrafanaTheme2 } from '@grafana/data';
-
-import { useStyles2 } from '../../../../themes/ThemeContext';
import { ActionButton } from '../../../Actions/ActionButton';
-import { ActionCellProps } from '../types';
+import { ActionCellProps, TableCellStyles } from '../types';
export const ActionsCell = ({ field, rowIdx, getActions }: ActionCellProps) => {
- const styles = useStyles2(getStyles);
+ const actions = getActions(field, rowIdx);
- const actions = useMemo(() => getActions(field, rowIdx), [getActions, field, rowIdx]);
+ if (actions.length === 0) {
+ return null;
+ }
- return (
-