diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 6475f01fa6..96ff81a7fd 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -58,6 +58,8 @@ const preview: Preview = {
+
+ diff --git a/package.json b/package.json index 5b0d036129..81dc4155c6 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "homepage": "/dashboard", "dependencies": { - "@devtron-labs/devtron-fe-common-lib": "1.10.8", + "@devtron-labs/devtron-fe-common-lib": "1.10.9", "@esbuild-plugins/node-globals-polyfill": "0.2.3", "@rjsf/core": "^5.13.3", "@rjsf/utils": "^5.13.3", @@ -66,7 +66,7 @@ "test:ci": "jest --watchAll=false --ci --json --coverage --testLocationInResults --outputFile=report.json", "jest": "jest", "lint-staged": "lint-staged", - "storybook": "IS_STORYBOOK=true storybook dev -p 6006", + "storybook": "IS_STORYBOOK=true GENERATE_SOURCEMAP=true storybook dev -p 6006", "build-storybook": "IS_STORYBOOK=true storybook build", "postinstall": "patch-package" }, diff --git a/src/css/forms.scss b/src/css/forms.scss index 730093e2d2..2e23f105c3 100644 --- a/src/css/forms.scss +++ b/src/css/forms.scss @@ -295,7 +295,7 @@ $checkbox-hover-bg-image: url('../assets/icons/ic-checkbox-hover.svg'); // Class for checkbox parent container, if added to parent container, hover effect will be applied to checkbox .checkbox__parent-container { - &:hover { + &--active, &:hover { .form__checkbox-container { background-image: $checkbox-hover-bg-image; } diff --git a/src/css/iconTheming.scss b/src/css/iconTheming.scss index 26d0b871ef..0eb01d3020 100644 --- a/src/css/iconTheming.scss +++ b/src/css/iconTheming.scss @@ -121,7 +121,7 @@ $svg-fill-hex-to-var: ( // Class for checkbox parent container, if added to parent container, hover effect will be applied to checkbox .checkbox__parent-container { - &:hover { + &--active, &:hover { .form__checkbox-container { background-image: $checkbox-hover-bg-image; } diff --git a/src/stories/Table.stories.tsx b/src/stories/Table.stories.tsx new file mode 100644 index 0000000000..ac4dac562f --- /dev/null +++ b/src/stories/Table.stories.tsx @@ -0,0 +1,245 @@ +import { useEffect } from 'react' +import { Meta, StoryObj } from '@storybook/react' +import { action } from '@storybook/addon-actions' +import { + Button, + ButtonComponentType, + ButtonStyleType, + ButtonVariantType, + ComponentSizeType, + FiltersTypeEnum, + PaginationEnum, + SearchBar, + SelectAllDialogStatus, + Table, + TableCellComponentProps, + TableProps, + TableViewWrapperProps, + TableSignalEnum, +} from '@devtron-labs/devtron-fe-common-lib' +import { ReactComponent as ICPlay } from '@Icons/ic-play-outline.svg' +import { ReactComponent as ICPause } from '@Icons/ic-pause.svg' +import { ReactComponent as ICWarning } from '@Icons/ic-warning-y6.svg' + +const CellComponent = ({ field, value, signals, row, isRowActive }: TableCellComponentProps) => { + const handleButtonClick = () => { + action(`Row ${value} clicked`) + } + + useEffect(() => { + const rowEnterPressedCallback = ({ + detail: { + activeRowData: { id }, + }, + }) => { + if (id === row.id && field === 'name') { + handleButtonClick() + } + } + + const getCallback = + (text: string) => + ({ + detail: { + activeRowData: { id }, + }, + }) => { + if (id === row.id && field === 'name') { + action(text) + } + } + + const deletePressedCallback = getCallback(`Delete pressed for ${value}`) + const openContextMenuCallback = getCallback(`Open context menu for ${value}`) + + signals.addEventListener(TableSignalEnum.ENTER_PRESSED, rowEnterPressedCallback) + signals.addEventListener(TableSignalEnum.DELETE_PRESSED, deletePressedCallback) + signals.addEventListener(TableSignalEnum.OPEN_CONTEXT_MENU, openContextMenuCallback) + + return () => { + signals.removeEventListener(TableSignalEnum.ENTER_PRESSED, rowEnterPressedCallback) + signals.removeEventListener(TableSignalEnum.DELETE_PRESSED, deletePressedCallback) + signals.removeEventListener(TableSignalEnum.OPEN_CONTEXT_MENU, openContextMenuCallback) + } + }, []) + + if (field === 'name') { + return ( +
+
+ ) + } + + return ( +
+ + + {value} +
+ ) +} + +const COLUMNS: TableProps['columns'] = [ + { + field: 'name', + size: { fixed: 300 }, + label: 'Name', + comparator: (a: string, b: string) => a.localeCompare(b), + isSortable: true, + CellComponent, + }, + { + field: 'value', + size: { + range: { + startWidth: 180, + minWidth: 100, + maxWidth: 600, + }, + }, + label: 'Value', + }, + { + field: 'message', + size: { + fixed: 200, + }, + label: 'Message', + CellComponent, + }, +] + +type RowDataType = { + name: string + value: string + message: string +} + +const ROWS: TableProps['rows'] = [ + { id: '1', data: { name: 'Alice', value: '123', message: 'Something new' } }, + { id: '2', data: { name: 'Bob', value: '456', message: 'Another message' } }, + { id: '3', data: { name: 'Charlie', value: '789', message: 'Yet another one' } }, + { id: '4', data: { name: 'Diana', value: '101', message: 'Message here' } }, + { id: '5', data: { name: 'Eve', value: '202', message: 'Something else' } }, + { id: '6', data: { name: 'Frank', value: '303', message: 'New message' } }, + { id: '7', data: { name: 'Grace', value: '404', message: 'Important note' } }, + { id: '8', data: { name: 'Hank', value: '505', message: 'Final message' } }, + { id: '9', data: { name: 'Ivy', value: '606', message: 'Additional info' } }, + { id: '10', data: { name: 'Jack', value: '707', message: 'Critical update' } }, + { id: '11', data: { name: 'Karen', value: '808', message: 'New feature' } }, + { id: '12', data: { name: 'Leo', value: '909', message: 'Bug fix' } }, + { id: '13', data: { name: 'Mona', value: '1010', message: 'Performance improvement' } }, + { id: '14', data: { name: 'Nina', value: '1111', message: 'Security patch' } }, + { id: '15', data: { name: 'Oscar', value: '1212', message: 'UI enhancement' } }, + { id: '16', data: { name: 'Paul', value: '1313', message: 'Backend update' } }, + { id: '17', data: { name: 'Quinn', value: '1414', message: 'Database migration' } }, + { id: '18', data: { name: 'Rachel', value: '1515', message: 'API change' } }, + { id: '19', data: { name: 'Steve', value: '1616', message: 'Documentation update' } }, + { id: '20', data: { name: 'Tina', value: '1717', message: 'New integration' } }, + { id: '21', data: { name: 'Uma', value: '1818', message: 'Deprecated feature' } }, + { id: '22', data: { name: 'Victor', value: '1919', message: 'Hotfix applied' } }, + { id: '23', data: { name: 'Wendy', value: '2020', message: 'Code refactor' } }, + { id: '24', data: { name: 'Xander', value: '2121', message: 'New dependency' } }, + { id: '25', data: { name: 'Yara', value: '2222', message: 'Improved logging' } }, + { id: '26', data: { name: 'Zane', value: '2323', message: 'Monitoring added' } }, + { id: '27', data: { name: 'Amy', value: '2424', message: 'Analytics update' } }, + { id: '28', data: { name: 'Brian', value: '2525', message: 'Localization added' } }, + { id: '29', data: { name: 'Cathy', value: '2626', message: 'Accessibility fix' } }, + { id: '30', data: { name: 'David', value: '2727', message: 'New dashboard' } }, + { id: '31', data: { name: 'Ella', value: '2828', message: 'Improved UX' } }, + { id: '32', data: { name: 'Fred', value: '2929', message: 'Updated icons' } }, + { id: '33', data: { name: 'Gina', value: '3030', message: 'Enhanced security' } }, + { id: '34', data: { name: 'Harry', value: '3131', message: 'New theme' } }, + { id: '35', data: { name: 'Iris', value: '3232', message: 'Updated dependencies' } }, + { id: '36', data: { name: 'Jake', value: '3333', message: 'Improved performance' } }, + { id: '37', data: { name: 'Kara', value: '3434', message: 'New API endpoint' } }, + { id: '38', data: { name: 'Liam', value: '3535', message: 'Updated README' } }, +] + +const meta = { + component: Table, +} satisfies Meta + +export default meta + +type Story = StoryObj + +const BulkActionsComponent = () => ( +
+
+) + +const ViewWrapper = ({ children, handleSearch, searchKey }: TableViewWrapperProps) => ( +
+
+ +
+ + {children} +
+) + +export const TableTemplate: Story = { + args: { + columns: COLUMNS, + rows: ROWS, + filtersVariant: FiltersTypeEnum.STATE, + id: 'table__story', + paginationVariant: PaginationEnum.PAGINATED, + emptyStateConfig: { + noRowsConfig: { + title: 'No rows to display', + description: 'There are no rows to display.', + }, + }, + filter: (row, filterData) => { + const lowerCasedSearchKey = filterData.searchKey.toLowerCase() + return (row.data as RowDataType).name.toLowerCase().includes(lowerCasedSearchKey) + }, + bulkSelectionConfig: { + BulkActionsComponent, + getSelectAllDialogStatus: () => SelectAllDialogStatus.CLOSED, + onBulkSelectionChanged: () => {}, + }, + stylesConfig: { + showSeparatorBetweenRows: true, + }, + ViewWrapper, + additionalFilterProps: { + initialSortKey: 'name', + }, + } as TableProps, +} diff --git a/yarn.lock b/yarn.lock index 549f4137a6..77bc0f02fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1126,10 +1126,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@devtron-labs/devtron-fe-common-lib@1.10.8": - version "1.10.8" - resolved "https://registry.yarnpkg.com/@devtron-labs/devtron-fe-common-lib/-/devtron-fe-common-lib-1.10.8.tgz#6a182b39e222a9dc980156de090726e0bab07467" - integrity sha512-vg3VMfTFt0ak08J0FnhtfAIiD0u+0c2n0dFNuuPeJuCY3SIDBNM3CEgYrwq3KQtRrkbiNNyBONJuA3FY8rOzsw== +"@devtron-labs/devtron-fe-common-lib@1.10.9": + version "1.10.9" + resolved "https://registry.yarnpkg.com/@devtron-labs/devtron-fe-common-lib/-/devtron-fe-common-lib-1.10.9.tgz#b64153a618c4ff0f4d13bca077a8ce24eda2af68" + integrity sha512-A/nXq/Y3AH1ULaBItEa+l+R5XjcdOjGHy4agurAdv/Zus/j6q3OD33zyuR7UwsghqPZMatO3O+Eew64l91D7xw== dependencies: "@codemirror/lang-json" "6.0.1" "@codemirror/lang-yaml" "6.1.2"