From d254edb9ac9e2c88d769901967be34adbfd20f50 Mon Sep 17 00:00:00 2001 From: vitPinchuk Date: Fri, 15 Nov 2024 13:37:42 +0300 Subject: [PATCH 1/5] update expand\collapse behavior for rows --- src/components/Table/Table.tsx | 13 +++++- src/components/TablePanel/TablePanel.tsx | 1 + .../editors/TablesEditor/TablesEditor.tsx | 1 + .../TableEditor/TableEditor.test.tsx | 41 +++++++++++++++++++ .../components/TableEditor/TableEditor.tsx | 38 ++++++++++++----- src/constants.ts | 1 + src/types/panel.ts | 7 ++++ src/utils/test.ts | 1 + 8 files changed, 91 insertions(+), 12 deletions(-) diff --git a/src/components/Table/Table.tsx b/src/components/Table/Table.tsx index f8d0a9f..486e8b6 100644 --- a/src/components/Table/Table.tsx +++ b/src/components/Table/Table.tsx @@ -114,8 +114,17 @@ interface Props { /** * Table Instance + * + * @type {MutableRefObject>} */ tableInstance: MutableRefObject>; + + /** + * Expanded By default + * + * @type {boolean} + */ + expandedByDefault: boolean; } /** @@ -185,6 +194,7 @@ export const Table = ({ width, pagination, tableInstance, + expandedByDefault, }: Props) => { /** * Styles and Theme @@ -221,7 +231,7 @@ export const Table = ({ /** * Expanded */ - const [expanded, setExpanded] = useState({}); + const [expanded, setExpanded] = useState(expandedByDefault ? true : {}); /** * Filtering @@ -261,6 +271,7 @@ export const Table = ({ enableExpanding: true, enableGrouping: true, onExpandedChange: setExpanded, + autoResetExpanded: false, /** * Filtering diff --git a/src/components/TablePanel/TablePanel.tsx b/src/components/TablePanel/TablePanel.tsx index bccc82b..ff974e4 100644 --- a/src/components/TablePanel/TablePanel.tsx +++ b/src/components/TablePanel/TablePanel.tsx @@ -206,6 +206,7 @@ export const TablePanel: React.FC = ({ )} = ({ context: { options, data }, onCh onChangeItems( items.concat([ { + expanded: false, name: newItemName, items: [], update: { datasource: '', payload: {} }, diff --git a/src/components/editors/TablesEditor/components/TableEditor/TableEditor.test.tsx b/src/components/editors/TablesEditor/components/TableEditor/TableEditor.test.tsx index 760093a..6111981 100644 --- a/src/components/editors/TablesEditor/components/TableEditor/TableEditor.test.tsx +++ b/src/components/editors/TablesEditor/components/TableEditor/TableEditor.test.tsx @@ -71,4 +71,45 @@ describe('TableEditor', () => { }) ); }); + + it('Should allow to change table expand state', () => { + render( + getComponent({ + value: createTableConfig({ + expanded: false, + items: [createColumnConfig({})], + }), + }) + ); + + expect(selectors.fieldExpanded()).toBeInTheDocument(); + fireEvent.click(selectors.fieldExpanded()); + + expect(onChange).toHaveBeenCalledWith( + expect.objectContaining({ + expanded: true, + items: [createColumnConfig({})], + }) + ); + }); + + it('Should allow to change table expand state if "expanded" not present in options', () => { + render( + getComponent({ + value: createTableConfig({ + items: [createColumnConfig({})], + }), + }) + ); + + expect(selectors.fieldExpanded()).toBeInTheDocument(); + fireEvent.click(selectors.fieldExpanded()); + + expect(onChange).toHaveBeenCalledWith( + expect.objectContaining({ + expanded: true, + items: [createColumnConfig({})], + }) + ); + }); }); diff --git a/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx b/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx index 271ca8c..f61e6df 100644 --- a/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx +++ b/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx @@ -1,6 +1,8 @@ import { DataFrame } from '@grafana/data'; +import { InlineField, InlineSwitch } from '@grafana/ui'; import React from 'react'; +import { TEST_IDS } from '@/constants'; import { EditorProps, TableConfig } from '@/types'; import { ColumnsEditor } from './components'; @@ -20,16 +22,30 @@ interface Props extends EditorProps { */ export const TableEditor: React.FC = ({ value, onChange, data }) => { return ( - { - onChange({ - ...value, - items, - }); - }} - /> + <> + + + onChange({ + ...value, + expanded: event.currentTarget.checked, + }) + } + {...TEST_IDS.tableEditor.fieldExpanded.apply()} + /> + + { + onChange({ + ...value, + items, + }); + }} + /> + ); }; diff --git a/src/constants.ts b/src/constants.ts index 40b8594..bb6337b 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -207,6 +207,7 @@ export const TEST_IDS = { tableEditor: { updateSectionHeader: createSelector('data-testid table-editor update-section-header'), updateSectionContent: createSelector('data-testid table-editor update-section-content'), + fieldExpanded: createSelector('data-testid table-editor field-expanded'), }, fieldPicker: { root: createSelector('data-testid field-picker'), diff --git a/src/types/panel.ts b/src/types/panel.ts index ef00617..00f9d46 100644 --- a/src/types/panel.ts +++ b/src/types/panel.ts @@ -385,6 +385,13 @@ export interface TableConfig { * @type {TablePaginationConfig} */ pagination: TablePaginationConfig; + + /** + * Expanded by default + * + * @type {boolean} + */ + expanded: boolean; } /** diff --git a/src/utils/test.ts b/src/utils/test.ts index 00ac786..007245a 100644 --- a/src/utils/test.ts +++ b/src/utils/test.ts @@ -251,6 +251,7 @@ export const createTableConfig = (table: Partial): TableConfig => ( items: [], update: createTableRequestConfig({}), pagination: createTablePaginationConfig({}), + expanded: false, ...table, }); From 220dcf460e547e17a4c9f89e42540979450a4a54 Mon Sep 17 00:00:00 2001 From: vitPinchuk Date: Fri, 15 Nov 2024 15:03:16 +0300 Subject: [PATCH 2/5] add migration --- provisioning/dashboards/panels.json | 307 +++++++++++++++++++++++++++- src/migration.test.ts | 26 +++ src/migration.ts | 4 + 3 files changed, 329 insertions(+), 8 deletions(-) diff --git a/provisioning/dashboards/panels.json b/provisioning/dashboards/panels.json index c415706..5c049e2 100644 --- a/provisioning/dashboards/panels.json +++ b/provisioning/dashboards/panels.json @@ -24,7 +24,7 @@ "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, - "id": 4, + "id": 3, "links": [], "panels": [ { @@ -759,7 +759,6 @@ "export": true } }, - "pluginVersion": "1.7.0", "targets": [ { "datasource": { @@ -1076,7 +1075,6 @@ "export": false } }, - "pluginVersion": "1.7.0", "targets": [ { "frame": { @@ -1484,7 +1482,6 @@ "export": true } }, - "pluginVersion": "1.7.0", "targets": [ { "datasource": { @@ -1753,7 +1750,6 @@ "export": true } }, - "pluginVersion": "1.7.0", "targets": [ { "datasource": { @@ -1822,6 +1818,9 @@ }, "fieldConfig": { "defaults": { + "color": { + "mode": "thresholds" + }, "mappings": [], "thresholds": { "mode": "absolute", @@ -1840,11 +1839,303 @@ "overrides": [] }, "gridPos": { - "h": 8, + "h": 10, "w": 24, "x": 0, "y": 49 }, + "id": 14, + "options": { + "nestedObjects": [], + "tables": [ + { + "expanded": true, + "items": [ + { + "aggregation": "none", + "appearance": { + "alignment": "start", + "background": { + "applyToRow": false + }, + "colors": {}, + "header": { + "fontSize": "md" + }, + "width": { + "auto": true, + "min": 20, + "value": 100 + }, + "wrap": true + }, + "edit": { + "editor": { + "type": "string" + }, + "enabled": false, + "permission": { + "mode": "", + "userRole": [] + } + }, + "enabled": true, + "field": { + "name": "labels", + "source": "A" + }, + "filter": { + "enabled": false, + "mode": "client", + "variable": "" + }, + "footer": [], + "group": true, + "label": "", + "objectId": "", + "pin": "", + "sort": { + "descFirst": false, + "enabled": false + }, + "type": "auto" + }, + { + "aggregation": "none", + "appearance": { + "alignment": "start", + "background": { + "applyToRow": false + }, + "colors": {}, + "header": { + "fontSize": "md" + }, + "width": { + "auto": true, + "min": 20, + "value": 100 + }, + "wrap": true + }, + "edit": { + "editor": { + "type": "string" + }, + "enabled": false, + "permission": { + "mode": "", + "userRole": [] + } + }, + "enabled": true, + "field": { + "name": "title", + "source": "A" + }, + "filter": { + "enabled": false, + "mode": "client", + "variable": "" + }, + "footer": [], + "group": false, + "label": "", + "objectId": "", + "pin": "", + "sort": { + "descFirst": false, + "enabled": false + }, + "type": "auto" + }, + { + "aggregation": "none", + "appearance": { + "alignment": "start", + "background": { + "applyToRow": false + }, + "colors": {}, + "header": { + "fontSize": "md" + }, + "width": { + "auto": true, + "min": 20, + "value": 100 + }, + "wrap": true + }, + "edit": { + "editor": { + "type": "string" + }, + "enabled": false, + "permission": { + "mode": "", + "userRole": [] + } + }, + "enabled": true, + "field": { + "name": "start_date", + "source": "A" + }, + "filter": { + "enabled": false, + "mode": "client", + "variable": "" + }, + "footer": [], + "group": false, + "label": "", + "objectId": "", + "pin": "", + "sort": { + "descFirst": false, + "enabled": false + }, + "type": "auto" + }, + { + "aggregation": "none", + "appearance": { + "alignment": "start", + "background": { + "applyToRow": false + }, + "colors": {}, + "header": { + "fontSize": "md" + }, + "width": { + "auto": true, + "min": 20, + "value": 100 + }, + "wrap": true + }, + "edit": { + "editor": { + "type": "string" + }, + "enabled": false, + "permission": { + "mode": "", + "userRole": [] + } + }, + "enabled": true, + "field": { + "name": "description", + "source": "A" + }, + "filter": { + "enabled": false, + "mode": "client", + "variable": "" + }, + "footer": [], + "group": false, + "label": "", + "objectId": "", + "pin": "", + "sort": { + "descFirst": false, + "enabled": false + }, + "type": "rich_text" + } + ], + "name": "Test", + "pagination": { + "enabled": false, + "mode": "client" + }, + "update": { + "datasource": "", + "payload": {} + } + } + ], + "tabsSorting": false, + "toolbar": { + "export": false + } + }, + "targets": [ + { + "frame": { + "fields": [ + { + "config": {}, + "name": "labels", + "type": "string", + "values": [] + }, + { + "config": {}, + "name": "title", + "type": "string", + "values": [] + }, + { + "config": {}, + "name": "start_date", + "type": "string", + "values": [] + }, + { + "config": {}, + "name": "description", + "type": "string", + "values": [] + } + ], + "meta": { + "custom": { + "customCode": "const createArray = (length, fillCell) => new Array(length).fill(fillCell)\n\nconst result = {\n ...frame,\n fields: frame.fields.map((field) => {\n if (field.name === 'labels') {\n return ({\n ...field,\n values: [createArray(4, 'Grafana 11.4'), createArray(4, 'Grafana 11.3'), createArray(4, 'Grafana 11.2'), createArray(4, 'Grafana 11.0'), createArray(4, 'Grafana 10.4'), createArray(4, 'Grafana 10.3'), createArray(4, 'Grafana 10.2'), createArray(4, 'Grafana 10.1'), createArray(4, 'Grafana 10.0')].flat()\n })\n }\n if (field.name === 'title') {\n return ({\n ...field,\n values: createArray(36, 'Title').map((item, index) => `${item} - ${index}`)\n })\n }\n if (field.name === 'start_date') {\n return ({\n ...field,\n values: createArray(36, '20-10-2024 10:00:30')\n })\n }\n if (field.name === 'description') {\n return ({\n ...field,\n values: createArray(36, '

Features/ 1

- Updated behavior
- Added All options
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.')\n })\n }\n return ({\n ...field,\n values: []\n })\n })\n}\n\nreturn Promise.resolve(result);", + "valuesEditor": "custom" + } + } + }, + "refId": "A" + } + ], + "title": "Expanded rows - auto", + "type": "volkovlabs-table-panel" + }, + { + "datasource": { + "type": "marcusolsson-static-datasource", + "uid": "P1D2C73DC01F2359B" + }, + "fieldConfig": { + "defaults": { + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 59 + }, "id": 8, "options": { "columnMode": "auto", @@ -1852,6 +2143,7 @@ "nestedObjects": [], "tables": [ { + "expanded": false, "items": [ { "aggregation": "none", @@ -1970,7 +2262,6 @@ "export": false } }, - "pluginVersion": "1.7.0", "targets": [ { "datasource": { @@ -2053,6 +2344,6 @@ "timezone": "", "title": "Panels", "uid": "O4tc_E6Gz", - "version": 1, + "version": 15, "weekStart": "" } diff --git a/src/migration.test.ts b/src/migration.test.ts index 0546d74..cf8b183 100644 --- a/src/migration.test.ts +++ b/src/migration.test.ts @@ -411,4 +411,30 @@ describe('migration', () => { }); }); }); + + describe('1.8.0', () => { + it('Should normalize expanded', async () => { + expect( + await getMigratedOptions({ + options: { + tables: [ + { + name: '', + items: [], + }, + ], + }, + } as any) + ).toEqual( + expect.objectContaining({ + tables: [ + expect.objectContaining({ + expanded: false, + items: [], + }), + ], + }) + ); + }); + }); }); diff --git a/src/migration.ts b/src/migration.ts index 7f484a9..94990f2 100644 --- a/src/migration.ts +++ b/src/migration.ts @@ -283,6 +283,10 @@ export const getMigratedOptions = async (panel: PanelModel }; } + if (!normalizedGroup.hasOwnProperty('expanded')) { + normalizedGroup.expanded = false; + } + if (panel.pluginVersion && semver.lt(panel.pluginVersion, '1.7.0') && !!normalizedGroup.update.datasource) { normalizedGroup.update = { ...normalizedGroup.update, From f622d0449a5b422bd613dbbd29f66457af998095 Mon Sep 17 00:00:00 2001 From: asimonok Date: Wed, 20 Nov 2024 15:39:44 +0300 Subject: [PATCH 3/5] Formatting --- .../editors/TablesEditor/components/TableEditor/TableEditor.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx b/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx index cdf8d3f..971e395 100644 --- a/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx +++ b/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx @@ -23,7 +23,7 @@ interface Props extends EditorProps { export const TableEditor: React.FC = ({ value, onChange, data }) => { return ( <> - + From 7c058ce75d265fbf713af57d66bab68f2c6fa496 Mon Sep 17 00:00:00 2001 From: Mikhail Volkov Date: Wed, 20 Nov 2024 21:18:58 -0500 Subject: [PATCH 4/5] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbc7e82..c510d6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ ### Features / Enhancements - Updated sort state on dashboard refresh (#163) -- Support variables in data sources for editable and nested objects (#167) +- Added support variables in data sources for editable and nested objects (#167) +- Updated group expand and collapse behavior (#161) ## 1.7.0 (2024-11-16) From 1342bc0dfb2e5a4e6cb5e3919ded67c0f2b15bf0 Mon Sep 17 00:00:00 2001 From: Mikhail Volkov Date: Wed, 20 Nov 2024 21:23:21 -0500 Subject: [PATCH 5/5] Add Inline Field Row --- .../components/TableEditor/TableEditor.tsx | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx b/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx index 971e395..31fb62b 100644 --- a/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx +++ b/src/components/editors/TablesEditor/components/TableEditor/TableEditor.tsx @@ -1,5 +1,5 @@ import { DataFrame } from '@grafana/data'; -import { InlineField, InlineSwitch } from '@grafana/ui'; +import { InlineField, InlineFieldRow, InlineSwitch } from '@grafana/ui'; import React from 'react'; import { TEST_IDS } from '@/constants'; @@ -23,30 +23,32 @@ interface Props extends EditorProps { export const TableEditor: React.FC = ({ value, onChange, data }) => { return ( <> - + + onChange({ ...value, - expanded: event.currentTarget.checked, + showHeader: event.currentTarget.checked, }) } - {...TEST_IDS.tableEditor.fieldExpanded.apply()} + {...TEST_IDS.tableEditor.fieldShowHeader.apply()} /> - + onChange({ ...value, - showHeader: event.currentTarget.checked, + expanded: event.currentTarget.checked, }) } - {...TEST_IDS.tableEditor.fieldShowHeader.apply()} + {...TEST_IDS.tableEditor.fieldExpanded.apply()} /> +