+
)
diff --git a/src/Shared/Components/BulkSelection/BulkSelection.tsx b/src/Shared/Components/BulkSelection/BulkSelection.tsx
index 866b89cb9..349b484c8 100644
--- a/src/Shared/Components/BulkSelection/BulkSelection.tsx
+++ b/src/Shared/Components/BulkSelection/BulkSelection.tsx
@@ -14,84 +14,101 @@
* limitations under the License.
*/
-import { ReactComponent as ICCheckAll } from '../../../Assets/Icon/ic-check-all.svg'
-import { ReactComponent as ICCheckSquare } from '../../../Assets/Icon/ic-check-square.svg'
+import { forwardRef, MouseEvent } from 'react'
+
import { ReactComponent as ICChevronDown } from '../../../Assets/Icon/ic-chevron-down.svg'
-import { ReactComponent as ICClose } from '../../../Assets/Icon/ic-close.svg'
-import { Checkbox, CHECKBOX_VALUE, noop, PopupMenu } from '../../../Common'
-import BulkSelectionDropdownItems from './BulkSelectionDropdownItems'
+import { Checkbox, noop } from '../../../Common'
+import { ActionMenu, ActionMenuItemType, ActionMenuProps } from '../ActionMenu'
import { useBulkSelection } from './BulkSelectionProvider'
import { BULK_DROPDOWN_TEST_ID, BulkSelectionOptionsLabels } from './constants'
-import { BulkSelectionDropdownItemsType, BulkSelectionEvents, BulkSelectionProps } from './types'
+import { BulkSelectionEvents, BulkSelectionProps } from './types'
+
+const BulkSelection = forwardRef
(
+ (
+ { showPagination, disabled = false, showChevronDownIcon = true, selectAllIfNotPaginated = false },
+ forwardedRef,
+ ) => {
+ const { handleBulkSelection, isChecked, checkboxValue, getSelectedIdentifiersCount } = useBulkSelection()
+ const areOptionsSelected = getSelectedIdentifiersCount() > 0
+ const BulkSelectionItems: ActionMenuItemType[] = [
+ {
+ id: BulkSelectionEvents.SELECT_ALL_ON_PAGE,
+ label: BulkSelectionOptionsLabels[BulkSelectionEvents.SELECT_ALL_ON_PAGE],
+ startIcon: { name: 'ic-check-square' },
+ },
+ ...(showPagination
+ ? [
+ {
+ id: BulkSelectionEvents.SELECT_ALL_ACROSS_PAGES,
+ label: BulkSelectionOptionsLabels[BulkSelectionEvents.SELECT_ALL_ACROSS_PAGES],
+ startIcon: { name: 'ic-check-all' },
+ } as ActionMenuItemType,
+ ]
+ : []),
+ ...(areOptionsSelected
+ ? [
+ {
+ id: BulkSelectionEvents.CLEAR_ALL_SELECTIONS,
+ label: BulkSelectionOptionsLabels[BulkSelectionEvents.CLEAR_ALL_SELECTIONS],
+ startIcon: { name: 'ic-close-small' },
+ type: 'negative',
+ } as ActionMenuItemType,
+ ]
+ : []),
+ ]
+
+ const onActionMenuClick: ActionMenuProps['onClick'] = (item) => {
+ handleBulkSelection({
+ action: item.id as BulkSelectionEvents,
+ })
+ }
+
+ const onSinglePageSelectAll = (e: MouseEvent) => {
+ e.stopPropagation()
-const BulkSelection = ({ showPagination, disabled = false, showChevronDownIcon = true }: BulkSelectionProps) => {
- const { handleBulkSelection, isChecked, checkboxValue, getSelectedIdentifiersCount } = useBulkSelection()
- const areOptionsSelected = getSelectedIdentifiersCount() > 0
- const BulkSelectionItems: BulkSelectionDropdownItemsType[] = [
- {
- locator: BulkSelectionEvents.SELECT_ALL_ON_PAGE,
- label: BulkSelectionOptionsLabels[BulkSelectionEvents.SELECT_ALL_ON_PAGE],
- isSelected: isChecked && checkboxValue === CHECKBOX_VALUE.CHECKED,
- icon: ICCheckSquare,
- },
- ...(showPagination
- ? [
- {
- locator: BulkSelectionEvents.SELECT_ALL_ACROSS_PAGES,
- label: BulkSelectionOptionsLabels[BulkSelectionEvents.SELECT_ALL_ACROSS_PAGES],
- isSelected: isChecked && checkboxValue === CHECKBOX_VALUE.BULK_CHECKED,
- icon: ICCheckAll,
- },
- ]
- : []),
- ...(areOptionsSelected
- ? [
- {
- locator: BulkSelectionEvents.CLEAR_ALL_SELECTIONS,
- label: BulkSelectionOptionsLabels[BulkSelectionEvents.CLEAR_ALL_SELECTIONS],
- isSelected: false,
- icon: ICClose,
- iconClass: 'icon-use-fill-n6',
- },
- ]
- : []),
- ]
+ handleBulkSelection({
+ action: areOptionsSelected
+ ? BulkSelectionEvents.CLEAR_ALL_SELECTIONS
+ : BulkSelectionEvents.SELECT_ALL_ON_PAGE,
+ })
+ }
- return (
-
-
-
+
+
+
- {showChevronDownIcon && }
-
+ {showChevronDownIcon && }
+
-
- {BulkSelectionItems.map((item) => (
-
- key={item.locator}
- locator={item.locator}
- label={item.label}
- isSelected={item.isSelected}
- icon={item.icon}
- handleBulkSelection={handleBulkSelection}
- iconClass={item.iconClass}
+
- ))}
-
-
- )
-}
+
+
+ )
+ },
+)
export default BulkSelection
diff --git a/src/Shared/Components/BulkSelection/BulkSelectionDropdownItems.tsx b/src/Shared/Components/BulkSelection/BulkSelectionDropdownItems.tsx
deleted file mode 100644
index a3b4fd9a3..000000000
--- a/src/Shared/Components/BulkSelection/BulkSelectionDropdownItems.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2024. Devtron Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { BulkSelectionDropdownItemsProps } from './types'
-
-const BulkSelectionDropdownItems = ({
- locator,
- label,
- isSelected,
- handleBulkSelection,
- icon: Icon,
- iconClass,
-}: BulkSelectionDropdownItemsProps) => {
- const handleSelect = () => {
- handleBulkSelection({
- action: locator,
- })
- }
-
- return (
-
- )
-}
-
-export default BulkSelectionDropdownItems
diff --git a/src/Shared/Components/BulkSelection/types.tsx b/src/Shared/Components/BulkSelection/types.tsx
index 7350a500a..d23424e59 100644
--- a/src/Shared/Components/BulkSelection/types.tsx
+++ b/src/Shared/Components/BulkSelection/types.tsx
@@ -54,20 +54,12 @@ export interface BulkSelectionProps {
*/
showChevronDownIcon?: boolean
disabled?: boolean
+ /**
+ * If true, pressing the checkbox will select all items on page if list is not paginated
+ */
+ selectAllIfNotPaginated?: boolean
}
-export interface BulkSelectionDropdownItemsType {
- locator: BulkSelectionEvents
- label: string
- isSelected: boolean
- icon: React.FunctionComponent>
- iconClass?: string
-}
-
-export interface BulkSelectionDropdownItemsProps
- extends BulkSelectionDropdownItemsType,
- Pick, 'handleBulkSelection'> {}
-
export enum SelectAllDialogStatus {
OPEN = 'OPEN',
CLOSED = 'CLOSED',
diff --git a/src/Shared/Components/Button/types.ts b/src/Shared/Components/Button/types.ts
index c00d1b14a..a896ce213 100644
--- a/src/Shared/Components/Button/types.ts
+++ b/src/Shared/Components/Button/types.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import { AnchorHTMLAttributes, ButtonHTMLAttributes, ReactElement } from 'react'
+import { AnchorHTMLAttributes, ButtonHTMLAttributes, ReactElement, Ref } from 'react'
import { LinkProps } from 'react-router-dom'
import { TooltipProps } from '@Common/Tooltip'
@@ -48,6 +48,7 @@ export enum ButtonComponentType {
export type ButtonProps =
(ComponentType extends ButtonComponentType.link
? {
+ ref?: Ref
component: ButtonComponentType.link
/**
* Props for the link component
@@ -59,6 +60,7 @@ export type ButtonProps
component: ButtonComponentType.anchor
linkProps?: never
buttonProps?: never
@@ -74,6 +76,7 @@ export type ButtonProps['onClick']
}
: {
+ ref?: Ref
/**
* Component to be rendered from the available options
*
diff --git a/src/Shared/Components/Icon/Icon.tsx b/src/Shared/Components/Icon/Icon.tsx
index eaa2a5589..1d29db585 100644
--- a/src/Shared/Components/Icon/Icon.tsx
+++ b/src/Shared/Components/Icon/Icon.tsx
@@ -22,6 +22,7 @@ import { ReactComponent as ICBitbucket } from '@IconsV2/ic-bitbucket.svg'
import { ReactComponent as ICBookOpen } from '@IconsV2/ic-book-open.svg'
import { ReactComponent as ICBrain } from '@IconsV2/ic-brain.svg'
import { ReactComponent as ICBrowser } from '@IconsV2/ic-browser.svg'
+import { ReactComponent as ICBug } from '@IconsV2/ic-bug.svg'
import { ReactComponent as ICBuildColor } from '@IconsV2/ic-build-color.svg'
import { ReactComponent as ICCalendar } from '@IconsV2/ic-calendar.svg'
import { ReactComponent as ICCancelled } from '@IconsV2/ic-cancelled.svg'
@@ -33,9 +34,12 @@ import { ReactComponent as ICCd } from '@IconsV2/ic-cd.svg'
import { ReactComponent as ICChatCircleDots } from '@IconsV2/ic-chat-circle-dots.svg'
import { ReactComponent as ICChatCircleOnline } from '@IconsV2/ic-chat-circle-online.svg'
import { ReactComponent as ICCheck } from '@IconsV2/ic-check.svg'
+import { ReactComponent as ICCheckAll } from '@IconsV2/ic-check-all.svg'
+import { ReactComponent as ICCheckSquare } from '@IconsV2/ic-check-square.svg'
import { ReactComponent as ICChecks } from '@IconsV2/ic-checks.svg'
import { ReactComponent as ICCiLinked } from '@IconsV2/ic-ci-linked.svg'
import { ReactComponent as ICCircleLoader } from '@IconsV2/ic-circle-loader.svg'
+import { ReactComponent as ICCleanBrush } from '@IconsV2/ic-clean-brush.svg'
import { ReactComponent as ICClock } from '@IconsV2/ic-clock.svg'
import { ReactComponent as ICCloseLarge } from '@IconsV2/ic-close-large.svg'
import { ReactComponent as ICCloseSmall } from '@IconsV2/ic-close-small.svg'
@@ -44,6 +48,7 @@ import { ReactComponent as ICCluster } from '@IconsV2/ic-cluster.svg'
import { ReactComponent as ICClusterIsolated } from '@IconsV2/ic-cluster-isolated.svg'
import { ReactComponent as ICCode } from '@IconsV2/ic-code.svg'
import { ReactComponent as ICContainer } from '@IconsV2/ic-container.svg'
+import { ReactComponent as ICContainerRegistry } from '@IconsV2/ic-container-registry.svg'
import { ReactComponent as ICCookr } from '@IconsV2/ic-cookr.svg'
import { ReactComponent as ICCopy } from '@IconsV2/ic-copy.svg'
import { ReactComponent as ICCpu } from '@IconsV2/ic-cpu.svg'
@@ -63,6 +68,7 @@ import { ReactComponent as ICDevtronJob } from '@IconsV2/ic-devtron-job.svg'
import { ReactComponent as ICDisconnect } from '@IconsV2/ic-disconnect.svg'
import { ReactComponent as ICDiscordFill } from '@IconsV2/ic-discord-fill.svg'
import { ReactComponent as ICDockerhub } from '@IconsV2/ic-dockerhub.svg'
+import { ReactComponent as ICDownload } from '@IconsV2/ic-download.svg'
import { ReactComponent as ICEcr } from '@IconsV2/ic-ecr.svg'
import { ReactComponent as ICEdit } from '@IconsV2/ic-edit.svg'
import { ReactComponent as ICEmail } from '@IconsV2/ic-email.svg'
@@ -77,6 +83,7 @@ import { ReactComponent as ICExpandSm } from '@IconsV2/ic-expand-sm.svg'
import { ReactComponent as ICFailure } from '@IconsV2/ic-failure.svg'
import { ReactComponent as ICFastForward } from '@IconsV2/ic-fast-forward.svg'
import { ReactComponent as ICFile } from '@IconsV2/ic-file.svg'
+import { ReactComponent as ICFileCode } from '@IconsV2/ic-file-code.svg'
import { ReactComponent as ICFileEdit } from '@IconsV2/ic-file-edit.svg'
import { ReactComponent as ICFileKey } from '@IconsV2/ic-file-key.svg'
import { ReactComponent as ICFiles } from '@IconsV2/ic-files.svg'
@@ -85,6 +92,7 @@ import { ReactComponent as ICFilterApplied } from '@IconsV2/ic-filter-applied.sv
import { ReactComponent as ICFlask } from '@IconsV2/ic-flask.svg'
import { ReactComponent as ICFolderColor } from '@IconsV2/ic-folder-color.svg'
import { ReactComponent as ICFolderUser } from '@IconsV2/ic-folder-user.svg'
+import { ReactComponent as ICGavel } from '@IconsV2/ic-gavel.svg'
import { ReactComponent as ICGear } from '@IconsV2/ic-gear.svg'
import { ReactComponent as ICGift } from '@IconsV2/ic-gift.svg'
import { ReactComponent as ICGiftGradient } from '@IconsV2/ic-gift-gradient.svg'
@@ -108,6 +116,7 @@ import { ReactComponent as ICHibernate } from '@IconsV2/ic-hibernate.svg'
import { ReactComponent as ICHibernateCircle } from '@IconsV2/ic-hibernate-circle.svg'
import { ReactComponent as ICInProgress } from '@IconsV2/ic-in-progress.svg'
import { ReactComponent as ICInfoFilled } from '@IconsV2/ic-info-filled.svg'
+import { ReactComponent as ICInfoFilledColor } from '@IconsV2/ic-info-filled-color.svg'
import { ReactComponent as ICInfoOutline } from '@IconsV2/ic-info-outline.svg'
import { ReactComponent as ICInstall } from '@IconsV2/ic-install.svg'
import { ReactComponent as ICJobColor } from '@IconsV2/ic-job-color.svg'
@@ -124,6 +133,7 @@ import { ReactComponent as ICLightningFill } from '@IconsV2/ic-lightning-fill.sv
import { ReactComponent as ICLinkedBuildColor } from '@IconsV2/ic-linked-build-color.svg'
import { ReactComponent as ICLivspace } from '@IconsV2/ic-livspace.svg'
import { ReactComponent as ICLogout } from '@IconsV2/ic-logout.svg'
+import { ReactComponent as ICLogs } from '@IconsV2/ic-logs.svg'
import { ReactComponent as ICMagnifyingGlass } from '@IconsV2/ic-magnifying-glass.svg'
import { ReactComponent as ICMediumDelete } from '@IconsV2/ic-medium-delete.svg'
import { ReactComponent as ICMediumPaintbucket } from '@IconsV2/ic-medium-paintbucket.svg'
@@ -148,6 +158,7 @@ import { ReactComponent as ICOutOfSync } from '@IconsV2/ic-out-of-sync.svg'
import { ReactComponent as ICPaperPlane } from '@IconsV2/ic-paper-plane.svg'
import { ReactComponent as ICPaperPlaneColor } from '@IconsV2/ic-paper-plane-color.svg'
import { ReactComponent as ICPath } from '@IconsV2/ic-path.svg'
+import { ReactComponent as ICPauseCircle } from '@IconsV2/ic-pause-circle.svg'
import { ReactComponent as ICPencil } from '@IconsV2/ic-pencil.svg'
import { ReactComponent as ICPlayOutline } from '@IconsV2/ic-play-outline.svg'
import { ReactComponent as ICQuay } from '@IconsV2/ic-quay.svg'
@@ -163,6 +174,7 @@ import { ReactComponent as ICSortDescending } from '@IconsV2/ic-sort-descending.
import { ReactComponent as ICSortable } from '@IconsV2/ic-sortable.svg'
import { ReactComponent as ICSparkleAiColor } from '@IconsV2/ic-sparkle-ai-color.svg'
import { ReactComponent as ICSparkleColor } from '@IconsV2/ic-sparkle-color.svg'
+import { ReactComponent as ICSpeedometer } from '@IconsV2/ic-speedometer.svg'
import { ReactComponent as ICSpinny } from '@IconsV2/ic-spinny.svg'
import { ReactComponent as ICSprayCan } from '@IconsV2/ic-spray-can.svg'
import { ReactComponent as ICStack } from '@IconsV2/ic-stack.svg'
@@ -189,6 +201,7 @@ import { ReactComponent as ICTimeoutDash } from '@IconsV2/ic-timeout-dash.svg'
import { ReactComponent as ICTimer } from '@IconsV2/ic-timer.svg'
import { ReactComponent as ICTrafficSignal } from '@IconsV2/ic-traffic-signal.svg'
import { ReactComponent as ICTravclan } from '@IconsV2/ic-travclan.svg'
+import { ReactComponent as ICTwoCubes } from '@IconsV2/ic-two-cubes.svg'
import { ReactComponent as ICUbuntu } from '@IconsV2/ic-ubuntu.svg'
import { ReactComponent as ICUnknown } from '@IconsV2/ic-unknown.svg'
import { ReactComponent as ICUserCircle } from '@IconsV2/ic-user-circle.svg'
@@ -227,6 +240,7 @@ export const iconMap = {
'ic-book-open': ICBookOpen,
'ic-brain': ICBrain,
'ic-browser': ICBrowser,
+ 'ic-bug': ICBug,
'ic-build-color': ICBuildColor,
'ic-calendar': ICCalendar,
'ic-cancelled': ICCancelled,
@@ -237,10 +251,13 @@ export const iconMap = {
'ic-cd': ICCd,
'ic-chat-circle-dots': ICChatCircleDots,
'ic-chat-circle-online': ICChatCircleOnline,
+ 'ic-check-all': ICCheckAll,
+ 'ic-check-square': ICCheckSquare,
'ic-check': ICCheck,
'ic-checks': ICChecks,
'ic-ci-linked': ICCiLinked,
'ic-circle-loader': ICCircleLoader,
+ 'ic-clean-brush': ICCleanBrush,
'ic-clock': ICClock,
'ic-close-large': ICCloseLarge,
'ic-close-small': ICCloseSmall,
@@ -248,6 +265,7 @@ export const iconMap = {
'ic-cluster-isolated': ICClusterIsolated,
'ic-cluster': ICCluster,
'ic-code': ICCode,
+ 'ic-container-registry': ICContainerRegistry,
'ic-container': ICContainer,
'ic-cookr': ICCookr,
'ic-copy': ICCopy,
@@ -268,6 +286,7 @@ export const iconMap = {
'ic-disconnect': ICDisconnect,
'ic-discord-fill': ICDiscordFill,
'ic-dockerhub': ICDockerhub,
+ 'ic-download': ICDownload,
'ic-ecr': ICEcr,
'ic-edit': ICEdit,
'ic-email': ICEmail,
@@ -281,6 +300,7 @@ export const iconMap = {
'ic-expand-sm': ICExpandSm,
'ic-failure': ICFailure,
'ic-fast-forward': ICFastForward,
+ 'ic-file-code': ICFileCode,
'ic-file-edit': ICFileEdit,
'ic-file-key': ICFileKey,
'ic-file': ICFile,
@@ -290,6 +310,7 @@ export const iconMap = {
'ic-flask': ICFlask,
'ic-folder-color': ICFolderColor,
'ic-folder-user': ICFolderUser,
+ 'ic-gavel': ICGavel,
'ic-gear': ICGear,
'ic-gift-gradient': ICGiftGradient,
'ic-gift': ICGift,
@@ -312,6 +333,7 @@ export const iconMap = {
'ic-hibernate-circle': ICHibernateCircle,
'ic-hibernate': ICHibernate,
'ic-in-progress': ICInProgress,
+ 'ic-info-filled-color': ICInfoFilledColor,
'ic-info-filled': ICInfoFilled,
'ic-info-outline': ICInfoOutline,
'ic-install': ICInstall,
@@ -329,6 +351,7 @@ export const iconMap = {
'ic-linked-build-color': ICLinkedBuildColor,
'ic-livspace': ICLivspace,
'ic-logout': ICLogout,
+ 'ic-logs': ICLogs,
'ic-magnifying-glass': ICMagnifyingGlass,
'ic-medium-delete': ICMediumDelete,
'ic-medium-paintbucket': ICMediumPaintbucket,
@@ -353,6 +376,7 @@ export const iconMap = {
'ic-paper-plane-color': ICPaperPlaneColor,
'ic-paper-plane': ICPaperPlane,
'ic-path': ICPath,
+ 'ic-pause-circle': ICPauseCircle,
'ic-pencil': ICPencil,
'ic-play-outline': ICPlayOutline,
'ic-quay': ICQuay,
@@ -368,6 +392,7 @@ export const iconMap = {
'ic-sortable': ICSortable,
'ic-sparkle-ai-color': ICSparkleAiColor,
'ic-sparkle-color': ICSparkleColor,
+ 'ic-speedometer': ICSpeedometer,
'ic-spinny': ICSpinny,
'ic-spray-can': ICSprayCan,
'ic-stack': ICStack,
@@ -394,6 +419,7 @@ export const iconMap = {
'ic-timer': ICTimer,
'ic-traffic-signal': ICTrafficSignal,
'ic-travclan': ICTravclan,
+ 'ic-two-cubes': ICTwoCubes,
'ic-ubuntu': ICUbuntu,
'ic-unknown': ICUnknown,
'ic-user-circle': ICUserCircle,
diff --git a/src/Shared/Components/InfoBlock/InfoBlock.component.tsx b/src/Shared/Components/InfoBlock/InfoBlock.component.tsx
index 0f5309242..194cd67a1 100644
--- a/src/Shared/Components/InfoBlock/InfoBlock.component.tsx
+++ b/src/Shared/Components/InfoBlock/InfoBlock.component.tsx
@@ -19,8 +19,9 @@ import { deriveBorderRadiusAndBorderClassFromConfig } from '@Shared/Helpers'
import { Button } from '../Button'
import {
- CONTAINER_SIZE_TO_BUTTON_SIZE,
CONTAINER_SIZE_TO_CLASS_MAP,
+ CONTAINER_SIZE_TO_ICON_BUTTON_SIZE,
+ CONTAINER_SIZE_TO_TEXT_BUTTON_SIZE,
SIZE_TO_ICON_CLASS_MAP,
VARIANT_TO_ICON_MAP,
} from './constants'
@@ -40,6 +41,9 @@ const InfoBlock = ({
const baseContainerClass = `${CONTAINER_SIZE_TO_CLASS_MAP[size]} ${VARIANT_TO_BG_MAP[variant]} ${VARIANT_TO_BORDER_MAP[variant]} ${deriveBorderRadiusAndBorderClassFromConfig({ borderConfig, borderRadiusConfig })} w-100 py-8 br-4 bw-1`
const iconClass = `dc__no-shrink flex dc__fill-available-space ${SIZE_TO_ICON_CLASS_MAP[size]}`
const icon = customIcon ?? VARIANT_TO_ICON_MAP[variant]
+ const buttonSize = buttonProps?.icon
+ ? CONTAINER_SIZE_TO_ICON_BUTTON_SIZE[size]
+ : CONTAINER_SIZE_TO_TEXT_BUTTON_SIZE[size]
const renderIcon = () => {icon}
@@ -99,7 +103,7 @@ const InfoBlock = ({
{renderContent()}
- {buttonProps &&