From ba4fa06f3b7d3fbf028fa496326beed6cb282b70 Mon Sep 17 00:00:00 2001 From: asimonok Date: Thu, 23 Nov 2023 12:40:51 +0300 Subject: [PATCH 1/5] Update with lint rules --- cypress/integration/01-view-panel.test.ts | 4 +- package-lock.json | 23 +++- package.json | 3 +- .../{styles.ts => ButtonView.styles.ts} | 2 +- src/components/ButtonView/ButtonView.test.tsx | 12 +- src/components/ButtonView/ButtonView.tsx | 16 +-- src/components/Collapse/Collapse.tsx | 4 +- src/components/Collapse/styles.ts | 2 +- .../{styles.ts => GroupsEditor.styles.ts} | 2 +- .../GroupsEditor/GroupsEditor.test.tsx | 10 +- src/components/GroupsEditor/GroupsEditor.tsx | 24 ++-- .../{styles.ts => LevelsEditor.styles.ts} | 2 +- .../LevelsEditor/LevelsEditor.test.tsx | 20 +-- src/components/LevelsEditor/LevelsEditor.tsx | 18 +-- .../MinimizeView/MinimizeView.test.tsx | 14 +- src/components/MinimizeView/MinimizeView.tsx | 6 +- .../OptionsVariable/OptionsVariable.test.tsx | 18 +-- .../OptionsVariable/OptionsVariable.tsx | 6 +- src/components/Table/Filter.tsx | 20 +-- .../Table/{styles.ts => Table.styles.ts} | 2 +- src/components/Table/Table.test.tsx | 6 +- src/components/Table/Table.tsx | 26 ++-- .../{styles.ts => TableView.styles.ts} | 2 +- src/components/TableView/TableView.test.tsx | 6 +- src/components/TableView/TableView.tsx | 14 +- .../TextVariable/TextVariable.test.tsx | 4 +- src/components/TextVariable/TextVariable.tsx | 4 +- src/constants/panel.ts | 22 ++-- src/constants/tests.ts | 2 +- src/constants/variable.ts | 6 +- src/hooks/useTable.test.tsx | 122 +++++++++--------- src/hooks/useTable.tsx | 28 ++-- src/module.ts | 44 +++---- src/utils/options-variable.ts | 18 +-- src/utils/table.ts | 4 +- src/utils/variable.test.ts | 20 +-- src/utils/variable.ts | 20 +-- 37 files changed, 286 insertions(+), 270 deletions(-) rename src/components/ButtonView/{styles.ts => ButtonView.styles.ts} (80%) rename src/components/GroupsEditor/{styles.ts => GroupsEditor.styles.ts} (94%) rename src/components/LevelsEditor/{styles.ts => LevelsEditor.styles.ts} (96%) rename src/components/Table/{styles.ts => Table.styles.ts} (97%) rename src/components/TableView/{styles.ts => TableView.styles.ts} (94%) diff --git a/cypress/integration/01-view-panel.test.ts b/cypress/integration/01-view-panel.test.ts index efb5fde..df08c72 100644 --- a/cypress/integration/01-view-panel.test.ts +++ b/cypress/integration/01-view-panel.test.ts @@ -1,5 +1,5 @@ import { e2e } from '@grafana/e2e'; -import { TestIds } from '../../src/constants'; +import { TEST_IDS } from '../../src/constants'; /** * Dashboard @@ -29,7 +29,7 @@ describe('Viewing an Variable panel', () => { /** * Root */ - const chart = currentPanel.find(getTestIdSelector(TestIds.tableView.root)); + const chart = currentPanel.find(getTestIdSelector(TEST_IDS.tableView.root)); chart.should('be.visible'); /** diff --git a/package-lock.json b/package-lock.json index bd91c24..83d48b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@grafana/ui": "^10.2.1", "@tanstack/react-table": "8.9.3", "@tanstack/react-virtual": "3.0.0-beta.60", + "@volkovlabs/components": "^1.1.0", "react": "^18.2.0", "react-beautiful-dnd": "^13.1.1", "react-dom": "^18.2.0", @@ -36,7 +37,7 @@ "@types/node": "^18.18.10", "@types/react-beautiful-dnd": "^13.1.7", "@typescript-eslint/eslint-plugin": "^6.11.0", - "@volkovlabs/eslint-config": "^1.1.0", + "@volkovlabs/eslint-config": "^1.2.1", "@volkovlabs/jest-selectors": "^1.2.0", "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.8.1", @@ -6663,10 +6664,24 @@ "dev": true, "peer": true }, - "node_modules/@volkovlabs/eslint-config": { + "node_modules/@volkovlabs/components": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@volkovlabs/eslint-config/-/eslint-config-1.1.0.tgz", - "integrity": "sha512-yYXJkayS6rUoJzXHnthvViXLbCaLHWBcMHtrlonJ0kqME7A0VDYaqRbNJu+5+Mj8Czim4jxcUWKw1LWNFTECig==", + "resolved": "https://registry.npmjs.org/@volkovlabs/components/-/components-1.1.0.tgz", + "integrity": "sha512-pNTfieF4pYvyRfvhO0tvkM5FK0b19w6jhjdMgbviwPdMLD7HlIj/DVmOjW5d9v2s6arIvz03LylHpACUD4Iy0Q==", + "dependencies": { + "@emotion/css": "^11.11.2", + "@grafana/data": "^10.2.1", + "@grafana/ui": "^10.2.1" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@volkovlabs/eslint-config": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@volkovlabs/eslint-config/-/eslint-config-1.2.1.tgz", + "integrity": "sha512-O/0kwVIlmWkqQpCgZQ4ZwzUBOabYTZEa0VXlXwDXjq2ACpmyCFNBpupyudbSEiwdjJ18skf5EAG3sLTs3HYUGA==", "dev": true, "dependencies": { "@typescript-eslint/eslint-plugin": "^6.0.0", diff --git a/package.json b/package.json index b24185a..c203c62 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "@grafana/ui": "^10.2.1", "@tanstack/react-table": "8.9.3", "@tanstack/react-virtual": "3.0.0-beta.60", + "@volkovlabs/components": "^1.1.0", "react": "^18.2.0", "react-beautiful-dnd": "^13.1.1", "react-dom": "^18.2.0", @@ -29,7 +30,7 @@ "@types/node": "^18.18.10", "@types/react-beautiful-dnd": "^13.1.7", "@typescript-eslint/eslint-plugin": "^6.11.0", - "@volkovlabs/eslint-config": "^1.1.0", + "@volkovlabs/eslint-config": "^1.2.1", "@volkovlabs/jest-selectors": "^1.2.0", "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.8.1", diff --git a/src/components/ButtonView/styles.ts b/src/components/ButtonView/ButtonView.styles.ts similarity index 80% rename from src/components/ButtonView/styles.ts rename to src/components/ButtonView/ButtonView.styles.ts index f5b24f8..c0db6d9 100644 --- a/src/components/ButtonView/styles.ts +++ b/src/components/ButtonView/ButtonView.styles.ts @@ -4,7 +4,7 @@ import { GrafanaTheme2 } from '@grafana/data'; /** * Styles */ -export const Styles = (theme: GrafanaTheme2) => { +export const getStyles = (theme: GrafanaTheme2) => { return { root: css` display: flex; diff --git a/src/components/ButtonView/ButtonView.test.tsx b/src/components/ButtonView/ButtonView.test.tsx index f982454..2d09d53 100644 --- a/src/components/ButtonView/ButtonView.test.tsx +++ b/src/components/ButtonView/ButtonView.test.tsx @@ -3,7 +3,7 @@ import { fireEvent, render, screen } from '@testing-library/react'; import { getJestSelectors } from '@volkovlabs/jest-selectors'; import React from 'react'; -import { AllValue, AllValueParameter, TestIds } from '../../constants'; +import { ALL_VALUE, ALL_VALUE_PARAMETER, TEST_IDS } from '../../constants'; import { useRuntimeVariables } from '../../hooks'; import { VariableType } from '../../types'; import { selectVariableValues } from '../../utils'; @@ -36,7 +36,7 @@ describe('ButtonView', () => { /** * Selectors */ - const getSelectors = getJestSelectors(TestIds.buttonView); + const getSelectors = getJestSelectors(TEST_IDS.buttonView); const selectors = getSelectors(screen); /** @@ -77,8 +77,8 @@ describe('ButtonView', () => { type: VariableType.CUSTOM, options: [ { - text: AllValue, - value: AllValueParameter, + text: ALL_VALUE, + value: ALL_VALUE_PARAMETER, selected: false, }, { @@ -164,7 +164,7 @@ describe('ButtonView', () => { }) ); - expect(selectors.item(false, AllValue)).toBeInTheDocument(); + expect(selectors.item(false, ALL_VALUE)).toBeInTheDocument(); expect(selectors.item(false, 'device1')).toBeInTheDocument(); expect(selectors.item(false, 'device2')).toBeInTheDocument(); }); @@ -207,7 +207,7 @@ describe('ButtonView', () => { /** * All should be selected */ - expect(selectVariableValues).toHaveBeenCalledWith([AllValueParameter], variable); + expect(selectVariableValues).toHaveBeenCalledWith([ALL_VALUE_PARAMETER], variable); }); it('Should work if no status color', () => { diff --git a/src/components/ButtonView/ButtonView.tsx b/src/components/ButtonView/ButtonView.tsx index 2065784..88c94cc 100644 --- a/src/components/ButtonView/ButtonView.tsx +++ b/src/components/ButtonView/ButtonView.tsx @@ -3,11 +3,11 @@ import { EventBus, PanelData } from '@grafana/data'; import { Alert, Button, useStyles2, useTheme2 } from '@grafana/ui'; import React, { useMemo } from 'react'; -import { AllValue, AllValueParameter, TestIds } from '../../constants'; +import { ALL_VALUE, ALL_VALUE_PARAMETER, TEST_IDS } from '../../constants'; import { useRuntimeVariables, useStatus } from '../../hooks'; import { PanelOptions } from '../../types'; import { isVariableWithOptions, updateVariableOptions } from '../../utils'; -import { Styles } from './styles'; +import { getStyles } from './ButtonView.styles'; /** * Properties @@ -40,7 +40,7 @@ export const ButtonView: React.FC = ({ /** * Styles and Theme */ - const styles = useStyles2(Styles); + const styles = useStyles2(getStyles); const theme = useTheme2(); /** @@ -68,7 +68,7 @@ export const ButtonView: React.FC = ({ */ if (!variable) { return ( - + Variable is not selected. ); @@ -80,7 +80,7 @@ export const ButtonView: React.FC = ({ const options = isVariableWithOptions(variable) && variable.options.length; if (!options) { return ( - + Options are not available. ); @@ -94,10 +94,10 @@ export const ButtonView: React.FC = ({ padding: ${padding}px; ` )} - data-testid={TestIds.buttonView.root} + data-testid={TEST_IDS.buttonView.root} > {variable.options.map((option) => { - const value = option.value === AllValueParameter ? AllValue : option.value; + const value = option.value === ALL_VALUE_PARAMETER ? ALL_VALUE : option.value; const status = getStatus(value); const backgroundColor = option.selected ? status.exist @@ -132,7 +132,7 @@ export const ButtonView: React.FC = ({ value, }); }} - data-testid={TestIds.buttonView.item(value)} + data-testid={TEST_IDS.buttonView.item(value)} > {option.text.toString()} diff --git a/src/components/Collapse/Collapse.tsx b/src/components/Collapse/Collapse.tsx index ded6e05..679cff3 100644 --- a/src/components/Collapse/Collapse.tsx +++ b/src/components/Collapse/Collapse.tsx @@ -1,7 +1,7 @@ import { IconButton, useTheme2 } from '@grafana/ui'; import React from 'react'; -import { Styles } from './styles'; +import { getStyles } from './styles'; /** * Properties @@ -59,7 +59,7 @@ export const Collapse: React.FC = ({ * Styles and Theme */ const theme = useTheme2(); - const styles = Styles(theme); + const styles = getStyles(theme); return (
diff --git a/src/components/Collapse/styles.ts b/src/components/Collapse/styles.ts index 752d8fc..0b8170d 100644 --- a/src/components/Collapse/styles.ts +++ b/src/components/Collapse/styles.ts @@ -4,7 +4,7 @@ import { GrafanaTheme2 } from '@grafana/data'; /** * Styles */ -export const Styles = (theme: GrafanaTheme2) => { +export const getStyles = (theme: GrafanaTheme2) => { return { root: css` border: 1px solid ${theme.colors.border.weak}; diff --git a/src/components/GroupsEditor/styles.ts b/src/components/GroupsEditor/GroupsEditor.styles.ts similarity index 94% rename from src/components/GroupsEditor/styles.ts rename to src/components/GroupsEditor/GroupsEditor.styles.ts index f549e9a..355aab0 100644 --- a/src/components/GroupsEditor/styles.ts +++ b/src/components/GroupsEditor/GroupsEditor.styles.ts @@ -4,7 +4,7 @@ import { GrafanaTheme2 } from '@grafana/data'; /** * Styles */ -export const Styles = (theme: GrafanaTheme2) => { +export const getStyles = (theme: GrafanaTheme2) => { return { newGroup: css` margin: ${theme.spacing(2)} 0; diff --git a/src/components/GroupsEditor/GroupsEditor.test.tsx b/src/components/GroupsEditor/GroupsEditor.test.tsx index 62588e2..06e1fb6 100644 --- a/src/components/GroupsEditor/GroupsEditor.test.tsx +++ b/src/components/GroupsEditor/GroupsEditor.test.tsx @@ -4,7 +4,7 @@ import { getJestSelectors } from '@volkovlabs/jest-selectors'; import React from 'react'; import { DragDropContext, DropResult } from 'react-beautiful-dnd'; -import { TestIds } from '../../constants'; +import { TEST_IDS } from '../../constants'; import { LevelsEditor } from '../LevelsEditor'; import { GroupsEditor } from './GroupsEditor'; @@ -32,7 +32,7 @@ jest.mock('@grafana/ui', () => ({ * Mock LevelsEditor */ jest.mock('../LevelsEditor', () => ({ - LevelsEditor: jest.fn(() =>
), + LevelsEditor: jest.fn(() =>
), })); /** @@ -94,7 +94,7 @@ describe('GroupsEditor', () => { * Selectors */ const getSelectors = getJestSelectors({ - ...TestIds.groupsEditor, + ...TEST_IDS.groupsEditor, ...InTestIds, }); const selectors = getSelectors(screen); @@ -102,7 +102,7 @@ describe('GroupsEditor', () => { /** * Levels Selectors */ - const getLevelsSelectors = getJestSelectors(TestIds.levelsEditor); + const getLevelsSelectors = getJestSelectors(TEST_IDS.levelsEditor); const levelsSelectors = getLevelsSelectors(screen); it('Should render groups', () => { @@ -677,7 +677,7 @@ describe('GroupsEditor', () => { const onChange = jest.fn(); jest.mocked(LevelsEditor).mockImplementation(({ name, onChange }) => ( -
+
) : (
{name}
) } - headerTestId={TestIds.groupsEditor.item(name)} + headerTestId={TEST_IDS.groupsEditor.item(name)} actions={ <> {editItem !== name && ( @@ -246,7 +246,7 @@ export const GroupsEditor: React.FC = ({ context: { options, data }, onCh setEditName(name); setEditItem(name); }} - data-testid={TestIds.groupsEditor.buttonStartRename} + data-testid={TEST_IDS.groupsEditor.buttonStartRename} /> )} diff --git a/src/components/LevelsEditor/styles.ts b/src/components/LevelsEditor/LevelsEditor.styles.ts similarity index 96% rename from src/components/LevelsEditor/styles.ts rename to src/components/LevelsEditor/LevelsEditor.styles.ts index c82fd7b..7b76eda 100644 --- a/src/components/LevelsEditor/styles.ts +++ b/src/components/LevelsEditor/LevelsEditor.styles.ts @@ -4,7 +4,7 @@ import { GrafanaTheme2 } from '@grafana/data'; /** * Styles */ -export const Styles = (theme: GrafanaTheme2) => { +export const getStyles = (theme: GrafanaTheme2) => { return { header: css` padding: ${theme.spacing(0.5, 0.5)}; diff --git a/src/components/LevelsEditor/LevelsEditor.test.tsx b/src/components/LevelsEditor/LevelsEditor.test.tsx index 0f4cf94..a196d94 100644 --- a/src/components/LevelsEditor/LevelsEditor.test.tsx +++ b/src/components/LevelsEditor/LevelsEditor.test.tsx @@ -4,7 +4,7 @@ import { act, fireEvent, render, screen, within } from '@testing-library/react'; import React from 'react'; import { DragDropContext, DropResult } from 'react-beautiful-dnd'; -import { TestIds } from '../../constants'; +import { TEST_IDS } from '../../constants'; import { LevelsEditor } from './LevelsEditor'; /** @@ -112,8 +112,8 @@ describe('LevelsEditor', () => { }) ); - expect(screen.getByTestId(TestIds.levelsEditor.item('field1'))).toBeInTheDocument(); - expect(screen.getByTestId(TestIds.levelsEditor.item('field2'))).toBeInTheDocument(); + expect(screen.getByTestId(TEST_IDS.levelsEditor.item('field1'))).toBeInTheDocument(); + expect(screen.getByTestId(TEST_IDS.levelsEditor.item('field2'))).toBeInTheDocument(); }); it('Should allow select any fields', () => { @@ -290,13 +290,13 @@ describe('LevelsEditor', () => { ); await act(() => - fireEvent.change(screen.getByLabelText(TestIds.levelsEditor.newItemName), { target: { value: 'field2' } }) + fireEvent.change(screen.getByLabelText(TEST_IDS.levelsEditor.newItemName), { target: { value: 'field2' } }) ); - expect(screen.getByTestId(TestIds.levelsEditor.buttonAddNew)).toBeInTheDocument(); - expect(screen.getByTestId(TestIds.levelsEditor.buttonAddNew)).not.toBeDisabled(); + expect(screen.getByTestId(TEST_IDS.levelsEditor.buttonAddNew)).toBeInTheDocument(); + expect(screen.getByTestId(TEST_IDS.levelsEditor.buttonAddNew)).not.toBeDisabled(); - await act(() => fireEvent.click(screen.getByTestId(TestIds.levelsEditor.buttonAddNew))); + await act(() => fireEvent.click(screen.getByTestId(TEST_IDS.levelsEditor.buttonAddNew))); expect(onChange).toHaveBeenCalledWith({ name: 'Group 1', @@ -328,7 +328,7 @@ describe('LevelsEditor', () => { }) ); - const field2 = screen.getByTestId(TestIds.levelsEditor.item('field2')); + const field2 = screen.getByTestId(TEST_IDS.levelsEditor.item('field2')); /** * Check field presence @@ -338,7 +338,7 @@ describe('LevelsEditor', () => { /** * Remove */ - await act(() => fireEvent.click(within(field2).getByTestId(TestIds.levelsEditor.buttonRemove))); + await act(() => fireEvent.click(within(field2).getByTestId(TEST_IDS.levelsEditor.buttonRemove))); expect(onChange).toHaveBeenCalledWith({ name: 'Group 1', items: [{ name: 'field1', source: 'A' }] }); }); @@ -357,7 +357,7 @@ describe('LevelsEditor', () => { }) ); - expect(screen.getByTestId(TestIds.levelsEditor.root)).toBeInTheDocument(); + expect(screen.getByTestId(TEST_IDS.levelsEditor.root)).toBeInTheDocument(); }); it('Should reorder items', async () => { diff --git a/src/components/LevelsEditor/LevelsEditor.tsx b/src/components/LevelsEditor/LevelsEditor.tsx index e273186..1ec916b 100644 --- a/src/components/LevelsEditor/LevelsEditor.tsx +++ b/src/components/LevelsEditor/LevelsEditor.tsx @@ -11,10 +11,10 @@ import { NotDraggingStyle, } from 'react-beautiful-dnd'; -import { TestIds } from '../../constants'; +import { TEST_IDS } from '../../constants'; import { Level, LevelsGroup } from '../../types'; import { reorder } from '../../utils'; -import { Styles } from './styles'; +import { getStyles } from './LevelsEditor.styles'; /** * Get Item Style @@ -56,7 +56,7 @@ export const LevelsEditor: React.FC = ({ items: groupLevels, name, onChan * Styles and Theme */ const theme = useTheme2(); - const styles = Styles(theme); + const styles = getStyles(theme); /** * States @@ -154,7 +154,7 @@ export const LevelsEditor: React.FC = ({ items: groupLevels, name, onChan }, [items, newLevel, onChangeItems]); return ( -
+
{(provided) => ( @@ -168,7 +168,7 @@ export const LevelsEditor: React.FC = ({ items: groupLevels, name, onChan {...provided.dragHandleProps} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, index)} className={styles.item} - data-testid={TestIds.levelsEditor.item(item.name)} + data-testid={TEST_IDS.levelsEditor.item(item.name)} >
@@ -184,7 +184,7 @@ export const LevelsEditor: React.FC = ({ items: groupLevels, name, onChan name="trash-alt" onClick={() => onChangeItems(items.filter((field) => field.name !== item.name))} aria-label="Remove" - data-testid={TestIds.levelsEditor.buttonRemove} + data-testid={TEST_IDS.levelsEditor.buttonRemove} /> = ({ items: groupLevels, name, onChan - + { +interface Props { /** * Column */ - column: Column; + column: Column; /** * Always Visible @@ -24,11 +24,11 @@ interface Props { * Filter * @param props */ -export const Filter = ({ column, alwaysVisible }: Props) => { +export const Filter = ({ column, alwaysVisible }: Props) => { /** * Styles */ - const styles = useStyles2(Styles); + const styles = useStyles2(getStyles); /** * States @@ -69,7 +69,7 @@ export const Filter = ({ column, alwaysVisible }: Prop onClick={() => { column.setFilterValue(!columnFilterValue); }} - data-testid={TestIds.table.favoritesFilter} + data-testid={TEST_IDS.table.favoritesFilter} > {columnFilterValue ? : } @@ -85,14 +85,14 @@ export const Filter = ({ column, alwaysVisible }: Prop value={typeof columnFilterValue === 'string' ? columnFilterValue : ''} onChange={onChangeFilterValue} className={styles.filterInput} - data-testid={TestIds.table.fieldFilterValue} + data-testid={TEST_IDS.table.fieldFilterValue} addonAfter={ columnFilterValue ? (