Skip to content

Commit 3d8aa83

Browse files
authored
Merge pull request #652 from devtron-labs/feat/table
feat: table component
2 parents dfc11a4 + 966af75 commit 3d8aa83

19 files changed

+1374
-10
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devtron-labs/devtron-fe-common-lib",
3-
"version": "1.10.8",
3+
"version": "1.10.9",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",

src/Common/Hooks/UseRegisterShortcut/types.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import { IS_PLATFORM_MAC_OS } from '@Common/Constants'
1818

19+
// NOTE: check this link for more info on keyboard keys: https://w3c.github.io/uievents-key/
1920
export const KEYBOARD_KEYS_MAP = {
2021
Control: 'Ctrl',
2122
Shift: '⇧',
@@ -25,8 +26,22 @@ export const KEYBOARD_KEYS_MAP = {
2526
E: 'E',
2627
R: 'R',
2728
K: 'K',
29+
X: 'X',
30+
A: 'A',
2831
Escape: 'Esc',
2932
Enter: '↩',
33+
ArrowLeft: '←',
34+
ArrowRight: '→',
35+
ArrowUp: '↑',
36+
ArrowDown: '↓',
37+
PageUp: 'PgUp',
38+
PageDown: 'PgDn',
39+
Home: 'Home',
40+
End: 'End',
41+
Backspace: '⌫',
42+
Delete: '⌦',
43+
'.': '.',
44+
Space: 'Space',
3045
} as const
3146

3247
export type SupportedKeyboardKeysType = keyof typeof KEYBOARD_KEYS_MAP

src/Common/Hooks/useStateFilters/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export interface UseStateFiltersReturnType<T>
3131
| 'pageSize'
3232
| 'searchKey'
3333
| 'handleSearch'
34+
| 'isFilterApplied'
3435
> {}
3536

3637
export interface PaginationType<T> extends Pick<UseUrlFiltersReturnType<T>, 'pageSize'> {

src/Common/Hooks/useStateFilters/useStateFilters.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ const useStateFilters = <T = string,>({
116116
changePage,
117117
changePageSize,
118118
offset,
119+
isFilterApplied: !!searchKey,
119120
}
120121
}
121122

src/Common/Hooks/useUrlFilters/types.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import { SortingOrder } from '../../Constants'
1818

19-
export interface UseUrlFiltersProps<T, K> {
19+
export interface UseUrlFiltersProps<T, K extends {}> {
2020
/**
2121
* The key on which the sorting should be applied
2222
*/
@@ -37,9 +37,9 @@ export interface UseUrlFiltersProps<T, K> {
3737
redirectionMethod?: 'replace' | 'push'
3838
}
3939

40-
export type UpdateSearchParamsOptionsType<T, K = unknown> = Partial<Pick<UseUrlFiltersProps<T, K>, 'redirectionMethod'>>
40+
export type UpdateSearchParamsOptionsType<T, K = {}> = Partial<Pick<UseUrlFiltersProps<T, K>, 'redirectionMethod'>>
4141

42-
export type UseUrlFiltersReturnType<T, K = unknown> = K & {
42+
export type UseUrlFiltersReturnType<T, K = {}> = K & {
4343
/**
4444
* Currently applied page size
4545
*/
@@ -86,4 +86,5 @@ export type UseUrlFiltersReturnType<T, K = unknown> = K & {
8686
* Update the search params with the passed object
8787
*/
8888
updateSearchParams: (paramsToSerialize: Partial<K>, options?: UpdateSearchParamsOptionsType<T, K>) => void
89+
isFilterApplied: boolean
8990
}

src/Common/Hooks/useUrlFilters/useUrlFilters.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { getUrlWithSearchParams } from '@Common/Helper'
2020
import { DEFAULT_BASE_PAGE_SIZE, EXCLUDED_FALSY_VALUES, SortingOrder } from '../../Constants'
2121
import { DEFAULT_PAGE_NUMBER, URL_FILTER_KEYS } from './constants'
2222
import { UpdateSearchParamsOptionsType, UseUrlFiltersProps, UseUrlFiltersReturnType } from './types'
23-
import { setItemInLocalStorageIfKeyExists } from './utils'
23+
import { areAnyAdditionalFiltersApplied, setItemInLocalStorageIfKeyExists } from './utils'
2424

2525
const { PAGE_SIZE, PAGE_NUMBER, SEARCH_KEY, SORT_BY, SORT_ORDER } = URL_FILTER_KEYS
2626

@@ -41,7 +41,8 @@ const { PAGE_SIZE, PAGE_NUMBER, SEARCH_KEY, SORT_BY, SORT_ORDER } = URL_FILTER_K
4141
* ```
4242
*
4343
*/
44-
const useUrlFilters = <T = string, K = unknown>({
44+
45+
const useUrlFilters = <T = string, K = {}>({
4546
initialSortKey,
4647
parseSearchParams,
4748
localStorageKey,
@@ -220,6 +221,7 @@ const useUrlFilters = <T = string, K = unknown>({
220221
clearFilters,
221222
...parsedParams,
222223
updateSearchParams,
224+
isFilterApplied: !!searchKey || areAnyAdditionalFiltersApplied(parsedParams),
223225
}
224226
}
225227

src/Common/Hooks/useUrlFilters/utils.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,28 @@
1414
* limitations under the License.
1515
*/
1616

17+
import { isNullOrUndefined } from '@Shared/Helpers'
18+
1719
export const setItemInLocalStorageIfKeyExists = (localStorageKey: string, value: string) => {
1820
if (localStorageKey) {
1921
localStorage.setItem(localStorageKey, value)
2022
}
2123
}
24+
25+
export const areAnyAdditionalFiltersApplied = (parsedParams: Record<string | number, any>) => {
26+
if (!parsedParams || !Object.keys(parsedParams).length) {
27+
return false
28+
}
29+
30+
return Object.keys(parsedParams).some((key) => {
31+
if (isNullOrUndefined(parsedParams[key])) {
32+
return false
33+
}
34+
35+
if (Array.isArray(parsedParams[key]) || typeof parsedParams[key] === 'string') {
36+
return parsedParams[key].length > 0
37+
}
38+
39+
return true
40+
})
41+
}

src/Common/Tooltip/ShortcutKeyComboTooltipContent.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ const ShortcutKeyComboTooltipContent = ({ text, combo }: TooltipProps['shortcutK
2323
{!!combo?.length && (
2424
<div className="flexbox dc__gap-4 dc__align-items-center flex-wrap">
2525
{combo.map((key) => (
26-
<span key={key} className="shortcut-keys__chip dc__capitalize lh-16 fs-11 fw-5 flex">
26+
// TODO: check styling for this since span was replaced by kbd
27+
<kbd key={key} className="shortcut-keys__chip dc__capitalize lh-16 fs-11 fw-5 flex">
2728
{KEYBOARD_KEYS_MAP[key]}
28-
</span>
29+
</kbd>
2930
))}
3031
</div>
3132
)}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2024. Devtron Inc.
3+
*/
4+
5+
import { ReactComponent as ICClose } from '@Icons/ic-close.svg'
6+
import { DraggableButton, DraggablePositionVariant, DraggableWrapper } from '@Common/DraggableWrapper'
7+
import { ComponentSizeType } from '@Shared/constants'
8+
import { useRegisterShortcut } from '@Common/Hooks'
9+
import { useEffect } from 'react'
10+
import { BulkSelectionActionWidgetProps } from './types'
11+
import { Button, ButtonComponentType, ButtonStyleType, ButtonVariantType } from '../Button'
12+
import { DRAG_SELECTOR_IDENTIFIER } from './constants'
13+
14+
const BulkSelectionActionWidget = ({
15+
count,
16+
handleClearBulkSelection,
17+
parentRef,
18+
BulkActionsComponent,
19+
}: BulkSelectionActionWidgetProps) => {
20+
const { registerShortcut, unregisterShortcut } = useRegisterShortcut()
21+
22+
useEffect(() => {
23+
registerShortcut({ keys: ['Escape'], callback: handleClearBulkSelection })
24+
25+
return () => {
26+
unregisterShortcut(['Escape'])
27+
}
28+
}, [])
29+
30+
return (
31+
<DraggableWrapper
32+
dragSelector={`.${DRAG_SELECTOR_IDENTIFIER}`}
33+
positionVariant={DraggablePositionVariant.PARENT_BOTTOM_CENTER}
34+
zIndex="calc(var(--modal-index) - 1)"
35+
parentRef={parentRef}
36+
>
37+
<div className="dc__separated-flexbox dc__separated-flexbox--gap-8 p-12 bulk-selection-widget br-8">
38+
<div className="flexbox dc__gap-8">
39+
<DraggableButton dragClassName={DRAG_SELECTOR_IDENTIFIER} />
40+
41+
<div className="fs-13 lh-20 fw-6 flex dc__gap-12">
42+
<span className="flex dc__gap-2 bcb-5 text__white br-4 px-6">{count}</span>
43+
<span className="cn-9">Selected</span>
44+
</div>
45+
</div>
46+
47+
<BulkActionsComponent />
48+
49+
<Button
50+
icon={<ICClose />}
51+
dataTestId="table__action-widget--close"
52+
component={ButtonComponentType.button}
53+
style={ButtonStyleType.negativeGrey}
54+
variant={ButtonVariantType.borderLess}
55+
ariaLabel="Clear selection(s)"
56+
size={ComponentSizeType.small}
57+
onClick={handleClearBulkSelection}
58+
showAriaLabelInTippy={false}
59+
/>
60+
</div>
61+
</DraggableWrapper>
62+
)
63+
}
64+
65+
export default BulkSelectionActionWidget

0 commit comments

Comments
 (0)